2 * Copyright (c) 2007, Cameron Rich
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
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.
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.
32 * @defgroup bigint_api Big Integer API
33 * @brief The bigint implementation as used by the axTLS project.
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.
40 * It supports the following reduction techniques:
45 * It also implements the following:
46 * - Karatsuba multiplication
48 * - Sliding window exponentiation
49 * - Chinese Remainder Theorem (implemented in rsa.c).
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.
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>
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 */
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
);
87 #ifdef CONFIG_BIGINT_CHECK_ON
88 static void check(const bigint
*bi
);
90 #define check(A) /**< disappears in normal production mode */
95 * @brief Start a new bigint context.
96 * @return A bigint context.
98 BI_CTX
*bi_initialize(void)
100 /* calloc() sets everything to zero */
101 BI_CTX
*ctx
= (BI_CTX
*)calloc(1, sizeof(BI_CTX
));
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
);
112 * @brief Close the bigint context and free any resources.
114 * Free up any used memory - a check is done if all objects were not
116 * @param ctx [in] The bigint session context.
118 void bi_terminate(BI_CTX
*ctx
)
120 bi_depermanent(ctx
->bi_radix
);
121 bi_free(ctx
, ctx
->bi_radix
);
123 if (ctx
->active_count
!= 0)
125 #ifdef CONFIG_SSL_FULL_MODE
126 printf("bi_terminate: there were %d un-freed bigints\n",
137 *@brief Clear the memory cache.
139 void bi_clear_cache(BI_CTX
*ctx
)
143 if (ctx
->free_list
== NULL
)
146 for (p
= ctx
->free_list
; p
!= NULL
; p
= pn
)
154 ctx
->free_list
= NULL
;
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.
163 bigint
*bi_copy(bigint
*bi
)
166 if (bi
->refs
!= PERMANENT
)
172 * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
174 * For this object to be freed, bi_depermanent() must be called.
175 * @param bi [in] The bigint to be made permanent.
177 void bi_permanent(bigint
*bi
)
182 #ifdef CONFIG_SSL_FULL_MODE
183 printf("bi_permanent: refs was not 1\n");
188 bi
->refs
= PERMANENT
;
192 * @brief Take a permanent object and make it eligible for freedom.
193 * @param bi [in] The bigint to be made back to temporary.
195 void bi_depermanent(bigint
*bi
)
198 if (bi
->refs
!= PERMANENT
)
200 #ifdef CONFIG_SSL_FULL_MODE
201 printf("bi_depermanent: bigint was not permanent\n");
210 * @brief Free a bigint object so it can be used again.
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.
216 void bi_free(BI_CTX
*ctx
, bigint
*bi
)
219 if (bi
->refs
== PERMANENT
)
229 bi
->next
= ctx
->free_list
;
233 if (--ctx
->active_count
< 0)
235 #ifdef CONFIG_SSL_FULL_MODE
236 printf("bi_free: active_count went negative "
237 "- double-freed bigint?\n");
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.
249 bigint
*int_to_bi(BI_CTX
*ctx
, comp i
)
251 bigint
*biR
= alloc(ctx
, 1);
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.
261 bigint
*bi_clone(BI_CTX
*ctx
, const bigint
*bi
)
263 bigint
*biR
= alloc(ctx
, bi
->size
);
265 memcpy(biR
->comps
, bi
->comps
, bi
->size
*COMP_BYTE_SIZE
);
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.
276 bigint
*bi_add(BI_CTX
*ctx
, bigint
*bia
, bigint
*bib
)
285 n
= max(bia
->size
, bib
->size
);
286 more_comps(bia
, n
+1);
297 carry
= cy1
| (rl
< sl
);
301 *pa
= carry
; /* do overflow */
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.
315 bigint
*bi_subtract(BI_CTX
*ctx
,
316 bigint
*bia
, bigint
*bib
, int *is_negative
)
319 comp
*pa
, *pb
, carry
= 0;
334 carry
= cy1
| (rl
> sl
);
338 if (is_negative
) /* indicate a negative result */
340 *is_negative
= carry
;
343 bi_free(ctx
, trim(bib
)); /* put bib back to the way it was */
348 * Perform a multiply between a bigint an an (unsigned) integer
350 static bigint
*bi_int_multiply(BI_CTX
*ctx
, bigint
*bia
, comp b
)
352 int j
= 0, n
= bia
->size
;
353 bigint
*biR
= alloc(ctx
, n
+ 1);
355 comp
*r
= biR
->comps
;
356 comp
*a
= bia
->comps
;
360 /* clear things to start with */
361 memset(r
, 0, ((n
+1)*COMP_BYTE_SIZE
));
365 long_comp tmp
= *r
+ (long_comp
)a
[j
]*b
+ carry
;
366 *r
++ = (comp
)tmp
; /* downsize */
367 carry
= (comp
)(tmp
>> COMP_BIT_SIZE
);
376 * @brief Does both division and modulo calculations.
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
384 * @return The result of the division/reduction.
386 bigint
*bi_divide(BI_CTX
*ctx
, bigint
*u
, bigint
*v
, int is_mod
)
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
;
392 bigint
*quotient
, *tmp_u
;
398 /* if doing reduction and we are < mod, then return mod */
399 if (is_mod
&& bi_compare(v
, u
) > 0)
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));
410 /* clear things to start with */
411 memset(quotient
->comps
, 0, ((quotient
->size
)*COMP_BYTE_SIZE
));
416 u
= bi_int_multiply(ctx
, u
, d
);
420 v
= ctx
->bi_normalised_mod
[mod_offset
];
424 v
= bi_int_multiply(ctx
, v
, d
);
428 if (orig_u_size
== u
->size
) /* new digit position u0 */
430 more_comps(u
, orig_u_size
+ 1);
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
);
441 q_dash
= COMP_RADIX
-1;
445 q_dash
= (comp
)(((long_comp
)U(0)*COMP_RADIX
+ U(1))/V1
);
447 if (v
->size
> 1 && V2
)
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))
461 /* multiply and subtract */
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);
475 tmp_u
= bi_add(ctx
, tmp_u
, bi_copy(v
));
477 /* lop off the carry */
488 memcpy(&u
->comps
[u
->size
-n
-1-j
], tmp_u
->comps
, (n
+1)*COMP_BYTE_SIZE
);
494 if (is_mod
) /* get the remainder */
496 bi_free(ctx
, quotient
);
497 return bi_int_divide(ctx
, trim(u
), d
);
499 else /* get the quotient */
502 return trim(quotient
);
507 * Perform an integer divide on a bigint.
509 static bigint
*bi_int_divide(BI_CTX
*ctx
, bigint
*biR
, comp denom
)
511 int i
= biR
->size
- 1;
518 r
= (r
<<COMP_BIT_SIZE
) + biR
->comps
[i
];
519 biR
->comps
[i
] = (comp
)(r
/ denom
);
526 #ifdef CONFIG_BIGINT_MONTGOMERY
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
)
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];
541 for (i
= 2; i
<= COMP_BIT_SIZE
; i
++)
543 if ((long_comp
)N
*t
%two_2_i
>= two_2_i_minus_1
)
545 t
+= two_2_i_minus_1
;
548 two_2_i_minus_1
<<= 1;
552 return (comp
)(COMP_RADIX
-t
);
556 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
557 defined(CONFIG_BIGINT_MONTGOMERY)
559 * Take each component and shift down (in terms of components)
561 static bigint
*comp_right_shift(bigint
*biR
, int num_shifts
)
563 int i
= biR
->size
-num_shifts
;
564 comp
*x
= biR
->comps
;
565 comp
*y
= &biR
->comps
[num_shifts
];
569 if (i
<= 0) /* have we completely right shifted? */
571 biR
->comps
[0] = 0; /* return 0 */
581 biR
->size
-= num_shifts
;
586 * Take each component and shift it up (in terms of components)
588 static bigint
*comp_left_shift(bigint
*biR
, int num_shifts
)
600 more_comps(biR
, biR
->size
+ num_shifts
);
602 x
= &biR
->comps
[i
+num_shifts
];
610 memset(biR
->comps
, 0, num_shifts
*COMP_BYTE_SIZE
); /* zero LS comps */
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.
622 bigint
*bi_import(BI_CTX
*ctx
, const uint8_t *data
, int size
)
624 bigint
*biR
= alloc(ctx
, (size
+COMP_BYTE_SIZE
-1)/COMP_BYTE_SIZE
);
625 int i
, j
= 0, offset
= 0;
627 memset(biR
->comps
, 0, biR
->size
*COMP_BYTE_SIZE
);
629 for (i
= size
-1; i
>= 0; i
--)
631 biR
->comps
[offset
] += data
[i
] << (j
*8);
633 if (++j
== COMP_BYTE_SIZE
)
643 #ifdef CONFIG_SSL_FULL_MODE
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
650 * @return A bigint representing this data.
652 bigint
*bi_str_import(BI_CTX
*ctx
, const char *data
)
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
);
659 for (i
= size
-1; i
>= 0; i
--)
661 int num
= (data
[i
] <= '9') ? (data
[i
] - '0') : (data
[i
] - 'A' + 10);
662 biR
->comps
[offset
] += num
<< (j
*4);
664 if (++j
== COMP_NUM_NIBBLES
)
674 void bi_print(const char *label
, bigint
*x
)
680 printf("%s: (null)\n", label
);
684 printf("%s: (size %d)\n", label
, x
->size
);
685 for (i
= x
->size
-1; i
>= 0; i
--)
687 for (j
= COMP_NUM_NIBBLES
-1; j
>= 0; j
--)
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
);
700 * @brief Take a bigint and convert it into a byte sequence.
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
709 void bi_export(BI_CTX
*ctx
, bigint
*x
, uint8_t *data
, int size
)
711 int i
, j
, k
= size
-1;
714 memset(data
, 0, size
); /* ensure all leading 0's are cleared */
716 for (i
= 0; i
< x
->size
; i
++)
718 for (j
= 0; j
< COMP_BYTE_SIZE
; j
++)
720 comp mask
= 0xff << (j
*8);
721 int num
= (x
->comps
[i
] & mask
) >> (j
*8);
736 * @brief Pre-calculate some of the expensive steps in reduction.
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().
748 void bi_set_mod(BI_CTX
*ctx
, bigint
*bim
, int mod_offset
)
751 comp d
= (comp
)((long_comp
)COMP_RADIX
/(bim
->comps
[k
-1]+1));
752 #ifdef CONFIG_BIGINT_MONTGOMERY
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
]);
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 */
768 bi_permanent(ctx
->bi_RR_mod_m
[mod_offset
]);
769 bi_permanent(ctx
->bi_R_mod_m
[mod_offset
]);
771 ctx
->N0_dash
[mod_offset
] = modular_inverse(ctx
->bi_mod
[mod_offset
]);
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
]);
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.
787 void bi_free_mod(BI_CTX
*ctx
, int mod_offset
)
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
]);
800 bi_depermanent(ctx
->bi_normalised_mod
[mod_offset
]);
801 bi_free(ctx
, ctx
->bi_normalised_mod
[mod_offset
]);
805 * Perform a standard multiplication between two bigints.
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.
811 static bigint
*regular_multiply(BI_CTX
*ctx
, bigint
*bia
, bigint
*bib
,
812 int inner_partial
, int outer_partial
)
817 bigint
*biR
= alloc(ctx
, n
+ t
);
818 comp
*sr
= biR
->comps
;
819 comp
*sa
= bia
->comps
;
820 comp
*sb
= bib
->comps
;
825 /* clear things to start with */
826 memset(biR
->comps
, 0, ((n
+t
)*COMP_BYTE_SIZE
));
835 if (outer_partial
&& outer_partial
-i
> 0 && outer_partial
< n
)
837 r_index
= outer_partial
-1;
838 j
= outer_partial
-i
-1;
843 if (inner_partial
&& r_index
>= inner_partial
)
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
;
861 #ifdef CONFIG_BIGINT_KARATSUBA
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
867 static bigint
*karatsuba(BI_CTX
*ctx
, bigint
*bia
, bigint
*bib
, int is_square
)
870 bigint
*p0
, *p1
, *p2
;
875 m
= (bia
->size
+ 1)/2;
879 m
= (max(bia
->size
, bib
->size
) + 1)/2;
882 x0
= bi_clone(ctx
, bia
);
884 x1
= bi_clone(ctx
, bia
);
885 comp_right_shift(x1
, m
);
888 /* work out the 3 partial products */
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
));
895 else /* normal multiply */
898 y0
= bi_clone(ctx
, bib
);
900 y1
= bi_clone(ctx
, bib
);
901 comp_right_shift(y1
, m
);
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
));
909 p1
= bi_subtract(ctx
,
910 bi_subtract(ctx
, p1
, bi_copy(p2
), NULL
), bi_copy(p0
), NULL
);
912 comp_left_shift(p1
, m
);
913 comp_left_shift(p2
, 2*m
);
914 return bi_add(ctx
, p1
, bi_add(ctx
, p0
, p2
));
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.
925 bigint
*bi_multiply(BI_CTX
*ctx
, bigint
*bia
, bigint
*bib
)
930 #ifdef CONFIG_BIGINT_KARATSUBA
931 if (min(bia
->size
, bib
->size
) < MUL_KARATSUBA_THRESH
)
933 return regular_multiply(ctx
, bia
, bib
, 0, 0);
936 return karatsuba(ctx
, bia
, bib
, 0);
938 return regular_multiply(ctx
, bia
, bib
, 0, 0);
942 #ifdef CONFIG_BIGINT_SQUARE
944 * Perform the actual square operion. It takes into account overflow.
946 static bigint
*regular_square(BI_CTX
*ctx
, bigint
*bi
)
950 bigint
*biR
= alloc(ctx
, t
*2+1);
951 comp
*w
= biR
->comps
;
954 memset(w
, 0, biR
->size
*COMP_BYTE_SIZE
);
958 long_comp tmp
= w
[2*i
] + (long_comp
)x
[i
]*x
[i
];
960 carry
= tmp
>> COMP_BIT_SIZE
;
962 for (j
= i
+1; j
< t
; j
++)
965 long_comp xx
= (long_comp
)x
[i
]*x
[j
];
966 if ((COMP_MAX
-xx
) < xx
)
971 if ((COMP_MAX
-tmp
) < w
[i
+j
])
976 if ((COMP_MAX
-tmp
) < carry
)
981 carry
= tmp
>> COMP_BIT_SIZE
;
987 tmp
= w
[i
+t
] + carry
;
989 w
[i
+t
+1] = tmp
>> COMP_BIT_SIZE
;
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.
1002 bigint
*bi_square(BI_CTX
*ctx
, bigint
*bia
)
1006 #ifdef CONFIG_BIGINT_KARATSUBA
1007 if (bia
->size
< SQU_KARATSUBA_THRESH
)
1009 return regular_square(ctx
, bia
);
1012 return karatsuba(ctx
, bia
, NULL
, 1);
1014 return regular_square(ctx
, bia
);
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.
1025 int bi_compare(bigint
*bia
, bigint
*bib
)
1032 if (bia
->size
> bib
->size
)
1034 else if (bia
->size
< bib
->size
)
1038 comp
*a
= bia
->comps
;
1039 comp
*b
= bib
->comps
;
1041 /* Same number of components. Compare starting from the high end
1042 * and working down. */
1053 else if (a
[i
] < b
[i
])
1065 * Allocate and zero more components. Does not consume bi.
1067 static void more_comps(bigint
*bi
, int n
)
1069 if (n
> bi
->max_comps
)
1071 bi
->max_comps
= max(bi
->max_comps
* 2, n
);
1072 bi
->comps
= (comp
*)realloc(bi
->comps
, bi
->max_comps
* COMP_BYTE_SIZE
);
1077 memset(&bi
->comps
[bi
->size
], 0, (n
-bi
->size
)*COMP_BYTE_SIZE
);
1084 * Make a new empty bigint. It may just use an old one if one is available.
1085 * Otherwise get one off the heap.
1087 static bigint
*alloc(BI_CTX
*ctx
, int size
)
1091 /* Can we recycle an old bigint? */
1092 if (ctx
->free_list
!= NULL
)
1094 biR
= ctx
->free_list
;
1095 ctx
->free_list
= biR
->next
;
1100 #ifdef CONFIG_SSL_FULL_MODE
1101 printf("alloc: refs was not 0\n");
1103 abort(); /* create a stack trace from a core dump */
1106 more_comps(biR
, size
);
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 */
1119 ctx
->active_count
++;
1124 * Work out the highest '1' bit in an exponent. Used when doing sliding-window
1127 static int find_max_exp_index(bigint
*biexp
)
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 */
1139 return i
+(biexp
->size
-1)*COMP_BIT_SIZE
;
1145 return -1; /* error - must have been a leading 0 */
1149 * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
1152 static int exp_bit_is_one(bigint
*biexp
, int offset
)
1154 comp test
= biexp
->comps
[offset
/ COMP_BIT_SIZE
];
1155 int num_shifts
= offset
% COMP_BIT_SIZE
;
1161 for (i
= 0; i
< num_shifts
; i
++)
1166 return (test
& shift
) != 0;
1169 #ifdef CONFIG_BIGINT_CHECK_ON
1171 * Perform a sanity check on bi.
1173 static void check(const bigint
*bi
)
1177 printf("check: zero or negative refs in bigint\n");
1181 if (bi
->next
!= NULL
)
1183 printf("check: attempt to use a bigint from "
1191 * Delete any leading 0's (and allow for 0).
1193 static bigint
*trim(bigint
*bi
)
1197 while (bi
->comps
[bi
->size
-1] == 0 && bi
->size
> 1)
1205 #if defined(CONFIG_BIGINT_MONTGOMERY)
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.
1212 bigint
*bi_mont(BI_CTX
*ctx
, bigint
*bixy
)
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
];
1221 if (ctx
->use_classical
) /* just use classical instead */
1223 return bi_mod(ctx
, bixy
);
1230 bixy
= bi_add(ctx
, bixy
, comp_left_shift(
1231 bi_int_multiply(ctx
, bim
, bixy
->comps
[i
]*mod_inv
), i
));
1234 comp_right_shift(bixy
, n
);
1236 if (bi_compare(bixy
, bim
) >= 0)
1238 bixy
= bi_subtract(ctx
, bixy
, bim
, NULL
);
1244 #elif defined(CONFIG_BIGINT_BARRETT)
1246 * Stomp on the most significant components to give the illusion of a "mod base
1249 static bigint
*comp_mod(bigint
*bi
, int mod
)
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.
1267 bigint
*bi_barrett(BI_CTX
*ctx
, bigint
*bi
)
1269 bigint
*q1
, *q2
, *q3
, *r1
, *r2
, *r
;
1270 uint8_t mod_offset
= ctx
->mod_offset
;
1271 bigint
*bim
= ctx
->bi_mod
[mod_offset
];
1277 /* use Classical method instead - Barrett cannot help here */
1280 return bi_mod(ctx
, bi
);
1283 q1
= comp_right_shift(bi_clone(ctx
, bi
), k
-1);
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);
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
);
1294 /* if (r >= m) r = r - m; */
1295 if (bi_compare(r
, bim
) >= 0)
1297 r
= bi_subtract(ctx
, r
, bim
, NULL
);
1302 #endif /* CONFIG_BIGINT_BARRETT */
1304 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
1306 * Work out g1, g3, g5, g7... etc for the sliding-window algorithm
1308 static void precompute_slide_window(BI_CTX
*ctx
, int window
, bigint
*g1
)
1313 for (i
= 0; i
< window
-1; i
++) /* compute 2^(window-1) */
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 */
1323 for (i
= 1; i
< k
; i
++)
1325 ctx
->g
[i
] = bi_residue(ctx
, bi_multiply(ctx
, ctx
->g
[i
-1], bi_copy(g2
)));
1326 bi_permanent(ctx
->g
[i
]);
1335 * @brief Perform a modular exponentiation.
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().
1345 bigint
*bi_mod_power(BI_CTX
*ctx
, bigint
*bi
, bigint
*biexp
)
1347 int i
= find_max_exp_index(biexp
), j
, window_size
= 1;
1348 bigint
*biR
= int_to_bi(ctx
, 1);
1350 #if defined(CONFIG_BIGINT_MONTGOMERY)
1351 uint8_t mod_offset
= ctx
->mod_offset
;
1352 if (!ctx
->use_classical
)
1356 bi_multiply(ctx
, bi
, ctx
->bi_RR_mod_m
[mod_offset
])); /* x' */
1358 biR
= ctx
->bi_R_mod_m
[mod_offset
]; /* A */
1365 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
1366 for (j
= i
; j
> 32; j
/= 5) /* work out an optimum size */
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
);
1375 bi_permanent(ctx
->g
[0]);
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 */
1382 if (exp_bit_is_one(biexp
, i
))
1384 int l
= i
-window_size
+1;
1387 if (l
< 0) /* LSB of exponent will always be 1 */
1391 while (exp_bit_is_one(biexp
, l
) == 0)
1392 l
++; /* go back up */
1395 /* build up the section of the exponent */
1396 for (j
= i
; j
>= l
; j
--)
1398 biR
= bi_residue(ctx
, bi_square(ctx
, biR
));
1399 if (exp_bit_is_one(biexp
, j
))
1406 part_exp
= (part_exp
-1)/2; /* adjust for array */
1407 biR
= bi_residue(ctx
, bi_multiply(ctx
, biR
, ctx
->g
[part_exp
]));
1410 else /* square it */
1412 biR
= bi_residue(ctx
, bi_square(ctx
, biR
));
1418 for (i
= 0; i
< ctx
->window
; i
++)
1420 bi_depermanent(ctx
->g
[i
]);
1421 bi_free(ctx
, ctx
->g
[i
]);
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 */
1434 #ifdef CONFIG_SSL_CERT_VERIFICATION
1436 * @brief Perform a modular exponentiation using a temporary modulus.
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().
1447 bigint
*bi_mod_power2(BI_CTX
*ctx
, bigint
*bi
, bigint
*bim
, bigint
*biexp
)
1449 bigint
*biR
, *tmp_biR
;
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
);
1467 bi_free(ctx
, biexp
);
1472 #ifdef CONFIG_BIGINT_CRT
1474 * @brief Use the Chinese Remainder Theorem to quickly perform RSA decrypts.
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
1485 bigint
*bi_crt(BI_CTX
*ctx
, bigint
*bi
,
1486 bigint
*dP
, bigint
*dQ
,
1487 bigint
*p
, bigint
*q
, bigint
*qInv
)
1489 bigint
*m1
, *m2
, *h
;
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;
1496 ctx
->mod_offset
= BIGINT_P_OFFSET
;
1497 m1
= bi_mod_power(ctx
, bi_copy(bi
), dP
);
1499 ctx
->mod_offset
= BIGINT_Q_OFFSET
;
1500 m2
= bi_mod_power(ctx
, bi
, dQ
);
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 */
1509 return bi_add(ctx
, m2
, bi_multiply(ctx
, q
, h
));