5 * multiple-precision integer library
\r
8 * Copyright (c) PeerSec Networks, 2002-2006. All Rights Reserved.
\r
9 * The latest version of this code is available at http://www.matrixssl.org
\r
11 * This software is open source; you can redistribute it and/or modify
\r
12 * it under the terms of the GNU General Public License as published by
\r
13 * the Free Software Foundation; either version 2 of the License, or
\r
14 * (at your option) any later version.
\r
16 * This General Public License does NOT permit incorporating this software
\r
17 * into proprietary programs. If you are unable to comply with the GPL, a
\r
18 * commercial license for this software may be purchased from PeerSec Networks
\r
19 * at http://www.peersec.com
\r
21 * This program is distributed in WITHOUT ANY WARRANTY; without even the
\r
22 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
23 * See the GNU General Public License for more details.
\r
25 * You should have received a copy of the GNU General Public License
\r
26 * along with this program; if not, write to the Free Software
\r
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
28 * http://www.gnu.org/copyleft/gpl.html
\r
30 /******************************************************************************/
\r
42 #define MIN(x,y) ((x)<(y)?(x):(y))
\r
44 #define MAX(x,y) ((x)>(y)?(x):(y))
\r
51 C++ compilers don't like assigning void * to mp_digit *
\r
53 #define OPT_CAST(x) (x *)
\r
58 C on the other hand doesn't care
\r
62 #endif /* __cplusplus */
\r
64 /******************************************************************************/
\r
66 some default configurations.
\r
68 A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
\r
69 A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
\r
71 At the very least a mp_digit must be able to hold 7 bits
\r
72 [any size beyond that is ok provided it doesn't overflow the data type]
\r
75 typedef unsigned char mp_digit;
\r
76 typedef unsigned short mp_word;
\r
77 #elif defined(MP_16BIT)
\r
78 typedef unsigned short mp_digit;
\r
79 typedef unsigned long mp_word;
\r
80 #elif defined(MP_64BIT)
\r
82 for GCC only on supported platforms
\r
85 typedef unsigned long long ulong64;
\r
86 typedef signed long long long64;
\r
89 typedef ulong64 mp_digit;
\r
90 typedef unsigned long mp_word __attribute__ ((mode(TI)));
\r
92 #define DIGIT_BIT 60
\r
95 this is the default case, 28-bit digits
\r
98 #if defined(_MSC_VER) || defined(__BORLANDC__)
\r
99 typedef unsigned __int64 ulong64;
\r
100 typedef signed __int64 long64;
\r
102 typedef unsigned long long ulong64;
\r
103 typedef signed long long long64;
\r
107 typedef unsigned long mp_digit;
\r
108 typedef ulong64 mp_word;
\r
112 this is an extension that uses 31-bit digits
\r
114 #define DIGIT_BIT 31
\r
115 #else /* MP_31BIT */
\r
117 default case is 28-bit digits, defines MP_28BIT as a handy macro to test
\r
119 #define DIGIT_BIT 28
\r
121 #endif /* MP_31BIT */
\r
122 #endif /* MP_8BIT */
\r
125 otherwise the bits per digit is calculated automatically from the size of
\r
129 #define DIGIT_BIT ((int32)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
\r
130 #endif /* DIGIT_BIT */
\r
132 #define MP_DIGIT_BIT DIGIT_BIT
\r
133 #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
\r
134 #define MP_DIGIT_MAX MP_MASK
\r
136 /******************************************************************************/
\r
140 #define MP_LT -1 /* less than */
\r
141 #define MP_EQ 0 /* equal to */
\r
142 #define MP_GT 1 /* greater than */
\r
144 #define MP_ZPOS 0 /* positive integer */
\r
145 #define MP_NEG 1 /* negative */
\r
147 #define MP_OKAY 0 /* ok result */
\r
148 #define MP_MEM -2 /* out of mem */
\r
149 #define MP_VAL -3 /* invalid input */
\r
150 #define MP_RANGE MP_VAL
\r
152 #define MP_YES 1 /* yes response */
\r
153 #define MP_NO 0 /* no response */
\r
155 typedef int32 mp_err;
\r
157 /******************************************************************************/
\r
159 various build options
\r
161 #define MP_PREC 64 /* default digits of precision */
\r
164 define this to use lower memory usage routines (exptmods mostly)
\r
169 size of comba arrays, should be at least
\r
170 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2)
\r
172 #define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
\r
175 int32 used, alloc, sign;
\r
179 #define USED(m) ((m)->used)
\r
180 #define DIGIT(m,k) ((m)->dp[(k)])
\r
181 #define SIGN(m) ((m)->sign)
\r
183 /******************************************************************************/
\r
185 init and deinit bignum functions
\r
191 extern int32 mp_init(psPool_t *pool, mp_int *a);
\r
196 extern void mp_clear(mp_int *a);
\r
199 init a series of arguments
\r
201 extern int32 _mp_init_multi(psPool_t *pool, mp_int *mp0, mp_int *mp1, mp_int *mp2,
\r
202 mp_int *mp3, mp_int *mp4, mp_int *mp5, mp_int *mp6,
\r
206 clear a series of arguments
\r
208 extern void _mp_clear_multi(mp_int *mp0, mp_int *mp1, mp_int *mp2, mp_int *mp3,
\r
209 mp_int *mp4, mp_int *mp5, mp_int *mp6, mp_int *mp7);
\r
214 extern void mp_exch(mp_int *a, mp_int *b);
\r
217 shrink ram required for a bignum
\r
219 extern int32 mp_shrink(mp_int *a);
\r
222 grow an int32 to a given size
\r
224 extern int32 mp_grow(mp_int *a, int32 size);
\r
227 init to a given number of digits
\r
229 extern int32 mp_init_size(psPool_t *pool, mp_int *a, int32 size);
\r
231 /******************************************************************************/
\r
233 Basic Manipulations
\r
235 #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
\r
236 #define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
\r
237 #define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
\r
239 extern int32 mp_add_d (mp_int * a, mp_digit b, mp_int * c);
\r
240 extern int32 mp_sub_d (mp_int * a, mp_digit b, mp_int * c);
\r
244 extern void mp_zero(mp_int *a);
\r
249 extern void mp_set(mp_int *a, mp_digit b);
\r
254 extern int32 mp_copy(mp_int *a, mp_int *b);
\r
257 inits and copies, a = b
\r
259 extern int32 mp_init_copy(psPool_t *pool, mp_int *a, mp_int *b);
\r
264 extern void mp_clamp(mp_int *a);
\r
266 /******************************************************************************/
\r
272 right shift by "b" digits
\r
274 extern void mp_rshd(mp_int *a, int32 b);
\r
277 left shift by "b" digits
\r
279 extern int32 mp_lshd(mp_int *a, int32 b);
\r
284 extern int32 mp_div_2d(psPool_t *pool, mp_int *a, int32 b, mp_int *c, mp_int *d);
\r
289 extern int32 mp_div_2(mp_int *a, mp_int *b);
\r
294 extern int32 mp_mul_2d(mp_int *a, int32 b, mp_int *c);
\r
299 extern int32 mp_mod_2d(mp_int *a, int32 b, mp_int *c);
\r
304 extern int32 mp_2expt(mp_int *a, int32 b);
\r
306 /******************************************************************************/
\r
314 extern int32 mp_abs(mp_int *a, mp_int *b);
\r
319 extern int32 mp_cmp(mp_int *a, mp_int *b);
\r
324 extern int32 mp_cmp_mag(mp_int *a, mp_int *b);
\r
329 extern int32 mp_add(mp_int *a, mp_int *b, mp_int *c);
\r
334 extern int32 mp_sub(mp_int *a, mp_int *b, mp_int *c);
\r
340 /* STEVE - moved mp_mul out of SLOW case */
\r
341 extern int32 mp_mul(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c);
\r
342 #ifdef USE_SMALL_WORD
\r
343 extern int32 mp_sqr(psPool_t *pool, mp_int *a, mp_int *b);
\r
349 extern int32 mp_div(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c, mp_int *d);
\r
352 c = a mod b, 0 <= c < b
\r
354 extern int32 mp_mod(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c);
\r
356 /******************************************************************************/
\r
358 single digit functions
\r
362 compare against a single digit
\r
364 extern int32 mp_cmp_d(mp_int *a, mp_digit b);
\r
369 extern int32 mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
\r
371 /******************************************************************************/
\r
379 extern int32 mp_addmod(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c, mp_int *d);
\r
384 extern int32 mp_mulmod(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c, mp_int *d);
\r
389 #ifdef USE_SMALL_WORD
\r
390 extern int32 mp_invmod(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c);
\r
394 setups the montgomery reduction
\r
396 extern int32 mp_montgomery_setup(mp_int *a, mp_digit *mp);
\r
399 computes a = B**n mod b without division or multiplication useful for
\r
400 normalizing numbers in a Montgomery system.
\r
402 extern int32 mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
\r
405 computes x/R == x (mod N) via Montgomery Reduction
\r
407 #ifdef USE_SMALL_WORD
\r
408 extern int32 mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
\r
414 /* TODO - we never define this */
\r
415 extern int32 mp_exptmod(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c, mp_int *d);
\r
417 /******************************************************************************/
\r
419 If we're using 1024 or 2048 bit keys and 28 bit digits, we only need the
\r
420 fast_ versions of these functions, removing the others to save space.
\r
421 Otherwise, we include the slow versions as well and which version to use
\r
422 is done at runtime.
\r
424 #ifdef USE_SMALL_WORD
\r
425 extern int32 s_mp_mul_digs(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c,
\r
427 extern int32 s_mp_sqr(psPool_t *pool, mp_int *a, mp_int *b);
\r
429 #define mp_montgomery_reduce fast_mp_montgomery_reduce
\r
430 #define mp_sqr fast_s_mp_sqr
\r
432 #define mp_mul(P, A, B, C) fast_s_mp_mul_digs(P, A, B, C, (A)->used + (B)->used + 1)
\r
434 #define s_mp_mul_digs fast_s_mp_mul_digs
\r
435 #define mp_invmod fast_mp_invmod
\r
438 /******************************************************************************/
\r
442 extern int32 mp_count_bits(mp_int *a);
\r
444 extern int32 mp_unsigned_bin_size(mp_int *a);
\r
445 extern int32 mp_read_unsigned_bin(mp_int *a, unsigned char *b, int32 c);
\r
446 extern int32 mp_to_unsigned_bin(psPool_t *pool, mp_int *a, unsigned char *b);
\r
448 extern int32 mp_signed_bin_size(mp_int *a);
\r
451 lowlevel functions, do not call!
\r
454 #ifdef USE_SMALL_WORD
\r
455 #define s_mp_mul(P, A, B, C) s_mp_mul_digs(P, A, B, C, (A)->used + (B)->used + 1)
\r
457 #define s_mp_mul(P, A, B, C) sslAssert();
\r
460 /* define this in all cases for now STEVE */
\r
461 #define s_mp_mul(P, A, B, C) s_mp_mul_digs(P, A, B, C, (A)->used + (B)->used + 1)
\r
467 extern int32 mp_mul_2(mp_int *a, mp_int *b);
\r
469 extern int32 s_mp_add(mp_int *a, mp_int *b, mp_int *c);
\r
470 extern int32 s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
\r
472 extern int32 fast_s_mp_mul_digs(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c,
\r
474 extern int32 fast_s_mp_sqr(psPool_t *pool, mp_int *a, mp_int *b);
\r
476 extern int32 fast_mp_invmod(psPool_t *pool, mp_int *a, mp_int *b, mp_int *c);
\r
477 extern int32 fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
\r
479 extern void bn_reverse(unsigned char *s, int32 len);
\r
484 #endif /* __cplusplus */
\r
486 #endif /* _h_MPI */
\r