2 * Copyright(C) 2006 Cameron Rich
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * @defgroup bigint_api Big Integer API
21 * @brief The bigint implementation as used by the axTLS project.
23 * The bigint library is for RSA encryption/decryption as well as signing.
24 * This code tries to minimise use of malloc/free by maintaining a small
25 * cache. A bigint context may maintain state by being made "permanent".
26 * It be be later released with a bi_depermanent() and bi_free() call.
28 * It supports the following reduction techniques:
33 * It also implements the following:
34 * - Karatsuba multiplication
36 * - Sliding window exponentiation
37 * - Chinese Remainder Theorem (implemented in rsa.c).
39 * All the algorithms used are pretty standard, and designed for different
40 * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
41 * may need to be tested for negativity.
43 * This library steals some ideas from Jef Poskanzer
44 * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
45 * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
46 * detail from "The Handbook of Applied Cryptography"
47 * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
59 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
60 static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
61 static bigint *alloc(BI_CTX *ctx, int size);
62 static bigint *trim(bigint *bi);
63 static void more_comps(bigint *bi, int n);
64 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
65 defined(CONFIG_BIGINT_MONTGOMERY)
66 static bigint *comp_right_shift(bigint *biR, int num_shifts);
67 static bigint *comp_left_shift(bigint *biR, int num_shifts);
70 #ifdef CONFIG_BIGINT_CHECK_ON
71 static void check(const bigint *bi);
75 * @brief Start a new bigint context.
76 * @return A bigint context.
78 BI_CTX *bi_initialize(void)
80 BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
82 ctx->active_list = NULL;
83 ctx->active_count = 0;
84 ctx->free_list = NULL;
87 #ifdef CONFIG_BIGINT_MONTGOMERY
88 ctx->use_classical = 0;
92 ctx->bi_radix = alloc(ctx, 2);
93 ctx->bi_radix->comps[0] = 0;
94 ctx->bi_radix->comps[1] = 1;
95 bi_permanent(ctx->bi_radix);
101 * @brief Close the bigint context and free any resources.
103 * Free up any used memory - a check is done if all objects were not
105 * @param ctx [in] The bigint session context.
107 void bi_terminate(BI_CTX *ctx)
111 bi_depermanent(ctx->bi_radix);
112 bi_free(ctx, ctx->bi_radix);
114 if (ctx->active_count != 0)
116 #ifdef CONFIG_SSL_FULL_MODE
117 printf("bi_terminate: there were %d un-freed bigints\n",
123 for (p = ctx->free_list; p != NULL; p = pn)
134 * @brief Increment the number of references to this object.
135 * It does not do a full copy.
136 * @param bi [in] The bigint to copy.
137 * @return A reference to the same bigint.
139 bigint *bi_copy(bigint *bi)
142 if (bi->refs != PERMANENT)
148 * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
150 * For this object to be freed, bi_depermanent() must be called.
151 * @param bi [in] The bigint to be made permanent.
153 void bi_permanent(bigint *bi)
158 #ifdef CONFIG_SSL_FULL_MODE
159 printf("bi_permanent: refs was not 1\n");
164 bi->refs = PERMANENT;
168 * @brief Take a permanent object and make it eligible for freedom.
169 * @param bi [in] The bigint to be made back to temporary.
171 void bi_depermanent(bigint *bi)
174 if (bi->refs != PERMANENT)
176 #ifdef CONFIG_SSL_FULL_MODE
177 printf("bi_depermanent: bigint was not permanent\n");
186 * @brief Free a bigint object so it can be used again.
188 * The memory itself it not actually freed, just tagged as being available
189 * @param ctx [in] The bigint session context.
190 * @param bi [in] The bigint to be freed.
192 void bi_free(BI_CTX *ctx, bigint *bi)
195 if (bi->refs == PERMANENT)
205 bi->next = ctx->free_list;
209 if (--ctx->active_count < 0)
211 #ifdef CONFIG_SSL_FULL_MODE
212 printf("bi_free: active_count went negative "
213 "- double-freed bigint?\n");
220 * @brief Convert an (unsigned) integer into a bigint.
221 * @param ctx [in] The bigint session context.
222 * @param i [in] The (unsigned) integer to be converted.
225 bigint *int_to_bi(BI_CTX *ctx, comp i)
227 bigint *biR = alloc(ctx, 1);
233 * @brief Do a full copy of the bigint object.
234 * @param ctx [in] The bigint session context.
235 * @param bi [in] The bigint object to be copied.
237 bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
239 bigint *biR = alloc(ctx, bi->size);
241 memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
246 * @brief Perform an addition operation between two bigints.
247 * @param ctx [in] The bigint session context.
248 * @param bia [in] A bigint.
249 * @param bib [in] Another bigint.
250 * @return The result of the addition.
252 bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
261 n = max(bia->size, bib->size);
262 more_comps(bia, n+1);
273 carry = cy1 | (rl < sl);
277 *pa = carry; /* do overflow */
283 * @brief Perform a subtraction operation between two bigints.
284 * @param ctx [in] The bigint session context.
285 * @param bia [in] A bigint.
286 * @param bib [in] Another bigint.
287 * @param is_negative [out] If defined, indicates that the result was negative.
288 * is_negative may be NULL.
289 * @return The result of the subtraction. The result is always positive.
291 bigint *bi_subtract(BI_CTX *ctx,
292 bigint *bia, bigint *bib, int *is_negative)
295 comp *pa, *pb, carry = 0;
310 carry = cy1 | (rl > sl);
314 if (is_negative) /* indicate a negative result */
316 *is_negative = carry;
319 bi_free(ctx, trim(bib)); /* put bib back to the way it was */
324 * Perform a multiply between a bigint an an (unsigned) integer
326 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
328 int j = 0, n = bia->size;
329 bigint *biR = alloc(ctx, n + 1);
331 comp *r = biR->comps;
332 comp *a = bia->comps;
336 /* clear things to start with */
337 memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
341 long_comp tmp = *r + (long_comp)a[j]*b + carry;
342 *r++ = (comp)tmp; /* downsize */
343 carry = (comp)(tmp >> COMP_BIT_SIZE);
352 * @brief Does both division and modulo calculations.
354 * Used extensively when doing classical reduction.
355 * @param ctx [in] The bigint session context.
356 * @param u [in] A bigint which is the numerator.
357 * @param v [in] Either the denominator or the modulus depending on the mode.
358 * @param is_mod [n] Determines if this is a normal division (0) or a reduction
360 * @return The result of the division/reduction.
362 bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
364 int n = v->size, m = u->size-n;
365 int j = 0, orig_u_size = u->size;
366 uint8_t mod_offset = ctx->mod_offset;
368 bigint *quotient, *tmp_u;
374 /* if doing reduction and we are < mod, then return mod */
375 if (is_mod && bi_compare(v, u) > 0)
381 quotient = alloc(ctx, m+1);
382 tmp_u = alloc(ctx, n+1);
383 v = trim(v); /* make sure we have no leading 0's */
384 d = (comp)((long_comp)COMP_RADIX/(V1+1));
386 /* clear things to start with */
387 memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
392 u = bi_int_multiply(ctx, u, d);
396 v = ctx->bi_normalised_mod[mod_offset];
400 v = bi_int_multiply(ctx, v, d);
404 if (orig_u_size == u->size) /* new digit position u0 */
406 more_comps(u, orig_u_size + 1);
411 /* get a temporary short version of u */
412 memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
417 q_dash = COMP_RADIX-1;
421 q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
424 if (v->size > 1 && V2)
426 /* we are implementing the following:
427 if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
428 q_dash*V1)*COMP_RADIX) + U(2))) ... */
429 comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
430 (long_comp)q_dash*V1);
431 if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
437 /* multiply and subtract */
441 tmp_u = bi_subtract(ctx, tmp_u,
442 bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
443 more_comps(tmp_u, n+1);
451 tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
453 /* lop off the carry */
464 memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
470 if (is_mod) /* get the remainder */
472 bi_free(ctx, quotient);
473 return bi_int_divide(ctx, trim(u), d);
475 else /* get the quotient */
478 return trim(quotient);
483 * Perform an integer divide on a bigint.
485 static bigint *bi_int_divide(__unused BI_CTX *ctx, bigint *biR, comp denom)
487 int i = biR->size - 1;
494 r = (r<<COMP_BIT_SIZE) + biR->comps[i];
495 biR->comps[i] = (comp)(r / denom);
502 #ifdef CONFIG_BIGINT_MONTGOMERY
504 * There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1,
505 * where B^-1(B-1) mod N=1. Actually, only the least significant part of
506 * N' is needed, hence the definition N0'=N' mod b. We reproduce below the
507 * simple algorithm from an article by Dusse and Kaliski to efficiently
508 * find N0' from N0 and b */
509 static comp modular_inverse(bigint *bim)
513 comp two_2_i_minus_1 = 2; /* 2^(i-1) */
514 long_comp two_2_i = 4; /* 2^i */
515 comp N = bim->comps[0];
517 for (i = 2; i <= COMP_BIT_SIZE; i++)
519 if ((long_comp)N*t%two_2_i >= two_2_i_minus_1)
521 t += two_2_i_minus_1;
524 two_2_i_minus_1 <<= 1;
528 return (comp)(COMP_RADIX-t);
532 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
533 defined(CONFIG_BIGINT_MONTGOMERY)
535 * Take each component and shift down (in terms of components)
537 static bigint *comp_right_shift(bigint *biR, int num_shifts)
539 int i = biR->size-num_shifts;
540 comp *x = biR->comps;
541 comp *y = &biR->comps[num_shifts];
545 if (i <= 0) /* have we completely right shifted? */
547 biR->comps[0] = 0; /* return 0 */
557 biR->size -= num_shifts;
562 * Take each component and shift it up (in terms of components)
564 static bigint *comp_left_shift(bigint *biR, int num_shifts)
576 more_comps(biR, biR->size + num_shifts);
578 x = &biR->comps[i+num_shifts];
586 memset(biR->comps, 0, num_shifts*COMP_BYTE_SIZE); /* zero LS comps */
592 * @brief Allow a binary sequence to be imported as a bigint.
593 * @param ctx [in] The bigint session context.
594 * @param data [in] The data to be converted.
595 * @param size [in] The number of bytes of data.
596 * @return A bigint representing this data.
598 bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
600 bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
601 int i, j = 0, offset = 0;
603 memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
605 for (i = size-1; i >= 0; i--)
607 biR->comps[offset] += data[i] << (j*8);
609 if (++j == COMP_BYTE_SIZE)
619 #ifdef CONFIG_SSL_FULL_MODE
621 * @brief The testharness uses this code to import text hex-streams and
622 * convert them into bigints.
623 * @param ctx [in] The bigint session context.
624 * @param data [in] A string consisting of hex characters. The characters must
626 * @return A bigint representing this data.
628 bigint *bi_str_import(BI_CTX *ctx, const char *data)
630 int size = strlen(data);
631 bigint *biR = alloc(ctx, (size+COMP_NUM_NIBBLES-1)/COMP_NUM_NIBBLES);
632 int i, j = 0, offset = 0;
633 memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
635 for (i = size-1; i >= 0; i--)
637 int num = (data[i] <= '9') ? (data[i] - '0') : (data[i] - 'A' + 10);
638 biR->comps[offset] += num << (j*4);
640 if (++j == COMP_NUM_NIBBLES)
650 void bi_print(const char *label, bigint *x)
656 printf("%s: (null)\n", label);
660 printf("%s: (size %d)\n", label, x->size);
661 for (i = x->size-1; i >= 0; i--)
663 for (j = COMP_NUM_NIBBLES-1; j >= 0; j--)
665 comp mask = 0x0f << (j*4);
666 comp num = (x->comps[i] & mask) >> (j*4);
667 putc((num <= 9) ? (num + '0') : (num + 'A' - 10), stdout);
676 * @brief Take a bigint and convert it into a byte sequence.
678 * This is useful after a decrypt operation.
679 * @param ctx [in] The bigint session context.
680 * @param x [in] The bigint to be converted.
681 * @param data [out] The converted data as a byte stream.
682 * @param size [in] The maximum size of the byte stream. Unused bytes will be
685 void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
687 int i, j, k = size-1;
690 memset(data, 0, size); /* ensure all leading 0's are cleared */
692 for (i = 0; i < x->size; i++)
694 for (j = 0; j < COMP_BYTE_SIZE; j++)
696 comp mask = 0xff << (j*8);
697 int num = (x->comps[i] & mask) >> (j*8);
711 * @brief Pre-calculate some of the expensive steps in reduction.
713 * This function should only be called once (normally when a session starts).
714 * When the session is over, bi_free_mod() should be called. bi_mod_power()
715 * relies on this function being called.
716 * @param ctx [in] The bigint session context.
717 * @param bim [in] The bigint modulus that will be used.
718 * @param mod_offset [in] There are three moduluii that can be stored - the
719 * standard modulus, and its two primes p and q. This offset refers to which
720 * modulus we are referring to.
721 * @see bi_free_mod(), bi_mod_power().
723 void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
726 comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
727 #ifdef CONFIG_BIGINT_MONTGOMERY
731 ctx->bi_mod[mod_offset] = bim;
732 bi_permanent(ctx->bi_mod[mod_offset]);
733 ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
734 bi_permanent(ctx->bi_normalised_mod[mod_offset]);
736 #if defined(CONFIG_BIGINT_MONTGOMERY)
737 /* set montgomery variables */
738 R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1); /* R */
739 R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1); /* R^2 */
740 ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2); /* R^2 mod m */
741 ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R); /* R mod m */
743 bi_permanent(ctx->bi_RR_mod_m[mod_offset]);
744 bi_permanent(ctx->bi_R_mod_m[mod_offset]);
746 ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]);
748 #elif defined (CONFIG_BIGINT_BARRETT)
749 ctx->bi_mu[mod_offset] =
750 bi_divide(ctx, comp_left_shift(
751 bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0);
752 bi_permanent(ctx->bi_mu[mod_offset]);
757 * @brief Used when cleaning various bigints at the end of a session.
758 * @param ctx [in] The bigint session context.
759 * @param mod_offset [in] The offset to use.
762 void bi_free_mod(BI_CTX *ctx, int mod_offset)
764 bi_depermanent(ctx->bi_mod[mod_offset]);
765 bi_free(ctx, ctx->bi_mod[mod_offset]);
766 #if defined (CONFIG_BIGINT_MONTGOMERY)
767 bi_depermanent(ctx->bi_RR_mod_m[mod_offset]);
768 bi_depermanent(ctx->bi_R_mod_m[mod_offset]);
769 bi_free(ctx, ctx->bi_RR_mod_m[mod_offset]);
770 bi_free(ctx, ctx->bi_R_mod_m[mod_offset]);
771 #elif defined(CONFIG_BIGINT_BARRETT)
772 bi_depermanent(ctx->bi_mu[mod_offset]);
773 bi_free(ctx, ctx->bi_mu[mod_offset]);
775 bi_depermanent(ctx->bi_normalised_mod[mod_offset]);
776 bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
780 * Perform a standard multiplication between two bigints.
782 static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
784 int i, j, i_plus_j, n = bia->size, t = bib->size;
785 bigint *biR = alloc(ctx, n + t);
786 comp *sr = biR->comps;
787 comp *sa = bia->comps;
788 comp *sb = bib->comps;
793 /* clear things to start with */
794 memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
806 long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
807 sr[i_plus_j++] = (comp)tmp; /* downsize */
808 carry = (comp)(tmp >> COMP_BIT_SIZE);
811 sr[i_plus_j] = carry;
819 #ifdef CONFIG_BIGINT_KARATSUBA
821 * Karatsuba improves on regular multiplication due to only 3 multiplications
822 * being done instead of 4. The additional additions/subtractions are O(N)
823 * rather than O(N^2) and so for big numbers it saves on a few operations
825 static bigint *karatsuba(BI_CTX *ctx, bigint *bia, bigint *bib, int is_square)
828 bigint *p0, *p1, *p2;
833 m = (bia->size + 1)/2;
837 m = (max(bia->size, bib->size) + 1)/2;
840 x0 = bi_clone(ctx, bia);
842 x1 = bi_clone(ctx, bia);
843 comp_right_shift(x1, m);
846 /* work out the 3 partial products */
849 p0 = bi_square(ctx, bi_copy(x0));
850 p2 = bi_square(ctx, bi_copy(x1));
851 p1 = bi_square(ctx, bi_add(ctx, x0, x1));
853 else /* normal multiply */
856 y0 = bi_clone(ctx, bib);
858 y1 = bi_clone(ctx, bib);
859 comp_right_shift(y1, m);
862 p0 = bi_multiply(ctx, bi_copy(x0), bi_copy(y0));
863 p2 = bi_multiply(ctx, bi_copy(x1), bi_copy(y1));
864 p1 = bi_multiply(ctx, bi_add(ctx, x0, x1), bi_add(ctx, y0, y1));
867 p1 = bi_subtract(ctx,
868 bi_subtract(ctx, p1, bi_copy(p2), NULL), bi_copy(p0), NULL);
870 comp_left_shift(p1, m);
871 comp_left_shift(p2, 2*m);
872 return bi_add(ctx, p1, bi_add(ctx, p0, p2));
877 * @brief Perform a multiplication operation between two bigints.
878 * @param ctx [in] The bigint session context.
879 * @param bia [in] A bigint.
880 * @param bib [in] Another bigint.
881 * @return The result of the multiplication.
883 bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
888 #ifdef CONFIG_BIGINT_KARATSUBA
889 if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH)
891 return regular_multiply(ctx, bia, bib);
894 return karatsuba(ctx, bia, bib, 0);
896 return regular_multiply(ctx, bia, bib);
900 #ifdef CONFIG_BIGINT_SQUARE
902 * Perform the actual square operion. It takes into account overflow.
904 static bigint *regular_square(BI_CTX *ctx, bigint *bi)
908 bigint *biR = alloc(ctx, t*2);
909 comp *w = biR->comps;
913 memset(w, 0, biR->size*COMP_BYTE_SIZE);
917 long_comp tmp = w[2*i] + (long_comp)x[i]*x[i];
920 carry = (comp)(tmp >> COMP_BIT_SIZE);
922 for (j = i+1; j < t; j++)
924 long_comp xx = (long_comp)x[i]*x[j];
925 long_comp blob = (long_comp)w[i+j]+carry;
927 if (u) /* previous overflow */
933 if (xx & COMP_BIG_MSB) /* check for overflow */
940 carry = (comp)(tmp >> COMP_BIT_SIZE);
947 w[i+t+1] = 1; /* add carry */
956 * @brief Perform a square operation on a bigint.
957 * @param ctx [in] The bigint session context.
958 * @param bia [in] A bigint.
959 * @return The result of the multiplication.
961 bigint *bi_square(BI_CTX *ctx, bigint *bia)
965 #ifdef CONFIG_BIGINT_KARATSUBA
966 if (bia->size < SQU_KARATSUBA_THRESH)
968 return regular_square(ctx, bia);
971 return karatsuba(ctx, bia, NULL, 1);
973 return regular_square(ctx, bia);
979 * @brief Compare two bigints.
980 * @param bia [in] A bigint.
981 * @param bib [in] Another bigint.
982 * @return -1 if smaller, 1 if larger and 0 if equal.
984 int bi_compare(bigint *bia, bigint *bib)
991 if (bia->size > bib->size)
993 else if (bia->size < bib->size)
997 comp *a = bia->comps;
998 comp *b = bib->comps;
1000 /* Same number of components. Compare starting from the high end
1001 * and working down. */
1012 else if (a[i] < b[i])
1024 * Allocate and zero more components. Does not consume bi.
1026 static void more_comps(bigint *bi, int n)
1028 if (n > bi->max_comps)
1030 bi->max_comps = max(bi->max_comps * 2, n);
1031 bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
1036 memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
1043 * Make a new empty bigint. It may just use an old one if one is available.
1044 * Otherwise get one off the heap.
1046 static bigint *alloc(BI_CTX *ctx, int size)
1050 /* Can we recycle an old bigint? */
1051 if (ctx->free_list != NULL)
1053 biR = ctx->free_list;
1054 ctx->free_list = biR->next;
1059 #ifdef CONFIG_SSL_FULL_MODE
1060 printf("alloc: refs was not 0\n");
1065 more_comps(biR, size);
1069 /* No free bigints available - create a new one. */
1070 biR = (bigint *)malloc(sizeof(bigint));
1071 biR->comps = (comp*)malloc(size * COMP_BYTE_SIZE);
1072 biR->max_comps = size; /* give some space to spare */
1078 ctx->active_count++;
1083 * Work out the highest '1' bit in an exponent. Used when doing sliding-window
1086 static int find_max_exp_index(bigint *biexp)
1088 int i = COMP_BIT_SIZE-1;
1089 comp shift = COMP_RADIX/2;
1090 comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */
1098 return i+(biexp->size-1)*COMP_BIT_SIZE;
1104 return -1; /* error - must have been a leading 0 */
1108 * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
1111 static int exp_bit_is_one(bigint *biexp, int offset)
1113 comp test = biexp->comps[offset / COMP_BIT_SIZE];
1114 int num_shifts = offset % COMP_BIT_SIZE;
1120 for (i = 0; i < num_shifts; i++)
1125 return test & shift;
1128 #ifdef CONFIG_BIGINT_CHECK_ON
1130 * Perform a sanity check on bi.
1132 static void check(const bigint *bi)
1136 printf("check: zero or negative refs in bigint\n");
1140 if (bi->next != NULL)
1142 printf("check: attempt to use a bigint from "
1150 * Delete any leading 0's (and allow for 0).
1152 static bigint *trim(bigint *bi)
1156 while (bi->comps[bi->size-1] == 0 && bi->size > 1)
1164 #if defined(CONFIG_BIGINT_MONTGOMERY)
1166 * @brief Perform a single montgomery reduction.
1167 * @param ctx [in] The bigint session context.
1168 * @param bixy [in] A bigint.
1169 * @return The result of the montgomery reduction.
1171 bigint *bi_mont(BI_CTX *ctx, bigint *bixy)
1174 uint8_t mod_offset = ctx->mod_offset;
1175 bigint *bim = ctx->bi_mod[mod_offset];
1176 comp mod_inv = ctx->N0_dash[mod_offset];
1180 if (ctx->use_classical) /* just use classical instead */
1182 return bi_mod(ctx, bixy);
1189 bixy = bi_add(ctx, bixy, comp_left_shift(
1190 bi_int_multiply(ctx, bim, bixy->comps[i]*mod_inv), i));
1193 comp_right_shift(bixy, n);
1195 if (bi_compare(bixy, bim) >= 0)
1197 bixy = bi_subtract(ctx, bixy, bim, NULL);
1203 #elif defined(CONFIG_BIGINT_BARRETT)
1205 * Stomp on the most significant components to give the illusion of a "mod base
1208 static bigint *comp_mod(bigint *bi, int mod)
1221 * Barrett reduction has no need for some parts of the product, so ignore bits
1222 * of the multiply. This routine gives Barrett its big performance
1223 * improvements over classical/Montgomery reduction methods.
1225 static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib,
1226 int inner_partial, int outer_partial)
1228 int i = 0, j, n = bia->size, t = bib->size;
1236 biR = alloc(ctx, n + t);
1243 memset(sr, 0, inner_partial*COMP_BYTE_SIZE);
1245 else /* outer partial */
1247 if (n < outer_partial || t < outer_partial) /* should we bother? */
1251 biR->comps[0] = 0; /* return 0 */
1256 memset(&sr[outer_partial], 0, (n+t-outer_partial)*COMP_BYTE_SIZE);
1268 if (outer_partial && i_plus_j < outer_partial)
1270 i_plus_j = outer_partial;
1271 a = &sa[outer_partial-i];
1272 j = n-(outer_partial-i);
1277 if (inner_partial && i_plus_j >= inner_partial)
1282 tmp = sr[i_plus_j] + ((long_comp)*a++)*b + carry;
1283 sr[i_plus_j++] = (comp)tmp; /* downsize */
1284 carry = (comp)(tmp >> COMP_BIT_SIZE);
1287 sr[i_plus_j] = carry;
1296 * @brief Perform a single barrett reduction.
1297 * @param ctx [in] The bigint session context.
1298 * @param bi [in] A bigint.
1299 * @return The result of the barrett reduction.
1301 bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
1303 bigint *q1, *q2, *q3, *r1, *r2, *r;
1304 uint8_t mod_offset = ctx->mod_offset;
1305 bigint *bim = ctx->bi_mod[mod_offset];
1311 /* use classical method instead - Barrett cannot help here */
1314 return bi_mod(ctx, bi);
1317 q1 = comp_right_shift(bi_clone(ctx, bi), k-1);
1319 /* do outer partial multiply */
1320 q2 = partial_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1);
1321 q3 = comp_right_shift(q2, k+1);
1322 r1 = comp_mod(bi, k+1);
1324 /* do inner partial multiply */
1325 r2 = comp_mod(partial_multiply(ctx, q3, bim, k+1, 0), k+1);
1326 r = bi_subtract(ctx, r1, r2, NULL);
1328 /* if (r >= m) r = r - m; */
1329 if (bi_compare(r, bim) >= 0)
1331 r = bi_subtract(ctx, r, bim, NULL);
1336 #endif /* CONFIG_BIGINT_BARRETT */
1338 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
1340 * Work out g1, g3, g5, g7... etc for the sliding-window algorithm
1342 static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1)
1347 for (i = 0; i < window-1; i++) /* compute 2^(window-1) */
1352 ctx->g = (bigint **)malloc(k*sizeof(bigint *));
1353 ctx->g[0] = bi_clone(ctx, g1);
1354 bi_permanent(ctx->g[0]);
1355 g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0])); /* g^2 */
1357 for (i = 1; i < k; i++)
1359 ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i-1], bi_copy(g2)));
1360 bi_permanent(ctx->g[i]);
1369 * @brief Perform a modular exponentiation.
1371 * This function requires bi_set_mod() to have been called previously. This is
1372 * one of the optimisations used for performance.
1373 * @param ctx [in] The bigint session context.
1374 * @param bi [in] The bigint on which to perform the mod power operation.
1375 * @param biexp [in] The bigint exponent.
1376 * @see bi_set_mod().
1378 bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1380 int i = find_max_exp_index(biexp), j, window_size = 1;
1381 bigint *biR = int_to_bi(ctx, 1);
1383 #if defined(CONFIG_BIGINT_MONTGOMERY)
1384 uint8_t mod_offset = ctx->mod_offset;
1385 if (!ctx->use_classical)
1389 bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset])); /* x' */
1391 biR = ctx->bi_R_mod_m[mod_offset]; /* A */
1398 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
1399 for (j = i; j > 32; j /= 5) /* work out an optimum size */
1404 /* work out the slide constants */
1405 precompute_slide_window(ctx, window_size, bi);
1406 #else /* just one constant */
1407 ctx->g = (bigint **)malloc(sizeof(bigint *));
1408 ctx->g[0] = bi_clone(ctx, bi);
1410 bi_permanent(ctx->g[0]);
1413 /* if sliding-window is off, then only one bit will be done at a time and
1414 * will reduce to standard left-to-right exponentiation */
1417 if (exp_bit_is_one(biexp, i))
1419 int l = i-window_size+1;
1422 if (l < 0) /* LSB of exponent will always be 1 */
1428 while (exp_bit_is_one(biexp, l) == 0)
1430 l++; /* go back up */
1434 /* build up the section of the exponent */
1435 for (j = i; j >= l; j--)
1437 biR = bi_residue(ctx, bi_square(ctx, biR));
1438 if (exp_bit_is_one(biexp, j))
1445 part_exp = (part_exp-1)/2; /* adjust for array */
1446 biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp]));
1449 else /* square it */
1451 biR = bi_residue(ctx, bi_square(ctx, biR));
1457 for (i = 0; i < ctx->window; i++)
1459 bi_depermanent(ctx->g[i]);
1460 bi_free(ctx, ctx->g[i]);
1465 bi_free(ctx, biexp);
1466 #if defined CONFIG_BIGINT_MONTGOMERY
1467 return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */
1468 #else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */
1473 #ifdef CONFIG_SSL_CERT_VERIFICATION
1475 * @brief Perform a modular exponentiation using a temporary modulus.
1477 * We need this function to check the signatures of certificates. The modulus
1478 * of this function is temporary as it's just used for authentication.
1479 * @param ctx [in] The bigint session context.
1480 * @param bi [in] The bigint to perform the exp/mod.
1481 * @param bim [in] The temporary modulus.
1482 * @param biexp [in] The bigint exponent.
1483 * @see bi_set_mod().
1485 bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp)
1487 bigint *biR, *tmp_biR;
1489 /* Set up a temporary bigint context and transfer what we need between
1490 * them. We need to do this since we want to keep the original modulus
1491 * which is already in this context. This operation is only called when
1492 * doing peer verification, and so is not expensive :-) */
1493 BI_CTX *tmp_ctx = bi_initialize();
1494 bi_set_mod(tmp_ctx, bi_clone(tmp_ctx, bim), BIGINT_M_OFFSET);
1495 tmp_biR = bi_mod_power(tmp_ctx,
1496 bi_clone(tmp_ctx, bi),
1497 bi_clone(tmp_ctx, biexp));
1498 biR = bi_clone(ctx, tmp_biR);
1499 bi_free(tmp_ctx, tmp_biR);
1500 bi_free_mod(tmp_ctx, BIGINT_M_OFFSET);
1501 bi_terminate(tmp_ctx);
1505 bi_free(ctx, biexp);