Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MiniTLS-GPL by
tfm.h
00001 /* TomsFastMath, a fast ISO C bignum library. 00002 * 00003 * This project is meant to fill in where LibTomMath 00004 * falls short. That is speed ;-) 00005 * 00006 * This project is public domain and free for all purposes. 00007 * 00008 * Tom St Denis, tomstdenis@gmail.com 00009 */ 00010 #ifndef TFM_H_ 00011 #define TFM_H_ 00012 00013 #include <stdio.h> 00014 #include <string.h> 00015 #include <stdint.h> 00016 #include <stdlib.h> 00017 #include <ctype.h> 00018 #include <limits.h> 00019 00020 /* Specific Config */ 00021 #include "inc/minitls_config.h" 00022 #define TFM_ECC192 CRYPTO_ECC192 //Enable stuff needed for ECC 192 computations 00023 #define TFM_NO_ASM 1 00024 #define TFM_TIMING_RESISTANT //Slower but fixed computation times and lower stack usage 00025 #define FP_MAX_SIZE 2*(DIGIT_BIT+CRYPTO_MAX_KEY_SIZE)//ECC192 max 00026 00027 /* */ 00028 00029 #ifndef MIN 00030 #define MIN(x,y) ((x)<(y)?(x):(y)) 00031 #endif 00032 00033 #ifndef MAX 00034 #define MAX(x,y) ((x)>(y)?(x):(y)) 00035 #endif 00036 00037 /* externally define this symbol to ignore the default settings, useful for changing the build from the make process */ 00038 #ifndef TFM_ALREADY_SET 00039 00040 /* do we want the large set of small multiplications ? 00041 Enable these if you are going to be doing a lot of small (<= 16 digit) multiplications say in ECC 00042 Or if you're on a 64-bit machine doing RSA as a 1024-bit integer == 16 digits ;-) 00043 */ 00044 //#define TFM_SMALL_SET 00045 00046 /* do we want huge code 00047 Enable these if you are doing 20, 24, 28, 32, 48, 64 digit multiplications (useful for RSA) 00048 Less important on 64-bit machines as 32 digits == 2048 bits 00049 */ 00050 #if 0 //DG 00051 #if 0 00052 #define TFM_MUL3 00053 #define TFM_MUL4 00054 #define TFM_MUL6 00055 #define TFM_MUL7 00056 #define TFM_MUL8 00057 #define TFM_MUL9 00058 #define TFM_MUL12 00059 #define TFM_MUL17 00060 #endif 00061 #define TFM_MUL20 00062 #define TFM_MUL24 00063 #define TFM_MUL28 00064 #define TFM_MUL32 00065 #define TFM_MUL48 00066 #define TFM_MUL64 00067 #if 0 00068 #define TFM_SQR3 00069 #define TFM_SQR4 00070 #define TFM_SQR6 00071 #define TFM_SQR7 00072 #define TFM_SQR8 00073 #define TFM_SQR9 00074 #define TFM_SQR12 00075 #define TFM_SQR17 00076 #endif 00077 #define TFM_SQR20 00078 #define TFM_SQR24 00079 #define TFM_SQR28 00080 #define TFM_SQR32 00081 #define TFM_SQR48 00082 #define TFM_SQR64 00083 #endif 00084 00085 /* do we want some overflow checks 00086 Not required if you make sure your numbers are within range (e.g. by default a modulus for fp_exptmod() can only be upto 2048 bits long) 00087 */ 00088 /* #define TFM_CHECK */ 00089 00090 /* Is the target a P4 Prescott 00091 */ 00092 /* #define TFM_PRESCOTT */ 00093 00094 /* Do we want timing resistant fp_exptmod() ? 00095 * This makes it slower but also timing invariant with respect to the exponent 00096 */ 00097 //#define TFM_TIMING_RESISTANT 00098 00099 #endif 00100 00101 /* Max size of any number in bits. Basically the largest size you will be multiplying 00102 * should be half [or smaller] of FP_MAX_SIZE-four_digit 00103 * 00104 * You can externally define this or it defaults to 4096-bits [allowing multiplications upto 2048x2048 bits ] 00105 */ 00106 #ifndef FP_MAX_SIZE 00107 #define FP_MAX_SIZE (4096+(8*DIGIT_BIT)) 00108 #endif 00109 00110 /* will this lib work? */ 00111 #if (CHAR_BIT & 7) 00112 #error CHAR_BIT must be a multiple of eight. 00113 #endif 00114 #if FP_MAX_SIZE % CHAR_BIT 00115 #error FP_MAX_SIZE must be a multiple of CHAR_BIT 00116 #endif 00117 00118 /* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */ 00119 #if defined(__x86_64__) 00120 #if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) 00121 #error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid! 00122 #endif 00123 #if !defined(TFM_X86_64) && !defined(TFM_NO_ASM) 00124 #define TFM_X86_64 00125 #endif 00126 #endif 00127 #if defined(TFM_X86_64) 00128 #if !defined(FP_64BIT) 00129 #define FP_64BIT 00130 #endif 00131 #endif 00132 00133 /* try to detect x86-32 */ 00134 #if defined(__i386__) && !defined(TFM_SSE2) 00135 #if defined(TFM_X86_64) || defined(TFM_ARM) 00136 #error x86-32 detected, x86-64/ARM optimizations are not valid! 00137 #endif 00138 #if !defined(TFM_X86) && !defined(TFM_NO_ASM) 00139 #define TFM_X86 00140 #endif 00141 #endif 00142 00143 /* make sure we're 32-bit for x86-32/sse/arm/ppc32 */ 00144 #if (defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) || defined(TFM_PPC32)) && defined(FP_64BIT) 00145 #warning x86-32, SSE2 and ARM, PPC32 optimizations require 32-bit digits (undefining) 00146 #undef FP_64BIT 00147 #endif 00148 00149 /* multi asms? */ 00150 #ifdef TFM_X86 00151 #define TFM_ASM 00152 #endif 00153 #ifdef TFM_X86_64 00154 #ifdef TFM_ASM 00155 #error TFM_ASM already defined! 00156 #endif 00157 #define TFM_ASM 00158 #endif 00159 #ifdef TFM_SSE2 00160 #ifdef TFM_ASM 00161 #error TFM_ASM already defined! 00162 #endif 00163 #define TFM_ASM 00164 #endif 00165 #ifdef TFM_ARM 00166 #ifdef TFM_ASM 00167 #error TFM_ASM already defined! 00168 #endif 00169 #define TFM_ASM 00170 #endif 00171 #ifdef TFM_PPC32 00172 #ifdef TFM_ASM 00173 #error TFM_ASM already defined! 00174 #endif 00175 #define TFM_ASM 00176 #endif 00177 #ifdef TFM_PPC64 00178 #ifdef TFM_ASM 00179 #error TFM_ASM already defined! 00180 #endif 00181 #define TFM_ASM 00182 #endif 00183 #ifdef TFM_AVR32 00184 #ifdef TFM_ASM 00185 #error TFM_ASM already defined! 00186 #endif 00187 #define TFM_ASM 00188 #endif 00189 00190 /* we want no asm? */ 00191 #ifdef TFM_NO_ASM 00192 #undef TFM_X86 00193 #undef TFM_X86_64 00194 #undef TFM_SSE2 00195 #undef TFM_ARM 00196 #undef TFM_PPC32 00197 #undef TFM_PPC64 00198 #undef TFM_AVR32 00199 #undef TFM_ASM 00200 #endif 00201 00202 /* ECC helpers */ 00203 #ifdef TFM_ECC192 00204 #ifdef FP_64BIT 00205 #define TFM_MUL3 00206 #define TFM_SQR3 00207 #else 00208 #define TFM_MUL6 00209 #define TFM_SQR6 00210 #endif 00211 #endif 00212 00213 #ifdef TFM_ECC224 00214 #ifdef FP_64BIT 00215 #define TFM_MUL4 00216 #define TFM_SQR4 00217 #else 00218 #define TFM_MUL7 00219 #define TFM_SQR7 00220 #endif 00221 #endif 00222 00223 #ifdef TFM_ECC256 00224 #ifdef FP_64BIT 00225 #define TFM_MUL4 00226 #define TFM_SQR4 00227 #else 00228 #define TFM_MUL8 00229 #define TFM_SQR8 00230 #endif 00231 #endif 00232 00233 #ifdef TFM_ECC384 00234 #ifdef FP_64BIT 00235 #define TFM_MUL6 00236 #define TFM_SQR6 00237 #else 00238 #define TFM_MUL12 00239 #define TFM_SQR12 00240 #endif 00241 #endif 00242 00243 #ifdef TFM_ECC521 00244 #ifdef FP_64BIT 00245 #define TFM_MUL9 00246 #define TFM_SQR9 00247 #else 00248 #define TFM_MUL17 00249 #define TFM_SQR17 00250 #endif 00251 #endif 00252 00253 00254 /* some default configurations. 00255 */ 00256 #if 0 00257 #if defined(FP_64BIT) 00258 /* for GCC only on supported platforms */ 00259 #ifndef CRYPT 00260 typedef unsigned long ulong64; 00261 #endif 00262 typedef ulong64 fp_digit; 00263 typedef unsigned long fp_word __attribute__ ((mode(TI))); 00264 #else 00265 /* this is to make porting into LibTomCrypt easier :-) */ 00266 #ifndef CRYPT 00267 #if defined(_MSC_VER) || defined(__BORLANDC__) 00268 typedef unsigned __int64 ulong64; 00269 typedef signed __int64 long64; 00270 #else 00271 typedef unsigned long long ulong64; 00272 typedef signed long long long64; 00273 #endif 00274 #endif 00275 typedef unsigned long fp_digit; 00276 typedef ulong64 fp_word; 00277 #endif 00278 #endif 00279 00280 typedef uint32_t fp_digit; 00281 typedef uint64_t fp_word; 00282 00283 /* # of digits this is */ 00284 #define DIGIT_BIT (int)((CHAR_BIT) * sizeof(fp_digit)) 00285 #define FP_MASK (fp_digit)(-1) 00286 #define FP_SIZE (FP_MAX_SIZE/DIGIT_BIT) 00287 00288 /* signs */ 00289 #define FP_ZPOS 0 00290 #define FP_NEG 1 00291 00292 /* return codes */ 00293 #include "inc/minitls_errors.h" 00294 #define FP_OKAY MINITLS_OK 00295 #define FP_VAL MINITLS_ERR_PARAMETERS 00296 #define FP_MEM MINITLS_ERR_MEMORY 00297 00298 /* equalities */ 00299 #define FP_LT -1 /* less than */ 00300 #define FP_EQ 0 /* equal to */ 00301 #define FP_GT 1 /* greater than */ 00302 00303 /* replies */ 00304 #define FP_YES 1 /* yes response */ 00305 #define FP_NO 0 /* no response */ 00306 00307 /* a FP type */ 00308 typedef struct { 00309 fp_digit dp[FP_SIZE]; 00310 int used, 00311 sign; 00312 } fp_int; 00313 00314 /* functions */ 00315 00316 /* returns a TFM ident string useful for debugging... */ 00317 const char *fp_ident(void); 00318 00319 /* initialize [or zero] an fp int */ 00320 #define fp_init(a) (void)memset((a), 0, sizeof(fp_int)) 00321 #define fp_zero(a) fp_init(a) 00322 00323 /* zero/even/odd ? */ 00324 #define fp_iszero(a) (((a)->used == 0) ? FP_YES : FP_NO) 00325 #define fp_iseven(a) (((a)->used >= 0 && (((a)->dp[0] & 1) == 0)) ? FP_YES : FP_NO) 00326 #define fp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? FP_YES : FP_NO) 00327 00328 /* set to a small digit */ 00329 void fp_set(fp_int *a, fp_digit b); 00330 00331 /* copy from a to b */ 00332 #define fp_copy(a, b) (void)(((a) != (b)) && memcpy((b), (a), sizeof(fp_int))) 00333 #define fp_init_copy(a, b) fp_copy(b, a) 00334 00335 /* clamp digits */ 00336 #define fp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : FP_ZPOS; } 00337 00338 /* negate and absolute */ 00339 #define fp_neg(a, b) { fp_copy(a, b); (b)->sign ^= 1; fp_clamp(b); } 00340 #define fp_abs(a, b) { fp_copy(a, b); (b)->sign = 0; } 00341 00342 /* right shift x digits */ 00343 void fp_rshd(fp_int *a, int x); 00344 00345 /* left shift x digits */ 00346 void fp_lshd(fp_int *a, int x); 00347 00348 /* signed comparison */ 00349 int fp_cmp(fp_int *a, fp_int *b); 00350 00351 /* unsigned comparison */ 00352 int fp_cmp_mag(fp_int *a, fp_int *b); 00353 00354 /* power of 2 operations */ 00355 void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d); 00356 void fp_mod_2d(fp_int *a, int b, fp_int *c); 00357 void fp_mul_2d(fp_int *a, int b, fp_int *c); 00358 void fp_2expt (fp_int *a, int b); 00359 void fp_mul_2(fp_int *a, fp_int *c); 00360 void fp_div_2(fp_int *a, fp_int *c); 00361 00362 /* Counts the number of lsbs which are zero before the first zero bit */ 00363 int fp_cnt_lsb(fp_int *a); 00364 00365 /* c = a + b */ 00366 void fp_add(fp_int *a, fp_int *b, fp_int *c); 00367 00368 /* c = a - b */ 00369 void fp_sub(fp_int *a, fp_int *b, fp_int *c); 00370 00371 /* c = a * b */ 00372 void fp_mul(fp_int *a, fp_int *b, fp_int *c); 00373 00374 /* b = a*a */ 00375 void fp_sqr(fp_int *a, fp_int *b); 00376 00377 /* a/b => cb + d == a */ 00378 int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d); 00379 00380 /* c = a mod b, 0 <= c < b */ 00381 int fp_mod(fp_int *a, fp_int *b, fp_int *c); 00382 00383 /* compare against a single digit */ 00384 int fp_cmp_d(fp_int *a, fp_digit b); 00385 00386 /* c = a + b */ 00387 void fp_add_d(fp_int *a, fp_digit b, fp_int *c); 00388 00389 /* c = a - b */ 00390 void fp_sub_d(fp_int *a, fp_digit b, fp_int *c); 00391 00392 /* c = a * b */ 00393 void fp_mul_d(fp_int *a, fp_digit b, fp_int *c); 00394 00395 /* a/b => cb + d == a */ 00396 int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d); 00397 00398 /* c = a mod b, 0 <= c < b */ 00399 int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c); 00400 00401 /* ---> number theory <--- */ 00402 /* d = a + b (mod c) */ 00403 int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); 00404 00405 /* d = a - b (mod c) */ 00406 int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); 00407 00408 /* d = a * b (mod c) */ 00409 int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); 00410 00411 /* c = a * a (mod b) */ 00412 int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c); 00413 00414 /* c = 1/a (mod b) */ 00415 int fp_invmod(fp_int *a, fp_int *b, fp_int *c); 00416 00417 /* c = (a, b) */ 00418 void fp_gcd(fp_int *a, fp_int *b, fp_int *c); 00419 00420 /* c = [a, b] */ 00421 void fp_lcm(fp_int *a, fp_int *b, fp_int *c); 00422 00423 /* setups the montgomery reduction */ 00424 int fp_montgomery_setup(fp_int *a, fp_digit *mp); 00425 00426 /* computes a = B**n mod b without division or multiplication useful for 00427 * normalizing numbers in a Montgomery system. 00428 */ 00429 void fp_montgomery_calc_normalization(fp_int *a, fp_int *b); 00430 00431 /* computes x/R == x (mod N) via Montgomery Reduction */ 00432 void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); 00433 00434 /* d = a**b (mod c) */ 00435 int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); 00436 00437 /* primality stuff */ 00438 00439 /* perform a Miller-Rabin test of a to the base b and store result in "result" */ 00440 void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result); 00441 00442 /* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime */ 00443 int fp_isprime(fp_int *a); 00444 00445 /* Primality generation flags */ 00446 #define TFM_PRIME_BBS 0x0001 /* BBS style prime */ 00447 #define TFM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ 00448 #define TFM_PRIME_2MSB_OFF 0x0004 /* force 2nd MSB to 0 */ 00449 #define TFM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ 00450 00451 /* callback for fp_prime_random, should fill dst with random bytes and return how many read [upto len] */ 00452 typedef int tfm_prime_callback(unsigned char *dst, int len, void *dat); 00453 00454 #define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat) 00455 00456 int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat); 00457 00458 /* radix conersions */ 00459 int fp_count_bits(fp_int *a); 00460 00461 int fp_unsigned_bin_size(fp_int *a); 00462 void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c); 00463 void fp_to_unsigned_bin(fp_int *a, unsigned char *b); 00464 00465 int fp_signed_bin_size(fp_int *a); 00466 void fp_read_signed_bin(fp_int *a, unsigned char *b, int c); 00467 void fp_to_signed_bin(fp_int *a, unsigned char *b); 00468 00469 int fp_read_radix(fp_int *a, char *str, int radix); 00470 int fp_toradix(fp_int *a, char *str, int radix); 00471 int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen); 00472 00473 00474 /* VARIOUS LOW LEVEL STUFFS */ 00475 void s_fp_add(fp_int *a, fp_int *b, fp_int *c); 00476 void s_fp_sub(fp_int *a, fp_int *b, fp_int *c); 00477 void fp_reverse(unsigned char *s, int len); 00478 00479 void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C); 00480 00481 #ifdef TFM_SMALL_SET 00482 void fp_mul_comba_small(fp_int *A, fp_int *B, fp_int *C); 00483 #endif 00484 00485 #ifdef TFM_MUL3 00486 void fp_mul_comba3(fp_int *A, fp_int *B, fp_int *C); 00487 #endif 00488 #ifdef TFM_MUL4 00489 void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C); 00490 #endif 00491 #ifdef TFM_MUL6 00492 void fp_mul_comba6(fp_int *A, fp_int *B, fp_int *C); 00493 #endif 00494 #ifdef TFM_MUL7 00495 void fp_mul_comba7(fp_int *A, fp_int *B, fp_int *C); 00496 #endif 00497 #ifdef TFM_MUL8 00498 void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C); 00499 #endif 00500 #ifdef TFM_MUL9 00501 void fp_mul_comba9(fp_int *A, fp_int *B, fp_int *C); 00502 #endif 00503 #ifdef TFM_MUL12 00504 void fp_mul_comba12(fp_int *A, fp_int *B, fp_int *C); 00505 #endif 00506 #ifdef TFM_MUL17 00507 void fp_mul_comba17(fp_int *A, fp_int *B, fp_int *C); 00508 #endif 00509 00510 #ifdef TFM_MUL20 00511 void fp_mul_comba20(fp_int *A, fp_int *B, fp_int *C); 00512 #endif 00513 #ifdef TFM_MUL24 00514 void fp_mul_comba24(fp_int *A, fp_int *B, fp_int *C); 00515 #endif 00516 #ifdef TFM_MUL28 00517 void fp_mul_comba28(fp_int *A, fp_int *B, fp_int *C); 00518 #endif 00519 #ifdef TFM_MUL32 00520 void fp_mul_comba32(fp_int *A, fp_int *B, fp_int *C); 00521 #endif 00522 #ifdef TFM_MUL48 00523 void fp_mul_comba48(fp_int *A, fp_int *B, fp_int *C); 00524 #endif 00525 #ifdef TFM_MUL64 00526 void fp_mul_comba64(fp_int *A, fp_int *B, fp_int *C); 00527 #endif 00528 00529 void fp_sqr_comba(fp_int *A, fp_int *B); 00530 00531 #ifdef TFM_SMALL_SET 00532 void fp_sqr_comba_small(fp_int *A, fp_int *B); 00533 #endif 00534 00535 #ifdef TFM_SQR3 00536 void fp_sqr_comba3(fp_int *A, fp_int *B); 00537 #endif 00538 #ifdef TFM_SQR4 00539 void fp_sqr_comba4(fp_int *A, fp_int *B); 00540 #endif 00541 #ifdef TFM_SQR6 00542 void fp_sqr_comba6(fp_int *A, fp_int *B); 00543 #endif 00544 #ifdef TFM_SQR7 00545 void fp_sqr_comba7(fp_int *A, fp_int *B); 00546 #endif 00547 #ifdef TFM_SQR8 00548 void fp_sqr_comba8(fp_int *A, fp_int *B); 00549 #endif 00550 #ifdef TFM_SQR9 00551 void fp_sqr_comba9(fp_int *A, fp_int *B); 00552 #endif 00553 #ifdef TFM_SQR12 00554 void fp_sqr_comba12(fp_int *A, fp_int *B); 00555 #endif 00556 #ifdef TFM_SQR17 00557 void fp_sqr_comba17(fp_int *A, fp_int *B); 00558 #endif 00559 00560 #ifdef TFM_SQR20 00561 void fp_sqr_comba20(fp_int *A, fp_int *B); 00562 #endif 00563 #ifdef TFM_SQR24 00564 void fp_sqr_comba24(fp_int *A, fp_int *B); 00565 #endif 00566 #ifdef TFM_SQR28 00567 void fp_sqr_comba28(fp_int *A, fp_int *B); 00568 #endif 00569 #ifdef TFM_SQR32 00570 void fp_sqr_comba32(fp_int *A, fp_int *B); 00571 #endif 00572 #ifdef TFM_SQR48 00573 void fp_sqr_comba48(fp_int *A, fp_int *B); 00574 #endif 00575 #ifdef TFM_SQR64 00576 void fp_sqr_comba64(fp_int *A, fp_int *B); 00577 #endif 00578 extern const char *fp_s_rmap; 00579 00580 #endif 00581 00582 00583 /* $Source: /cvs/libtom/tomsfastmath/src/headers/tfm.h,v $ */ 00584 /* $Revision: 1.3 $ */ 00585 /* $Date: 2007/02/27 02:38:44 $ */
Generated on Tue Jul 12 2022 19:20:10 by
1.7.2
