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