wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 13:f67a6c6013ca 1 /* integer.c
wolfSSL 13:f67a6c6013ca 2 *
wolfSSL 13:f67a6c6013ca 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 13:f67a6c6013ca 4 *
wolfSSL 13:f67a6c6013ca 5 * This file is part of wolfSSL.
wolfSSL 13:f67a6c6013ca 6 *
wolfSSL 13:f67a6c6013ca 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 13:f67a6c6013ca 8 * it under the terms of the GNU General Public License as published by
wolfSSL 13:f67a6c6013ca 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 13:f67a6c6013ca 10 * (at your option) any later version.
wolfSSL 13:f67a6c6013ca 11 *
wolfSSL 13:f67a6c6013ca 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 13:f67a6c6013ca 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 13:f67a6c6013ca 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 13:f67a6c6013ca 15 * GNU General Public License for more details.
wolfSSL 13:f67a6c6013ca 16 *
wolfSSL 13:f67a6c6013ca 17 * You should have received a copy of the GNU General Public License
wolfSSL 13:f67a6c6013ca 18 * along with this program; if not, write to the Free Software
wolfSSL 13:f67a6c6013ca 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 13:f67a6c6013ca 20 */
wolfSSL 13:f67a6c6013ca 21
wolfSSL 13:f67a6c6013ca 22
wolfSSL 13:f67a6c6013ca 23
wolfSSL 13:f67a6c6013ca 24 /*
wolfSSL 13:f67a6c6013ca 25 * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,
wolfSSL 13:f67a6c6013ca 26 * http://math.libtomcrypt.com
wolfSSL 13:f67a6c6013ca 27 */
wolfSSL 13:f67a6c6013ca 28
wolfSSL 13:f67a6c6013ca 29
wolfSSL 13:f67a6c6013ca 30 #ifdef HAVE_CONFIG_H
wolfSSL 13:f67a6c6013ca 31 #include <config.h>
wolfSSL 13:f67a6c6013ca 32 #endif
wolfSSL 13:f67a6c6013ca 33
wolfSSL 13:f67a6c6013ca 34 /* in case user set USE_FAST_MATH there */
wolfSSL 13:f67a6c6013ca 35 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 13:f67a6c6013ca 36
wolfSSL 13:f67a6c6013ca 37 #ifdef NO_INLINE
wolfSSL 13:f67a6c6013ca 38 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 13:f67a6c6013ca 39 #else
wolfSSL 13:f67a6c6013ca 40 #define WOLFSSL_MISC_INCLUDED
wolfSSL 13:f67a6c6013ca 41 #include <wolfcrypt/src/misc.c>
wolfSSL 13:f67a6c6013ca 42 #endif
wolfSSL 13:f67a6c6013ca 43
wolfSSL 13:f67a6c6013ca 44 #ifndef NO_BIG_INT
wolfSSL 13:f67a6c6013ca 45
wolfSSL 13:f67a6c6013ca 46 #ifndef USE_FAST_MATH
wolfSSL 13:f67a6c6013ca 47
wolfSSL 13:f67a6c6013ca 48 #include <wolfssl/wolfcrypt/integer.h>
wolfSSL 13:f67a6c6013ca 49
wolfSSL 13:f67a6c6013ca 50 #if defined(FREESCALE_LTC_TFM)
wolfSSL 13:f67a6c6013ca 51 #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
wolfSSL 13:f67a6c6013ca 52 #endif
wolfSSL 13:f67a6c6013ca 53 #ifdef WOLFSSL_DEBUG_MATH
wolfSSL 13:f67a6c6013ca 54 #include <stdio.h>
wolfSSL 13:f67a6c6013ca 55 #endif
wolfSSL 13:f67a6c6013ca 56
wolfSSL 13:f67a6c6013ca 57 #ifndef NO_WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 58 #ifndef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 59 #define WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 60 #endif
wolfSSL 13:f67a6c6013ca 61 #endif
wolfSSL 13:f67a6c6013ca 62
wolfSSL 13:f67a6c6013ca 63 #ifdef SHOW_GEN
wolfSSL 13:f67a6c6013ca 64 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
wolfSSL 13:f67a6c6013ca 65 #if MQX_USE_IO_OLD
wolfSSL 13:f67a6c6013ca 66 #include <fio.h>
wolfSSL 13:f67a6c6013ca 67 #else
wolfSSL 13:f67a6c6013ca 68 #include <nio.h>
wolfSSL 13:f67a6c6013ca 69 #endif
wolfSSL 13:f67a6c6013ca 70 #else
wolfSSL 13:f67a6c6013ca 71 #include <stdio.h>
wolfSSL 13:f67a6c6013ca 72 #endif
wolfSSL 13:f67a6c6013ca 73 #endif
wolfSSL 13:f67a6c6013ca 74
wolfSSL 13:f67a6c6013ca 75 /* reverse an array, used for radix code */
wolfSSL 13:f67a6c6013ca 76 static void
wolfSSL 13:f67a6c6013ca 77 bn_reverse (unsigned char *s, int len)
wolfSSL 13:f67a6c6013ca 78 {
wolfSSL 13:f67a6c6013ca 79 int ix, iy;
wolfSSL 13:f67a6c6013ca 80 unsigned char t;
wolfSSL 13:f67a6c6013ca 81
wolfSSL 13:f67a6c6013ca 82 ix = 0;
wolfSSL 13:f67a6c6013ca 83 iy = len - 1;
wolfSSL 13:f67a6c6013ca 84 while (ix < iy) {
wolfSSL 13:f67a6c6013ca 85 t = s[ix];
wolfSSL 13:f67a6c6013ca 86 s[ix] = s[iy];
wolfSSL 13:f67a6c6013ca 87 s[iy] = t;
wolfSSL 13:f67a6c6013ca 88 ++ix;
wolfSSL 13:f67a6c6013ca 89 --iy;
wolfSSL 13:f67a6c6013ca 90 }
wolfSSL 13:f67a6c6013ca 91 }
wolfSSL 13:f67a6c6013ca 92
wolfSSL 13:f67a6c6013ca 93 /* math settings check */
wolfSSL 13:f67a6c6013ca 94 word32 CheckRunTimeSettings(void)
wolfSSL 13:f67a6c6013ca 95 {
wolfSSL 13:f67a6c6013ca 96 return CTC_SETTINGS;
wolfSSL 13:f67a6c6013ca 97 }
wolfSSL 13:f67a6c6013ca 98
wolfSSL 13:f67a6c6013ca 99
wolfSSL 13:f67a6c6013ca 100 /* handle up to 6 inits */
wolfSSL 13:f67a6c6013ca 101 int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
wolfSSL 13:f67a6c6013ca 102 mp_int* f)
wolfSSL 13:f67a6c6013ca 103 {
wolfSSL 13:f67a6c6013ca 104 int res = MP_OKAY;
wolfSSL 13:f67a6c6013ca 105
wolfSSL 13:f67a6c6013ca 106 if (a) XMEMSET(a, 0, sizeof(mp_int));
wolfSSL 13:f67a6c6013ca 107 if (b) XMEMSET(b, 0, sizeof(mp_int));
wolfSSL 13:f67a6c6013ca 108 if (c) XMEMSET(c, 0, sizeof(mp_int));
wolfSSL 13:f67a6c6013ca 109 if (d) XMEMSET(d, 0, sizeof(mp_int));
wolfSSL 13:f67a6c6013ca 110 if (e) XMEMSET(e, 0, sizeof(mp_int));
wolfSSL 13:f67a6c6013ca 111 if (f) XMEMSET(f, 0, sizeof(mp_int));
wolfSSL 13:f67a6c6013ca 112
wolfSSL 13:f67a6c6013ca 113 if (a && ((res = mp_init(a)) != MP_OKAY))
wolfSSL 13:f67a6c6013ca 114 return res;
wolfSSL 13:f67a6c6013ca 115
wolfSSL 13:f67a6c6013ca 116 if (b && ((res = mp_init(b)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 117 mp_clear(a);
wolfSSL 13:f67a6c6013ca 118 return res;
wolfSSL 13:f67a6c6013ca 119 }
wolfSSL 13:f67a6c6013ca 120
wolfSSL 13:f67a6c6013ca 121 if (c && ((res = mp_init(c)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 122 mp_clear(a); mp_clear(b);
wolfSSL 13:f67a6c6013ca 123 return res;
wolfSSL 13:f67a6c6013ca 124 }
wolfSSL 13:f67a6c6013ca 125
wolfSSL 13:f67a6c6013ca 126 if (d && ((res = mp_init(d)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 127 mp_clear(a); mp_clear(b); mp_clear(c);
wolfSSL 13:f67a6c6013ca 128 return res;
wolfSSL 13:f67a6c6013ca 129 }
wolfSSL 13:f67a6c6013ca 130
wolfSSL 13:f67a6c6013ca 131 if (e && ((res = mp_init(e)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 132 mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d);
wolfSSL 13:f67a6c6013ca 133 return res;
wolfSSL 13:f67a6c6013ca 134 }
wolfSSL 13:f67a6c6013ca 135
wolfSSL 13:f67a6c6013ca 136 if (f && ((res = mp_init(f)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 137 mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e);
wolfSSL 13:f67a6c6013ca 138 return res;
wolfSSL 13:f67a6c6013ca 139 }
wolfSSL 13:f67a6c6013ca 140
wolfSSL 13:f67a6c6013ca 141 return res;
wolfSSL 13:f67a6c6013ca 142 }
wolfSSL 13:f67a6c6013ca 143
wolfSSL 13:f67a6c6013ca 144
wolfSSL 13:f67a6c6013ca 145 /* init a new mp_int */
wolfSSL 13:f67a6c6013ca 146 int mp_init (mp_int * a)
wolfSSL 13:f67a6c6013ca 147 {
wolfSSL 13:f67a6c6013ca 148 /* Safeguard against passing in a null pointer */
wolfSSL 13:f67a6c6013ca 149 if (a == NULL)
wolfSSL 13:f67a6c6013ca 150 return MP_VAL;
wolfSSL 13:f67a6c6013ca 151
wolfSSL 13:f67a6c6013ca 152 /* defer allocation until mp_grow */
wolfSSL 13:f67a6c6013ca 153 a->dp = NULL;
wolfSSL 13:f67a6c6013ca 154
wolfSSL 13:f67a6c6013ca 155 /* set the used to zero, allocated digits to the default precision
wolfSSL 13:f67a6c6013ca 156 * and sign to positive */
wolfSSL 13:f67a6c6013ca 157 a->used = 0;
wolfSSL 13:f67a6c6013ca 158 a->alloc = 0;
wolfSSL 13:f67a6c6013ca 159 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 160 #ifdef HAVE_WOLF_BIGINT
wolfSSL 13:f67a6c6013ca 161 wc_bigint_init(&a->raw);
wolfSSL 13:f67a6c6013ca 162 #endif
wolfSSL 13:f67a6c6013ca 163
wolfSSL 13:f67a6c6013ca 164 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 165 }
wolfSSL 13:f67a6c6013ca 166
wolfSSL 13:f67a6c6013ca 167
wolfSSL 13:f67a6c6013ca 168 /* clear one (frees) */
wolfSSL 13:f67a6c6013ca 169 void mp_clear (mp_int * a)
wolfSSL 13:f67a6c6013ca 170 {
wolfSSL 13:f67a6c6013ca 171 int i;
wolfSSL 13:f67a6c6013ca 172
wolfSSL 13:f67a6c6013ca 173 if (a == NULL)
wolfSSL 13:f67a6c6013ca 174 return;
wolfSSL 13:f67a6c6013ca 175
wolfSSL 13:f67a6c6013ca 176 /* only do anything if a hasn't been freed previously */
wolfSSL 13:f67a6c6013ca 177 if (a->dp != NULL) {
wolfSSL 13:f67a6c6013ca 178 /* first zero the digits */
wolfSSL 13:f67a6c6013ca 179 for (i = 0; i < a->used; i++) {
wolfSSL 13:f67a6c6013ca 180 a->dp[i] = 0;
wolfSSL 13:f67a6c6013ca 181 }
wolfSSL 13:f67a6c6013ca 182
wolfSSL 13:f67a6c6013ca 183 /* free ram */
wolfSSL 13:f67a6c6013ca 184 mp_free(a);
wolfSSL 13:f67a6c6013ca 185
wolfSSL 13:f67a6c6013ca 186 /* reset members to make debugging easier */
wolfSSL 13:f67a6c6013ca 187 a->alloc = a->used = 0;
wolfSSL 13:f67a6c6013ca 188 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 189 }
wolfSSL 13:f67a6c6013ca 190 }
wolfSSL 13:f67a6c6013ca 191
wolfSSL 13:f67a6c6013ca 192 void mp_free (mp_int * a)
wolfSSL 13:f67a6c6013ca 193 {
wolfSSL 13:f67a6c6013ca 194 /* only do anything if a hasn't been freed previously */
wolfSSL 13:f67a6c6013ca 195 if (a->dp != NULL) {
wolfSSL 13:f67a6c6013ca 196 /* free ram */
wolfSSL 13:f67a6c6013ca 197 XFREE(a->dp, 0, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 198 a->dp = NULL;
wolfSSL 13:f67a6c6013ca 199 }
wolfSSL 13:f67a6c6013ca 200
wolfSSL 13:f67a6c6013ca 201 #ifdef HAVE_WOLF_BIGINT
wolfSSL 13:f67a6c6013ca 202 wc_bigint_free(&a->raw);
wolfSSL 13:f67a6c6013ca 203 #endif
wolfSSL 13:f67a6c6013ca 204 }
wolfSSL 13:f67a6c6013ca 205
wolfSSL 13:f67a6c6013ca 206 void mp_forcezero(mp_int * a)
wolfSSL 13:f67a6c6013ca 207 {
wolfSSL 13:f67a6c6013ca 208 if (a == NULL)
wolfSSL 13:f67a6c6013ca 209 return;
wolfSSL 13:f67a6c6013ca 210
wolfSSL 13:f67a6c6013ca 211 /* only do anything if a hasn't been freed previously */
wolfSSL 13:f67a6c6013ca 212 if (a->dp != NULL) {
wolfSSL 13:f67a6c6013ca 213 /* force zero the used digits */
wolfSSL 13:f67a6c6013ca 214 ForceZero(a->dp, a->used * sizeof(mp_digit));
wolfSSL 13:f67a6c6013ca 215 #ifdef HAVE_WOLF_BIGINT
wolfSSL 13:f67a6c6013ca 216 wc_bigint_zero(&a->raw);
wolfSSL 13:f67a6c6013ca 217 #endif
wolfSSL 13:f67a6c6013ca 218 /* free ram */
wolfSSL 13:f67a6c6013ca 219 mp_free(a);
wolfSSL 13:f67a6c6013ca 220
wolfSSL 13:f67a6c6013ca 221 /* reset members to make debugging easier */
wolfSSL 13:f67a6c6013ca 222 a->alloc = a->used = 0;
wolfSSL 13:f67a6c6013ca 223 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 224 }
wolfSSL 13:f67a6c6013ca 225
wolfSSL 13:f67a6c6013ca 226 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 227 a->used = 0;
wolfSSL 13:f67a6c6013ca 228 }
wolfSSL 13:f67a6c6013ca 229
wolfSSL 13:f67a6c6013ca 230
wolfSSL 13:f67a6c6013ca 231 /* get the size for an unsigned equivalent */
wolfSSL 13:f67a6c6013ca 232 int mp_unsigned_bin_size (mp_int * a)
wolfSSL 13:f67a6c6013ca 233 {
wolfSSL 13:f67a6c6013ca 234 int size = mp_count_bits (a);
wolfSSL 13:f67a6c6013ca 235 return (size / 8 + ((size & 7) != 0 ? 1 : 0));
wolfSSL 13:f67a6c6013ca 236 }
wolfSSL 13:f67a6c6013ca 237
wolfSSL 13:f67a6c6013ca 238
wolfSSL 13:f67a6c6013ca 239 /* returns the number of bits in an int */
wolfSSL 13:f67a6c6013ca 240 int mp_count_bits (mp_int * a)
wolfSSL 13:f67a6c6013ca 241 {
wolfSSL 13:f67a6c6013ca 242 int r;
wolfSSL 13:f67a6c6013ca 243 mp_digit q;
wolfSSL 13:f67a6c6013ca 244
wolfSSL 13:f67a6c6013ca 245 /* shortcut */
wolfSSL 13:f67a6c6013ca 246 if (a->used == 0) {
wolfSSL 13:f67a6c6013ca 247 return 0;
wolfSSL 13:f67a6c6013ca 248 }
wolfSSL 13:f67a6c6013ca 249
wolfSSL 13:f67a6c6013ca 250 /* get number of digits and add that */
wolfSSL 13:f67a6c6013ca 251 r = (a->used - 1) * DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 252
wolfSSL 13:f67a6c6013ca 253 /* take the last digit and count the bits in it */
wolfSSL 13:f67a6c6013ca 254 q = a->dp[a->used - 1];
wolfSSL 13:f67a6c6013ca 255 while (q > ((mp_digit) 0)) {
wolfSSL 13:f67a6c6013ca 256 ++r;
wolfSSL 13:f67a6c6013ca 257 q >>= ((mp_digit) 1);
wolfSSL 13:f67a6c6013ca 258 }
wolfSSL 13:f67a6c6013ca 259 return r;
wolfSSL 13:f67a6c6013ca 260 }
wolfSSL 13:f67a6c6013ca 261
wolfSSL 13:f67a6c6013ca 262
wolfSSL 13:f67a6c6013ca 263 int mp_leading_bit (mp_int * a)
wolfSSL 13:f67a6c6013ca 264 {
wolfSSL 13:f67a6c6013ca 265 int bit = 0;
wolfSSL 13:f67a6c6013ca 266 mp_int t;
wolfSSL 13:f67a6c6013ca 267
wolfSSL 13:f67a6c6013ca 268 if (mp_init_copy(&t, a) != MP_OKAY)
wolfSSL 13:f67a6c6013ca 269 return 0;
wolfSSL 13:f67a6c6013ca 270
wolfSSL 13:f67a6c6013ca 271 while (mp_iszero(&t) == MP_NO) {
wolfSSL 13:f67a6c6013ca 272 #ifndef MP_8BIT
wolfSSL 13:f67a6c6013ca 273 bit = (t.dp[0] & 0x80) != 0;
wolfSSL 13:f67a6c6013ca 274 #else
wolfSSL 13:f67a6c6013ca 275 bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0;
wolfSSL 13:f67a6c6013ca 276 #endif
wolfSSL 13:f67a6c6013ca 277 if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY)
wolfSSL 13:f67a6c6013ca 278 break;
wolfSSL 13:f67a6c6013ca 279 }
wolfSSL 13:f67a6c6013ca 280 mp_clear(&t);
wolfSSL 13:f67a6c6013ca 281 return bit;
wolfSSL 13:f67a6c6013ca 282 }
wolfSSL 13:f67a6c6013ca 283
wolfSSL 13:f67a6c6013ca 284 int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b)
wolfSSL 13:f67a6c6013ca 285 {
wolfSSL 13:f67a6c6013ca 286 int res = 0;
wolfSSL 13:f67a6c6013ca 287 while (mp_iszero(t) == MP_NO) {
wolfSSL 13:f67a6c6013ca 288 #ifndef MP_8BIT
wolfSSL 13:f67a6c6013ca 289 b[x++] = (unsigned char) (t->dp[0] & 255);
wolfSSL 13:f67a6c6013ca 290 #else
wolfSSL 13:f67a6c6013ca 291 b[x++] = (unsigned char) (t->dp[0] | ((t->dp[1] & 0x01) << 7));
wolfSSL 13:f67a6c6013ca 292 #endif
wolfSSL 13:f67a6c6013ca 293 if ((res = mp_div_2d (t, 8, t, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 294 return res;
wolfSSL 13:f67a6c6013ca 295 }
wolfSSL 13:f67a6c6013ca 296 res = x;
wolfSSL 13:f67a6c6013ca 297 }
wolfSSL 13:f67a6c6013ca 298 return res;
wolfSSL 13:f67a6c6013ca 299 }
wolfSSL 13:f67a6c6013ca 300
wolfSSL 13:f67a6c6013ca 301 /* store in unsigned [big endian] format */
wolfSSL 13:f67a6c6013ca 302 int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
wolfSSL 13:f67a6c6013ca 303 {
wolfSSL 13:f67a6c6013ca 304 int x, res;
wolfSSL 13:f67a6c6013ca 305 mp_int t;
wolfSSL 13:f67a6c6013ca 306
wolfSSL 13:f67a6c6013ca 307 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 308 return res;
wolfSSL 13:f67a6c6013ca 309 }
wolfSSL 13:f67a6c6013ca 310
wolfSSL 13:f67a6c6013ca 311 x = mp_to_unsigned_bin_at_pos(0, &t, b);
wolfSSL 13:f67a6c6013ca 312 if (x < 0) {
wolfSSL 13:f67a6c6013ca 313 mp_clear(&t);
wolfSSL 13:f67a6c6013ca 314 return x;
wolfSSL 13:f67a6c6013ca 315 }
wolfSSL 13:f67a6c6013ca 316
wolfSSL 13:f67a6c6013ca 317 bn_reverse (b, x);
wolfSSL 13:f67a6c6013ca 318 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 319 return res;
wolfSSL 13:f67a6c6013ca 320 }
wolfSSL 13:f67a6c6013ca 321
wolfSSL 13:f67a6c6013ca 322
wolfSSL 13:f67a6c6013ca 323 /* creates "a" then copies b into it */
wolfSSL 13:f67a6c6013ca 324 int mp_init_copy (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 325 {
wolfSSL 13:f67a6c6013ca 326 int res;
wolfSSL 13:f67a6c6013ca 327
wolfSSL 13:f67a6c6013ca 328 if ((res = mp_init (a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 329 return res;
wolfSSL 13:f67a6c6013ca 330 }
wolfSSL 13:f67a6c6013ca 331 return mp_copy (b, a);
wolfSSL 13:f67a6c6013ca 332 }
wolfSSL 13:f67a6c6013ca 333
wolfSSL 13:f67a6c6013ca 334
wolfSSL 13:f67a6c6013ca 335 /* copy, b = a */
wolfSSL 13:f67a6c6013ca 336 int mp_copy (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 337 {
wolfSSL 13:f67a6c6013ca 338 int res, n;
wolfSSL 13:f67a6c6013ca 339
wolfSSL 13:f67a6c6013ca 340 /* Safeguard against passing in a null pointer */
wolfSSL 13:f67a6c6013ca 341 if (a == NULL || b == NULL)
wolfSSL 13:f67a6c6013ca 342 return MP_VAL;
wolfSSL 13:f67a6c6013ca 343
wolfSSL 13:f67a6c6013ca 344 /* if dst == src do nothing */
wolfSSL 13:f67a6c6013ca 345 if (a == b) {
wolfSSL 13:f67a6c6013ca 346 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 347 }
wolfSSL 13:f67a6c6013ca 348
wolfSSL 13:f67a6c6013ca 349 /* grow dest */
wolfSSL 13:f67a6c6013ca 350 if (b->alloc < a->used || b->alloc == 0) {
wolfSSL 13:f67a6c6013ca 351 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 352 return res;
wolfSSL 13:f67a6c6013ca 353 }
wolfSSL 13:f67a6c6013ca 354 }
wolfSSL 13:f67a6c6013ca 355
wolfSSL 13:f67a6c6013ca 356 /* zero b and copy the parameters over */
wolfSSL 13:f67a6c6013ca 357 {
wolfSSL 13:f67a6c6013ca 358 mp_digit *tmpa, *tmpb;
wolfSSL 13:f67a6c6013ca 359
wolfSSL 13:f67a6c6013ca 360 /* pointer aliases */
wolfSSL 13:f67a6c6013ca 361
wolfSSL 13:f67a6c6013ca 362 /* source */
wolfSSL 13:f67a6c6013ca 363 tmpa = a->dp;
wolfSSL 13:f67a6c6013ca 364
wolfSSL 13:f67a6c6013ca 365 /* destination */
wolfSSL 13:f67a6c6013ca 366 tmpb = b->dp;
wolfSSL 13:f67a6c6013ca 367
wolfSSL 13:f67a6c6013ca 368 /* copy all the digits */
wolfSSL 13:f67a6c6013ca 369 for (n = 0; n < a->used; n++) {
wolfSSL 13:f67a6c6013ca 370 *tmpb++ = *tmpa++;
wolfSSL 13:f67a6c6013ca 371 }
wolfSSL 13:f67a6c6013ca 372
wolfSSL 13:f67a6c6013ca 373 /* clear high digits */
wolfSSL 13:f67a6c6013ca 374 for (; n < b->used && b->dp; n++) {
wolfSSL 13:f67a6c6013ca 375 *tmpb++ = 0;
wolfSSL 13:f67a6c6013ca 376 }
wolfSSL 13:f67a6c6013ca 377 }
wolfSSL 13:f67a6c6013ca 378
wolfSSL 13:f67a6c6013ca 379 /* copy used count and sign */
wolfSSL 13:f67a6c6013ca 380 b->used = a->used;
wolfSSL 13:f67a6c6013ca 381 b->sign = a->sign;
wolfSSL 13:f67a6c6013ca 382 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 383 }
wolfSSL 13:f67a6c6013ca 384
wolfSSL 13:f67a6c6013ca 385
wolfSSL 13:f67a6c6013ca 386 /* grow as required */
wolfSSL 13:f67a6c6013ca 387 int mp_grow (mp_int * a, int size)
wolfSSL 13:f67a6c6013ca 388 {
wolfSSL 13:f67a6c6013ca 389 int i;
wolfSSL 13:f67a6c6013ca 390 mp_digit *tmp;
wolfSSL 13:f67a6c6013ca 391
wolfSSL 13:f67a6c6013ca 392 /* if the alloc size is smaller alloc more ram */
wolfSSL 13:f67a6c6013ca 393 if (a->alloc < size || size == 0) {
wolfSSL 13:f67a6c6013ca 394 /* ensure there are always at least MP_PREC digits extra on top */
wolfSSL 13:f67a6c6013ca 395 size += (MP_PREC * 2) - (size % MP_PREC);
wolfSSL 13:f67a6c6013ca 396
wolfSSL 13:f67a6c6013ca 397 /* reallocate the array a->dp
wolfSSL 13:f67a6c6013ca 398 *
wolfSSL 13:f67a6c6013ca 399 * We store the return in a temporary variable
wolfSSL 13:f67a6c6013ca 400 * in case the operation failed we don't want
wolfSSL 13:f67a6c6013ca 401 * to overwrite the dp member of a.
wolfSSL 13:f67a6c6013ca 402 */
wolfSSL 13:f67a6c6013ca 403 tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size, NULL,
wolfSSL 13:f67a6c6013ca 404 DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 405 if (tmp == NULL) {
wolfSSL 13:f67a6c6013ca 406 /* reallocation failed but "a" is still valid [can be freed] */
wolfSSL 13:f67a6c6013ca 407 return MP_MEM;
wolfSSL 13:f67a6c6013ca 408 }
wolfSSL 13:f67a6c6013ca 409
wolfSSL 13:f67a6c6013ca 410 /* reallocation succeeded so set a->dp */
wolfSSL 13:f67a6c6013ca 411 a->dp = tmp;
wolfSSL 13:f67a6c6013ca 412
wolfSSL 13:f67a6c6013ca 413 /* zero excess digits */
wolfSSL 13:f67a6c6013ca 414 i = a->alloc;
wolfSSL 13:f67a6c6013ca 415 a->alloc = size;
wolfSSL 13:f67a6c6013ca 416 for (; i < a->alloc; i++) {
wolfSSL 13:f67a6c6013ca 417 a->dp[i] = 0;
wolfSSL 13:f67a6c6013ca 418 }
wolfSSL 13:f67a6c6013ca 419 }
wolfSSL 13:f67a6c6013ca 420 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 421 }
wolfSSL 13:f67a6c6013ca 422
wolfSSL 13:f67a6c6013ca 423
wolfSSL 13:f67a6c6013ca 424 /* shift right by a certain bit count (store quotient in c, optional
wolfSSL 13:f67a6c6013ca 425 remainder in d) */
wolfSSL 13:f67a6c6013ca 426 int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
wolfSSL 13:f67a6c6013ca 427 {
wolfSSL 13:f67a6c6013ca 428 int D, res;
wolfSSL 13:f67a6c6013ca 429 mp_int t;
wolfSSL 13:f67a6c6013ca 430
wolfSSL 13:f67a6c6013ca 431
wolfSSL 13:f67a6c6013ca 432 /* if the shift count is <= 0 then we do no work */
wolfSSL 13:f67a6c6013ca 433 if (b <= 0) {
wolfSSL 13:f67a6c6013ca 434 res = mp_copy (a, c);
wolfSSL 13:f67a6c6013ca 435 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 436 mp_zero (d);
wolfSSL 13:f67a6c6013ca 437 }
wolfSSL 13:f67a6c6013ca 438 return res;
wolfSSL 13:f67a6c6013ca 439 }
wolfSSL 13:f67a6c6013ca 440
wolfSSL 13:f67a6c6013ca 441 if ((res = mp_init (&t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 442 return res;
wolfSSL 13:f67a6c6013ca 443 }
wolfSSL 13:f67a6c6013ca 444
wolfSSL 13:f67a6c6013ca 445 /* get the remainder */
wolfSSL 13:f67a6c6013ca 446 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 447 if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 448 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 449 return res;
wolfSSL 13:f67a6c6013ca 450 }
wolfSSL 13:f67a6c6013ca 451 }
wolfSSL 13:f67a6c6013ca 452
wolfSSL 13:f67a6c6013ca 453 /* copy */
wolfSSL 13:f67a6c6013ca 454 if ((res = mp_copy (a, c)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 455 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 456 return res;
wolfSSL 13:f67a6c6013ca 457 }
wolfSSL 13:f67a6c6013ca 458
wolfSSL 13:f67a6c6013ca 459 /* shift by as many digits in the bit count */
wolfSSL 13:f67a6c6013ca 460 if (b >= (int)DIGIT_BIT) {
wolfSSL 13:f67a6c6013ca 461 mp_rshd (c, b / DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 462 }
wolfSSL 13:f67a6c6013ca 463
wolfSSL 13:f67a6c6013ca 464 /* shift any bit count < DIGIT_BIT */
wolfSSL 13:f67a6c6013ca 465 D = (b % DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 466 if (D != 0) {
wolfSSL 13:f67a6c6013ca 467 mp_rshb(c, D);
wolfSSL 13:f67a6c6013ca 468 }
wolfSSL 13:f67a6c6013ca 469 mp_clamp (c);
wolfSSL 13:f67a6c6013ca 470 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 471 mp_exch (&t, d);
wolfSSL 13:f67a6c6013ca 472 }
wolfSSL 13:f67a6c6013ca 473 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 474 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 475 }
wolfSSL 13:f67a6c6013ca 476
wolfSSL 13:f67a6c6013ca 477
wolfSSL 13:f67a6c6013ca 478 /* set to zero */
wolfSSL 13:f67a6c6013ca 479 void mp_zero (mp_int * a)
wolfSSL 13:f67a6c6013ca 480 {
wolfSSL 13:f67a6c6013ca 481 int n;
wolfSSL 13:f67a6c6013ca 482 mp_digit *tmp;
wolfSSL 13:f67a6c6013ca 483
wolfSSL 13:f67a6c6013ca 484 if (a == NULL)
wolfSSL 13:f67a6c6013ca 485 return;
wolfSSL 13:f67a6c6013ca 486
wolfSSL 13:f67a6c6013ca 487 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 488 a->used = 0;
wolfSSL 13:f67a6c6013ca 489
wolfSSL 13:f67a6c6013ca 490 tmp = a->dp;
wolfSSL 13:f67a6c6013ca 491 for (n = 0; n < a->alloc; n++) {
wolfSSL 13:f67a6c6013ca 492 *tmp++ = 0;
wolfSSL 13:f67a6c6013ca 493 }
wolfSSL 13:f67a6c6013ca 494 }
wolfSSL 13:f67a6c6013ca 495
wolfSSL 13:f67a6c6013ca 496
wolfSSL 13:f67a6c6013ca 497 /* trim unused digits
wolfSSL 13:f67a6c6013ca 498 *
wolfSSL 13:f67a6c6013ca 499 * This is used to ensure that leading zero digits are
wolfSSL 13:f67a6c6013ca 500 * trimmed and the leading "used" digit will be non-zero
wolfSSL 13:f67a6c6013ca 501 * Typically very fast. Also fixes the sign if there
wolfSSL 13:f67a6c6013ca 502 * are no more leading digits
wolfSSL 13:f67a6c6013ca 503 */
wolfSSL 13:f67a6c6013ca 504 void mp_clamp (mp_int * a)
wolfSSL 13:f67a6c6013ca 505 {
wolfSSL 13:f67a6c6013ca 506 /* decrease used while the most significant digit is
wolfSSL 13:f67a6c6013ca 507 * zero.
wolfSSL 13:f67a6c6013ca 508 */
wolfSSL 13:f67a6c6013ca 509 while (a->used > 0 && a->dp[a->used - 1] == 0) {
wolfSSL 13:f67a6c6013ca 510 --(a->used);
wolfSSL 13:f67a6c6013ca 511 }
wolfSSL 13:f67a6c6013ca 512
wolfSSL 13:f67a6c6013ca 513 /* reset the sign flag if used == 0 */
wolfSSL 13:f67a6c6013ca 514 if (a->used == 0) {
wolfSSL 13:f67a6c6013ca 515 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 516 }
wolfSSL 13:f67a6c6013ca 517 }
wolfSSL 13:f67a6c6013ca 518
wolfSSL 13:f67a6c6013ca 519
wolfSSL 13:f67a6c6013ca 520 /* swap the elements of two integers, for cases where you can't simply swap the
wolfSSL 13:f67a6c6013ca 521 * mp_int pointers around
wolfSSL 13:f67a6c6013ca 522 */
wolfSSL 13:f67a6c6013ca 523 void mp_exch (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 524 {
wolfSSL 13:f67a6c6013ca 525 mp_int t;
wolfSSL 13:f67a6c6013ca 526
wolfSSL 13:f67a6c6013ca 527 t = *a;
wolfSSL 13:f67a6c6013ca 528 *a = *b;
wolfSSL 13:f67a6c6013ca 529 *b = t;
wolfSSL 13:f67a6c6013ca 530 }
wolfSSL 13:f67a6c6013ca 531
wolfSSL 13:f67a6c6013ca 532
wolfSSL 13:f67a6c6013ca 533 /* shift right a certain number of bits */
wolfSSL 13:f67a6c6013ca 534 void mp_rshb (mp_int *c, int x)
wolfSSL 13:f67a6c6013ca 535 {
wolfSSL 13:f67a6c6013ca 536 mp_digit *tmpc, mask, shift;
wolfSSL 13:f67a6c6013ca 537 mp_digit r, rr;
wolfSSL 13:f67a6c6013ca 538 mp_digit D = x;
wolfSSL 13:f67a6c6013ca 539
wolfSSL 13:f67a6c6013ca 540 /* mask */
wolfSSL 13:f67a6c6013ca 541 mask = (((mp_digit)1) << D) - 1;
wolfSSL 13:f67a6c6013ca 542
wolfSSL 13:f67a6c6013ca 543 /* shift for lsb */
wolfSSL 13:f67a6c6013ca 544 shift = DIGIT_BIT - D;
wolfSSL 13:f67a6c6013ca 545
wolfSSL 13:f67a6c6013ca 546 /* alias */
wolfSSL 13:f67a6c6013ca 547 tmpc = c->dp + (c->used - 1);
wolfSSL 13:f67a6c6013ca 548
wolfSSL 13:f67a6c6013ca 549 /* carry */
wolfSSL 13:f67a6c6013ca 550 r = 0;
wolfSSL 13:f67a6c6013ca 551 for (x = c->used - 1; x >= 0; x--) {
wolfSSL 13:f67a6c6013ca 552 /* get the lower bits of this word in a temp */
wolfSSL 13:f67a6c6013ca 553 rr = *tmpc & mask;
wolfSSL 13:f67a6c6013ca 554
wolfSSL 13:f67a6c6013ca 555 /* shift the current word and mix in the carry bits from previous word */
wolfSSL 13:f67a6c6013ca 556 *tmpc = (*tmpc >> D) | (r << shift);
wolfSSL 13:f67a6c6013ca 557 --tmpc;
wolfSSL 13:f67a6c6013ca 558
wolfSSL 13:f67a6c6013ca 559 /* set the carry to the carry bits of the current word found above */
wolfSSL 13:f67a6c6013ca 560 r = rr;
wolfSSL 13:f67a6c6013ca 561 }
wolfSSL 13:f67a6c6013ca 562 mp_clamp(c);
wolfSSL 13:f67a6c6013ca 563 }
wolfSSL 13:f67a6c6013ca 564
wolfSSL 13:f67a6c6013ca 565
wolfSSL 13:f67a6c6013ca 566 /* shift right a certain amount of digits */
wolfSSL 13:f67a6c6013ca 567 void mp_rshd (mp_int * a, int b)
wolfSSL 13:f67a6c6013ca 568 {
wolfSSL 13:f67a6c6013ca 569 int x;
wolfSSL 13:f67a6c6013ca 570
wolfSSL 13:f67a6c6013ca 571 /* if b <= 0 then ignore it */
wolfSSL 13:f67a6c6013ca 572 if (b <= 0) {
wolfSSL 13:f67a6c6013ca 573 return;
wolfSSL 13:f67a6c6013ca 574 }
wolfSSL 13:f67a6c6013ca 575
wolfSSL 13:f67a6c6013ca 576 /* if b > used then simply zero it and return */
wolfSSL 13:f67a6c6013ca 577 if (a->used <= b) {
wolfSSL 13:f67a6c6013ca 578 mp_zero (a);
wolfSSL 13:f67a6c6013ca 579 return;
wolfSSL 13:f67a6c6013ca 580 }
wolfSSL 13:f67a6c6013ca 581
wolfSSL 13:f67a6c6013ca 582 {
wolfSSL 13:f67a6c6013ca 583 mp_digit *bottom, *top;
wolfSSL 13:f67a6c6013ca 584
wolfSSL 13:f67a6c6013ca 585 /* shift the digits down */
wolfSSL 13:f67a6c6013ca 586
wolfSSL 13:f67a6c6013ca 587 /* bottom */
wolfSSL 13:f67a6c6013ca 588 bottom = a->dp;
wolfSSL 13:f67a6c6013ca 589
wolfSSL 13:f67a6c6013ca 590 /* top [offset into digits] */
wolfSSL 13:f67a6c6013ca 591 top = a->dp + b;
wolfSSL 13:f67a6c6013ca 592
wolfSSL 13:f67a6c6013ca 593 /* this is implemented as a sliding window where
wolfSSL 13:f67a6c6013ca 594 * the window is b-digits long and digits from
wolfSSL 13:f67a6c6013ca 595 * the top of the window are copied to the bottom
wolfSSL 13:f67a6c6013ca 596 *
wolfSSL 13:f67a6c6013ca 597 * e.g.
wolfSSL 13:f67a6c6013ca 598
wolfSSL 13:f67a6c6013ca 599 b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
wolfSSL 13:f67a6c6013ca 600 /\ | ---->
wolfSSL 13:f67a6c6013ca 601 \-------------------/ ---->
wolfSSL 13:f67a6c6013ca 602 */
wolfSSL 13:f67a6c6013ca 603 for (x = 0; x < (a->used - b); x++) {
wolfSSL 13:f67a6c6013ca 604 *bottom++ = *top++;
wolfSSL 13:f67a6c6013ca 605 }
wolfSSL 13:f67a6c6013ca 606
wolfSSL 13:f67a6c6013ca 607 /* zero the top digits */
wolfSSL 13:f67a6c6013ca 608 for (; x < a->used; x++) {
wolfSSL 13:f67a6c6013ca 609 *bottom++ = 0;
wolfSSL 13:f67a6c6013ca 610 }
wolfSSL 13:f67a6c6013ca 611 }
wolfSSL 13:f67a6c6013ca 612
wolfSSL 13:f67a6c6013ca 613 /* remove excess digits */
wolfSSL 13:f67a6c6013ca 614 a->used -= b;
wolfSSL 13:f67a6c6013ca 615 }
wolfSSL 13:f67a6c6013ca 616
wolfSSL 13:f67a6c6013ca 617
wolfSSL 13:f67a6c6013ca 618 /* calc a value mod 2**b */
wolfSSL 13:f67a6c6013ca 619 int mp_mod_2d (mp_int * a, int b, mp_int * c)
wolfSSL 13:f67a6c6013ca 620 {
wolfSSL 13:f67a6c6013ca 621 int x, res;
wolfSSL 13:f67a6c6013ca 622
wolfSSL 13:f67a6c6013ca 623 /* if b is <= 0 then zero the int */
wolfSSL 13:f67a6c6013ca 624 if (b <= 0) {
wolfSSL 13:f67a6c6013ca 625 mp_zero (c);
wolfSSL 13:f67a6c6013ca 626 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 627 }
wolfSSL 13:f67a6c6013ca 628
wolfSSL 13:f67a6c6013ca 629 /* if the modulus is larger than the value than return */
wolfSSL 13:f67a6c6013ca 630 if (b >= (int) (a->used * DIGIT_BIT)) {
wolfSSL 13:f67a6c6013ca 631 res = mp_copy (a, c);
wolfSSL 13:f67a6c6013ca 632 return res;
wolfSSL 13:f67a6c6013ca 633 }
wolfSSL 13:f67a6c6013ca 634
wolfSSL 13:f67a6c6013ca 635 /* copy */
wolfSSL 13:f67a6c6013ca 636 if ((res = mp_copy (a, c)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 637 return res;
wolfSSL 13:f67a6c6013ca 638 }
wolfSSL 13:f67a6c6013ca 639
wolfSSL 13:f67a6c6013ca 640 /* zero digits above the last digit of the modulus */
wolfSSL 13:f67a6c6013ca 641 for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
wolfSSL 13:f67a6c6013ca 642 c->dp[x] = 0;
wolfSSL 13:f67a6c6013ca 643 }
wolfSSL 13:f67a6c6013ca 644 /* clear the digit that is not completely outside/inside the modulus */
wolfSSL 13:f67a6c6013ca 645 c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) <<
wolfSSL 13:f67a6c6013ca 646 (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
wolfSSL 13:f67a6c6013ca 647 mp_clamp (c);
wolfSSL 13:f67a6c6013ca 648 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 649 }
wolfSSL 13:f67a6c6013ca 650
wolfSSL 13:f67a6c6013ca 651
wolfSSL 13:f67a6c6013ca 652 /* reads a unsigned char array, assumes the msb is stored first [big endian] */
wolfSSL 13:f67a6c6013ca 653 int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
wolfSSL 13:f67a6c6013ca 654 {
wolfSSL 13:f67a6c6013ca 655 int res;
wolfSSL 13:f67a6c6013ca 656
wolfSSL 13:f67a6c6013ca 657 /* make sure there are at least two digits */
wolfSSL 13:f67a6c6013ca 658 if (a->alloc < 2) {
wolfSSL 13:f67a6c6013ca 659 if ((res = mp_grow(a, 2)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 660 return res;
wolfSSL 13:f67a6c6013ca 661 }
wolfSSL 13:f67a6c6013ca 662 }
wolfSSL 13:f67a6c6013ca 663
wolfSSL 13:f67a6c6013ca 664 /* zero the int */
wolfSSL 13:f67a6c6013ca 665 mp_zero (a);
wolfSSL 13:f67a6c6013ca 666
wolfSSL 13:f67a6c6013ca 667 /* read the bytes in */
wolfSSL 13:f67a6c6013ca 668 while (c-- > 0) {
wolfSSL 13:f67a6c6013ca 669 if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 670 return res;
wolfSSL 13:f67a6c6013ca 671 }
wolfSSL 13:f67a6c6013ca 672
wolfSSL 13:f67a6c6013ca 673 #ifndef MP_8BIT
wolfSSL 13:f67a6c6013ca 674 a->dp[0] |= *b++;
wolfSSL 13:f67a6c6013ca 675 a->used += 1;
wolfSSL 13:f67a6c6013ca 676 #else
wolfSSL 13:f67a6c6013ca 677 a->dp[0] = (*b & MP_MASK);
wolfSSL 13:f67a6c6013ca 678 a->dp[1] |= ((*b++ >> 7U) & 1);
wolfSSL 13:f67a6c6013ca 679 a->used += 2;
wolfSSL 13:f67a6c6013ca 680 #endif
wolfSSL 13:f67a6c6013ca 681 }
wolfSSL 13:f67a6c6013ca 682 mp_clamp (a);
wolfSSL 13:f67a6c6013ca 683 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 684 }
wolfSSL 13:f67a6c6013ca 685
wolfSSL 13:f67a6c6013ca 686
wolfSSL 13:f67a6c6013ca 687 /* shift left by a certain bit count */
wolfSSL 13:f67a6c6013ca 688 int mp_mul_2d (mp_int * a, int b, mp_int * c)
wolfSSL 13:f67a6c6013ca 689 {
wolfSSL 13:f67a6c6013ca 690 mp_digit d;
wolfSSL 13:f67a6c6013ca 691 int res;
wolfSSL 13:f67a6c6013ca 692
wolfSSL 13:f67a6c6013ca 693 /* copy */
wolfSSL 13:f67a6c6013ca 694 if (a != c) {
wolfSSL 13:f67a6c6013ca 695 if ((res = mp_copy (a, c)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 696 return res;
wolfSSL 13:f67a6c6013ca 697 }
wolfSSL 13:f67a6c6013ca 698 }
wolfSSL 13:f67a6c6013ca 699
wolfSSL 13:f67a6c6013ca 700 if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
wolfSSL 13:f67a6c6013ca 701 if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 702 return res;
wolfSSL 13:f67a6c6013ca 703 }
wolfSSL 13:f67a6c6013ca 704 }
wolfSSL 13:f67a6c6013ca 705
wolfSSL 13:f67a6c6013ca 706 /* shift by as many digits in the bit count */
wolfSSL 13:f67a6c6013ca 707 if (b >= (int)DIGIT_BIT) {
wolfSSL 13:f67a6c6013ca 708 if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 709 return res;
wolfSSL 13:f67a6c6013ca 710 }
wolfSSL 13:f67a6c6013ca 711 }
wolfSSL 13:f67a6c6013ca 712
wolfSSL 13:f67a6c6013ca 713 /* shift any bit count < DIGIT_BIT */
wolfSSL 13:f67a6c6013ca 714 d = (mp_digit) (b % DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 715 if (d != 0) {
wolfSSL 13:f67a6c6013ca 716 mp_digit *tmpc, shift, mask, r, rr;
wolfSSL 13:f67a6c6013ca 717 int x;
wolfSSL 13:f67a6c6013ca 718
wolfSSL 13:f67a6c6013ca 719 /* bitmask for carries */
wolfSSL 13:f67a6c6013ca 720 mask = (((mp_digit)1) << d) - 1;
wolfSSL 13:f67a6c6013ca 721
wolfSSL 13:f67a6c6013ca 722 /* shift for msbs */
wolfSSL 13:f67a6c6013ca 723 shift = DIGIT_BIT - d;
wolfSSL 13:f67a6c6013ca 724
wolfSSL 13:f67a6c6013ca 725 /* alias */
wolfSSL 13:f67a6c6013ca 726 tmpc = c->dp;
wolfSSL 13:f67a6c6013ca 727
wolfSSL 13:f67a6c6013ca 728 /* carry */
wolfSSL 13:f67a6c6013ca 729 r = 0;
wolfSSL 13:f67a6c6013ca 730 for (x = 0; x < c->used; x++) {
wolfSSL 13:f67a6c6013ca 731 /* get the higher bits of the current word */
wolfSSL 13:f67a6c6013ca 732 rr = (*tmpc >> shift) & mask;
wolfSSL 13:f67a6c6013ca 733
wolfSSL 13:f67a6c6013ca 734 /* shift the current word and OR in the carry */
wolfSSL 13:f67a6c6013ca 735 *tmpc = (mp_digit)(((*tmpc << d) | r) & MP_MASK);
wolfSSL 13:f67a6c6013ca 736 ++tmpc;
wolfSSL 13:f67a6c6013ca 737
wolfSSL 13:f67a6c6013ca 738 /* set the carry to the carry bits of the current word */
wolfSSL 13:f67a6c6013ca 739 r = rr;
wolfSSL 13:f67a6c6013ca 740 }
wolfSSL 13:f67a6c6013ca 741
wolfSSL 13:f67a6c6013ca 742 /* set final carry */
wolfSSL 13:f67a6c6013ca 743 if (r != 0) {
wolfSSL 13:f67a6c6013ca 744 c->dp[(c->used)++] = r;
wolfSSL 13:f67a6c6013ca 745 }
wolfSSL 13:f67a6c6013ca 746 }
wolfSSL 13:f67a6c6013ca 747 mp_clamp (c);
wolfSSL 13:f67a6c6013ca 748 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 749 }
wolfSSL 13:f67a6c6013ca 750
wolfSSL 13:f67a6c6013ca 751
wolfSSL 13:f67a6c6013ca 752 /* shift left a certain amount of digits */
wolfSSL 13:f67a6c6013ca 753 int mp_lshd (mp_int * a, int b)
wolfSSL 13:f67a6c6013ca 754 {
wolfSSL 13:f67a6c6013ca 755 int x, res;
wolfSSL 13:f67a6c6013ca 756
wolfSSL 13:f67a6c6013ca 757 /* if its less than zero return */
wolfSSL 13:f67a6c6013ca 758 if (b <= 0) {
wolfSSL 13:f67a6c6013ca 759 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 760 }
wolfSSL 13:f67a6c6013ca 761
wolfSSL 13:f67a6c6013ca 762 /* grow to fit the new digits */
wolfSSL 13:f67a6c6013ca 763 if (a->alloc < a->used + b) {
wolfSSL 13:f67a6c6013ca 764 if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 765 return res;
wolfSSL 13:f67a6c6013ca 766 }
wolfSSL 13:f67a6c6013ca 767 }
wolfSSL 13:f67a6c6013ca 768
wolfSSL 13:f67a6c6013ca 769 {
wolfSSL 13:f67a6c6013ca 770 mp_digit *top, *bottom;
wolfSSL 13:f67a6c6013ca 771
wolfSSL 13:f67a6c6013ca 772 /* increment the used by the shift amount then copy upwards */
wolfSSL 13:f67a6c6013ca 773 a->used += b;
wolfSSL 13:f67a6c6013ca 774
wolfSSL 13:f67a6c6013ca 775 /* top */
wolfSSL 13:f67a6c6013ca 776 top = a->dp + a->used - 1;
wolfSSL 13:f67a6c6013ca 777
wolfSSL 13:f67a6c6013ca 778 /* base */
wolfSSL 13:f67a6c6013ca 779 bottom = a->dp + a->used - 1 - b;
wolfSSL 13:f67a6c6013ca 780
wolfSSL 13:f67a6c6013ca 781 /* much like mp_rshd this is implemented using a sliding window
wolfSSL 13:f67a6c6013ca 782 * except the window goes the other way around. Copying from
wolfSSL 13:f67a6c6013ca 783 * the bottom to the top. see bn_mp_rshd.c for more info.
wolfSSL 13:f67a6c6013ca 784 */
wolfSSL 13:f67a6c6013ca 785 for (x = a->used - 1; x >= b; x--) {
wolfSSL 13:f67a6c6013ca 786 *top-- = *bottom--;
wolfSSL 13:f67a6c6013ca 787 }
wolfSSL 13:f67a6c6013ca 788
wolfSSL 13:f67a6c6013ca 789 /* zero the lower digits */
wolfSSL 13:f67a6c6013ca 790 top = a->dp;
wolfSSL 13:f67a6c6013ca 791 for (x = 0; x < b; x++) {
wolfSSL 13:f67a6c6013ca 792 *top++ = 0;
wolfSSL 13:f67a6c6013ca 793 }
wolfSSL 13:f67a6c6013ca 794 }
wolfSSL 13:f67a6c6013ca 795 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 796 }
wolfSSL 13:f67a6c6013ca 797
wolfSSL 13:f67a6c6013ca 798
wolfSSL 13:f67a6c6013ca 799 /* this is a shell function that calls either the normal or Montgomery
wolfSSL 13:f67a6c6013ca 800 * exptmod functions. Originally the call to the montgomery code was
wolfSSL 13:f67a6c6013ca 801 * embedded in the normal function but that wasted a lot of stack space
wolfSSL 13:f67a6c6013ca 802 * for nothing (since 99% of the time the Montgomery code would be called)
wolfSSL 13:f67a6c6013ca 803 */
wolfSSL 13:f67a6c6013ca 804 #if defined(FREESCALE_LTC_TFM)
wolfSSL 13:f67a6c6013ca 805 int wolfcrypt_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
wolfSSL 13:f67a6c6013ca 806 #else
wolfSSL 13:f67a6c6013ca 807 int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
wolfSSL 13:f67a6c6013ca 808 #endif
wolfSSL 13:f67a6c6013ca 809 {
wolfSSL 13:f67a6c6013ca 810 int dr;
wolfSSL 13:f67a6c6013ca 811
wolfSSL 13:f67a6c6013ca 812 /* modulus P must be positive */
wolfSSL 13:f67a6c6013ca 813 if (P->sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 814 return MP_VAL;
wolfSSL 13:f67a6c6013ca 815 }
wolfSSL 13:f67a6c6013ca 816
wolfSSL 13:f67a6c6013ca 817 /* if exponent X is negative we have to recurse */
wolfSSL 13:f67a6c6013ca 818 if (X->sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 819 #ifdef BN_MP_INVMOD_C
wolfSSL 13:f67a6c6013ca 820 mp_int tmpG, tmpX;
wolfSSL 13:f67a6c6013ca 821 int err;
wolfSSL 13:f67a6c6013ca 822
wolfSSL 13:f67a6c6013ca 823 /* first compute 1/G mod P */
wolfSSL 13:f67a6c6013ca 824 if ((err = mp_init(&tmpG)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 825 return err;
wolfSSL 13:f67a6c6013ca 826 }
wolfSSL 13:f67a6c6013ca 827 if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 828 mp_clear(&tmpG);
wolfSSL 13:f67a6c6013ca 829 return err;
wolfSSL 13:f67a6c6013ca 830 }
wolfSSL 13:f67a6c6013ca 831
wolfSSL 13:f67a6c6013ca 832 /* now get |X| */
wolfSSL 13:f67a6c6013ca 833 if ((err = mp_init(&tmpX)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 834 mp_clear(&tmpG);
wolfSSL 13:f67a6c6013ca 835 return err;
wolfSSL 13:f67a6c6013ca 836 }
wolfSSL 13:f67a6c6013ca 837 if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 838 mp_clear(&tmpG);
wolfSSL 13:f67a6c6013ca 839 mp_clear(&tmpX);
wolfSSL 13:f67a6c6013ca 840 return err;
wolfSSL 13:f67a6c6013ca 841 }
wolfSSL 13:f67a6c6013ca 842
wolfSSL 13:f67a6c6013ca 843 /* and now compute (1/G)**|X| instead of G**X [X < 0] */
wolfSSL 13:f67a6c6013ca 844 err = mp_exptmod(&tmpG, &tmpX, P, Y);
wolfSSL 13:f67a6c6013ca 845 mp_clear(&tmpG);
wolfSSL 13:f67a6c6013ca 846 mp_clear(&tmpX);
wolfSSL 13:f67a6c6013ca 847 return err;
wolfSSL 13:f67a6c6013ca 848 #else
wolfSSL 13:f67a6c6013ca 849 /* no invmod */
wolfSSL 13:f67a6c6013ca 850 return MP_VAL;
wolfSSL 13:f67a6c6013ca 851 #endif
wolfSSL 13:f67a6c6013ca 852 }
wolfSSL 13:f67a6c6013ca 853
wolfSSL 13:f67a6c6013ca 854 /* modified diminished radix reduction */
wolfSSL 13:f67a6c6013ca 855 #if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && \
wolfSSL 13:f67a6c6013ca 856 defined(BN_S_MP_EXPTMOD_C)
wolfSSL 13:f67a6c6013ca 857 if (mp_reduce_is_2k_l(P) == MP_YES) {
wolfSSL 13:f67a6c6013ca 858 return s_mp_exptmod(G, X, P, Y, 1);
wolfSSL 13:f67a6c6013ca 859 }
wolfSSL 13:f67a6c6013ca 860 #endif
wolfSSL 13:f67a6c6013ca 861
wolfSSL 13:f67a6c6013ca 862 #ifdef BN_MP_DR_IS_MODULUS_C
wolfSSL 13:f67a6c6013ca 863 /* is it a DR modulus? */
wolfSSL 13:f67a6c6013ca 864 dr = mp_dr_is_modulus(P);
wolfSSL 13:f67a6c6013ca 865 #else
wolfSSL 13:f67a6c6013ca 866 /* default to no */
wolfSSL 13:f67a6c6013ca 867 dr = 0;
wolfSSL 13:f67a6c6013ca 868 #endif
wolfSSL 13:f67a6c6013ca 869
wolfSSL 13:f67a6c6013ca 870 #ifdef BN_MP_REDUCE_IS_2K_C
wolfSSL 13:f67a6c6013ca 871 /* if not, is it a unrestricted DR modulus? */
wolfSSL 13:f67a6c6013ca 872 if (dr == 0) {
wolfSSL 13:f67a6c6013ca 873 dr = mp_reduce_is_2k(P) << 1;
wolfSSL 13:f67a6c6013ca 874 }
wolfSSL 13:f67a6c6013ca 875 #endif
wolfSSL 13:f67a6c6013ca 876
wolfSSL 13:f67a6c6013ca 877 /* if the modulus is odd or dr != 0 use the montgomery method */
wolfSSL 13:f67a6c6013ca 878 #ifdef BN_MP_EXPTMOD_FAST_C
wolfSSL 13:f67a6c6013ca 879 if (mp_isodd (P) == MP_YES || dr != 0) {
wolfSSL 13:f67a6c6013ca 880 return mp_exptmod_fast (G, X, P, Y, dr);
wolfSSL 13:f67a6c6013ca 881 } else {
wolfSSL 13:f67a6c6013ca 882 #endif
wolfSSL 13:f67a6c6013ca 883 #ifdef BN_S_MP_EXPTMOD_C
wolfSSL 13:f67a6c6013ca 884 /* otherwise use the generic Barrett reduction technique */
wolfSSL 13:f67a6c6013ca 885 return s_mp_exptmod (G, X, P, Y, 0);
wolfSSL 13:f67a6c6013ca 886 #else
wolfSSL 13:f67a6c6013ca 887 /* no exptmod for evens */
wolfSSL 13:f67a6c6013ca 888 return MP_VAL;
wolfSSL 13:f67a6c6013ca 889 #endif
wolfSSL 13:f67a6c6013ca 890 #ifdef BN_MP_EXPTMOD_FAST_C
wolfSSL 13:f67a6c6013ca 891 }
wolfSSL 13:f67a6c6013ca 892 #endif
wolfSSL 13:f67a6c6013ca 893 }
wolfSSL 13:f67a6c6013ca 894
wolfSSL 13:f67a6c6013ca 895
wolfSSL 13:f67a6c6013ca 896 /* b = |a|
wolfSSL 13:f67a6c6013ca 897 *
wolfSSL 13:f67a6c6013ca 898 * Simple function copies the input and fixes the sign to positive
wolfSSL 13:f67a6c6013ca 899 */
wolfSSL 13:f67a6c6013ca 900 int mp_abs (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 901 {
wolfSSL 13:f67a6c6013ca 902 int res;
wolfSSL 13:f67a6c6013ca 903
wolfSSL 13:f67a6c6013ca 904 /* copy a to b */
wolfSSL 13:f67a6c6013ca 905 if (a != b) {
wolfSSL 13:f67a6c6013ca 906 if ((res = mp_copy (a, b)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 907 return res;
wolfSSL 13:f67a6c6013ca 908 }
wolfSSL 13:f67a6c6013ca 909 }
wolfSSL 13:f67a6c6013ca 910
wolfSSL 13:f67a6c6013ca 911 /* force the sign of b to positive */
wolfSSL 13:f67a6c6013ca 912 b->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 913
wolfSSL 13:f67a6c6013ca 914 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 915 }
wolfSSL 13:f67a6c6013ca 916
wolfSSL 13:f67a6c6013ca 917
wolfSSL 13:f67a6c6013ca 918 /* hac 14.61, pp608 */
wolfSSL 13:f67a6c6013ca 919 #if defined(FREESCALE_LTC_TFM)
wolfSSL 13:f67a6c6013ca 920 int wolfcrypt_mp_invmod(mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 921 #else
wolfSSL 13:f67a6c6013ca 922 int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 923 #endif
wolfSSL 13:f67a6c6013ca 924 {
wolfSSL 13:f67a6c6013ca 925 /* b cannot be negative */
wolfSSL 13:f67a6c6013ca 926 if (b->sign == MP_NEG || mp_iszero(b) == MP_YES) {
wolfSSL 13:f67a6c6013ca 927 return MP_VAL;
wolfSSL 13:f67a6c6013ca 928 }
wolfSSL 13:f67a6c6013ca 929
wolfSSL 13:f67a6c6013ca 930 #ifdef BN_FAST_MP_INVMOD_C
wolfSSL 13:f67a6c6013ca 931 /* if the modulus is odd we can use a faster routine instead */
wolfSSL 13:f67a6c6013ca 932 if (mp_isodd (b) == MP_YES) {
wolfSSL 13:f67a6c6013ca 933 return fast_mp_invmod (a, b, c);
wolfSSL 13:f67a6c6013ca 934 }
wolfSSL 13:f67a6c6013ca 935 #endif
wolfSSL 13:f67a6c6013ca 936
wolfSSL 13:f67a6c6013ca 937 #ifdef BN_MP_INVMOD_SLOW_C
wolfSSL 13:f67a6c6013ca 938 return mp_invmod_slow(a, b, c);
wolfSSL 13:f67a6c6013ca 939 #endif
wolfSSL 13:f67a6c6013ca 940 }
wolfSSL 13:f67a6c6013ca 941
wolfSSL 13:f67a6c6013ca 942
wolfSSL 13:f67a6c6013ca 943 /* computes the modular inverse via binary extended euclidean algorithm,
wolfSSL 13:f67a6c6013ca 944 * that is c = 1/a mod b
wolfSSL 13:f67a6c6013ca 945 *
wolfSSL 13:f67a6c6013ca 946 * Based on slow invmod except this is optimized for the case where b is
wolfSSL 13:f67a6c6013ca 947 * odd as per HAC Note 14.64 on pp. 610
wolfSSL 13:f67a6c6013ca 948 */
wolfSSL 13:f67a6c6013ca 949 int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 950 {
wolfSSL 13:f67a6c6013ca 951 mp_int x, y, u, v, B, D;
wolfSSL 13:f67a6c6013ca 952 int res, neg, loop_check = 0;
wolfSSL 13:f67a6c6013ca 953
wolfSSL 13:f67a6c6013ca 954 /* 2. [modified] b must be odd */
wolfSSL 13:f67a6c6013ca 955 if (mp_iseven (b) == MP_YES) {
wolfSSL 13:f67a6c6013ca 956 return MP_VAL;
wolfSSL 13:f67a6c6013ca 957 }
wolfSSL 13:f67a6c6013ca 958
wolfSSL 13:f67a6c6013ca 959 /* init all our temps */
wolfSSL 13:f67a6c6013ca 960 if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 961 return res;
wolfSSL 13:f67a6c6013ca 962 }
wolfSSL 13:f67a6c6013ca 963
wolfSSL 13:f67a6c6013ca 964 /* x == modulus, y == value to invert */
wolfSSL 13:f67a6c6013ca 965 if ((res = mp_copy (b, &x)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 966 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 967 }
wolfSSL 13:f67a6c6013ca 968
wolfSSL 13:f67a6c6013ca 969 /* we need y = |a| */
wolfSSL 13:f67a6c6013ca 970 if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 971 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 972 }
wolfSSL 13:f67a6c6013ca 973
wolfSSL 13:f67a6c6013ca 974 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
wolfSSL 13:f67a6c6013ca 975 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 976 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 977 }
wolfSSL 13:f67a6c6013ca 978 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 979 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 980 }
wolfSSL 13:f67a6c6013ca 981 if ((res = mp_set (&D, 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 982 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 983 }
wolfSSL 13:f67a6c6013ca 984
wolfSSL 13:f67a6c6013ca 985 top:
wolfSSL 13:f67a6c6013ca 986 /* 4. while u is even do */
wolfSSL 13:f67a6c6013ca 987 while (mp_iseven (&u) == MP_YES) {
wolfSSL 13:f67a6c6013ca 988 /* 4.1 u = u/2 */
wolfSSL 13:f67a6c6013ca 989 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 990 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 991 }
wolfSSL 13:f67a6c6013ca 992 /* 4.2 if B is odd then */
wolfSSL 13:f67a6c6013ca 993 if (mp_isodd (&B) == MP_YES) {
wolfSSL 13:f67a6c6013ca 994 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 995 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 996 }
wolfSSL 13:f67a6c6013ca 997 }
wolfSSL 13:f67a6c6013ca 998 /* B = B/2 */
wolfSSL 13:f67a6c6013ca 999 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1000 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1001 }
wolfSSL 13:f67a6c6013ca 1002 }
wolfSSL 13:f67a6c6013ca 1003
wolfSSL 13:f67a6c6013ca 1004 /* 5. while v is even do */
wolfSSL 13:f67a6c6013ca 1005 while (mp_iseven (&v) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1006 /* 5.1 v = v/2 */
wolfSSL 13:f67a6c6013ca 1007 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1008 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1009 }
wolfSSL 13:f67a6c6013ca 1010 /* 5.2 if D is odd then */
wolfSSL 13:f67a6c6013ca 1011 if (mp_isodd (&D) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1012 /* D = (D-x)/2 */
wolfSSL 13:f67a6c6013ca 1013 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1014 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1015 }
wolfSSL 13:f67a6c6013ca 1016 }
wolfSSL 13:f67a6c6013ca 1017 /* D = D/2 */
wolfSSL 13:f67a6c6013ca 1018 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1019 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1020 }
wolfSSL 13:f67a6c6013ca 1021 }
wolfSSL 13:f67a6c6013ca 1022
wolfSSL 13:f67a6c6013ca 1023 /* 6. if u >= v then */
wolfSSL 13:f67a6c6013ca 1024 if (mp_cmp (&u, &v) != MP_LT) {
wolfSSL 13:f67a6c6013ca 1025 /* u = u - v, B = B - D */
wolfSSL 13:f67a6c6013ca 1026 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1027 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1028 }
wolfSSL 13:f67a6c6013ca 1029
wolfSSL 13:f67a6c6013ca 1030 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1031 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1032 }
wolfSSL 13:f67a6c6013ca 1033 } else {
wolfSSL 13:f67a6c6013ca 1034 /* v - v - u, D = D - B */
wolfSSL 13:f67a6c6013ca 1035 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1036 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1037 }
wolfSSL 13:f67a6c6013ca 1038
wolfSSL 13:f67a6c6013ca 1039 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1040 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1041 }
wolfSSL 13:f67a6c6013ca 1042 }
wolfSSL 13:f67a6c6013ca 1043
wolfSSL 13:f67a6c6013ca 1044 /* if not zero goto step 4 */
wolfSSL 13:f67a6c6013ca 1045 if (mp_iszero (&u) == MP_NO) {
wolfSSL 13:f67a6c6013ca 1046 if (++loop_check > 4096) {
wolfSSL 13:f67a6c6013ca 1047 res = MP_VAL;
wolfSSL 13:f67a6c6013ca 1048 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1049 }
wolfSSL 13:f67a6c6013ca 1050 goto top;
wolfSSL 13:f67a6c6013ca 1051 }
wolfSSL 13:f67a6c6013ca 1052
wolfSSL 13:f67a6c6013ca 1053 /* now a = C, b = D, gcd == g*v */
wolfSSL 13:f67a6c6013ca 1054
wolfSSL 13:f67a6c6013ca 1055 /* if v != 1 then there is no inverse */
wolfSSL 13:f67a6c6013ca 1056 if (mp_cmp_d (&v, 1) != MP_EQ) {
wolfSSL 13:f67a6c6013ca 1057 res = MP_VAL;
wolfSSL 13:f67a6c6013ca 1058 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1059 }
wolfSSL 13:f67a6c6013ca 1060
wolfSSL 13:f67a6c6013ca 1061 /* b is now the inverse */
wolfSSL 13:f67a6c6013ca 1062 neg = a->sign;
wolfSSL 13:f67a6c6013ca 1063 while (D.sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 1064 if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1065 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1066 }
wolfSSL 13:f67a6c6013ca 1067 }
wolfSSL 13:f67a6c6013ca 1068 /* too big */
wolfSSL 13:f67a6c6013ca 1069 while (mp_cmp_mag(&D, b) != MP_LT) {
wolfSSL 13:f67a6c6013ca 1070 if ((res = mp_sub(&D, b, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1071 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1072 }
wolfSSL 13:f67a6c6013ca 1073 }
wolfSSL 13:f67a6c6013ca 1074 mp_exch (&D, c);
wolfSSL 13:f67a6c6013ca 1075 c->sign = neg;
wolfSSL 13:f67a6c6013ca 1076 res = MP_OKAY;
wolfSSL 13:f67a6c6013ca 1077
wolfSSL 13:f67a6c6013ca 1078 LBL_ERR:mp_clear(&x);
wolfSSL 13:f67a6c6013ca 1079 mp_clear(&y);
wolfSSL 13:f67a6c6013ca 1080 mp_clear(&u);
wolfSSL 13:f67a6c6013ca 1081 mp_clear(&v);
wolfSSL 13:f67a6c6013ca 1082 mp_clear(&B);
wolfSSL 13:f67a6c6013ca 1083 mp_clear(&D);
wolfSSL 13:f67a6c6013ca 1084 return res;
wolfSSL 13:f67a6c6013ca 1085 }
wolfSSL 13:f67a6c6013ca 1086
wolfSSL 13:f67a6c6013ca 1087
wolfSSL 13:f67a6c6013ca 1088 /* hac 14.61, pp608 */
wolfSSL 13:f67a6c6013ca 1089 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 1090 {
wolfSSL 13:f67a6c6013ca 1091 mp_int x, y, u, v, A, B, C, D;
wolfSSL 13:f67a6c6013ca 1092 int res;
wolfSSL 13:f67a6c6013ca 1093
wolfSSL 13:f67a6c6013ca 1094 /* b cannot be negative */
wolfSSL 13:f67a6c6013ca 1095 if (b->sign == MP_NEG || mp_iszero(b) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1096 return MP_VAL;
wolfSSL 13:f67a6c6013ca 1097 }
wolfSSL 13:f67a6c6013ca 1098
wolfSSL 13:f67a6c6013ca 1099 /* init temps */
wolfSSL 13:f67a6c6013ca 1100 if ((res = mp_init_multi(&x, &y, &u, &v,
wolfSSL 13:f67a6c6013ca 1101 &A, &B)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1102 return res;
wolfSSL 13:f67a6c6013ca 1103 }
wolfSSL 13:f67a6c6013ca 1104
wolfSSL 13:f67a6c6013ca 1105 /* init rest of tmps temps */
wolfSSL 13:f67a6c6013ca 1106 if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1107 mp_clear(&x);
wolfSSL 13:f67a6c6013ca 1108 mp_clear(&y);
wolfSSL 13:f67a6c6013ca 1109 mp_clear(&u);
wolfSSL 13:f67a6c6013ca 1110 mp_clear(&v);
wolfSSL 13:f67a6c6013ca 1111 mp_clear(&A);
wolfSSL 13:f67a6c6013ca 1112 mp_clear(&B);
wolfSSL 13:f67a6c6013ca 1113 return res;
wolfSSL 13:f67a6c6013ca 1114 }
wolfSSL 13:f67a6c6013ca 1115
wolfSSL 13:f67a6c6013ca 1116 /* x = a, y = b */
wolfSSL 13:f67a6c6013ca 1117 if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1118 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1119 }
wolfSSL 13:f67a6c6013ca 1120 if ((res = mp_copy (b, &y)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1121 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1122 }
wolfSSL 13:f67a6c6013ca 1123
wolfSSL 13:f67a6c6013ca 1124 /* 2. [modified] if x,y are both even then return an error! */
wolfSSL 13:f67a6c6013ca 1125 if (mp_iseven (&x) == MP_YES && mp_iseven (&y) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1126 res = MP_VAL;
wolfSSL 13:f67a6c6013ca 1127 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1128 }
wolfSSL 13:f67a6c6013ca 1129
wolfSSL 13:f67a6c6013ca 1130 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
wolfSSL 13:f67a6c6013ca 1131 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1132 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1133 }
wolfSSL 13:f67a6c6013ca 1134 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1135 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1136 }
wolfSSL 13:f67a6c6013ca 1137 if ((res = mp_set (&A, 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1138 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1139 }
wolfSSL 13:f67a6c6013ca 1140 if ((res = mp_set (&D, 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1141 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1142 }
wolfSSL 13:f67a6c6013ca 1143
wolfSSL 13:f67a6c6013ca 1144 top:
wolfSSL 13:f67a6c6013ca 1145 /* 4. while u is even do */
wolfSSL 13:f67a6c6013ca 1146 while (mp_iseven (&u) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1147 /* 4.1 u = u/2 */
wolfSSL 13:f67a6c6013ca 1148 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1149 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1150 }
wolfSSL 13:f67a6c6013ca 1151 /* 4.2 if A or B is odd then */
wolfSSL 13:f67a6c6013ca 1152 if (mp_isodd (&A) == MP_YES || mp_isodd (&B) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1153 /* A = (A+y)/2, B = (B-x)/2 */
wolfSSL 13:f67a6c6013ca 1154 if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1155 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1156 }
wolfSSL 13:f67a6c6013ca 1157 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1158 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1159 }
wolfSSL 13:f67a6c6013ca 1160 }
wolfSSL 13:f67a6c6013ca 1161 /* A = A/2, B = B/2 */
wolfSSL 13:f67a6c6013ca 1162 if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1163 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1164 }
wolfSSL 13:f67a6c6013ca 1165 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1166 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1167 }
wolfSSL 13:f67a6c6013ca 1168 }
wolfSSL 13:f67a6c6013ca 1169
wolfSSL 13:f67a6c6013ca 1170 /* 5. while v is even do */
wolfSSL 13:f67a6c6013ca 1171 while (mp_iseven (&v) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1172 /* 5.1 v = v/2 */
wolfSSL 13:f67a6c6013ca 1173 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1174 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1175 }
wolfSSL 13:f67a6c6013ca 1176 /* 5.2 if C or D is odd then */
wolfSSL 13:f67a6c6013ca 1177 if (mp_isodd (&C) == MP_YES || mp_isodd (&D) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1178 /* C = (C+y)/2, D = (D-x)/2 */
wolfSSL 13:f67a6c6013ca 1179 if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1180 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1181 }
wolfSSL 13:f67a6c6013ca 1182 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1183 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1184 }
wolfSSL 13:f67a6c6013ca 1185 }
wolfSSL 13:f67a6c6013ca 1186 /* C = C/2, D = D/2 */
wolfSSL 13:f67a6c6013ca 1187 if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1188 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1189 }
wolfSSL 13:f67a6c6013ca 1190 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1191 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1192 }
wolfSSL 13:f67a6c6013ca 1193 }
wolfSSL 13:f67a6c6013ca 1194
wolfSSL 13:f67a6c6013ca 1195 /* 6. if u >= v then */
wolfSSL 13:f67a6c6013ca 1196 if (mp_cmp (&u, &v) != MP_LT) {
wolfSSL 13:f67a6c6013ca 1197 /* u = u - v, A = A - C, B = B - D */
wolfSSL 13:f67a6c6013ca 1198 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1199 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1200 }
wolfSSL 13:f67a6c6013ca 1201
wolfSSL 13:f67a6c6013ca 1202 if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1203 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1204 }
wolfSSL 13:f67a6c6013ca 1205
wolfSSL 13:f67a6c6013ca 1206 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1207 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1208 }
wolfSSL 13:f67a6c6013ca 1209 } else {
wolfSSL 13:f67a6c6013ca 1210 /* v - v - u, C = C - A, D = D - B */
wolfSSL 13:f67a6c6013ca 1211 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1212 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1213 }
wolfSSL 13:f67a6c6013ca 1214
wolfSSL 13:f67a6c6013ca 1215 if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1216 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1217 }
wolfSSL 13:f67a6c6013ca 1218
wolfSSL 13:f67a6c6013ca 1219 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1220 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1221 }
wolfSSL 13:f67a6c6013ca 1222 }
wolfSSL 13:f67a6c6013ca 1223
wolfSSL 13:f67a6c6013ca 1224 /* if not zero goto step 4 */
wolfSSL 13:f67a6c6013ca 1225 if (mp_iszero (&u) == MP_NO)
wolfSSL 13:f67a6c6013ca 1226 goto top;
wolfSSL 13:f67a6c6013ca 1227
wolfSSL 13:f67a6c6013ca 1228 /* now a = C, b = D, gcd == g*v */
wolfSSL 13:f67a6c6013ca 1229
wolfSSL 13:f67a6c6013ca 1230 /* if v != 1 then there is no inverse */
wolfSSL 13:f67a6c6013ca 1231 if (mp_cmp_d (&v, 1) != MP_EQ) {
wolfSSL 13:f67a6c6013ca 1232 res = MP_VAL;
wolfSSL 13:f67a6c6013ca 1233 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1234 }
wolfSSL 13:f67a6c6013ca 1235
wolfSSL 13:f67a6c6013ca 1236 /* if its too low */
wolfSSL 13:f67a6c6013ca 1237 while (mp_cmp_d(&C, 0) == MP_LT) {
wolfSSL 13:f67a6c6013ca 1238 if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1239 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1240 }
wolfSSL 13:f67a6c6013ca 1241 }
wolfSSL 13:f67a6c6013ca 1242
wolfSSL 13:f67a6c6013ca 1243 /* too big */
wolfSSL 13:f67a6c6013ca 1244 while (mp_cmp_mag(&C, b) != MP_LT) {
wolfSSL 13:f67a6c6013ca 1245 if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1246 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1247 }
wolfSSL 13:f67a6c6013ca 1248 }
wolfSSL 13:f67a6c6013ca 1249
wolfSSL 13:f67a6c6013ca 1250 /* C is now the inverse */
wolfSSL 13:f67a6c6013ca 1251 mp_exch (&C, c);
wolfSSL 13:f67a6c6013ca 1252 res = MP_OKAY;
wolfSSL 13:f67a6c6013ca 1253 LBL_ERR:mp_clear(&x);
wolfSSL 13:f67a6c6013ca 1254 mp_clear(&y);
wolfSSL 13:f67a6c6013ca 1255 mp_clear(&u);
wolfSSL 13:f67a6c6013ca 1256 mp_clear(&v);
wolfSSL 13:f67a6c6013ca 1257 mp_clear(&A);
wolfSSL 13:f67a6c6013ca 1258 mp_clear(&B);
wolfSSL 13:f67a6c6013ca 1259 mp_clear(&C);
wolfSSL 13:f67a6c6013ca 1260 mp_clear(&D);
wolfSSL 13:f67a6c6013ca 1261 return res;
wolfSSL 13:f67a6c6013ca 1262 }
wolfSSL 13:f67a6c6013ca 1263
wolfSSL 13:f67a6c6013ca 1264
wolfSSL 13:f67a6c6013ca 1265 /* compare magnitude of two ints (unsigned) */
wolfSSL 13:f67a6c6013ca 1266 int mp_cmp_mag (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 1267 {
wolfSSL 13:f67a6c6013ca 1268 int n;
wolfSSL 13:f67a6c6013ca 1269 mp_digit *tmpa, *tmpb;
wolfSSL 13:f67a6c6013ca 1270
wolfSSL 13:f67a6c6013ca 1271 /* compare based on # of non-zero digits */
wolfSSL 13:f67a6c6013ca 1272 if (a->used > b->used) {
wolfSSL 13:f67a6c6013ca 1273 return MP_GT;
wolfSSL 13:f67a6c6013ca 1274 }
wolfSSL 13:f67a6c6013ca 1275
wolfSSL 13:f67a6c6013ca 1276 if (a->used < b->used) {
wolfSSL 13:f67a6c6013ca 1277 return MP_LT;
wolfSSL 13:f67a6c6013ca 1278 }
wolfSSL 13:f67a6c6013ca 1279
wolfSSL 13:f67a6c6013ca 1280 /* alias for a */
wolfSSL 13:f67a6c6013ca 1281 tmpa = a->dp + (a->used - 1);
wolfSSL 13:f67a6c6013ca 1282
wolfSSL 13:f67a6c6013ca 1283 /* alias for b */
wolfSSL 13:f67a6c6013ca 1284 tmpb = b->dp + (a->used - 1);
wolfSSL 13:f67a6c6013ca 1285
wolfSSL 13:f67a6c6013ca 1286 /* compare based on digits */
wolfSSL 13:f67a6c6013ca 1287 for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
wolfSSL 13:f67a6c6013ca 1288 if (*tmpa > *tmpb) {
wolfSSL 13:f67a6c6013ca 1289 return MP_GT;
wolfSSL 13:f67a6c6013ca 1290 }
wolfSSL 13:f67a6c6013ca 1291
wolfSSL 13:f67a6c6013ca 1292 if (*tmpa < *tmpb) {
wolfSSL 13:f67a6c6013ca 1293 return MP_LT;
wolfSSL 13:f67a6c6013ca 1294 }
wolfSSL 13:f67a6c6013ca 1295 }
wolfSSL 13:f67a6c6013ca 1296 return MP_EQ;
wolfSSL 13:f67a6c6013ca 1297 }
wolfSSL 13:f67a6c6013ca 1298
wolfSSL 13:f67a6c6013ca 1299
wolfSSL 13:f67a6c6013ca 1300 /* compare two ints (signed)*/
wolfSSL 13:f67a6c6013ca 1301 int mp_cmp (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 1302 {
wolfSSL 13:f67a6c6013ca 1303 /* compare based on sign */
wolfSSL 13:f67a6c6013ca 1304 if (a->sign != b->sign) {
wolfSSL 13:f67a6c6013ca 1305 if (a->sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 1306 return MP_LT;
wolfSSL 13:f67a6c6013ca 1307 } else {
wolfSSL 13:f67a6c6013ca 1308 return MP_GT;
wolfSSL 13:f67a6c6013ca 1309 }
wolfSSL 13:f67a6c6013ca 1310 }
wolfSSL 13:f67a6c6013ca 1311
wolfSSL 13:f67a6c6013ca 1312 /* compare digits */
wolfSSL 13:f67a6c6013ca 1313 if (a->sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 1314 /* if negative compare opposite direction */
wolfSSL 13:f67a6c6013ca 1315 return mp_cmp_mag(b, a);
wolfSSL 13:f67a6c6013ca 1316 } else {
wolfSSL 13:f67a6c6013ca 1317 return mp_cmp_mag(a, b);
wolfSSL 13:f67a6c6013ca 1318 }
wolfSSL 13:f67a6c6013ca 1319 }
wolfSSL 13:f67a6c6013ca 1320
wolfSSL 13:f67a6c6013ca 1321
wolfSSL 13:f67a6c6013ca 1322 /* compare a digit */
wolfSSL 13:f67a6c6013ca 1323 int mp_cmp_d(mp_int * a, mp_digit b)
wolfSSL 13:f67a6c6013ca 1324 {
wolfSSL 13:f67a6c6013ca 1325 /* special case for zero*/
wolfSSL 13:f67a6c6013ca 1326 if (a->used == 0 && b == 0)
wolfSSL 13:f67a6c6013ca 1327 return MP_EQ;
wolfSSL 13:f67a6c6013ca 1328
wolfSSL 13:f67a6c6013ca 1329 /* compare based on sign */
wolfSSL 13:f67a6c6013ca 1330 if ((b && a->used == 0) || a->sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 1331 return MP_LT;
wolfSSL 13:f67a6c6013ca 1332 }
wolfSSL 13:f67a6c6013ca 1333
wolfSSL 13:f67a6c6013ca 1334 /* compare based on magnitude */
wolfSSL 13:f67a6c6013ca 1335 if (a->used > 1) {
wolfSSL 13:f67a6c6013ca 1336 return MP_GT;
wolfSSL 13:f67a6c6013ca 1337 }
wolfSSL 13:f67a6c6013ca 1338
wolfSSL 13:f67a6c6013ca 1339 /* compare the only digit of a to b */
wolfSSL 13:f67a6c6013ca 1340 if (a->dp[0] > b) {
wolfSSL 13:f67a6c6013ca 1341 return MP_GT;
wolfSSL 13:f67a6c6013ca 1342 } else if (a->dp[0] < b) {
wolfSSL 13:f67a6c6013ca 1343 return MP_LT;
wolfSSL 13:f67a6c6013ca 1344 } else {
wolfSSL 13:f67a6c6013ca 1345 return MP_EQ;
wolfSSL 13:f67a6c6013ca 1346 }
wolfSSL 13:f67a6c6013ca 1347 }
wolfSSL 13:f67a6c6013ca 1348
wolfSSL 13:f67a6c6013ca 1349
wolfSSL 13:f67a6c6013ca 1350 /* set to a digit */
wolfSSL 13:f67a6c6013ca 1351 int mp_set (mp_int * a, mp_digit b)
wolfSSL 13:f67a6c6013ca 1352 {
wolfSSL 13:f67a6c6013ca 1353 int res;
wolfSSL 13:f67a6c6013ca 1354 mp_zero (a);
wolfSSL 13:f67a6c6013ca 1355 res = mp_grow (a, 1);
wolfSSL 13:f67a6c6013ca 1356 if (res == MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1357 a->dp[0] = (mp_digit)(b & MP_MASK);
wolfSSL 13:f67a6c6013ca 1358 a->used = (a->dp[0] != 0) ? 1 : 0;
wolfSSL 13:f67a6c6013ca 1359 }
wolfSSL 13:f67a6c6013ca 1360 return res;
wolfSSL 13:f67a6c6013ca 1361 }
wolfSSL 13:f67a6c6013ca 1362
wolfSSL 13:f67a6c6013ca 1363 /* chek if a bit is set */
wolfSSL 13:f67a6c6013ca 1364 int mp_is_bit_set (mp_int *a, mp_digit b)
wolfSSL 13:f67a6c6013ca 1365 {
wolfSSL 13:f67a6c6013ca 1366 if ((mp_digit)a->used < b/DIGIT_BIT)
wolfSSL 13:f67a6c6013ca 1367 return 0;
wolfSSL 13:f67a6c6013ca 1368
wolfSSL 13:f67a6c6013ca 1369 return (int)((a->dp[b/DIGIT_BIT] >> b%DIGIT_BIT) & (mp_digit)1);
wolfSSL 13:f67a6c6013ca 1370 }
wolfSSL 13:f67a6c6013ca 1371
wolfSSL 13:f67a6c6013ca 1372 /* c = a mod b, 0 <= c < b */
wolfSSL 13:f67a6c6013ca 1373 #if defined(FREESCALE_LTC_TFM)
wolfSSL 13:f67a6c6013ca 1374 int wolfcrypt_mp_mod(mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 1375 #else
wolfSSL 13:f67a6c6013ca 1376 int mp_mod (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 1377 #endif
wolfSSL 13:f67a6c6013ca 1378 {
wolfSSL 13:f67a6c6013ca 1379 mp_int t;
wolfSSL 13:f67a6c6013ca 1380 int res;
wolfSSL 13:f67a6c6013ca 1381
wolfSSL 13:f67a6c6013ca 1382 if ((res = mp_init (&t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1383 return res;
wolfSSL 13:f67a6c6013ca 1384 }
wolfSSL 13:f67a6c6013ca 1385
wolfSSL 13:f67a6c6013ca 1386 if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1387 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 1388 return res;
wolfSSL 13:f67a6c6013ca 1389 }
wolfSSL 13:f67a6c6013ca 1390
wolfSSL 13:f67a6c6013ca 1391 if (t.sign != b->sign) {
wolfSSL 13:f67a6c6013ca 1392 res = mp_add (b, &t, c);
wolfSSL 13:f67a6c6013ca 1393 } else {
wolfSSL 13:f67a6c6013ca 1394 res = MP_OKAY;
wolfSSL 13:f67a6c6013ca 1395 mp_exch (&t, c);
wolfSSL 13:f67a6c6013ca 1396 }
wolfSSL 13:f67a6c6013ca 1397
wolfSSL 13:f67a6c6013ca 1398 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 1399 return res;
wolfSSL 13:f67a6c6013ca 1400 }
wolfSSL 13:f67a6c6013ca 1401
wolfSSL 13:f67a6c6013ca 1402
wolfSSL 13:f67a6c6013ca 1403 /* slower bit-bang division... also smaller */
wolfSSL 13:f67a6c6013ca 1404 int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
wolfSSL 13:f67a6c6013ca 1405 {
wolfSSL 13:f67a6c6013ca 1406 mp_int ta, tb, tq, q;
wolfSSL 13:f67a6c6013ca 1407 int res, n, n2;
wolfSSL 13:f67a6c6013ca 1408
wolfSSL 13:f67a6c6013ca 1409 /* is divisor zero ? */
wolfSSL 13:f67a6c6013ca 1410 if (mp_iszero (b) == MP_YES) {
wolfSSL 13:f67a6c6013ca 1411 return MP_VAL;
wolfSSL 13:f67a6c6013ca 1412 }
wolfSSL 13:f67a6c6013ca 1413
wolfSSL 13:f67a6c6013ca 1414 /* if a < b then q=0, r = a */
wolfSSL 13:f67a6c6013ca 1415 if (mp_cmp_mag (a, b) == MP_LT) {
wolfSSL 13:f67a6c6013ca 1416 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 1417 res = mp_copy (a, d);
wolfSSL 13:f67a6c6013ca 1418 } else {
wolfSSL 13:f67a6c6013ca 1419 res = MP_OKAY;
wolfSSL 13:f67a6c6013ca 1420 }
wolfSSL 13:f67a6c6013ca 1421 if (c != NULL) {
wolfSSL 13:f67a6c6013ca 1422 mp_zero (c);
wolfSSL 13:f67a6c6013ca 1423 }
wolfSSL 13:f67a6c6013ca 1424 return res;
wolfSSL 13:f67a6c6013ca 1425 }
wolfSSL 13:f67a6c6013ca 1426
wolfSSL 13:f67a6c6013ca 1427 /* init our temps */
wolfSSL 13:f67a6c6013ca 1428 if ((res = mp_init_multi(&ta, &tb, &tq, &q, 0, 0)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1429 return res;
wolfSSL 13:f67a6c6013ca 1430 }
wolfSSL 13:f67a6c6013ca 1431
wolfSSL 13:f67a6c6013ca 1432 if ((res = mp_set(&tq, 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1433 return res;
wolfSSL 13:f67a6c6013ca 1434 }
wolfSSL 13:f67a6c6013ca 1435 n = mp_count_bits(a) - mp_count_bits(b);
wolfSSL 13:f67a6c6013ca 1436 if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
wolfSSL 13:f67a6c6013ca 1437 ((res = mp_abs(b, &tb)) != MP_OKAY) ||
wolfSSL 13:f67a6c6013ca 1438 ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
wolfSSL 13:f67a6c6013ca 1439 ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 1440 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1441 }
wolfSSL 13:f67a6c6013ca 1442
wolfSSL 13:f67a6c6013ca 1443 while (n-- >= 0) {
wolfSSL 13:f67a6c6013ca 1444 if (mp_cmp(&tb, &ta) != MP_GT) {
wolfSSL 13:f67a6c6013ca 1445 if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
wolfSSL 13:f67a6c6013ca 1446 ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 1447 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1448 }
wolfSSL 13:f67a6c6013ca 1449 }
wolfSSL 13:f67a6c6013ca 1450 if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
wolfSSL 13:f67a6c6013ca 1451 ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
wolfSSL 13:f67a6c6013ca 1452 goto LBL_ERR;
wolfSSL 13:f67a6c6013ca 1453 }
wolfSSL 13:f67a6c6013ca 1454 }
wolfSSL 13:f67a6c6013ca 1455
wolfSSL 13:f67a6c6013ca 1456 /* now q == quotient and ta == remainder */
wolfSSL 13:f67a6c6013ca 1457 n = a->sign;
wolfSSL 13:f67a6c6013ca 1458 n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
wolfSSL 13:f67a6c6013ca 1459 if (c != NULL) {
wolfSSL 13:f67a6c6013ca 1460 mp_exch(c, &q);
wolfSSL 13:f67a6c6013ca 1461 c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
wolfSSL 13:f67a6c6013ca 1462 }
wolfSSL 13:f67a6c6013ca 1463 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 1464 mp_exch(d, &ta);
wolfSSL 13:f67a6c6013ca 1465 d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
wolfSSL 13:f67a6c6013ca 1466 }
wolfSSL 13:f67a6c6013ca 1467 LBL_ERR:
wolfSSL 13:f67a6c6013ca 1468 mp_clear(&ta);
wolfSSL 13:f67a6c6013ca 1469 mp_clear(&tb);
wolfSSL 13:f67a6c6013ca 1470 mp_clear(&tq);
wolfSSL 13:f67a6c6013ca 1471 mp_clear(&q);
wolfSSL 13:f67a6c6013ca 1472 return res;
wolfSSL 13:f67a6c6013ca 1473 }
wolfSSL 13:f67a6c6013ca 1474
wolfSSL 13:f67a6c6013ca 1475
wolfSSL 13:f67a6c6013ca 1476 /* b = a/2 */
wolfSSL 13:f67a6c6013ca 1477 int mp_div_2(mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 1478 {
wolfSSL 13:f67a6c6013ca 1479 int x, res, oldused;
wolfSSL 13:f67a6c6013ca 1480
wolfSSL 13:f67a6c6013ca 1481 /* copy */
wolfSSL 13:f67a6c6013ca 1482 if (b->alloc < a->used) {
wolfSSL 13:f67a6c6013ca 1483 if ((res = mp_grow (b, a->used)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1484 return res;
wolfSSL 13:f67a6c6013ca 1485 }
wolfSSL 13:f67a6c6013ca 1486 }
wolfSSL 13:f67a6c6013ca 1487
wolfSSL 13:f67a6c6013ca 1488 oldused = b->used;
wolfSSL 13:f67a6c6013ca 1489 b->used = a->used;
wolfSSL 13:f67a6c6013ca 1490 {
wolfSSL 13:f67a6c6013ca 1491 mp_digit r, rr, *tmpa, *tmpb;
wolfSSL 13:f67a6c6013ca 1492
wolfSSL 13:f67a6c6013ca 1493 /* source alias */
wolfSSL 13:f67a6c6013ca 1494 tmpa = a->dp + b->used - 1;
wolfSSL 13:f67a6c6013ca 1495
wolfSSL 13:f67a6c6013ca 1496 /* dest alias */
wolfSSL 13:f67a6c6013ca 1497 tmpb = b->dp + b->used - 1;
wolfSSL 13:f67a6c6013ca 1498
wolfSSL 13:f67a6c6013ca 1499 /* carry */
wolfSSL 13:f67a6c6013ca 1500 r = 0;
wolfSSL 13:f67a6c6013ca 1501 for (x = b->used - 1; x >= 0; x--) {
wolfSSL 13:f67a6c6013ca 1502 /* get the carry for the next iteration */
wolfSSL 13:f67a6c6013ca 1503 rr = *tmpa & 1;
wolfSSL 13:f67a6c6013ca 1504
wolfSSL 13:f67a6c6013ca 1505 /* shift the current digit, add in carry and store */
wolfSSL 13:f67a6c6013ca 1506 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
wolfSSL 13:f67a6c6013ca 1507
wolfSSL 13:f67a6c6013ca 1508 /* forward carry to next iteration */
wolfSSL 13:f67a6c6013ca 1509 r = rr;
wolfSSL 13:f67a6c6013ca 1510 }
wolfSSL 13:f67a6c6013ca 1511
wolfSSL 13:f67a6c6013ca 1512 /* zero excess digits */
wolfSSL 13:f67a6c6013ca 1513 tmpb = b->dp + b->used;
wolfSSL 13:f67a6c6013ca 1514 for (x = b->used; x < oldused; x++) {
wolfSSL 13:f67a6c6013ca 1515 *tmpb++ = 0;
wolfSSL 13:f67a6c6013ca 1516 }
wolfSSL 13:f67a6c6013ca 1517 }
wolfSSL 13:f67a6c6013ca 1518 b->sign = a->sign;
wolfSSL 13:f67a6c6013ca 1519 mp_clamp (b);
wolfSSL 13:f67a6c6013ca 1520 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 1521 }
wolfSSL 13:f67a6c6013ca 1522
wolfSSL 13:f67a6c6013ca 1523
wolfSSL 13:f67a6c6013ca 1524 /* high level addition (handles signs) */
wolfSSL 13:f67a6c6013ca 1525 int mp_add (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 1526 {
wolfSSL 13:f67a6c6013ca 1527 int sa, sb, res;
wolfSSL 13:f67a6c6013ca 1528
wolfSSL 13:f67a6c6013ca 1529 /* get sign of both inputs */
wolfSSL 13:f67a6c6013ca 1530 sa = a->sign;
wolfSSL 13:f67a6c6013ca 1531 sb = b->sign;
wolfSSL 13:f67a6c6013ca 1532
wolfSSL 13:f67a6c6013ca 1533 /* handle two cases, not four */
wolfSSL 13:f67a6c6013ca 1534 if (sa == sb) {
wolfSSL 13:f67a6c6013ca 1535 /* both positive or both negative */
wolfSSL 13:f67a6c6013ca 1536 /* add their magnitudes, copy the sign */
wolfSSL 13:f67a6c6013ca 1537 c->sign = sa;
wolfSSL 13:f67a6c6013ca 1538 res = s_mp_add (a, b, c);
wolfSSL 13:f67a6c6013ca 1539 } else {
wolfSSL 13:f67a6c6013ca 1540 /* one positive, the other negative */
wolfSSL 13:f67a6c6013ca 1541 /* subtract the one with the greater magnitude from */
wolfSSL 13:f67a6c6013ca 1542 /* the one of the lesser magnitude. The result gets */
wolfSSL 13:f67a6c6013ca 1543 /* the sign of the one with the greater magnitude. */
wolfSSL 13:f67a6c6013ca 1544 if (mp_cmp_mag (a, b) == MP_LT) {
wolfSSL 13:f67a6c6013ca 1545 c->sign = sb;
wolfSSL 13:f67a6c6013ca 1546 res = s_mp_sub (b, a, c);
wolfSSL 13:f67a6c6013ca 1547 } else {
wolfSSL 13:f67a6c6013ca 1548 c->sign = sa;
wolfSSL 13:f67a6c6013ca 1549 res = s_mp_sub (a, b, c);
wolfSSL 13:f67a6c6013ca 1550 }
wolfSSL 13:f67a6c6013ca 1551 }
wolfSSL 13:f67a6c6013ca 1552 return res;
wolfSSL 13:f67a6c6013ca 1553 }
wolfSSL 13:f67a6c6013ca 1554
wolfSSL 13:f67a6c6013ca 1555
wolfSSL 13:f67a6c6013ca 1556 /* low level addition, based on HAC pp.594, Algorithm 14.7 */
wolfSSL 13:f67a6c6013ca 1557 int s_mp_add (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 1558 {
wolfSSL 13:f67a6c6013ca 1559 mp_int *x;
wolfSSL 13:f67a6c6013ca 1560 int olduse, res, min_ab, max_ab;
wolfSSL 13:f67a6c6013ca 1561
wolfSSL 13:f67a6c6013ca 1562 /* find sizes, we let |a| <= |b| which means we have to sort
wolfSSL 13:f67a6c6013ca 1563 * them. "x" will point to the input with the most digits
wolfSSL 13:f67a6c6013ca 1564 */
wolfSSL 13:f67a6c6013ca 1565 if (a->used > b->used) {
wolfSSL 13:f67a6c6013ca 1566 min_ab = b->used;
wolfSSL 13:f67a6c6013ca 1567 max_ab = a->used;
wolfSSL 13:f67a6c6013ca 1568 x = a;
wolfSSL 13:f67a6c6013ca 1569 } else {
wolfSSL 13:f67a6c6013ca 1570 min_ab = a->used;
wolfSSL 13:f67a6c6013ca 1571 max_ab = b->used;
wolfSSL 13:f67a6c6013ca 1572 x = b;
wolfSSL 13:f67a6c6013ca 1573 }
wolfSSL 13:f67a6c6013ca 1574
wolfSSL 13:f67a6c6013ca 1575 /* init result */
wolfSSL 13:f67a6c6013ca 1576 if (c->alloc < max_ab + 1) {
wolfSSL 13:f67a6c6013ca 1577 if ((res = mp_grow (c, max_ab + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1578 return res;
wolfSSL 13:f67a6c6013ca 1579 }
wolfSSL 13:f67a6c6013ca 1580 }
wolfSSL 13:f67a6c6013ca 1581
wolfSSL 13:f67a6c6013ca 1582 /* get old used digit count and set new one */
wolfSSL 13:f67a6c6013ca 1583 olduse = c->used;
wolfSSL 13:f67a6c6013ca 1584 c->used = max_ab + 1;
wolfSSL 13:f67a6c6013ca 1585
wolfSSL 13:f67a6c6013ca 1586 {
wolfSSL 13:f67a6c6013ca 1587 mp_digit u, *tmpa, *tmpb, *tmpc;
wolfSSL 13:f67a6c6013ca 1588 int i;
wolfSSL 13:f67a6c6013ca 1589
wolfSSL 13:f67a6c6013ca 1590 /* alias for digit pointers */
wolfSSL 13:f67a6c6013ca 1591
wolfSSL 13:f67a6c6013ca 1592 /* first input */
wolfSSL 13:f67a6c6013ca 1593 tmpa = a->dp;
wolfSSL 13:f67a6c6013ca 1594
wolfSSL 13:f67a6c6013ca 1595 /* second input */
wolfSSL 13:f67a6c6013ca 1596 tmpb = b->dp;
wolfSSL 13:f67a6c6013ca 1597
wolfSSL 13:f67a6c6013ca 1598 /* destination */
wolfSSL 13:f67a6c6013ca 1599 tmpc = c->dp;
wolfSSL 13:f67a6c6013ca 1600
wolfSSL 13:f67a6c6013ca 1601 /* zero the carry */
wolfSSL 13:f67a6c6013ca 1602 u = 0;
wolfSSL 13:f67a6c6013ca 1603 for (i = 0; i < min_ab; i++) {
wolfSSL 13:f67a6c6013ca 1604 /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
wolfSSL 13:f67a6c6013ca 1605 *tmpc = *tmpa++ + *tmpb++ + u;
wolfSSL 13:f67a6c6013ca 1606
wolfSSL 13:f67a6c6013ca 1607 /* U = carry bit of T[i] */
wolfSSL 13:f67a6c6013ca 1608 u = *tmpc >> ((mp_digit)DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 1609
wolfSSL 13:f67a6c6013ca 1610 /* take away carry bit from T[i] */
wolfSSL 13:f67a6c6013ca 1611 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 1612 }
wolfSSL 13:f67a6c6013ca 1613
wolfSSL 13:f67a6c6013ca 1614 /* now copy higher words if any, that is in A+B
wolfSSL 13:f67a6c6013ca 1615 * if A or B has more digits add those in
wolfSSL 13:f67a6c6013ca 1616 */
wolfSSL 13:f67a6c6013ca 1617 if (min_ab != max_ab) {
wolfSSL 13:f67a6c6013ca 1618 for (; i < max_ab; i++) {
wolfSSL 13:f67a6c6013ca 1619 /* T[i] = X[i] + U */
wolfSSL 13:f67a6c6013ca 1620 *tmpc = x->dp[i] + u;
wolfSSL 13:f67a6c6013ca 1621
wolfSSL 13:f67a6c6013ca 1622 /* U = carry bit of T[i] */
wolfSSL 13:f67a6c6013ca 1623 u = *tmpc >> ((mp_digit)DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 1624
wolfSSL 13:f67a6c6013ca 1625 /* take away carry bit from T[i] */
wolfSSL 13:f67a6c6013ca 1626 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 1627 }
wolfSSL 13:f67a6c6013ca 1628 }
wolfSSL 13:f67a6c6013ca 1629
wolfSSL 13:f67a6c6013ca 1630 /* add carry */
wolfSSL 13:f67a6c6013ca 1631 *tmpc++ = u;
wolfSSL 13:f67a6c6013ca 1632
wolfSSL 13:f67a6c6013ca 1633 /* clear digits above olduse */
wolfSSL 13:f67a6c6013ca 1634 for (i = c->used; i < olduse; i++) {
wolfSSL 13:f67a6c6013ca 1635 *tmpc++ = 0;
wolfSSL 13:f67a6c6013ca 1636 }
wolfSSL 13:f67a6c6013ca 1637 }
wolfSSL 13:f67a6c6013ca 1638
wolfSSL 13:f67a6c6013ca 1639 mp_clamp (c);
wolfSSL 13:f67a6c6013ca 1640 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 1641 }
wolfSSL 13:f67a6c6013ca 1642
wolfSSL 13:f67a6c6013ca 1643
wolfSSL 13:f67a6c6013ca 1644 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
wolfSSL 13:f67a6c6013ca 1645 int s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 1646 {
wolfSSL 13:f67a6c6013ca 1647 int olduse, res, min_b, max_a;
wolfSSL 13:f67a6c6013ca 1648
wolfSSL 13:f67a6c6013ca 1649 /* find sizes */
wolfSSL 13:f67a6c6013ca 1650 min_b = b->used;
wolfSSL 13:f67a6c6013ca 1651 max_a = a->used;
wolfSSL 13:f67a6c6013ca 1652
wolfSSL 13:f67a6c6013ca 1653 /* init result */
wolfSSL 13:f67a6c6013ca 1654 if (c->alloc < max_a) {
wolfSSL 13:f67a6c6013ca 1655 if ((res = mp_grow (c, max_a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1656 return res;
wolfSSL 13:f67a6c6013ca 1657 }
wolfSSL 13:f67a6c6013ca 1658 }
wolfSSL 13:f67a6c6013ca 1659
wolfSSL 13:f67a6c6013ca 1660 /* sanity check on destination */
wolfSSL 13:f67a6c6013ca 1661 if (c->dp == NULL)
wolfSSL 13:f67a6c6013ca 1662 return MP_VAL;
wolfSSL 13:f67a6c6013ca 1663
wolfSSL 13:f67a6c6013ca 1664 olduse = c->used;
wolfSSL 13:f67a6c6013ca 1665 c->used = max_a;
wolfSSL 13:f67a6c6013ca 1666
wolfSSL 13:f67a6c6013ca 1667 {
wolfSSL 13:f67a6c6013ca 1668 mp_digit u, *tmpa, *tmpb, *tmpc;
wolfSSL 13:f67a6c6013ca 1669 int i;
wolfSSL 13:f67a6c6013ca 1670
wolfSSL 13:f67a6c6013ca 1671 /* alias for digit pointers */
wolfSSL 13:f67a6c6013ca 1672 tmpa = a->dp;
wolfSSL 13:f67a6c6013ca 1673 tmpb = b->dp;
wolfSSL 13:f67a6c6013ca 1674 tmpc = c->dp;
wolfSSL 13:f67a6c6013ca 1675
wolfSSL 13:f67a6c6013ca 1676 /* set carry to zero */
wolfSSL 13:f67a6c6013ca 1677 u = 0;
wolfSSL 13:f67a6c6013ca 1678 for (i = 0; i < min_b; i++) {
wolfSSL 13:f67a6c6013ca 1679 /* T[i] = A[i] - B[i] - U */
wolfSSL 13:f67a6c6013ca 1680 *tmpc = *tmpa++ - *tmpb++ - u;
wolfSSL 13:f67a6c6013ca 1681
wolfSSL 13:f67a6c6013ca 1682 /* U = carry bit of T[i]
wolfSSL 13:f67a6c6013ca 1683 * Note this saves performing an AND operation since
wolfSSL 13:f67a6c6013ca 1684 * if a carry does occur it will propagate all the way to the
wolfSSL 13:f67a6c6013ca 1685 * MSB. As a result a single shift is enough to get the carry
wolfSSL 13:f67a6c6013ca 1686 */
wolfSSL 13:f67a6c6013ca 1687 u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
wolfSSL 13:f67a6c6013ca 1688
wolfSSL 13:f67a6c6013ca 1689 /* Clear carry from T[i] */
wolfSSL 13:f67a6c6013ca 1690 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 1691 }
wolfSSL 13:f67a6c6013ca 1692
wolfSSL 13:f67a6c6013ca 1693 /* now copy higher words if any, e.g. if A has more digits than B */
wolfSSL 13:f67a6c6013ca 1694 for (; i < max_a; i++) {
wolfSSL 13:f67a6c6013ca 1695 /* T[i] = A[i] - U */
wolfSSL 13:f67a6c6013ca 1696 *tmpc = *tmpa++ - u;
wolfSSL 13:f67a6c6013ca 1697
wolfSSL 13:f67a6c6013ca 1698 /* U = carry bit of T[i] */
wolfSSL 13:f67a6c6013ca 1699 u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
wolfSSL 13:f67a6c6013ca 1700
wolfSSL 13:f67a6c6013ca 1701 /* Clear carry from T[i] */
wolfSSL 13:f67a6c6013ca 1702 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 1703 }
wolfSSL 13:f67a6c6013ca 1704
wolfSSL 13:f67a6c6013ca 1705 /* clear digits above used (since we may not have grown result above) */
wolfSSL 13:f67a6c6013ca 1706 for (i = c->used; i < olduse; i++) {
wolfSSL 13:f67a6c6013ca 1707 *tmpc++ = 0;
wolfSSL 13:f67a6c6013ca 1708 }
wolfSSL 13:f67a6c6013ca 1709 }
wolfSSL 13:f67a6c6013ca 1710
wolfSSL 13:f67a6c6013ca 1711 mp_clamp (c);
wolfSSL 13:f67a6c6013ca 1712 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 1713 }
wolfSSL 13:f67a6c6013ca 1714
wolfSSL 13:f67a6c6013ca 1715
wolfSSL 13:f67a6c6013ca 1716 /* high level subtraction (handles signs) */
wolfSSL 13:f67a6c6013ca 1717 int mp_sub (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 1718 {
wolfSSL 13:f67a6c6013ca 1719 int sa, sb, res;
wolfSSL 13:f67a6c6013ca 1720
wolfSSL 13:f67a6c6013ca 1721 sa = a->sign;
wolfSSL 13:f67a6c6013ca 1722 sb = b->sign;
wolfSSL 13:f67a6c6013ca 1723
wolfSSL 13:f67a6c6013ca 1724 if (sa != sb) {
wolfSSL 13:f67a6c6013ca 1725 /* subtract a negative from a positive, OR */
wolfSSL 13:f67a6c6013ca 1726 /* subtract a positive from a negative. */
wolfSSL 13:f67a6c6013ca 1727 /* In either case, ADD their magnitudes, */
wolfSSL 13:f67a6c6013ca 1728 /* and use the sign of the first number. */
wolfSSL 13:f67a6c6013ca 1729 c->sign = sa;
wolfSSL 13:f67a6c6013ca 1730 res = s_mp_add (a, b, c);
wolfSSL 13:f67a6c6013ca 1731 } else {
wolfSSL 13:f67a6c6013ca 1732 /* subtract a positive from a positive, OR */
wolfSSL 13:f67a6c6013ca 1733 /* subtract a negative from a negative. */
wolfSSL 13:f67a6c6013ca 1734 /* First, take the difference between their */
wolfSSL 13:f67a6c6013ca 1735 /* magnitudes, then... */
wolfSSL 13:f67a6c6013ca 1736 if (mp_cmp_mag (a, b) != MP_LT) {
wolfSSL 13:f67a6c6013ca 1737 /* Copy the sign from the first */
wolfSSL 13:f67a6c6013ca 1738 c->sign = sa;
wolfSSL 13:f67a6c6013ca 1739 /* The first has a larger or equal magnitude */
wolfSSL 13:f67a6c6013ca 1740 res = s_mp_sub (a, b, c);
wolfSSL 13:f67a6c6013ca 1741 } else {
wolfSSL 13:f67a6c6013ca 1742 /* The result has the *opposite* sign from */
wolfSSL 13:f67a6c6013ca 1743 /* the first number. */
wolfSSL 13:f67a6c6013ca 1744 c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
wolfSSL 13:f67a6c6013ca 1745 /* The second has a larger magnitude */
wolfSSL 13:f67a6c6013ca 1746 res = s_mp_sub (b, a, c);
wolfSSL 13:f67a6c6013ca 1747 }
wolfSSL 13:f67a6c6013ca 1748 }
wolfSSL 13:f67a6c6013ca 1749 return res;
wolfSSL 13:f67a6c6013ca 1750 }
wolfSSL 13:f67a6c6013ca 1751
wolfSSL 13:f67a6c6013ca 1752
wolfSSL 13:f67a6c6013ca 1753 /* determines if reduce_2k_l can be used */
wolfSSL 13:f67a6c6013ca 1754 int mp_reduce_is_2k_l(mp_int *a)
wolfSSL 13:f67a6c6013ca 1755 {
wolfSSL 13:f67a6c6013ca 1756 int ix, iy;
wolfSSL 13:f67a6c6013ca 1757
wolfSSL 13:f67a6c6013ca 1758 if (a->used == 0) {
wolfSSL 13:f67a6c6013ca 1759 return MP_NO;
wolfSSL 13:f67a6c6013ca 1760 } else if (a->used == 1) {
wolfSSL 13:f67a6c6013ca 1761 return MP_YES;
wolfSSL 13:f67a6c6013ca 1762 } else if (a->used > 1) {
wolfSSL 13:f67a6c6013ca 1763 /* if more than half of the digits are -1 we're sold */
wolfSSL 13:f67a6c6013ca 1764 for (iy = ix = 0; ix < a->used; ix++) {
wolfSSL 13:f67a6c6013ca 1765 if (a->dp[ix] == MP_MASK) {
wolfSSL 13:f67a6c6013ca 1766 ++iy;
wolfSSL 13:f67a6c6013ca 1767 }
wolfSSL 13:f67a6c6013ca 1768 }
wolfSSL 13:f67a6c6013ca 1769 return (iy >= (a->used/2)) ? MP_YES : MP_NO;
wolfSSL 13:f67a6c6013ca 1770
wolfSSL 13:f67a6c6013ca 1771 }
wolfSSL 13:f67a6c6013ca 1772 return MP_NO;
wolfSSL 13:f67a6c6013ca 1773 }
wolfSSL 13:f67a6c6013ca 1774
wolfSSL 13:f67a6c6013ca 1775
wolfSSL 13:f67a6c6013ca 1776 /* determines if mp_reduce_2k can be used */
wolfSSL 13:f67a6c6013ca 1777 int mp_reduce_is_2k(mp_int *a)
wolfSSL 13:f67a6c6013ca 1778 {
wolfSSL 13:f67a6c6013ca 1779 int ix, iy, iw;
wolfSSL 13:f67a6c6013ca 1780 mp_digit iz;
wolfSSL 13:f67a6c6013ca 1781
wolfSSL 13:f67a6c6013ca 1782 if (a->used == 0) {
wolfSSL 13:f67a6c6013ca 1783 return MP_NO;
wolfSSL 13:f67a6c6013ca 1784 } else if (a->used == 1) {
wolfSSL 13:f67a6c6013ca 1785 return MP_YES;
wolfSSL 13:f67a6c6013ca 1786 } else if (a->used > 1) {
wolfSSL 13:f67a6c6013ca 1787 iy = mp_count_bits(a);
wolfSSL 13:f67a6c6013ca 1788 iz = 1;
wolfSSL 13:f67a6c6013ca 1789 iw = 1;
wolfSSL 13:f67a6c6013ca 1790
wolfSSL 13:f67a6c6013ca 1791 /* Test every bit from the second digit up, must be 1 */
wolfSSL 13:f67a6c6013ca 1792 for (ix = DIGIT_BIT; ix < iy; ix++) {
wolfSSL 13:f67a6c6013ca 1793 if ((a->dp[iw] & iz) == 0) {
wolfSSL 13:f67a6c6013ca 1794 return MP_NO;
wolfSSL 13:f67a6c6013ca 1795 }
wolfSSL 13:f67a6c6013ca 1796 iz <<= 1;
wolfSSL 13:f67a6c6013ca 1797 if (iz > (mp_digit)MP_MASK) {
wolfSSL 13:f67a6c6013ca 1798 ++iw;
wolfSSL 13:f67a6c6013ca 1799 iz = 1;
wolfSSL 13:f67a6c6013ca 1800 }
wolfSSL 13:f67a6c6013ca 1801 }
wolfSSL 13:f67a6c6013ca 1802 }
wolfSSL 13:f67a6c6013ca 1803 return MP_YES;
wolfSSL 13:f67a6c6013ca 1804 }
wolfSSL 13:f67a6c6013ca 1805
wolfSSL 13:f67a6c6013ca 1806
wolfSSL 13:f67a6c6013ca 1807 /* determines if a number is a valid DR modulus */
wolfSSL 13:f67a6c6013ca 1808 int mp_dr_is_modulus(mp_int *a)
wolfSSL 13:f67a6c6013ca 1809 {
wolfSSL 13:f67a6c6013ca 1810 int ix;
wolfSSL 13:f67a6c6013ca 1811
wolfSSL 13:f67a6c6013ca 1812 /* must be at least two digits */
wolfSSL 13:f67a6c6013ca 1813 if (a->used < 2) {
wolfSSL 13:f67a6c6013ca 1814 return 0;
wolfSSL 13:f67a6c6013ca 1815 }
wolfSSL 13:f67a6c6013ca 1816
wolfSSL 13:f67a6c6013ca 1817 /* must be of the form b**k - a [a <= b] so all
wolfSSL 13:f67a6c6013ca 1818 * but the first digit must be equal to -1 (mod b).
wolfSSL 13:f67a6c6013ca 1819 */
wolfSSL 13:f67a6c6013ca 1820 for (ix = 1; ix < a->used; ix++) {
wolfSSL 13:f67a6c6013ca 1821 if (a->dp[ix] != MP_MASK) {
wolfSSL 13:f67a6c6013ca 1822 return 0;
wolfSSL 13:f67a6c6013ca 1823 }
wolfSSL 13:f67a6c6013ca 1824 }
wolfSSL 13:f67a6c6013ca 1825 return 1;
wolfSSL 13:f67a6c6013ca 1826 }
wolfSSL 13:f67a6c6013ca 1827
wolfSSL 13:f67a6c6013ca 1828
wolfSSL 13:f67a6c6013ca 1829 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
wolfSSL 13:f67a6c6013ca 1830 *
wolfSSL 13:f67a6c6013ca 1831 * Uses a left-to-right k-ary sliding window to compute the modular
wolfSSL 13:f67a6c6013ca 1832 * exponentiation.
wolfSSL 13:f67a6c6013ca 1833 * The value of k changes based on the size of the exponent.
wolfSSL 13:f67a6c6013ca 1834 *
wolfSSL 13:f67a6c6013ca 1835 * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
wolfSSL 13:f67a6c6013ca 1836 */
wolfSSL 13:f67a6c6013ca 1837
wolfSSL 13:f67a6c6013ca 1838 #ifdef MP_LOW_MEM
wolfSSL 13:f67a6c6013ca 1839 #define TAB_SIZE 32
wolfSSL 13:f67a6c6013ca 1840 #else
wolfSSL 13:f67a6c6013ca 1841 #define TAB_SIZE 256
wolfSSL 13:f67a6c6013ca 1842 #endif
wolfSSL 13:f67a6c6013ca 1843
wolfSSL 13:f67a6c6013ca 1844 int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
wolfSSL 13:f67a6c6013ca 1845 int redmode)
wolfSSL 13:f67a6c6013ca 1846 {
wolfSSL 13:f67a6c6013ca 1847 mp_int res;
wolfSSL 13:f67a6c6013ca 1848 mp_digit buf, mp;
wolfSSL 13:f67a6c6013ca 1849 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
wolfSSL 13:f67a6c6013ca 1850 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 1851 mp_int* M = NULL;
wolfSSL 13:f67a6c6013ca 1852 #else
wolfSSL 13:f67a6c6013ca 1853 mp_int M[TAB_SIZE];
wolfSSL 13:f67a6c6013ca 1854 #endif
wolfSSL 13:f67a6c6013ca 1855 /* use a pointer to the reduction algorithm. This allows us to use
wolfSSL 13:f67a6c6013ca 1856 * one of many reduction algorithms without modding the guts of
wolfSSL 13:f67a6c6013ca 1857 * the code with if statements everywhere.
wolfSSL 13:f67a6c6013ca 1858 */
wolfSSL 13:f67a6c6013ca 1859 int (*redux)(mp_int*,mp_int*,mp_digit);
wolfSSL 13:f67a6c6013ca 1860
wolfSSL 13:f67a6c6013ca 1861 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 1862 M = (mp_int*) XMALLOC(sizeof(mp_int) * TAB_SIZE, NULL,
wolfSSL 13:f67a6c6013ca 1863 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 13:f67a6c6013ca 1864 if (M == NULL)
wolfSSL 13:f67a6c6013ca 1865 return MP_MEM;
wolfSSL 13:f67a6c6013ca 1866 #endif
wolfSSL 13:f67a6c6013ca 1867
wolfSSL 13:f67a6c6013ca 1868 /* find window size */
wolfSSL 13:f67a6c6013ca 1869 x = mp_count_bits (X);
wolfSSL 13:f67a6c6013ca 1870 if (x <= 7) {
wolfSSL 13:f67a6c6013ca 1871 winsize = 2;
wolfSSL 13:f67a6c6013ca 1872 } else if (x <= 36) {
wolfSSL 13:f67a6c6013ca 1873 winsize = 3;
wolfSSL 13:f67a6c6013ca 1874 } else if (x <= 140) {
wolfSSL 13:f67a6c6013ca 1875 winsize = 4;
wolfSSL 13:f67a6c6013ca 1876 } else if (x <= 450) {
wolfSSL 13:f67a6c6013ca 1877 winsize = 5;
wolfSSL 13:f67a6c6013ca 1878 } else if (x <= 1303) {
wolfSSL 13:f67a6c6013ca 1879 winsize = 6;
wolfSSL 13:f67a6c6013ca 1880 } else if (x <= 3529) {
wolfSSL 13:f67a6c6013ca 1881 winsize = 7;
wolfSSL 13:f67a6c6013ca 1882 } else {
wolfSSL 13:f67a6c6013ca 1883 winsize = 8;
wolfSSL 13:f67a6c6013ca 1884 }
wolfSSL 13:f67a6c6013ca 1885
wolfSSL 13:f67a6c6013ca 1886 #ifdef MP_LOW_MEM
wolfSSL 13:f67a6c6013ca 1887 if (winsize > 5) {
wolfSSL 13:f67a6c6013ca 1888 winsize = 5;
wolfSSL 13:f67a6c6013ca 1889 }
wolfSSL 13:f67a6c6013ca 1890 #endif
wolfSSL 13:f67a6c6013ca 1891
wolfSSL 13:f67a6c6013ca 1892 /* init M array */
wolfSSL 13:f67a6c6013ca 1893 /* init first cell */
wolfSSL 13:f67a6c6013ca 1894 if ((err = mp_init(&M[1])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1895 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 1896 XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 13:f67a6c6013ca 1897 #endif
wolfSSL 13:f67a6c6013ca 1898
wolfSSL 13:f67a6c6013ca 1899 return err;
wolfSSL 13:f67a6c6013ca 1900 }
wolfSSL 13:f67a6c6013ca 1901
wolfSSL 13:f67a6c6013ca 1902 /* now init the second half of the array */
wolfSSL 13:f67a6c6013ca 1903 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
wolfSSL 13:f67a6c6013ca 1904 if ((err = mp_init(&M[x])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1905 for (y = 1<<(winsize-1); y < x; y++) {
wolfSSL 13:f67a6c6013ca 1906 mp_clear (&M[y]);
wolfSSL 13:f67a6c6013ca 1907 }
wolfSSL 13:f67a6c6013ca 1908 mp_clear(&M[1]);
wolfSSL 13:f67a6c6013ca 1909
wolfSSL 13:f67a6c6013ca 1910 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 1911 XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 13:f67a6c6013ca 1912 #endif
wolfSSL 13:f67a6c6013ca 1913
wolfSSL 13:f67a6c6013ca 1914 return err;
wolfSSL 13:f67a6c6013ca 1915 }
wolfSSL 13:f67a6c6013ca 1916 }
wolfSSL 13:f67a6c6013ca 1917
wolfSSL 13:f67a6c6013ca 1918 /* determine and setup reduction code */
wolfSSL 13:f67a6c6013ca 1919 if (redmode == 0) {
wolfSSL 13:f67a6c6013ca 1920 #ifdef BN_MP_MONTGOMERY_SETUP_C
wolfSSL 13:f67a6c6013ca 1921 /* now setup montgomery */
wolfSSL 13:f67a6c6013ca 1922 if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1923 goto LBL_M;
wolfSSL 13:f67a6c6013ca 1924 }
wolfSSL 13:f67a6c6013ca 1925 #else
wolfSSL 13:f67a6c6013ca 1926 err = MP_VAL;
wolfSSL 13:f67a6c6013ca 1927 goto LBL_M;
wolfSSL 13:f67a6c6013ca 1928 #endif
wolfSSL 13:f67a6c6013ca 1929
wolfSSL 13:f67a6c6013ca 1930 /* automatically pick the comba one if available (saves quite a few
wolfSSL 13:f67a6c6013ca 1931 calls/ifs) */
wolfSSL 13:f67a6c6013ca 1932 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
wolfSSL 13:f67a6c6013ca 1933 if (((P->used * 2 + 1) < MP_WARRAY) &&
wolfSSL 13:f67a6c6013ca 1934 P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
wolfSSL 13:f67a6c6013ca 1935 redux = fast_mp_montgomery_reduce;
wolfSSL 13:f67a6c6013ca 1936 } else
wolfSSL 13:f67a6c6013ca 1937 #endif
wolfSSL 13:f67a6c6013ca 1938 {
wolfSSL 13:f67a6c6013ca 1939 #ifdef BN_MP_MONTGOMERY_REDUCE_C
wolfSSL 13:f67a6c6013ca 1940 /* use slower baseline Montgomery method */
wolfSSL 13:f67a6c6013ca 1941 redux = mp_montgomery_reduce;
wolfSSL 13:f67a6c6013ca 1942 #else
wolfSSL 13:f67a6c6013ca 1943 err = MP_VAL;
wolfSSL 13:f67a6c6013ca 1944 goto LBL_M;
wolfSSL 13:f67a6c6013ca 1945 #endif
wolfSSL 13:f67a6c6013ca 1946 }
wolfSSL 13:f67a6c6013ca 1947 } else if (redmode == 1) {
wolfSSL 13:f67a6c6013ca 1948 #if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
wolfSSL 13:f67a6c6013ca 1949 /* setup DR reduction for moduli of the form B**k - b */
wolfSSL 13:f67a6c6013ca 1950 mp_dr_setup(P, &mp);
wolfSSL 13:f67a6c6013ca 1951 redux = mp_dr_reduce;
wolfSSL 13:f67a6c6013ca 1952 #else
wolfSSL 13:f67a6c6013ca 1953 err = MP_VAL;
wolfSSL 13:f67a6c6013ca 1954 goto LBL_M;
wolfSSL 13:f67a6c6013ca 1955 #endif
wolfSSL 13:f67a6c6013ca 1956 } else {
wolfSSL 13:f67a6c6013ca 1957 #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
wolfSSL 13:f67a6c6013ca 1958 /* setup DR reduction for moduli of the form 2**k - b */
wolfSSL 13:f67a6c6013ca 1959 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1960 goto LBL_M;
wolfSSL 13:f67a6c6013ca 1961 }
wolfSSL 13:f67a6c6013ca 1962 redux = mp_reduce_2k;
wolfSSL 13:f67a6c6013ca 1963 #else
wolfSSL 13:f67a6c6013ca 1964 err = MP_VAL;
wolfSSL 13:f67a6c6013ca 1965 goto LBL_M;
wolfSSL 13:f67a6c6013ca 1966 #endif
wolfSSL 13:f67a6c6013ca 1967 }
wolfSSL 13:f67a6c6013ca 1968
wolfSSL 13:f67a6c6013ca 1969 /* setup result */
wolfSSL 13:f67a6c6013ca 1970 if ((err = mp_init (&res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1971 goto LBL_M;
wolfSSL 13:f67a6c6013ca 1972 }
wolfSSL 13:f67a6c6013ca 1973
wolfSSL 13:f67a6c6013ca 1974 /* create M table
wolfSSL 13:f67a6c6013ca 1975 *
wolfSSL 13:f67a6c6013ca 1976
wolfSSL 13:f67a6c6013ca 1977 *
wolfSSL 13:f67a6c6013ca 1978 * The first half of the table is not computed though accept for M[0] and M[1]
wolfSSL 13:f67a6c6013ca 1979 */
wolfSSL 13:f67a6c6013ca 1980
wolfSSL 13:f67a6c6013ca 1981 if (redmode == 0) {
wolfSSL 13:f67a6c6013ca 1982 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
wolfSSL 13:f67a6c6013ca 1983 /* now we need R mod m */
wolfSSL 13:f67a6c6013ca 1984 if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1985 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 1986 }
wolfSSL 13:f67a6c6013ca 1987 #else
wolfSSL 13:f67a6c6013ca 1988 err = MP_VAL;
wolfSSL 13:f67a6c6013ca 1989 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 1990 #endif
wolfSSL 13:f67a6c6013ca 1991
wolfSSL 13:f67a6c6013ca 1992 /* now set M[1] to G * R mod m */
wolfSSL 13:f67a6c6013ca 1993 if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1994 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 1995 }
wolfSSL 13:f67a6c6013ca 1996 } else {
wolfSSL 13:f67a6c6013ca 1997 if ((err = mp_set(&res, 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 1998 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 1999 }
wolfSSL 13:f67a6c6013ca 2000 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2001 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2002 }
wolfSSL 13:f67a6c6013ca 2003 }
wolfSSL 13:f67a6c6013ca 2004
wolfSSL 13:f67a6c6013ca 2005 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/
wolfSSL 13:f67a6c6013ca 2006 if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2007 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2008 }
wolfSSL 13:f67a6c6013ca 2009
wolfSSL 13:f67a6c6013ca 2010 for (x = 0; x < (winsize - 1); x++) {
wolfSSL 13:f67a6c6013ca 2011 if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))],
wolfSSL 13:f67a6c6013ca 2012 &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2013 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2014 }
wolfSSL 13:f67a6c6013ca 2015 if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2016 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2017 }
wolfSSL 13:f67a6c6013ca 2018 }
wolfSSL 13:f67a6c6013ca 2019
wolfSSL 13:f67a6c6013ca 2020 /* create upper table */
wolfSSL 13:f67a6c6013ca 2021 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
wolfSSL 13:f67a6c6013ca 2022 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2023 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2024 }
wolfSSL 13:f67a6c6013ca 2025 if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2026 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2027 }
wolfSSL 13:f67a6c6013ca 2028 }
wolfSSL 13:f67a6c6013ca 2029
wolfSSL 13:f67a6c6013ca 2030 /* set initial mode and bit cnt */
wolfSSL 13:f67a6c6013ca 2031 mode = 0;
wolfSSL 13:f67a6c6013ca 2032 bitcnt = 1;
wolfSSL 13:f67a6c6013ca 2033 buf = 0;
wolfSSL 13:f67a6c6013ca 2034 digidx = X->used - 1;
wolfSSL 13:f67a6c6013ca 2035 bitcpy = 0;
wolfSSL 13:f67a6c6013ca 2036 bitbuf = 0;
wolfSSL 13:f67a6c6013ca 2037
wolfSSL 13:f67a6c6013ca 2038 for (;;) {
wolfSSL 13:f67a6c6013ca 2039 /* grab next digit as required */
wolfSSL 13:f67a6c6013ca 2040 if (--bitcnt == 0) {
wolfSSL 13:f67a6c6013ca 2041 /* if digidx == -1 we are out of digits so break */
wolfSSL 13:f67a6c6013ca 2042 if (digidx == -1) {
wolfSSL 13:f67a6c6013ca 2043 break;
wolfSSL 13:f67a6c6013ca 2044 }
wolfSSL 13:f67a6c6013ca 2045 /* read next digit and reset bitcnt */
wolfSSL 13:f67a6c6013ca 2046 buf = X->dp[digidx--];
wolfSSL 13:f67a6c6013ca 2047 bitcnt = (int)DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 2048 }
wolfSSL 13:f67a6c6013ca 2049
wolfSSL 13:f67a6c6013ca 2050 /* grab the next msb from the exponent */
wolfSSL 13:f67a6c6013ca 2051 y = (int)(buf >> (DIGIT_BIT - 1)) & 1;
wolfSSL 13:f67a6c6013ca 2052 buf <<= (mp_digit)1;
wolfSSL 13:f67a6c6013ca 2053
wolfSSL 13:f67a6c6013ca 2054 /* if the bit is zero and mode == 0 then we ignore it
wolfSSL 13:f67a6c6013ca 2055 * These represent the leading zero bits before the first 1 bit
wolfSSL 13:f67a6c6013ca 2056 * in the exponent. Technically this opt is not required but it
wolfSSL 13:f67a6c6013ca 2057 * does lower the # of trivial squaring/reductions used
wolfSSL 13:f67a6c6013ca 2058 */
wolfSSL 13:f67a6c6013ca 2059 if (mode == 0 && y == 0) {
wolfSSL 13:f67a6c6013ca 2060 continue;
wolfSSL 13:f67a6c6013ca 2061 }
wolfSSL 13:f67a6c6013ca 2062
wolfSSL 13:f67a6c6013ca 2063 /* if the bit is zero and mode == 1 then we square */
wolfSSL 13:f67a6c6013ca 2064 if (mode == 1 && y == 0) {
wolfSSL 13:f67a6c6013ca 2065 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2066 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2067 }
wolfSSL 13:f67a6c6013ca 2068 if ((err = redux (&res, P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2069 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2070 }
wolfSSL 13:f67a6c6013ca 2071 continue;
wolfSSL 13:f67a6c6013ca 2072 }
wolfSSL 13:f67a6c6013ca 2073
wolfSSL 13:f67a6c6013ca 2074 /* else we add it to the window */
wolfSSL 13:f67a6c6013ca 2075 bitbuf |= (y << (winsize - ++bitcpy));
wolfSSL 13:f67a6c6013ca 2076 mode = 2;
wolfSSL 13:f67a6c6013ca 2077
wolfSSL 13:f67a6c6013ca 2078 if (bitcpy == winsize) {
wolfSSL 13:f67a6c6013ca 2079 /* ok window is filled so square as required and multiply */
wolfSSL 13:f67a6c6013ca 2080 /* square first */
wolfSSL 13:f67a6c6013ca 2081 for (x = 0; x < winsize; x++) {
wolfSSL 13:f67a6c6013ca 2082 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2083 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2084 }
wolfSSL 13:f67a6c6013ca 2085 if ((err = redux (&res, P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2086 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2087 }
wolfSSL 13:f67a6c6013ca 2088 }
wolfSSL 13:f67a6c6013ca 2089
wolfSSL 13:f67a6c6013ca 2090 /* then multiply */
wolfSSL 13:f67a6c6013ca 2091 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2092 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2093 }
wolfSSL 13:f67a6c6013ca 2094 if ((err = redux (&res, P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2095 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2096 }
wolfSSL 13:f67a6c6013ca 2097
wolfSSL 13:f67a6c6013ca 2098 /* empty window and reset */
wolfSSL 13:f67a6c6013ca 2099 bitcpy = 0;
wolfSSL 13:f67a6c6013ca 2100 bitbuf = 0;
wolfSSL 13:f67a6c6013ca 2101 mode = 1;
wolfSSL 13:f67a6c6013ca 2102 }
wolfSSL 13:f67a6c6013ca 2103 }
wolfSSL 13:f67a6c6013ca 2104
wolfSSL 13:f67a6c6013ca 2105 /* if bits remain then square/multiply */
wolfSSL 13:f67a6c6013ca 2106 if (mode == 2 && bitcpy > 0) {
wolfSSL 13:f67a6c6013ca 2107 /* square then multiply if the bit is set */
wolfSSL 13:f67a6c6013ca 2108 for (x = 0; x < bitcpy; x++) {
wolfSSL 13:f67a6c6013ca 2109 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2110 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2111 }
wolfSSL 13:f67a6c6013ca 2112 if ((err = redux (&res, P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2113 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2114 }
wolfSSL 13:f67a6c6013ca 2115
wolfSSL 13:f67a6c6013ca 2116 /* get next bit of the window */
wolfSSL 13:f67a6c6013ca 2117 bitbuf <<= 1;
wolfSSL 13:f67a6c6013ca 2118 if ((bitbuf & (1 << winsize)) != 0) {
wolfSSL 13:f67a6c6013ca 2119 /* then multiply */
wolfSSL 13:f67a6c6013ca 2120 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2121 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2122 }
wolfSSL 13:f67a6c6013ca 2123 if ((err = redux (&res, P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2124 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2125 }
wolfSSL 13:f67a6c6013ca 2126 }
wolfSSL 13:f67a6c6013ca 2127 }
wolfSSL 13:f67a6c6013ca 2128 }
wolfSSL 13:f67a6c6013ca 2129
wolfSSL 13:f67a6c6013ca 2130 if (redmode == 0) {
wolfSSL 13:f67a6c6013ca 2131 /* fixup result if Montgomery reduction is used
wolfSSL 13:f67a6c6013ca 2132 * recall that any value in a Montgomery system is
wolfSSL 13:f67a6c6013ca 2133 * actually multiplied by R mod n. So we have
wolfSSL 13:f67a6c6013ca 2134 * to reduce one more time to cancel out the factor
wolfSSL 13:f67a6c6013ca 2135 * of R.
wolfSSL 13:f67a6c6013ca 2136 */
wolfSSL 13:f67a6c6013ca 2137 if ((err = redux(&res, P, mp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2138 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 2139 }
wolfSSL 13:f67a6c6013ca 2140 }
wolfSSL 13:f67a6c6013ca 2141
wolfSSL 13:f67a6c6013ca 2142 /* swap res with Y */
wolfSSL 13:f67a6c6013ca 2143 mp_exch (&res, Y);
wolfSSL 13:f67a6c6013ca 2144 err = MP_OKAY;
wolfSSL 13:f67a6c6013ca 2145 LBL_RES:mp_clear (&res);
wolfSSL 13:f67a6c6013ca 2146 LBL_M:
wolfSSL 13:f67a6c6013ca 2147 mp_clear(&M[1]);
wolfSSL 13:f67a6c6013ca 2148 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
wolfSSL 13:f67a6c6013ca 2149 mp_clear (&M[x]);
wolfSSL 13:f67a6c6013ca 2150 }
wolfSSL 13:f67a6c6013ca 2151
wolfSSL 13:f67a6c6013ca 2152 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 2153 XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 13:f67a6c6013ca 2154 #endif
wolfSSL 13:f67a6c6013ca 2155
wolfSSL 13:f67a6c6013ca 2156 return err;
wolfSSL 13:f67a6c6013ca 2157 }
wolfSSL 13:f67a6c6013ca 2158
wolfSSL 13:f67a6c6013ca 2159
wolfSSL 13:f67a6c6013ca 2160 /* setups the montgomery reduction stuff */
wolfSSL 13:f67a6c6013ca 2161 int mp_montgomery_setup (mp_int * n, mp_digit * rho)
wolfSSL 13:f67a6c6013ca 2162 {
wolfSSL 13:f67a6c6013ca 2163 mp_digit x, b;
wolfSSL 13:f67a6c6013ca 2164
wolfSSL 13:f67a6c6013ca 2165 /* fast inversion mod 2**k
wolfSSL 13:f67a6c6013ca 2166 *
wolfSSL 13:f67a6c6013ca 2167 * Based on the fact that
wolfSSL 13:f67a6c6013ca 2168 *
wolfSSL 13:f67a6c6013ca 2169 * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
wolfSSL 13:f67a6c6013ca 2170 * => 2*X*A - X*X*A*A = 1
wolfSSL 13:f67a6c6013ca 2171 * => 2*(1) - (1) = 1
wolfSSL 13:f67a6c6013ca 2172 */
wolfSSL 13:f67a6c6013ca 2173 b = n->dp[0];
wolfSSL 13:f67a6c6013ca 2174
wolfSSL 13:f67a6c6013ca 2175 if ((b & 1) == 0) {
wolfSSL 13:f67a6c6013ca 2176 return MP_VAL;
wolfSSL 13:f67a6c6013ca 2177 }
wolfSSL 13:f67a6c6013ca 2178
wolfSSL 13:f67a6c6013ca 2179 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
wolfSSL 13:f67a6c6013ca 2180 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
wolfSSL 13:f67a6c6013ca 2181 #if !defined(MP_8BIT)
wolfSSL 13:f67a6c6013ca 2182 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
wolfSSL 13:f67a6c6013ca 2183 #endif
wolfSSL 13:f67a6c6013ca 2184 #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
wolfSSL 13:f67a6c6013ca 2185 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
wolfSSL 13:f67a6c6013ca 2186 #endif
wolfSSL 13:f67a6c6013ca 2187 #ifdef MP_64BIT
wolfSSL 13:f67a6c6013ca 2188 x *= 2 - b * x; /* here x*a==1 mod 2**64 */
wolfSSL 13:f67a6c6013ca 2189 #endif
wolfSSL 13:f67a6c6013ca 2190
wolfSSL 13:f67a6c6013ca 2191 /* rho = -1/m mod b */
wolfSSL 13:f67a6c6013ca 2192 /* TAO, switched mp_word casts to mp_digit to shut up compiler */
wolfSSL 13:f67a6c6013ca 2193 *rho = (mp_digit)((((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK);
wolfSSL 13:f67a6c6013ca 2194
wolfSSL 13:f67a6c6013ca 2195 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2196 }
wolfSSL 13:f67a6c6013ca 2197
wolfSSL 13:f67a6c6013ca 2198
wolfSSL 13:f67a6c6013ca 2199 /* computes xR**-1 == x (mod N) via Montgomery Reduction
wolfSSL 13:f67a6c6013ca 2200 *
wolfSSL 13:f67a6c6013ca 2201 * This is an optimized implementation of montgomery_reduce
wolfSSL 13:f67a6c6013ca 2202 * which uses the comba method to quickly calculate the columns of the
wolfSSL 13:f67a6c6013ca 2203 * reduction.
wolfSSL 13:f67a6c6013ca 2204 *
wolfSSL 13:f67a6c6013ca 2205 * Based on Algorithm 14.32 on pp.601 of HAC.
wolfSSL 13:f67a6c6013ca 2206 */
wolfSSL 13:f67a6c6013ca 2207 int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
wolfSSL 13:f67a6c6013ca 2208 {
wolfSSL 13:f67a6c6013ca 2209 int ix, res, olduse;
wolfSSL 13:f67a6c6013ca 2210 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 2211 mp_word* W; /* uses dynamic memory and slower */
wolfSSL 13:f67a6c6013ca 2212 #else
wolfSSL 13:f67a6c6013ca 2213 mp_word W[MP_WARRAY];
wolfSSL 13:f67a6c6013ca 2214 #endif
wolfSSL 13:f67a6c6013ca 2215
wolfSSL 13:f67a6c6013ca 2216 /* get old used count */
wolfSSL 13:f67a6c6013ca 2217 olduse = x->used;
wolfSSL 13:f67a6c6013ca 2218
wolfSSL 13:f67a6c6013ca 2219 /* grow a as required */
wolfSSL 13:f67a6c6013ca 2220 if (x->alloc < n->used + 1) {
wolfSSL 13:f67a6c6013ca 2221 if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2222 return res;
wolfSSL 13:f67a6c6013ca 2223 }
wolfSSL 13:f67a6c6013ca 2224 }
wolfSSL 13:f67a6c6013ca 2225
wolfSSL 13:f67a6c6013ca 2226 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 2227 W = (mp_word*)XMALLOC(sizeof(mp_word) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 2228 if (W == NULL)
wolfSSL 13:f67a6c6013ca 2229 return MP_MEM;
wolfSSL 13:f67a6c6013ca 2230 #endif
wolfSSL 13:f67a6c6013ca 2231
wolfSSL 13:f67a6c6013ca 2232 /* first we have to get the digits of the input into
wolfSSL 13:f67a6c6013ca 2233 * an array of double precision words W[...]
wolfSSL 13:f67a6c6013ca 2234 */
wolfSSL 13:f67a6c6013ca 2235 {
wolfSSL 13:f67a6c6013ca 2236 mp_word *_W;
wolfSSL 13:f67a6c6013ca 2237 mp_digit *tmpx;
wolfSSL 13:f67a6c6013ca 2238
wolfSSL 13:f67a6c6013ca 2239 /* alias for the W[] array */
wolfSSL 13:f67a6c6013ca 2240 _W = W;
wolfSSL 13:f67a6c6013ca 2241
wolfSSL 13:f67a6c6013ca 2242 /* alias for the digits of x*/
wolfSSL 13:f67a6c6013ca 2243 tmpx = x->dp;
wolfSSL 13:f67a6c6013ca 2244
wolfSSL 13:f67a6c6013ca 2245 /* copy the digits of a into W[0..a->used-1] */
wolfSSL 13:f67a6c6013ca 2246 for (ix = 0; ix < x->used; ix++) {
wolfSSL 13:f67a6c6013ca 2247 *_W++ = *tmpx++;
wolfSSL 13:f67a6c6013ca 2248 }
wolfSSL 13:f67a6c6013ca 2249
wolfSSL 13:f67a6c6013ca 2250 /* zero the high words of W[a->used..m->used*2] */
wolfSSL 13:f67a6c6013ca 2251 for (; ix < n->used * 2 + 1; ix++) {
wolfSSL 13:f67a6c6013ca 2252 *_W++ = 0;
wolfSSL 13:f67a6c6013ca 2253 }
wolfSSL 13:f67a6c6013ca 2254 }
wolfSSL 13:f67a6c6013ca 2255
wolfSSL 13:f67a6c6013ca 2256 /* now we proceed to zero successive digits
wolfSSL 13:f67a6c6013ca 2257 * from the least significant upwards
wolfSSL 13:f67a6c6013ca 2258 */
wolfSSL 13:f67a6c6013ca 2259 for (ix = 0; ix < n->used; ix++) {
wolfSSL 13:f67a6c6013ca 2260 /* mu = ai * m' mod b
wolfSSL 13:f67a6c6013ca 2261 *
wolfSSL 13:f67a6c6013ca 2262 * We avoid a double precision multiplication (which isn't required)
wolfSSL 13:f67a6c6013ca 2263 * by casting the value down to a mp_digit. Note this requires
wolfSSL 13:f67a6c6013ca 2264 * that W[ix-1] have the carry cleared (see after the inner loop)
wolfSSL 13:f67a6c6013ca 2265 */
wolfSSL 13:f67a6c6013ca 2266 mp_digit mu;
wolfSSL 13:f67a6c6013ca 2267 mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
wolfSSL 13:f67a6c6013ca 2268
wolfSSL 13:f67a6c6013ca 2269 /* a = a + mu * m * b**i
wolfSSL 13:f67a6c6013ca 2270 *
wolfSSL 13:f67a6c6013ca 2271 * This is computed in place and on the fly. The multiplication
wolfSSL 13:f67a6c6013ca 2272 * by b**i is handled by offseting which columns the results
wolfSSL 13:f67a6c6013ca 2273 * are added to.
wolfSSL 13:f67a6c6013ca 2274 *
wolfSSL 13:f67a6c6013ca 2275 * Note the comba method normally doesn't handle carries in the
wolfSSL 13:f67a6c6013ca 2276 * inner loop In this case we fix the carry from the previous
wolfSSL 13:f67a6c6013ca 2277 * column since the Montgomery reduction requires digits of the
wolfSSL 13:f67a6c6013ca 2278 * result (so far) [see above] to work. This is
wolfSSL 13:f67a6c6013ca 2279 * handled by fixing up one carry after the inner loop. The
wolfSSL 13:f67a6c6013ca 2280 * carry fixups are done in order so after these loops the
wolfSSL 13:f67a6c6013ca 2281 * first m->used words of W[] have the carries fixed
wolfSSL 13:f67a6c6013ca 2282 */
wolfSSL 13:f67a6c6013ca 2283 {
wolfSSL 13:f67a6c6013ca 2284 int iy;
wolfSSL 13:f67a6c6013ca 2285 mp_digit *tmpn;
wolfSSL 13:f67a6c6013ca 2286 mp_word *_W;
wolfSSL 13:f67a6c6013ca 2287
wolfSSL 13:f67a6c6013ca 2288 /* alias for the digits of the modulus */
wolfSSL 13:f67a6c6013ca 2289 tmpn = n->dp;
wolfSSL 13:f67a6c6013ca 2290
wolfSSL 13:f67a6c6013ca 2291 /* Alias for the columns set by an offset of ix */
wolfSSL 13:f67a6c6013ca 2292 _W = W + ix;
wolfSSL 13:f67a6c6013ca 2293
wolfSSL 13:f67a6c6013ca 2294 /* inner loop */
wolfSSL 13:f67a6c6013ca 2295 for (iy = 0; iy < n->used; iy++) {
wolfSSL 13:f67a6c6013ca 2296 *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
wolfSSL 13:f67a6c6013ca 2297 }
wolfSSL 13:f67a6c6013ca 2298 }
wolfSSL 13:f67a6c6013ca 2299
wolfSSL 13:f67a6c6013ca 2300 /* now fix carry for next digit, W[ix+1] */
wolfSSL 13:f67a6c6013ca 2301 W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 2302 }
wolfSSL 13:f67a6c6013ca 2303
wolfSSL 13:f67a6c6013ca 2304 /* now we have to propagate the carries and
wolfSSL 13:f67a6c6013ca 2305 * shift the words downward [all those least
wolfSSL 13:f67a6c6013ca 2306 * significant digits we zeroed].
wolfSSL 13:f67a6c6013ca 2307 */
wolfSSL 13:f67a6c6013ca 2308 {
wolfSSL 13:f67a6c6013ca 2309 mp_digit *tmpx;
wolfSSL 13:f67a6c6013ca 2310 mp_word *_W, *_W1;
wolfSSL 13:f67a6c6013ca 2311
wolfSSL 13:f67a6c6013ca 2312 /* nox fix rest of carries */
wolfSSL 13:f67a6c6013ca 2313
wolfSSL 13:f67a6c6013ca 2314 /* alias for current word */
wolfSSL 13:f67a6c6013ca 2315 _W1 = W + ix;
wolfSSL 13:f67a6c6013ca 2316
wolfSSL 13:f67a6c6013ca 2317 /* alias for next word, where the carry goes */
wolfSSL 13:f67a6c6013ca 2318 _W = W + ++ix;
wolfSSL 13:f67a6c6013ca 2319
wolfSSL 13:f67a6c6013ca 2320 for (; ix <= n->used * 2 + 1; ix++) {
wolfSSL 13:f67a6c6013ca 2321 *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 2322 }
wolfSSL 13:f67a6c6013ca 2323
wolfSSL 13:f67a6c6013ca 2324 /* copy out, A = A/b**n
wolfSSL 13:f67a6c6013ca 2325 *
wolfSSL 13:f67a6c6013ca 2326 * The result is A/b**n but instead of converting from an
wolfSSL 13:f67a6c6013ca 2327 * array of mp_word to mp_digit than calling mp_rshd
wolfSSL 13:f67a6c6013ca 2328 * we just copy them in the right order
wolfSSL 13:f67a6c6013ca 2329 */
wolfSSL 13:f67a6c6013ca 2330
wolfSSL 13:f67a6c6013ca 2331 /* alias for destination word */
wolfSSL 13:f67a6c6013ca 2332 tmpx = x->dp;
wolfSSL 13:f67a6c6013ca 2333
wolfSSL 13:f67a6c6013ca 2334 /* alias for shifted double precision result */
wolfSSL 13:f67a6c6013ca 2335 _W = W + n->used;
wolfSSL 13:f67a6c6013ca 2336
wolfSSL 13:f67a6c6013ca 2337 for (ix = 0; ix < n->used + 1; ix++) {
wolfSSL 13:f67a6c6013ca 2338 *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 2339 }
wolfSSL 13:f67a6c6013ca 2340
wolfSSL 13:f67a6c6013ca 2341 /* zero olduse digits, if the input a was larger than
wolfSSL 13:f67a6c6013ca 2342 * m->used+1 we'll have to clear the digits
wolfSSL 13:f67a6c6013ca 2343 */
wolfSSL 13:f67a6c6013ca 2344 for (; ix < olduse; ix++) {
wolfSSL 13:f67a6c6013ca 2345 *tmpx++ = 0;
wolfSSL 13:f67a6c6013ca 2346 }
wolfSSL 13:f67a6c6013ca 2347 }
wolfSSL 13:f67a6c6013ca 2348
wolfSSL 13:f67a6c6013ca 2349 /* set the max used and clamp */
wolfSSL 13:f67a6c6013ca 2350 x->used = n->used + 1;
wolfSSL 13:f67a6c6013ca 2351 mp_clamp (x);
wolfSSL 13:f67a6c6013ca 2352
wolfSSL 13:f67a6c6013ca 2353 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 2354 XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 2355 #endif
wolfSSL 13:f67a6c6013ca 2356
wolfSSL 13:f67a6c6013ca 2357 /* if A >= m then A = A - m */
wolfSSL 13:f67a6c6013ca 2358 if (mp_cmp_mag (x, n) != MP_LT) {
wolfSSL 13:f67a6c6013ca 2359 return s_mp_sub (x, n, x);
wolfSSL 13:f67a6c6013ca 2360 }
wolfSSL 13:f67a6c6013ca 2361 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2362 }
wolfSSL 13:f67a6c6013ca 2363
wolfSSL 13:f67a6c6013ca 2364
wolfSSL 13:f67a6c6013ca 2365 /* computes xR**-1 == x (mod N) via Montgomery Reduction */
wolfSSL 13:f67a6c6013ca 2366 int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
wolfSSL 13:f67a6c6013ca 2367 {
wolfSSL 13:f67a6c6013ca 2368 int ix, res, digs;
wolfSSL 13:f67a6c6013ca 2369 mp_digit mu;
wolfSSL 13:f67a6c6013ca 2370
wolfSSL 13:f67a6c6013ca 2371 /* can the fast reduction [comba] method be used?
wolfSSL 13:f67a6c6013ca 2372 *
wolfSSL 13:f67a6c6013ca 2373 * Note that unlike in mul you're safely allowed *less*
wolfSSL 13:f67a6c6013ca 2374 * than the available columns [255 per default] since carries
wolfSSL 13:f67a6c6013ca 2375 * are fixed up in the inner loop.
wolfSSL 13:f67a6c6013ca 2376 */
wolfSSL 13:f67a6c6013ca 2377 digs = n->used * 2 + 1;
wolfSSL 13:f67a6c6013ca 2378 if ((digs < MP_WARRAY) &&
wolfSSL 13:f67a6c6013ca 2379 n->used <
wolfSSL 13:f67a6c6013ca 2380 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
wolfSSL 13:f67a6c6013ca 2381 return fast_mp_montgomery_reduce (x, n, rho);
wolfSSL 13:f67a6c6013ca 2382 }
wolfSSL 13:f67a6c6013ca 2383
wolfSSL 13:f67a6c6013ca 2384 /* grow the input as required */
wolfSSL 13:f67a6c6013ca 2385 if (x->alloc < digs) {
wolfSSL 13:f67a6c6013ca 2386 if ((res = mp_grow (x, digs)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2387 return res;
wolfSSL 13:f67a6c6013ca 2388 }
wolfSSL 13:f67a6c6013ca 2389 }
wolfSSL 13:f67a6c6013ca 2390 x->used = digs;
wolfSSL 13:f67a6c6013ca 2391
wolfSSL 13:f67a6c6013ca 2392 for (ix = 0; ix < n->used; ix++) {
wolfSSL 13:f67a6c6013ca 2393 /* mu = ai * rho mod b
wolfSSL 13:f67a6c6013ca 2394 *
wolfSSL 13:f67a6c6013ca 2395 * The value of rho must be precalculated via
wolfSSL 13:f67a6c6013ca 2396 * montgomery_setup() such that
wolfSSL 13:f67a6c6013ca 2397 * it equals -1/n0 mod b this allows the
wolfSSL 13:f67a6c6013ca 2398 * following inner loop to reduce the
wolfSSL 13:f67a6c6013ca 2399 * input one digit at a time
wolfSSL 13:f67a6c6013ca 2400 */
wolfSSL 13:f67a6c6013ca 2401 mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
wolfSSL 13:f67a6c6013ca 2402
wolfSSL 13:f67a6c6013ca 2403 /* a = a + mu * m * b**i */
wolfSSL 13:f67a6c6013ca 2404 {
wolfSSL 13:f67a6c6013ca 2405 int iy;
wolfSSL 13:f67a6c6013ca 2406 mp_digit *tmpn, *tmpx, u;
wolfSSL 13:f67a6c6013ca 2407 mp_word r;
wolfSSL 13:f67a6c6013ca 2408
wolfSSL 13:f67a6c6013ca 2409 /* alias for digits of the modulus */
wolfSSL 13:f67a6c6013ca 2410 tmpn = n->dp;
wolfSSL 13:f67a6c6013ca 2411
wolfSSL 13:f67a6c6013ca 2412 /* alias for the digits of x [the input] */
wolfSSL 13:f67a6c6013ca 2413 tmpx = x->dp + ix;
wolfSSL 13:f67a6c6013ca 2414
wolfSSL 13:f67a6c6013ca 2415 /* set the carry to zero */
wolfSSL 13:f67a6c6013ca 2416 u = 0;
wolfSSL 13:f67a6c6013ca 2417
wolfSSL 13:f67a6c6013ca 2418 /* Multiply and add in place */
wolfSSL 13:f67a6c6013ca 2419 for (iy = 0; iy < n->used; iy++) {
wolfSSL 13:f67a6c6013ca 2420 /* compute product and sum */
wolfSSL 13:f67a6c6013ca 2421 r = ((mp_word)mu) * ((mp_word)*tmpn++) +
wolfSSL 13:f67a6c6013ca 2422 ((mp_word) u) + ((mp_word) * tmpx);
wolfSSL 13:f67a6c6013ca 2423
wolfSSL 13:f67a6c6013ca 2424 /* get carry */
wolfSSL 13:f67a6c6013ca 2425 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 2426
wolfSSL 13:f67a6c6013ca 2427 /* fix digit */
wolfSSL 13:f67a6c6013ca 2428 *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 2429 }
wolfSSL 13:f67a6c6013ca 2430 /* At this point the ix'th digit of x should be zero */
wolfSSL 13:f67a6c6013ca 2431
wolfSSL 13:f67a6c6013ca 2432
wolfSSL 13:f67a6c6013ca 2433 /* propagate carries upwards as required*/
wolfSSL 13:f67a6c6013ca 2434 while (u) {
wolfSSL 13:f67a6c6013ca 2435 *tmpx += u;
wolfSSL 13:f67a6c6013ca 2436 u = *tmpx >> DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 2437 *tmpx++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 2438 }
wolfSSL 13:f67a6c6013ca 2439 }
wolfSSL 13:f67a6c6013ca 2440 }
wolfSSL 13:f67a6c6013ca 2441
wolfSSL 13:f67a6c6013ca 2442 /* at this point the n.used'th least
wolfSSL 13:f67a6c6013ca 2443 * significant digits of x are all zero
wolfSSL 13:f67a6c6013ca 2444 * which means we can shift x to the
wolfSSL 13:f67a6c6013ca 2445 * right by n.used digits and the
wolfSSL 13:f67a6c6013ca 2446 * residue is unchanged.
wolfSSL 13:f67a6c6013ca 2447 */
wolfSSL 13:f67a6c6013ca 2448
wolfSSL 13:f67a6c6013ca 2449 /* x = x/b**n.used */
wolfSSL 13:f67a6c6013ca 2450 mp_clamp(x);
wolfSSL 13:f67a6c6013ca 2451 mp_rshd (x, n->used);
wolfSSL 13:f67a6c6013ca 2452
wolfSSL 13:f67a6c6013ca 2453 /* if x >= n then x = x - n */
wolfSSL 13:f67a6c6013ca 2454 if (mp_cmp_mag (x, n) != MP_LT) {
wolfSSL 13:f67a6c6013ca 2455 return s_mp_sub (x, n, x);
wolfSSL 13:f67a6c6013ca 2456 }
wolfSSL 13:f67a6c6013ca 2457
wolfSSL 13:f67a6c6013ca 2458 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2459 }
wolfSSL 13:f67a6c6013ca 2460
wolfSSL 13:f67a6c6013ca 2461
wolfSSL 13:f67a6c6013ca 2462 /* determines the setup value */
wolfSSL 13:f67a6c6013ca 2463 void mp_dr_setup(mp_int *a, mp_digit *d)
wolfSSL 13:f67a6c6013ca 2464 {
wolfSSL 13:f67a6c6013ca 2465 /* the casts are required if DIGIT_BIT is one less than
wolfSSL 13:f67a6c6013ca 2466 * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
wolfSSL 13:f67a6c6013ca 2467 */
wolfSSL 13:f67a6c6013ca 2468 *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
wolfSSL 13:f67a6c6013ca 2469 ((mp_word)a->dp[0]));
wolfSSL 13:f67a6c6013ca 2470 }
wolfSSL 13:f67a6c6013ca 2471
wolfSSL 13:f67a6c6013ca 2472
wolfSSL 13:f67a6c6013ca 2473 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
wolfSSL 13:f67a6c6013ca 2474 *
wolfSSL 13:f67a6c6013ca 2475 * Based on algorithm from the paper
wolfSSL 13:f67a6c6013ca 2476 *
wolfSSL 13:f67a6c6013ca 2477 * "Generating Efficient Primes for Discrete Log Cryptosystems"
wolfSSL 13:f67a6c6013ca 2478 * Chae Hoon Lim, Pil Joong Lee,
wolfSSL 13:f67a6c6013ca 2479 * POSTECH Information Research Laboratories
wolfSSL 13:f67a6c6013ca 2480 *
wolfSSL 13:f67a6c6013ca 2481 * The modulus must be of a special format [see manual]
wolfSSL 13:f67a6c6013ca 2482 *
wolfSSL 13:f67a6c6013ca 2483 * Has been modified to use algorithm 7.10 from the LTM book instead
wolfSSL 13:f67a6c6013ca 2484 *
wolfSSL 13:f67a6c6013ca 2485 * Input x must be in the range 0 <= x <= (n-1)**2
wolfSSL 13:f67a6c6013ca 2486 */
wolfSSL 13:f67a6c6013ca 2487 int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
wolfSSL 13:f67a6c6013ca 2488 {
wolfSSL 13:f67a6c6013ca 2489 int err, i, m;
wolfSSL 13:f67a6c6013ca 2490 mp_word r;
wolfSSL 13:f67a6c6013ca 2491 mp_digit mu, *tmpx1, *tmpx2;
wolfSSL 13:f67a6c6013ca 2492
wolfSSL 13:f67a6c6013ca 2493 /* m = digits in modulus */
wolfSSL 13:f67a6c6013ca 2494 m = n->used;
wolfSSL 13:f67a6c6013ca 2495
wolfSSL 13:f67a6c6013ca 2496 /* ensure that "x" has at least 2m digits */
wolfSSL 13:f67a6c6013ca 2497 if (x->alloc < m + m) {
wolfSSL 13:f67a6c6013ca 2498 if ((err = mp_grow (x, m + m)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2499 return err;
wolfSSL 13:f67a6c6013ca 2500 }
wolfSSL 13:f67a6c6013ca 2501 }
wolfSSL 13:f67a6c6013ca 2502
wolfSSL 13:f67a6c6013ca 2503 /* top of loop, this is where the code resumes if
wolfSSL 13:f67a6c6013ca 2504 * another reduction pass is required.
wolfSSL 13:f67a6c6013ca 2505 */
wolfSSL 13:f67a6c6013ca 2506 top:
wolfSSL 13:f67a6c6013ca 2507 /* aliases for digits */
wolfSSL 13:f67a6c6013ca 2508 /* alias for lower half of x */
wolfSSL 13:f67a6c6013ca 2509 tmpx1 = x->dp;
wolfSSL 13:f67a6c6013ca 2510
wolfSSL 13:f67a6c6013ca 2511 /* alias for upper half of x, or x/B**m */
wolfSSL 13:f67a6c6013ca 2512 tmpx2 = x->dp + m;
wolfSSL 13:f67a6c6013ca 2513
wolfSSL 13:f67a6c6013ca 2514 /* set carry to zero */
wolfSSL 13:f67a6c6013ca 2515 mu = 0;
wolfSSL 13:f67a6c6013ca 2516
wolfSSL 13:f67a6c6013ca 2517 /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
wolfSSL 13:f67a6c6013ca 2518 for (i = 0; i < m; i++) {
wolfSSL 13:f67a6c6013ca 2519 r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
wolfSSL 13:f67a6c6013ca 2520 *tmpx1++ = (mp_digit)(r & MP_MASK);
wolfSSL 13:f67a6c6013ca 2521 mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 2522 }
wolfSSL 13:f67a6c6013ca 2523
wolfSSL 13:f67a6c6013ca 2524 /* set final carry */
wolfSSL 13:f67a6c6013ca 2525 *tmpx1++ = mu;
wolfSSL 13:f67a6c6013ca 2526
wolfSSL 13:f67a6c6013ca 2527 /* zero words above m */
wolfSSL 13:f67a6c6013ca 2528 for (i = m + 1; i < x->used; i++) {
wolfSSL 13:f67a6c6013ca 2529 *tmpx1++ = 0;
wolfSSL 13:f67a6c6013ca 2530 }
wolfSSL 13:f67a6c6013ca 2531
wolfSSL 13:f67a6c6013ca 2532 /* clamp, sub and return */
wolfSSL 13:f67a6c6013ca 2533 mp_clamp (x);
wolfSSL 13:f67a6c6013ca 2534
wolfSSL 13:f67a6c6013ca 2535 /* if x >= n then subtract and reduce again
wolfSSL 13:f67a6c6013ca 2536 * Each successive "recursion" makes the input smaller and smaller.
wolfSSL 13:f67a6c6013ca 2537 */
wolfSSL 13:f67a6c6013ca 2538 if (mp_cmp_mag (x, n) != MP_LT) {
wolfSSL 13:f67a6c6013ca 2539 s_mp_sub(x, n, x);
wolfSSL 13:f67a6c6013ca 2540 goto top;
wolfSSL 13:f67a6c6013ca 2541 }
wolfSSL 13:f67a6c6013ca 2542 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2543 }
wolfSSL 13:f67a6c6013ca 2544
wolfSSL 13:f67a6c6013ca 2545
wolfSSL 13:f67a6c6013ca 2546 /* reduces a modulo n where n is of the form 2**p - d */
wolfSSL 13:f67a6c6013ca 2547 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
wolfSSL 13:f67a6c6013ca 2548 {
wolfSSL 13:f67a6c6013ca 2549 mp_int q;
wolfSSL 13:f67a6c6013ca 2550 int p, res;
wolfSSL 13:f67a6c6013ca 2551
wolfSSL 13:f67a6c6013ca 2552 if ((res = mp_init(&q)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2553 return res;
wolfSSL 13:f67a6c6013ca 2554 }
wolfSSL 13:f67a6c6013ca 2555
wolfSSL 13:f67a6c6013ca 2556 p = mp_count_bits(n);
wolfSSL 13:f67a6c6013ca 2557 top:
wolfSSL 13:f67a6c6013ca 2558 /* q = a/2**p, a = a mod 2**p */
wolfSSL 13:f67a6c6013ca 2559 if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2560 goto ERR;
wolfSSL 13:f67a6c6013ca 2561 }
wolfSSL 13:f67a6c6013ca 2562
wolfSSL 13:f67a6c6013ca 2563 if (d != 1) {
wolfSSL 13:f67a6c6013ca 2564 /* q = q * d */
wolfSSL 13:f67a6c6013ca 2565 if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2566 goto ERR;
wolfSSL 13:f67a6c6013ca 2567 }
wolfSSL 13:f67a6c6013ca 2568 }
wolfSSL 13:f67a6c6013ca 2569
wolfSSL 13:f67a6c6013ca 2570 /* a = a + q */
wolfSSL 13:f67a6c6013ca 2571 if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2572 goto ERR;
wolfSSL 13:f67a6c6013ca 2573 }
wolfSSL 13:f67a6c6013ca 2574
wolfSSL 13:f67a6c6013ca 2575 if (mp_cmp_mag(a, n) != MP_LT) {
wolfSSL 13:f67a6c6013ca 2576 s_mp_sub(a, n, a);
wolfSSL 13:f67a6c6013ca 2577 goto top;
wolfSSL 13:f67a6c6013ca 2578 }
wolfSSL 13:f67a6c6013ca 2579
wolfSSL 13:f67a6c6013ca 2580 ERR:
wolfSSL 13:f67a6c6013ca 2581 mp_clear(&q);
wolfSSL 13:f67a6c6013ca 2582 return res;
wolfSSL 13:f67a6c6013ca 2583 }
wolfSSL 13:f67a6c6013ca 2584
wolfSSL 13:f67a6c6013ca 2585
wolfSSL 13:f67a6c6013ca 2586 /* determines the setup value */
wolfSSL 13:f67a6c6013ca 2587 int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
wolfSSL 13:f67a6c6013ca 2588 {
wolfSSL 13:f67a6c6013ca 2589 int res, p;
wolfSSL 13:f67a6c6013ca 2590 mp_int tmp;
wolfSSL 13:f67a6c6013ca 2591
wolfSSL 13:f67a6c6013ca 2592 if ((res = mp_init(&tmp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2593 return res;
wolfSSL 13:f67a6c6013ca 2594 }
wolfSSL 13:f67a6c6013ca 2595
wolfSSL 13:f67a6c6013ca 2596 p = mp_count_bits(a);
wolfSSL 13:f67a6c6013ca 2597 if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2598 mp_clear(&tmp);
wolfSSL 13:f67a6c6013ca 2599 return res;
wolfSSL 13:f67a6c6013ca 2600 }
wolfSSL 13:f67a6c6013ca 2601
wolfSSL 13:f67a6c6013ca 2602 if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2603 mp_clear(&tmp);
wolfSSL 13:f67a6c6013ca 2604 return res;
wolfSSL 13:f67a6c6013ca 2605 }
wolfSSL 13:f67a6c6013ca 2606
wolfSSL 13:f67a6c6013ca 2607 *d = tmp.dp[0];
wolfSSL 13:f67a6c6013ca 2608 mp_clear(&tmp);
wolfSSL 13:f67a6c6013ca 2609 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2610 }
wolfSSL 13:f67a6c6013ca 2611
wolfSSL 13:f67a6c6013ca 2612
wolfSSL 13:f67a6c6013ca 2613 /* set the b bit of a */
wolfSSL 13:f67a6c6013ca 2614 int mp_set_bit (mp_int * a, int b)
wolfSSL 13:f67a6c6013ca 2615 {
wolfSSL 13:f67a6c6013ca 2616 int i = b / DIGIT_BIT, res;
wolfSSL 13:f67a6c6013ca 2617
wolfSSL 13:f67a6c6013ca 2618 if (a->used < (int)(i + 1)) {
wolfSSL 13:f67a6c6013ca 2619 /* grow a to accommodate the single bit */
wolfSSL 13:f67a6c6013ca 2620 if ((res = mp_grow (a, i + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2621 return res;
wolfSSL 13:f67a6c6013ca 2622 }
wolfSSL 13:f67a6c6013ca 2623
wolfSSL 13:f67a6c6013ca 2624 /* set the used count of where the bit will go */
wolfSSL 13:f67a6c6013ca 2625 a->used = (int)(i + 1);
wolfSSL 13:f67a6c6013ca 2626 }
wolfSSL 13:f67a6c6013ca 2627
wolfSSL 13:f67a6c6013ca 2628 /* put the single bit in its place */
wolfSSL 13:f67a6c6013ca 2629 a->dp[i] |= ((mp_digit)1) << (b % DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 2630
wolfSSL 13:f67a6c6013ca 2631 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2632 }
wolfSSL 13:f67a6c6013ca 2633
wolfSSL 13:f67a6c6013ca 2634 /* computes a = 2**b
wolfSSL 13:f67a6c6013ca 2635 *
wolfSSL 13:f67a6c6013ca 2636 * Simple algorithm which zeros the int, set the required bit
wolfSSL 13:f67a6c6013ca 2637 */
wolfSSL 13:f67a6c6013ca 2638 int mp_2expt (mp_int * a, int b)
wolfSSL 13:f67a6c6013ca 2639 {
wolfSSL 13:f67a6c6013ca 2640 /* zero a as per default */
wolfSSL 13:f67a6c6013ca 2641 mp_zero (a);
wolfSSL 13:f67a6c6013ca 2642
wolfSSL 13:f67a6c6013ca 2643 return mp_set_bit(a, b);
wolfSSL 13:f67a6c6013ca 2644 }
wolfSSL 13:f67a6c6013ca 2645
wolfSSL 13:f67a6c6013ca 2646 /* multiply by a digit */
wolfSSL 13:f67a6c6013ca 2647 int mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
wolfSSL 13:f67a6c6013ca 2648 {
wolfSSL 13:f67a6c6013ca 2649 mp_digit u, *tmpa, *tmpc;
wolfSSL 13:f67a6c6013ca 2650 mp_word r;
wolfSSL 13:f67a6c6013ca 2651 int ix, res, olduse;
wolfSSL 13:f67a6c6013ca 2652
wolfSSL 13:f67a6c6013ca 2653 /* make sure c is big enough to hold a*b */
wolfSSL 13:f67a6c6013ca 2654 if (c->alloc < a->used + 1) {
wolfSSL 13:f67a6c6013ca 2655 if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2656 return res;
wolfSSL 13:f67a6c6013ca 2657 }
wolfSSL 13:f67a6c6013ca 2658 }
wolfSSL 13:f67a6c6013ca 2659
wolfSSL 13:f67a6c6013ca 2660 /* get the original destinations used count */
wolfSSL 13:f67a6c6013ca 2661 olduse = c->used;
wolfSSL 13:f67a6c6013ca 2662
wolfSSL 13:f67a6c6013ca 2663 /* set the sign */
wolfSSL 13:f67a6c6013ca 2664 c->sign = a->sign;
wolfSSL 13:f67a6c6013ca 2665
wolfSSL 13:f67a6c6013ca 2666 /* alias for a->dp [source] */
wolfSSL 13:f67a6c6013ca 2667 tmpa = a->dp;
wolfSSL 13:f67a6c6013ca 2668
wolfSSL 13:f67a6c6013ca 2669 /* alias for c->dp [dest] */
wolfSSL 13:f67a6c6013ca 2670 tmpc = c->dp;
wolfSSL 13:f67a6c6013ca 2671
wolfSSL 13:f67a6c6013ca 2672 /* zero carry */
wolfSSL 13:f67a6c6013ca 2673 u = 0;
wolfSSL 13:f67a6c6013ca 2674
wolfSSL 13:f67a6c6013ca 2675 /* compute columns */
wolfSSL 13:f67a6c6013ca 2676 for (ix = 0; ix < a->used; ix++) {
wolfSSL 13:f67a6c6013ca 2677 /* compute product and carry sum for this term */
wolfSSL 13:f67a6c6013ca 2678 r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
wolfSSL 13:f67a6c6013ca 2679
wolfSSL 13:f67a6c6013ca 2680 /* mask off higher bits to get a single digit */
wolfSSL 13:f67a6c6013ca 2681 *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 2682
wolfSSL 13:f67a6c6013ca 2683 /* send carry into next iteration */
wolfSSL 13:f67a6c6013ca 2684 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 2685 }
wolfSSL 13:f67a6c6013ca 2686
wolfSSL 13:f67a6c6013ca 2687 /* store final carry [if any] and increment ix offset */
wolfSSL 13:f67a6c6013ca 2688 *tmpc++ = u;
wolfSSL 13:f67a6c6013ca 2689 ++ix;
wolfSSL 13:f67a6c6013ca 2690
wolfSSL 13:f67a6c6013ca 2691 /* now zero digits above the top */
wolfSSL 13:f67a6c6013ca 2692 while (ix++ < olduse) {
wolfSSL 13:f67a6c6013ca 2693 *tmpc++ = 0;
wolfSSL 13:f67a6c6013ca 2694 }
wolfSSL 13:f67a6c6013ca 2695
wolfSSL 13:f67a6c6013ca 2696 /* set used count */
wolfSSL 13:f67a6c6013ca 2697 c->used = a->used + 1;
wolfSSL 13:f67a6c6013ca 2698 mp_clamp(c);
wolfSSL 13:f67a6c6013ca 2699
wolfSSL 13:f67a6c6013ca 2700 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2701 }
wolfSSL 13:f67a6c6013ca 2702
wolfSSL 13:f67a6c6013ca 2703
wolfSSL 13:f67a6c6013ca 2704 /* d = a * b (mod c) */
wolfSSL 13:f67a6c6013ca 2705 #if defined(FREESCALE_LTC_TFM)
wolfSSL 13:f67a6c6013ca 2706 int wolfcrypt_mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)
wolfSSL 13:f67a6c6013ca 2707 #else
wolfSSL 13:f67a6c6013ca 2708 int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
wolfSSL 13:f67a6c6013ca 2709 #endif
wolfSSL 13:f67a6c6013ca 2710 {
wolfSSL 13:f67a6c6013ca 2711 int res;
wolfSSL 13:f67a6c6013ca 2712 mp_int t;
wolfSSL 13:f67a6c6013ca 2713
wolfSSL 13:f67a6c6013ca 2714 if ((res = mp_init (&t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2715 return res;
wolfSSL 13:f67a6c6013ca 2716 }
wolfSSL 13:f67a6c6013ca 2717
wolfSSL 13:f67a6c6013ca 2718 res = mp_mul (a, b, &t);
wolfSSL 13:f67a6c6013ca 2719 if (res == MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2720 res = mp_mod (&t, c, d);
wolfSSL 13:f67a6c6013ca 2721 }
wolfSSL 13:f67a6c6013ca 2722
wolfSSL 13:f67a6c6013ca 2723 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 2724 return res;
wolfSSL 13:f67a6c6013ca 2725 }
wolfSSL 13:f67a6c6013ca 2726
wolfSSL 13:f67a6c6013ca 2727
wolfSSL 13:f67a6c6013ca 2728 /* d = a - b (mod c) */
wolfSSL 13:f67a6c6013ca 2729 int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
wolfSSL 13:f67a6c6013ca 2730 {
wolfSSL 13:f67a6c6013ca 2731 int res;
wolfSSL 13:f67a6c6013ca 2732 mp_int t;
wolfSSL 13:f67a6c6013ca 2733
wolfSSL 13:f67a6c6013ca 2734 if ((res = mp_init (&t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2735 return res;
wolfSSL 13:f67a6c6013ca 2736 }
wolfSSL 13:f67a6c6013ca 2737
wolfSSL 13:f67a6c6013ca 2738 res = mp_sub (a, b, &t);
wolfSSL 13:f67a6c6013ca 2739 if (res == MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2740 res = mp_mod (&t, c, d);
wolfSSL 13:f67a6c6013ca 2741 }
wolfSSL 13:f67a6c6013ca 2742
wolfSSL 13:f67a6c6013ca 2743 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 2744
wolfSSL 13:f67a6c6013ca 2745 return res;
wolfSSL 13:f67a6c6013ca 2746 }
wolfSSL 13:f67a6c6013ca 2747
wolfSSL 13:f67a6c6013ca 2748 /* d = a + b (mod c) */
wolfSSL 13:f67a6c6013ca 2749 int mp_addmod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
wolfSSL 13:f67a6c6013ca 2750 {
wolfSSL 13:f67a6c6013ca 2751 int res;
wolfSSL 13:f67a6c6013ca 2752 mp_int t;
wolfSSL 13:f67a6c6013ca 2753
wolfSSL 13:f67a6c6013ca 2754 if ((res = mp_init (&t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2755 return res;
wolfSSL 13:f67a6c6013ca 2756 }
wolfSSL 13:f67a6c6013ca 2757
wolfSSL 13:f67a6c6013ca 2758 res = mp_add (a, b, &t);
wolfSSL 13:f67a6c6013ca 2759 if (res == MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2760 res = mp_mod (&t, c, d);
wolfSSL 13:f67a6c6013ca 2761 }
wolfSSL 13:f67a6c6013ca 2762
wolfSSL 13:f67a6c6013ca 2763 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 2764
wolfSSL 13:f67a6c6013ca 2765 return res;
wolfSSL 13:f67a6c6013ca 2766 }
wolfSSL 13:f67a6c6013ca 2767
wolfSSL 13:f67a6c6013ca 2768 /* computes b = a*a */
wolfSSL 13:f67a6c6013ca 2769 int mp_sqr (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 2770 {
wolfSSL 13:f67a6c6013ca 2771 int res;
wolfSSL 13:f67a6c6013ca 2772
wolfSSL 13:f67a6c6013ca 2773 {
wolfSSL 13:f67a6c6013ca 2774 #ifdef BN_FAST_S_MP_SQR_C
wolfSSL 13:f67a6c6013ca 2775 /* can we use the fast comba multiplier? */
wolfSSL 13:f67a6c6013ca 2776 if ((a->used * 2 + 1) < MP_WARRAY &&
wolfSSL 13:f67a6c6013ca 2777 a->used <
wolfSSL 13:f67a6c6013ca 2778 (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
wolfSSL 13:f67a6c6013ca 2779 res = fast_s_mp_sqr (a, b);
wolfSSL 13:f67a6c6013ca 2780 } else
wolfSSL 13:f67a6c6013ca 2781 #endif
wolfSSL 13:f67a6c6013ca 2782 #ifdef BN_S_MP_SQR_C
wolfSSL 13:f67a6c6013ca 2783 res = s_mp_sqr (a, b);
wolfSSL 13:f67a6c6013ca 2784 #else
wolfSSL 13:f67a6c6013ca 2785 res = MP_VAL;
wolfSSL 13:f67a6c6013ca 2786 #endif
wolfSSL 13:f67a6c6013ca 2787 }
wolfSSL 13:f67a6c6013ca 2788 b->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 2789 return res;
wolfSSL 13:f67a6c6013ca 2790 }
wolfSSL 13:f67a6c6013ca 2791
wolfSSL 13:f67a6c6013ca 2792
wolfSSL 13:f67a6c6013ca 2793 /* high level multiplication (handles sign) */
wolfSSL 13:f67a6c6013ca 2794 #if defined(FREESCALE_LTC_TFM)
wolfSSL 13:f67a6c6013ca 2795 int wolfcrypt_mp_mul(mp_int *a, mp_int *b, mp_int *c)
wolfSSL 13:f67a6c6013ca 2796 #else
wolfSSL 13:f67a6c6013ca 2797 int mp_mul (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 2798 #endif
wolfSSL 13:f67a6c6013ca 2799 {
wolfSSL 13:f67a6c6013ca 2800 int res, neg;
wolfSSL 13:f67a6c6013ca 2801 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
wolfSSL 13:f67a6c6013ca 2802
wolfSSL 13:f67a6c6013ca 2803 {
wolfSSL 13:f67a6c6013ca 2804 /* can we use the fast multiplier?
wolfSSL 13:f67a6c6013ca 2805 *
wolfSSL 13:f67a6c6013ca 2806 * The fast multiplier can be used if the output will
wolfSSL 13:f67a6c6013ca 2807 * have less than MP_WARRAY digits and the number of
wolfSSL 13:f67a6c6013ca 2808 * digits won't affect carry propagation
wolfSSL 13:f67a6c6013ca 2809 */
wolfSSL 13:f67a6c6013ca 2810 int digs = a->used + b->used + 1;
wolfSSL 13:f67a6c6013ca 2811
wolfSSL 13:f67a6c6013ca 2812 #ifdef BN_FAST_S_MP_MUL_DIGS_C
wolfSSL 13:f67a6c6013ca 2813 if ((digs < MP_WARRAY) &&
wolfSSL 13:f67a6c6013ca 2814 MIN(a->used, b->used) <=
wolfSSL 13:f67a6c6013ca 2815 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
wolfSSL 13:f67a6c6013ca 2816 res = fast_s_mp_mul_digs (a, b, c, digs);
wolfSSL 13:f67a6c6013ca 2817 } else
wolfSSL 13:f67a6c6013ca 2818 #endif
wolfSSL 13:f67a6c6013ca 2819 #ifdef BN_S_MP_MUL_DIGS_C
wolfSSL 13:f67a6c6013ca 2820 res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
wolfSSL 13:f67a6c6013ca 2821 #else
wolfSSL 13:f67a6c6013ca 2822 res = MP_VAL;
wolfSSL 13:f67a6c6013ca 2823 #endif
wolfSSL 13:f67a6c6013ca 2824
wolfSSL 13:f67a6c6013ca 2825 }
wolfSSL 13:f67a6c6013ca 2826 c->sign = (c->used > 0) ? neg : MP_ZPOS;
wolfSSL 13:f67a6c6013ca 2827 return res;
wolfSSL 13:f67a6c6013ca 2828 }
wolfSSL 13:f67a6c6013ca 2829
wolfSSL 13:f67a6c6013ca 2830
wolfSSL 13:f67a6c6013ca 2831 /* b = a*2 */
wolfSSL 13:f67a6c6013ca 2832 int mp_mul_2(mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 2833 {
wolfSSL 13:f67a6c6013ca 2834 int x, res, oldused;
wolfSSL 13:f67a6c6013ca 2835
wolfSSL 13:f67a6c6013ca 2836 /* grow to accommodate result */
wolfSSL 13:f67a6c6013ca 2837 if (b->alloc < a->used + 1) {
wolfSSL 13:f67a6c6013ca 2838 if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2839 return res;
wolfSSL 13:f67a6c6013ca 2840 }
wolfSSL 13:f67a6c6013ca 2841 }
wolfSSL 13:f67a6c6013ca 2842
wolfSSL 13:f67a6c6013ca 2843 oldused = b->used;
wolfSSL 13:f67a6c6013ca 2844 b->used = a->used;
wolfSSL 13:f67a6c6013ca 2845
wolfSSL 13:f67a6c6013ca 2846 {
wolfSSL 13:f67a6c6013ca 2847 mp_digit r, rr, *tmpa, *tmpb;
wolfSSL 13:f67a6c6013ca 2848
wolfSSL 13:f67a6c6013ca 2849 /* alias for source */
wolfSSL 13:f67a6c6013ca 2850 tmpa = a->dp;
wolfSSL 13:f67a6c6013ca 2851
wolfSSL 13:f67a6c6013ca 2852 /* alias for dest */
wolfSSL 13:f67a6c6013ca 2853 tmpb = b->dp;
wolfSSL 13:f67a6c6013ca 2854
wolfSSL 13:f67a6c6013ca 2855 /* carry */
wolfSSL 13:f67a6c6013ca 2856 r = 0;
wolfSSL 13:f67a6c6013ca 2857 for (x = 0; x < a->used; x++) {
wolfSSL 13:f67a6c6013ca 2858
wolfSSL 13:f67a6c6013ca 2859 /* get what will be the *next* carry bit from the
wolfSSL 13:f67a6c6013ca 2860 * MSB of the current digit
wolfSSL 13:f67a6c6013ca 2861 */
wolfSSL 13:f67a6c6013ca 2862 rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
wolfSSL 13:f67a6c6013ca 2863
wolfSSL 13:f67a6c6013ca 2864 /* now shift up this digit, add in the carry [from the previous] */
wolfSSL 13:f67a6c6013ca 2865 *tmpb++ = (mp_digit)(((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK);
wolfSSL 13:f67a6c6013ca 2866
wolfSSL 13:f67a6c6013ca 2867 /* copy the carry that would be from the source
wolfSSL 13:f67a6c6013ca 2868 * digit into the next iteration
wolfSSL 13:f67a6c6013ca 2869 */
wolfSSL 13:f67a6c6013ca 2870 r = rr;
wolfSSL 13:f67a6c6013ca 2871 }
wolfSSL 13:f67a6c6013ca 2872
wolfSSL 13:f67a6c6013ca 2873 /* new leading digit? */
wolfSSL 13:f67a6c6013ca 2874 if (r != 0) {
wolfSSL 13:f67a6c6013ca 2875 /* add a MSB which is always 1 at this point */
wolfSSL 13:f67a6c6013ca 2876 *tmpb = 1;
wolfSSL 13:f67a6c6013ca 2877 ++(b->used);
wolfSSL 13:f67a6c6013ca 2878 }
wolfSSL 13:f67a6c6013ca 2879
wolfSSL 13:f67a6c6013ca 2880 /* now zero any excess digits on the destination
wolfSSL 13:f67a6c6013ca 2881 * that we didn't write to
wolfSSL 13:f67a6c6013ca 2882 */
wolfSSL 13:f67a6c6013ca 2883 tmpb = b->dp + b->used;
wolfSSL 13:f67a6c6013ca 2884 for (x = b->used; x < oldused; x++) {
wolfSSL 13:f67a6c6013ca 2885 *tmpb++ = 0;
wolfSSL 13:f67a6c6013ca 2886 }
wolfSSL 13:f67a6c6013ca 2887 }
wolfSSL 13:f67a6c6013ca 2888 b->sign = a->sign;
wolfSSL 13:f67a6c6013ca 2889 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2890 }
wolfSSL 13:f67a6c6013ca 2891
wolfSSL 13:f67a6c6013ca 2892
wolfSSL 13:f67a6c6013ca 2893 /* divide by three (based on routine from MPI and the GMP manual) */
wolfSSL 13:f67a6c6013ca 2894 int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
wolfSSL 13:f67a6c6013ca 2895 {
wolfSSL 13:f67a6c6013ca 2896 mp_int q;
wolfSSL 13:f67a6c6013ca 2897 mp_word w, t;
wolfSSL 13:f67a6c6013ca 2898 mp_digit b;
wolfSSL 13:f67a6c6013ca 2899 int res, ix;
wolfSSL 13:f67a6c6013ca 2900
wolfSSL 13:f67a6c6013ca 2901 /* b = 2**DIGIT_BIT / 3 */
wolfSSL 13:f67a6c6013ca 2902 b = (mp_digit) ( (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3) );
wolfSSL 13:f67a6c6013ca 2903
wolfSSL 13:f67a6c6013ca 2904 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 2905 return res;
wolfSSL 13:f67a6c6013ca 2906 }
wolfSSL 13:f67a6c6013ca 2907
wolfSSL 13:f67a6c6013ca 2908 q.used = a->used;
wolfSSL 13:f67a6c6013ca 2909 q.sign = a->sign;
wolfSSL 13:f67a6c6013ca 2910 w = 0;
wolfSSL 13:f67a6c6013ca 2911 for (ix = a->used - 1; ix >= 0; ix--) {
wolfSSL 13:f67a6c6013ca 2912 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
wolfSSL 13:f67a6c6013ca 2913
wolfSSL 13:f67a6c6013ca 2914 if (w >= 3) {
wolfSSL 13:f67a6c6013ca 2915 /* multiply w by [1/3] */
wolfSSL 13:f67a6c6013ca 2916 t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 2917
wolfSSL 13:f67a6c6013ca 2918 /* now subtract 3 * [w/3] from w, to get the remainder */
wolfSSL 13:f67a6c6013ca 2919 w -= t+t+t;
wolfSSL 13:f67a6c6013ca 2920
wolfSSL 13:f67a6c6013ca 2921 /* fixup the remainder as required since
wolfSSL 13:f67a6c6013ca 2922 * the optimization is not exact.
wolfSSL 13:f67a6c6013ca 2923 */
wolfSSL 13:f67a6c6013ca 2924 while (w >= 3) {
wolfSSL 13:f67a6c6013ca 2925 t += 1;
wolfSSL 13:f67a6c6013ca 2926 w -= 3;
wolfSSL 13:f67a6c6013ca 2927 }
wolfSSL 13:f67a6c6013ca 2928 } else {
wolfSSL 13:f67a6c6013ca 2929 t = 0;
wolfSSL 13:f67a6c6013ca 2930 }
wolfSSL 13:f67a6c6013ca 2931 q.dp[ix] = (mp_digit)t;
wolfSSL 13:f67a6c6013ca 2932 }
wolfSSL 13:f67a6c6013ca 2933
wolfSSL 13:f67a6c6013ca 2934 /* [optional] store the remainder */
wolfSSL 13:f67a6c6013ca 2935 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 2936 *d = (mp_digit)w;
wolfSSL 13:f67a6c6013ca 2937 }
wolfSSL 13:f67a6c6013ca 2938
wolfSSL 13:f67a6c6013ca 2939 /* [optional] store the quotient */
wolfSSL 13:f67a6c6013ca 2940 if (c != NULL) {
wolfSSL 13:f67a6c6013ca 2941 mp_clamp(&q);
wolfSSL 13:f67a6c6013ca 2942 mp_exch(&q, c);
wolfSSL 13:f67a6c6013ca 2943 }
wolfSSL 13:f67a6c6013ca 2944 mp_clear(&q);
wolfSSL 13:f67a6c6013ca 2945
wolfSSL 13:f67a6c6013ca 2946 return res;
wolfSSL 13:f67a6c6013ca 2947 }
wolfSSL 13:f67a6c6013ca 2948
wolfSSL 13:f67a6c6013ca 2949
wolfSSL 13:f67a6c6013ca 2950 /* init an mp_init for a given size */
wolfSSL 13:f67a6c6013ca 2951 int mp_init_size (mp_int * a, int size)
wolfSSL 13:f67a6c6013ca 2952 {
wolfSSL 13:f67a6c6013ca 2953 int x;
wolfSSL 13:f67a6c6013ca 2954
wolfSSL 13:f67a6c6013ca 2955 /* pad size so there are always extra digits */
wolfSSL 13:f67a6c6013ca 2956 size += (MP_PREC * 2) - (size % MP_PREC);
wolfSSL 13:f67a6c6013ca 2957
wolfSSL 13:f67a6c6013ca 2958 /* alloc mem */
wolfSSL 13:f67a6c6013ca 2959 a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size, NULL,
wolfSSL 13:f67a6c6013ca 2960 DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 2961 if (a->dp == NULL) {
wolfSSL 13:f67a6c6013ca 2962 return MP_MEM;
wolfSSL 13:f67a6c6013ca 2963 }
wolfSSL 13:f67a6c6013ca 2964
wolfSSL 13:f67a6c6013ca 2965 /* set the members */
wolfSSL 13:f67a6c6013ca 2966 a->used = 0;
wolfSSL 13:f67a6c6013ca 2967 a->alloc = size;
wolfSSL 13:f67a6c6013ca 2968 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 2969 #ifdef HAVE_WOLF_BIGINT
wolfSSL 13:f67a6c6013ca 2970 wc_bigint_init(&a->raw);
wolfSSL 13:f67a6c6013ca 2971 #endif
wolfSSL 13:f67a6c6013ca 2972
wolfSSL 13:f67a6c6013ca 2973 /* zero the digits */
wolfSSL 13:f67a6c6013ca 2974 for (x = 0; x < size; x++) {
wolfSSL 13:f67a6c6013ca 2975 a->dp[x] = 0;
wolfSSL 13:f67a6c6013ca 2976 }
wolfSSL 13:f67a6c6013ca 2977
wolfSSL 13:f67a6c6013ca 2978 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 2979 }
wolfSSL 13:f67a6c6013ca 2980
wolfSSL 13:f67a6c6013ca 2981
wolfSSL 13:f67a6c6013ca 2982 /* the jist of squaring...
wolfSSL 13:f67a6c6013ca 2983 * you do like mult except the offset of the tmpx [one that
wolfSSL 13:f67a6c6013ca 2984 * starts closer to zero] can't equal the offset of tmpy.
wolfSSL 13:f67a6c6013ca 2985 * So basically you set up iy like before then you min it with
wolfSSL 13:f67a6c6013ca 2986 * (ty-tx) so that it never happens. You double all those
wolfSSL 13:f67a6c6013ca 2987 * you add in the inner loop
wolfSSL 13:f67a6c6013ca 2988
wolfSSL 13:f67a6c6013ca 2989 After that loop you do the squares and add them in.
wolfSSL 13:f67a6c6013ca 2990 */
wolfSSL 13:f67a6c6013ca 2991
wolfSSL 13:f67a6c6013ca 2992 int fast_s_mp_sqr (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 2993 {
wolfSSL 13:f67a6c6013ca 2994 int olduse, res, pa, ix, iz;
wolfSSL 13:f67a6c6013ca 2995 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 2996 mp_digit* W; /* uses dynamic memory and slower */
wolfSSL 13:f67a6c6013ca 2997 #else
wolfSSL 13:f67a6c6013ca 2998 mp_digit W[MP_WARRAY];
wolfSSL 13:f67a6c6013ca 2999 #endif
wolfSSL 13:f67a6c6013ca 3000 mp_digit *tmpx;
wolfSSL 13:f67a6c6013ca 3001 mp_word W1;
wolfSSL 13:f67a6c6013ca 3002
wolfSSL 13:f67a6c6013ca 3003 /* grow the destination as required */
wolfSSL 13:f67a6c6013ca 3004 pa = a->used + a->used;
wolfSSL 13:f67a6c6013ca 3005 if (b->alloc < pa) {
wolfSSL 13:f67a6c6013ca 3006 if ((res = mp_grow (b, pa)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3007 return res;
wolfSSL 13:f67a6c6013ca 3008 }
wolfSSL 13:f67a6c6013ca 3009 }
wolfSSL 13:f67a6c6013ca 3010
wolfSSL 13:f67a6c6013ca 3011 if (pa > MP_WARRAY)
wolfSSL 13:f67a6c6013ca 3012 return MP_RANGE; /* TAO range check */
wolfSSL 13:f67a6c6013ca 3013
wolfSSL 13:f67a6c6013ca 3014 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3015 W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 3016 if (W == NULL)
wolfSSL 13:f67a6c6013ca 3017 return MP_MEM;
wolfSSL 13:f67a6c6013ca 3018 #endif
wolfSSL 13:f67a6c6013ca 3019
wolfSSL 13:f67a6c6013ca 3020 /* number of output digits to produce */
wolfSSL 13:f67a6c6013ca 3021 W1 = 0;
wolfSSL 13:f67a6c6013ca 3022 for (ix = 0; ix < pa; ix++) {
wolfSSL 13:f67a6c6013ca 3023 int tx, ty, iy;
wolfSSL 13:f67a6c6013ca 3024 mp_word _W;
wolfSSL 13:f67a6c6013ca 3025 mp_digit *tmpy;
wolfSSL 13:f67a6c6013ca 3026
wolfSSL 13:f67a6c6013ca 3027 /* clear counter */
wolfSSL 13:f67a6c6013ca 3028 _W = 0;
wolfSSL 13:f67a6c6013ca 3029
wolfSSL 13:f67a6c6013ca 3030 /* get offsets into the two bignums */
wolfSSL 13:f67a6c6013ca 3031 ty = MIN(a->used-1, ix);
wolfSSL 13:f67a6c6013ca 3032 tx = ix - ty;
wolfSSL 13:f67a6c6013ca 3033
wolfSSL 13:f67a6c6013ca 3034 /* setup temp aliases */
wolfSSL 13:f67a6c6013ca 3035 tmpx = a->dp + tx;
wolfSSL 13:f67a6c6013ca 3036 tmpy = a->dp + ty;
wolfSSL 13:f67a6c6013ca 3037
wolfSSL 13:f67a6c6013ca 3038 /* this is the number of times the loop will iterate, essentially
wolfSSL 13:f67a6c6013ca 3039 while (tx++ < a->used && ty-- >= 0) { ... }
wolfSSL 13:f67a6c6013ca 3040 */
wolfSSL 13:f67a6c6013ca 3041 iy = MIN(a->used-tx, ty+1);
wolfSSL 13:f67a6c6013ca 3042
wolfSSL 13:f67a6c6013ca 3043 /* now for squaring tx can never equal ty
wolfSSL 13:f67a6c6013ca 3044 * we halve the distance since they approach at a rate of 2x
wolfSSL 13:f67a6c6013ca 3045 * and we have to round because odd cases need to be executed
wolfSSL 13:f67a6c6013ca 3046 */
wolfSSL 13:f67a6c6013ca 3047 iy = MIN(iy, (ty-tx+1)>>1);
wolfSSL 13:f67a6c6013ca 3048
wolfSSL 13:f67a6c6013ca 3049 /* execute loop */
wolfSSL 13:f67a6c6013ca 3050 for (iz = 0; iz < iy; iz++) {
wolfSSL 13:f67a6c6013ca 3051 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
wolfSSL 13:f67a6c6013ca 3052 }
wolfSSL 13:f67a6c6013ca 3053
wolfSSL 13:f67a6c6013ca 3054 /* double the inner product and add carry */
wolfSSL 13:f67a6c6013ca 3055 _W = _W + _W + W1;
wolfSSL 13:f67a6c6013ca 3056
wolfSSL 13:f67a6c6013ca 3057 /* even columns have the square term in them */
wolfSSL 13:f67a6c6013ca 3058 if ((ix&1) == 0) {
wolfSSL 13:f67a6c6013ca 3059 _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
wolfSSL 13:f67a6c6013ca 3060 }
wolfSSL 13:f67a6c6013ca 3061
wolfSSL 13:f67a6c6013ca 3062 /* store it */
wolfSSL 13:f67a6c6013ca 3063 W[ix] = (mp_digit)(_W & MP_MASK);
wolfSSL 13:f67a6c6013ca 3064
wolfSSL 13:f67a6c6013ca 3065 /* make next carry */
wolfSSL 13:f67a6c6013ca 3066 W1 = _W >> ((mp_word)DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 3067 }
wolfSSL 13:f67a6c6013ca 3068
wolfSSL 13:f67a6c6013ca 3069 /* setup dest */
wolfSSL 13:f67a6c6013ca 3070 olduse = b->used;
wolfSSL 13:f67a6c6013ca 3071 b->used = a->used+a->used;
wolfSSL 13:f67a6c6013ca 3072
wolfSSL 13:f67a6c6013ca 3073 {
wolfSSL 13:f67a6c6013ca 3074 mp_digit *tmpb;
wolfSSL 13:f67a6c6013ca 3075 tmpb = b->dp;
wolfSSL 13:f67a6c6013ca 3076 for (ix = 0; ix < pa; ix++) {
wolfSSL 13:f67a6c6013ca 3077 *tmpb++ = (mp_digit)(W[ix] & MP_MASK);
wolfSSL 13:f67a6c6013ca 3078 }
wolfSSL 13:f67a6c6013ca 3079
wolfSSL 13:f67a6c6013ca 3080 /* clear unused digits [that existed in the old copy of c] */
wolfSSL 13:f67a6c6013ca 3081 for (; ix < olduse; ix++) {
wolfSSL 13:f67a6c6013ca 3082 *tmpb++ = 0;
wolfSSL 13:f67a6c6013ca 3083 }
wolfSSL 13:f67a6c6013ca 3084 }
wolfSSL 13:f67a6c6013ca 3085 mp_clamp (b);
wolfSSL 13:f67a6c6013ca 3086
wolfSSL 13:f67a6c6013ca 3087 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3088 XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 3089 #endif
wolfSSL 13:f67a6c6013ca 3090
wolfSSL 13:f67a6c6013ca 3091 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3092 }
wolfSSL 13:f67a6c6013ca 3093
wolfSSL 13:f67a6c6013ca 3094
wolfSSL 13:f67a6c6013ca 3095 /* Fast (comba) multiplier
wolfSSL 13:f67a6c6013ca 3096 *
wolfSSL 13:f67a6c6013ca 3097 * This is the fast column-array [comba] multiplier. It is
wolfSSL 13:f67a6c6013ca 3098 * designed to compute the columns of the product first
wolfSSL 13:f67a6c6013ca 3099 * then handle the carries afterwards. This has the effect
wolfSSL 13:f67a6c6013ca 3100 * of making the nested loops that compute the columns very
wolfSSL 13:f67a6c6013ca 3101 * simple and schedulable on super-scalar processors.
wolfSSL 13:f67a6c6013ca 3102 *
wolfSSL 13:f67a6c6013ca 3103 * This has been modified to produce a variable number of
wolfSSL 13:f67a6c6013ca 3104 * digits of output so if say only a half-product is required
wolfSSL 13:f67a6c6013ca 3105 * you don't have to compute the upper half (a feature
wolfSSL 13:f67a6c6013ca 3106 * required for fast Barrett reduction).
wolfSSL 13:f67a6c6013ca 3107 *
wolfSSL 13:f67a6c6013ca 3108 * Based on Algorithm 14.12 on pp.595 of HAC.
wolfSSL 13:f67a6c6013ca 3109 *
wolfSSL 13:f67a6c6013ca 3110 */
wolfSSL 13:f67a6c6013ca 3111 int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
wolfSSL 13:f67a6c6013ca 3112 {
wolfSSL 13:f67a6c6013ca 3113 int olduse, res, pa, ix, iz;
wolfSSL 13:f67a6c6013ca 3114 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3115 mp_digit* W; /* uses dynamic memory and slower */
wolfSSL 13:f67a6c6013ca 3116 #else
wolfSSL 13:f67a6c6013ca 3117 mp_digit W[MP_WARRAY];
wolfSSL 13:f67a6c6013ca 3118 #endif
wolfSSL 13:f67a6c6013ca 3119 mp_word _W;
wolfSSL 13:f67a6c6013ca 3120
wolfSSL 13:f67a6c6013ca 3121 /* grow the destination as required */
wolfSSL 13:f67a6c6013ca 3122 if (c->alloc < digs) {
wolfSSL 13:f67a6c6013ca 3123 if ((res = mp_grow (c, digs)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3124 return res;
wolfSSL 13:f67a6c6013ca 3125 }
wolfSSL 13:f67a6c6013ca 3126 }
wolfSSL 13:f67a6c6013ca 3127
wolfSSL 13:f67a6c6013ca 3128 /* number of output digits to produce */
wolfSSL 13:f67a6c6013ca 3129 pa = MIN(digs, a->used + b->used);
wolfSSL 13:f67a6c6013ca 3130 if (pa > MP_WARRAY)
wolfSSL 13:f67a6c6013ca 3131 return MP_RANGE; /* TAO range check */
wolfSSL 13:f67a6c6013ca 3132
wolfSSL 13:f67a6c6013ca 3133 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3134 W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 3135 if (W == NULL)
wolfSSL 13:f67a6c6013ca 3136 return MP_MEM;
wolfSSL 13:f67a6c6013ca 3137 #endif
wolfSSL 13:f67a6c6013ca 3138
wolfSSL 13:f67a6c6013ca 3139 /* clear the carry */
wolfSSL 13:f67a6c6013ca 3140 _W = 0;
wolfSSL 13:f67a6c6013ca 3141 for (ix = 0; ix < pa; ix++) {
wolfSSL 13:f67a6c6013ca 3142 int tx, ty;
wolfSSL 13:f67a6c6013ca 3143 int iy;
wolfSSL 13:f67a6c6013ca 3144 mp_digit *tmpx, *tmpy;
wolfSSL 13:f67a6c6013ca 3145
wolfSSL 13:f67a6c6013ca 3146 /* get offsets into the two bignums */
wolfSSL 13:f67a6c6013ca 3147 ty = MIN(b->used-1, ix);
wolfSSL 13:f67a6c6013ca 3148 tx = ix - ty;
wolfSSL 13:f67a6c6013ca 3149
wolfSSL 13:f67a6c6013ca 3150 /* setup temp aliases */
wolfSSL 13:f67a6c6013ca 3151 tmpx = a->dp + tx;
wolfSSL 13:f67a6c6013ca 3152 tmpy = b->dp + ty;
wolfSSL 13:f67a6c6013ca 3153
wolfSSL 13:f67a6c6013ca 3154 /* this is the number of times the loop will iterate, essentially
wolfSSL 13:f67a6c6013ca 3155 while (tx++ < a->used && ty-- >= 0) { ... }
wolfSSL 13:f67a6c6013ca 3156 */
wolfSSL 13:f67a6c6013ca 3157 iy = MIN(a->used-tx, ty+1);
wolfSSL 13:f67a6c6013ca 3158
wolfSSL 13:f67a6c6013ca 3159 /* execute loop */
wolfSSL 13:f67a6c6013ca 3160 for (iz = 0; iz < iy; ++iz) {
wolfSSL 13:f67a6c6013ca 3161 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
wolfSSL 13:f67a6c6013ca 3162
wolfSSL 13:f67a6c6013ca 3163 }
wolfSSL 13:f67a6c6013ca 3164
wolfSSL 13:f67a6c6013ca 3165 /* store term */
wolfSSL 13:f67a6c6013ca 3166 W[ix] = (mp_digit)(((mp_digit)_W) & MP_MASK);
wolfSSL 13:f67a6c6013ca 3167
wolfSSL 13:f67a6c6013ca 3168 /* make next carry */
wolfSSL 13:f67a6c6013ca 3169 _W = _W >> ((mp_word)DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 3170 }
wolfSSL 13:f67a6c6013ca 3171
wolfSSL 13:f67a6c6013ca 3172 /* setup dest */
wolfSSL 13:f67a6c6013ca 3173 olduse = c->used;
wolfSSL 13:f67a6c6013ca 3174 c->used = pa;
wolfSSL 13:f67a6c6013ca 3175
wolfSSL 13:f67a6c6013ca 3176 {
wolfSSL 13:f67a6c6013ca 3177 mp_digit *tmpc;
wolfSSL 13:f67a6c6013ca 3178 tmpc = c->dp;
wolfSSL 13:f67a6c6013ca 3179 for (ix = 0; ix < pa; ix++) { /* JRB, +1 could read uninitialized data */
wolfSSL 13:f67a6c6013ca 3180 /* now extract the previous digit [below the carry] */
wolfSSL 13:f67a6c6013ca 3181 *tmpc++ = W[ix];
wolfSSL 13:f67a6c6013ca 3182 }
wolfSSL 13:f67a6c6013ca 3183
wolfSSL 13:f67a6c6013ca 3184 /* clear unused digits [that existed in the old copy of c] */
wolfSSL 13:f67a6c6013ca 3185 for (; ix < olduse; ix++) {
wolfSSL 13:f67a6c6013ca 3186 *tmpc++ = 0;
wolfSSL 13:f67a6c6013ca 3187 }
wolfSSL 13:f67a6c6013ca 3188 }
wolfSSL 13:f67a6c6013ca 3189 mp_clamp (c);
wolfSSL 13:f67a6c6013ca 3190
wolfSSL 13:f67a6c6013ca 3191 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3192 XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 3193 #endif
wolfSSL 13:f67a6c6013ca 3194
wolfSSL 13:f67a6c6013ca 3195 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3196 }
wolfSSL 13:f67a6c6013ca 3197
wolfSSL 13:f67a6c6013ca 3198
wolfSSL 13:f67a6c6013ca 3199 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
wolfSSL 13:f67a6c6013ca 3200 int s_mp_sqr (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 3201 {
wolfSSL 13:f67a6c6013ca 3202 mp_int t;
wolfSSL 13:f67a6c6013ca 3203 int res, ix, iy, pa;
wolfSSL 13:f67a6c6013ca 3204 mp_word r;
wolfSSL 13:f67a6c6013ca 3205 mp_digit u, tmpx, *tmpt;
wolfSSL 13:f67a6c6013ca 3206
wolfSSL 13:f67a6c6013ca 3207 pa = a->used;
wolfSSL 13:f67a6c6013ca 3208 if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3209 return res;
wolfSSL 13:f67a6c6013ca 3210 }
wolfSSL 13:f67a6c6013ca 3211
wolfSSL 13:f67a6c6013ca 3212 /* default used is maximum possible size */
wolfSSL 13:f67a6c6013ca 3213 t.used = 2*pa + 1;
wolfSSL 13:f67a6c6013ca 3214
wolfSSL 13:f67a6c6013ca 3215 for (ix = 0; ix < pa; ix++) {
wolfSSL 13:f67a6c6013ca 3216 /* first calculate the digit at 2*ix */
wolfSSL 13:f67a6c6013ca 3217 /* calculate double precision result */
wolfSSL 13:f67a6c6013ca 3218 r = ((mp_word) t.dp[2*ix]) +
wolfSSL 13:f67a6c6013ca 3219 ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
wolfSSL 13:f67a6c6013ca 3220
wolfSSL 13:f67a6c6013ca 3221 /* store lower part in result */
wolfSSL 13:f67a6c6013ca 3222 t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 3223
wolfSSL 13:f67a6c6013ca 3224 /* get the carry */
wolfSSL 13:f67a6c6013ca 3225 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 3226
wolfSSL 13:f67a6c6013ca 3227 /* left hand side of A[ix] * A[iy] */
wolfSSL 13:f67a6c6013ca 3228 tmpx = a->dp[ix];
wolfSSL 13:f67a6c6013ca 3229
wolfSSL 13:f67a6c6013ca 3230 /* alias for where to store the results */
wolfSSL 13:f67a6c6013ca 3231 tmpt = t.dp + (2*ix + 1);
wolfSSL 13:f67a6c6013ca 3232
wolfSSL 13:f67a6c6013ca 3233 for (iy = ix + 1; iy < pa; iy++) {
wolfSSL 13:f67a6c6013ca 3234 /* first calculate the product */
wolfSSL 13:f67a6c6013ca 3235 r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
wolfSSL 13:f67a6c6013ca 3236
wolfSSL 13:f67a6c6013ca 3237 /* now calculate the double precision result, note we use
wolfSSL 13:f67a6c6013ca 3238 * addition instead of *2 since it's easier to optimize
wolfSSL 13:f67a6c6013ca 3239 */
wolfSSL 13:f67a6c6013ca 3240 r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
wolfSSL 13:f67a6c6013ca 3241
wolfSSL 13:f67a6c6013ca 3242 /* store lower part */
wolfSSL 13:f67a6c6013ca 3243 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 3244
wolfSSL 13:f67a6c6013ca 3245 /* get carry */
wolfSSL 13:f67a6c6013ca 3246 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 3247 }
wolfSSL 13:f67a6c6013ca 3248 /* propagate upwards */
wolfSSL 13:f67a6c6013ca 3249 while (u != ((mp_digit) 0)) {
wolfSSL 13:f67a6c6013ca 3250 r = ((mp_word) *tmpt) + ((mp_word) u);
wolfSSL 13:f67a6c6013ca 3251 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 3252 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 3253 }
wolfSSL 13:f67a6c6013ca 3254 }
wolfSSL 13:f67a6c6013ca 3255
wolfSSL 13:f67a6c6013ca 3256 mp_clamp (&t);
wolfSSL 13:f67a6c6013ca 3257 mp_exch (&t, b);
wolfSSL 13:f67a6c6013ca 3258 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 3259 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3260 }
wolfSSL 13:f67a6c6013ca 3261
wolfSSL 13:f67a6c6013ca 3262
wolfSSL 13:f67a6c6013ca 3263 /* multiplies |a| * |b| and only computes up to digs digits of result
wolfSSL 13:f67a6c6013ca 3264 * HAC pp. 595, Algorithm 14.12 Modified so you can control how
wolfSSL 13:f67a6c6013ca 3265 * many digits of output are created.
wolfSSL 13:f67a6c6013ca 3266 */
wolfSSL 13:f67a6c6013ca 3267 int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
wolfSSL 13:f67a6c6013ca 3268 {
wolfSSL 13:f67a6c6013ca 3269 mp_int t;
wolfSSL 13:f67a6c6013ca 3270 int res, pa, pb, ix, iy;
wolfSSL 13:f67a6c6013ca 3271 mp_digit u;
wolfSSL 13:f67a6c6013ca 3272 mp_word r;
wolfSSL 13:f67a6c6013ca 3273 mp_digit tmpx, *tmpt, *tmpy;
wolfSSL 13:f67a6c6013ca 3274
wolfSSL 13:f67a6c6013ca 3275 /* can we use the fast multiplier? */
wolfSSL 13:f67a6c6013ca 3276 if (((digs) < MP_WARRAY) &&
wolfSSL 13:f67a6c6013ca 3277 MIN (a->used, b->used) <
wolfSSL 13:f67a6c6013ca 3278 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
wolfSSL 13:f67a6c6013ca 3279 return fast_s_mp_mul_digs (a, b, c, digs);
wolfSSL 13:f67a6c6013ca 3280 }
wolfSSL 13:f67a6c6013ca 3281
wolfSSL 13:f67a6c6013ca 3282 if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3283 return res;
wolfSSL 13:f67a6c6013ca 3284 }
wolfSSL 13:f67a6c6013ca 3285 t.used = digs;
wolfSSL 13:f67a6c6013ca 3286
wolfSSL 13:f67a6c6013ca 3287 /* compute the digits of the product directly */
wolfSSL 13:f67a6c6013ca 3288 pa = a->used;
wolfSSL 13:f67a6c6013ca 3289 for (ix = 0; ix < pa; ix++) {
wolfSSL 13:f67a6c6013ca 3290 /* set the carry to zero */
wolfSSL 13:f67a6c6013ca 3291 u = 0;
wolfSSL 13:f67a6c6013ca 3292
wolfSSL 13:f67a6c6013ca 3293 /* limit ourselves to making digs digits of output */
wolfSSL 13:f67a6c6013ca 3294 pb = MIN (b->used, digs - ix);
wolfSSL 13:f67a6c6013ca 3295
wolfSSL 13:f67a6c6013ca 3296 /* setup some aliases */
wolfSSL 13:f67a6c6013ca 3297 /* copy of the digit from a used within the nested loop */
wolfSSL 13:f67a6c6013ca 3298 tmpx = a->dp[ix];
wolfSSL 13:f67a6c6013ca 3299
wolfSSL 13:f67a6c6013ca 3300 /* an alias for the destination shifted ix places */
wolfSSL 13:f67a6c6013ca 3301 tmpt = t.dp + ix;
wolfSSL 13:f67a6c6013ca 3302
wolfSSL 13:f67a6c6013ca 3303 /* an alias for the digits of b */
wolfSSL 13:f67a6c6013ca 3304 tmpy = b->dp;
wolfSSL 13:f67a6c6013ca 3305
wolfSSL 13:f67a6c6013ca 3306 /* compute the columns of the output and propagate the carry */
wolfSSL 13:f67a6c6013ca 3307 for (iy = 0; iy < pb; iy++) {
wolfSSL 13:f67a6c6013ca 3308 /* compute the column as a mp_word */
wolfSSL 13:f67a6c6013ca 3309 r = ((mp_word)*tmpt) +
wolfSSL 13:f67a6c6013ca 3310 ((mp_word)tmpx) * ((mp_word)*tmpy++) +
wolfSSL 13:f67a6c6013ca 3311 ((mp_word) u);
wolfSSL 13:f67a6c6013ca 3312
wolfSSL 13:f67a6c6013ca 3313 /* the new column is the lower part of the result */
wolfSSL 13:f67a6c6013ca 3314 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 3315
wolfSSL 13:f67a6c6013ca 3316 /* get the carry word from the result */
wolfSSL 13:f67a6c6013ca 3317 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 3318 }
wolfSSL 13:f67a6c6013ca 3319 /* set carry if it is placed below digs */
wolfSSL 13:f67a6c6013ca 3320 if (ix + iy < digs) {
wolfSSL 13:f67a6c6013ca 3321 *tmpt = u;
wolfSSL 13:f67a6c6013ca 3322 }
wolfSSL 13:f67a6c6013ca 3323 }
wolfSSL 13:f67a6c6013ca 3324
wolfSSL 13:f67a6c6013ca 3325 mp_clamp (&t);
wolfSSL 13:f67a6c6013ca 3326 mp_exch (&t, c);
wolfSSL 13:f67a6c6013ca 3327
wolfSSL 13:f67a6c6013ca 3328 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 3329 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3330 }
wolfSSL 13:f67a6c6013ca 3331
wolfSSL 13:f67a6c6013ca 3332
wolfSSL 13:f67a6c6013ca 3333 /*
wolfSSL 13:f67a6c6013ca 3334 * shifts with subtractions when the result is greater than b.
wolfSSL 13:f67a6c6013ca 3335 *
wolfSSL 13:f67a6c6013ca 3336 * The method is slightly modified to shift B unconditionally up to just under
wolfSSL 13:f67a6c6013ca 3337 * the leading bit of b. This saves a lot of multiple precision shifting.
wolfSSL 13:f67a6c6013ca 3338 */
wolfSSL 13:f67a6c6013ca 3339 int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 3340 {
wolfSSL 13:f67a6c6013ca 3341 int x, bits, res;
wolfSSL 13:f67a6c6013ca 3342
wolfSSL 13:f67a6c6013ca 3343 /* how many bits of last digit does b use */
wolfSSL 13:f67a6c6013ca 3344 bits = mp_count_bits (b) % DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 3345
wolfSSL 13:f67a6c6013ca 3346 if (b->used > 1) {
wolfSSL 13:f67a6c6013ca 3347 if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1))
wolfSSL 13:f67a6c6013ca 3348 != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3349 return res;
wolfSSL 13:f67a6c6013ca 3350 }
wolfSSL 13:f67a6c6013ca 3351 } else {
wolfSSL 13:f67a6c6013ca 3352 if ((res = mp_set(a, 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3353 return res;
wolfSSL 13:f67a6c6013ca 3354 }
wolfSSL 13:f67a6c6013ca 3355 bits = 1;
wolfSSL 13:f67a6c6013ca 3356 }
wolfSSL 13:f67a6c6013ca 3357
wolfSSL 13:f67a6c6013ca 3358 /* now compute C = A * B mod b */
wolfSSL 13:f67a6c6013ca 3359 for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
wolfSSL 13:f67a6c6013ca 3360 if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3361 return res;
wolfSSL 13:f67a6c6013ca 3362 }
wolfSSL 13:f67a6c6013ca 3363 if (mp_cmp_mag (a, b) != MP_LT) {
wolfSSL 13:f67a6c6013ca 3364 if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3365 return res;
wolfSSL 13:f67a6c6013ca 3366 }
wolfSSL 13:f67a6c6013ca 3367 }
wolfSSL 13:f67a6c6013ca 3368 }
wolfSSL 13:f67a6c6013ca 3369
wolfSSL 13:f67a6c6013ca 3370 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3371 }
wolfSSL 13:f67a6c6013ca 3372
wolfSSL 13:f67a6c6013ca 3373
wolfSSL 13:f67a6c6013ca 3374 #ifdef MP_LOW_MEM
wolfSSL 13:f67a6c6013ca 3375 #define TAB_SIZE 32
wolfSSL 13:f67a6c6013ca 3376 #else
wolfSSL 13:f67a6c6013ca 3377 #define TAB_SIZE 256
wolfSSL 13:f67a6c6013ca 3378 #endif
wolfSSL 13:f67a6c6013ca 3379
wolfSSL 13:f67a6c6013ca 3380 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
wolfSSL 13:f67a6c6013ca 3381 {
wolfSSL 13:f67a6c6013ca 3382 mp_int M[TAB_SIZE], res, mu;
wolfSSL 13:f67a6c6013ca 3383 mp_digit buf;
wolfSSL 13:f67a6c6013ca 3384 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
wolfSSL 13:f67a6c6013ca 3385 int (*redux)(mp_int*,mp_int*,mp_int*);
wolfSSL 13:f67a6c6013ca 3386
wolfSSL 13:f67a6c6013ca 3387 /* find window size */
wolfSSL 13:f67a6c6013ca 3388 x = mp_count_bits (X);
wolfSSL 13:f67a6c6013ca 3389 if (x <= 7) {
wolfSSL 13:f67a6c6013ca 3390 winsize = 2;
wolfSSL 13:f67a6c6013ca 3391 } else if (x <= 36) {
wolfSSL 13:f67a6c6013ca 3392 winsize = 3;
wolfSSL 13:f67a6c6013ca 3393 } else if (x <= 140) {
wolfSSL 13:f67a6c6013ca 3394 winsize = 4;
wolfSSL 13:f67a6c6013ca 3395 } else if (x <= 450) {
wolfSSL 13:f67a6c6013ca 3396 winsize = 5;
wolfSSL 13:f67a6c6013ca 3397 } else if (x <= 1303) {
wolfSSL 13:f67a6c6013ca 3398 winsize = 6;
wolfSSL 13:f67a6c6013ca 3399 } else if (x <= 3529) {
wolfSSL 13:f67a6c6013ca 3400 winsize = 7;
wolfSSL 13:f67a6c6013ca 3401 } else {
wolfSSL 13:f67a6c6013ca 3402 winsize = 8;
wolfSSL 13:f67a6c6013ca 3403 }
wolfSSL 13:f67a6c6013ca 3404
wolfSSL 13:f67a6c6013ca 3405 #ifdef MP_LOW_MEM
wolfSSL 13:f67a6c6013ca 3406 if (winsize > 5) {
wolfSSL 13:f67a6c6013ca 3407 winsize = 5;
wolfSSL 13:f67a6c6013ca 3408 }
wolfSSL 13:f67a6c6013ca 3409 #endif
wolfSSL 13:f67a6c6013ca 3410
wolfSSL 13:f67a6c6013ca 3411 /* init M array */
wolfSSL 13:f67a6c6013ca 3412 /* init first cell */
wolfSSL 13:f67a6c6013ca 3413 if ((err = mp_init(&M[1])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3414 return err;
wolfSSL 13:f67a6c6013ca 3415 }
wolfSSL 13:f67a6c6013ca 3416
wolfSSL 13:f67a6c6013ca 3417 /* now init the second half of the array */
wolfSSL 13:f67a6c6013ca 3418 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
wolfSSL 13:f67a6c6013ca 3419 if ((err = mp_init(&M[x])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3420 for (y = 1<<(winsize-1); y < x; y++) {
wolfSSL 13:f67a6c6013ca 3421 mp_clear (&M[y]);
wolfSSL 13:f67a6c6013ca 3422 }
wolfSSL 13:f67a6c6013ca 3423 mp_clear(&M[1]);
wolfSSL 13:f67a6c6013ca 3424 return err;
wolfSSL 13:f67a6c6013ca 3425 }
wolfSSL 13:f67a6c6013ca 3426 }
wolfSSL 13:f67a6c6013ca 3427
wolfSSL 13:f67a6c6013ca 3428 /* create mu, used for Barrett reduction */
wolfSSL 13:f67a6c6013ca 3429 if ((err = mp_init (&mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3430 goto LBL_M;
wolfSSL 13:f67a6c6013ca 3431 }
wolfSSL 13:f67a6c6013ca 3432
wolfSSL 13:f67a6c6013ca 3433 if (redmode == 0) {
wolfSSL 13:f67a6c6013ca 3434 if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3435 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3436 }
wolfSSL 13:f67a6c6013ca 3437 redux = mp_reduce;
wolfSSL 13:f67a6c6013ca 3438 } else {
wolfSSL 13:f67a6c6013ca 3439 if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3440 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3441 }
wolfSSL 13:f67a6c6013ca 3442 redux = mp_reduce_2k_l;
wolfSSL 13:f67a6c6013ca 3443 }
wolfSSL 13:f67a6c6013ca 3444
wolfSSL 13:f67a6c6013ca 3445 /* create M table
wolfSSL 13:f67a6c6013ca 3446 *
wolfSSL 13:f67a6c6013ca 3447 * The M table contains powers of the base,
wolfSSL 13:f67a6c6013ca 3448 * e.g. M[x] = G**x mod P
wolfSSL 13:f67a6c6013ca 3449 *
wolfSSL 13:f67a6c6013ca 3450 * The first half of the table is not
wolfSSL 13:f67a6c6013ca 3451 * computed though accept for M[0] and M[1]
wolfSSL 13:f67a6c6013ca 3452 */
wolfSSL 13:f67a6c6013ca 3453 if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3454 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3455 }
wolfSSL 13:f67a6c6013ca 3456
wolfSSL 13:f67a6c6013ca 3457 /* compute the value at M[1<<(winsize-1)] by squaring
wolfSSL 13:f67a6c6013ca 3458 * M[1] (winsize-1) times
wolfSSL 13:f67a6c6013ca 3459 */
wolfSSL 13:f67a6c6013ca 3460 if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3461 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3462 }
wolfSSL 13:f67a6c6013ca 3463
wolfSSL 13:f67a6c6013ca 3464 for (x = 0; x < (winsize - 1); x++) {
wolfSSL 13:f67a6c6013ca 3465 /* square it */
wolfSSL 13:f67a6c6013ca 3466 if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))],
wolfSSL 13:f67a6c6013ca 3467 &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3468 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3469 }
wolfSSL 13:f67a6c6013ca 3470
wolfSSL 13:f67a6c6013ca 3471 /* reduce modulo P */
wolfSSL 13:f67a6c6013ca 3472 if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3473 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3474 }
wolfSSL 13:f67a6c6013ca 3475 }
wolfSSL 13:f67a6c6013ca 3476
wolfSSL 13:f67a6c6013ca 3477 /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
wolfSSL 13:f67a6c6013ca 3478 * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
wolfSSL 13:f67a6c6013ca 3479 */
wolfSSL 13:f67a6c6013ca 3480 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
wolfSSL 13:f67a6c6013ca 3481 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3482 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3483 }
wolfSSL 13:f67a6c6013ca 3484 if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3485 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3486 }
wolfSSL 13:f67a6c6013ca 3487 }
wolfSSL 13:f67a6c6013ca 3488
wolfSSL 13:f67a6c6013ca 3489 /* setup result */
wolfSSL 13:f67a6c6013ca 3490 if ((err = mp_init (&res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3491 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3492 }
wolfSSL 13:f67a6c6013ca 3493 if ((err = mp_set (&res, 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3494 goto LBL_MU;
wolfSSL 13:f67a6c6013ca 3495 }
wolfSSL 13:f67a6c6013ca 3496
wolfSSL 13:f67a6c6013ca 3497 /* set initial mode and bit cnt */
wolfSSL 13:f67a6c6013ca 3498 mode = 0;
wolfSSL 13:f67a6c6013ca 3499 bitcnt = 1;
wolfSSL 13:f67a6c6013ca 3500 buf = 0;
wolfSSL 13:f67a6c6013ca 3501 digidx = X->used - 1;
wolfSSL 13:f67a6c6013ca 3502 bitcpy = 0;
wolfSSL 13:f67a6c6013ca 3503 bitbuf = 0;
wolfSSL 13:f67a6c6013ca 3504
wolfSSL 13:f67a6c6013ca 3505 for (;;) {
wolfSSL 13:f67a6c6013ca 3506 /* grab next digit as required */
wolfSSL 13:f67a6c6013ca 3507 if (--bitcnt == 0) {
wolfSSL 13:f67a6c6013ca 3508 /* if digidx == -1 we are out of digits */
wolfSSL 13:f67a6c6013ca 3509 if (digidx == -1) {
wolfSSL 13:f67a6c6013ca 3510 break;
wolfSSL 13:f67a6c6013ca 3511 }
wolfSSL 13:f67a6c6013ca 3512 /* read next digit and reset the bitcnt */
wolfSSL 13:f67a6c6013ca 3513 buf = X->dp[digidx--];
wolfSSL 13:f67a6c6013ca 3514 bitcnt = (int) DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 3515 }
wolfSSL 13:f67a6c6013ca 3516
wolfSSL 13:f67a6c6013ca 3517 /* grab the next msb from the exponent */
wolfSSL 13:f67a6c6013ca 3518 y = (int)(buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
wolfSSL 13:f67a6c6013ca 3519 buf <<= (mp_digit)1;
wolfSSL 13:f67a6c6013ca 3520
wolfSSL 13:f67a6c6013ca 3521 /* if the bit is zero and mode == 0 then we ignore it
wolfSSL 13:f67a6c6013ca 3522 * These represent the leading zero bits before the first 1 bit
wolfSSL 13:f67a6c6013ca 3523 * in the exponent. Technically this opt is not required but it
wolfSSL 13:f67a6c6013ca 3524 * does lower the # of trivial squaring/reductions used
wolfSSL 13:f67a6c6013ca 3525 */
wolfSSL 13:f67a6c6013ca 3526 if (mode == 0 && y == 0) {
wolfSSL 13:f67a6c6013ca 3527 continue;
wolfSSL 13:f67a6c6013ca 3528 }
wolfSSL 13:f67a6c6013ca 3529
wolfSSL 13:f67a6c6013ca 3530 /* if the bit is zero and mode == 1 then we square */
wolfSSL 13:f67a6c6013ca 3531 if (mode == 1 && y == 0) {
wolfSSL 13:f67a6c6013ca 3532 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3533 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3534 }
wolfSSL 13:f67a6c6013ca 3535 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3536 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3537 }
wolfSSL 13:f67a6c6013ca 3538 continue;
wolfSSL 13:f67a6c6013ca 3539 }
wolfSSL 13:f67a6c6013ca 3540
wolfSSL 13:f67a6c6013ca 3541 /* else we add it to the window */
wolfSSL 13:f67a6c6013ca 3542 bitbuf |= (y << (winsize - ++bitcpy));
wolfSSL 13:f67a6c6013ca 3543 mode = 2;
wolfSSL 13:f67a6c6013ca 3544
wolfSSL 13:f67a6c6013ca 3545 if (bitcpy == winsize) {
wolfSSL 13:f67a6c6013ca 3546 /* ok window is filled so square as required and multiply */
wolfSSL 13:f67a6c6013ca 3547 /* square first */
wolfSSL 13:f67a6c6013ca 3548 for (x = 0; x < winsize; x++) {
wolfSSL 13:f67a6c6013ca 3549 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3550 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3551 }
wolfSSL 13:f67a6c6013ca 3552 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3553 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3554 }
wolfSSL 13:f67a6c6013ca 3555 }
wolfSSL 13:f67a6c6013ca 3556
wolfSSL 13:f67a6c6013ca 3557 /* then multiply */
wolfSSL 13:f67a6c6013ca 3558 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3559 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3560 }
wolfSSL 13:f67a6c6013ca 3561 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3562 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3563 }
wolfSSL 13:f67a6c6013ca 3564
wolfSSL 13:f67a6c6013ca 3565 /* empty window and reset */
wolfSSL 13:f67a6c6013ca 3566 bitcpy = 0;
wolfSSL 13:f67a6c6013ca 3567 bitbuf = 0;
wolfSSL 13:f67a6c6013ca 3568 mode = 1;
wolfSSL 13:f67a6c6013ca 3569 }
wolfSSL 13:f67a6c6013ca 3570 }
wolfSSL 13:f67a6c6013ca 3571
wolfSSL 13:f67a6c6013ca 3572 /* if bits remain then square/multiply */
wolfSSL 13:f67a6c6013ca 3573 if (mode == 2 && bitcpy > 0) {
wolfSSL 13:f67a6c6013ca 3574 /* square then multiply if the bit is set */
wolfSSL 13:f67a6c6013ca 3575 for (x = 0; x < bitcpy; x++) {
wolfSSL 13:f67a6c6013ca 3576 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3577 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3578 }
wolfSSL 13:f67a6c6013ca 3579 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3580 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3581 }
wolfSSL 13:f67a6c6013ca 3582
wolfSSL 13:f67a6c6013ca 3583 bitbuf <<= 1;
wolfSSL 13:f67a6c6013ca 3584 if ((bitbuf & (1 << winsize)) != 0) {
wolfSSL 13:f67a6c6013ca 3585 /* then multiply */
wolfSSL 13:f67a6c6013ca 3586 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3587 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3588 }
wolfSSL 13:f67a6c6013ca 3589 if ((err = redux (&res, P, &mu)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3590 goto LBL_RES;
wolfSSL 13:f67a6c6013ca 3591 }
wolfSSL 13:f67a6c6013ca 3592 }
wolfSSL 13:f67a6c6013ca 3593 }
wolfSSL 13:f67a6c6013ca 3594 }
wolfSSL 13:f67a6c6013ca 3595
wolfSSL 13:f67a6c6013ca 3596 mp_exch (&res, Y);
wolfSSL 13:f67a6c6013ca 3597 err = MP_OKAY;
wolfSSL 13:f67a6c6013ca 3598 LBL_RES:mp_clear (&res);
wolfSSL 13:f67a6c6013ca 3599 LBL_MU:mp_clear (&mu);
wolfSSL 13:f67a6c6013ca 3600 LBL_M:
wolfSSL 13:f67a6c6013ca 3601 mp_clear(&M[1]);
wolfSSL 13:f67a6c6013ca 3602 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
wolfSSL 13:f67a6c6013ca 3603 mp_clear (&M[x]);
wolfSSL 13:f67a6c6013ca 3604 }
wolfSSL 13:f67a6c6013ca 3605 return err;
wolfSSL 13:f67a6c6013ca 3606 }
wolfSSL 13:f67a6c6013ca 3607
wolfSSL 13:f67a6c6013ca 3608
wolfSSL 13:f67a6c6013ca 3609 /* pre-calculate the value required for Barrett reduction
wolfSSL 13:f67a6c6013ca 3610 * For a given modulus "b" it calculates the value required in "a"
wolfSSL 13:f67a6c6013ca 3611 */
wolfSSL 13:f67a6c6013ca 3612 int mp_reduce_setup (mp_int * a, mp_int * b)
wolfSSL 13:f67a6c6013ca 3613 {
wolfSSL 13:f67a6c6013ca 3614 int res;
wolfSSL 13:f67a6c6013ca 3615
wolfSSL 13:f67a6c6013ca 3616 if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3617 return res;
wolfSSL 13:f67a6c6013ca 3618 }
wolfSSL 13:f67a6c6013ca 3619 return mp_div (a, b, a, NULL);
wolfSSL 13:f67a6c6013ca 3620 }
wolfSSL 13:f67a6c6013ca 3621
wolfSSL 13:f67a6c6013ca 3622
wolfSSL 13:f67a6c6013ca 3623 /* reduces x mod m, assumes 0 < x < m**2, mu is
wolfSSL 13:f67a6c6013ca 3624 * precomputed via mp_reduce_setup.
wolfSSL 13:f67a6c6013ca 3625 * From HAC pp.604 Algorithm 14.42
wolfSSL 13:f67a6c6013ca 3626 */
wolfSSL 13:f67a6c6013ca 3627 int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
wolfSSL 13:f67a6c6013ca 3628 {
wolfSSL 13:f67a6c6013ca 3629 mp_int q;
wolfSSL 13:f67a6c6013ca 3630 int res, um = m->used;
wolfSSL 13:f67a6c6013ca 3631
wolfSSL 13:f67a6c6013ca 3632 /* q = x */
wolfSSL 13:f67a6c6013ca 3633 if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3634 return res;
wolfSSL 13:f67a6c6013ca 3635 }
wolfSSL 13:f67a6c6013ca 3636
wolfSSL 13:f67a6c6013ca 3637 /* q1 = x / b**(k-1) */
wolfSSL 13:f67a6c6013ca 3638 mp_rshd (&q, um - 1);
wolfSSL 13:f67a6c6013ca 3639
wolfSSL 13:f67a6c6013ca 3640 /* according to HAC this optimization is ok */
wolfSSL 13:f67a6c6013ca 3641 if (((mp_word) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
wolfSSL 13:f67a6c6013ca 3642 if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3643 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3644 }
wolfSSL 13:f67a6c6013ca 3645 } else {
wolfSSL 13:f67a6c6013ca 3646 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
wolfSSL 13:f67a6c6013ca 3647 if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3648 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3649 }
wolfSSL 13:f67a6c6013ca 3650 #elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
wolfSSL 13:f67a6c6013ca 3651 if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3652 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3653 }
wolfSSL 13:f67a6c6013ca 3654 #else
wolfSSL 13:f67a6c6013ca 3655 {
wolfSSL 13:f67a6c6013ca 3656 res = MP_VAL;
wolfSSL 13:f67a6c6013ca 3657 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3658 }
wolfSSL 13:f67a6c6013ca 3659 #endif
wolfSSL 13:f67a6c6013ca 3660 }
wolfSSL 13:f67a6c6013ca 3661
wolfSSL 13:f67a6c6013ca 3662 /* q3 = q2 / b**(k+1) */
wolfSSL 13:f67a6c6013ca 3663 mp_rshd (&q, um + 1);
wolfSSL 13:f67a6c6013ca 3664
wolfSSL 13:f67a6c6013ca 3665 /* x = x mod b**(k+1), quick (no division) */
wolfSSL 13:f67a6c6013ca 3666 if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3667 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3668 }
wolfSSL 13:f67a6c6013ca 3669
wolfSSL 13:f67a6c6013ca 3670 /* q = q * m mod b**(k+1), quick (no division) */
wolfSSL 13:f67a6c6013ca 3671 if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3672 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3673 }
wolfSSL 13:f67a6c6013ca 3674
wolfSSL 13:f67a6c6013ca 3675 /* x = x - q */
wolfSSL 13:f67a6c6013ca 3676 if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3677 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3678 }
wolfSSL 13:f67a6c6013ca 3679
wolfSSL 13:f67a6c6013ca 3680 /* If x < 0, add b**(k+1) to it */
wolfSSL 13:f67a6c6013ca 3681 if (mp_cmp_d (x, 0) == MP_LT) {
wolfSSL 13:f67a6c6013ca 3682 if ((res = mp_set (&q, 1)) != MP_OKAY)
wolfSSL 13:f67a6c6013ca 3683 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3684 if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
wolfSSL 13:f67a6c6013ca 3685 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3686 if ((res = mp_add (x, &q, x)) != MP_OKAY)
wolfSSL 13:f67a6c6013ca 3687 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3688 }
wolfSSL 13:f67a6c6013ca 3689
wolfSSL 13:f67a6c6013ca 3690 /* Back off if it's too big */
wolfSSL 13:f67a6c6013ca 3691 while (mp_cmp (x, m) != MP_LT) {
wolfSSL 13:f67a6c6013ca 3692 if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3693 goto CLEANUP;
wolfSSL 13:f67a6c6013ca 3694 }
wolfSSL 13:f67a6c6013ca 3695 }
wolfSSL 13:f67a6c6013ca 3696
wolfSSL 13:f67a6c6013ca 3697 CLEANUP:
wolfSSL 13:f67a6c6013ca 3698 mp_clear (&q);
wolfSSL 13:f67a6c6013ca 3699
wolfSSL 13:f67a6c6013ca 3700 return res;
wolfSSL 13:f67a6c6013ca 3701 }
wolfSSL 13:f67a6c6013ca 3702
wolfSSL 13:f67a6c6013ca 3703
wolfSSL 13:f67a6c6013ca 3704 /* reduces a modulo n where n is of the form 2**p - d
wolfSSL 13:f67a6c6013ca 3705 This differs from reduce_2k since "d" can be larger
wolfSSL 13:f67a6c6013ca 3706 than a single digit.
wolfSSL 13:f67a6c6013ca 3707 */
wolfSSL 13:f67a6c6013ca 3708 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
wolfSSL 13:f67a6c6013ca 3709 {
wolfSSL 13:f67a6c6013ca 3710 mp_int q;
wolfSSL 13:f67a6c6013ca 3711 int p, res;
wolfSSL 13:f67a6c6013ca 3712
wolfSSL 13:f67a6c6013ca 3713 if ((res = mp_init(&q)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3714 return res;
wolfSSL 13:f67a6c6013ca 3715 }
wolfSSL 13:f67a6c6013ca 3716
wolfSSL 13:f67a6c6013ca 3717 p = mp_count_bits(n);
wolfSSL 13:f67a6c6013ca 3718 top:
wolfSSL 13:f67a6c6013ca 3719 /* q = a/2**p, a = a mod 2**p */
wolfSSL 13:f67a6c6013ca 3720 if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3721 goto ERR;
wolfSSL 13:f67a6c6013ca 3722 }
wolfSSL 13:f67a6c6013ca 3723
wolfSSL 13:f67a6c6013ca 3724 /* q = q * d */
wolfSSL 13:f67a6c6013ca 3725 if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3726 goto ERR;
wolfSSL 13:f67a6c6013ca 3727 }
wolfSSL 13:f67a6c6013ca 3728
wolfSSL 13:f67a6c6013ca 3729 /* a = a + q */
wolfSSL 13:f67a6c6013ca 3730 if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3731 goto ERR;
wolfSSL 13:f67a6c6013ca 3732 }
wolfSSL 13:f67a6c6013ca 3733
wolfSSL 13:f67a6c6013ca 3734 if (mp_cmp_mag(a, n) != MP_LT) {
wolfSSL 13:f67a6c6013ca 3735 s_mp_sub(a, n, a);
wolfSSL 13:f67a6c6013ca 3736 goto top;
wolfSSL 13:f67a6c6013ca 3737 }
wolfSSL 13:f67a6c6013ca 3738
wolfSSL 13:f67a6c6013ca 3739 ERR:
wolfSSL 13:f67a6c6013ca 3740 mp_clear(&q);
wolfSSL 13:f67a6c6013ca 3741 return res;
wolfSSL 13:f67a6c6013ca 3742 }
wolfSSL 13:f67a6c6013ca 3743
wolfSSL 13:f67a6c6013ca 3744
wolfSSL 13:f67a6c6013ca 3745 /* determines the setup value */
wolfSSL 13:f67a6c6013ca 3746 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
wolfSSL 13:f67a6c6013ca 3747 {
wolfSSL 13:f67a6c6013ca 3748 int res;
wolfSSL 13:f67a6c6013ca 3749 mp_int tmp;
wolfSSL 13:f67a6c6013ca 3750
wolfSSL 13:f67a6c6013ca 3751 if ((res = mp_init(&tmp)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3752 return res;
wolfSSL 13:f67a6c6013ca 3753 }
wolfSSL 13:f67a6c6013ca 3754
wolfSSL 13:f67a6c6013ca 3755 if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3756 goto ERR;
wolfSSL 13:f67a6c6013ca 3757 }
wolfSSL 13:f67a6c6013ca 3758
wolfSSL 13:f67a6c6013ca 3759 if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3760 goto ERR;
wolfSSL 13:f67a6c6013ca 3761 }
wolfSSL 13:f67a6c6013ca 3762
wolfSSL 13:f67a6c6013ca 3763 ERR:
wolfSSL 13:f67a6c6013ca 3764 mp_clear(&tmp);
wolfSSL 13:f67a6c6013ca 3765 return res;
wolfSSL 13:f67a6c6013ca 3766 }
wolfSSL 13:f67a6c6013ca 3767
wolfSSL 13:f67a6c6013ca 3768
wolfSSL 13:f67a6c6013ca 3769 /* multiplies |a| * |b| and does not compute the lower digs digits
wolfSSL 13:f67a6c6013ca 3770 * [meant to get the higher part of the product]
wolfSSL 13:f67a6c6013ca 3771 */
wolfSSL 13:f67a6c6013ca 3772 int s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
wolfSSL 13:f67a6c6013ca 3773 {
wolfSSL 13:f67a6c6013ca 3774 mp_int t;
wolfSSL 13:f67a6c6013ca 3775 int res, pa, pb, ix, iy;
wolfSSL 13:f67a6c6013ca 3776 mp_digit u;
wolfSSL 13:f67a6c6013ca 3777 mp_word r;
wolfSSL 13:f67a6c6013ca 3778 mp_digit tmpx, *tmpt, *tmpy;
wolfSSL 13:f67a6c6013ca 3779
wolfSSL 13:f67a6c6013ca 3780 /* can we use the fast multiplier? */
wolfSSL 13:f67a6c6013ca 3781 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
wolfSSL 13:f67a6c6013ca 3782 if (((a->used + b->used + 1) < MP_WARRAY)
wolfSSL 13:f67a6c6013ca 3783 && MIN (a->used, b->used) <
wolfSSL 13:f67a6c6013ca 3784 (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
wolfSSL 13:f67a6c6013ca 3785 return fast_s_mp_mul_high_digs (a, b, c, digs);
wolfSSL 13:f67a6c6013ca 3786 }
wolfSSL 13:f67a6c6013ca 3787 #endif
wolfSSL 13:f67a6c6013ca 3788
wolfSSL 13:f67a6c6013ca 3789 if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3790 return res;
wolfSSL 13:f67a6c6013ca 3791 }
wolfSSL 13:f67a6c6013ca 3792 t.used = a->used + b->used + 1;
wolfSSL 13:f67a6c6013ca 3793
wolfSSL 13:f67a6c6013ca 3794 pa = a->used;
wolfSSL 13:f67a6c6013ca 3795 pb = b->used;
wolfSSL 13:f67a6c6013ca 3796 for (ix = 0; ix < pa && a->dp; ix++) {
wolfSSL 13:f67a6c6013ca 3797 /* clear the carry */
wolfSSL 13:f67a6c6013ca 3798 u = 0;
wolfSSL 13:f67a6c6013ca 3799
wolfSSL 13:f67a6c6013ca 3800 /* left hand side of A[ix] * B[iy] */
wolfSSL 13:f67a6c6013ca 3801 tmpx = a->dp[ix];
wolfSSL 13:f67a6c6013ca 3802
wolfSSL 13:f67a6c6013ca 3803 /* alias to the address of where the digits will be stored */
wolfSSL 13:f67a6c6013ca 3804 tmpt = &(t.dp[digs]);
wolfSSL 13:f67a6c6013ca 3805
wolfSSL 13:f67a6c6013ca 3806 /* alias for where to read the right hand side from */
wolfSSL 13:f67a6c6013ca 3807 tmpy = b->dp + (digs - ix);
wolfSSL 13:f67a6c6013ca 3808
wolfSSL 13:f67a6c6013ca 3809 for (iy = digs - ix; iy < pb; iy++) {
wolfSSL 13:f67a6c6013ca 3810 /* calculate the double precision result */
wolfSSL 13:f67a6c6013ca 3811 r = ((mp_word)*tmpt) +
wolfSSL 13:f67a6c6013ca 3812 ((mp_word)tmpx) * ((mp_word)*tmpy++) +
wolfSSL 13:f67a6c6013ca 3813 ((mp_word) u);
wolfSSL 13:f67a6c6013ca 3814
wolfSSL 13:f67a6c6013ca 3815 /* get the lower part */
wolfSSL 13:f67a6c6013ca 3816 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
wolfSSL 13:f67a6c6013ca 3817
wolfSSL 13:f67a6c6013ca 3818 /* carry the carry */
wolfSSL 13:f67a6c6013ca 3819 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
wolfSSL 13:f67a6c6013ca 3820 }
wolfSSL 13:f67a6c6013ca 3821 *tmpt = u;
wolfSSL 13:f67a6c6013ca 3822 }
wolfSSL 13:f67a6c6013ca 3823 mp_clamp (&t);
wolfSSL 13:f67a6c6013ca 3824 mp_exch (&t, c);
wolfSSL 13:f67a6c6013ca 3825 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 3826 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3827 }
wolfSSL 13:f67a6c6013ca 3828
wolfSSL 13:f67a6c6013ca 3829
wolfSSL 13:f67a6c6013ca 3830 /* this is a modified version of fast_s_mul_digs that only produces
wolfSSL 13:f67a6c6013ca 3831 * output digits *above* digs. See the comments for fast_s_mul_digs
wolfSSL 13:f67a6c6013ca 3832 * to see how it works.
wolfSSL 13:f67a6c6013ca 3833 *
wolfSSL 13:f67a6c6013ca 3834 * This is used in the Barrett reduction since for one of the multiplications
wolfSSL 13:f67a6c6013ca 3835 * only the higher digits were needed. This essentially halves the work.
wolfSSL 13:f67a6c6013ca 3836 *
wolfSSL 13:f67a6c6013ca 3837 * Based on Algorithm 14.12 on pp.595 of HAC.
wolfSSL 13:f67a6c6013ca 3838 */
wolfSSL 13:f67a6c6013ca 3839 int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
wolfSSL 13:f67a6c6013ca 3840 {
wolfSSL 13:f67a6c6013ca 3841 int olduse, res, pa, ix, iz;
wolfSSL 13:f67a6c6013ca 3842 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3843 mp_digit* W; /* uses dynamic memory and slower */
wolfSSL 13:f67a6c6013ca 3844 #else
wolfSSL 13:f67a6c6013ca 3845 mp_digit W[MP_WARRAY];
wolfSSL 13:f67a6c6013ca 3846 #endif
wolfSSL 13:f67a6c6013ca 3847 mp_word _W;
wolfSSL 13:f67a6c6013ca 3848
wolfSSL 13:f67a6c6013ca 3849 if (a->dp == NULL) { /* JRB, avoid reading uninitialized values */
wolfSSL 13:f67a6c6013ca 3850 return MP_VAL;
wolfSSL 13:f67a6c6013ca 3851 }
wolfSSL 13:f67a6c6013ca 3852
wolfSSL 13:f67a6c6013ca 3853 /* grow the destination as required */
wolfSSL 13:f67a6c6013ca 3854 pa = a->used + b->used;
wolfSSL 13:f67a6c6013ca 3855 if (c->alloc < pa) {
wolfSSL 13:f67a6c6013ca 3856 if ((res = mp_grow (c, pa)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3857 return res;
wolfSSL 13:f67a6c6013ca 3858 }
wolfSSL 13:f67a6c6013ca 3859 }
wolfSSL 13:f67a6c6013ca 3860
wolfSSL 13:f67a6c6013ca 3861 if (pa > MP_WARRAY)
wolfSSL 13:f67a6c6013ca 3862 return MP_RANGE; /* TAO range check */
wolfSSL 13:f67a6c6013ca 3863
wolfSSL 13:f67a6c6013ca 3864 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3865 W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 3866 if (W == NULL)
wolfSSL 13:f67a6c6013ca 3867 return MP_MEM;
wolfSSL 13:f67a6c6013ca 3868 #endif
wolfSSL 13:f67a6c6013ca 3869
wolfSSL 13:f67a6c6013ca 3870 /* number of output digits to produce */
wolfSSL 13:f67a6c6013ca 3871 pa = a->used + b->used;
wolfSSL 13:f67a6c6013ca 3872 _W = 0;
wolfSSL 13:f67a6c6013ca 3873 for (ix = digs; ix < pa; ix++) { /* JRB, have a->dp check at top of function*/
wolfSSL 13:f67a6c6013ca 3874 int tx, ty, iy;
wolfSSL 13:f67a6c6013ca 3875 mp_digit *tmpx, *tmpy;
wolfSSL 13:f67a6c6013ca 3876
wolfSSL 13:f67a6c6013ca 3877 /* get offsets into the two bignums */
wolfSSL 13:f67a6c6013ca 3878 ty = MIN(b->used-1, ix);
wolfSSL 13:f67a6c6013ca 3879 tx = ix - ty;
wolfSSL 13:f67a6c6013ca 3880
wolfSSL 13:f67a6c6013ca 3881 /* setup temp aliases */
wolfSSL 13:f67a6c6013ca 3882 tmpx = a->dp + tx;
wolfSSL 13:f67a6c6013ca 3883 tmpy = b->dp + ty;
wolfSSL 13:f67a6c6013ca 3884
wolfSSL 13:f67a6c6013ca 3885 /* this is the number of times the loop will iterate, essentially its
wolfSSL 13:f67a6c6013ca 3886 while (tx++ < a->used && ty-- >= 0) { ... }
wolfSSL 13:f67a6c6013ca 3887 */
wolfSSL 13:f67a6c6013ca 3888 iy = MIN(a->used-tx, ty+1);
wolfSSL 13:f67a6c6013ca 3889
wolfSSL 13:f67a6c6013ca 3890 /* execute loop */
wolfSSL 13:f67a6c6013ca 3891 for (iz = 0; iz < iy; iz++) {
wolfSSL 13:f67a6c6013ca 3892 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
wolfSSL 13:f67a6c6013ca 3893 }
wolfSSL 13:f67a6c6013ca 3894
wolfSSL 13:f67a6c6013ca 3895 /* store term */
wolfSSL 13:f67a6c6013ca 3896 W[ix] = (mp_digit)(((mp_digit)_W) & MP_MASK);
wolfSSL 13:f67a6c6013ca 3897
wolfSSL 13:f67a6c6013ca 3898 /* make next carry */
wolfSSL 13:f67a6c6013ca 3899 _W = _W >> ((mp_word)DIGIT_BIT);
wolfSSL 13:f67a6c6013ca 3900 }
wolfSSL 13:f67a6c6013ca 3901
wolfSSL 13:f67a6c6013ca 3902 /* setup dest */
wolfSSL 13:f67a6c6013ca 3903 olduse = c->used;
wolfSSL 13:f67a6c6013ca 3904 c->used = pa;
wolfSSL 13:f67a6c6013ca 3905
wolfSSL 13:f67a6c6013ca 3906 {
wolfSSL 13:f67a6c6013ca 3907 mp_digit *tmpc;
wolfSSL 13:f67a6c6013ca 3908
wolfSSL 13:f67a6c6013ca 3909 tmpc = c->dp + digs;
wolfSSL 13:f67a6c6013ca 3910 for (ix = digs; ix < pa; ix++) { /* TAO, <= could potentially overwrite */
wolfSSL 13:f67a6c6013ca 3911 /* now extract the previous digit [below the carry] */
wolfSSL 13:f67a6c6013ca 3912 *tmpc++ = W[ix];
wolfSSL 13:f67a6c6013ca 3913 }
wolfSSL 13:f67a6c6013ca 3914
wolfSSL 13:f67a6c6013ca 3915 /* clear unused digits [that existed in the old copy of c] */
wolfSSL 13:f67a6c6013ca 3916 for (; ix < olduse; ix++) {
wolfSSL 13:f67a6c6013ca 3917 *tmpc++ = 0;
wolfSSL 13:f67a6c6013ca 3918 }
wolfSSL 13:f67a6c6013ca 3919 }
wolfSSL 13:f67a6c6013ca 3920 mp_clamp (c);
wolfSSL 13:f67a6c6013ca 3921
wolfSSL 13:f67a6c6013ca 3922 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 13:f67a6c6013ca 3923 XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
wolfSSL 13:f67a6c6013ca 3924 #endif
wolfSSL 13:f67a6c6013ca 3925
wolfSSL 13:f67a6c6013ca 3926 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3927 }
wolfSSL 13:f67a6c6013ca 3928
wolfSSL 13:f67a6c6013ca 3929
wolfSSL 13:f67a6c6013ca 3930 #ifndef MP_SET_CHUNK_BITS
wolfSSL 13:f67a6c6013ca 3931 #define MP_SET_CHUNK_BITS 4
wolfSSL 13:f67a6c6013ca 3932 #endif
wolfSSL 13:f67a6c6013ca 3933 int mp_set_int (mp_int * a, unsigned long b)
wolfSSL 13:f67a6c6013ca 3934 {
wolfSSL 13:f67a6c6013ca 3935 int x, res;
wolfSSL 13:f67a6c6013ca 3936
wolfSSL 13:f67a6c6013ca 3937 /* use direct mp_set if b is less than mp_digit max */
wolfSSL 13:f67a6c6013ca 3938 if (b < MP_DIGIT_MAX) {
wolfSSL 13:f67a6c6013ca 3939 return mp_set (a, (mp_digit)b);
wolfSSL 13:f67a6c6013ca 3940 }
wolfSSL 13:f67a6c6013ca 3941
wolfSSL 13:f67a6c6013ca 3942 mp_zero (a);
wolfSSL 13:f67a6c6013ca 3943
wolfSSL 13:f67a6c6013ca 3944 /* set chunk bits at a time */
wolfSSL 13:f67a6c6013ca 3945 for (x = 0; x < (int)(sizeof(b) * 8) / MP_SET_CHUNK_BITS; x++) {
wolfSSL 13:f67a6c6013ca 3946 /* shift the number up chunk bits */
wolfSSL 13:f67a6c6013ca 3947 if ((res = mp_mul_2d (a, MP_SET_CHUNK_BITS, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3948 return res;
wolfSSL 13:f67a6c6013ca 3949 }
wolfSSL 13:f67a6c6013ca 3950
wolfSSL 13:f67a6c6013ca 3951 /* OR in the top bits of the source */
wolfSSL 13:f67a6c6013ca 3952 a->dp[0] |= (b >> ((sizeof(b) * 8) - MP_SET_CHUNK_BITS)) &
wolfSSL 13:f67a6c6013ca 3953 ((1 << MP_SET_CHUNK_BITS) - 1);
wolfSSL 13:f67a6c6013ca 3954
wolfSSL 13:f67a6c6013ca 3955 /* shift the source up to the next chunk bits */
wolfSSL 13:f67a6c6013ca 3956 b <<= MP_SET_CHUNK_BITS;
wolfSSL 13:f67a6c6013ca 3957
wolfSSL 13:f67a6c6013ca 3958 /* ensure that digits are not clamped off */
wolfSSL 13:f67a6c6013ca 3959 a->used += 1;
wolfSSL 13:f67a6c6013ca 3960 }
wolfSSL 13:f67a6c6013ca 3961 mp_clamp (a);
wolfSSL 13:f67a6c6013ca 3962 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 3963 }
wolfSSL 13:f67a6c6013ca 3964
wolfSSL 13:f67a6c6013ca 3965
wolfSSL 13:f67a6c6013ca 3966 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC)
wolfSSL 13:f67a6c6013ca 3967
wolfSSL 13:f67a6c6013ca 3968 /* c = a * a (mod b) */
wolfSSL 13:f67a6c6013ca 3969 int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 3970 {
wolfSSL 13:f67a6c6013ca 3971 int res;
wolfSSL 13:f67a6c6013ca 3972 mp_int t;
wolfSSL 13:f67a6c6013ca 3973
wolfSSL 13:f67a6c6013ca 3974 if ((res = mp_init (&t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3975 return res;
wolfSSL 13:f67a6c6013ca 3976 }
wolfSSL 13:f67a6c6013ca 3977
wolfSSL 13:f67a6c6013ca 3978 if ((res = mp_sqr (a, &t)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 3979 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 3980 return res;
wolfSSL 13:f67a6c6013ca 3981 }
wolfSSL 13:f67a6c6013ca 3982 res = mp_mod (&t, b, c);
wolfSSL 13:f67a6c6013ca 3983 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 3984 return res;
wolfSSL 13:f67a6c6013ca 3985 }
wolfSSL 13:f67a6c6013ca 3986
wolfSSL 13:f67a6c6013ca 3987 #endif
wolfSSL 13:f67a6c6013ca 3988
wolfSSL 13:f67a6c6013ca 3989
wolfSSL 13:f67a6c6013ca 3990 #if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(WOLFSSL_SNIFFER) || \
wolfSSL 13:f67a6c6013ca 3991 defined(WOLFSSL_HAVE_WOLFSCEP) || defined(WOLFSSL_KEY_GEN) || \
wolfSSL 13:f67a6c6013ca 3992 defined(OPENSSL_EXTRA) || defined(WC_RSA_BLINDING)
wolfSSL 13:f67a6c6013ca 3993
wolfSSL 13:f67a6c6013ca 3994 /* single digit addition */
wolfSSL 13:f67a6c6013ca 3995 int mp_add_d (mp_int* a, mp_digit b, mp_int* c)
wolfSSL 13:f67a6c6013ca 3996 {
wolfSSL 13:f67a6c6013ca 3997 int res, ix, oldused;
wolfSSL 13:f67a6c6013ca 3998 mp_digit *tmpa, *tmpc, mu;
wolfSSL 13:f67a6c6013ca 3999
wolfSSL 13:f67a6c6013ca 4000 /* grow c as required */
wolfSSL 13:f67a6c6013ca 4001 if (c->alloc < a->used + 1) {
wolfSSL 13:f67a6c6013ca 4002 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4003 return res;
wolfSSL 13:f67a6c6013ca 4004 }
wolfSSL 13:f67a6c6013ca 4005 }
wolfSSL 13:f67a6c6013ca 4006
wolfSSL 13:f67a6c6013ca 4007 /* if a is negative and |a| >= b, call c = |a| - b */
wolfSSL 13:f67a6c6013ca 4008 if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
wolfSSL 13:f67a6c6013ca 4009 /* temporarily fix sign of a */
wolfSSL 13:f67a6c6013ca 4010 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4011
wolfSSL 13:f67a6c6013ca 4012 /* c = |a| - b */
wolfSSL 13:f67a6c6013ca 4013 res = mp_sub_d(a, b, c);
wolfSSL 13:f67a6c6013ca 4014
wolfSSL 13:f67a6c6013ca 4015 /* fix sign */
wolfSSL 13:f67a6c6013ca 4016 a->sign = c->sign = MP_NEG;
wolfSSL 13:f67a6c6013ca 4017
wolfSSL 13:f67a6c6013ca 4018 /* clamp */
wolfSSL 13:f67a6c6013ca 4019 mp_clamp(c);
wolfSSL 13:f67a6c6013ca 4020
wolfSSL 13:f67a6c6013ca 4021 return res;
wolfSSL 13:f67a6c6013ca 4022 }
wolfSSL 13:f67a6c6013ca 4023
wolfSSL 13:f67a6c6013ca 4024 /* old number of used digits in c */
wolfSSL 13:f67a6c6013ca 4025 oldused = c->used;
wolfSSL 13:f67a6c6013ca 4026
wolfSSL 13:f67a6c6013ca 4027 /* sign always positive */
wolfSSL 13:f67a6c6013ca 4028 c->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4029
wolfSSL 13:f67a6c6013ca 4030 /* source alias */
wolfSSL 13:f67a6c6013ca 4031 tmpa = a->dp;
wolfSSL 13:f67a6c6013ca 4032
wolfSSL 13:f67a6c6013ca 4033 /* destination alias */
wolfSSL 13:f67a6c6013ca 4034 tmpc = c->dp;
wolfSSL 13:f67a6c6013ca 4035
wolfSSL 13:f67a6c6013ca 4036 /* if a is positive */
wolfSSL 13:f67a6c6013ca 4037 if (a->sign == MP_ZPOS) {
wolfSSL 13:f67a6c6013ca 4038 /* add digit, after this we're propagating
wolfSSL 13:f67a6c6013ca 4039 * the carry.
wolfSSL 13:f67a6c6013ca 4040 */
wolfSSL 13:f67a6c6013ca 4041 *tmpc = *tmpa++ + b;
wolfSSL 13:f67a6c6013ca 4042 mu = *tmpc >> DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 4043 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 4044
wolfSSL 13:f67a6c6013ca 4045 /* now handle rest of the digits */
wolfSSL 13:f67a6c6013ca 4046 for (ix = 1; ix < a->used; ix++) {
wolfSSL 13:f67a6c6013ca 4047 *tmpc = *tmpa++ + mu;
wolfSSL 13:f67a6c6013ca 4048 mu = *tmpc >> DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 4049 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 4050 }
wolfSSL 13:f67a6c6013ca 4051 /* set final carry */
wolfSSL 13:f67a6c6013ca 4052 if (ix < c->alloc) {
wolfSSL 13:f67a6c6013ca 4053 ix++;
wolfSSL 13:f67a6c6013ca 4054 *tmpc++ = mu;
wolfSSL 13:f67a6c6013ca 4055 }
wolfSSL 13:f67a6c6013ca 4056
wolfSSL 13:f67a6c6013ca 4057 /* setup size */
wolfSSL 13:f67a6c6013ca 4058 c->used = a->used + 1;
wolfSSL 13:f67a6c6013ca 4059 } else {
wolfSSL 13:f67a6c6013ca 4060 /* a was negative and |a| < b */
wolfSSL 13:f67a6c6013ca 4061 c->used = 1;
wolfSSL 13:f67a6c6013ca 4062
wolfSSL 13:f67a6c6013ca 4063 /* the result is a single digit */
wolfSSL 13:f67a6c6013ca 4064 if (a->used == 1) {
wolfSSL 13:f67a6c6013ca 4065 *tmpc++ = b - a->dp[0];
wolfSSL 13:f67a6c6013ca 4066 } else {
wolfSSL 13:f67a6c6013ca 4067 *tmpc++ = b;
wolfSSL 13:f67a6c6013ca 4068 }
wolfSSL 13:f67a6c6013ca 4069
wolfSSL 13:f67a6c6013ca 4070 /* setup count so the clearing of oldused
wolfSSL 13:f67a6c6013ca 4071 * can fall through correctly
wolfSSL 13:f67a6c6013ca 4072 */
wolfSSL 13:f67a6c6013ca 4073 ix = 1;
wolfSSL 13:f67a6c6013ca 4074 }
wolfSSL 13:f67a6c6013ca 4075
wolfSSL 13:f67a6c6013ca 4076 /* now zero to oldused */
wolfSSL 13:f67a6c6013ca 4077 while (ix++ < oldused) {
wolfSSL 13:f67a6c6013ca 4078 *tmpc++ = 0;
wolfSSL 13:f67a6c6013ca 4079 }
wolfSSL 13:f67a6c6013ca 4080 mp_clamp(c);
wolfSSL 13:f67a6c6013ca 4081
wolfSSL 13:f67a6c6013ca 4082 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4083 }
wolfSSL 13:f67a6c6013ca 4084
wolfSSL 13:f67a6c6013ca 4085
wolfSSL 13:f67a6c6013ca 4086 /* single digit subtraction */
wolfSSL 13:f67a6c6013ca 4087 int mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
wolfSSL 13:f67a6c6013ca 4088 {
wolfSSL 13:f67a6c6013ca 4089 mp_digit *tmpa, *tmpc, mu;
wolfSSL 13:f67a6c6013ca 4090 int res, ix, oldused;
wolfSSL 13:f67a6c6013ca 4091
wolfSSL 13:f67a6c6013ca 4092 /* grow c as required */
wolfSSL 13:f67a6c6013ca 4093 if (c->alloc < a->used + 1) {
wolfSSL 13:f67a6c6013ca 4094 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4095 return res;
wolfSSL 13:f67a6c6013ca 4096 }
wolfSSL 13:f67a6c6013ca 4097 }
wolfSSL 13:f67a6c6013ca 4098
wolfSSL 13:f67a6c6013ca 4099 /* if a is negative just do an unsigned
wolfSSL 13:f67a6c6013ca 4100 * addition [with fudged signs]
wolfSSL 13:f67a6c6013ca 4101 */
wolfSSL 13:f67a6c6013ca 4102 if (a->sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 4103 a->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4104 res = mp_add_d(a, b, c);
wolfSSL 13:f67a6c6013ca 4105 a->sign = c->sign = MP_NEG;
wolfSSL 13:f67a6c6013ca 4106
wolfSSL 13:f67a6c6013ca 4107 /* clamp */
wolfSSL 13:f67a6c6013ca 4108 mp_clamp(c);
wolfSSL 13:f67a6c6013ca 4109
wolfSSL 13:f67a6c6013ca 4110 return res;
wolfSSL 13:f67a6c6013ca 4111 }
wolfSSL 13:f67a6c6013ca 4112
wolfSSL 13:f67a6c6013ca 4113 /* setup regs */
wolfSSL 13:f67a6c6013ca 4114 oldused = c->used;
wolfSSL 13:f67a6c6013ca 4115 tmpa = a->dp;
wolfSSL 13:f67a6c6013ca 4116 tmpc = c->dp;
wolfSSL 13:f67a6c6013ca 4117
wolfSSL 13:f67a6c6013ca 4118 /* if a <= b simply fix the single digit */
wolfSSL 13:f67a6c6013ca 4119 if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
wolfSSL 13:f67a6c6013ca 4120 if (a->used == 1) {
wolfSSL 13:f67a6c6013ca 4121 *tmpc++ = b - *tmpa;
wolfSSL 13:f67a6c6013ca 4122 } else {
wolfSSL 13:f67a6c6013ca 4123 *tmpc++ = b;
wolfSSL 13:f67a6c6013ca 4124 }
wolfSSL 13:f67a6c6013ca 4125 ix = 1;
wolfSSL 13:f67a6c6013ca 4126
wolfSSL 13:f67a6c6013ca 4127 /* negative/1digit */
wolfSSL 13:f67a6c6013ca 4128 c->sign = MP_NEG;
wolfSSL 13:f67a6c6013ca 4129 c->used = 1;
wolfSSL 13:f67a6c6013ca 4130 } else {
wolfSSL 13:f67a6c6013ca 4131 /* positive/size */
wolfSSL 13:f67a6c6013ca 4132 c->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4133 c->used = a->used;
wolfSSL 13:f67a6c6013ca 4134
wolfSSL 13:f67a6c6013ca 4135 /* subtract first digit */
wolfSSL 13:f67a6c6013ca 4136 *tmpc = *tmpa++ - b;
wolfSSL 13:f67a6c6013ca 4137 mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
wolfSSL 13:f67a6c6013ca 4138 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 4139
wolfSSL 13:f67a6c6013ca 4140 /* handle rest of the digits */
wolfSSL 13:f67a6c6013ca 4141 for (ix = 1; ix < a->used; ix++) {
wolfSSL 13:f67a6c6013ca 4142 *tmpc = *tmpa++ - mu;
wolfSSL 13:f67a6c6013ca 4143 mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
wolfSSL 13:f67a6c6013ca 4144 *tmpc++ &= MP_MASK;
wolfSSL 13:f67a6c6013ca 4145 }
wolfSSL 13:f67a6c6013ca 4146 }
wolfSSL 13:f67a6c6013ca 4147
wolfSSL 13:f67a6c6013ca 4148 /* zero excess digits */
wolfSSL 13:f67a6c6013ca 4149 while (ix++ < oldused) {
wolfSSL 13:f67a6c6013ca 4150 *tmpc++ = 0;
wolfSSL 13:f67a6c6013ca 4151 }
wolfSSL 13:f67a6c6013ca 4152 mp_clamp(c);
wolfSSL 13:f67a6c6013ca 4153 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4154 }
wolfSSL 13:f67a6c6013ca 4155
wolfSSL 13:f67a6c6013ca 4156 #endif /* defined(HAVE_ECC) || !defined(NO_PWDBASED) */
wolfSSL 13:f67a6c6013ca 4157
wolfSSL 13:f67a6c6013ca 4158
wolfSSL 13:f67a6c6013ca 4159 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(HAVE_ECC)
wolfSSL 13:f67a6c6013ca 4160
wolfSSL 13:f67a6c6013ca 4161 static const int lnz[16] = {
wolfSSL 13:f67a6c6013ca 4162 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
wolfSSL 13:f67a6c6013ca 4163 };
wolfSSL 13:f67a6c6013ca 4164
wolfSSL 13:f67a6c6013ca 4165 /* Counts the number of lsbs which are zero before the first zero bit */
wolfSSL 13:f67a6c6013ca 4166 int mp_cnt_lsb(mp_int *a)
wolfSSL 13:f67a6c6013ca 4167 {
wolfSSL 13:f67a6c6013ca 4168 int x;
wolfSSL 13:f67a6c6013ca 4169 mp_digit q = 0, qq;
wolfSSL 13:f67a6c6013ca 4170
wolfSSL 13:f67a6c6013ca 4171 /* easy out */
wolfSSL 13:f67a6c6013ca 4172 if (mp_iszero(a) == MP_YES) {
wolfSSL 13:f67a6c6013ca 4173 return 0;
wolfSSL 13:f67a6c6013ca 4174 }
wolfSSL 13:f67a6c6013ca 4175
wolfSSL 13:f67a6c6013ca 4176 /* scan lower digits until non-zero */
wolfSSL 13:f67a6c6013ca 4177 for (x = 0; x < a->used && a->dp[x] == 0; x++) {}
wolfSSL 13:f67a6c6013ca 4178 if (a->dp)
wolfSSL 13:f67a6c6013ca 4179 q = a->dp[x];
wolfSSL 13:f67a6c6013ca 4180 x *= DIGIT_BIT;
wolfSSL 13:f67a6c6013ca 4181
wolfSSL 13:f67a6c6013ca 4182 /* now scan this digit until a 1 is found */
wolfSSL 13:f67a6c6013ca 4183 if ((q & 1) == 0) {
wolfSSL 13:f67a6c6013ca 4184 do {
wolfSSL 13:f67a6c6013ca 4185 qq = q & 15;
wolfSSL 13:f67a6c6013ca 4186 x += lnz[qq];
wolfSSL 13:f67a6c6013ca 4187 q >>= 4;
wolfSSL 13:f67a6c6013ca 4188 } while (qq == 0);
wolfSSL 13:f67a6c6013ca 4189 }
wolfSSL 13:f67a6c6013ca 4190 return x;
wolfSSL 13:f67a6c6013ca 4191 }
wolfSSL 13:f67a6c6013ca 4192
wolfSSL 13:f67a6c6013ca 4193
wolfSSL 13:f67a6c6013ca 4194
wolfSSL 13:f67a6c6013ca 4195
wolfSSL 13:f67a6c6013ca 4196 static int s_is_power_of_two(mp_digit b, int *p)
wolfSSL 13:f67a6c6013ca 4197 {
wolfSSL 13:f67a6c6013ca 4198 int x;
wolfSSL 13:f67a6c6013ca 4199
wolfSSL 13:f67a6c6013ca 4200 /* fast return if no power of two */
wolfSSL 13:f67a6c6013ca 4201 if ((b==0) || (b & (b-1))) {
wolfSSL 13:f67a6c6013ca 4202 return 0;
wolfSSL 13:f67a6c6013ca 4203 }
wolfSSL 13:f67a6c6013ca 4204
wolfSSL 13:f67a6c6013ca 4205 for (x = 0; x < DIGIT_BIT; x++) {
wolfSSL 13:f67a6c6013ca 4206 if (b == (((mp_digit)1)<<x)) {
wolfSSL 13:f67a6c6013ca 4207 *p = x;
wolfSSL 13:f67a6c6013ca 4208 return 1;
wolfSSL 13:f67a6c6013ca 4209 }
wolfSSL 13:f67a6c6013ca 4210 }
wolfSSL 13:f67a6c6013ca 4211 return 0;
wolfSSL 13:f67a6c6013ca 4212 }
wolfSSL 13:f67a6c6013ca 4213
wolfSSL 13:f67a6c6013ca 4214 /* single digit division (based on routine from MPI) */
wolfSSL 13:f67a6c6013ca 4215 static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
wolfSSL 13:f67a6c6013ca 4216 {
wolfSSL 13:f67a6c6013ca 4217 mp_int q;
wolfSSL 13:f67a6c6013ca 4218 mp_word w;
wolfSSL 13:f67a6c6013ca 4219 mp_digit t;
wolfSSL 13:f67a6c6013ca 4220 int res = MP_OKAY, ix;
wolfSSL 13:f67a6c6013ca 4221
wolfSSL 13:f67a6c6013ca 4222 /* cannot divide by zero */
wolfSSL 13:f67a6c6013ca 4223 if (b == 0) {
wolfSSL 13:f67a6c6013ca 4224 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4225 }
wolfSSL 13:f67a6c6013ca 4226
wolfSSL 13:f67a6c6013ca 4227 /* quick outs */
wolfSSL 13:f67a6c6013ca 4228 if (b == 1 || mp_iszero(a) == MP_YES) {
wolfSSL 13:f67a6c6013ca 4229 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 4230 *d = 0;
wolfSSL 13:f67a6c6013ca 4231 }
wolfSSL 13:f67a6c6013ca 4232 if (c != NULL) {
wolfSSL 13:f67a6c6013ca 4233 return mp_copy(a, c);
wolfSSL 13:f67a6c6013ca 4234 }
wolfSSL 13:f67a6c6013ca 4235 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4236 }
wolfSSL 13:f67a6c6013ca 4237
wolfSSL 13:f67a6c6013ca 4238 /* power of two ? */
wolfSSL 13:f67a6c6013ca 4239 if (s_is_power_of_two(b, &ix) == 1) {
wolfSSL 13:f67a6c6013ca 4240 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 4241 *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
wolfSSL 13:f67a6c6013ca 4242 }
wolfSSL 13:f67a6c6013ca 4243 if (c != NULL) {
wolfSSL 13:f67a6c6013ca 4244 return mp_div_2d(a, ix, c, NULL);
wolfSSL 13:f67a6c6013ca 4245 }
wolfSSL 13:f67a6c6013ca 4246 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4247 }
wolfSSL 13:f67a6c6013ca 4248
wolfSSL 13:f67a6c6013ca 4249 #ifdef BN_MP_DIV_3_C
wolfSSL 13:f67a6c6013ca 4250 /* three? */
wolfSSL 13:f67a6c6013ca 4251 if (b == 3) {
wolfSSL 13:f67a6c6013ca 4252 return mp_div_3(a, c, d);
wolfSSL 13:f67a6c6013ca 4253 }
wolfSSL 13:f67a6c6013ca 4254 #endif
wolfSSL 13:f67a6c6013ca 4255
wolfSSL 13:f67a6c6013ca 4256 /* no easy answer [c'est la vie]. Just division */
wolfSSL 13:f67a6c6013ca 4257 if (c != NULL) {
wolfSSL 13:f67a6c6013ca 4258 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4259 return res;
wolfSSL 13:f67a6c6013ca 4260 }
wolfSSL 13:f67a6c6013ca 4261
wolfSSL 13:f67a6c6013ca 4262 q.used = a->used;
wolfSSL 13:f67a6c6013ca 4263 q.sign = a->sign;
wolfSSL 13:f67a6c6013ca 4264 }
wolfSSL 13:f67a6c6013ca 4265 else {
wolfSSL 13:f67a6c6013ca 4266 if ((res = mp_init(&q)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4267 return res;
wolfSSL 13:f67a6c6013ca 4268 }
wolfSSL 13:f67a6c6013ca 4269 }
wolfSSL 13:f67a6c6013ca 4270
wolfSSL 13:f67a6c6013ca 4271
wolfSSL 13:f67a6c6013ca 4272 w = 0;
wolfSSL 13:f67a6c6013ca 4273 for (ix = a->used - 1; ix >= 0; ix--) {
wolfSSL 13:f67a6c6013ca 4274 w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
wolfSSL 13:f67a6c6013ca 4275
wolfSSL 13:f67a6c6013ca 4276 if (w >= b) {
wolfSSL 13:f67a6c6013ca 4277 t = (mp_digit)(w / b);
wolfSSL 13:f67a6c6013ca 4278 w -= ((mp_word)t) * ((mp_word)b);
wolfSSL 13:f67a6c6013ca 4279 } else {
wolfSSL 13:f67a6c6013ca 4280 t = 0;
wolfSSL 13:f67a6c6013ca 4281 }
wolfSSL 13:f67a6c6013ca 4282 if (c != NULL)
wolfSSL 13:f67a6c6013ca 4283 q.dp[ix] = (mp_digit)t;
wolfSSL 13:f67a6c6013ca 4284 }
wolfSSL 13:f67a6c6013ca 4285
wolfSSL 13:f67a6c6013ca 4286 if (d != NULL) {
wolfSSL 13:f67a6c6013ca 4287 *d = (mp_digit)w;
wolfSSL 13:f67a6c6013ca 4288 }
wolfSSL 13:f67a6c6013ca 4289
wolfSSL 13:f67a6c6013ca 4290 if (c != NULL) {
wolfSSL 13:f67a6c6013ca 4291 mp_clamp(&q);
wolfSSL 13:f67a6c6013ca 4292 mp_exch(&q, c);
wolfSSL 13:f67a6c6013ca 4293 }
wolfSSL 13:f67a6c6013ca 4294 mp_clear(&q);
wolfSSL 13:f67a6c6013ca 4295
wolfSSL 13:f67a6c6013ca 4296 return res;
wolfSSL 13:f67a6c6013ca 4297 }
wolfSSL 13:f67a6c6013ca 4298
wolfSSL 13:f67a6c6013ca 4299
wolfSSL 13:f67a6c6013ca 4300 int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
wolfSSL 13:f67a6c6013ca 4301 {
wolfSSL 13:f67a6c6013ca 4302 return mp_div_d(a, b, NULL, c);
wolfSSL 13:f67a6c6013ca 4303 }
wolfSSL 13:f67a6c6013ca 4304
wolfSSL 13:f67a6c6013ca 4305 #endif /* defined(WOLFSSL_KEY_GEN)||defined(HAVE_COMP_KEY)||defined(HAVE_ECC) */
wolfSSL 13:f67a6c6013ca 4306
wolfSSL 13:f67a6c6013ca 4307 #ifdef WOLFSSL_KEY_GEN
wolfSSL 13:f67a6c6013ca 4308
wolfSSL 13:f67a6c6013ca 4309 const mp_digit ltm_prime_tab[PRIME_SIZE] = {
wolfSSL 13:f67a6c6013ca 4310 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
wolfSSL 13:f67a6c6013ca 4311 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
wolfSSL 13:f67a6c6013ca 4312 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
wolfSSL 13:f67a6c6013ca 4313 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
wolfSSL 13:f67a6c6013ca 4314 #ifndef MP_8BIT
wolfSSL 13:f67a6c6013ca 4315 0x0083,
wolfSSL 13:f67a6c6013ca 4316 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
wolfSSL 13:f67a6c6013ca 4317 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
wolfSSL 13:f67a6c6013ca 4318 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
wolfSSL 13:f67a6c6013ca 4319 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
wolfSSL 13:f67a6c6013ca 4320
wolfSSL 13:f67a6c6013ca 4321 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
wolfSSL 13:f67a6c6013ca 4322 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
wolfSSL 13:f67a6c6013ca 4323 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
wolfSSL 13:f67a6c6013ca 4324 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
wolfSSL 13:f67a6c6013ca 4325 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
wolfSSL 13:f67a6c6013ca 4326 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
wolfSSL 13:f67a6c6013ca 4327 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
wolfSSL 13:f67a6c6013ca 4328 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
wolfSSL 13:f67a6c6013ca 4329
wolfSSL 13:f67a6c6013ca 4330 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
wolfSSL 13:f67a6c6013ca 4331 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
wolfSSL 13:f67a6c6013ca 4332 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
wolfSSL 13:f67a6c6013ca 4333 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
wolfSSL 13:f67a6c6013ca 4334 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
wolfSSL 13:f67a6c6013ca 4335 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
wolfSSL 13:f67a6c6013ca 4336 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
wolfSSL 13:f67a6c6013ca 4337 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
wolfSSL 13:f67a6c6013ca 4338
wolfSSL 13:f67a6c6013ca 4339 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
wolfSSL 13:f67a6c6013ca 4340 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
wolfSSL 13:f67a6c6013ca 4341 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
wolfSSL 13:f67a6c6013ca 4342 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
wolfSSL 13:f67a6c6013ca 4343 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
wolfSSL 13:f67a6c6013ca 4344 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
wolfSSL 13:f67a6c6013ca 4345 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
wolfSSL 13:f67a6c6013ca 4346 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
wolfSSL 13:f67a6c6013ca 4347 #endif
wolfSSL 13:f67a6c6013ca 4348 };
wolfSSL 13:f67a6c6013ca 4349
wolfSSL 13:f67a6c6013ca 4350
wolfSSL 13:f67a6c6013ca 4351 /* Miller-Rabin test of "a" to the base of "b" as described in
wolfSSL 13:f67a6c6013ca 4352 * HAC pp. 139 Algorithm 4.24
wolfSSL 13:f67a6c6013ca 4353 *
wolfSSL 13:f67a6c6013ca 4354 * Sets result to 0 if definitely composite or 1 if probably prime.
wolfSSL 13:f67a6c6013ca 4355 * Randomly the chance of error is no more than 1/4 and often
wolfSSL 13:f67a6c6013ca 4356 * very much lower.
wolfSSL 13:f67a6c6013ca 4357 */
wolfSSL 13:f67a6c6013ca 4358 static int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
wolfSSL 13:f67a6c6013ca 4359 {
wolfSSL 13:f67a6c6013ca 4360 mp_int n1, y, r;
wolfSSL 13:f67a6c6013ca 4361 int s, j, err;
wolfSSL 13:f67a6c6013ca 4362
wolfSSL 13:f67a6c6013ca 4363 /* default */
wolfSSL 13:f67a6c6013ca 4364 *result = MP_NO;
wolfSSL 13:f67a6c6013ca 4365
wolfSSL 13:f67a6c6013ca 4366 /* ensure b > 1 */
wolfSSL 13:f67a6c6013ca 4367 if (mp_cmp_d(b, 1) != MP_GT) {
wolfSSL 13:f67a6c6013ca 4368 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4369 }
wolfSSL 13:f67a6c6013ca 4370
wolfSSL 13:f67a6c6013ca 4371 /* get n1 = a - 1 */
wolfSSL 13:f67a6c6013ca 4372 if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4373 return err;
wolfSSL 13:f67a6c6013ca 4374 }
wolfSSL 13:f67a6c6013ca 4375 if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4376 goto LBL_N1;
wolfSSL 13:f67a6c6013ca 4377 }
wolfSSL 13:f67a6c6013ca 4378
wolfSSL 13:f67a6c6013ca 4379 /* set 2**s * r = n1 */
wolfSSL 13:f67a6c6013ca 4380 if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4381 goto LBL_N1;
wolfSSL 13:f67a6c6013ca 4382 }
wolfSSL 13:f67a6c6013ca 4383
wolfSSL 13:f67a6c6013ca 4384 /* count the number of least significant bits
wolfSSL 13:f67a6c6013ca 4385 * which are zero
wolfSSL 13:f67a6c6013ca 4386 */
wolfSSL 13:f67a6c6013ca 4387 s = mp_cnt_lsb(&r);
wolfSSL 13:f67a6c6013ca 4388
wolfSSL 13:f67a6c6013ca 4389 /* now divide n - 1 by 2**s */
wolfSSL 13:f67a6c6013ca 4390 if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4391 goto LBL_R;
wolfSSL 13:f67a6c6013ca 4392 }
wolfSSL 13:f67a6c6013ca 4393
wolfSSL 13:f67a6c6013ca 4394 /* compute y = b**r mod a */
wolfSSL 13:f67a6c6013ca 4395 if ((err = mp_init (&y)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4396 goto LBL_R;
wolfSSL 13:f67a6c6013ca 4397 }
wolfSSL 13:f67a6c6013ca 4398 if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4399 goto LBL_Y;
wolfSSL 13:f67a6c6013ca 4400 }
wolfSSL 13:f67a6c6013ca 4401
wolfSSL 13:f67a6c6013ca 4402 /* if y != 1 and y != n1 do */
wolfSSL 13:f67a6c6013ca 4403 if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
wolfSSL 13:f67a6c6013ca 4404 j = 1;
wolfSSL 13:f67a6c6013ca 4405 /* while j <= s-1 and y != n1 */
wolfSSL 13:f67a6c6013ca 4406 while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
wolfSSL 13:f67a6c6013ca 4407 if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4408 goto LBL_Y;
wolfSSL 13:f67a6c6013ca 4409 }
wolfSSL 13:f67a6c6013ca 4410
wolfSSL 13:f67a6c6013ca 4411 /* if y == 1 then composite */
wolfSSL 13:f67a6c6013ca 4412 if (mp_cmp_d (&y, 1) == MP_EQ) {
wolfSSL 13:f67a6c6013ca 4413 goto LBL_Y;
wolfSSL 13:f67a6c6013ca 4414 }
wolfSSL 13:f67a6c6013ca 4415
wolfSSL 13:f67a6c6013ca 4416 ++j;
wolfSSL 13:f67a6c6013ca 4417 }
wolfSSL 13:f67a6c6013ca 4418
wolfSSL 13:f67a6c6013ca 4419 /* if y != n1 then composite */
wolfSSL 13:f67a6c6013ca 4420 if (mp_cmp (&y, &n1) != MP_EQ) {
wolfSSL 13:f67a6c6013ca 4421 goto LBL_Y;
wolfSSL 13:f67a6c6013ca 4422 }
wolfSSL 13:f67a6c6013ca 4423 }
wolfSSL 13:f67a6c6013ca 4424
wolfSSL 13:f67a6c6013ca 4425 /* probably prime now */
wolfSSL 13:f67a6c6013ca 4426 *result = MP_YES;
wolfSSL 13:f67a6c6013ca 4427 LBL_Y:mp_clear (&y);
wolfSSL 13:f67a6c6013ca 4428 LBL_R:mp_clear (&r);
wolfSSL 13:f67a6c6013ca 4429 LBL_N1:mp_clear (&n1);
wolfSSL 13:f67a6c6013ca 4430 return err;
wolfSSL 13:f67a6c6013ca 4431 }
wolfSSL 13:f67a6c6013ca 4432
wolfSSL 13:f67a6c6013ca 4433
wolfSSL 13:f67a6c6013ca 4434 /* determines if an integers is divisible by one
wolfSSL 13:f67a6c6013ca 4435 * of the first PRIME_SIZE primes or not
wolfSSL 13:f67a6c6013ca 4436 *
wolfSSL 13:f67a6c6013ca 4437 * sets result to 0 if not, 1 if yes
wolfSSL 13:f67a6c6013ca 4438 */
wolfSSL 13:f67a6c6013ca 4439 static int mp_prime_is_divisible (mp_int * a, int *result)
wolfSSL 13:f67a6c6013ca 4440 {
wolfSSL 13:f67a6c6013ca 4441 int err, ix;
wolfSSL 13:f67a6c6013ca 4442 mp_digit res;
wolfSSL 13:f67a6c6013ca 4443
wolfSSL 13:f67a6c6013ca 4444 /* default to not */
wolfSSL 13:f67a6c6013ca 4445 *result = MP_NO;
wolfSSL 13:f67a6c6013ca 4446
wolfSSL 13:f67a6c6013ca 4447 for (ix = 0; ix < PRIME_SIZE; ix++) {
wolfSSL 13:f67a6c6013ca 4448 /* what is a mod LBL_prime_tab[ix] */
wolfSSL 13:f67a6c6013ca 4449 if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4450 return err;
wolfSSL 13:f67a6c6013ca 4451 }
wolfSSL 13:f67a6c6013ca 4452
wolfSSL 13:f67a6c6013ca 4453 /* is the residue zero? */
wolfSSL 13:f67a6c6013ca 4454 if (res == 0) {
wolfSSL 13:f67a6c6013ca 4455 *result = MP_YES;
wolfSSL 13:f67a6c6013ca 4456 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4457 }
wolfSSL 13:f67a6c6013ca 4458 }
wolfSSL 13:f67a6c6013ca 4459
wolfSSL 13:f67a6c6013ca 4460 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4461 }
wolfSSL 13:f67a6c6013ca 4462
wolfSSL 13:f67a6c6013ca 4463 static const int USE_BBS = 1;
wolfSSL 13:f67a6c6013ca 4464
wolfSSL 13:f67a6c6013ca 4465 int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap)
wolfSSL 13:f67a6c6013ca 4466 {
wolfSSL 13:f67a6c6013ca 4467 int err, res, type;
wolfSSL 13:f67a6c6013ca 4468 byte* buf;
wolfSSL 13:f67a6c6013ca 4469
wolfSSL 13:f67a6c6013ca 4470 if (N == NULL || rng == NULL)
wolfSSL 13:f67a6c6013ca 4471 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4472
wolfSSL 13:f67a6c6013ca 4473 /* get type */
wolfSSL 13:f67a6c6013ca 4474 if (len < 0) {
wolfSSL 13:f67a6c6013ca 4475 type = USE_BBS;
wolfSSL 13:f67a6c6013ca 4476 len = -len;
wolfSSL 13:f67a6c6013ca 4477 } else {
wolfSSL 13:f67a6c6013ca 4478 type = 0;
wolfSSL 13:f67a6c6013ca 4479 }
wolfSSL 13:f67a6c6013ca 4480
wolfSSL 13:f67a6c6013ca 4481 /* allow sizes between 2 and 512 bytes for a prime size */
wolfSSL 13:f67a6c6013ca 4482 if (len < 2 || len > 512) {
wolfSSL 13:f67a6c6013ca 4483 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4484 }
wolfSSL 13:f67a6c6013ca 4485
wolfSSL 13:f67a6c6013ca 4486 /* allocate buffer to work with */
wolfSSL 13:f67a6c6013ca 4487 buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA);
wolfSSL 13:f67a6c6013ca 4488 if (buf == NULL) {
wolfSSL 13:f67a6c6013ca 4489 return MP_MEM;
wolfSSL 13:f67a6c6013ca 4490 }
wolfSSL 13:f67a6c6013ca 4491 XMEMSET(buf, 0, len);
wolfSSL 13:f67a6c6013ca 4492
wolfSSL 13:f67a6c6013ca 4493 do {
wolfSSL 13:f67a6c6013ca 4494 #ifdef SHOW_GEN
wolfSSL 13:f67a6c6013ca 4495 printf(".");
wolfSSL 13:f67a6c6013ca 4496 fflush(stdout);
wolfSSL 13:f67a6c6013ca 4497 #endif
wolfSSL 13:f67a6c6013ca 4498 /* generate value */
wolfSSL 13:f67a6c6013ca 4499 err = wc_RNG_GenerateBlock(rng, buf, len);
wolfSSL 13:f67a6c6013ca 4500 if (err != 0) {
wolfSSL 13:f67a6c6013ca 4501 XFREE(buf, heap, DYNAMIC_TYPE_RSA);
wolfSSL 13:f67a6c6013ca 4502 return err;
wolfSSL 13:f67a6c6013ca 4503 }
wolfSSL 13:f67a6c6013ca 4504
wolfSSL 13:f67a6c6013ca 4505 /* munge bits */
wolfSSL 13:f67a6c6013ca 4506 buf[0] |= 0x80 | 0x40;
wolfSSL 13:f67a6c6013ca 4507 buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
wolfSSL 13:f67a6c6013ca 4508
wolfSSL 13:f67a6c6013ca 4509 /* load value */
wolfSSL 13:f67a6c6013ca 4510 if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4511 XFREE(buf, heap, DYNAMIC_TYPE_RSA);
wolfSSL 13:f67a6c6013ca 4512 return err;
wolfSSL 13:f67a6c6013ca 4513 }
wolfSSL 13:f67a6c6013ca 4514
wolfSSL 13:f67a6c6013ca 4515 /* test */
wolfSSL 13:f67a6c6013ca 4516 if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4517 XFREE(buf, heap, DYNAMIC_TYPE_RSA);
wolfSSL 13:f67a6c6013ca 4518 return err;
wolfSSL 13:f67a6c6013ca 4519 }
wolfSSL 13:f67a6c6013ca 4520 } while (res == MP_NO);
wolfSSL 13:f67a6c6013ca 4521
wolfSSL 13:f67a6c6013ca 4522 XMEMSET(buf, 0, len);
wolfSSL 13:f67a6c6013ca 4523 XFREE(buf, heap, DYNAMIC_TYPE_RSA);
wolfSSL 13:f67a6c6013ca 4524
wolfSSL 13:f67a6c6013ca 4525 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4526 }
wolfSSL 13:f67a6c6013ca 4527
wolfSSL 13:f67a6c6013ca 4528 /*
wolfSSL 13:f67a6c6013ca 4529 * Sets result to 1 if probably prime, 0 otherwise
wolfSSL 13:f67a6c6013ca 4530 */
wolfSSL 13:f67a6c6013ca 4531 int mp_prime_is_prime (mp_int * a, int t, int *result)
wolfSSL 13:f67a6c6013ca 4532 {
wolfSSL 13:f67a6c6013ca 4533 mp_int b;
wolfSSL 13:f67a6c6013ca 4534 int ix, err, res;
wolfSSL 13:f67a6c6013ca 4535
wolfSSL 13:f67a6c6013ca 4536 /* default to no */
wolfSSL 13:f67a6c6013ca 4537 *result = MP_NO;
wolfSSL 13:f67a6c6013ca 4538
wolfSSL 13:f67a6c6013ca 4539 /* valid value of t? */
wolfSSL 13:f67a6c6013ca 4540 if (t <= 0 || t > PRIME_SIZE) {
wolfSSL 13:f67a6c6013ca 4541 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4542 }
wolfSSL 13:f67a6c6013ca 4543
wolfSSL 13:f67a6c6013ca 4544 /* is the input equal to one of the primes in the table? */
wolfSSL 13:f67a6c6013ca 4545 for (ix = 0; ix < PRIME_SIZE; ix++) {
wolfSSL 13:f67a6c6013ca 4546 if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
wolfSSL 13:f67a6c6013ca 4547 *result = 1;
wolfSSL 13:f67a6c6013ca 4548 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4549 }
wolfSSL 13:f67a6c6013ca 4550 }
wolfSSL 13:f67a6c6013ca 4551
wolfSSL 13:f67a6c6013ca 4552 /* first perform trial division */
wolfSSL 13:f67a6c6013ca 4553 if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4554 return err;
wolfSSL 13:f67a6c6013ca 4555 }
wolfSSL 13:f67a6c6013ca 4556
wolfSSL 13:f67a6c6013ca 4557 /* return if it was trivially divisible */
wolfSSL 13:f67a6c6013ca 4558 if (res == MP_YES) {
wolfSSL 13:f67a6c6013ca 4559 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4560 }
wolfSSL 13:f67a6c6013ca 4561
wolfSSL 13:f67a6c6013ca 4562 /* now perform the miller-rabin rounds */
wolfSSL 13:f67a6c6013ca 4563 if ((err = mp_init (&b)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4564 return err;
wolfSSL 13:f67a6c6013ca 4565 }
wolfSSL 13:f67a6c6013ca 4566
wolfSSL 13:f67a6c6013ca 4567 for (ix = 0; ix < t; ix++) {
wolfSSL 13:f67a6c6013ca 4568 /* set the prime */
wolfSSL 13:f67a6c6013ca 4569 if ((err = mp_set (&b, ltm_prime_tab[ix])) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4570 goto LBL_B;
wolfSSL 13:f67a6c6013ca 4571 }
wolfSSL 13:f67a6c6013ca 4572
wolfSSL 13:f67a6c6013ca 4573 if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4574 goto LBL_B;
wolfSSL 13:f67a6c6013ca 4575 }
wolfSSL 13:f67a6c6013ca 4576
wolfSSL 13:f67a6c6013ca 4577 if (res == MP_NO) {
wolfSSL 13:f67a6c6013ca 4578 goto LBL_B;
wolfSSL 13:f67a6c6013ca 4579 }
wolfSSL 13:f67a6c6013ca 4580 }
wolfSSL 13:f67a6c6013ca 4581
wolfSSL 13:f67a6c6013ca 4582 /* passed the test */
wolfSSL 13:f67a6c6013ca 4583 *result = MP_YES;
wolfSSL 13:f67a6c6013ca 4584 LBL_B:mp_clear (&b);
wolfSSL 13:f67a6c6013ca 4585 return err;
wolfSSL 13:f67a6c6013ca 4586 }
wolfSSL 13:f67a6c6013ca 4587
wolfSSL 13:f67a6c6013ca 4588
wolfSSL 13:f67a6c6013ca 4589 /* computes least common multiple as |a*b|/(a, b) */
wolfSSL 13:f67a6c6013ca 4590 int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 4591 {
wolfSSL 13:f67a6c6013ca 4592 int res;
wolfSSL 13:f67a6c6013ca 4593 mp_int t1, t2;
wolfSSL 13:f67a6c6013ca 4594
wolfSSL 13:f67a6c6013ca 4595
wolfSSL 13:f67a6c6013ca 4596 if ((res = mp_init_multi (&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4597 return res;
wolfSSL 13:f67a6c6013ca 4598 }
wolfSSL 13:f67a6c6013ca 4599
wolfSSL 13:f67a6c6013ca 4600 /* t1 = get the GCD of the two inputs */
wolfSSL 13:f67a6c6013ca 4601 if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4602 goto LBL_T;
wolfSSL 13:f67a6c6013ca 4603 }
wolfSSL 13:f67a6c6013ca 4604
wolfSSL 13:f67a6c6013ca 4605 /* divide the smallest by the GCD */
wolfSSL 13:f67a6c6013ca 4606 if (mp_cmp_mag(a, b) == MP_LT) {
wolfSSL 13:f67a6c6013ca 4607 /* store quotient in t2 such that t2 * b is the LCM */
wolfSSL 13:f67a6c6013ca 4608 if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4609 goto LBL_T;
wolfSSL 13:f67a6c6013ca 4610 }
wolfSSL 13:f67a6c6013ca 4611 res = mp_mul(b, &t2, c);
wolfSSL 13:f67a6c6013ca 4612 } else {
wolfSSL 13:f67a6c6013ca 4613 /* store quotient in t2 such that t2 * a is the LCM */
wolfSSL 13:f67a6c6013ca 4614 if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4615 goto LBL_T;
wolfSSL 13:f67a6c6013ca 4616 }
wolfSSL 13:f67a6c6013ca 4617 res = mp_mul(a, &t2, c);
wolfSSL 13:f67a6c6013ca 4618 }
wolfSSL 13:f67a6c6013ca 4619
wolfSSL 13:f67a6c6013ca 4620 /* fix the sign to positive */
wolfSSL 13:f67a6c6013ca 4621 c->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4622
wolfSSL 13:f67a6c6013ca 4623 LBL_T:
wolfSSL 13:f67a6c6013ca 4624 mp_clear(&t1);
wolfSSL 13:f67a6c6013ca 4625 mp_clear(&t2);
wolfSSL 13:f67a6c6013ca 4626 return res;
wolfSSL 13:f67a6c6013ca 4627 }
wolfSSL 13:f67a6c6013ca 4628
wolfSSL 13:f67a6c6013ca 4629
wolfSSL 13:f67a6c6013ca 4630
wolfSSL 13:f67a6c6013ca 4631 /* Greatest Common Divisor using the binary method */
wolfSSL 13:f67a6c6013ca 4632 int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
wolfSSL 13:f67a6c6013ca 4633 {
wolfSSL 13:f67a6c6013ca 4634 mp_int u, v;
wolfSSL 13:f67a6c6013ca 4635 int k, u_lsb, v_lsb, res;
wolfSSL 13:f67a6c6013ca 4636
wolfSSL 13:f67a6c6013ca 4637 /* either zero than gcd is the largest */
wolfSSL 13:f67a6c6013ca 4638 if (mp_iszero (a) == MP_YES) {
wolfSSL 13:f67a6c6013ca 4639 return mp_abs (b, c);
wolfSSL 13:f67a6c6013ca 4640 }
wolfSSL 13:f67a6c6013ca 4641 if (mp_iszero (b) == MP_YES) {
wolfSSL 13:f67a6c6013ca 4642 return mp_abs (a, c);
wolfSSL 13:f67a6c6013ca 4643 }
wolfSSL 13:f67a6c6013ca 4644
wolfSSL 13:f67a6c6013ca 4645 /* get copies of a and b we can modify */
wolfSSL 13:f67a6c6013ca 4646 if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4647 return res;
wolfSSL 13:f67a6c6013ca 4648 }
wolfSSL 13:f67a6c6013ca 4649
wolfSSL 13:f67a6c6013ca 4650 if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4651 goto LBL_U;
wolfSSL 13:f67a6c6013ca 4652 }
wolfSSL 13:f67a6c6013ca 4653
wolfSSL 13:f67a6c6013ca 4654 /* must be positive for the remainder of the algorithm */
wolfSSL 13:f67a6c6013ca 4655 u.sign = v.sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4656
wolfSSL 13:f67a6c6013ca 4657 /* B1. Find the common power of two for u and v */
wolfSSL 13:f67a6c6013ca 4658 u_lsb = mp_cnt_lsb(&u);
wolfSSL 13:f67a6c6013ca 4659 v_lsb = mp_cnt_lsb(&v);
wolfSSL 13:f67a6c6013ca 4660 k = MIN(u_lsb, v_lsb);
wolfSSL 13:f67a6c6013ca 4661
wolfSSL 13:f67a6c6013ca 4662 if (k > 0) {
wolfSSL 13:f67a6c6013ca 4663 /* divide the power of two out */
wolfSSL 13:f67a6c6013ca 4664 if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4665 goto LBL_V;
wolfSSL 13:f67a6c6013ca 4666 }
wolfSSL 13:f67a6c6013ca 4667
wolfSSL 13:f67a6c6013ca 4668 if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4669 goto LBL_V;
wolfSSL 13:f67a6c6013ca 4670 }
wolfSSL 13:f67a6c6013ca 4671 }
wolfSSL 13:f67a6c6013ca 4672
wolfSSL 13:f67a6c6013ca 4673 /* divide any remaining factors of two out */
wolfSSL 13:f67a6c6013ca 4674 if (u_lsb != k) {
wolfSSL 13:f67a6c6013ca 4675 if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4676 goto LBL_V;
wolfSSL 13:f67a6c6013ca 4677 }
wolfSSL 13:f67a6c6013ca 4678 }
wolfSSL 13:f67a6c6013ca 4679
wolfSSL 13:f67a6c6013ca 4680 if (v_lsb != k) {
wolfSSL 13:f67a6c6013ca 4681 if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4682 goto LBL_V;
wolfSSL 13:f67a6c6013ca 4683 }
wolfSSL 13:f67a6c6013ca 4684 }
wolfSSL 13:f67a6c6013ca 4685
wolfSSL 13:f67a6c6013ca 4686 while (mp_iszero(&v) == MP_NO) {
wolfSSL 13:f67a6c6013ca 4687 /* make sure v is the largest */
wolfSSL 13:f67a6c6013ca 4688 if (mp_cmp_mag(&u, &v) == MP_GT) {
wolfSSL 13:f67a6c6013ca 4689 /* swap u and v to make sure v is >= u */
wolfSSL 13:f67a6c6013ca 4690 mp_exch(&u, &v);
wolfSSL 13:f67a6c6013ca 4691 }
wolfSSL 13:f67a6c6013ca 4692
wolfSSL 13:f67a6c6013ca 4693 /* subtract smallest from largest */
wolfSSL 13:f67a6c6013ca 4694 if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4695 goto LBL_V;
wolfSSL 13:f67a6c6013ca 4696 }
wolfSSL 13:f67a6c6013ca 4697
wolfSSL 13:f67a6c6013ca 4698 /* Divide out all factors of two */
wolfSSL 13:f67a6c6013ca 4699 if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4700 goto LBL_V;
wolfSSL 13:f67a6c6013ca 4701 }
wolfSSL 13:f67a6c6013ca 4702 }
wolfSSL 13:f67a6c6013ca 4703
wolfSSL 13:f67a6c6013ca 4704 /* multiply by 2**k which we divided out at the beginning */
wolfSSL 13:f67a6c6013ca 4705 if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4706 goto LBL_V;
wolfSSL 13:f67a6c6013ca 4707 }
wolfSSL 13:f67a6c6013ca 4708 c->sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4709 res = MP_OKAY;
wolfSSL 13:f67a6c6013ca 4710 LBL_V:mp_clear (&u);
wolfSSL 13:f67a6c6013ca 4711 LBL_U:mp_clear (&v);
wolfSSL 13:f67a6c6013ca 4712 return res;
wolfSSL 13:f67a6c6013ca 4713 }
wolfSSL 13:f67a6c6013ca 4714
wolfSSL 13:f67a6c6013ca 4715 #endif /* WOLFSSL_KEY_GEN */
wolfSSL 13:f67a6c6013ca 4716
wolfSSL 13:f67a6c6013ca 4717
wolfSSL 13:f67a6c6013ca 4718 #if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
wolfSSL 13:f67a6c6013ca 4719
wolfSSL 13:f67a6c6013ca 4720 /* chars used in radix conversions */
wolfSSL 13:f67a6c6013ca 4721 const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\
wolfSSL 13:f67a6c6013ca 4722 abcdefghijklmnopqrstuvwxyz+/";
wolfSSL 13:f67a6c6013ca 4723 #endif
wolfSSL 13:f67a6c6013ca 4724
wolfSSL 13:f67a6c6013ca 4725 #ifdef HAVE_ECC
wolfSSL 13:f67a6c6013ca 4726 /* read a string [ASCII] in a given radix */
wolfSSL 13:f67a6c6013ca 4727 int mp_read_radix (mp_int * a, const char *str, int radix)
wolfSSL 13:f67a6c6013ca 4728 {
wolfSSL 13:f67a6c6013ca 4729 int y, res, neg;
wolfSSL 13:f67a6c6013ca 4730 char ch;
wolfSSL 13:f67a6c6013ca 4731
wolfSSL 13:f67a6c6013ca 4732 /* zero the digit bignum */
wolfSSL 13:f67a6c6013ca 4733 mp_zero(a);
wolfSSL 13:f67a6c6013ca 4734
wolfSSL 13:f67a6c6013ca 4735 /* make sure the radix is ok */
wolfSSL 13:f67a6c6013ca 4736 if (radix < 2 || radix > 64) {
wolfSSL 13:f67a6c6013ca 4737 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4738 }
wolfSSL 13:f67a6c6013ca 4739
wolfSSL 13:f67a6c6013ca 4740 /* if the leading digit is a
wolfSSL 13:f67a6c6013ca 4741 * minus set the sign to negative.
wolfSSL 13:f67a6c6013ca 4742 */
wolfSSL 13:f67a6c6013ca 4743 if (*str == '-') {
wolfSSL 13:f67a6c6013ca 4744 ++str;
wolfSSL 13:f67a6c6013ca 4745 neg = MP_NEG;
wolfSSL 13:f67a6c6013ca 4746 } else {
wolfSSL 13:f67a6c6013ca 4747 neg = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4748 }
wolfSSL 13:f67a6c6013ca 4749
wolfSSL 13:f67a6c6013ca 4750 /* set the integer to the default of zero */
wolfSSL 13:f67a6c6013ca 4751 mp_zero (a);
wolfSSL 13:f67a6c6013ca 4752
wolfSSL 13:f67a6c6013ca 4753 /* process each digit of the string */
wolfSSL 13:f67a6c6013ca 4754 while (*str) {
wolfSSL 13:f67a6c6013ca 4755 /* if the radix <= 36 the conversion is case insensitive
wolfSSL 13:f67a6c6013ca 4756 * this allows numbers like 1AB and 1ab to represent the same value
wolfSSL 13:f67a6c6013ca 4757 * [e.g. in hex]
wolfSSL 13:f67a6c6013ca 4758 */
wolfSSL 13:f67a6c6013ca 4759 ch = (radix <= 36) ? (char)XTOUPPER((unsigned char)*str) : *str;
wolfSSL 13:f67a6c6013ca 4760 for (y = 0; y < 64; y++) {
wolfSSL 13:f67a6c6013ca 4761 if (ch == mp_s_rmap[y]) {
wolfSSL 13:f67a6c6013ca 4762 break;
wolfSSL 13:f67a6c6013ca 4763 }
wolfSSL 13:f67a6c6013ca 4764 }
wolfSSL 13:f67a6c6013ca 4765
wolfSSL 13:f67a6c6013ca 4766 /* if the char was found in the map
wolfSSL 13:f67a6c6013ca 4767 * and is less than the given radix add it
wolfSSL 13:f67a6c6013ca 4768 * to the number, otherwise exit the loop.
wolfSSL 13:f67a6c6013ca 4769 */
wolfSSL 13:f67a6c6013ca 4770 if (y < radix) {
wolfSSL 13:f67a6c6013ca 4771 if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4772 return res;
wolfSSL 13:f67a6c6013ca 4773 }
wolfSSL 13:f67a6c6013ca 4774 if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4775 return res;
wolfSSL 13:f67a6c6013ca 4776 }
wolfSSL 13:f67a6c6013ca 4777 } else {
wolfSSL 13:f67a6c6013ca 4778 break;
wolfSSL 13:f67a6c6013ca 4779 }
wolfSSL 13:f67a6c6013ca 4780 ++str;
wolfSSL 13:f67a6c6013ca 4781 }
wolfSSL 13:f67a6c6013ca 4782
wolfSSL 13:f67a6c6013ca 4783 /* set the sign only if a != 0 */
wolfSSL 13:f67a6c6013ca 4784 if (mp_iszero(a) != MP_YES) {
wolfSSL 13:f67a6c6013ca 4785 a->sign = neg;
wolfSSL 13:f67a6c6013ca 4786 }
wolfSSL 13:f67a6c6013ca 4787 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4788 }
wolfSSL 13:f67a6c6013ca 4789 #endif /* HAVE_ECC */
wolfSSL 13:f67a6c6013ca 4790
wolfSSL 13:f67a6c6013ca 4791 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
wolfSSL 13:f67a6c6013ca 4792 defined(WOLFSSL_DEBUG_MATH)
wolfSSL 13:f67a6c6013ca 4793
wolfSSL 13:f67a6c6013ca 4794 /* returns size of ASCII representation */
wolfSSL 13:f67a6c6013ca 4795 int mp_radix_size (mp_int *a, int radix, int *size)
wolfSSL 13:f67a6c6013ca 4796 {
wolfSSL 13:f67a6c6013ca 4797 int res, digs;
wolfSSL 13:f67a6c6013ca 4798 mp_int t;
wolfSSL 13:f67a6c6013ca 4799 mp_digit d;
wolfSSL 13:f67a6c6013ca 4800
wolfSSL 13:f67a6c6013ca 4801 *size = 0;
wolfSSL 13:f67a6c6013ca 4802
wolfSSL 13:f67a6c6013ca 4803 /* special case for binary */
wolfSSL 13:f67a6c6013ca 4804 if (radix == 2) {
wolfSSL 13:f67a6c6013ca 4805 *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
wolfSSL 13:f67a6c6013ca 4806 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4807 }
wolfSSL 13:f67a6c6013ca 4808
wolfSSL 13:f67a6c6013ca 4809 /* make sure the radix is in range */
wolfSSL 13:f67a6c6013ca 4810 if (radix < 2 || radix > 64) {
wolfSSL 13:f67a6c6013ca 4811 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4812 }
wolfSSL 13:f67a6c6013ca 4813
wolfSSL 13:f67a6c6013ca 4814 if (mp_iszero(a) == MP_YES) {
wolfSSL 13:f67a6c6013ca 4815 *size = 2;
wolfSSL 13:f67a6c6013ca 4816 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4817 }
wolfSSL 13:f67a6c6013ca 4818
wolfSSL 13:f67a6c6013ca 4819 /* digs is the digit count */
wolfSSL 13:f67a6c6013ca 4820 digs = 0;
wolfSSL 13:f67a6c6013ca 4821
wolfSSL 13:f67a6c6013ca 4822 /* if it's negative add one for the sign */
wolfSSL 13:f67a6c6013ca 4823 if (a->sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 4824 ++digs;
wolfSSL 13:f67a6c6013ca 4825 }
wolfSSL 13:f67a6c6013ca 4826
wolfSSL 13:f67a6c6013ca 4827 /* init a copy of the input */
wolfSSL 13:f67a6c6013ca 4828 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4829 return res;
wolfSSL 13:f67a6c6013ca 4830 }
wolfSSL 13:f67a6c6013ca 4831
wolfSSL 13:f67a6c6013ca 4832 /* force temp to positive */
wolfSSL 13:f67a6c6013ca 4833 t.sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4834
wolfSSL 13:f67a6c6013ca 4835 /* fetch out all of the digits */
wolfSSL 13:f67a6c6013ca 4836 while (mp_iszero (&t) == MP_NO) {
wolfSSL 13:f67a6c6013ca 4837 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4838 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 4839 return res;
wolfSSL 13:f67a6c6013ca 4840 }
wolfSSL 13:f67a6c6013ca 4841 ++digs;
wolfSSL 13:f67a6c6013ca 4842 }
wolfSSL 13:f67a6c6013ca 4843 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 4844
wolfSSL 13:f67a6c6013ca 4845 /* return digs + 1, the 1 is for the NULL byte that would be required. */
wolfSSL 13:f67a6c6013ca 4846 *size = digs + 1;
wolfSSL 13:f67a6c6013ca 4847 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4848 }
wolfSSL 13:f67a6c6013ca 4849
wolfSSL 13:f67a6c6013ca 4850 /* stores a bignum as a ASCII string in a given radix (2..64) */
wolfSSL 13:f67a6c6013ca 4851 int mp_toradix (mp_int *a, char *str, int radix)
wolfSSL 13:f67a6c6013ca 4852 {
wolfSSL 13:f67a6c6013ca 4853 int res, digs;
wolfSSL 13:f67a6c6013ca 4854 mp_int t;
wolfSSL 13:f67a6c6013ca 4855 mp_digit d;
wolfSSL 13:f67a6c6013ca 4856 char *_s = str;
wolfSSL 13:f67a6c6013ca 4857
wolfSSL 13:f67a6c6013ca 4858 /* check range of the radix */
wolfSSL 13:f67a6c6013ca 4859 if (radix < 2 || radix > 64) {
wolfSSL 13:f67a6c6013ca 4860 return MP_VAL;
wolfSSL 13:f67a6c6013ca 4861 }
wolfSSL 13:f67a6c6013ca 4862
wolfSSL 13:f67a6c6013ca 4863 /* quick out if its zero */
wolfSSL 13:f67a6c6013ca 4864 if (mp_iszero(a) == MP_YES) {
wolfSSL 13:f67a6c6013ca 4865 *str++ = '0';
wolfSSL 13:f67a6c6013ca 4866 *str = '\0';
wolfSSL 13:f67a6c6013ca 4867 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4868 }
wolfSSL 13:f67a6c6013ca 4869
wolfSSL 13:f67a6c6013ca 4870 if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4871 return res;
wolfSSL 13:f67a6c6013ca 4872 }
wolfSSL 13:f67a6c6013ca 4873
wolfSSL 13:f67a6c6013ca 4874 /* if it is negative output a - */
wolfSSL 13:f67a6c6013ca 4875 if (t.sign == MP_NEG) {
wolfSSL 13:f67a6c6013ca 4876 ++_s;
wolfSSL 13:f67a6c6013ca 4877 *str++ = '-';
wolfSSL 13:f67a6c6013ca 4878 t.sign = MP_ZPOS;
wolfSSL 13:f67a6c6013ca 4879 }
wolfSSL 13:f67a6c6013ca 4880
wolfSSL 13:f67a6c6013ca 4881 digs = 0;
wolfSSL 13:f67a6c6013ca 4882 while (mp_iszero (&t) == MP_NO) {
wolfSSL 13:f67a6c6013ca 4883 if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
wolfSSL 13:f67a6c6013ca 4884 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 4885 return res;
wolfSSL 13:f67a6c6013ca 4886 }
wolfSSL 13:f67a6c6013ca 4887 *str++ = mp_s_rmap[d];
wolfSSL 13:f67a6c6013ca 4888 ++digs;
wolfSSL 13:f67a6c6013ca 4889 }
wolfSSL 13:f67a6c6013ca 4890
wolfSSL 13:f67a6c6013ca 4891 /* reverse the digits of the string. In this case _s points
wolfSSL 13:f67a6c6013ca 4892 * to the first digit [excluding the sign] of the number]
wolfSSL 13:f67a6c6013ca 4893 */
wolfSSL 13:f67a6c6013ca 4894 bn_reverse ((unsigned char *)_s, digs);
wolfSSL 13:f67a6c6013ca 4895
wolfSSL 13:f67a6c6013ca 4896 /* append a NULL so the string is properly terminated */
wolfSSL 13:f67a6c6013ca 4897 *str = '\0';
wolfSSL 13:f67a6c6013ca 4898
wolfSSL 13:f67a6c6013ca 4899 mp_clear (&t);
wolfSSL 13:f67a6c6013ca 4900 return MP_OKAY;
wolfSSL 13:f67a6c6013ca 4901 }
wolfSSL 13:f67a6c6013ca 4902
wolfSSL 13:f67a6c6013ca 4903 #ifdef WOLFSSL_DEBUG_MATH
wolfSSL 13:f67a6c6013ca 4904 void mp_dump(const char* desc, mp_int* a, byte verbose)
wolfSSL 13:f67a6c6013ca 4905 {
wolfSSL 13:f67a6c6013ca 4906 char *buffer;
wolfSSL 13:f67a6c6013ca 4907 int size = a->alloc;
wolfSSL 13:f67a6c6013ca 4908
wolfSSL 13:f67a6c6013ca 4909 buffer = (char*)XMALLOC(size * sizeof(mp_digit) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 13:f67a6c6013ca 4910 if (buffer == NULL) {
wolfSSL 13:f67a6c6013ca 4911 return;
wolfSSL 13:f67a6c6013ca 4912 }
wolfSSL 13:f67a6c6013ca 4913
wolfSSL 13:f67a6c6013ca 4914 printf("%s: ptr=%p, used=%d, sign=%d, size=%d, mpd=%d\n",
wolfSSL 13:f67a6c6013ca 4915 desc, a, a->used, a->sign, size, (int)sizeof(mp_digit));
wolfSSL 13:f67a6c6013ca 4916
wolfSSL 13:f67a6c6013ca 4917 mp_toradix(a, buffer, 16);
wolfSSL 13:f67a6c6013ca 4918 printf(" %s\n ", buffer);
wolfSSL 13:f67a6c6013ca 4919
wolfSSL 13:f67a6c6013ca 4920 if (verbose) {
wolfSSL 13:f67a6c6013ca 4921 int i;
wolfSSL 13:f67a6c6013ca 4922 for(i=0; i<a->alloc * (int)sizeof(mp_digit); i++) {
wolfSSL 13:f67a6c6013ca 4923 printf("%02x ", *(((byte*)a->dp) + i));
wolfSSL 13:f67a6c6013ca 4924 }
wolfSSL 13:f67a6c6013ca 4925 printf("\n");
wolfSSL 13:f67a6c6013ca 4926 }
wolfSSL 13:f67a6c6013ca 4927
wolfSSL 13:f67a6c6013ca 4928 XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 13:f67a6c6013ca 4929 }
wolfSSL 13:f67a6c6013ca 4930 #endif /* WOLFSSL_DEBUG_MATH */
wolfSSL 13:f67a6c6013ca 4931
wolfSSL 13:f67a6c6013ca 4932 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
wolfSSL 13:f67a6c6013ca 4933
wolfSSL 13:f67a6c6013ca 4934 #endif /* USE_FAST_MATH */
wolfSSL 13:f67a6c6013ca 4935
wolfSSL 13:f67a6c6013ca 4936 #endif /* NO_BIG_INT */
wolfSSL 13:f67a6c6013ca 4937
wolfSSL 13:f67a6c6013ca 4938