File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / axTLS / crypto / bigint.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Sep 28 11:55:55 2012 UTC (12 years, 3 months ago) by misho
Branches: v1_4_8, MAIN
CVS tags: datecs, HEAD
axTLS

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>