Functions | |
| static bigint * | bi_int_multiply (BI_CTX *ctx, bigint *bia, comp b) |
| Perform a multiply between a bigint an an (unsigned) integer. | |
| static bigint * | bi_int_divide (BI_CTX *ctx, bigint *biR, comp denom) |
| static bigint __malloc * | alloc (BI_CTX *ctx, int size) |
| static bigint * | trim (bigint *bi) |
| static void | more_comps (bigint *bi, int n) |
| BI_CTX * | bi_initialize (void) |
| Start a new bigint context. | |
| void | bi_terminate (BI_CTX *ctx) |
| Close the bigint context and free any resources. | |
| bigint * | bi_copy (bigint *bi) |
| Increment the number of references to this object. | |
| void | bi_permanent (bigint *bi) |
| Simply make a bigint object "unfreeable" if bi_free() is called on it. | |
| void | bi_depermanent (bigint *bi) |
| Take a permanent object and make it eligible for freedom. | |
| void | bi_free (BI_CTX *ctx, bigint *bi) |
| Free a bigint object so it can be used again. | |
| bigint * | int_to_bi (BI_CTX *ctx, comp i) |
| Convert an (unsigned) integer into a bigint. | |
| bigint * | bi_clone (BI_CTX *ctx, const bigint *bi) |
| Do a full copy of the bigint object. | |
| bigint * | bi_add (BI_CTX *ctx, bigint *bia, bigint *bib) |
| Perform an addition operation between two bigints. | |
| bigint * | bi_subtract (BI_CTX *ctx, bigint *bia, bigint *bib, int *is_negative) |
| Perform a subtraction operation between two bigints. | |
| bigint * | bi_divide (BI_CTX *ctx, bigint *u, bigint *v, int is_mod) |
| Does both division and modulo calculations. | |
| static bigint * | bi_int_divide (BI_CTX *ctx __unused, bigint *biR, comp denom) |
| bigint * | bi_import (BI_CTX *ctx, const uint8_t *data, int size) |
| Allow a binary sequence to be imported as a bigint. | |
| void | bi_export (BI_CTX *ctx, bigint *x, uint8_t *data, int size) |
| Take a bigint and convert it into a byte sequence. | |
| void | bi_set_mod (BI_CTX *ctx, bigint *bim, int mod_offset) |
| Pre-calculate some of the expensive steps in reduction. | |
| void | bi_free_mod (BI_CTX *ctx, int mod_offset) |
| Used when cleaning various bigints at the end of a session. | |
| static bigint * | regular_multiply (BI_CTX *ctx, bigint *bia, bigint *bib) |
| Perform a standard multiplication between two bigints. | |
| bigint * | bi_multiply (BI_CTX *ctx, bigint *bia, bigint *bib) |
| Perform a multiplication operation between two bigints. | |
| int | bi_compare (bigint *bia, bigint *bib) |
| Compare two bigints. | |
| static int | find_max_exp_index (bigint *biexp) |
| static int | exp_bit_is_one (bigint *biexp, int offset) |
| bigint * | bi_mod_power (BI_CTX *ctx, bigint *bi, bigint *biexp) |
| Perform a modular exponentiation. | |
| bigint * | bi_mod_power2 (BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp) |
| Perform a modular exponentiation using a temporary modulus. | |
The bigint library is for RSA encryption/decryption as well as signing. This code tries to minimise use of malloc/free by maintaining a small cache. A bigint context may maintain state by being made "permanent". It be be later released with a bi_depermanent() and bi_free() call.
It supports the following reduction techniques:
It also implements the following:
All the algorithms used are pretty standard, and designed for different data bus sizes. Negative numbers are not dealt with at all, so a subtraction may need to be tested for negativity.
This library steals some ideas from Jef Poskanzer <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint> and GMP <http://www.swox.com/gmp>. It gets most of its implementation detail from "The Handbook of Applied Cryptography" <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
Perform a multiply between a bigint an an (unsigned) integer.
Definition at line 317 of file bigint.c.
References alloc(), bi_free(), check, COMP_BIT_SIZE, COMP_BYTE_SIZE, _bigint::comps, memset(), r, _bigint::size, and trim().
Referenced by bi_divide(), and bi_set_mod().
00318 { 00319 int j = 0, n = bia->size; 00320 bigint *biR = alloc(ctx, n + 1); 00321 comp carry = 0; 00322 comp *r = biR->comps; 00323 comp *a = bia->comps; 00324 00325 check(bia); 00326 00327 /* clear things to start with */ 00328 memset(r, 0, ((n+1)*COMP_BYTE_SIZE)); 00329 00330 do 00331 { 00332 long_comp tmp = *r + (long_comp)a[j]*b + carry; 00333 *r++ = (comp)tmp; /* downsize */ 00334 carry = (comp)(tmp >> COMP_BIT_SIZE); 00335 } while (++j < n); 00336 00337 *r = carry; 00338 bi_free(ctx, bia); 00339 return trim(biR); 00340 }
Referenced by bi_divide().
Definition at line 1039 of file bigint.c.
References abort, BI_CTX::active_count, COMP_BYTE_SIZE, _bigint::comps, BI_CTX::free_count, BI_CTX::free_list, malloc(), _bigint::max_comps, more_comps(), _bigint::next, NULL, printf(), _bigint::refs, and _bigint::size.
Referenced by bi_clone(), bi_divide(), bi_import(), bi_initialize(), bi_int_multiply(), int_to_bi(), and regular_multiply().
01040 { 01041 bigint *biR; 01042 01043 /* Can we recycle an old bigint? */ 01044 if (ctx->free_list != NULL) 01045 { 01046 biR = ctx->free_list; 01047 ctx->free_list = biR->next; 01048 ctx->free_count--; 01049 01050 if (biR->refs != 0) 01051 { 01052 #ifdef CONFIG_SSL_FULL_MODE 01053 printf("alloc: refs was not 0\n"); 01054 #endif 01055 abort(); /* create a stack trace from a core dump */ 01056 } 01057 01058 more_comps(biR, size); 01059 } 01060 else 01061 { 01062 /* No free bigints available - create a new one. */ 01063 biR = (bigint *)malloc(sizeof(bigint)); 01064 biR->comps = (comp*)malloc(size * COMP_BYTE_SIZE); 01065 biR->max_comps = size; /* give some space to spare */ 01066 } 01067 01068 biR->size = size; 01069 biR->refs = 1; 01070 biR->next = NULL; 01071 ctx->active_count++; 01072 return biR; 01073 }
Definition at line 1145 of file bigint.c.
References check, _bigint::comps, and _bigint::size.
Referenced by bi_add(), bi_divide(), bi_import(), bi_int_divide(), bi_int_multiply(), bi_subtract(), and regular_multiply().
01146 { 01147 check(bi); 01148 01149 while (bi->comps[bi->size-1] == 0 && bi->size > 1) 01150 { 01151 bi->size--; 01152 } 01153 01154 return bi; 01155 }
| static void more_comps | ( | bigint * | bi, | |
| int | n | |||
| ) | [static] |
Definition at line 1019 of file bigint.c.
References COMP_BYTE_SIZE, _bigint::comps, max, _bigint::max_comps, memset(), realloc(), and _bigint::size.
Referenced by alloc(), bi_add(), bi_divide(), and bi_subtract().
01020 { 01021 if (n > bi->max_comps) 01022 { 01023 bi->max_comps = max(bi->max_comps * 2, n); 01024 bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE); 01025 } 01026 01027 if (n > bi->size) 01028 { 01029 memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE); 01030 } 01031 01032 bi->size = n; 01033 }
| BI_CTX* bi_initialize | ( | void | ) |
Start a new bigint context.
Definition at line 78 of file bigint.c.
References alloc(), bi_permanent(), BI_CTX::bi_radix, calloc(), and _bigint::comps.
Referenced by bi_mod_power2(), and RSA_pub_key_new().
00079 { 00080 /* calloc() sets everything to zero */ 00081 BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX)); 00082 00083 /* the radix */ 00084 ctx->bi_radix = alloc(ctx, 2); 00085 ctx->bi_radix->comps[0] = 0; 00086 ctx->bi_radix->comps[1] = 1; 00087 bi_permanent(ctx->bi_radix); 00088 return ctx; 00089 }
| void bi_terminate | ( | BI_CTX * | ctx | ) |
Close the bigint context and free any resources.
Free up any used memory - a check is done if all objects were not properly freed.
| ctx | [in] The bigint session context. |
Definition at line 98 of file bigint.c.
References abort, BI_CTX::active_count, bi_depermanent(), bi_free(), BI_CTX::bi_radix, _bigint::comps, free(), BI_CTX::free_list, _bigint::next, NULL, and printf().
Referenced by bi_mod_power2(), and RSA_free().
00099 { 00100 bigint *p, *pn; 00101 00102 bi_depermanent(ctx->bi_radix); 00103 bi_free(ctx, ctx->bi_radix); 00104 00105 if (ctx->active_count != 0) 00106 { 00107 #ifdef CONFIG_SSL_FULL_MODE 00108 printf("bi_terminate: there were %d un-freed bigints\n", 00109 ctx->active_count); 00110 #endif 00111 abort(); 00112 } 00113 00114 for (p = ctx->free_list; p != NULL; p = pn) 00115 { 00116 pn = p->next; 00117 free(p->comps); 00118 free(p); 00119 } 00120 00121 free(ctx); 00122 }
Increment the number of references to this object.
It does not do a full copy.
| bi | [in] The bigint to copy. |
Definition at line 130 of file bigint.c.
References check, PERMANENT, and _bigint::refs.
Referenced by bi_divide().
00131 { 00132 check(bi); 00133 if (bi->refs != PERMANENT) 00134 bi->refs++; 00135 return bi; 00136 }
| void bi_permanent | ( | bigint * | bi | ) |
Simply make a bigint object "unfreeable" if bi_free() is called on it.
For this object to be freed, bi_depermanent() must be called.
| bi | [in] The bigint to be made permanent. |
Definition at line 144 of file bigint.c.
References abort, check, PERMANENT, printf(), and _bigint::refs.
Referenced by bi_initialize(), bi_mod_power(), bi_set_mod(), RSA_priv_key_new(), and RSA_pub_key_new().
00145 { 00146 check(bi); 00147 if (bi->refs != 1) 00148 { 00149 #ifdef CONFIG_SSL_FULL_MODE 00150 printf("bi_permanent: refs was not 1\n"); 00151 #endif 00152 abort(); 00153 } 00154 00155 bi->refs = PERMANENT; 00156 }
| void bi_depermanent | ( | bigint * | bi | ) |
Take a permanent object and make it eligible for freedom.
| bi | [in] The bigint to be made back to temporary. |
Definition at line 162 of file bigint.c.
References abort, check, PERMANENT, printf(), and _bigint::refs.
Referenced by bi_free_mod(), bi_mod_power(), bi_terminate(), and RSA_free().
00163 { 00164 check(bi); 00165 if (bi->refs != PERMANENT) 00166 { 00167 #ifdef CONFIG_SSL_FULL_MODE 00168 printf("bi_depermanent: bigint was not permanent\n"); 00169 #endif 00170 abort(); 00171 } 00172 00173 bi->refs = 1; 00174 }
Free a bigint object so it can be used again.
The memory itself it not actually freed, just tagged as being available
| ctx | [in] The bigint session context. | |
| bi | [in] The bigint to be freed. |
Definition at line 183 of file bigint.c.
References abort, BI_CTX::active_count, check, BI_CTX::free_count, BI_CTX::free_list, _bigint::next, PERMANENT, printf(), and _bigint::refs.
Referenced by bi_add(), bi_divide(), bi_export(), bi_free_mod(), bi_int_multiply(), bi_mod_power(), bi_mod_power2(), bi_subtract(), bi_terminate(), regular_multiply(), and RSA_free().
00184 { 00185 check(bi); 00186 if (bi->refs == PERMANENT) 00187 { 00188 return; 00189 } 00190 00191 if (--bi->refs > 0) 00192 { 00193 return; 00194 } 00195 00196 bi->next = ctx->free_list; 00197 ctx->free_list = bi; 00198 ctx->free_count++; 00199 00200 if (--ctx->active_count < 0) 00201 { 00202 #ifdef CONFIG_SSL_FULL_MODE 00203 printf("bi_free: active_count went negative " 00204 "- double-freed bigint?\n"); 00205 #endif 00206 abort(); 00207 } 00208 }
Convert an (unsigned) integer into a bigint.
| ctx | [in] The bigint session context. | |
| i | [in] The (unsigned) integer to be converted. |
Definition at line 216 of file bigint.c.
References alloc(), and _bigint::comps.
Referenced by bi_mod_power().
Do a full copy of the bigint object.
| ctx | [in] The bigint session context. | |
| bi | [in] The bigint object to be copied. |
Definition at line 228 of file bigint.c.
References alloc(), check, COMP_BYTE_SIZE, _bigint::comps, memcpy, and _bigint::size.
Referenced by bi_mod_power(), bi_mod_power2(), and bi_set_mod().
00229 { 00230 bigint *biR = alloc(ctx, bi->size); 00231 check(bi); 00232 memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE); 00233 return biR; 00234 }
Perform an addition operation between two bigints.
| ctx | [in] The bigint session context. | |
| bia | [in] A bigint. | |
| bib | [in] Another bigint. |
Definition at line 243 of file bigint.c.
References bi_free(), check, _bigint::comps, max, more_comps(), _bigint::size, and trim().
Referenced by bi_divide().
00244 { 00245 int n; 00246 comp carry = 0; 00247 comp *pa, *pb; 00248 00249 check(bia); 00250 check(bib); 00251 00252 n = max(bia->size, bib->size); 00253 more_comps(bia, n+1); 00254 more_comps(bib, n); 00255 pa = bia->comps; 00256 pb = bib->comps; 00257 00258 do 00259 { 00260 comp sl, rl, cy1; 00261 sl = *pa + *pb++; 00262 rl = sl + carry; 00263 cy1 = sl < *pa; 00264 carry = cy1 | (rl < sl); 00265 *pa++ = rl; 00266 } while (--n != 0); 00267 00268 *pa = carry; /* do overflow */ 00269 bi_free(ctx, bib); 00270 return trim(bia); 00271 }
Perform a subtraction operation between two bigints.
| ctx | [in] The bigint session context. | |
| bia | [in] A bigint. | |
| bib | [in] Another bigint. | |
| is_negative | [out] If defined, indicates that the result was negative. is_negative may be null. |
Definition at line 282 of file bigint.c.
References bi_free(), check, _bigint::comps, more_comps(), _bigint::size, and trim().
Referenced by bi_divide().
00284 { 00285 int n = bia->size; 00286 comp *pa, *pb, carry = 0; 00287 00288 check(bia); 00289 check(bib); 00290 00291 more_comps(bib, n); 00292 pa = bia->comps; 00293 pb = bib->comps; 00294 00295 do 00296 { 00297 comp sl, rl, cy1; 00298 sl = *pa - *pb++; 00299 rl = sl - carry; 00300 cy1 = sl > *pa; 00301 carry = cy1 | (rl > sl); 00302 *pa++ = rl; 00303 } while (--n != 0); 00304 00305 if (is_negative) /* indicate a negative result */ 00306 { 00307 *is_negative = carry; 00308 } 00309 00310 bi_free(ctx, trim(bib)); /* put bib back to the way it was */ 00311 return trim(bia); 00312 }
Does both division and modulo calculations.
Used extensively when doing classical reduction.
| ctx | [in] The bigint session context. | |
| u | [in] A bigint which is the numerator. | |
| v | [in] Either the denominator or the modulus depending on the mode. | |
| is_mod | [n] Determines if this is a normal division (0) or a reduction (1). |
Definition at line 353 of file bigint.c.
References alloc(), bi_add(), bi_compare(), bi_copy(), bi_free(), bi_int_divide(), bi_int_multiply(), BI_CTX::bi_normalised_mod, bi_subtract(), check, COMP_BYTE_SIZE, COMP_RADIX, _bigint::comps, memcpy, memset(), BI_CTX::mod_offset, more_comps(), Q, _bigint::size, trim(), U, V1, and V2.
Referenced by bi_set_mod().
00354 { 00355 int n = v->size, m = u->size-n; 00356 int j = 0, orig_u_size = u->size; 00357 uint8_t mod_offset = ctx->mod_offset; 00358 comp d; 00359 bigint *quotient, *tmp_u; 00360 comp q_dash; 00361 00362 check(u); 00363 check(v); 00364 00365 /* if doing reduction and we are < mod, then return mod */ 00366 if (is_mod && bi_compare(v, u) > 0) 00367 { 00368 bi_free(ctx, v); 00369 return u; 00370 } 00371 00372 quotient = alloc(ctx, m+1); 00373 tmp_u = alloc(ctx, n+1); 00374 v = trim(v); /* make sure we have no leading 0's */ 00375 d = (comp)((long_comp)COMP_RADIX/(V1+1)); 00376 00377 /* clear things to start with */ 00378 memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE)); 00379 00380 /* normalise */ 00381 if (d > 1) 00382 { 00383 u = bi_int_multiply(ctx, u, d); 00384 00385 if (is_mod) 00386 { 00387 v = ctx->bi_normalised_mod[mod_offset]; 00388 } 00389 else 00390 { 00391 v = bi_int_multiply(ctx, v, d); 00392 } 00393 } 00394 00395 if (orig_u_size == u->size) /* new digit position u0 */ 00396 { 00397 more_comps(u, orig_u_size + 1); 00398 } 00399 00400 do 00401 { 00402 /* get a temporary short version of u */ 00403 memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE); 00404 00405 /* calculate q' */ 00406 if (U(0) == V1) 00407 { 00408 q_dash = COMP_RADIX-1; 00409 } 00410 else 00411 { 00412 q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1); 00413 } 00414 00415 if (v->size > 1 && V2) 00416 { 00417 /* we are implementing the following: 00418 if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) - 00419 q_dash*V1)*COMP_RADIX) + U(2))) ... */ 00420 comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) - 00421 (long_comp)q_dash*V1); 00422 if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2)) 00423 { 00424 q_dash--; 00425 } 00426 } 00427 00428 /* multiply and subtract */ 00429 if (q_dash) 00430 { 00431 int is_negative; 00432 tmp_u = bi_subtract(ctx, tmp_u, 00433 bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative); 00434 more_comps(tmp_u, n+1); 00435 00436 Q(j) = q_dash; 00437 00438 /* add back */ 00439 if (is_negative) 00440 { 00441 Q(j)--; 00442 tmp_u = bi_add(ctx, tmp_u, bi_copy(v)); 00443 00444 /* lop off the carry */ 00445 tmp_u->size--; 00446 v->size--; 00447 } 00448 } 00449 else 00450 { 00451 Q(j) = 0; 00452 } 00453 00454 /* copy back to u */ 00455 memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE); 00456 } while (++j <= m); 00457 00458 bi_free(ctx, tmp_u); 00459 bi_free(ctx, v); 00460 00461 if (is_mod) /* get the remainder */ 00462 { 00463 bi_free(ctx, quotient); 00464 return bi_int_divide(ctx, trim(u), d); 00465 } 00466 else /* get the quotient */ 00467 { 00468 bi_free(ctx, u); 00469 return trim(quotient); 00470 } 00471 }
Definition at line 476 of file bigint.c.
References check, COMP_BIT_SIZE, _bigint::comps, r, _bigint::size, and trim().
00477 { 00478 int i = biR->size - 1; 00479 long_comp r = 0; 00480 00481 check(biR); 00482 00483 do 00484 { 00485 r = (r<<COMP_BIT_SIZE) + biR->comps[i]; 00486 biR->comps[i] = (comp)(r / denom); 00487 r %= denom; 00488 } while (--i != 0); 00489 00490 return trim(biR); 00491 }
Allow a binary sequence to be imported as a bigint.
| ctx | [in] The bigint session context. | |
| data | [in] The data to be converted. | |
| size | [in] The number of bytes of data. |
Definition at line 589 of file bigint.c.
References alloc(), COMP_BYTE_SIZE, _bigint::comps, memset(), offset, _bigint::size, and trim().
Referenced by RSA_decrypt(), RSA_encrypt(), RSA_priv_key_new(), and RSA_pub_key_new().
00590 { 00591 bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE); 00592 int i, j = 0, offset = 0; 00593 00594 memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE); 00595 00596 for (i = size-1; i >= 0; i--) 00597 { 00598 biR->comps[offset] += data[i] << (j*8); 00599 00600 if (++j == COMP_BYTE_SIZE) 00601 { 00602 j = 0; 00603 offset ++; 00604 } 00605 } 00606 00607 return trim(biR); 00608 }
Take a bigint and convert it into a byte sequence.
This is useful after a decrypt operation.
| ctx | [in] The bigint session context. | |
| x | [in] The bigint to be converted. | |
| data | [out] The converted data as a byte stream. | |
| size | [in] The maximum size of the byte stream. Unused bytes will be zeroed. |
Definition at line 676 of file bigint.c.
References bi_free(), check, COMP_BYTE_SIZE, _bigint::comps, k, memset(), and _bigint::size.
Referenced by RSA_decrypt(), and RSA_encrypt().
00677 { 00678 int i, j, k = size-1; 00679 00680 check(x); 00681 memset(data, 0, size); /* ensure all leading 0's are cleared */ 00682 00683 for (i = 0; i < x->size; i++) 00684 { 00685 for (j = 0; j < COMP_BYTE_SIZE; j++) 00686 { 00687 comp mask = 0xff << (j*8); 00688 int num = (x->comps[i] & mask) >> (j*8); 00689 data[k--] = num; 00690 00691 if (k < 0) 00692 { 00693 break; 00694 } 00695 } 00696 } 00697 00698 bi_free(ctx, x); 00699 }
Pre-calculate some of the expensive steps in reduction.
This function should only be called once (normally when a session starts). When the session is over, bi_free_mod() should be called. bi_mod_power() relies on this function being called.
| ctx | [in] The bigint session context. | |
| bim | [in] The bigint modulus that will be used. | |
| mod_offset | [in] There are three moduluii that can be stored - the standard modulus, and its two primes p and q. This offset refers to which modulus we are referring to. |
Definition at line 714 of file bigint.c.
References bi_clone(), bi_divide(), bi_int_multiply(), bi_mod, BI_CTX::bi_mod, BI_CTX::bi_normalised_mod, bi_permanent(), BI_CTX::bi_radix, COMP_RADIX, _bigint::comps, k, and _bigint::size.
Referenced by bi_mod_power2(), RSA_priv_key_new(), and RSA_pub_key_new().
00715 { 00716 int k = bim->size; 00717 comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1)); 00718 #ifdef CONFIG_BIGINT_MONTGOMERY 00719 bigint *R, *R2; 00720 #endif 00721 00722 ctx->bi_mod[mod_offset] = bim; 00723 bi_permanent(ctx->bi_mod[mod_offset]); 00724 ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d); 00725 bi_permanent(ctx->bi_normalised_mod[mod_offset]); 00726 00727 #if defined(CONFIG_BIGINT_MONTGOMERY) 00728 /* set montgomery variables */ 00729 R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1); /* R */ 00730 R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1); /* R^2 */ 00731 ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2); /* R^2 mod m */ 00732 ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R); /* R mod m */ 00733 00734 bi_permanent(ctx->bi_RR_mod_m[mod_offset]); 00735 bi_permanent(ctx->bi_R_mod_m[mod_offset]); 00736 00737 ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]); 00738 00739 #elif defined (CONFIG_BIGINT_BARRETT) 00740 ctx->bi_mu[mod_offset] = 00741 bi_divide(ctx, comp_left_shift( 00742 bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0); 00743 bi_permanent(ctx->bi_mu[mod_offset]); 00744 #endif 00745 }
| void bi_free_mod | ( | BI_CTX * | ctx, | |
| int | mod_offset | |||
| ) |
Used when cleaning various bigints at the end of a session.
| ctx | [in] The bigint session context. | |
| mod_offset | [in] The offset to use. |
Definition at line 753 of file bigint.c.
References bi_depermanent(), bi_free(), BI_CTX::bi_mod, and BI_CTX::bi_normalised_mod.
Referenced by bi_mod_power2(), and RSA_free().
00754 { 00755 bi_depermanent(ctx->bi_mod[mod_offset]); 00756 bi_free(ctx, ctx->bi_mod[mod_offset]); 00757 #if defined (CONFIG_BIGINT_MONTGOMERY) 00758 bi_depermanent(ctx->bi_RR_mod_m[mod_offset]); 00759 bi_depermanent(ctx->bi_R_mod_m[mod_offset]); 00760 bi_free(ctx, ctx->bi_RR_mod_m[mod_offset]); 00761 bi_free(ctx, ctx->bi_R_mod_m[mod_offset]); 00762 #elif defined(CONFIG_BIGINT_BARRETT) 00763 bi_depermanent(ctx->bi_mu[mod_offset]); 00764 bi_free(ctx, ctx->bi_mu[mod_offset]); 00765 #endif 00766 bi_depermanent(ctx->bi_normalised_mod[mod_offset]); 00767 bi_free(ctx, ctx->bi_normalised_mod[mod_offset]); 00768 }
Perform a standard multiplication between two bigints.
Definition at line 773 of file bigint.c.
References alloc(), bi_free(), check, COMP_BIT_SIZE, COMP_BYTE_SIZE, _bigint::comps, memset(), _bigint::size, and trim().
Referenced by bi_multiply().
00774 { 00775 int i, j, i_plus_j; 00776 int n = bia->size; 00777 int t = bib->size; 00778 bigint *biR = alloc(ctx, n + t); 00779 comp *sr = biR->comps; 00780 comp *sa = bia->comps; 00781 comp *sb = bib->comps; 00782 00783 check(bia); 00784 check(bib); 00785 00786 /* clear things to start with */ 00787 memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE)); 00788 i = 0; 00789 00790 do 00791 { 00792 comp carry = 0; 00793 comp b = *sb++; 00794 i_plus_j = i; 00795 j = 0; 00796 00797 do 00798 { 00799 long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry; 00800 sr[i_plus_j++] = (comp)tmp; /* downsize */ 00801 carry = (comp)(tmp >> COMP_BIT_SIZE); 00802 } while (++j < n); 00803 00804 sr[i_plus_j] = carry; 00805 } while (++i < t); 00806 00807 bi_free(ctx, bia); 00808 bi_free(ctx, bib); 00809 return trim(biR); 00810 }
Perform a multiplication operation between two bigints.
| ctx | [in] The bigint session context. | |
| bia | [in] A bigint. | |
| bib | [in] Another bigint. |
Definition at line 876 of file bigint.c.
References check, min, regular_multiply(), and _bigint::size.
Referenced by bi_mod_power().
00877 { 00878 check(bia); 00879 check(bib); 00880 00881 #ifdef CONFIG_BIGINT_KARATSUBA 00882 if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH) 00883 { 00884 return regular_multiply(ctx, bia, bib); 00885 } 00886 00887 return karatsuba(ctx, bia, bib, 0); 00888 #else 00889 return regular_multiply(ctx, bia, bib); 00890 #endif 00891 }
Compare two bigints.
| bia | [in] A bigint. | |
| bib | [in] Another bigint. |
Definition at line 977 of file bigint.c.
References check, _bigint::comps, r, and _bigint::size.
Referenced by bi_divide().
00978 { 00979 int r, i; 00980 00981 check(bia); 00982 check(bib); 00983 00984 if (bia->size > bib->size) 00985 r = 1; 00986 else if (bia->size < bib->size) 00987 r = -1; 00988 else 00989 { 00990 comp *a = bia->comps; 00991 comp *b = bib->comps; 00992 00993 /* Same number of components. Compare starting from the high end 00994 * and working down. */ 00995 r = 0; 00996 i = bia->size - 1; 00997 00998 do 00999 { 01000 if (a[i] > b[i]) 01001 { 01002 r = 1; 01003 break; 01004 } 01005 else if (a[i] < b[i]) 01006 { 01007 r = -1; 01008 break; 01009 } 01010 } while (--i >= 0); 01011 } 01012 01013 return r; 01014 }
| static int find_max_exp_index | ( | bigint * | biexp | ) | [static] |
Definition at line 1079 of file bigint.c.
References check, COMP_BIT_SIZE, COMP_RADIX, _bigint::comps, _bigint::size, and test.
Referenced by bi_mod_power().
01080 { 01081 int i = COMP_BIT_SIZE-1; 01082 comp shift = COMP_RADIX/2; 01083 comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */ 01084 01085 check(biexp); 01086 01087 do 01088 { 01089 if (test & shift) 01090 { 01091 return i+(biexp->size-1)*COMP_BIT_SIZE; 01092 } 01093 01094 shift >>= 1; 01095 } while (--i != 0); 01096 01097 return -1; /* error - must have been a leading 0 */ 01098 }
| static int exp_bit_is_one | ( | bigint * | biexp, | |
| int | offset | |||
| ) | [static] |
Definition at line 1104 of file bigint.c.
References check, COMP_BIT_SIZE, _bigint::comps, and test.
Referenced by bi_mod_power().
01105 { 01106 comp test = biexp->comps[offset / COMP_BIT_SIZE]; 01107 int num_shifts = offset % COMP_BIT_SIZE; 01108 comp shift = 1; 01109 int i; 01110 01111 check(biexp); 01112 01113 for (i = 0; i < num_shifts; i++) 01114 { 01115 shift <<= 1; 01116 } 01117 01118 return test & shift; 01119 }
Perform a modular exponentiation.
This function requires bi_set_mod() to have been called previously. This is one of the optimisations used for performance.
| ctx | [in] The bigint session context. | |
| bi | [in] The bigint on which to perform the mod power operation. | |
| biexp | [in] The bigint exponent. |
Definition at line 1371 of file bigint.c.
References bi_clone(), bi_depermanent(), bi_free(), bi_multiply(), bi_permanent(), bi_residue, bi_square, check, exp_bit_is_one(), find_max_exp_index(), free(), BI_CTX::g, int_to_bi(), malloc(), BI_CTX::mod_offset, and BI_CTX::window.
Referenced by bi_mod_power2(), RSA_private(), and RSA_public().
01372 { 01373 int i = find_max_exp_index(biexp), j, window_size = 1; 01374 bigint *biR = int_to_bi(ctx, 1); 01375 01376 #if defined(CONFIG_BIGINT_MONTGOMERY) 01377 uint8_t mod_offset = ctx->mod_offset; 01378 if (!ctx->use_classical) 01379 { 01380 /* preconvert */ 01381 bi = bi_mont(ctx, 01382 bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset])); /* x' */ 01383 bi_free(ctx, biR); 01384 biR = ctx->bi_R_mod_m[mod_offset]; /* A */ 01385 } 01386 #endif 01387 01388 check(bi); 01389 check(biexp); 01390 01391 #ifdef CONFIG_BIGINT_SLIDING_WINDOW 01392 for (j = i; j > 32; j /= 5) /* work out an optimum size */ 01393 window_size++; 01394 01395 /* work out the slide constants */ 01396 precompute_slide_window(ctx, window_size, bi); 01397 #else /* just one constant */ 01398 ctx->g = (bigint **)malloc(sizeof(bigint *)); 01399 ctx->g[0] = bi_clone(ctx, bi); 01400 ctx->window = 1; 01401 bi_permanent(ctx->g[0]); 01402 #endif 01403 01404 /* if sliding-window is off, then only one bit will be done at a time and 01405 * will reduce to standard left-to-right exponentiation */ 01406 do 01407 { 01408 if (exp_bit_is_one(biexp, i)) 01409 { 01410 int l = i-window_size+1; 01411 int part_exp = 0; 01412 01413 if (l < 0) /* LSB of exponent will always be 1 */ 01414 l = 0; 01415 else 01416 { 01417 while (exp_bit_is_one(biexp, l) == 0) 01418 l++; /* go back up */ 01419 } 01420 01421 /* build up the section of the exponent */ 01422 for (j = i; j >= l; j--) 01423 { 01424 biR = bi_residue(ctx, bi_square(ctx, biR)); 01425 if (exp_bit_is_one(biexp, j)) 01426 part_exp++; 01427 01428 if (j != l) 01429 part_exp <<= 1; 01430 } 01431 01432 part_exp = (part_exp-1)/2; /* adjust for array */ 01433 biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp])); 01434 i = l-1; 01435 } 01436 else /* square it */ 01437 { 01438 biR = bi_residue(ctx, bi_square(ctx, biR)); 01439 i--; 01440 } 01441 } while (i >= 0); 01442 01443 /* cleanup */ 01444 for (i = 0; i < ctx->window; i++) 01445 { 01446 bi_depermanent(ctx->g[i]); 01447 bi_free(ctx, ctx->g[i]); 01448 } 01449 01450 free(ctx->g); 01451 bi_free(ctx, bi); 01452 bi_free(ctx, biexp); 01453 #if defined CONFIG_BIGINT_MONTGOMERY 01454 return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */ 01455 #else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */ 01456 return biR; 01457 #endif 01458 }
Perform a modular exponentiation using a temporary modulus.
We need this function to check the signatures of certificates. The modulus of this function is temporary as it's just used for authentication.
| ctx | [in] The bigint session context. | |
| bi | [in] The bigint to perform the exp/mod. | |
| bim | [in] The temporary modulus. | |
| biexp | [in] The bigint exponent. |
Definition at line 1472 of file bigint.c.
References bi_clone(), bi_free(), bi_free_mod(), bi_initialize(), bi_mod_power(), bi_set_mod(), bi_terminate(), and BIGINT_M_OFFSET.
01473 { 01474 bigint *biR, *tmp_biR; 01475 01476 /* Set up a temporary bigint context and transfer what we need between 01477 * them. We need to do this since we want to keep the original modulus 01478 * which is already in this context. This operation is only called when 01479 * doing peer verification, and so is not expensive :-) */ 01480 BI_CTX *tmp_ctx = bi_initialize(); 01481 bi_set_mod(tmp_ctx, bi_clone(tmp_ctx, bim), BIGINT_M_OFFSET); 01482 tmp_biR = bi_mod_power(tmp_ctx, 01483 bi_clone(tmp_ctx, bi), 01484 bi_clone(tmp_ctx, biexp)); 01485 biR = bi_clone(ctx, tmp_biR); 01486 bi_free(tmp_ctx, tmp_biR); 01487 bi_free_mod(tmp_ctx, BIGINT_M_OFFSET); 01488 bi_terminate(tmp_ctx); 01489 01490 bi_free(ctx, bi); 01491 bi_free(ctx, bim); 01492 bi_free(ctx, biexp); 01493 return biR; 01494 }
1.5.7.1