Annotation of qemu/roms/ipxe/src/crypto/axtls/bigint.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Copyright(C) 2006 Cameron Rich
                      3:  *
                      4:  *  This library is free software; you can redistribute it and/or modify
                      5:  *  it under the terms of the GNU Lesser General Public License as published by
                      6:  *  the Free Software Foundation; either version 2.1 of the License, or
                      7:  *  (at your option) any later version.
                      8:  *
                      9:  *  This library is distributed in the hope that it will be useful,
                     10:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12:  *  GNU Lesser General Public License for more details.
                     13:  *
                     14:  *  You should have received a copy of the GNU Lesser General Public License
                     15:  *  along with this library; if not, write to the Free Software
                     16:  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     17:  */
                     18: 
                     19: /**
                     20:  * @defgroup bigint_api Big Integer API
                     21:  * @brief The bigint implementation as used by the axTLS project.
                     22:  *
                     23:  * The bigint library is for RSA encryption/decryption as well as signing.
                     24:  * This code tries to minimise use of malloc/free by maintaining a small 
                     25:  * cache. A bigint context may maintain state by being made "permanent". 
                     26:  * It be be later released with a bi_depermanent() and bi_free() call.
                     27:  *
                     28:  * It supports the following reduction techniques:
                     29:  * - Classical
                     30:  * - Barrett
                     31:  * - Montgomery
                     32:  *
                     33:  * It also implements the following:
                     34:  * - Karatsuba multiplication
                     35:  * - Squaring
                     36:  * - Sliding window exponentiation
                     37:  * - Chinese Remainder Theorem (implemented in rsa.c).
                     38:  *
                     39:  * All the algorithms used are pretty standard, and designed for different
                     40:  * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
                     41:  * may need to be tested for negativity.
                     42:  *
                     43:  * This library steals some ideas from Jef Poskanzer
                     44:  * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
                     45:  * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
                     46:  * detail from "The Handbook of Applied Cryptography"
                     47:  * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
                     48:  * @{
                     49:  */
                     50: 
                     51: #include <stdlib.h>
                     52: #include <limits.h>
                     53: #include <string.h>
                     54: #include <stdio.h>
                     55: #include <time.h>
                     56: #include "bigint.h"
                     57: #include "crypto.h"
                     58: 
                     59: static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
                     60: static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
                     61: static bigint __malloc *alloc(BI_CTX *ctx, int size);
                     62: static bigint *trim(bigint *bi);
                     63: static void more_comps(bigint *bi, int n);
                     64: #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
                     65:     defined(CONFIG_BIGINT_MONTGOMERY)
                     66: static bigint *comp_right_shift(bigint *biR, int num_shifts);
                     67: static bigint *comp_left_shift(bigint *biR, int num_shifts);
                     68: #endif
                     69: 
                     70: #ifdef CONFIG_BIGINT_CHECK_ON
                     71: static void check(const bigint *bi);
                     72: #endif
                     73: 
                     74: /**
                     75:  * @brief Start a new bigint context.
                     76:  * @return A bigint context.
                     77:  */
                     78: BI_CTX *bi_initialize(void)
                     79: {
                     80:     /* calloc() sets everything to zero */
                     81:     BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
                     82:    
                     83:     /* the radix */
                     84:     ctx->bi_radix = alloc(ctx, 2); 
                     85:     ctx->bi_radix->comps[0] = 0;
                     86:     ctx->bi_radix->comps[1] = 1;
                     87:     bi_permanent(ctx->bi_radix);
                     88:     return ctx;
                     89: }
                     90: 
                     91: /**
                     92:  * @brief Close the bigint context and free any resources.
                     93:  *
                     94:  * Free up any used memory - a check is done if all objects were not 
                     95:  * properly freed.
                     96:  * @param ctx [in]   The bigint session context.
                     97:  */
                     98: void bi_terminate(BI_CTX *ctx)
                     99: {
                    100:     bigint *p, *pn;
                    101: 
                    102:     bi_depermanent(ctx->bi_radix); 
                    103:     bi_free(ctx, ctx->bi_radix);
                    104: 
                    105:     if (ctx->active_count != 0)
                    106:     {
                    107: #ifdef CONFIG_SSL_FULL_MODE
                    108:         printf("bi_terminate: there were %d un-freed bigints\n",
                    109:                        ctx->active_count);
                    110: #endif
                    111:         abort();
                    112:     }
                    113: 
                    114:     for (p = ctx->free_list; p != NULL; p = pn)
                    115:     {
                    116:         pn = p->next;
                    117:         free(p->comps);
                    118:         free(p);
                    119:     }
                    120: 
                    121:     free(ctx);
                    122: }
                    123: 
                    124: /**
                    125:  * @brief Increment the number of references to this object. 
                    126:  * It does not do a full copy.
                    127:  * @param bi [in]   The bigint to copy.
                    128:  * @return A reference to the same bigint.
                    129:  */
                    130: bigint *bi_copy(bigint *bi)
                    131: {
                    132:     check(bi);
                    133:     if (bi->refs != PERMANENT)
                    134:         bi->refs++;
                    135:     return bi;
                    136: }
                    137: 
                    138: /**
                    139:  * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
                    140:  *
                    141:  * For this object to be freed, bi_depermanent() must be called.
                    142:  * @param bi [in]   The bigint to be made permanent.
                    143:  */
                    144: void bi_permanent(bigint *bi)
                    145: {
                    146:     check(bi);
                    147:     if (bi->refs != 1)
                    148:     {
                    149: #ifdef CONFIG_SSL_FULL_MODE
                    150:         printf("bi_permanent: refs was not 1\n");
                    151: #endif
                    152:         abort();
                    153:     }
                    154: 
                    155:     bi->refs = PERMANENT;
                    156: }
                    157: 
                    158: /**
                    159:  * @brief Take a permanent object and make it eligible for freedom.
                    160:  * @param bi [in]   The bigint to be made back to temporary.
                    161:  */
                    162: void bi_depermanent(bigint *bi)
                    163: {
                    164:     check(bi);
                    165:     if (bi->refs != PERMANENT)
                    166:     {
                    167: #ifdef CONFIG_SSL_FULL_MODE
                    168:         printf("bi_depermanent: bigint was not permanent\n");
                    169: #endif
                    170:         abort();
                    171:     }
                    172: 
                    173:     bi->refs = 1;
                    174: }
                    175: 
                    176: /**
                    177:  * @brief Free a bigint object so it can be used again. 
                    178:  *
                    179:  * The memory itself it not actually freed, just tagged as being available 
                    180:  * @param ctx [in]   The bigint session context.
                    181:  * @param bi [in]    The bigint to be freed.
                    182:  */
                    183: void bi_free(BI_CTX *ctx, bigint *bi)
                    184: {
                    185:     check(bi);
                    186:     if (bi->refs == PERMANENT)
                    187:     {
                    188:         return;
                    189:     }
                    190: 
                    191:     if (--bi->refs > 0)
                    192:     {
                    193:         return;
                    194:     }
                    195: 
                    196:     bi->next = ctx->free_list;
                    197:     ctx->free_list = bi;
                    198:     ctx->free_count++;
                    199: 
                    200:     if (--ctx->active_count < 0)
                    201:     {
                    202: #ifdef CONFIG_SSL_FULL_MODE
                    203:         printf("bi_free: active_count went negative "
                    204:                 "- double-freed bigint?\n");
                    205: #endif
                    206:         abort();
                    207:     }
                    208: }
                    209: 
                    210: /**
                    211:  * @brief Convert an (unsigned) integer into a bigint.
                    212:  * @param ctx [in]   The bigint session context.
                    213:  * @param i [in]     The (unsigned) integer to be converted.
                    214:  * 
                    215:  */
                    216: bigint *int_to_bi(BI_CTX *ctx, comp i)
                    217: {
                    218:     bigint *biR = alloc(ctx, 1);
                    219:     biR->comps[0] = i;
                    220:     return biR;
                    221: }
                    222: 
                    223: /**
                    224:  * @brief Do a full copy of the bigint object.
                    225:  * @param ctx [in]   The bigint session context.
                    226:  * @param bi  [in]   The bigint object to be copied.
                    227:  */
                    228: bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
                    229: {
                    230:     bigint *biR = alloc(ctx, bi->size);
                    231:     check(bi);
                    232:     memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
                    233:     return biR;
                    234: }
                    235: 
                    236: /**
                    237:  * @brief Perform an addition operation between two bigints.
                    238:  * @param ctx [in]  The bigint session context.
                    239:  * @param bia [in]  A bigint.
                    240:  * @param bib [in]  Another bigint.
                    241:  * @return The result of the addition.
                    242:  */
                    243: bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
                    244: {
                    245:     int n;
                    246:     comp carry = 0;
                    247:     comp *pa, *pb;
                    248: 
                    249:     check(bia);
                    250:     check(bib);
                    251: 
                    252:     n = max(bia->size, bib->size);
                    253:     more_comps(bia, n+1);
                    254:     more_comps(bib, n);
                    255:     pa = bia->comps;
                    256:     pb = bib->comps;
                    257: 
                    258:     do
                    259:     {
                    260:         comp  sl, rl, cy1;
                    261:         sl = *pa + *pb++;
                    262:         rl = sl + carry;
                    263:         cy1 = sl < *pa;
                    264:         carry = cy1 | (rl < sl);
                    265:         *pa++ = rl;
                    266:     } while (--n != 0);
                    267: 
                    268:     *pa = carry;                  /* do overflow */
                    269:     bi_free(ctx, bib);
                    270:     return trim(bia);
                    271: }
                    272: 
                    273: /**
                    274:  * @brief Perform a subtraction operation between two bigints.
                    275:  * @param ctx [in]  The bigint session context.
                    276:  * @param bia [in]  A bigint.
                    277:  * @param bib [in]  Another bigint.
                    278:  * @param is_negative [out] If defined, indicates that the result was negative.
                    279:  * is_negative may be null.
                    280:  * @return The result of the subtraction. The result is always positive.
                    281:  */
                    282: bigint *bi_subtract(BI_CTX *ctx, 
                    283:         bigint *bia, bigint *bib, int *is_negative)
                    284: {
                    285:     int n = bia->size;
                    286:     comp *pa, *pb, carry = 0;
                    287: 
                    288:     check(bia);
                    289:     check(bib);
                    290: 
                    291:     more_comps(bib, n);
                    292:     pa = bia->comps;
                    293:     pb = bib->comps;
                    294: 
                    295:     do 
                    296:     {
                    297:         comp sl, rl, cy1;
                    298:         sl = *pa - *pb++;
                    299:         rl = sl - carry;
                    300:         cy1 = sl > *pa;
                    301:         carry = cy1 | (rl > sl);
                    302:         *pa++ = rl;
                    303:     } while (--n != 0);
                    304: 
                    305:     if (is_negative)    /* indicate a negative result */
                    306:     {
                    307:         *is_negative = carry;
                    308:     }
                    309: 
                    310:     bi_free(ctx, trim(bib));    /* put bib back to the way it was */
                    311:     return trim(bia);
                    312: }
                    313: 
                    314: /**
                    315:  * Perform a multiply between a bigint an an (unsigned) integer
                    316:  */
                    317: static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
                    318: {
                    319:     int j = 0, n = bia->size;
                    320:     bigint *biR = alloc(ctx, n + 1);
                    321:     comp carry = 0;
                    322:     comp *r = biR->comps;
                    323:     comp *a = bia->comps;
                    324: 
                    325:     check(bia);
                    326: 
                    327:     /* clear things to start with */
                    328:     memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
                    329: 
                    330:     do
                    331:     {
                    332:         long_comp tmp = *r + (long_comp)a[j]*b + carry;
                    333:         *r++ = (comp)tmp;              /* downsize */
                    334:         carry = (comp)(tmp >> COMP_BIT_SIZE);
                    335:     } while (++j < n);
                    336: 
                    337:     *r = carry;
                    338:     bi_free(ctx, bia);
                    339:     return trim(biR);
                    340: }
                    341: 
                    342: /**
                    343:  * @brief Does both division and modulo calculations. 
                    344:  *
                    345:  * Used extensively when doing classical reduction.
                    346:  * @param ctx [in]  The bigint session context.
                    347:  * @param u [in]    A bigint which is the numerator.
                    348:  * @param v [in]    Either the denominator or the modulus depending on the mode.
                    349:  * @param is_mod [n] Determines if this is a normal division (0) or a reduction
                    350:  * (1).
                    351:  * @return  The result of the division/reduction.
                    352:  */
                    353: bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
                    354: {
                    355:     int n = v->size, m = u->size-n;
                    356:     int j = 0, orig_u_size = u->size;
                    357:     uint8_t mod_offset = ctx->mod_offset;
                    358:     comp d;
                    359:     bigint *quotient, *tmp_u;
                    360:     comp q_dash;
                    361: 
                    362:     check(u);
                    363:     check(v);
                    364: 
                    365:     /* if doing reduction and we are < mod, then return mod */
                    366:     if (is_mod && bi_compare(v, u) > 0)
                    367:     {
                    368:         bi_free(ctx, v);
                    369:         return u;
                    370:     }
                    371: 
                    372:     quotient = alloc(ctx, m+1);
                    373:     tmp_u = alloc(ctx, n+1);
                    374:     v = trim(v);        /* make sure we have no leading 0's */
                    375:     d = (comp)((long_comp)COMP_RADIX/(V1+1));
                    376: 
                    377:     /* clear things to start with */
                    378:     memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
                    379: 
                    380:     /* normalise */
                    381:     if (d > 1)
                    382:     {
                    383:         u = bi_int_multiply(ctx, u, d);
                    384: 
                    385:         if (is_mod)
                    386:         {
                    387:             v = ctx->bi_normalised_mod[mod_offset];
                    388:         }
                    389:         else
                    390:         {
                    391:             v = bi_int_multiply(ctx, v, d);
                    392:         }
                    393:     }
                    394: 
                    395:     if (orig_u_size == u->size)  /* new digit position u0 */
                    396:     {
                    397:         more_comps(u, orig_u_size + 1);
                    398:     }
                    399: 
                    400:     do
                    401:     {
                    402:         /* get a temporary short version of u */
                    403:         memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
                    404: 
                    405:         /* calculate q' */
                    406:         if (U(0) == V1)
                    407:         {
                    408:             q_dash = COMP_RADIX-1;
                    409:         }
                    410:         else
                    411:         {
                    412:             q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
                    413:         }
                    414: 
                    415:         if (v->size > 1 && V2)
                    416:         {
                    417:             /* we are implementing the following:
                    418:             if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) - 
                    419:                     q_dash*V1)*COMP_RADIX) + U(2))) ... */
                    420:             comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) - 
                    421:                                         (long_comp)q_dash*V1);
                    422:             if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
                    423:             {
                    424:                 q_dash--;
                    425:             }
                    426:         }
                    427: 
                    428:         /* multiply and subtract */
                    429:         if (q_dash)
                    430:         {
                    431:             int is_negative;
                    432:             tmp_u = bi_subtract(ctx, tmp_u, 
                    433:                     bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
                    434:             more_comps(tmp_u, n+1);
                    435: 
                    436:             Q(j) = q_dash; 
                    437: 
                    438:             /* add back */
                    439:             if (is_negative)
                    440:             {
                    441:                 Q(j)--;
                    442:                 tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
                    443: 
                    444:                 /* lop off the carry */
                    445:                 tmp_u->size--;
                    446:                 v->size--;
                    447:             }
                    448:         }
                    449:         else
                    450:         {
                    451:             Q(j) = 0; 
                    452:         }
                    453: 
                    454:         /* copy back to u */
                    455:         memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
                    456:     } while (++j <= m);
                    457: 
                    458:     bi_free(ctx, tmp_u);
                    459:     bi_free(ctx, v);
                    460: 
                    461:     if (is_mod)     /* get the remainder */
                    462:     {
                    463:         bi_free(ctx, quotient);
                    464:         return bi_int_divide(ctx, trim(u), d);
                    465:     }
                    466:     else            /* get the quotient */
                    467:     {
                    468:         bi_free(ctx, u);
                    469:         return trim(quotient);
                    470:     }
                    471: }
                    472: 
                    473: /*
                    474:  * Perform an integer divide on a bigint.
                    475:  */
                    476: static bigint *bi_int_divide(BI_CTX *ctx __unused, bigint *biR, comp denom)
                    477: {
                    478:     int i = biR->size - 1;
                    479:     long_comp r = 0;
                    480: 
                    481:     check(biR);
                    482: 
                    483:     do
                    484:     {
                    485:         r = (r<<COMP_BIT_SIZE) + biR->comps[i];
                    486:         biR->comps[i] = (comp)(r / denom);
                    487:         r %= denom;
                    488:     } while (--i != 0);
                    489: 
                    490:     return trim(biR);
                    491: }
                    492: 
                    493: #ifdef CONFIG_BIGINT_MONTGOMERY
                    494: /**
                    495:  * There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1, 
                    496:  * where B^-1(B-1) mod N=1. Actually, only the least significant part of 
                    497:  * N' is needed, hence the definition N0'=N' mod b. We reproduce below the 
                    498:  * simple algorithm from an article by Dusse and Kaliski to efficiently 
                    499:  * find N0' from N0 and b */
                    500: static comp modular_inverse(bigint *bim)
                    501: {
                    502:     int i;
                    503:     comp t = 1;
                    504:     comp two_2_i_minus_1 = 2;   /* 2^(i-1) */
                    505:     long_comp two_2_i = 4;      /* 2^i */
                    506:     comp N = bim->comps[0];
                    507: 
                    508:     for (i = 2; i <= COMP_BIT_SIZE; i++)
                    509:     {
                    510:         if ((long_comp)N*t%two_2_i >= two_2_i_minus_1)
                    511:         {
                    512:             t += two_2_i_minus_1;
                    513:         }
                    514: 
                    515:         two_2_i_minus_1 <<= 1;
                    516:         two_2_i <<= 1;
                    517:     }
                    518: 
                    519:     return (comp)(COMP_RADIX-t);
                    520: }
                    521: #endif
                    522: 
                    523: #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
                    524:     defined(CONFIG_BIGINT_MONTGOMERY)
                    525: /**
                    526:  * Take each component and shift down (in terms of components) 
                    527:  */
                    528: static bigint *comp_right_shift(bigint *biR, int num_shifts)
                    529: {
                    530:     int i = biR->size-num_shifts;
                    531:     comp *x = biR->comps;
                    532:     comp *y = &biR->comps[num_shifts];
                    533: 
                    534:     check(biR);
                    535: 
                    536:     if (i <= 0)     /* have we completely right shifted? */
                    537:     {
                    538:         biR->comps[0] = 0;  /* return 0 */
                    539:         biR->size = 1;
                    540:         return biR;
                    541:     }
                    542: 
                    543:     do
                    544:     {
                    545:         *x++ = *y++;
                    546:     } while (--i > 0);
                    547: 
                    548:     biR->size -= num_shifts;
                    549:     return biR;
                    550: }
                    551: 
                    552: /**
                    553:  * Take each component and shift it up (in terms of components) 
                    554:  */
                    555: static bigint *comp_left_shift(bigint *biR, int num_shifts)
                    556: {
                    557:     int i = biR->size-1;
                    558:     comp *x, *y;
                    559: 
                    560:     check(biR);
                    561: 
                    562:     if (num_shifts <= 0)
                    563:     {
                    564:         return biR;
                    565:     }
                    566: 
                    567:     more_comps(biR, biR->size + num_shifts);
                    568: 
                    569:     x = &biR->comps[i+num_shifts];
                    570:     y = &biR->comps[i];
                    571: 
                    572:     do
                    573:     {
                    574:         *x-- = *y--;
                    575:     } while (i--);
                    576: 
                    577:     memset(biR->comps, 0, num_shifts*COMP_BYTE_SIZE); /* zero LS comps */
                    578:     return biR;
                    579: }
                    580: #endif
                    581: 
                    582: /**
                    583:  * @brief Allow a binary sequence to be imported as a bigint.
                    584:  * @param ctx [in]  The bigint session context.
                    585:  * @param data [in] The data to be converted.
                    586:  * @param size [in] The number of bytes of data.
                    587:  * @return A bigint representing this data.
                    588:  */
                    589: bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
                    590: {
                    591:     bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
                    592:     int i, j = 0, offset = 0;
                    593: 
                    594:     memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
                    595: 
                    596:     for (i = size-1; i >= 0; i--)
                    597:     {
                    598:         biR->comps[offset] += data[i] << (j*8);
                    599: 
                    600:         if (++j == COMP_BYTE_SIZE)
                    601:         {
                    602:             j = 0;
                    603:             offset ++;
                    604:         }
                    605:     }
                    606: 
                    607:     return trim(biR);
                    608: }
                    609: 
                    610: #ifdef CONFIG_SSL_FULL_MODE
                    611: /**
                    612:  * @brief The testharness uses this code to import text hex-streams and 
                    613:  * convert them into bigints.
                    614:  * @param ctx [in]  The bigint session context.
                    615:  * @param data [in] A string consisting of hex characters. The characters must
                    616:  * be in upper case.
                    617:  * @return A bigint representing this data.
                    618:  */
                    619: bigint *bi_str_import(BI_CTX *ctx, const char *data)
                    620: {
                    621:     int size = strlen(data);
                    622:     bigint *biR = alloc(ctx, (size+COMP_NUM_NIBBLES-1)/COMP_NUM_NIBBLES);
                    623:     int i, j = 0, offset = 0;
                    624:     memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
                    625: 
                    626:     for (i = size-1; i >= 0; i--)
                    627:     {
                    628:         int num = (data[i] <= '9') ? (data[i] - '0') : (data[i] - 'A' + 10);
                    629:         biR->comps[offset] += num << (j*4);
                    630: 
                    631:         if (++j == COMP_NUM_NIBBLES)
                    632:         {
                    633:             j = 0;
                    634:             offset ++;
                    635:         }
                    636:     }
                    637: 
                    638:     return biR;
                    639: }
                    640: 
                    641: void bi_print(const char *label, bigint *x)
                    642: {
                    643:     int i, j;
                    644: 
                    645:     if (x == NULL)
                    646:     {
                    647:         printf("%s: (null)\n", label);
                    648:         return;
                    649:     }
                    650: 
                    651:     printf("%s: (size %d)\n", label, x->size);
                    652:     for (i = x->size-1; i >= 0; i--)
                    653:     {
                    654:         for (j = COMP_NUM_NIBBLES-1; j >= 0; j--)
                    655:         {
                    656:             comp mask = 0x0f << (j*4);
                    657:             comp num = (x->comps[i] & mask) >> (j*4);
                    658:             putc((num <= 9) ? (num + '0') : (num + 'A' - 10), stdout);
                    659:         }
                    660:     }  
                    661: 
                    662:     printf("\n");
                    663: }
                    664: #endif
                    665: 
                    666: /**
                    667:  * @brief Take a bigint and convert it into a byte sequence. 
                    668:  *
                    669:  * This is useful after a decrypt operation.
                    670:  * @param ctx [in]  The bigint session context.
                    671:  * @param x [in]  The bigint to be converted.
                    672:  * @param data [out] The converted data as a byte stream.
                    673:  * @param size [in] The maximum size of the byte stream. Unused bytes will be
                    674:  * zeroed.
                    675:  */
                    676: void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
                    677: {
                    678:     int i, j, k = size-1;
                    679: 
                    680:     check(x);
                    681:     memset(data, 0, size);  /* ensure all leading 0's are cleared */
                    682: 
                    683:     for (i = 0; i < x->size; i++)
                    684:     {
                    685:         for (j = 0; j < COMP_BYTE_SIZE; j++)
                    686:         {
                    687:             comp mask = 0xff << (j*8);
                    688:             int num = (x->comps[i] & mask) >> (j*8);
                    689:             data[k--] = num;
                    690: 
                    691:             if (k < 0)
                    692:             {
                    693:                 break;
                    694:             }
                    695:         }
                    696:     }
                    697: 
                    698:     bi_free(ctx, x);
                    699: }
                    700: 
                    701: /**
                    702:  * @brief Pre-calculate some of the expensive steps in reduction. 
                    703:  *
                    704:  * This function should only be called once (normally when a session starts).
                    705:  * When the session is over, bi_free_mod() should be called. bi_mod_power()
                    706:  * relies on this function being called.
                    707:  * @param ctx [in]  The bigint session context.
                    708:  * @param bim [in]  The bigint modulus that will be used.
                    709:  * @param mod_offset [in] There are three moduluii that can be stored - the
                    710:  * standard modulus, and its two primes p and q. This offset refers to which
                    711:  * modulus we are referring to.
                    712:  * @see bi_free_mod(), bi_mod_power().
                    713:  */
                    714: void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
                    715: {
                    716:     int k = bim->size;
                    717:     comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
                    718: #ifdef CONFIG_BIGINT_MONTGOMERY
                    719:     bigint *R, *R2;
                    720: #endif
                    721: 
                    722:     ctx->bi_mod[mod_offset] = bim;
                    723:     bi_permanent(ctx->bi_mod[mod_offset]);
                    724:     ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
                    725:     bi_permanent(ctx->bi_normalised_mod[mod_offset]);
                    726: 
                    727: #if defined(CONFIG_BIGINT_MONTGOMERY)
                    728:     /* set montgomery variables */
                    729:     R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1);     /* R */
                    730:     R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1);  /* R^2 */
                    731:     ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2);             /* R^2 mod m */
                    732:     ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R);               /* R mod m */
                    733: 
                    734:     bi_permanent(ctx->bi_RR_mod_m[mod_offset]);
                    735:     bi_permanent(ctx->bi_R_mod_m[mod_offset]);
                    736: 
                    737:     ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]);
                    738: 
                    739: #elif defined (CONFIG_BIGINT_BARRETT)
                    740:     ctx->bi_mu[mod_offset] = 
                    741:         bi_divide(ctx, comp_left_shift(
                    742:             bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0);
                    743:     bi_permanent(ctx->bi_mu[mod_offset]);
                    744: #endif
                    745: }
                    746: 
                    747: /**
                    748:  * @brief Used when cleaning various bigints at the end of a session.
                    749:  * @param ctx [in]  The bigint session context.
                    750:  * @param mod_offset [in] The offset to use.
                    751:  * @see bi_set_mod().
                    752:  */
                    753: void bi_free_mod(BI_CTX *ctx, int mod_offset)
                    754: {
                    755:     bi_depermanent(ctx->bi_mod[mod_offset]);
                    756:     bi_free(ctx, ctx->bi_mod[mod_offset]);
                    757: #if defined (CONFIG_BIGINT_MONTGOMERY)
                    758:     bi_depermanent(ctx->bi_RR_mod_m[mod_offset]);
                    759:     bi_depermanent(ctx->bi_R_mod_m[mod_offset]);
                    760:     bi_free(ctx, ctx->bi_RR_mod_m[mod_offset]);
                    761:     bi_free(ctx, ctx->bi_R_mod_m[mod_offset]);
                    762: #elif defined(CONFIG_BIGINT_BARRETT)
                    763:     bi_depermanent(ctx->bi_mu[mod_offset]); 
                    764:     bi_free(ctx, ctx->bi_mu[mod_offset]);
                    765: #endif
                    766:     bi_depermanent(ctx->bi_normalised_mod[mod_offset]); 
                    767:     bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
                    768: }
                    769: 
                    770: /** 
                    771:  * Perform a standard multiplication between two bigints.
                    772:  */
                    773: static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
                    774: {
                    775:     int i, j, i_plus_j;
                    776:     int n = bia->size; 
                    777:     int t = bib->size;
                    778:     bigint *biR = alloc(ctx, n + t);
                    779:     comp *sr = biR->comps;
                    780:     comp *sa = bia->comps;
                    781:     comp *sb = bib->comps;
                    782: 
                    783:     check(bia);
                    784:     check(bib);
                    785: 
                    786:     /* clear things to start with */
                    787:     memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
                    788:     i = 0;
                    789: 
                    790:     do 
                    791:     {
                    792:         comp carry = 0;
                    793:         comp b = *sb++;
                    794:         i_plus_j = i;
                    795:         j = 0;
                    796: 
                    797:         do
                    798:         {
                    799:             long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
                    800:             sr[i_plus_j++] = (comp)tmp;              /* downsize */
                    801:             carry = (comp)(tmp >> COMP_BIT_SIZE);
                    802:         } while (++j < n);
                    803: 
                    804:         sr[i_plus_j] = carry;
                    805:     } while (++i < t);
                    806: 
                    807:     bi_free(ctx, bia);
                    808:     bi_free(ctx, bib);
                    809:     return trim(biR);
                    810: }
                    811: 
                    812: #ifdef CONFIG_BIGINT_KARATSUBA
                    813: /*
                    814:  * Karatsuba improves on regular multiplication due to only 3 multiplications 
                    815:  * being done instead of 4. The additional additions/subtractions are O(N) 
                    816:  * rather than O(N^2) and so for big numbers it saves on a few operations 
                    817:  */
                    818: static bigint *karatsuba(BI_CTX *ctx, bigint *bia, bigint *bib, int is_square)
                    819: {
                    820:     bigint *x0, *x1;
                    821:     bigint *p0, *p1, *p2;
                    822:     int m;
                    823: 
                    824:     if (is_square)
                    825:     {
                    826:         m = (bia->size + 1)/2;
                    827:     }
                    828:     else
                    829:     {
                    830:         m = (max(bia->size, bib->size) + 1)/2;
                    831:     }
                    832: 
                    833:     x0 = bi_clone(ctx, bia);
                    834:     x0->size = m;
                    835:     x1 = bi_clone(ctx, bia);
                    836:     comp_right_shift(x1, m);
                    837:     bi_free(ctx, bia);
                    838: 
                    839:     /* work out the 3 partial products */
                    840:     if (is_square)
                    841:     {
                    842:         p0 = bi_square(ctx, bi_copy(x0));
                    843:         p2 = bi_square(ctx, bi_copy(x1));
                    844:         p1 = bi_square(ctx, bi_add(ctx, x0, x1));
                    845:     }
                    846:     else /* normal multiply */
                    847:     {
                    848:         bigint *y0, *y1;
                    849:         y0 = bi_clone(ctx, bib);
                    850:         y0->size = m;
                    851:         y1 = bi_clone(ctx, bib);
                    852:         comp_right_shift(y1, m);
                    853:         bi_free(ctx, bib);
                    854: 
                    855:         p0 = bi_multiply(ctx, bi_copy(x0), bi_copy(y0));
                    856:         p2 = bi_multiply(ctx, bi_copy(x1), bi_copy(y1));
                    857:         p1 = bi_multiply(ctx, bi_add(ctx, x0, x1), bi_add(ctx, y0, y1));
                    858:     }
                    859: 
                    860:     p1 = bi_subtract(ctx, 
                    861:             bi_subtract(ctx, p1, bi_copy(p2), NULL), bi_copy(p0), NULL);
                    862: 
                    863:     comp_left_shift(p1, m);
                    864:     comp_left_shift(p2, 2*m);
                    865:     return bi_add(ctx, p1, bi_add(ctx, p0, p2));
                    866: }
                    867: #endif
                    868: 
                    869: /**
                    870:  * @brief Perform a multiplication operation between two bigints.
                    871:  * @param ctx [in]  The bigint session context.
                    872:  * @param bia [in]  A bigint.
                    873:  * @param bib [in]  Another bigint.
                    874:  * @return The result of the multiplication.
                    875:  */
                    876: bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
                    877: {
                    878:     check(bia);
                    879:     check(bib);
                    880: 
                    881: #ifdef CONFIG_BIGINT_KARATSUBA
                    882:     if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH)
                    883:     {
                    884:         return regular_multiply(ctx, bia, bib);
                    885:     }
                    886: 
                    887:     return karatsuba(ctx, bia, bib, 0);
                    888: #else
                    889:     return regular_multiply(ctx, bia, bib);
                    890: #endif
                    891: }
                    892: 
                    893: #ifdef CONFIG_BIGINT_SQUARE
                    894: /*
                    895:  * Perform the actual square operion. It takes into account overflow.
                    896:  */
                    897: static bigint *regular_square(BI_CTX *ctx, bigint *bi)
                    898: {
                    899:     int t = bi->size;
                    900:     int i = 0, j;
                    901:     bigint *biR = alloc(ctx, t*2);
                    902:     comp *w = biR->comps;
                    903:     comp *x = bi->comps;
                    904:     comp carry;
                    905: 
                    906:     memset(w, 0, biR->size*COMP_BYTE_SIZE);
                    907: 
                    908:     do
                    909:     {
                    910:         long_comp tmp = w[2*i] + (long_comp)x[i]*x[i];
                    911:         comp u = 0;
                    912:         w[2*i] = (comp)tmp;
                    913:         carry = (comp)(tmp >> COMP_BIT_SIZE);
                    914: 
                    915:         for (j = i+1; j < t; j++)
                    916:         {
                    917:             long_comp xx = (long_comp)x[i]*x[j];
                    918:             long_comp blob = (long_comp)w[i+j]+carry;
                    919: 
                    920:             if (u)                  /* previous overflow */
                    921:             {
                    922:                 blob += COMP_RADIX;
                    923:             }
                    924: 
                    925:             u = 0;
                    926:             if (xx & COMP_BIG_MSB)  /* check for overflow */
                    927:             {
                    928:                 u = 1;
                    929:             }
                    930: 
                    931:             tmp = 2*xx + blob;
                    932:             w[i+j] = (comp)tmp;
                    933:             carry = (comp)(tmp >> COMP_BIT_SIZE);
                    934:         }
                    935: 
                    936:         w[i+t] += carry;
                    937: 
                    938:         if (u)
                    939:         {
                    940:             w[i+t+1] = 1;   /* add carry */
                    941:         }
                    942:     } while (++i < t);
                    943: 
                    944:     bi_free(ctx, bi);
                    945:     return trim(biR);
                    946: }
                    947: 
                    948: /**
                    949:  * @brief Perform a square operation on a bigint.
                    950:  * @param ctx [in]  The bigint session context.
                    951:  * @param bia [in]  A bigint.
                    952:  * @return The result of the multiplication.
                    953:  */
                    954: bigint *bi_square(BI_CTX *ctx, bigint *bia)
                    955: {
                    956:     check(bia);
                    957: 
                    958: #ifdef CONFIG_BIGINT_KARATSUBA
                    959:     if (bia->size < SQU_KARATSUBA_THRESH) 
                    960:     {
                    961:         return regular_square(ctx, bia);
                    962:     }
                    963: 
                    964:     return karatsuba(ctx, bia, NULL, 1);
                    965: #else
                    966:     return regular_square(ctx, bia);
                    967: #endif
                    968: }
                    969: #endif
                    970: 
                    971: /**
                    972:  * @brief Compare two bigints.
                    973:  * @param bia [in]  A bigint.
                    974:  * @param bib [in]  Another bigint.
                    975:  * @return -1 if smaller, 1 if larger and 0 if equal.
                    976:  */
                    977: int bi_compare(bigint *bia, bigint *bib)
                    978: {
                    979:     int r, i;
                    980: 
                    981:     check(bia);
                    982:     check(bib);
                    983: 
                    984:     if (bia->size > bib->size)
                    985:         r = 1;
                    986:     else if (bia->size < bib->size)
                    987:         r = -1;
                    988:     else
                    989:     {
                    990:         comp *a = bia->comps; 
                    991:         comp *b = bib->comps; 
                    992: 
                    993:         /* Same number of components.  Compare starting from the high end
                    994:          * and working down. */
                    995:         r = 0;
                    996:         i = bia->size - 1;
                    997: 
                    998:         do 
                    999:         {
                   1000:             if (a[i] > b[i])
                   1001:             { 
                   1002:                 r = 1;
                   1003:                 break; 
                   1004:             }
                   1005:             else if (a[i] < b[i])
                   1006:             { 
                   1007:                 r = -1;
                   1008:                 break; 
                   1009:             }
                   1010:         } while (--i >= 0);
                   1011:     }
                   1012: 
                   1013:     return r;
                   1014: }
                   1015: 
                   1016: /*
                   1017:  * Allocate and zero more components.  Does not consume bi. 
                   1018:  */
                   1019: static void more_comps(bigint *bi, int n)
                   1020: {
                   1021:     if (n > bi->max_comps)
                   1022:     {
                   1023:         bi->max_comps = max(bi->max_comps * 2, n);
                   1024:         bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
                   1025:     }
                   1026: 
                   1027:     if (n > bi->size)
                   1028:     {
                   1029:         memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
                   1030:     }
                   1031: 
                   1032:     bi->size = n;
                   1033: }
                   1034: 
                   1035: /*
                   1036:  * Make a new empty bigint. It may just use an old one if one is available.
                   1037:  * Otherwise get one off the heap.
                   1038:  */
                   1039: static bigint *alloc(BI_CTX *ctx, int size)
                   1040: {
                   1041:     bigint *biR;
                   1042: 
                   1043:     /* Can we recycle an old bigint? */
                   1044:     if (ctx->free_list != NULL)
                   1045:     {
                   1046:         biR = ctx->free_list;
                   1047:         ctx->free_list = biR->next;
                   1048:         ctx->free_count--;
                   1049: 
                   1050:         if (biR->refs != 0)
                   1051:         {
                   1052: #ifdef CONFIG_SSL_FULL_MODE
                   1053:             printf("alloc: refs was not 0\n");
                   1054: #endif
                   1055:             abort();    /* create a stack trace from a core dump */
                   1056:         }
                   1057: 
                   1058:         more_comps(biR, size);
                   1059:     }
                   1060:     else
                   1061:     {
                   1062:         /* No free bigints available - create a new one. */
                   1063:         biR = (bigint *)malloc(sizeof(bigint));
                   1064:         biR->comps = (comp*)malloc(size * COMP_BYTE_SIZE);
                   1065:         biR->max_comps = size;  /* give some space to spare */
                   1066:     }
                   1067: 
                   1068:     biR->size = size;
                   1069:     biR->refs = 1;
                   1070:     biR->next = NULL;
                   1071:     ctx->active_count++;
                   1072:     return biR;
                   1073: }
                   1074: 
                   1075: /*
                   1076:  * Work out the highest '1' bit in an exponent. Used when doing sliding-window
                   1077:  * exponentiation.
                   1078:  */
                   1079: static int find_max_exp_index(bigint *biexp)
                   1080: {
                   1081:     int i = COMP_BIT_SIZE-1;
                   1082:     comp shift = COMP_RADIX/2;
                   1083:     comp test = biexp->comps[biexp->size-1];    /* assume no leading zeroes */
                   1084: 
                   1085:     check(biexp);
                   1086: 
                   1087:     do
                   1088:     {
                   1089:         if (test & shift)
                   1090:         {
                   1091:             return i+(biexp->size-1)*COMP_BIT_SIZE;
                   1092:         }
                   1093: 
                   1094:         shift >>= 1;
                   1095:     } while (--i != 0);
                   1096: 
                   1097:     return -1;      /* error - must have been a leading 0 */
                   1098: }
                   1099: 
                   1100: /*
                   1101:  * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
                   1102:  * exponentiation.
                   1103:  */
                   1104: static int exp_bit_is_one(bigint *biexp, int offset)
                   1105: {
                   1106:     comp test = biexp->comps[offset / COMP_BIT_SIZE];
                   1107:     int num_shifts = offset % COMP_BIT_SIZE;
                   1108:     comp shift = 1;
                   1109:     int i;
                   1110: 
                   1111:     check(biexp);
                   1112: 
                   1113:     for (i = 0; i < num_shifts; i++)
                   1114:     {
                   1115:         shift <<= 1;
                   1116:     }
                   1117: 
                   1118:     return test & shift;
                   1119: }
                   1120: 
                   1121: #ifdef CONFIG_BIGINT_CHECK_ON
                   1122: /*
                   1123:  * Perform a sanity check on bi.
                   1124:  */
                   1125: static void check(const bigint *bi)
                   1126: {
                   1127:     if (bi->refs <= 0)
                   1128:     {
                   1129:         printf("check: zero or negative refs in bigint\n");
                   1130:         abort();
                   1131:     }
                   1132: 
                   1133:     if (bi->next != NULL)
                   1134:     {
                   1135:         printf("check: attempt to use a bigint from "
                   1136:                 "the free list\n");
                   1137:         abort();
                   1138:     }
                   1139: }
                   1140: #endif
                   1141: 
                   1142: /*
                   1143:  * Delete any leading 0's (and allow for 0).
                   1144:  */
                   1145: static bigint *trim(bigint *bi)
                   1146: {
                   1147:     check(bi);
                   1148: 
                   1149:     while (bi->comps[bi->size-1] == 0 && bi->size > 1)
                   1150:     {
                   1151:         bi->size--;
                   1152:     }
                   1153: 
                   1154:     return bi;
                   1155: }
                   1156: 
                   1157: #if defined(CONFIG_BIGINT_MONTGOMERY)
                   1158: /**
                   1159:  * @brief Perform a single montgomery reduction.
                   1160:  * @param ctx [in]  The bigint session context.
                   1161:  * @param bixy [in]  A bigint.
                   1162:  * @return The result of the montgomery reduction.
                   1163:  */
                   1164: bigint *bi_mont(BI_CTX *ctx, bigint *bixy)
                   1165: {
                   1166:     int i = 0, n;
                   1167:     uint8_t mod_offset = ctx->mod_offset;
                   1168:     bigint *bim = ctx->bi_mod[mod_offset];
                   1169:     comp mod_inv = ctx->N0_dash[mod_offset];
                   1170: 
                   1171:     check(bixy);
                   1172: 
                   1173:     if (ctx->use_classical)     /* just use classical instead */
                   1174:     {
                   1175:         return bi_mod(ctx, bixy);
                   1176:     }
                   1177: 
                   1178:     n = bim->size;
                   1179: 
                   1180:     do
                   1181:     {
                   1182:         bixy = bi_add(ctx, bixy, comp_left_shift(
                   1183:                     bi_int_multiply(ctx, bim, bixy->comps[i]*mod_inv), i));
                   1184:     } while (++i < n);
                   1185: 
                   1186:     comp_right_shift(bixy, n);
                   1187: 
                   1188:     if (bi_compare(bixy, bim) >= 0)
                   1189:     {
                   1190:         bixy = bi_subtract(ctx, bixy, bim, NULL);
                   1191:     }
                   1192: 
                   1193:     return bixy;
                   1194: }
                   1195: 
                   1196: #elif defined(CONFIG_BIGINT_BARRETT)
                   1197: /*
                   1198:  * Stomp on the most significant components to give the illusion of a "mod base
                   1199:  * radix" operation 
                   1200:  */
                   1201: static bigint *comp_mod(bigint *bi, int mod)
                   1202: {
                   1203:     check(bi);
                   1204: 
                   1205:     if (bi->size > mod)
                   1206:     {
                   1207:         bi->size = mod;
                   1208:     }
                   1209: 
                   1210:     return bi;
                   1211: }
                   1212: 
                   1213: /*
                   1214:  * Barrett reduction has no need for some parts of the product, so ignore bits
                   1215:  * of the multiply. This routine gives Barrett its big performance
                   1216:  * improvements over Classical/Montgomery reduction methods. 
                   1217:  */
                   1218: static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib, 
                   1219:         int inner_partial, int outer_partial)
                   1220: {
                   1221:     int i = 0, j, n = bia->size, t = bib->size;
                   1222:     bigint *biR;
                   1223:     comp carry;
                   1224:     comp *sr, *sa, *sb;
                   1225: 
                   1226:     check(bia);
                   1227:     check(bib);
                   1228: 
                   1229:     biR = alloc(ctx, n + t);
                   1230:     sa = bia->comps;
                   1231:     sb = bib->comps;
                   1232:     sr = biR->comps;
                   1233: 
                   1234:     if (inner_partial)
                   1235:     {
                   1236:         memset(sr, 0, inner_partial*COMP_BYTE_SIZE); 
                   1237:     }
                   1238:     else    /* outer partial */
                   1239:     {
                   1240:         if (n < outer_partial || t < outer_partial) /* should we bother? */
                   1241:         {
                   1242:             bi_free(ctx, bia);
                   1243:             bi_free(ctx, bib);
                   1244:             biR->comps[0] = 0;      /* return 0 */
                   1245:             biR->size = 1;
                   1246:             return biR;
                   1247:         }
                   1248: 
                   1249:         memset(&sr[outer_partial], 0, (n+t-outer_partial)*COMP_BYTE_SIZE);
                   1250:     }
                   1251: 
                   1252:     do 
                   1253:     {
                   1254:         comp *a = sa;
                   1255:         comp b = *sb++;
                   1256:         long_comp tmp;
                   1257:         int i_plus_j = i;
                   1258:         carry = 0;
                   1259:         j = n;
                   1260: 
                   1261:         if (outer_partial && i_plus_j < outer_partial)
                   1262:         {
                   1263:             i_plus_j = outer_partial;
                   1264:             a = &sa[outer_partial-i];
                   1265:             j = n-(outer_partial-i);
                   1266:         }
                   1267: 
                   1268:         do
                   1269:         {
                   1270:             if (inner_partial && i_plus_j >= inner_partial) 
                   1271:             {
                   1272:                 break;
                   1273:             }
                   1274: 
                   1275:             tmp = sr[i_plus_j] + ((long_comp)*a++)*b + carry;
                   1276:             sr[i_plus_j++] = (comp)tmp;              /* downsize */
                   1277:             carry = (comp)(tmp >> COMP_BIT_SIZE);
                   1278:         } while (--j != 0);
                   1279: 
                   1280:         sr[i_plus_j] = carry;
                   1281:     } while (++i < t);
                   1282: 
                   1283:     bi_free(ctx, bia);
                   1284:     bi_free(ctx, bib);
                   1285:     return trim(biR);
                   1286: }
                   1287: 
                   1288: /**
                   1289:  * @brief Perform a single Barrett reduction.
                   1290:  * @param ctx [in]  The bigint session context.
                   1291:  * @param bi [in]  A bigint.
                   1292:  * @return The result of the Barrett reduction.
                   1293:  */
                   1294: bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
                   1295: {
                   1296:     bigint *q1, *q2, *q3, *r1, *r2, *r;
                   1297:     uint8_t mod_offset = ctx->mod_offset;
                   1298:     bigint *bim = ctx->bi_mod[mod_offset];
                   1299:     int k = bim->size;
                   1300: 
                   1301:     check(bi);
                   1302:     check(bim);
                   1303: 
                   1304:     /* use Classical method instead  - Barrett cannot help here */
                   1305:     if (bi->size > k*2)
                   1306:     {
                   1307:         return bi_mod(ctx, bi);
                   1308:     }
                   1309: 
                   1310:     q1 = comp_right_shift(bi_clone(ctx, bi), k-1);
                   1311: 
                   1312:     /* do outer partial multiply */
                   1313:     q2 = partial_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1); 
                   1314:     q3 = comp_right_shift(q2, k+1);
                   1315:     r1 = comp_mod(bi, k+1);
                   1316: 
                   1317:     /* do inner partial multiply */
                   1318:     r2 = comp_mod(partial_multiply(ctx, q3, bim, k+1, 0), k+1);
                   1319:     r = bi_subtract(ctx, r1, r2, NULL);
                   1320: 
                   1321:     /* if (r >= m) r = r - m; */
                   1322:     if (bi_compare(r, bim) >= 0)
                   1323:     {
                   1324:         r = bi_subtract(ctx, r, bim, NULL);
                   1325:     }
                   1326: 
                   1327:     return r;
                   1328: }
                   1329: #endif /* CONFIG_BIGINT_BARRETT */
                   1330: 
                   1331: #ifdef CONFIG_BIGINT_SLIDING_WINDOW
                   1332: /*
                   1333:  * Work out g1, g3, g5, g7... etc for the sliding-window algorithm 
                   1334:  */
                   1335: static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1)
                   1336: {
                   1337:     int k = 1, i;
                   1338:     bigint *g2;
                   1339: 
                   1340:     for (i = 0; i < window-1; i++)   /* compute 2^(window-1) */
                   1341:     {
                   1342:         k <<= 1;
                   1343:     }
                   1344: 
                   1345:     ctx->g = (bigint **)malloc(k*sizeof(bigint *));
                   1346:     ctx->g[0] = bi_clone(ctx, g1);
                   1347:     bi_permanent(ctx->g[0]);
                   1348:     g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0]));   /* g^2 */
                   1349: 
                   1350:     for (i = 1; i < k; i++)
                   1351:     {
                   1352:         ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i-1], bi_copy(g2)));
                   1353:         bi_permanent(ctx->g[i]);
                   1354:     }
                   1355: 
                   1356:     bi_free(ctx, g2);
                   1357:     ctx->window = k;
                   1358: }
                   1359: #endif
                   1360: 
                   1361: /**
                   1362:  * @brief Perform a modular exponentiation.
                   1363:  *
                   1364:  * This function requires bi_set_mod() to have been called previously. This is 
                   1365:  * one of the optimisations used for performance.
                   1366:  * @param ctx [in]  The bigint session context.
                   1367:  * @param bi  [in]  The bigint on which to perform the mod power operation.
                   1368:  * @param biexp [in] The bigint exponent.
                   1369:  * @see bi_set_mod().
                   1370:  */
                   1371: bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
                   1372: {
                   1373:     int i = find_max_exp_index(biexp), j, window_size = 1;
                   1374:     bigint *biR = int_to_bi(ctx, 1);
                   1375: 
                   1376: #if defined(CONFIG_BIGINT_MONTGOMERY)
                   1377:     uint8_t mod_offset = ctx->mod_offset;
                   1378:     if (!ctx->use_classical)
                   1379:     {
                   1380:         /* preconvert */
                   1381:         bi = bi_mont(ctx, 
                   1382:                 bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset]));    /* x' */
                   1383:         bi_free(ctx, biR);
                   1384:         biR = ctx->bi_R_mod_m[mod_offset];                              /* A */
                   1385:     }
                   1386: #endif
                   1387: 
                   1388:     check(bi);
                   1389:     check(biexp);
                   1390: 
                   1391: #ifdef CONFIG_BIGINT_SLIDING_WINDOW
                   1392:     for (j = i; j > 32; j /= 5) /* work out an optimum size */
                   1393:         window_size++;
                   1394: 
                   1395:     /* work out the slide constants */
                   1396:     precompute_slide_window(ctx, window_size, bi);
                   1397: #else   /* just one constant */
                   1398:     ctx->g = (bigint **)malloc(sizeof(bigint *));
                   1399:     ctx->g[0] = bi_clone(ctx, bi);
                   1400:     ctx->window = 1;
                   1401:     bi_permanent(ctx->g[0]);
                   1402: #endif
                   1403: 
                   1404:     /* if sliding-window is off, then only one bit will be done at a time and
                   1405:      * will reduce to standard left-to-right exponentiation */
                   1406:     do
                   1407:     {
                   1408:         if (exp_bit_is_one(biexp, i))
                   1409:         {
                   1410:             int l = i-window_size+1;
                   1411:             int part_exp = 0;
                   1412: 
                   1413:             if (l < 0)  /* LSB of exponent will always be 1 */
                   1414:                 l = 0;
                   1415:             else
                   1416:             {
                   1417:                 while (exp_bit_is_one(biexp, l) == 0)
                   1418:                     l++;    /* go back up */
                   1419:             }
                   1420: 
                   1421:             /* build up the section of the exponent */
                   1422:             for (j = i; j >= l; j--)
                   1423:             {
                   1424:                 biR = bi_residue(ctx, bi_square(ctx, biR));
                   1425:                 if (exp_bit_is_one(biexp, j))
                   1426:                     part_exp++;
                   1427: 
                   1428:                 if (j != l)
                   1429:                     part_exp <<= 1;
                   1430:             }
                   1431: 
                   1432:             part_exp = (part_exp-1)/2;  /* adjust for array */
                   1433:             biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp]));
                   1434:             i = l-1;
                   1435:         }
                   1436:         else    /* square it */
                   1437:         {
                   1438:             biR = bi_residue(ctx, bi_square(ctx, biR));
                   1439:             i--;
                   1440:         }
                   1441:     } while (i >= 0);
                   1442:      
                   1443:     /* cleanup */
                   1444:     for (i = 0; i < ctx->window; i++)
                   1445:     {
                   1446:         bi_depermanent(ctx->g[i]);
                   1447:         bi_free(ctx, ctx->g[i]);
                   1448:     }
                   1449: 
                   1450:     free(ctx->g);
                   1451:     bi_free(ctx, bi);
                   1452:     bi_free(ctx, biexp);
                   1453: #if defined CONFIG_BIGINT_MONTGOMERY
                   1454:     return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */
                   1455: #else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */
                   1456:     return biR;
                   1457: #endif
                   1458: }
                   1459: 
                   1460: #ifdef CONFIG_SSL_CERT_VERIFICATION
                   1461: /**
                   1462:  * @brief Perform a modular exponentiation using a temporary modulus.
                   1463:  *
                   1464:  * We need this function to check the signatures of certificates. The modulus
                   1465:  * of this function is temporary as it's just used for authentication.
                   1466:  * @param ctx [in]  The bigint session context.
                   1467:  * @param bi  [in]  The bigint to perform the exp/mod.
                   1468:  * @param bim [in]  The temporary modulus.
                   1469:  * @param biexp [in] The bigint exponent.
                   1470:  * @see bi_set_mod().
                   1471:  */
                   1472: bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp)
                   1473: {
                   1474:     bigint *biR, *tmp_biR;
                   1475: 
                   1476:     /* Set up a temporary bigint context and transfer what we need between
                   1477:      * them. We need to do this since we want to keep the original modulus
                   1478:      * which is already in this context. This operation is only called when
                   1479:      * doing peer verification, and so is not expensive :-) */
                   1480:     BI_CTX *tmp_ctx = bi_initialize();
                   1481:     bi_set_mod(tmp_ctx, bi_clone(tmp_ctx, bim), BIGINT_M_OFFSET);
                   1482:     tmp_biR = bi_mod_power(tmp_ctx, 
                   1483:                 bi_clone(tmp_ctx, bi), 
                   1484:                 bi_clone(tmp_ctx, biexp));
                   1485:     biR = bi_clone(ctx, tmp_biR);
                   1486:     bi_free(tmp_ctx, tmp_biR);
                   1487:     bi_free_mod(tmp_ctx, BIGINT_M_OFFSET);
                   1488:     bi_terminate(tmp_ctx);
                   1489: 
                   1490:     bi_free(ctx, bi);
                   1491:     bi_free(ctx, bim);
                   1492:     bi_free(ctx, biexp);
                   1493:     return biR;
                   1494: }
                   1495: #endif
                   1496: /** @} */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.