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

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

Committer:
wolfSSL
Date:
Thu Apr 28 00:57:21 2016 +0000
Revision:
4:1b0d80432c79
wolfSSL 3.9.0

Who changed what in which revision?

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