wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 06:16:19 2017 +0000
Revision:
13:80fb167dafdf
Parent:
11:cee25a834751
wolfSSL 3.11.1: TLS1.3 Beta

Who changed what in which revision?

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