00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <stdlib.h>
00052 #include <limits.h>
00053 #include <string.h>
00054 #include <stdio.h>
00055 #include <time.h>
00056 #include "bigint.h"
00057 #include "crypto.h"
00058
00059 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
00060 static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
00061 static bigint __malloc *alloc(BI_CTX *ctx, int size);
00062 static bigint *trim(bigint *bi);
00063 static void more_comps(bigint *bi, int n);
00064 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
00065 defined(CONFIG_BIGINT_MONTGOMERY)
00066 static bigint *comp_right_shift(bigint *biR, int num_shifts);
00067 static bigint *comp_left_shift(bigint *biR, int num_shifts);
00068 #endif
00069
00070 #ifdef CONFIG_BIGINT_CHECK_ON
00071 static void check(const bigint *bi);
00072 #endif
00073
00074
00075
00076
00077
00078 BI_CTX *bi_initialize(void)
00079 {
00080
00081 BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
00082
00083
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 }
00090
00091
00092
00093
00094
00095
00096
00097
00098 void bi_terminate(BI_CTX *ctx)
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 }
00123
00124
00125
00126
00127
00128
00129
00130 bigint *bi_copy(bigint *bi)
00131 {
00132 check(bi);
00133 if (bi->refs != PERMANENT)
00134 bi->refs++;
00135 return bi;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 void bi_permanent(bigint *bi)
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 }
00157
00158
00159
00160
00161
00162 void bi_depermanent(bigint *bi)
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 }
00175
00176
00177
00178
00179
00180
00181
00182
00183 void bi_free(BI_CTX *ctx, bigint *bi)
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 }
00209
00210
00211
00212
00213
00214
00215
00216 bigint *int_to_bi(BI_CTX *ctx, comp i)
00217 {
00218 bigint *biR = alloc(ctx, 1);
00219 biR->comps[0] = i;
00220 return biR;
00221 }
00222
00223
00224
00225
00226
00227
00228 bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
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 }
00235
00236
00237
00238
00239
00240
00241
00242
00243 bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
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;
00269 bi_free(ctx, bib);
00270 return trim(bia);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 bigint *bi_subtract(BI_CTX *ctx,
00283 bigint *bia, bigint *bib, int *is_negative)
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)
00306 {
00307 *is_negative = carry;
00308 }
00309
00310 bi_free(ctx, trim(bib));
00311 return trim(bia);
00312 }
00313
00314
00315
00316
00317 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
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
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;
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 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_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
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);
00375 d = (comp)((long_comp)COMP_RADIX/(V1+1));
00376
00377
00378 memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
00379
00380
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)
00396 {
00397 more_comps(u, orig_u_size + 1);
00398 }
00399
00400 do
00401 {
00402
00403 memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
00404
00405
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
00418
00419
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
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
00439 if (is_negative)
00440 {
00441 Q(j)--;
00442 tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
00443
00444
00445 tmp_u->size--;
00446 v->size--;
00447 }
00448 }
00449 else
00450 {
00451 Q(j) = 0;
00452 }
00453
00454
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)
00462 {
00463 bi_free(ctx, quotient);
00464 return bi_int_divide(ctx, trim(u), d);
00465 }
00466 else
00467 {
00468 bi_free(ctx, u);
00469 return trim(quotient);
00470 }
00471 }
00472
00473
00474
00475
00476 static bigint *bi_int_divide(BI_CTX *ctx __unused, bigint *biR, comp denom)
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 }
00492
00493 #ifdef CONFIG_BIGINT_MONTGOMERY
00494
00495
00496
00497
00498
00499
00500 static comp modular_inverse(bigint *bim)
00501 {
00502 int i;
00503 comp t = 1;
00504 comp two_2_i_minus_1 = 2;
00505 long_comp two_2_i = 4;
00506 comp N = bim->comps[0];
00507
00508 for (i = 2; i <= COMP_BIT_SIZE; i++)
00509 {
00510 if ((long_comp)N*t%two_2_i >= two_2_i_minus_1)
00511 {
00512 t += two_2_i_minus_1;
00513 }
00514
00515 two_2_i_minus_1 <<= 1;
00516 two_2_i <<= 1;
00517 }
00518
00519 return (comp)(COMP_RADIX-t);
00520 }
00521 #endif
00522
00523 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
00524 defined(CONFIG_BIGINT_MONTGOMERY)
00525
00526
00527
00528 static bigint *comp_right_shift(bigint *biR, int num_shifts)
00529 {
00530 int i = biR->size-num_shifts;
00531 comp *x = biR->comps;
00532 comp *y = &biR->comps[num_shifts];
00533
00534 check(biR);
00535
00536 if (i <= 0)
00537 {
00538 biR->comps[0] = 0;
00539 biR->size = 1;
00540 return biR;
00541 }
00542
00543 do
00544 {
00545 *x++ = *y++;
00546 } while (--i > 0);
00547
00548 biR->size -= num_shifts;
00549 return biR;
00550 }
00551
00552
00553
00554
00555 static bigint *comp_left_shift(bigint *biR, int num_shifts)
00556 {
00557 int i = biR->size-1;
00558 comp *x, *y;
00559
00560 check(biR);
00561
00562 if (num_shifts <= 0)
00563 {
00564 return biR;
00565 }
00566
00567 more_comps(biR, biR->size + num_shifts);
00568
00569 x = &biR->comps[i+num_shifts];
00570 y = &biR->comps[i];
00571
00572 do
00573 {
00574 *x-- = *y--;
00575 } while (i--);
00576
00577 memset(biR->comps, 0, num_shifts*COMP_BYTE_SIZE);
00578 return biR;
00579 }
00580 #endif
00581
00582
00583
00584
00585
00586
00587
00588
00589 bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
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 }
00609
00610 #ifdef CONFIG_SSL_FULL_MODE
00611
00612
00613
00614
00615
00616
00617
00618
00619 bigint *bi_str_import(BI_CTX *ctx, const char *data)
00620 {
00621 int size = strlen(data);
00622 bigint *biR = alloc(ctx, (size+COMP_NUM_NIBBLES-1)/COMP_NUM_NIBBLES);
00623 int i, j = 0, offset = 0;
00624 memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
00625
00626 for (i = size-1; i >= 0; i--)
00627 {
00628 int num = (data[i] <= '9') ? (data[i] - '0') : (data[i] - 'A' + 10);
00629 biR->comps[offset] += num << (j*4);
00630
00631 if (++j == COMP_NUM_NIBBLES)
00632 {
00633 j = 0;
00634 offset ++;
00635 }
00636 }
00637
00638 return biR;
00639 }
00640
00641 void bi_print(const char *label, bigint *x)
00642 {
00643 int i, j;
00644
00645 if (x == NULL)
00646 {
00647 printf("%s: (null)\n", label);
00648 return;
00649 }
00650
00651 printf("%s: (size %d)\n", label, x->size);
00652 for (i = x->size-1; i >= 0; i--)
00653 {
00654 for (j = COMP_NUM_NIBBLES-1; j >= 0; j--)
00655 {
00656 comp mask = 0x0f << (j*4);
00657 comp num = (x->comps[i] & mask) >> (j*4);
00658 putc((num <= 9) ? (num + '0') : (num + 'A' - 10), stdout);
00659 }
00660 }
00661
00662 printf("\n");
00663 }
00664 #endif
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
00677 {
00678 int i, j, k = size-1;
00679
00680 check(x);
00681 memset(data, 0, size);
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 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
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
00729 R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1);
00730 R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1);
00731 ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2);
00732 ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R);
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 }
00746
00747
00748
00749
00750
00751
00752
00753 void bi_free_mod(BI_CTX *ctx, int mod_offset)
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 }
00769
00770
00771
00772
00773 static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
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
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;
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 }
00811
00812 #ifdef CONFIG_BIGINT_KARATSUBA
00813
00814
00815
00816
00817
00818 static bigint *karatsuba(BI_CTX *ctx, bigint *bia, bigint *bib, int is_square)
00819 {
00820 bigint *x0, *x1;
00821 bigint *p0, *p1, *p2;
00822 int m;
00823
00824 if (is_square)
00825 {
00826 m = (bia->size + 1)/2;
00827 }
00828 else
00829 {
00830 m = (max(bia->size, bib->size) + 1)/2;
00831 }
00832
00833 x0 = bi_clone(ctx, bia);
00834 x0->size = m;
00835 x1 = bi_clone(ctx, bia);
00836 comp_right_shift(x1, m);
00837 bi_free(ctx, bia);
00838
00839
00840 if (is_square)
00841 {
00842 p0 = bi_square(ctx, bi_copy(x0));
00843 p2 = bi_square(ctx, bi_copy(x1));
00844 p1 = bi_square(ctx, bi_add(ctx, x0, x1));
00845 }
00846 else
00847 {
00848 bigint *y0, *y1;
00849 y0 = bi_clone(ctx, bib);
00850 y0->size = m;
00851 y1 = bi_clone(ctx, bib);
00852 comp_right_shift(y1, m);
00853 bi_free(ctx, bib);
00854
00855 p0 = bi_multiply(ctx, bi_copy(x0), bi_copy(y0));
00856 p2 = bi_multiply(ctx, bi_copy(x1), bi_copy(y1));
00857 p1 = bi_multiply(ctx, bi_add(ctx, x0, x1), bi_add(ctx, y0, y1));
00858 }
00859
00860 p1 = bi_subtract(ctx,
00861 bi_subtract(ctx, p1, bi_copy(p2), NULL), bi_copy(p0), NULL);
00862
00863 comp_left_shift(p1, m);
00864 comp_left_shift(p2, 2*m);
00865 return bi_add(ctx, p1, bi_add(ctx, p0, p2));
00866 }
00867 #endif
00868
00869
00870
00871
00872
00873
00874
00875
00876 bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
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 }
00892
00893 #ifdef CONFIG_BIGINT_SQUARE
00894
00895
00896
00897 static bigint *regular_square(BI_CTX *ctx, bigint *bi)
00898 {
00899 int t = bi->size;
00900 int i = 0, j;
00901 bigint *biR = alloc(ctx, t*2);
00902 comp *w = biR->comps;
00903 comp *x = bi->comps;
00904 comp carry;
00905
00906 memset(w, 0, biR->size*COMP_BYTE_SIZE);
00907
00908 do
00909 {
00910 long_comp tmp = w[2*i] + (long_comp)x[i]*x[i];
00911 comp u = 0;
00912 w[2*i] = (comp)tmp;
00913 carry = (comp)(tmp >> COMP_BIT_SIZE);
00914
00915 for (j = i+1; j < t; j++)
00916 {
00917 long_comp xx = (long_comp)x[i]*x[j];
00918 long_comp blob = (long_comp)w[i+j]+carry;
00919
00920 if (u)
00921 {
00922 blob += COMP_RADIX;
00923 }
00924
00925 u = 0;
00926 if (xx & COMP_BIG_MSB)
00927 {
00928 u = 1;
00929 }
00930
00931 tmp = 2*xx + blob;
00932 w[i+j] = (comp)tmp;
00933 carry = (comp)(tmp >> COMP_BIT_SIZE);
00934 }
00935
00936 w[i+t] += carry;
00937
00938 if (u)
00939 {
00940 w[i+t+1] = 1;
00941 }
00942 } while (++i < t);
00943
00944 bi_free(ctx, bi);
00945 return trim(biR);
00946 }
00947
00948
00949
00950
00951
00952
00953
00954 bigint *bi_square(BI_CTX *ctx, bigint *bia)
00955 {
00956 check(bia);
00957
00958 #ifdef CONFIG_BIGINT_KARATSUBA
00959 if (bia->size < SQU_KARATSUBA_THRESH)
00960 {
00961 return regular_square(ctx, bia);
00962 }
00963
00964 return karatsuba(ctx, bia, NULL, 1);
00965 #else
00966 return regular_square(ctx, bia);
00967 #endif
00968 }
00969 #endif
00970
00971
00972
00973
00974
00975
00976
00977 int bi_compare(bigint *bia, bigint *bib)
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
00994
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 }
01015
01016
01017
01018
01019 static void more_comps(bigint *bi, int n)
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 }
01034
01035
01036
01037
01038
01039 static bigint *alloc(BI_CTX *ctx, int size)
01040 {
01041 bigint *biR;
01042
01043
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();
01056 }
01057
01058 more_comps(biR, size);
01059 }
01060 else
01061 {
01062
01063 biR = (bigint *)malloc(sizeof(bigint));
01064 biR->comps = (comp*)malloc(size * COMP_BYTE_SIZE);
01065 biR->max_comps = size;
01066 }
01067
01068 biR->size = size;
01069 biR->refs = 1;
01070 biR->next = NULL;
01071 ctx->active_count++;
01072 return biR;
01073 }
01074
01075
01076
01077
01078
01079 static int find_max_exp_index(bigint *biexp)
01080 {
01081 int i = COMP_BIT_SIZE-1;
01082 comp shift = COMP_RADIX/2;
01083 comp test = biexp->comps[biexp->size-1];
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;
01098 }
01099
01100
01101
01102
01103
01104 static int exp_bit_is_one(bigint *biexp, int offset)
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 }
01120
01121 #ifdef CONFIG_BIGINT_CHECK_ON
01122
01123
01124
01125 static void check(const bigint *bi)
01126 {
01127 if (bi->refs <= 0)
01128 {
01129 printf("check: zero or negative refs in bigint\n");
01130 abort();
01131 }
01132
01133 if (bi->next != NULL)
01134 {
01135 printf("check: attempt to use a bigint from "
01136 "the free list\n");
01137 abort();
01138 }
01139 }
01140 #endif
01141
01142
01143
01144
01145 static bigint *trim(bigint *bi)
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 }
01156
01157 #if defined(CONFIG_BIGINT_MONTGOMERY)
01158
01159
01160
01161
01162
01163
01164 bigint *bi_mont(BI_CTX *ctx, bigint *bixy)
01165 {
01166 int i = 0, n;
01167 uint8_t mod_offset = ctx->mod_offset;
01168 bigint *bim = ctx->bi_mod[mod_offset];
01169 comp mod_inv = ctx->N0_dash[mod_offset];
01170
01171 check(bixy);
01172
01173 if (ctx->use_classical)
01174 {
01175 return bi_mod(ctx, bixy);
01176 }
01177
01178 n = bim->size;
01179
01180 do
01181 {
01182 bixy = bi_add(ctx, bixy, comp_left_shift(
01183 bi_int_multiply(ctx, bim, bixy->comps[i]*mod_inv), i));
01184 } while (++i < n);
01185
01186 comp_right_shift(bixy, n);
01187
01188 if (bi_compare(bixy, bim) >= 0)
01189 {
01190 bixy = bi_subtract(ctx, bixy, bim, NULL);
01191 }
01192
01193 return bixy;
01194 }
01195
01196 #elif defined(CONFIG_BIGINT_BARRETT)
01197
01198
01199
01200
01201 static bigint *comp_mod(bigint *bi, int mod)
01202 {
01203 check(bi);
01204
01205 if (bi->size > mod)
01206 {
01207 bi->size = mod;
01208 }
01209
01210 return bi;
01211 }
01212
01213
01214
01215
01216
01217
01218 static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib,
01219 int inner_partial, int outer_partial)
01220 {
01221 int i = 0, j, n = bia->size, t = bib->size;
01222 bigint *biR;
01223 comp carry;
01224 comp *sr, *sa, *sb;
01225
01226 check(bia);
01227 check(bib);
01228
01229 biR = alloc(ctx, n + t);
01230 sa = bia->comps;
01231 sb = bib->comps;
01232 sr = biR->comps;
01233
01234 if (inner_partial)
01235 {
01236 memset(sr, 0, inner_partial*COMP_BYTE_SIZE);
01237 }
01238 else
01239 {
01240 if (n < outer_partial || t < outer_partial)
01241 {
01242 bi_free(ctx, bia);
01243 bi_free(ctx, bib);
01244 biR->comps[0] = 0;
01245 biR->size = 1;
01246 return biR;
01247 }
01248
01249 memset(&sr[outer_partial], 0, (n+t-outer_partial)*COMP_BYTE_SIZE);
01250 }
01251
01252 do
01253 {
01254 comp *a = sa;
01255 comp b = *sb++;
01256 long_comp tmp;
01257 int i_plus_j = i;
01258 carry = 0;
01259 j = n;
01260
01261 if (outer_partial && i_plus_j < outer_partial)
01262 {
01263 i_plus_j = outer_partial;
01264 a = &sa[outer_partial-i];
01265 j = n-(outer_partial-i);
01266 }
01267
01268 do
01269 {
01270 if (inner_partial && i_plus_j >= inner_partial)
01271 {
01272 break;
01273 }
01274
01275 tmp = sr[i_plus_j] + ((long_comp)*a++)*b + carry;
01276 sr[i_plus_j++] = (comp)tmp;
01277 carry = (comp)(tmp >> COMP_BIT_SIZE);
01278 } while (--j != 0);
01279
01280 sr[i_plus_j] = carry;
01281 } while (++i < t);
01282
01283 bi_free(ctx, bia);
01284 bi_free(ctx, bib);
01285 return trim(biR);
01286 }
01287
01288
01289
01290
01291
01292
01293
01294 bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
01295 {
01296 bigint *q1, *q2, *q3, *r1, *r2, *r;
01297 uint8_t mod_offset = ctx->mod_offset;
01298 bigint *bim = ctx->bi_mod[mod_offset];
01299 int k = bim->size;
01300
01301 check(bi);
01302 check(bim);
01303
01304
01305 if (bi->size > k*2)
01306 {
01307 return bi_mod(ctx, bi);
01308 }
01309
01310 q1 = comp_right_shift(bi_clone(ctx, bi), k-1);
01311
01312
01313 q2 = partial_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1);
01314 q3 = comp_right_shift(q2, k+1);
01315 r1 = comp_mod(bi, k+1);
01316
01317
01318 r2 = comp_mod(partial_multiply(ctx, q3, bim, k+1, 0), k+1);
01319 r = bi_subtract(ctx, r1, r2, NULL);
01320
01321
01322 if (bi_compare(r, bim) >= 0)
01323 {
01324 r = bi_subtract(ctx, r, bim, NULL);
01325 }
01326
01327 return r;
01328 }
01329 #endif
01330
01331 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
01332
01333
01334
01335 static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1)
01336 {
01337 int k = 1, i;
01338 bigint *g2;
01339
01340 for (i = 0; i < window-1; i++)
01341 {
01342 k <<= 1;
01343 }
01344
01345 ctx->g = (bigint **)malloc(k*sizeof(bigint *));
01346 ctx->g[0] = bi_clone(ctx, g1);
01347 bi_permanent(ctx->g[0]);
01348 g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0]));
01349
01350 for (i = 1; i < k; i++)
01351 {
01352 ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i-1], bi_copy(g2)));
01353 bi_permanent(ctx->g[i]);
01354 }
01355
01356 bi_free(ctx, g2);
01357 ctx->window = k;
01358 }
01359 #endif
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371 bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
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
01381 bi = bi_mont(ctx,
01382 bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset]));
01383 bi_free(ctx, biR);
01384 biR = ctx->bi_R_mod_m[mod_offset];
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)
01393 window_size++;
01394
01395
01396 precompute_slide_window(ctx, window_size, bi);
01397 #else
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
01405
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)
01414 l = 0;
01415 else
01416 {
01417 while (exp_bit_is_one(biexp, l) == 0)
01418 l++;
01419 }
01420
01421
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;
01433 biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp]));
01434 i = l-1;
01435 }
01436 else
01437 {
01438 biR = bi_residue(ctx, bi_square(ctx, biR));
01439 i--;
01440 }
01441 } while (i >= 0);
01442
01443
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);
01455 #else
01456 return biR;
01457 #endif
01458 }
01459
01460 #ifdef CONFIG_SSL_CERT_VERIFICATION
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472 bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp)
01473 {
01474 bigint *biR, *tmp_biR;
01475
01476
01477
01478
01479
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 }
01495 #endif
01496