Merge pull request #113 from czurnieden/develop
Added Fips 186.4 compliance, an additional strong Lucas-Selfridge (for BPSW) and a Frobenius (Paul Underwood) test, both optional. With documentation.
This commit is contained in:
		
						commit
						f9eec4350e
					
				
							
								
								
									
										55
									
								
								bn_mp_get_bit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								bn_mp_get_bit.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | #include "tommath_private.h" | ||||||
|  | #ifdef BN_MP_GET_BIT_C | ||||||
|  | 
 | ||||||
|  | /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||||
|  |  * | ||||||
|  |  * LibTomMath is a library that provides multiple-precision | ||||||
|  |  * integer arithmetic as well as number theoretic functionality. | ||||||
|  |  * | ||||||
|  |  * The library was designed directly after the MPI library by | ||||||
|  |  * Michael Fromberger but has been written from scratch with | ||||||
|  |  * additional optimizations in place. | ||||||
|  |  * | ||||||
|  |  * The library is free for all purposes without any express | ||||||
|  |  * guarantee it works. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* Checks the bit at position b and returns MP_YES
 | ||||||
|  |    if the bit is 1, MP_NO if it is 0 and MP_VAL | ||||||
|  |    in case of error */ | ||||||
|  | int mp_get_bit(const mp_int *a, int b) | ||||||
|  | { | ||||||
|  |    int limb; | ||||||
|  |    mp_digit bit, isset; | ||||||
|  | 
 | ||||||
|  |    if (b < 0) { | ||||||
|  |       return MP_VAL; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    limb = b / DIGIT_BIT; | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * Zero is a special value with the member "used" set to zero. | ||||||
|  |     * Needs to be tested before the check for the upper boundary | ||||||
|  |     * otherwise (limb >= a->used) would be true for a = 0 | ||||||
|  |     */ | ||||||
|  | 
 | ||||||
|  |    if (mp_iszero(a)) { | ||||||
|  |       return MP_NO; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (limb >= a->used) { | ||||||
|  |       return MP_VAL; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    bit = (mp_digit)(1) << (b % DIGIT_BIT); | ||||||
|  | 
 | ||||||
|  |    isset = a->dp[limb] & bit; | ||||||
|  |    return (isset != 0) ? MP_YES : MP_NO; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ref:         $Format:%D$ */ | ||||||
|  | /* git commit:  $Format:%H$ */ | ||||||
|  | /* commit time: $Format:%ai$ */ | ||||||
| @ -14,16 +14,10 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /* computes the jacobi c = (a | n) (or Legendre if n is prime)
 | /* computes the jacobi c = (a | n) (or Legendre if n is prime)
 | ||||||
|  * HAC pp. 73 Algorithm 2.149 |  * Kept for legacy reasons, please use mp_kronecker() instead | ||||||
|  * HAC is wrong here, as the special case of (0 | 1) is not |  | ||||||
|  * handled correctly. |  | ||||||
|  */ |  */ | ||||||
| int mp_jacobi(const mp_int *a, const mp_int *n, int *c) | int mp_jacobi(const mp_int *a, const mp_int *n, int *c) | ||||||
| { | { | ||||||
|    mp_int  a1, p1; |  | ||||||
|    int     k, s, r, res; |  | ||||||
|    mp_digit residue; |  | ||||||
| 
 |  | ||||||
|    /* if a < 0 return MP_VAL */ |    /* if a < 0 return MP_VAL */ | ||||||
|    if (mp_isneg(a) == MP_YES) { |    if (mp_isneg(a) == MP_YES) { | ||||||
|       return MP_VAL; |       return MP_VAL; | ||||||
| @ -34,81 +28,7 @@ int mp_jacobi(const mp_int *a, const mp_int *n, int *c) | |||||||
|       return MP_VAL; |       return MP_VAL; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* step 1. handle case of a == 0 */ |    return mp_kronecker(a,n,c); | ||||||
|    if (mp_iszero(a) == MP_YES) { |  | ||||||
|       /* special case of a == 0 and n == 1 */ |  | ||||||
|       if (mp_cmp_d(n, 1uL) == MP_EQ) { |  | ||||||
|          *c = 1; |  | ||||||
|       } else { |  | ||||||
|          *c = 0; |  | ||||||
|       } |  | ||||||
|       return MP_OKAY; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* step 2.  if a == 1, return 1 */ |  | ||||||
|    if (mp_cmp_d(a, 1uL) == MP_EQ) { |  | ||||||
|       *c = 1; |  | ||||||
|       return MP_OKAY; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* default */ |  | ||||||
|    s = 0; |  | ||||||
| 
 |  | ||||||
|    /* step 3.  write a = a1 * 2**k  */ |  | ||||||
|    if ((res = mp_init_copy(&a1, a)) != MP_OKAY) { |  | ||||||
|       return res; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    if ((res = mp_init(&p1)) != MP_OKAY) { |  | ||||||
|       goto LBL_A1; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* divide out larger power of two */ |  | ||||||
|    k = mp_cnt_lsb(&a1); |  | ||||||
|    if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { |  | ||||||
|       goto LBL_P1; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* step 4.  if e is even set s=1 */ |  | ||||||
|    if (((unsigned)k & 1u) == 0u) { |  | ||||||
|       s = 1; |  | ||||||
|    } else { |  | ||||||
|       /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ |  | ||||||
|       residue = n->dp[0] & 7u; |  | ||||||
| 
 |  | ||||||
|       if ((residue == 1u) || (residue == 7u)) { |  | ||||||
|          s = 1; |  | ||||||
|       } else if ((residue == 3u) || (residue == 5u)) { |  | ||||||
|          s = -1; |  | ||||||
|       } |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* step 5.  if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ |  | ||||||
|    if (((n->dp[0] & 3u) == 3u) && ((a1.dp[0] & 3u) == 3u)) { |  | ||||||
|       s = -s; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* if a1 == 1 we're done */ |  | ||||||
|    if (mp_cmp_d(&a1, 1uL) == MP_EQ) { |  | ||||||
|       *c = s; |  | ||||||
|    } else { |  | ||||||
|       /* n1 = n mod a1 */ |  | ||||||
|       if ((res = mp_mod(n, &a1, &p1)) != MP_OKAY) { |  | ||||||
|          goto LBL_P1; |  | ||||||
|       } |  | ||||||
|       if ((res = mp_jacobi(&p1, &a1, &r)) != MP_OKAY) { |  | ||||||
|          goto LBL_P1; |  | ||||||
|       } |  | ||||||
|       *c = s * r; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* done */ |  | ||||||
|    res = MP_OKAY; |  | ||||||
| LBL_P1: |  | ||||||
|    mp_clear(&p1); |  | ||||||
| LBL_A1: |  | ||||||
|    mp_clear(&a1); |  | ||||||
|    return res; |  | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								bn_mp_kronecker.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								bn_mp_kronecker.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | |||||||
|  | #include "tommath_private.h" | ||||||
|  | #ifdef BN_MP_KRONECKER_C | ||||||
|  | 
 | ||||||
|  | /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||||
|  |  * | ||||||
|  |  * LibTomMath is a library that provides multiple-precision | ||||||
|  |  * integer arithmetic as well as number theoretic functionality. | ||||||
|  |  * | ||||||
|  |  * The library was designed directly after the MPI library by | ||||||
|  |  * Michael Fromberger but has been written from scratch with | ||||||
|  |  * additional optimizations in place. | ||||||
|  |  * | ||||||
|  |  * The library is free for all purposes without any express | ||||||
|  |  * guarantee it works. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |    Kronecker symbol (a|p) | ||||||
|  |    Straightforward implementation of algorithm 1.4.10 in | ||||||
|  |    Henri Cohen: "A Course in Computational Algebraic Number Theory" | ||||||
|  | 
 | ||||||
|  |    @book{cohen2013course, | ||||||
|  |      title={A course in computational algebraic number theory}, | ||||||
|  |      author={Cohen, Henri}, | ||||||
|  |      volume={138}, | ||||||
|  |      year={2013}, | ||||||
|  |      publisher={Springer Science \& Business Media} | ||||||
|  |     } | ||||||
|  |  */ | ||||||
|  | int mp_kronecker(const mp_int *a, const mp_int *p, int *c) | ||||||
|  | { | ||||||
|  |    mp_int a1, p1, r; | ||||||
|  | 
 | ||||||
|  |    int e = MP_OKAY; | ||||||
|  |    int v, k; | ||||||
|  | 
 | ||||||
|  |    const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1}; | ||||||
|  | 
 | ||||||
|  |    if (mp_iszero(p)) { | ||||||
|  |       if (a->used == 1 && a->dp[0] == 1) { | ||||||
|  |          *c = 1; | ||||||
|  |          return e; | ||||||
|  |       } else { | ||||||
|  |          *c = 0; | ||||||
|  |          return e; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (mp_iseven(a) && mp_iseven(p)) { | ||||||
|  |       *c = 0; | ||||||
|  |       return e; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if ((e = mp_init_copy(&a1, a)) != MP_OKAY) { | ||||||
|  |       return e; | ||||||
|  |    } | ||||||
|  |    if ((e = mp_init_copy(&p1, p)) != MP_OKAY) { | ||||||
|  |       goto LBL_KRON_0; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    v = mp_cnt_lsb(&p1); | ||||||
|  |    if ((e = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) { | ||||||
|  |       goto LBL_KRON_1; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if ((v & 0x1) == 0) { | ||||||
|  |       k = 1; | ||||||
|  |    } else { | ||||||
|  |       k = table[a->dp[0] & 7]; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (p1.sign == MP_NEG) { | ||||||
|  |       p1.sign = MP_ZPOS; | ||||||
|  |       if (a1.sign == MP_NEG) { | ||||||
|  |          k = -k; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if ((e = mp_init(&r)) != MP_OKAY) { | ||||||
|  |       goto LBL_KRON_1; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    for (;;) { | ||||||
|  |       if (mp_iszero(&a1)) { | ||||||
|  |          if (mp_cmp_d(&p1, 1) == MP_EQ) { | ||||||
|  |             *c = k; | ||||||
|  |             goto LBL_KRON; | ||||||
|  |          } else { | ||||||
|  |             *c = 0; | ||||||
|  |             goto LBL_KRON; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       v = mp_cnt_lsb(&a1); | ||||||
|  |       if ((e = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) { | ||||||
|  |          goto LBL_KRON; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ((v & 0x1) == 1) { | ||||||
|  |          k = k * table[p1.dp[0] & 7]; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (a1.sign == MP_NEG) { | ||||||
|  |          /*
 | ||||||
|  |           * Compute k = (-1)^((a1)*(p1-1)/4) * k | ||||||
|  |           * a1.dp[0] + 1 cannot overflow because the MSB | ||||||
|  |           * of the type mp_digit is not set by definition | ||||||
|  |           */ | ||||||
|  |          if ((a1.dp[0] + 1) & p1.dp[0] & 2u) { | ||||||
|  |             k = -k; | ||||||
|  |          } | ||||||
|  |       } else { | ||||||
|  |          /* compute k = (-1)^((a1-1)*(p1-1)/4) * k */ | ||||||
|  |          if (a1.dp[0] & p1.dp[0] & 2u) { | ||||||
|  |             k = -k; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ((e = mp_copy(&a1,&r)) != MP_OKAY) { | ||||||
|  |          goto LBL_KRON; | ||||||
|  |       } | ||||||
|  |       r.sign = MP_ZPOS; | ||||||
|  |       if ((e = mp_mod(&p1, &r, &a1)) != MP_OKAY) { | ||||||
|  |          goto LBL_KRON; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_copy(&r, &p1)) != MP_OKAY) { | ||||||
|  |          goto LBL_KRON; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  | LBL_KRON: | ||||||
|  |    mp_clear(&r); | ||||||
|  | LBL_KRON_1: | ||||||
|  |    mp_clear(&p1); | ||||||
|  | LBL_KRON_0: | ||||||
|  |    mp_clear(&a1); | ||||||
|  | 
 | ||||||
|  |    return e; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ref:         $Format:%D$ */ | ||||||
|  | /* git commit:  $Format:%H$ */ | ||||||
|  | /* commit time: $Format:%ai$ */ | ||||||
							
								
								
									
										198
									
								
								bn_mp_prime_frobenius_underwood.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								bn_mp_prime_frobenius_underwood.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,198 @@ | |||||||
|  | #include "tommath_private.h" | ||||||
|  | #ifdef BN_MP_PRIME_FROBENIUS_UNDERWOOD_C | ||||||
|  | 
 | ||||||
|  | /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||||
|  |  * | ||||||
|  |  * LibTomMath is a library that provides multiple-precision | ||||||
|  |  * integer arithmetic as well as number theoretic functionality. | ||||||
|  |  * | ||||||
|  |  * The library was designed directly after the MPI library by | ||||||
|  |  * Michael Fromberger but has been written from scratch with | ||||||
|  |  * additional optimizations in place. | ||||||
|  |  * | ||||||
|  |  * The library is free for all purposes without any express | ||||||
|  |  * guarantee it works. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details | ||||||
|  |  */ | ||||||
|  | #ifndef LTM_USE_FIPS_ONLY | ||||||
|  | 
 | ||||||
|  | #ifdef MP_8BIT | ||||||
|  | /*
 | ||||||
|  |  * floor of positive solution of | ||||||
|  |  * (2^16)-1 = (a+4)*(2*a+5) | ||||||
|  |  * TODO: Both values are smaller than N^(1/4), would have to use a bigint | ||||||
|  |  *       for a instead but any a biger than about 120 are already so rare that | ||||||
|  |  *       it is possible to ignore them and still get enough pseudoprimes. | ||||||
|  |  *       But it is still a restriction of the set of available pseudoprimes | ||||||
|  |  *       which makes this implementation less secure if used stand-alone. | ||||||
|  |  */ | ||||||
|  | #define LTM_FROBENIUS_UNDERWOOD_A 177 | ||||||
|  | #else | ||||||
|  | #define LTM_FROBENIUS_UNDERWOOD_A 32764 | ||||||
|  | #endif | ||||||
|  | int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||||
|  | { | ||||||
|  |    mp_int T1z,T2z,Np1z,sz,tz; | ||||||
|  | 
 | ||||||
|  |    int a, ap2, length, i, j, isset; | ||||||
|  |    int e = MP_OKAY; | ||||||
|  | 
 | ||||||
|  |    *result = MP_NO; | ||||||
|  | 
 | ||||||
|  |    if ((e = mp_init_multi(&T1z,&T2z,&Np1z,&sz,&tz, NULL)) != MP_OKAY) { | ||||||
|  |       return e; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    for (a = 0; a < LTM_FROBENIUS_UNDERWOOD_A; a++) { | ||||||
|  |       /* TODO: That's ugly! No, really, it is! */ | ||||||
|  |       if (a==2||a==4||a==7||a==8||a==10||a==14||a==18||a==23||a==26||a==28) { | ||||||
|  |          continue; | ||||||
|  |       } | ||||||
|  |       /* (32764^2 - 4) < 2^31, no bigint for >MP_8BIT needed) */ | ||||||
|  |       if ((e = mp_set_long(&T1z,(unsigned long)a)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ((e = mp_sqr(&T1z,&T1z)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ((e = mp_sub_d(&T1z,4,&T1z)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ((e = mp_kronecker(&T1z, N, &j)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (j == -1) { | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (j == 0) { | ||||||
|  |          /* composite */ | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    /* Tell it a composite and set return value accordingly */ | ||||||
|  |    if (a >= LTM_FROBENIUS_UNDERWOOD_A) { | ||||||
|  |       e = MP_ITER; | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  |    /* Composite if N and (a+4)*(2*a+5) are not coprime */ | ||||||
|  |    if ((e = mp_set_long(&T1z, (unsigned long)((a+4)*(2*a+5)))) != MP_OKAY) { | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if ((e = mp_gcd(N,&T1z,&T1z)) != MP_OKAY) { | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (!(T1z.used == 1 && T1z.dp[0] == 1u)) { | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    ap2 = a + 2; | ||||||
|  |    if ((e = mp_add_d(N,1u,&Np1z)) != MP_OKAY) { | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    mp_set(&sz,1u); | ||||||
|  |    mp_set(&tz,2u); | ||||||
|  |    length = mp_count_bits(&Np1z); | ||||||
|  | 
 | ||||||
|  |    for (i = length - 2; i >= 0; i--) { | ||||||
|  |       /*
 | ||||||
|  |        * temp = (sz*(a*sz+2*tz))%N; | ||||||
|  |        * tz   = ((tz-sz)*(tz+sz))%N; | ||||||
|  |        * sz   = temp; | ||||||
|  |        */ | ||||||
|  |       if ((e = mp_mul_2(&tz,&T2z)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       /* a = 0 at about 50% of the cases (non-square and odd input) */ | ||||||
|  |       if (a != 0) { | ||||||
|  |          if ((e = mp_mul_d(&sz,(mp_digit)a,&T1z)) != MP_OKAY) { | ||||||
|  |             goto LBL_FU_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_add(&T1z,&T2z,&T2z)) != MP_OKAY) { | ||||||
|  |             goto LBL_FU_ERR; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ((e = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_sub(&tz, &sz, &T2z)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_add(&sz, &tz, &sz)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mul(&sz, &T2z, &tz)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mod(&tz, N, &tz)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mod(&T1z, N, &sz)) != MP_OKAY) { | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |       if ((isset = mp_get_bit(&Np1z,i)) == MP_VAL) { | ||||||
|  |          e = isset; | ||||||
|  |          goto LBL_FU_ERR; | ||||||
|  |       } | ||||||
|  |       if (isset == MP_YES) { | ||||||
|  |          /*
 | ||||||
|  |           *  temp = (a+2) * sz + tz | ||||||
|  |           *  tz   = 2 * tz - sz | ||||||
|  |           *  sz   = temp | ||||||
|  |           */ | ||||||
|  |          if (a == 0) { | ||||||
|  |             if ((e = mp_mul_2(&sz,&T1z)) != MP_OKAY) { | ||||||
|  |                goto LBL_FU_ERR; | ||||||
|  |             } | ||||||
|  |          } else { | ||||||
|  |             if ((e = mp_mul_d(&sz, (mp_digit) ap2, &T1z)) != MP_OKAY) { | ||||||
|  |                goto LBL_FU_ERR; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          if ((e = mp_add(&T1z, &tz, &T1z)) != MP_OKAY) { | ||||||
|  |             goto LBL_FU_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mul_2(&tz, &T2z)) != MP_OKAY) { | ||||||
|  |             goto LBL_FU_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_sub(&T2z, &sz, &tz)) != MP_OKAY) { | ||||||
|  |             goto LBL_FU_ERR; | ||||||
|  |          } | ||||||
|  |          mp_exch(&sz,&T1z); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if ((e = mp_set_long(&T1z, (unsigned long)(2 * a + 5))) != MP_OKAY) { | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  |    if ((e = mp_mod(&T1z,N,&T1z)) != MP_OKAY) { | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  |    if (mp_iszero(&sz) && (mp_cmp(&tz, &T1z) == MP_EQ)) { | ||||||
|  |       *result = MP_YES; | ||||||
|  |       goto LBL_FU_ERR; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  | LBL_FU_ERR: | ||||||
|  |    mp_clear_multi(&tz,&sz,&Np1z,&T2z,&T1z, NULL); | ||||||
|  |    return e; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ref:         $Format:%D$ */ | ||||||
|  | /* git commit:  $Format:%H$ */ | ||||||
|  | /* commit time: $Format:%ai$ */ | ||||||
| @ -13,33 +13,69 @@ | |||||||
|  * guarantee it works. |  * guarantee it works. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /* performs a variable number of rounds of Miller-Rabin
 | /* portable integer log of two with small footprint */ | ||||||
|  * | static unsigned int s_floor_ilog2(int value) | ||||||
|  * Probability of error after t rounds is no more than | { | ||||||
|  |    unsigned int r = 0; | ||||||
|  |    while ((value >>= 1) != 0) { | ||||||
|  |       r++; | ||||||
|  |    } | ||||||
|  |    return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|  * |  | ||||||
|  * Sets result to 1 if probably prime, 0 otherwise |  | ||||||
|  */ |  | ||||||
| int mp_prime_is_prime(const mp_int *a, int t, int *result) | int mp_prime_is_prime(const mp_int *a, int t, int *result) | ||||||
| { | { | ||||||
|    mp_int  b; |    mp_int  b; | ||||||
|    int     ix, err, res; |    int     ix, err, res, p_max = 0, size_a, len; | ||||||
|  |    unsigned int fips_rand, mask; | ||||||
| 
 | 
 | ||||||
|    /* default to no */ |    /* default to no */ | ||||||
|    *result = MP_NO; |    *result = MP_NO; | ||||||
| 
 | 
 | ||||||
|    /* valid value of t? */ |    /* valid value of t? */ | ||||||
|    if ((t <= 0) || (t > PRIME_SIZE)) { |    if (t > PRIME_SIZE) { | ||||||
|       return MP_VAL; |       return MP_VAL; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    /* Some shortcuts */ | ||||||
|  |    /* N > 3 */ | ||||||
|  |    if (a->used == 1) { | ||||||
|  |       if (a->dp[0] == 0 || a->dp[0] == 1) { | ||||||
|  |          *result = 0; | ||||||
|  |          return MP_OKAY; | ||||||
|  |       } | ||||||
|  |       if (a->dp[0] == 2) { | ||||||
|  |          *result = 1; | ||||||
|  |          return MP_OKAY; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    /* N must be odd */ | ||||||
|  |    if (mp_iseven(a) == MP_YES) { | ||||||
|  |       return MP_OKAY; | ||||||
|  |    } | ||||||
|  |    /* N is not a perfect square: floor(sqrt(N))^2 != N */ | ||||||
|  |    if ((err = mp_is_square(a, &res)) != MP_OKAY) { | ||||||
|  |       return err; | ||||||
|  |    } | ||||||
|  |    if (res != 0) { | ||||||
|  |       return MP_OKAY; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|    /* is the input equal to one of the primes in the table? */ |    /* is the input equal to one of the primes in the table? */ | ||||||
|    for (ix = 0; ix < PRIME_SIZE; ix++) { |    for (ix = 0; ix < PRIME_SIZE; ix++) { | ||||||
|       if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { |       if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { | ||||||
|          *result = 1; |          *result = MP_YES; | ||||||
|          return MP_OKAY; |          return MP_OKAY; | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  | #ifdef MP_8BIT | ||||||
|  |    /* The search in the loop above was exhaustive in this case */ | ||||||
|  |    if (a->used == 1 && PRIME_SIZE >= 31) { | ||||||
|  |       return MP_OKAY; | ||||||
|  |    } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|    /* first perform trial division */ |    /* first perform trial division */ | ||||||
|    if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) { |    if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) { | ||||||
| @ -51,22 +87,269 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | |||||||
|       return MP_OKAY; |       return MP_OKAY; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* now perform the miller-rabin rounds */ |    /*
 | ||||||
|    if ((err = mp_init(&b)) != MP_OKAY) { |        Run the Miller-Rabin test with base 2 for the BPSW test. | ||||||
|  |     */ | ||||||
|  |    if ((err = mp_init_set(&b,2)) != MP_OKAY) { | ||||||
|       return err; |       return err; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    for (ix = 0; ix < t; ix++) { |    if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { | ||||||
|       /* set the prime */ |       goto LBL_B; | ||||||
|       mp_set(&b, ltm_prime_tab[ix]); |    } | ||||||
|  |    if (res == MP_NO) { | ||||||
|  |       goto LBL_B; | ||||||
|  |    } | ||||||
|  |    /*
 | ||||||
|  |       Rumours have it that Mathematica does a second M-R test with base 3. | ||||||
|  |       Other rumours have it that their strong L-S test is slightly different. | ||||||
|  |       It does not hurt, though, beside a bit of extra runtime. | ||||||
|  |    */ | ||||||
|  |    b.dp[0]++; | ||||||
|  |    if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { | ||||||
|  |       goto LBL_B; | ||||||
|  |    } | ||||||
|  |    if (res == MP_NO) { | ||||||
|  |       goto LBL_B; | ||||||
|  |    } | ||||||
| 
 | 
 | ||||||
|       if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { |    /*
 | ||||||
|  |     * Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite | ||||||
|  |     * slow so if speed is an issue, define LTM_USE_FIPS_ONLY to use M-R tests with | ||||||
|  |     * bases 2, 3 and t random bases. | ||||||
|  |     */ | ||||||
|  | #ifndef LTM_USE_FIPS_ONLY | ||||||
|  |    if (t >= 0) { | ||||||
|  |       /*
 | ||||||
|  |        * Use a Frobenius-Underwood test instead of the Lucas-Selfridge test for | ||||||
|  |        * MP_8BIT (It is unknown if the Lucas-Selfridge test works with 16-bit | ||||||
|  |        * integers but the necesssary analysis is on the todo-list). | ||||||
|  |        */ | ||||||
|  | #if defined (MP_8BIT) || defined (LTM_USE_FROBENIUS_TEST) | ||||||
|  |       err = mp_prime_frobenius_underwood(a, &res); | ||||||
|  |       if (err != MP_OKAY && err != MP_ITER) { | ||||||
|  |          goto LBL_B; | ||||||
|  |       } | ||||||
|  |       if (res == MP_NO) { | ||||||
|  |          goto LBL_B; | ||||||
|  |       } | ||||||
|  | #else | ||||||
|  |       if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) { | ||||||
|  |          goto LBL_B; | ||||||
|  |       } | ||||||
|  |       if (res == MP_NO) { | ||||||
|  |          goto LBL_B; | ||||||
|  |       } | ||||||
|  | #endif | ||||||
|  |    } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |    /* run at least one Miller-Rabin test with a random base */ | ||||||
|  |    if (t == 0) { | ||||||
|  |       t = 1; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |       abs(t) extra rounds of M-R to extend the range of primes it can find if t < 0. | ||||||
|  |       Only recommended if the input range is known to be < 3317044064679887385961981 | ||||||
|  | 
 | ||||||
|  |       It uses the bases for a deterministic M-R test if input < 3317044064679887385961981 | ||||||
|  |       The caller has to check the size. | ||||||
|  | 
 | ||||||
|  |       Not for cryptographic use because with known bases strong M-R pseudoprimes can | ||||||
|  |       be constructed. Use at least one M-R test with a random base (t >= 1). | ||||||
|  | 
 | ||||||
|  |       The 1119 bit large number | ||||||
|  | 
 | ||||||
|  |       80383745745363949125707961434194210813883768828755814583748891752229742737653\ | ||||||
|  |       33652186502336163960045457915042023603208766569966760987284043965408232928738\ | ||||||
|  |       79185086916685732826776177102938969773947016708230428687109997439976544144845\ | ||||||
|  |       34115587245063340927902227529622941498423068816854043264575340183297861112989\ | ||||||
|  |       60644845216191652872597534901 | ||||||
|  | 
 | ||||||
|  |       has been constructed by F. Arnault (F. Arnault, "Rabin-Miller primality test: | ||||||
|  |       composite numbers which pass it.",  Mathematics of Computation, 1995, 64. Jg., | ||||||
|  |       Nr. 209, S. 355-361), is a semiprime with the two factors | ||||||
|  | 
 | ||||||
|  |       40095821663949960541830645208454685300518816604113250877450620473800321707011\ | ||||||
|  |       96242716223191597219733582163165085358166969145233813917169287527980445796800\ | ||||||
|  |       452592031836601 | ||||||
|  | 
 | ||||||
|  |       20047910831974980270915322604227342650259408302056625438725310236900160853505\ | ||||||
|  |       98121358111595798609866791081582542679083484572616906958584643763990222898400\ | ||||||
|  |       226296015918301 | ||||||
|  | 
 | ||||||
|  |       and it is a strong pseudoprime to all forty-six prime M-R bases up to 200 | ||||||
|  | 
 | ||||||
|  |       It does not fail the strong Bailley-PSP test as implemented here, it is just | ||||||
|  |       given as an example, if not the reason to use the BPSW-test instead of M-R-tests | ||||||
|  |       with a sequence of primes 2...n. | ||||||
|  | 
 | ||||||
|  |    */ | ||||||
|  |    if (t < 0) { | ||||||
|  |       t = -t; | ||||||
|  |       /*
 | ||||||
|  |           Sorenson, Jonathan; Webster, Jonathan (2015). | ||||||
|  |            "Strong Pseudoprimes to Twelve Prime Bases". | ||||||
|  |        */ | ||||||
|  |       /* 0x437ae92817f9fc85b7e5 = 318665857834031151167461 */ | ||||||
|  |       if ((err =   mp_read_radix(&b, "437ae92817f9fc85b7e5", 16)) != MP_OKAY) { | ||||||
|          goto LBL_B; |          goto LBL_B; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (res == MP_NO) { |       if (mp_cmp(a,&b) == MP_LT) { | ||||||
|  |          p_max = 12; | ||||||
|  |       } else { | ||||||
|  |          /* 0x2be6951adc5b22410a5fd = 3317044064679887385961981 */ | ||||||
|  |          if ((err = mp_read_radix(&b, "2be6951adc5b22410a5fd", 16)) != MP_OKAY) { | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          if (mp_cmp(a,&b) == MP_LT) { | ||||||
|  |             p_max = 13; | ||||||
|  |          } else { | ||||||
|  |             err = MP_VAL; | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       /* for compatibility with the current API (well, compatible within a sign's width) */ | ||||||
|  |       if (p_max < t) { | ||||||
|  |          p_max = t; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (p_max > PRIME_SIZE) { | ||||||
|  |          err = MP_VAL; | ||||||
|          goto LBL_B; |          goto LBL_B; | ||||||
|       } |       } | ||||||
|  |       /* we did bases 2 and 3  already, skip them */ | ||||||
|  |       for (ix = 2; ix < p_max; ix++) { | ||||||
|  |          mp_set(&b,ltm_prime_tab[ix]); | ||||||
|  |          if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  |          if (res == MP_NO) { | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    /*
 | ||||||
|  |        Do "t" M-R tests with random bases between 3 and "a". | ||||||
|  |        See Fips 186.4 p. 126ff | ||||||
|  |    */ | ||||||
|  |    else if (t > 0) { | ||||||
|  |       /*
 | ||||||
|  |        * The mp_digit's have a defined bit-size but the size of the | ||||||
|  |        * array a.dp is a simple 'int' and this library can not assume full | ||||||
|  |        * compliance to the current C-standard (ISO/IEC 9899:2011) because | ||||||
|  |        * it gets used for small embeded processors, too. Some of those MCUs | ||||||
|  |        * have compilers that one cannot call standard compliant by any means. | ||||||
|  |        * Hence the ugly type-fiddling in the following code. | ||||||
|  |        */ | ||||||
|  |       size_a = mp_count_bits(a); | ||||||
|  |       mask = (1u << s_floor_ilog2(size_a)) - 1u; | ||||||
|  |       /*
 | ||||||
|  |          Assuming the General Rieman hypothesis (never thought to write that in a | ||||||
|  |          comment) the upper bound can be lowered to  2*(log a)^2. | ||||||
|  |          E. Bach, "Explicit bounds for primality testing and related problems," | ||||||
|  |          Math. Comp. 55 (1990), 355-380. | ||||||
|  | 
 | ||||||
|  |             size_a = (size_a/10) * 7; | ||||||
|  |             len = 2 * (size_a * size_a); | ||||||
|  | 
 | ||||||
|  |          E.g.: a number of size 2^2048 would be reduced to the upper limit | ||||||
|  | 
 | ||||||
|  |             floor(2048/10)*7 = 1428 | ||||||
|  |             2 * 1428^2       = 4078368 | ||||||
|  | 
 | ||||||
|  |          (would have been ~4030331.9962 with floats and natural log instead) | ||||||
|  |          That number is smaller than 2^28, the default bit-size of mp_digit. | ||||||
|  |       */ | ||||||
|  | 
 | ||||||
|  |       /*
 | ||||||
|  |         How many tests, you might ask? Dana Jacobsen of Math::Prime::Util fame | ||||||
|  |         does exactly 1. In words: one. Look at the end of _GMP_is_prime() in | ||||||
|  |         Math-Prime-Util-GMP-0.50/primality.c if you do not believe it. | ||||||
|  | 
 | ||||||
|  |         The function mp_rand() goes to some length to use a cryptographically | ||||||
|  |         good PRNG. That also means that the chance to always get the same base | ||||||
|  |         in the loop is non-zero, although very low. | ||||||
|  |         If the BPSW test and/or the addtional Frobenious test have been | ||||||
|  |         performed instead of just the Miller-Rabin test with the bases 2 and 3, | ||||||
|  |         a single extra test should suffice, so such a very unlikely event | ||||||
|  |         will not do much harm. | ||||||
|  | 
 | ||||||
|  |         To preemptivly answer the dangling question: no, a witness does not | ||||||
|  |         need to be prime. | ||||||
|  |       */ | ||||||
|  |       for (ix = 0; ix < t; ix++) { | ||||||
|  |          /* mp_rand() guarantees the first digit to be non-zero */ | ||||||
|  |          if ((err = mp_rand(&b, 1)) != MP_OKAY) { | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  |          /*
 | ||||||
|  |           * Reduce digit before casting because mp_digit might be bigger than | ||||||
|  |           * an unsigned int and "mask" on the other side is most probably not. | ||||||
|  |           */ | ||||||
|  |          fips_rand = (unsigned int)(b.dp[0] & (mp_digit) mask); | ||||||
|  | #ifdef MP_8BIT | ||||||
|  |          /*
 | ||||||
|  |           * One 8-bit digit is too small, so concatenate two if the size of | ||||||
|  |           * unsigned int allows for it. | ||||||
|  |           */ | ||||||
|  |          if ((sizeof(unsigned int) * CHAR_BIT)/2 >= (sizeof(mp_digit) * CHAR_BIT)) { | ||||||
|  |             if ((err = mp_rand(&b, 1)) != MP_OKAY) { | ||||||
|  |                goto LBL_B; | ||||||
|  |             } | ||||||
|  |             fips_rand <<= sizeof(mp_digit) * CHAR_BIT; | ||||||
|  |             fips_rand |= (unsigned int) b.dp[0]; | ||||||
|  |             fips_rand &= mask; | ||||||
|  |          } | ||||||
|  | #endif | ||||||
|  |          /* Ceil, because small numbers have a right to live, too, */ | ||||||
|  |          len = (int)((fips_rand + DIGIT_BIT) / DIGIT_BIT); | ||||||
|  |          /*  Unlikely. */ | ||||||
|  |          if (len < 0) { | ||||||
|  |             ix--; | ||||||
|  |             continue; | ||||||
|  |          } | ||||||
|  |          /*
 | ||||||
|  |           * As mentioned above, one 8-bit digit is too small and | ||||||
|  |           * although it can only happen in the unlikely case that | ||||||
|  |           * an "unsigned int" is smaller than 16 bit a simple test | ||||||
|  |           * is cheap and the correction even cheaper. | ||||||
|  |           */ | ||||||
|  | #ifdef MP_8BIT | ||||||
|  |          /* All "a" < 2^8 have been caught before */ | ||||||
|  |          if (len == 1) { | ||||||
|  |             len++; | ||||||
|  |          } | ||||||
|  | #endif | ||||||
|  |          if ((err = mp_rand(&b, len)) != MP_OKAY) { | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  |          /*
 | ||||||
|  |           * That number might got too big and the witness has to be | ||||||
|  |           * smaller than or equal to "a" | ||||||
|  |           */ | ||||||
|  |          len = mp_count_bits(&b); | ||||||
|  |          if (len > size_a) { | ||||||
|  |             len = len - size_a; | ||||||
|  |             mp_div_2d(&b, len, &b, NULL); | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          /* Although the chance for b <= 3 is miniscule, try again. */ | ||||||
|  |          if (mp_cmp_d(&b,3) != MP_GT) { | ||||||
|  |             ix--; | ||||||
|  |             continue; | ||||||
|  |          } | ||||||
|  |          if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  |          if (res == MP_NO) { | ||||||
|  |             goto LBL_B; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* passed the test */ |    /* passed the test */ | ||||||
| @ -75,6 +358,7 @@ LBL_B: | |||||||
|    mp_clear(&b); |    mp_clear(&b); | ||||||
|    return err; |    return err; | ||||||
| } | } | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /* ref:         $Format:%D$ */ | /* ref:         $Format:%D$ */ | ||||||
|  | |||||||
| @ -24,11 +24,6 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) | |||||||
|    mp_digit res_tab[PRIME_SIZE], step, kstep; |    mp_digit res_tab[PRIME_SIZE], step, kstep; | ||||||
|    mp_int   b; |    mp_int   b; | ||||||
| 
 | 
 | ||||||
|    /* ensure t is valid */ |  | ||||||
|    if ((t <= 0) || (t > PRIME_SIZE)) { |  | ||||||
|       return MP_VAL; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* force positive */ |    /* force positive */ | ||||||
|    a->sign = MP_ZPOS; |    a->sign = MP_ZPOS; | ||||||
| 
 | 
 | ||||||
| @ -141,17 +136,9 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) | |||||||
|          continue; |          continue; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       /* is this prime? */ |       if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { | ||||||
|       for (x = 0; x < t; x++) { |          goto LBL_ERR; | ||||||
|          mp_set(&b, ltm_prime_tab[x]); |  | ||||||
|          if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { |  | ||||||
|             goto LBL_ERR; |  | ||||||
|          } |  | ||||||
|          if (res == MP_NO) { |  | ||||||
|             break; |  | ||||||
|          } |  | ||||||
|       } |       } | ||||||
| 
 |  | ||||||
|       if (res == MP_YES) { |       if (res == MP_YES) { | ||||||
|          break; |          break; | ||||||
|       } |       } | ||||||
|  | |||||||
| @ -17,17 +17,24 @@ | |||||||
| static const struct { | static const struct { | ||||||
|    int k, t; |    int k, t; | ||||||
| } sizes[] = { | } sizes[] = { | ||||||
|    {   128,    28 }, |    {    80,    -1 }, /* Use deterministic algorithm for size <= 80 bits */ | ||||||
|  |    {    81,    39 }, | ||||||
|  |    {    96,    37 }, | ||||||
|  |    {   128,    32 }, | ||||||
|  |    {   160,    27 }, | ||||||
|  |    {   192,    21 }, | ||||||
|    {   256,    16 }, |    {   256,    16 }, | ||||||
|    {   384,    10 }, |    {   384,    10 }, | ||||||
|    {   512,     7 }, |    {   512,     7 }, | ||||||
|    {   640,     6 }, |    {   640,     6 }, | ||||||
|    {   768,     5 }, |    {   768,     5 }, | ||||||
|    {   896,     4 }, |    {   896,     4 }, | ||||||
|    {  1024,     4 } |    {  1024,     4 }, | ||||||
|  |    {  2048,     2 }, | ||||||
|  |    {  4096,     1 }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* returns # of RM trials required for a given bit size */ | /* returns # of RM trials required for a given bit size and max. error of 2^(-96)*/ | ||||||
| int mp_prime_rabin_miller_trials(int size) | int mp_prime_rabin_miller_trials(int size) | ||||||
| { | { | ||||||
|    int x; |    int x; | ||||||
|  | |||||||
							
								
								
									
										413
									
								
								bn_mp_prime_strong_lucas_selfridge.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										413
									
								
								bn_mp_prime_strong_lucas_selfridge.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,413 @@ | |||||||
|  | #include "tommath_private.h" | ||||||
|  | #ifdef BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C | ||||||
|  | 
 | ||||||
|  | /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||||
|  |  * | ||||||
|  |  * LibTomMath is a library that provides multiple-precision | ||||||
|  |  * integer arithmetic as well as number theoretic functionality. | ||||||
|  |  * | ||||||
|  |  * The library was designed directly after the MPI library by | ||||||
|  |  * Michael Fromberger but has been written from scratch with | ||||||
|  |  * additional optimizations in place. | ||||||
|  |  * | ||||||
|  |  * The library is free for all purposes without any express | ||||||
|  |  * guarantee it works. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details | ||||||
|  |  */ | ||||||
|  | #ifndef LTM_USE_FIPS_ONLY | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  8-bit is just too small. You can try the Frobenius test | ||||||
|  |  *  but that frobenius test can fail, too, for the same reason. | ||||||
|  |  */ | ||||||
|  | #ifndef MP_8BIT | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * multiply bigint a with int d and put the result in c | ||||||
|  |  * Like mp_mul_d() but with a signed long as the small input | ||||||
|  |  */ | ||||||
|  | static int s_mp_mul_si(const mp_int *a, long d, mp_int *c) | ||||||
|  | { | ||||||
|  |    mp_int t; | ||||||
|  |    int err, neg = 0; | ||||||
|  | 
 | ||||||
|  |    if ((err = mp_init(&t)) != MP_OKAY) { | ||||||
|  |       return err; | ||||||
|  |    } | ||||||
|  |    if (d < 0) { | ||||||
|  |       neg = 1; | ||||||
|  |       d = -d; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * mp_digit might be smaller than a long, which excludes | ||||||
|  |     * the use of mp_mul_d() here. | ||||||
|  |     */ | ||||||
|  |    if ((err = mp_set_long(&t, (unsigned long) d)) != MP_OKAY) { | ||||||
|  |       goto LBL_MPMULSI_ERR; | ||||||
|  |    } | ||||||
|  |    if ((err = mp_mul(a, &t, c)) != MP_OKAY) { | ||||||
|  |       goto LBL_MPMULSI_ERR; | ||||||
|  |    } | ||||||
|  |    if (neg ==  1) { | ||||||
|  |       c->sign = (a->sign == MP_NEG) ? MP_ZPOS: MP_NEG; | ||||||
|  |    } | ||||||
|  | LBL_MPMULSI_ERR: | ||||||
|  |    mp_clear(&t); | ||||||
|  |    return err; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |     Strong Lucas-Selfridge test. | ||||||
|  |     returns MP_YES if it is a strong L-S prime, MP_NO if it is composite | ||||||
|  | 
 | ||||||
|  |     Code ported from  Thomas Ray Nicely's implementation of the BPSW test | ||||||
|  |     at http://www.trnicely.net/misc/bpsw.html
 | ||||||
|  | 
 | ||||||
|  |     Freeware copyright (C) 2016 Thomas R. Nicely <http://www.trnicely.net>.
 | ||||||
|  |     Released into the public domain by the author, who disclaims any legal | ||||||
|  |     liability arising from its use | ||||||
|  | 
 | ||||||
|  |     The multi-line comments are made by Thomas R. Nicely and are copied verbatim. | ||||||
|  |     Additional comments marked "CZ" (without the quotes) are by the code-portist. | ||||||
|  | 
 | ||||||
|  |     (If that name sounds familiar, he is the guy who found the fdiv bug in the | ||||||
|  |      Pentium (P5x, I think) Intel processor) | ||||||
|  | */ | ||||||
|  | int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) | ||||||
|  | { | ||||||
|  |    /* CZ TODO: choose better variable names! */ | ||||||
|  |    mp_int Dz, gcd, Np1, Uz, Vz, U2mz, V2mz, Qmz, Q2mz, Qkdz, T1z, T2z, T3z, T4z, Q2kdz; | ||||||
|  |    /* CZ TODO: Some of them need the full 32 bit, hence the (temporary) exclusion of MP_8BIT */ | ||||||
|  |    int32_t D, Ds, J, sign, P, Q, r, s, u, Nbits; | ||||||
|  |    int e = MP_OKAY; | ||||||
|  |    int isset; | ||||||
|  | 
 | ||||||
|  |    *result = MP_NO; | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |    Find the first element D in the sequence {5, -7, 9, -11, 13, ...} | ||||||
|  |    such that Jacobi(D,N) = -1 (Selfridge's algorithm). Theory | ||||||
|  |    indicates that, if N is not a perfect square, D will "nearly | ||||||
|  |    always" be "small." Just in case, an overflow trap for D is | ||||||
|  |    included. | ||||||
|  |    */ | ||||||
|  | 
 | ||||||
|  |    if ((e = mp_init_multi(&Dz, &gcd, &Np1, &Uz, &Vz, &U2mz, &V2mz, &Qmz, &Q2mz, &Qkdz, &T1z, &T2z, &T3z, &T4z, &Q2kdz, | ||||||
|  |                           NULL)) != MP_OKAY) { | ||||||
|  |       return e; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    D = 5; | ||||||
|  |    sign = 1; | ||||||
|  | 
 | ||||||
|  |    for (;;) { | ||||||
|  |       Ds   = sign * D; | ||||||
|  |       sign = -sign; | ||||||
|  |       if ((e = mp_set_long(&Dz,(unsigned long) D)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_gcd(a, &Dz, &gcd)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       /* if 1 < GCD < N then N is composite with factor "D", and
 | ||||||
|  |          Jacobi(D,N) is technically undefined (but often returned | ||||||
|  |          as zero). */ | ||||||
|  |       if ((mp_cmp_d(&gcd,1u) == MP_GT) && (mp_cmp(&gcd,a) == MP_LT)) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if (Ds < 0) { | ||||||
|  |          Dz.sign = MP_NEG; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_kronecker(&Dz, a, &J)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (J == -1) { | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  |       D += 2; | ||||||
|  | 
 | ||||||
|  |       if (D > INT_MAX - 2) { | ||||||
|  |          e = MP_VAL; | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    P = 1;              /* Selfridge's choice */ | ||||||
|  |    Q = (1 - Ds) / 4;   /* Required so D = P*P - 4*Q */ | ||||||
|  | 
 | ||||||
|  |    /* NOTE: The conditions (a) N does not divide Q, and
 | ||||||
|  |       (b) D is square-free or not a perfect square, are included by | ||||||
|  |       some authors; e.g., "Prime numbers and computer methods for | ||||||
|  |       factorization," Hans Riesel (2nd ed., 1994, Birkhauser, Boston), | ||||||
|  |       p. 130. For this particular application of Lucas sequences, | ||||||
|  |       these conditions were found to be immaterial. */ | ||||||
|  | 
 | ||||||
|  |    /* Now calculate N - Jacobi(D,N) = N + 1 (even), and calculate the
 | ||||||
|  |       odd positive integer d and positive integer s for which | ||||||
|  |       N + 1 = 2^s*d (similar to the step for N - 1 in Miller's test). | ||||||
|  |       The strong Lucas-Selfridge test then returns N as a strong | ||||||
|  |       Lucas probable prime (slprp) if any of the following | ||||||
|  |       conditions is met: U_d=0, V_d=0, V_2d=0, V_4d=0, V_8d=0, | ||||||
|  |       V_16d=0, ..., etc., ending with V_{2^(s-1)*d}=V_{(N+1)/2}=0 | ||||||
|  |       (all equalities mod N). Thus d is the highest index of U that | ||||||
|  |       must be computed (since V_2m is independent of U), compared | ||||||
|  |       to U_{N+1} for the standard Lucas-Selfridge test; and no | ||||||
|  |       index of V beyond (N+1)/2 is required, just as in the | ||||||
|  |       standard Lucas-Selfridge test. However, the quantity Q^d must | ||||||
|  |       be computed for use (if necessary) in the latter stages of | ||||||
|  |       the test. The result is that the strong Lucas-Selfridge test | ||||||
|  |       has a running time only slightly greater (order of 10 %) than | ||||||
|  |       that of the standard Lucas-Selfridge test, while producing | ||||||
|  |       only (roughly) 30 % as many pseudoprimes (and every strong | ||||||
|  |       Lucas pseudoprime is also a standard Lucas pseudoprime). Thus | ||||||
|  |       the evidence indicates that the strong Lucas-Selfridge test is | ||||||
|  |       more effective than the standard Lucas-Selfridge test, and a | ||||||
|  |       Baillie-PSW test based on the strong Lucas-Selfridge test | ||||||
|  |       should be more reliable. */ | ||||||
|  | 
 | ||||||
|  |    if ((e = mp_add_d(a,1u,&Np1)) != MP_OKAY) { | ||||||
|  |       goto LBL_LS_ERR; | ||||||
|  |    } | ||||||
|  |    s = mp_cnt_lsb(&Np1); | ||||||
|  | 
 | ||||||
|  |    /* CZ
 | ||||||
|  |     * This should round towards zero because | ||||||
|  |     * Thomas R. Nicely used GMP's mpz_tdiv_q_2exp() | ||||||
|  |     * and mp_div_2d() is equivalent. Additionally: | ||||||
|  |     * dividing an even number by two does not produce | ||||||
|  |     * any leftovers. | ||||||
|  |     */ | ||||||
|  |    if ((e = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY) { | ||||||
|  |       goto LBL_LS_ERR; | ||||||
|  |    } | ||||||
|  |    /* We must now compute U_d and V_d. Since d is odd, the accumulated
 | ||||||
|  |       values U and V are initialized to U_1 and V_1 (if the target | ||||||
|  |       index were even, U and V would be initialized instead to U_0=0 | ||||||
|  |       and V_0=2). The values of U_2m and V_2m are also initialized to | ||||||
|  |       U_1 and V_1; the FOR loop calculates in succession U_2 and V_2, | ||||||
|  |       U_4 and V_4, U_8 and V_8, etc. If the corresponding bits | ||||||
|  |       (1, 2, 3, ...) of t are on (the zero bit having been accounted | ||||||
|  |       for in the initialization of U and V), these values are then | ||||||
|  |       combined with the previous totals for U and V, using the | ||||||
|  |       composition formulas for addition of indices. */ | ||||||
|  | 
 | ||||||
|  |    mp_set(&Uz, 1u);    /* U=U_1 */ | ||||||
|  |    mp_set(&Vz, (mp_digit)P);    /* V=V_1 */ | ||||||
|  |    mp_set(&U2mz, 1u);  /* U_1 */ | ||||||
|  |    mp_set(&V2mz, (mp_digit)P);  /* V_1 */ | ||||||
|  | 
 | ||||||
|  |    if (Q < 0) { | ||||||
|  |       Q = -Q; | ||||||
|  |       if ((e = mp_set_long(&Qmz, (unsigned long) Q)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       /* Initializes calculation of Q^d */ | ||||||
|  |       if ((e = mp_set_long(&Qkdz, (unsigned long) Q)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       Qmz.sign = MP_NEG; | ||||||
|  |       Q2mz.sign = MP_NEG; | ||||||
|  |       Qkdz.sign = MP_NEG; | ||||||
|  |       Q = -Q; | ||||||
|  |    } else { | ||||||
|  |       if ((e = mp_set_long(&Qmz, (unsigned long) Q)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       /* Initializes calculation of Q^d */ | ||||||
|  |       if ((e = mp_set_long(&Qkdz, (unsigned long) Q)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    Nbits = mp_count_bits(&Dz); | ||||||
|  |    for (u = 1; u < Nbits; u++) { /* zero bit off, already accounted for */ | ||||||
|  |       /* Formulas for doubling of indices (carried out mod N). Note that
 | ||||||
|  |        * the indices denoted as "2m" are actually powers of 2, specifically | ||||||
|  |        * 2^(ul-1) beginning each loop and 2^ul ending each loop. | ||||||
|  |        * | ||||||
|  |        * U_2m = U_m*V_m | ||||||
|  |        * V_2m = V_m*V_m - 2*Q^m | ||||||
|  |        */ | ||||||
|  | 
 | ||||||
|  |       if ((e = mp_mul(&U2mz,&V2mz,&U2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mod(&U2mz,a,&U2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_sqr(&V2mz,&V2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_sub(&V2mz,&Q2mz,&V2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mod(&V2mz,a,&V2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       /* Must calculate powers of Q for use in V_2m, also for Q^d later */ | ||||||
|  |       if ((e = mp_sqr(&Qmz,&Qmz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       /* prevents overflow */ /* CZ  still necessary without a fixed prealloc'd mem.? */ | ||||||
|  |       if ((e = mp_mod(&Qmz,a,&Qmz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mul_2(&Qmz,&Q2mz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ((isset = mp_get_bit(&Dz,u)) == MP_VAL) { | ||||||
|  |          e = isset; | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if (isset == MP_YES) { | ||||||
|  |          /* Formulas for addition of indices (carried out mod N);
 | ||||||
|  |           * | ||||||
|  |           * U_(m+n) = (U_m*V_n + U_n*V_m)/2 | ||||||
|  |           * V_(m+n) = (V_m*V_n + D*U_m*U_n)/2 | ||||||
|  |           * | ||||||
|  |           * Be careful with division by 2 (mod N)! | ||||||
|  |           */ | ||||||
|  | 
 | ||||||
|  |          if ((e = mp_mul(&U2mz,&Vz,&T1z)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mul(&Uz,&V2mz,&T2z)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mul(&V2mz,&Vz,&T3z)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mul(&U2mz,&Uz,&T4z)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = s_mp_mul_si(&T4z,(long)Ds,&T4z)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_add(&T1z,&T2z,&Uz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if (mp_isodd(&Uz)) { | ||||||
|  |             if ((e = mp_add(&Uz,a,&Uz)) != MP_OKAY) { | ||||||
|  |                goto LBL_LS_ERR; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          /* CZ
 | ||||||
|  |           * This should round towards negative infinity because | ||||||
|  |           * Thomas R. Nicely used GMP's mpz_fdiv_q_2exp(). | ||||||
|  |           * But mp_div_2() does not do so, it is truncating instead. | ||||||
|  |           */ | ||||||
|  |          if ((e = mp_div_2(&Uz,&Uz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((Uz.sign == MP_NEG) && mp_isodd(&Uz)) { | ||||||
|  |             if ((e = mp_sub_d(&Uz,1u,&Uz)) != MP_OKAY) { | ||||||
|  |                goto LBL_LS_ERR; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          if ((e = mp_add(&T3z,&T4z,&Vz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if (mp_isodd(&Vz)) { | ||||||
|  |             if ((e = mp_add(&Vz,a,&Vz)) != MP_OKAY) { | ||||||
|  |                goto LBL_LS_ERR; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          if ((e = mp_div_2(&Vz,&Vz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if (Vz.sign == MP_NEG && mp_isodd(&Vz)) { | ||||||
|  |             if ((e = mp_sub_d(&Vz,1,&Vz)) != MP_OKAY) { | ||||||
|  |                goto LBL_LS_ERR; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mod(&Uz,a,&Uz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mod(&Vz,a,&Vz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          /* Calculating Q^d for later use */ | ||||||
|  |          if ((e = mp_mul(&Qkdz,&Qmz,&Qkdz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mod(&Qkdz,a,&Qkdz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    /* If U_d or V_d is congruent to 0 mod N, then N is a prime or a
 | ||||||
|  |       strong Lucas pseudoprime. */ | ||||||
|  |    if (mp_iszero(&Uz) || mp_iszero(&Vz)) { | ||||||
|  |       *result = MP_YES; | ||||||
|  |       goto LBL_LS_ERR; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    /* NOTE: Ribenboim ("The new book of prime number records," 3rd ed.,
 | ||||||
|  |       1995/6) omits the condition V0 on p.142, but includes it on | ||||||
|  |       p. 130. The condition is NECESSARY; otherwise the test will | ||||||
|  |       return false negatives---e.g., the primes 29 and 2000029 will be | ||||||
|  |       returned as composite. */ | ||||||
|  | 
 | ||||||
|  |    /* Otherwise, we must compute V_2d, V_4d, V_8d, ..., V_{2^(s-1)*d}
 | ||||||
|  |       by repeated use of the formula V_2m = V_m*V_m - 2*Q^m. If any of | ||||||
|  |       these are congruent to 0 mod N, then N is a prime or a strong | ||||||
|  |       Lucas pseudoprime. */ | ||||||
|  | 
 | ||||||
|  |    /* Initialize 2*Q^(d*2^r) for V_2m */ | ||||||
|  |    if ((e = mp_mul_2(&Qkdz,&Q2kdz)) != MP_OKAY) { | ||||||
|  |       goto LBL_LS_ERR; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    for (r = 1; r < s; r++) { | ||||||
|  |       if ((e = mp_sqr(&Vz,&Vz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_sub(&Vz,&Q2kdz,&Vz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if ((e = mp_mod(&Vz,a,&Vz)) != MP_OKAY) { | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       if (mp_iszero(&Vz)) { | ||||||
|  |          *result = MP_YES; | ||||||
|  |          goto LBL_LS_ERR; | ||||||
|  |       } | ||||||
|  |       /* Calculate Q^{d*2^r} for next r (final iteration irrelevant). */ | ||||||
|  |       if (r < (s - 1)) { | ||||||
|  |          if ((e = mp_sqr(&Qkdz,&Qkdz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mod(&Qkdz,a,&Qkdz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |          if ((e = mp_mul_2(&Qkdz,&Q2kdz)) != MP_OKAY) { | ||||||
|  |             goto LBL_LS_ERR; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | LBL_LS_ERR: | ||||||
|  |    mp_clear_multi(&Q2kdz, &T4z, &T3z, &T2z, &T1z, &Qkdz, &Q2mz, &Qmz, &V2mz, &U2mz, &Vz, &Uz, &Np1, &gcd, &Dz, NULL); | ||||||
|  |    return e; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ref:         $Format:%D$ */ | ||||||
|  | /* git commit:  $Format:%H$ */ | ||||||
|  | /* commit time: $Format:%ai$ */ | ||||||
							
								
								
									
										10292
									
								
								callgraph.txt
									
									
									
									
									
								
							
							
						
						
									
										10292
									
								
								callgraph.txt
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										88
									
								
								demo/demo.c
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								demo/demo.c
									
									
									
									
									
								
							| @ -118,6 +118,35 @@ static struct mp_jacobi_st jacobi[] = { | |||||||
|    { 7, {  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1, -1 } }, |    { 7, {  1, -1,  1, -1, -1,  0,  1,  1, -1,  1, -1, -1,  0,  1,  1, -1 } }, | ||||||
|    { 9, { -1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1 } }, |    { 9, { -1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  1 } }, | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | struct mp_kronecker_st { | ||||||
|  |    long n; | ||||||
|  |    int c[21]; | ||||||
|  | }; | ||||||
|  | static struct mp_kronecker_st kronecker[] = { | ||||||
|  |    /*-10, -9, -8, -7,-6, -5, -4, -3, -2, -1, 0, 1,  2,  3, 4,  5,  6,  7,  8, 9, 10*/ | ||||||
|  |    { -10, {  0, -1,  0, -1, 0,  0,  0,  1,  0, -1, 0, 1,  0, -1, 0,  0,  0,  1,  0, 1,  0  } }, | ||||||
|  |    {  -9, { -1,  0, -1,  1, 0, -1, -1,  0, -1, -1, 0, 1,  1,  0, 1,  1,  0, -1,  1, 0,  1  } }, | ||||||
|  |    {  -8, {  0, -1,  0,  1, 0,  1,  0, -1,  0, -1, 0, 1,  0,  1, 0, -1,  0, -1,  0, 1,  0  } }, | ||||||
|  |    {  -7, {  1, -1, -1,  0, 1,  1, -1,  1, -1, -1, 0, 1,  1, -1, 1, -1, -1,  0,  1, 1, -1  } }, | ||||||
|  |    {  -6, {  0,  0,  0, -1, 0, -1,  0,  0,  0, -1, 0, 1,  0,  0, 0,  1,  0,  1,  0, 0,  0  } }, | ||||||
|  |    {  -5, {  0, -1,  1, -1, 1,  0, -1, -1,  1, -1, 0, 1, -1,  1, 1,  0, -1,  1, -1, 1,  0  } }, | ||||||
|  |    {  -4, {  0, -1,  0,  1, 0, -1,  0,  1,  0, -1, 0, 1,  0, -1, 0,  1,  0, -1,  0, 1,  0  } }, | ||||||
|  |    {  -3, { -1,  0,  1, -1, 0,  1, -1,  0,  1, -1, 0, 1, -1,  0, 1, -1,  0,  1, -1, 0,  1  } }, | ||||||
|  |    {  -2, {  0, -1,  0,  1, 0,  1,  0, -1,  0, -1, 0, 1,  0,  1, 0, -1,  0, -1,  0, 1,  0  } }, | ||||||
|  |    {  -1, { -1, -1, -1,  1, 1, -1, -1,  1, -1, -1, 1, 1,  1, -1, 1,  1, -1, -1,  1, 1,  1  } }, | ||||||
|  |    {   0, {  0,  0,  0,  0, 0,  0,  0,  0,  0,  1, 0, 1,  0,  0, 0,  0,  0,  0,  0, 0,  0  } }, | ||||||
|  |    {   1, {  1,  1,  1,  1, 1,  1,  1,  1,  1,  1, 1, 1,  1,  1, 1,  1,  1,  1,  1, 1,  1  } }, | ||||||
|  |    {   2, {  0,  1,  0,  1, 0, -1,  0, -1,  0,  1, 0, 1,  0, -1, 0, -1,  0,  1,  0, 1,  0  } }, | ||||||
|  |    {   3, {  1,  0, -1, -1, 0, -1,  1,  0, -1,  1, 0, 1, -1,  0, 1, -1,  0, -1, -1, 0,  1  } }, | ||||||
|  |    {   4, {  0,  1,  0,  1, 0,  1,  0,  1,  0,  1, 0, 1,  0,  1, 0,  1,  0,  1,  0, 1,  0  } }, | ||||||
|  |    {   5, {  0,  1, -1, -1, 1,  0,  1, -1, -1,  1, 0, 1, -1, -1, 1,  0,  1, -1, -1, 1,  0  } }, | ||||||
|  |    {   6, {  0,  0,  0, -1, 0,  1,  0,  0,  0,  1, 0, 1,  0,  0, 0,  1,  0, -1,  0, 0,  0  } }, | ||||||
|  |    {   7, { -1,  1,  1,  0, 1, -1,  1,  1,  1,  1, 0, 1,  1,  1, 1, -1,  1,  0,  1, 1, -1  } }, | ||||||
|  |    {   8, {  0,  1,  0,  1, 0, -1,  0, -1,  0,  1, 0, 1,  0, -1, 0, -1,  0,  1,  0, 1,  0  } }, | ||||||
|  |    {   9, {  1,  0,  1,  1, 0,  1,  1,  0,  1,  1, 0, 1,  1,  0, 1,  1,  0,  1,  1, 0,  1  } }, | ||||||
|  |    {  10, {  0,  1,  0, -1, 0,  0,  0,  1,  0,  1, 0, 1,  0,  1, 0,  0,  0, -1,  0, 1,  0  } } | ||||||
|  | }; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if LTM_DEMO_TEST_VS_MTEST != 0 | #if LTM_DEMO_TEST_VS_MTEST != 0 | ||||||
| @ -133,6 +162,7 @@ int main(void) | |||||||
|             gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n; |             gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n; | ||||||
| #else | #else | ||||||
|    unsigned long s, t; |    unsigned long s, t; | ||||||
|  |    long k, m; | ||||||
|    unsigned long long q, r; |    unsigned long long q, r; | ||||||
|    mp_digit mp; |    mp_digit mp; | ||||||
|    int i, n, err, should; |    int i, n, err, should; | ||||||
| @ -261,6 +291,43 @@ int main(void) | |||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |    mp_set_int(&a, 0); | ||||||
|  |    mp_set_int(&b, 1u); | ||||||
|  |    if ((err = mp_kronecker(&a, &b, &i)) != MP_OKAY) { | ||||||
|  |       printf("Failed executing mp_kronecker(0 | 1) %s.\n", mp_error_to_string(err)); | ||||||
|  |       return EXIT_FAILURE; | ||||||
|  |    } | ||||||
|  |    if (i != 1) { | ||||||
|  |       printf("Failed trivial mp_kronecker(0 | 1) %d != 1\n", i); | ||||||
|  |       return EXIT_FAILURE; | ||||||
|  |    } | ||||||
|  |    for (cnt = 0; cnt < (int)(sizeof(kronecker)/sizeof(kronecker[0])); ++cnt) { | ||||||
|  |       k = kronecker[cnt].n; | ||||||
|  |       if (k < 0) { | ||||||
|  |          mp_set_int(&a, (unsigned long)(-k)); | ||||||
|  |          mp_neg(&a, &a); | ||||||
|  |       } else { | ||||||
|  |          mp_set_int(&a, (unsigned long) k); | ||||||
|  |       } | ||||||
|  |       /* only test positive values of a */ | ||||||
|  |       for (m = -10; m <= 10; m++) { | ||||||
|  |          if (m < 0) { | ||||||
|  |             mp_set_int(&b,(unsigned long)(-m)); | ||||||
|  |             mp_neg(&b, &b); | ||||||
|  |          } else { | ||||||
|  |             mp_set_int(&b, (unsigned long) m); | ||||||
|  |          } | ||||||
|  |          if ((err = mp_kronecker(&a, &b, &i)) != MP_OKAY) { | ||||||
|  |             printf("Failed executing mp_kronecker(%ld | %ld) %s.\n", kronecker[cnt].n, m, mp_error_to_string(err)); | ||||||
|  |             return EXIT_FAILURE; | ||||||
|  |          } | ||||||
|  |          if (err == MP_OKAY && i != kronecker[cnt].c[m + 10]) { | ||||||
|  |             printf("Failed trivial mp_kronecker(%ld | %ld) %d != %d\n", kronecker[cnt].n, m, i, kronecker[cnt].c[m + 10]); | ||||||
|  |             return EXIT_FAILURE; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|    /* test mp_complement */ |    /* test mp_complement */ | ||||||
|    printf("\n\nTesting: mp_complement"); |    printf("\n\nTesting: mp_complement"); | ||||||
|    for (i = 0; i < 1000; ++i) { |    for (i = 0; i < 1000; ++i) { | ||||||
| @ -604,6 +671,27 @@ int main(void) | |||||||
|    } |    } | ||||||
|    printf("\n"); |    printf("\n"); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |    /* strong Miller-Rabin pseudoprime to the first 200 primes (F. Arnault) */ | ||||||
|  |    puts("Testing mp_prime_is_prime() with Arnault's pseudoprime  803...901 \n"); | ||||||
|  |    mp_read_radix(&a, | ||||||
|  |                  "91xLNF3roobhzgTzoFIG6P13ZqhOVYSN60Fa7Cj2jVR1g0k89zdahO9/kAiRprpfO1VAp1aBHucLFV/qLKLFb+zonV7R2Vxp1K13ClwUXStpV0oxTNQVjwybmFb5NBEHImZ6V7P6+udRJuH8VbMEnS0H8/pSqQrg82OoQQ2fPpAk6G1hkjqoCv5s/Yr", | ||||||
|  |                  64); | ||||||
|  |    mp_prime_is_prime(&a, 8, &cnt); | ||||||
|  |    if (cnt == MP_YES) { | ||||||
|  |       printf("Arnault's pseudoprime is not prime but mp_prime_is_prime says it is.\n"); | ||||||
|  |       return EXIT_FAILURE; | ||||||
|  |    } | ||||||
|  |    /* About the same size as Arnault's pseudoprime */ | ||||||
|  |    puts("Testing mp_prime_is_prime() with certified prime 2^1119 + 53\n"); | ||||||
|  |    mp_set(&a,1u); | ||||||
|  |    mp_mul_2d(&a,1119,&a); | ||||||
|  |    mp_add_d(&a,53,&a); | ||||||
|  |    mp_prime_is_prime(&a, 8, &cnt); | ||||||
|  |    if (cnt == MP_NO) { | ||||||
|  |       printf("A certified prime is a prime but mp_prime_is_prime says it not.\n"); | ||||||
|  |       return EXIT_FAILURE; | ||||||
|  |    } | ||||||
|    for (ix = 16; ix < 128; ix++) { |    for (ix = 16; ix < 128; ix++) { | ||||||
|       printf("Testing (    safe-prime): %9d bits    \r", ix); |       printf("Testing (    safe-prime): %9d bits    \r", ix); | ||||||
|       fflush(stdout); |       fflush(stdout); | ||||||
|  | |||||||
| @ -103,6 +103,10 @@ int main(void) | |||||||
|    uint64_t tt, gg, CLK_PER_SEC; |    uint64_t tt, gg, CLK_PER_SEC; | ||||||
|    FILE *log, *logb, *logc, *logd; |    FILE *log, *logb, *logc, *logd; | ||||||
|    mp_int a, b, c, d, e, f; |    mp_int a, b, c, d, e, f; | ||||||
|  | #ifdef LTM_TIMING_PRIME_IS_PRIME | ||||||
|  |    const char *name; | ||||||
|  |    int m; | ||||||
|  | #endif | ||||||
|    int n, cnt, ix, old_kara_m, old_kara_s, old_toom_m, old_toom_s; |    int n, cnt, ix, old_kara_m, old_kara_s, old_toom_m, old_toom_s; | ||||||
|    unsigned rr; |    unsigned rr; | ||||||
| 
 | 
 | ||||||
| @ -121,6 +125,42 @@ int main(void) | |||||||
|    CLK_PER_SEC = TIMFUNC() - CLK_PER_SEC; |    CLK_PER_SEC = TIMFUNC() - CLK_PER_SEC; | ||||||
| 
 | 
 | ||||||
|    printf("CLK_PER_SEC == %" PRIu64 "\n", CLK_PER_SEC); |    printf("CLK_PER_SEC == %" PRIu64 "\n", CLK_PER_SEC); | ||||||
|  | 
 | ||||||
|  | #ifdef LTM_TIMING_PRIME_IS_PRIME | ||||||
|  |    for (m = 0; m < 2; ++m) { | ||||||
|  |       if (m == 0) { | ||||||
|  |          name = "    Arnault"; | ||||||
|  |          mp_read_radix(&a, | ||||||
|  |                        "91xLNF3roobhzgTzoFIG6P13ZqhOVYSN60Fa7Cj2jVR1g0k89zdahO9/kAiRprpfO1VAp1aBHucLFV/qLKLFb+zonV7R2Vxp1K13ClwUXStpV0oxTNQVjwybmFb5NBEHImZ6V7P6+udRJuH8VbMEnS0H8/pSqQrg82OoQQ2fPpAk6G1hkjqoCv5s/Yr", | ||||||
|  |                        64); | ||||||
|  |       } else { | ||||||
|  |          name = "2^1119 + 53"; | ||||||
|  |          mp_set(&a,1u); | ||||||
|  |          mp_mul_2d(&a,1119,&a); | ||||||
|  |          mp_add_d(&a,53,&a); | ||||||
|  |       } | ||||||
|  |       cnt = mp_prime_rabin_miller_trials(mp_count_bits(&a)); | ||||||
|  |       ix = -cnt; | ||||||
|  |       for (; cnt >= ix; cnt += ix) { | ||||||
|  |          rr = 0u; | ||||||
|  |          tt = UINT64_MAX; | ||||||
|  |          do { | ||||||
|  |             gg = TIMFUNC(); | ||||||
|  |             DO(mp_prime_is_prime(&a, cnt, &n)); | ||||||
|  |             gg = (TIMFUNC() - gg) >> 1; | ||||||
|  |             if (tt > gg) | ||||||
|  |                tt = gg; | ||||||
|  |             if ((m == 0) && (n == MP_YES)) { | ||||||
|  |                printf("Arnault's pseudoprime is not prime but mp_prime_is_prime says it is.\n"); | ||||||
|  |                return EXIT_FAILURE; | ||||||
|  |             } | ||||||
|  |          } while (++rr < 100u); | ||||||
|  |          printf("Prime-check\t%s(%2d) => %9" PRIu64 "/sec, %9" PRIu64 " cycles\n", | ||||||
|  |                 name, cnt, CLK_PER_SEC / tt, tt); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|    log = FOPEN("logs/add.log", "w"); |    log = FOPEN("logs/add.log", "w"); | ||||||
|    for (cnt = 8; cnt <= 128; cnt += 8) { |    for (cnt = 8; cnt <= 128; cnt += 8) { | ||||||
|       SLEEP; |       SLEEP; | ||||||
|  | |||||||
							
								
								
									
										153
									
								
								doc/bn.tex
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								doc/bn.tex
									
									
									
									
									
								
							| @ -152,7 +152,7 @@ myprng | mtest/mtest | test | |||||||
| 
 | 
 | ||||||
| This will output a row of numbers that are increasing.  Each column is a different test (such as addition, multiplication, etc) | This will output a row of numbers that are increasing.  Each column is a different test (such as addition, multiplication, etc) | ||||||
| that is being performed.  The numbers represent how many times the test was invoked.  If an error is detected the program | that is being performed.  The numbers represent how many times the test was invoked.  If an error is detected the program | ||||||
| will exit with a dump of the relevent numbers it was working with. | will exit with a dump of the relevant numbers it was working with. | ||||||
| 
 | 
 | ||||||
| \section{Build Configuration} | \section{Build Configuration} | ||||||
| LibTomMath can configured at build time in three phases we shall call ``depends'', ``tweaks'' and ``trims''. | LibTomMath can configured at build time in three phases we shall call ``depends'', ``tweaks'' and ``trims''. | ||||||
| @ -291,7 +291,7 @@ exponentiations.  It depends largely on the processor, compiler and the moduli b | |||||||
| 
 | 
 | ||||||
| Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern.  However, | Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern.  However, | ||||||
| on the other side of the coin LibTomMath offers you a totally free (public domain) well structured math library | on the other side of the coin LibTomMath offers you a totally free (public domain) well structured math library | ||||||
| that is very flexible, complete and performs well in resource contrained environments.  Fast RSA for example can | that is very flexible, complete and performs well in resource constrained environments.  Fast RSA for example can | ||||||
| be performed with as little as 8KB of ram for data (again depending on build options). | be performed with as little as 8KB of ram for data (again depending on build options). | ||||||
| 
 | 
 | ||||||
| \chapter{Getting Started with LibTomMath} | \chapter{Getting Started with LibTomMath} | ||||||
| @ -693,7 +693,7 @@ int mp_count_bits(const mp_int *a); | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| \section{Small Constants} | \section{Small Constants} | ||||||
| Setting mp\_ints to small constants is a relatively common operation.  To accomodate these instances there are two | Setting mp\_ints to small constants is a relatively common operation.  To accommodate these instances there are two | ||||||
| small constant assignment functions.  The first function is used to set a single digit constant while the second sets | small constant assignment functions.  The first function is used to set a single digit constant while the second sets | ||||||
| an ISO C style ``unsigned long'' constant.  The reason for both functions is efficiency.  Setting a single digit is quick but the | an ISO C style ``unsigned long'' constant.  The reason for both functions is efficiency.  Setting a single digit is quick but the | ||||||
| domain of a digit can change (it's always at least $0 \ldots 127$). | domain of a digit can change (it's always at least $0 \ldots 127$). | ||||||
| @ -797,7 +797,7 @@ number == 654321 | |||||||
| int mp_set_long (mp_int * a, unsigned long b); | int mp_set_long (mp_int * a, unsigned long b); | ||||||
| \end{alltt} | \end{alltt} | ||||||
| 
 | 
 | ||||||
| This will assign the value of the platform-dependant sized variable $b$ to the mp\_int $a$. | This will assign the value of the platform-dependent sized variable $b$ to the mp\_int $a$. | ||||||
| 
 | 
 | ||||||
| To get the ``unsigned long'' copy of an mp\_int the following function can be used. | To get the ``unsigned long'' copy of an mp\_int the following function can be used. | ||||||
| 
 | 
 | ||||||
| @ -1222,6 +1222,15 @@ int mp_tc_xor (mp_int * a, mp_int * b, mp_int * c); | |||||||
| The compute $c = a \odot b$ as above if both $a$ and $b$ are positive, negative values are converted into their two-complement representation first. This can be used to implement arbitrary-precision two-complement integers together with the arithmetic right-shift at page \ref{arithrightshift}. | The compute $c = a \odot b$ as above if both $a$ and $b$ are positive, negative values are converted into their two-complement representation first. This can be used to implement arbitrary-precision two-complement integers together with the arithmetic right-shift at page \ref{arithrightshift}. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | \subsection{Bit Picking} | ||||||
|  | \index{mp\_get\_bit} | ||||||
|  | \begin{alltt} | ||||||
|  | int mp_get_bit(mp_int *a, int b) | ||||||
|  | \end{alltt} | ||||||
|  | 
 | ||||||
|  | Pick a bit: returns \texttt{MP\_YES} if the bit at position $b$ (0-index) is set, that is if it is 1 (one), \texttt{MP\_NO} | ||||||
|  | if the bit is 0 (zero) and \texttt{MP\_VAL} if $b < 0$. | ||||||
|  | 
 | ||||||
| \section{Addition and Subtraction} | \section{Addition and Subtraction} | ||||||
| 
 | 
 | ||||||
| To compute an addition or subtraction the following two functions can be used. | To compute an addition or subtraction the following two functions can be used. | ||||||
| @ -1613,9 +1622,9 @@ a single final reduction to correct for the normalization and the fast reduction | |||||||
| 
 | 
 | ||||||
| For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}. | For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}. | ||||||
| 
 | 
 | ||||||
| \section{Restricted Dimminished Radix} | \section{Restricted Diminished Radix} | ||||||
| 
 | 
 | ||||||
| ``Dimminished Radix'' reduction refers to reduction with respect to moduli that are ameniable to simple | ``Diminished Radix'' reduction refers to reduction with respect to moduli that are amenable to simple | ||||||
| digit shifting and small multiplications.  In this case the ``restricted'' variant refers to moduli of the | digit shifting and small multiplications.  In this case the ``restricted'' variant refers to moduli of the | ||||||
| form $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$). | form $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$). | ||||||
| 
 | 
 | ||||||
| @ -1636,8 +1645,8 @@ int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); | |||||||
| \end{alltt} | \end{alltt} | ||||||
| 
 | 
 | ||||||
| This reduces $a$ in place modulo $b$ with the pre--computed value $mp$.  $b$ must be of a restricted | This reduces $a$ in place modulo $b$ with the pre--computed value $mp$.  $b$ must be of a restricted | ||||||
| dimminished radix form and $a$ must be in the range $0 \le a < b^2$.  Dimminished radix reductions are | diminished radix form and $a$ must be in the range $0 \le a < b^2$.  Diminished radix reductions are | ||||||
| much faster than both Barrett and Montgomery reductions as they have a much lower asymtotic running time. | much faster than both Barrett and Montgomery reductions as they have a much lower asymptotic running time. | ||||||
| 
 | 
 | ||||||
| Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA or | Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA or | ||||||
| BBS cryptographic purposes.  This reduction algorithm is useful for Diffie-Hellman and ECC where fixed | BBS cryptographic purposes.  This reduction algorithm is useful for Diffie-Hellman and ECC where fixed | ||||||
| @ -1646,7 +1655,7 @@ primes are acceptable. | |||||||
| Note that unlike Montgomery reduction there is no normalization process.  The result of this function is | Note that unlike Montgomery reduction there is no normalization process.  The result of this function is | ||||||
| equal to the correct residue. | equal to the correct residue. | ||||||
| 
 | 
 | ||||||
| \section{Unrestricted Dimminshed Radix} | \section{Unrestricted Diminished Radix} | ||||||
| 
 | 
 | ||||||
| Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the | Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the | ||||||
| form $2^k - p$ for $0 < p < \beta$.  In this sense the unrestricted reductions are more flexible as they | form $2^k - p$ for $0 < p < \beta$.  In this sense the unrestricted reductions are more flexible as they | ||||||
| @ -1731,8 +1740,8 @@ $X$ the operation is performed as $Y \equiv (G^{-1} \mbox{ mod }P)^{\vert X \ver | |||||||
| $gcd(G, P) = 1$. | $gcd(G, P) = 1$. | ||||||
| 
 | 
 | ||||||
| This function is actually a shell around the two internal exponentiation functions.  This routine will automatically | This function is actually a shell around the two internal exponentiation functions.  This routine will automatically | ||||||
| detect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix based exponentiation can be used.  Generally | detect when Barrett, Montgomery, Restricted and Unrestricted Diminished Radix based exponentiation can be used.  Generally | ||||||
| moduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations.  Followed by Montgomery | moduli of the a ``restricted diminished radix'' form lead to the fastest modular exponentiations.  Followed by Montgomery | ||||||
| and the other two algorithms. | and the other two algorithms. | ||||||
| 
 | 
 | ||||||
| \section{Modulus a Power of Two} | \section{Modulus a Power of Two} | ||||||
| @ -1815,6 +1824,92 @@ require ten tests whereas a 1024-bit number would only require four tests. | |||||||
| 
 | 
 | ||||||
| You should always still perform a trial division before a Miller-Rabin test though. | You should always still perform a trial division before a Miller-Rabin test though. | ||||||
| 
 | 
 | ||||||
|  | A small table, broke in two for typographical reasons, with the number of rounds of Miller-Rabin tests is shown below. | ||||||
|  | The first column is the number of bits $b$ in the prime $p = 2^b$, the numbers in the first row represent the  | ||||||
|  | probability that the number that all of the Miller-Rabin tests deemed a pseudoprime is actually a composite. There is a deterministic test for numbers smaller than $2^{80}$. | ||||||
|  | 
 | ||||||
|  | \begin{table}[h] | ||||||
|  | \begin{center} | ||||||
|  | \begin{tabular}{c c c c c c c} | ||||||
|  | \textbf{bits} & $\mathbf{2^{-80}}$ & $\mathbf{2^{-96}}$ & $\mathbf{2^{-112}}$ & $\mathbf{2^{-128}}$ & $\mathbf{2^{-160}}$ & $\mathbf{2^{-192}}$ \\ | ||||||
|  | 80    & 31 & 39 & 47 & 55 & 71 & 87  \\ | ||||||
|  | 96    & 29 & 37 & 45 & 53 & 69 & 85  \\ | ||||||
|  | 128   & 24 & 32 & 40 & 48 & 64 & 80  \\ | ||||||
|  | 160   & 19 & 27 & 35 & 43 & 59 & 75  \\ | ||||||
|  | 192   & 15 & 21 & 29 & 37 & 53 & 69  \\ | ||||||
|  | 256   & 10 & 15 & 20 & 27 & 43 & 59  \\ | ||||||
|  | 384   & 7  & 9  & 12 & 16 & 25 & 38  \\ | ||||||
|  | 512   & 5  & 7  & 9  & 12 & 18 & 26  \\ | ||||||
|  | 768   & 4  & 5  & 6  & 8  & 11 & 16  \\ | ||||||
|  | 1024  & 3  & 4  & 5  & 6  & 9  & 12  \\ | ||||||
|  | 1536  & 2  & 3  & 3  & 4  & 6  & 8   \\ | ||||||
|  | 2048  & 2  & 2  & 3  & 3  & 4  & 6   \\ | ||||||
|  | 3072  & 1  & 2  & 2  & 2  & 3  & 4   \\ | ||||||
|  | 4096  & 1  & 1  & 2  & 2  & 2  & 3   \\ | ||||||
|  | 6144  & 1  & 1  & 1  & 1  & 2  & 2   \\ | ||||||
|  | 8192  & 1  & 1  & 1  & 1  & 2  & 2   \\ | ||||||
|  | 12288 & 1  & 1  & 1  & 1  & 1  & 1   \\ | ||||||
|  | 16384 & 1  & 1  & 1  & 1  & 1  & 1   \\ | ||||||
|  | 24576 & 1  & 1  & 1  & 1  & 1  & 1   \\ | ||||||
|  | 32768 & 1  & 1  & 1  & 1  & 1  & 1 | ||||||
|  | \end{tabular} | ||||||
|  | \caption{ Number of Miller-Rabin rounds. Part I } \label{table:millerrabinrunsp1} | ||||||
|  | \end{center} | ||||||
|  | \end{table} | ||||||
|  | \newpage | ||||||
|  | \begin{table}[h] | ||||||
|  | \begin{center} | ||||||
|  | \begin{tabular}{c c c c c c c c} | ||||||
|  | \textbf{bits} &$\mathbf{2^{-224}}$ & $\mathbf{2^{-256}}$ & $\mathbf{2^{-288}}$ & $\mathbf{2^{-320}}$ & $\mathbf{2^{-352}}$ & $\mathbf{2^{-384}}$ & $\mathbf{2^{-416}}$\\ | ||||||
|  | 80    & 103 & 119 & 135 & 151 & 167 & 183 & 199 \\ | ||||||
|  | 96    & 101 & 117 & 133 & 149 & 165 & 181 & 197 \\ | ||||||
|  | 128   & 96  & 112 & 128 & 144 & 160 & 176 & 192 \\ | ||||||
|  | 160   & 91  & 107 & 123 & 139 & 155 & 171 & 187 \\ | ||||||
|  | 192   & 85  & 101 & 117 & 133 & 149 & 165 & 181 \\ | ||||||
|  | 256   & 75  & 91  & 107 & 123 & 139 & 155 & 171 \\ | ||||||
|  | 384   & 54  & 70  & 86  & 102 & 118 & 134 & 150 \\ | ||||||
|  | 512   & 36  & 49  & 65  & 81  & 97  & 113 & 129 \\ | ||||||
|  | 768   & 22  & 29  & 37  & 47  & 58  & 70  & 86  \\ | ||||||
|  | 1024  & 16  & 21  & 26  & 33  & 40  & 48  & 58  \\ | ||||||
|  | 1536  & 10  & 13  & 17  & 21  & 25  & 30  & 35  \\ | ||||||
|  | 2048  & 8   & 10  & 13  & 15  & 18  & 22  & 26  \\ | ||||||
|  | 3072  & 5   & 7   & 8	& 10  & 12  & 14  & 17  \\ | ||||||
|  | 4096  & 4   & 5   & 6	& 8   & 9   & 11  & 12  \\ | ||||||
|  | 6144  & 3   & 4   & 4	& 5   & 6   & 7   & 8	\\ | ||||||
|  | 8192  & 2   & 3   & 3	& 4   & 5   & 6   & 6	\\ | ||||||
|  | 12288 & 2   & 2   & 2	& 3   & 3   & 4   & 4	\\ | ||||||
|  | 16384 & 1   & 2   & 2	& 2   & 3   & 3   & 3	\\ | ||||||
|  | 24576 & 1   & 1   & 2	& 2   & 2   & 2   & 2	\\ | ||||||
|  | 32768 & 1   & 1   & 1	& 1   & 2   & 2   & 2 | ||||||
|  | \end{tabular} | ||||||
|  | \caption{ Number of Miller-Rabin rounds. Part II } \label{table:millerrabinrunsp2} | ||||||
|  | \end{center} | ||||||
|  | \end{table} | ||||||
|  | 
 | ||||||
|  | Determining the probability needed to pick the right column is a bit harder. Fips 186.4, for example has $2^{-80}$ for $512$ bit large numbers, $2^{-112}$ for $1024$ bits, and $2^{128}$ for $1536$ bits. It can be seen in table \ref{table:millerrabinrunsp1} that those combinations follow the diagonal from $(512,2^{-80})$ downwards and to the right to gain a lower probabilty of getting a composite declared a pseudoprime for the same amount of work or less. | ||||||
|  | 
 | ||||||
|  | If this version of the library has the strong Lucas-Selfridge and/or the Frobenius-Underwood test implemented only one or two rounds of the Miller-Rabin test with a random base is necesssary for numbers larger than or equal to $1024$ bits. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | \section{Strong Lucas-Selfridge Test} | ||||||
|  | \index{mp\_prime\_strong\_lucas\_selfridge} | ||||||
|  | \begin{alltt} | ||||||
|  | int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) | ||||||
|  | \end{alltt} | ||||||
|  | Performs a strong Lucas-Selfridge test. The strong Lucas-Selfridge test together with the Rabin-Miler test with bases $2$ and $3$ resemble the BPSW test. The single internal use is a compile-time option in \texttt{mp\_prime\_is\_prime} and can be excluded | ||||||
|  | from the Libtommath build if not needed. | ||||||
|  | 
 | ||||||
|  | \section{Frobenius (Underwood)  Test} | ||||||
|  | \index{mp\_prime\_frobenius\_underwood} | ||||||
|  | \begin{alltt} | ||||||
|  | int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||||
|  | \end{alltt} | ||||||
|  | Performs the variant of the Frobenius test as described by Paul Underwood. The single internal use is in | ||||||
|  | \texttt{mp\_prime\_is\_prime} for \texttt{MP\_8BIT} only but can be included at build-time for all other sizes | ||||||
|  | if the preprocessor macro \texttt{LTM\_USE\_FROBENIUS\_TEST} is defined. | ||||||
|  | 
 | ||||||
|  | It returns \texttt{MP\_ITER} if the number of iterations is exhausted, assumes a composite as the input and sets \texttt{result} accordingly. This will reduce the set of available pseudoprimes by a very small amount: test with large datasets (more than $10^{10}$ numbers, both randomly chosen and sequences of odd numbers with a random start point) found only 31 (thirty-one) numbers with $a > 120$ and none at all with just an additional simple check for divisors $d < 2^8$. | ||||||
|  | 
 | ||||||
| \section{Primality Testing} | \section{Primality Testing} | ||||||
| Testing if a number is a square can be done a bit faster than just by calculating the square root. It is used by the primality testing function described below. | Testing if a number is a square can be done a bit faster than just by calculating the square root. It is used by the primality testing function described below. | ||||||
| \index{mp\_is\_square} | \index{mp\_is\_square} | ||||||
| @ -1827,16 +1922,29 @@ int mp_is_square(const mp_int *arg, int *ret); | |||||||
| \begin{alltt} | \begin{alltt} | ||||||
| int mp_prime_is_prime (mp_int * a, int t, int *result) | int mp_prime_is_prime (mp_int * a, int t, int *result) | ||||||
| \end{alltt} | \end{alltt} | ||||||
| This will perform a trial division followed by $t$ rounds of Miller-Rabin tests on $a$ and store the result in $result$. | This will perform a trial division followed by two rounds of Miller-Rabin with bases 2 and 3 and a Lucas-Selfridge test. The Lucas-Selfridge test is replaced with a Frobenius-Underwood for \texttt{MP\_8BIT}. The Frobenius-Underwood test for all other sizes is available as a compile-time option with the preprocessor macro \texttt{LTM\_USE\_FROBENIUS\_TEST}. See file | ||||||
| If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero.  Note that $t$ is bounded by | \texttt{bn\_mp\_prime\_is\_prime.c} for the necessary details. It shall be noted that both functions are much slower than | ||||||
| $1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$). | the Miller-Rabin test and if speed is an essential issue, the macro \texttt{LTM\_USE\_FIPS\_ONLY} switches both functions, the Frobenius-Underwood test and the Lucas-Selfridge test off and their code will not even be compiled into the library. | ||||||
|  | 
 | ||||||
|  | If $t$ is set to a positive value $t$ additional rounds of the Miller-Rabin test with random bases will be performed to allow for Fips 186.4 (vid.~p.~126ff) compliance. The function \texttt{mp\_prime\_rabin\_miller\_trials} can be used to determine the number of rounds. It is vital that the function \texttt{mp\_rand()} has a cryptographically strong random number generator available. | ||||||
|  | 
 | ||||||
|  | One Miller-Rabin tests with a random base will be run automatically, so by setting $t$ to a positive value this function will run $t + 1$ Miller-Rabin tests with random bases. | ||||||
|  | 
 | ||||||
|  | If  $t$ is set to a negative value the test will run the deterministic Miller-Rabin test for the primes up to | ||||||
|  | $3317044064679887385961981$. That limit has to be checked by the caller. If $-t > 13$ than $-t - 13$ additional rounds of the | ||||||
|  | Miller-Rabin test will be performed but note that $-t$ is bounded by $1 \le -t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number | ||||||
|  | of primes in the prime number table (by default this is $256$) and the first 13 primes have already been used. It will return | ||||||
|  | \texttt{MP\_VAL} in case of$-t > PRIME\_SIZE$. | ||||||
|  | 
 | ||||||
|  | If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero. | ||||||
| 
 | 
 | ||||||
| \section{Next Prime} | \section{Next Prime} | ||||||
| \index{mp\_prime\_next\_prime} | \index{mp\_prime\_next\_prime} | ||||||
| \begin{alltt} | \begin{alltt} | ||||||
| int mp_prime_next_prime(mp_int *a, int t, int bbs_style) | int mp_prime_next_prime(mp_int *a, int t, int bbs_style) | ||||||
| \end{alltt} | \end{alltt} | ||||||
| This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests.  Set $bbs\_style$ to one if you | This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests but see the documentation for | ||||||
|  | mp\_prime\_is\_prime for details regarding the use of the argument $t$.  Set $bbs\_style$ to one if you | ||||||
| want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime. | want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime. | ||||||
| 
 | 
 | ||||||
| \section{Random Primes} | \section{Random Primes} | ||||||
| @ -1846,7 +1954,8 @@ int mp_prime_random(mp_int *a, int t, int size, int bbs, | |||||||
|                     ltm_prime_callback cb, void *dat) |                     ltm_prime_callback cb, void *dat) | ||||||
| \end{alltt} | \end{alltt} | ||||||
| This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass | This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass | ||||||
| $t$ rounds of tests.  The ``ltm\_prime\_callback'' is a typedef for | $t$ rounds of tests but see the documentation for mp\_prime\_is\_prime for details regarding the use of the argument $t$. | ||||||
|  | The ``ltm\_prime\_callback'' is a typedef for | ||||||
| 
 | 
 | ||||||
| \begin{alltt} | \begin{alltt} | ||||||
| typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); | typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); | ||||||
| @ -2016,7 +2125,7 @@ This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that | |||||||
| a \cdot U1 + b \cdot U2 = U3 | a \cdot U1 + b \cdot U2 = U3 | ||||||
| \end{equation} | \end{equation} | ||||||
| 
 | 
 | ||||||
| Any of the U1/U2/U3 paramters can be set to \textbf{NULL} if they are not desired. | Any of the U1/U2/U3 parameters can be set to \textbf{NULL} if they are not desired. | ||||||
| 
 | 
 | ||||||
| \section{Greatest Common Divisor} | \section{Greatest Common Divisor} | ||||||
| \index{mp\_gcd} | \index{mp\_gcd} | ||||||
| @ -2042,6 +2151,14 @@ symbol.  The result is stored in $c$ and can take on one of three values $\lbrac | |||||||
| then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$.  The result will be $0$ if $a$ divides $p$ | then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$.  The result will be $0$ if $a$ divides $p$ | ||||||
| and the result will be $1$ if $a$ is a quadratic residue modulo $p$. | and the result will be $1$ if $a$ is a quadratic residue modulo $p$. | ||||||
| 
 | 
 | ||||||
|  | \section{Kronecker Symbol} | ||||||
|  | \index{mp\_kronecker} | ||||||
|  | \begin{alltt} | ||||||
|  | int mp_kronecker (mp_int * a, mp_int * p, int *c) | ||||||
|  | \end{alltt} | ||||||
|  | Extension of the Jacoby symbol to all $\lbrace a, p \rbrace \in \mathbb{Z}$ . | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| \section{Modular square root} | \section{Modular square root} | ||||||
| \index{mp\_sqrtmod\_prime} | \index{mp\_sqrtmod\_prime} | ||||||
| \begin{alltt} | \begin{alltt} | ||||||
| @ -2087,6 +2204,7 @@ These work like the full mp\_int capable variants except the second parameter $b | |||||||
| functions fairly handy if you have to work with relatively small numbers since you will not have to allocate | functions fairly handy if you have to work with relatively small numbers since you will not have to allocate | ||||||
| an entire mp\_int to store a number like $1$ or $2$. | an entire mp\_int to store a number like $1$ or $2$. | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| The division by three can be made faster by replacing the division with a multiplication by the multiplicative inverse of three. | The division by three can be made faster by replacing the division with a multiplication by the multiplicative inverse of three. | ||||||
| 
 | 
 | ||||||
| \index{mp\_div\_3} | \index{mp\_div\_3} | ||||||
| @ -2191,7 +2309,6 @@ Other macros which are either shortcuts to normal functions or just other names | |||||||
| \end{alltt} | \end{alltt} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| \input{bn.ind} | \input{bn.ind} | ||||||
| 
 | 
 | ||||||
| \end{document} | \end{document} | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ top: | |||||||
|             if ((clock() - t1) > CLOCKS_PER_SEC) { |             if ((clock() - t1) > CLOCKS_PER_SEC) { | ||||||
|                printf("."); |                printf("."); | ||||||
|                fflush(stdout); |                fflush(stdout); | ||||||
| /*            sleep((clock() - t1 + CLOCKS_PER_SEC/2)/CLOCKS_PER_SEC); */ |                /*            sleep((clock() - t1 + CLOCKS_PER_SEC/2)/CLOCKS_PER_SEC); */ | ||||||
|                t1 = clock(); |                t1 = clock(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -472,6 +472,10 @@ | |||||||
| 			RelativePath="bn_mp_gcd.c" | 			RelativePath="bn_mp_gcd.c" | ||||||
| 			> | 			> | ||||||
| 		</File> | 		</File> | ||||||
|  | 		<File | ||||||
|  | 			RelativePath="bn_mp_get_bit.c" | ||||||
|  | 			> | ||||||
|  | 		</File> | ||||||
| 		<File | 		<File | ||||||
| 			RelativePath="bn_mp_get_double.c" | 			RelativePath="bn_mp_get_double.c" | ||||||
| 			> | 			> | ||||||
| @ -544,6 +548,10 @@ | |||||||
| 			RelativePath="bn_mp_karatsuba_sqr.c" | 			RelativePath="bn_mp_karatsuba_sqr.c" | ||||||
| 			> | 			> | ||||||
| 		</File> | 		</File> | ||||||
|  | 		<File | ||||||
|  | 			RelativePath="bn_mp_kronecker.c" | ||||||
|  | 			> | ||||||
|  | 		</File> | ||||||
| 		<File | 		<File | ||||||
| 			RelativePath="bn_mp_lcm.c" | 			RelativePath="bn_mp_lcm.c" | ||||||
| 			> | 			> | ||||||
| @ -616,6 +624,10 @@ | |||||||
| 			RelativePath="bn_mp_prime_fermat.c" | 			RelativePath="bn_mp_prime_fermat.c" | ||||||
| 			> | 			> | ||||||
| 		</File> | 		</File> | ||||||
|  | 		<File | ||||||
|  | 			RelativePath="bn_mp_prime_frobenius_underwood.c" | ||||||
|  | 			> | ||||||
|  | 		</File> | ||||||
| 		<File | 		<File | ||||||
| 			RelativePath="bn_mp_prime_is_divisible.c" | 			RelativePath="bn_mp_prime_is_divisible.c" | ||||||
| 			> | 			> | ||||||
| @ -640,6 +652,10 @@ | |||||||
| 			RelativePath="bn_mp_prime_random_ex.c" | 			RelativePath="bn_mp_prime_random_ex.c" | ||||||
| 			> | 			> | ||||||
| 		</File> | 		</File> | ||||||
|  | 		<File | ||||||
|  | 			RelativePath="bn_mp_prime_strong_lucas_selfridge.c" | ||||||
|  | 			> | ||||||
|  | 		</File> | ||||||
| 		<File | 		<File | ||||||
| 			RelativePath="bn_mp_radix_size.c" | 			RelativePath="bn_mp_radix_size.c" | ||||||
| 			> | 			> | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								makefile
									
									
									
									
									
								
							| @ -32,25 +32,26 @@ bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp | |||||||
| bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | ||||||
| bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | ||||||
| bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | ||||||
| bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \ | bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o \ | ||||||
| bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o bn_mp_init.o \ | bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o \ | ||||||
| bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | ||||||
| bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | ||||||
| bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | bn_mp_karatsuba_sqr.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | ||||||
| bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | ||||||
| bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | ||||||
| bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \ | bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o \ | ||||||
| bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \ | bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ | ||||||
| bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ | bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o \ | ||||||
| bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \ | bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o \ | ||||||
| bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \ | bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o \ | ||||||
| bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o \ | bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o \ | ||||||
| bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \ | bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o \ | ||||||
| bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o \ | bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o \ | ||||||
| bn_mp_tc_or.o bn_mp_tc_xor.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o \ | bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o bn_mp_tc_or.o bn_mp_tc_xor.o \ | ||||||
| bn_mp_to_unsigned_bin_n.o bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o \ | bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \ | ||||||
| bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o \ | bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o \ | ||||||
| bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o \ | ||||||
|  | bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | ||||||
| 
 | 
 | ||||||
| #END_INS
 | #END_INS
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -35,25 +35,26 @@ bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp | |||||||
| bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | ||||||
| bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | ||||||
| bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | ||||||
| bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \ | bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o \ | ||||||
| bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o bn_mp_init.o \ | bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o \ | ||||||
| bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | ||||||
| bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | ||||||
| bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | bn_mp_karatsuba_sqr.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | ||||||
| bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | ||||||
| bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | ||||||
| bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \ | bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o \ | ||||||
| bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \ | bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ | ||||||
| bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ | bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o \ | ||||||
| bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \ | bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o \ | ||||||
| bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \ | bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o \ | ||||||
| bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o \ | bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o \ | ||||||
| bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \ | bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o \ | ||||||
| bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o \ | bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o \ | ||||||
| bn_mp_tc_or.o bn_mp_tc_xor.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o \ | bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o bn_mp_tc_or.o bn_mp_tc_xor.o \ | ||||||
| bn_mp_to_unsigned_bin_n.o bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o \ | bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \ | ||||||
| bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o \ | bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o \ | ||||||
| bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o \ | ||||||
|  | bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | ||||||
| 
 | 
 | ||||||
| HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h | HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,25 +27,26 @@ bn_mp_addmod.obj bn_mp_and.obj bn_mp_clamp.obj bn_mp_clear.obj bn_mp_clear_multi | |||||||
| bn_mp_cmp_mag.obj bn_mp_cnt_lsb.obj bn_mp_complement.obj bn_mp_copy.obj bn_mp_count_bits.obj bn_mp_div.obj \ | bn_mp_cmp_mag.obj bn_mp_cnt_lsb.obj bn_mp_complement.obj bn_mp_copy.obj bn_mp_count_bits.obj bn_mp_div.obj \ | ||||||
| bn_mp_div_2.obj bn_mp_div_2d.obj bn_mp_div_3.obj bn_mp_div_d.obj bn_mp_dr_is_modulus.obj bn_mp_dr_reduce.obj \ | bn_mp_div_2.obj bn_mp_div_2d.obj bn_mp_div_3.obj bn_mp_div_d.obj bn_mp_dr_is_modulus.obj bn_mp_dr_reduce.obj \ | ||||||
| bn_mp_dr_setup.obj bn_mp_exch.obj bn_mp_export.obj bn_mp_expt_d.obj bn_mp_expt_d_ex.obj bn_mp_exptmod.obj \ | bn_mp_dr_setup.obj bn_mp_exch.obj bn_mp_export.obj bn_mp_expt_d.obj bn_mp_expt_d_ex.obj bn_mp_exptmod.obj \ | ||||||
| bn_mp_exptmod_fast.obj bn_mp_exteuclid.obj bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_gcd.obj bn_mp_get_double.obj \ | bn_mp_exptmod_fast.obj bn_mp_exteuclid.obj bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_gcd.obj bn_mp_get_bit.obj \ | ||||||
| bn_mp_get_int.obj bn_mp_get_long.obj bn_mp_get_long_long.obj bn_mp_grow.obj bn_mp_import.obj bn_mp_init.obj \ | bn_mp_get_double.obj bn_mp_get_int.obj bn_mp_get_long.obj bn_mp_get_long_long.obj bn_mp_grow.obj bn_mp_import.obj \ | ||||||
| bn_mp_init_copy.obj bn_mp_init_multi.obj bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_init_size.obj \ | bn_mp_init.obj bn_mp_init_copy.obj bn_mp_init_multi.obj bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_init_size.obj \ | ||||||
| bn_mp_invmod.obj bn_mp_invmod_slow.obj bn_mp_is_square.obj bn_mp_jacobi.obj bn_mp_karatsuba_mul.obj \ | bn_mp_invmod.obj bn_mp_invmod_slow.obj bn_mp_is_square.obj bn_mp_jacobi.obj bn_mp_karatsuba_mul.obj \ | ||||||
| bn_mp_karatsuba_sqr.obj bn_mp_lcm.obj bn_mp_lshd.obj bn_mp_mod.obj bn_mp_mod_2d.obj bn_mp_mod_d.obj \ | bn_mp_karatsuba_sqr.obj bn_mp_kronecker.obj bn_mp_lcm.obj bn_mp_lshd.obj bn_mp_mod.obj bn_mp_mod_2d.obj bn_mp_mod_d.obj \ | ||||||
| bn_mp_montgomery_calc_normalization.obj bn_mp_montgomery_reduce.obj bn_mp_montgomery_setup.obj bn_mp_mul.obj \ | bn_mp_montgomery_calc_normalization.obj bn_mp_montgomery_reduce.obj bn_mp_montgomery_setup.obj bn_mp_mul.obj \ | ||||||
| bn_mp_mul_2.obj bn_mp_mul_2d.obj bn_mp_mul_d.obj bn_mp_mulmod.obj bn_mp_n_root.obj bn_mp_n_root_ex.obj bn_mp_neg.obj \ | bn_mp_mul_2.obj bn_mp_mul_2d.obj bn_mp_mul_d.obj bn_mp_mulmod.obj bn_mp_n_root.obj bn_mp_n_root_ex.obj bn_mp_neg.obj \ | ||||||
| bn_mp_or.obj bn_mp_prime_fermat.obj bn_mp_prime_is_divisible.obj bn_mp_prime_is_prime.obj \ | bn_mp_or.obj bn_mp_prime_fermat.obj bn_mp_prime_frobenius_underwood.obj bn_mp_prime_is_divisible.obj \ | ||||||
| bn_mp_prime_miller_rabin.obj bn_mp_prime_next_prime.obj bn_mp_prime_rabin_miller_trials.obj \ | bn_mp_prime_is_prime.obj bn_mp_prime_miller_rabin.obj bn_mp_prime_next_prime.obj \ | ||||||
| bn_mp_prime_random_ex.obj bn_mp_radix_size.obj bn_mp_radix_smap.obj bn_mp_rand.obj bn_mp_read_radix.obj \ | bn_mp_prime_rabin_miller_trials.obj bn_mp_prime_random_ex.obj bn_mp_prime_strong_lucas_selfridge.obj \ | ||||||
| bn_mp_read_signed_bin.obj bn_mp_read_unsigned_bin.obj bn_mp_reduce.obj bn_mp_reduce_2k.obj bn_mp_reduce_2k_l.obj \ | bn_mp_radix_size.obj bn_mp_radix_smap.obj bn_mp_rand.obj bn_mp_read_radix.obj bn_mp_read_signed_bin.obj \ | ||||||
| bn_mp_reduce_2k_setup.obj bn_mp_reduce_2k_setup_l.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_is_2k_l.obj \ | bn_mp_read_unsigned_bin.obj bn_mp_reduce.obj bn_mp_reduce_2k.obj bn_mp_reduce_2k_l.obj bn_mp_reduce_2k_setup.obj \ | ||||||
| bn_mp_reduce_setup.obj bn_mp_rshd.obj bn_mp_set.obj bn_mp_set_double.obj bn_mp_set_int.obj bn_mp_set_long.obj \ | bn_mp_reduce_2k_setup_l.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_setup.obj bn_mp_rshd.obj \ | ||||||
| bn_mp_set_long_long.obj bn_mp_shrink.obj bn_mp_signed_bin_size.obj bn_mp_sqr.obj bn_mp_sqrmod.obj bn_mp_sqrt.obj \ | bn_mp_set.obj bn_mp_set_double.obj bn_mp_set_int.obj bn_mp_set_long.obj bn_mp_set_long_long.obj bn_mp_shrink.obj \ | ||||||
| bn_mp_sqrtmod_prime.obj bn_mp_sub.obj bn_mp_sub_d.obj bn_mp_submod.obj bn_mp_tc_and.obj bn_mp_tc_div_2d.obj \ | bn_mp_signed_bin_size.obj bn_mp_sqr.obj bn_mp_sqrmod.obj bn_mp_sqrt.obj bn_mp_sqrtmod_prime.obj bn_mp_sub.obj \ | ||||||
| bn_mp_tc_or.obj bn_mp_tc_xor.obj bn_mp_to_signed_bin.obj bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin.obj \ | bn_mp_sub_d.obj bn_mp_submod.obj bn_mp_tc_and.obj bn_mp_tc_div_2d.obj bn_mp_tc_or.obj bn_mp_tc_xor.obj \ | ||||||
| bn_mp_to_unsigned_bin_n.obj bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_toradix.obj bn_mp_toradix_n.obj \ | bn_mp_to_signed_bin.obj bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin.obj bn_mp_to_unsigned_bin_n.obj \ | ||||||
| bn_mp_unsigned_bin_size.obj bn_mp_xor.obj bn_mp_zero.obj bn_prime_tab.obj bn_reverse.obj bn_s_mp_add.obj \ | bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_toradix.obj bn_mp_toradix_n.obj bn_mp_unsigned_bin_size.obj bn_mp_xor.obj \ | ||||||
| bn_s_mp_exptmod.obj bn_s_mp_mul_digs.obj bn_s_mp_mul_high_digs.obj bn_s_mp_sqr.obj bn_s_mp_sub.obj bncore.obj | bn_mp_zero.obj bn_prime_tab.obj bn_reverse.obj bn_s_mp_add.obj bn_s_mp_exptmod.obj bn_s_mp_mul_digs.obj \ | ||||||
|  | bn_s_mp_mul_high_digs.obj bn_s_mp_sqr.obj bn_s_mp_sub.obj bncore.obj | ||||||
| 
 | 
 | ||||||
| HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h | HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,25 +28,26 @@ bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp | |||||||
| bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | ||||||
| bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | ||||||
| bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | ||||||
| bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \ | bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o \ | ||||||
| bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o bn_mp_init.o \ | bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o \ | ||||||
| bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | ||||||
| bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | ||||||
| bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | bn_mp_karatsuba_sqr.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | ||||||
| bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | ||||||
| bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | ||||||
| bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \ | bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o \ | ||||||
| bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \ | bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ | ||||||
| bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ | bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o \ | ||||||
| bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \ | bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o \ | ||||||
| bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \ | bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o \ | ||||||
| bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o \ | bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o \ | ||||||
| bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \ | bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o \ | ||||||
| bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o \ | bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o \ | ||||||
| bn_mp_tc_or.o bn_mp_tc_xor.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o \ | bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o bn_mp_tc_or.o bn_mp_tc_xor.o \ | ||||||
| bn_mp_to_unsigned_bin_n.o bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o \ | bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \ | ||||||
| bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o \ | bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o \ | ||||||
| bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o \ | ||||||
|  | bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | ||||||
| 
 | 
 | ||||||
| #END_INS | #END_INS | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -36,25 +36,26 @@ bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp | |||||||
| bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \ | ||||||
| bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \ | ||||||
| bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \ | ||||||
| bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \ | bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o \ | ||||||
| bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o bn_mp_init.o \ | bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o \ | ||||||
| bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \ | ||||||
| bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o \ | ||||||
| bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | bn_mp_karatsuba_sqr.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o \ | ||||||
| bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o \ | ||||||
| bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o \ | ||||||
| bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \ | bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o \ | ||||||
| bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \ | bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ | ||||||
| bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ | bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o \ | ||||||
| bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \ | bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o \ | ||||||
| bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \ | bn_mp_read_unsigned_bin.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o \ | ||||||
| bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o \ | bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o \ | ||||||
| bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \ | bn_mp_set.o bn_mp_set_double.o bn_mp_set_int.o bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o \ | ||||||
| bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o \ | bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o \ | ||||||
| bn_mp_tc_or.o bn_mp_tc_xor.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o \ | bn_mp_sub_d.o bn_mp_submod.o bn_mp_tc_and.o bn_mp_tc_div_2d.o bn_mp_tc_or.o bn_mp_tc_xor.o \ | ||||||
| bn_mp_to_unsigned_bin_n.o bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o \ | bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \ | ||||||
| bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o \ | bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o \ | ||||||
| bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | bn_mp_zero.o bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o \ | ||||||
|  | bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o | ||||||
| 
 | 
 | ||||||
| HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h | HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -293,7 +293,7 @@ int main(int argc, char *argv[]) | |||||||
|          rand_num2(&a); |          rand_num2(&a); | ||||||
|          rand_num2(&b); |          rand_num2(&b); | ||||||
|          rand_num2(&c); |          rand_num2(&c); | ||||||
| /*      if (c.dp[0]&1) mp_add_d(&c, 1, &c); */ |          /*      if (c.dp[0]&1) mp_add_d(&c, 1, &c); */ | ||||||
|          a.sign = b.sign = c.sign = 0; |          a.sign = b.sign = c.sign = 0; | ||||||
|          mp_exptmod(&a, &b, &c, &d); |          mp_exptmod(&a, &b, &c, &d); | ||||||
|          printf("expt\n"); |          printf("expt\n"); | ||||||
|  | |||||||
| @ -66,6 +66,9 @@ _die() | |||||||
|     exit 128 |     exit 128 | ||||||
|   else |   else | ||||||
|     echo "assuming timeout while running test - continue" |     echo "assuming timeout while running test - continue" | ||||||
|  |     local _tail="" | ||||||
|  |     which tail >/dev/null && _tail="tail -n 1 test_${suffix}.log" && \ | ||||||
|  |     echo "last line of test_"${suffix}".log was:" && $_tail && echo "" | ||||||
|     ret=$(( $ret + 1 )) |     ret=$(( $ret + 1 )) | ||||||
|   fi |   fi | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								tommath.h
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								tommath.h
									
									
									
									
									
								
							| @ -115,6 +115,7 @@ typedef mp_digit mp_min_u32; | |||||||
| #define MP_MEM        -2  /* out of mem */ | #define MP_MEM        -2  /* out of mem */ | ||||||
| #define MP_VAL        -3  /* invalid input */ | #define MP_VAL        -3  /* invalid input */ | ||||||
| #define MP_RANGE      MP_VAL | #define MP_RANGE      MP_VAL | ||||||
|  | #define MP_ITER       -4  /* Max. iterations reached */ | ||||||
| 
 | 
 | ||||||
| #define MP_YES        1   /* yes response */ | #define MP_YES        1   /* yes response */ | ||||||
| #define MP_NO         0   /* no response */ | #define MP_NO         0   /* no response */ | ||||||
| @ -298,6 +299,11 @@ int mp_or(const mp_int *a, const mp_int *b, mp_int *c); | |||||||
| /* c = a AND b */ | /* c = a AND b */ | ||||||
| int mp_and(const mp_int *a, const mp_int *b, mp_int *c); | int mp_and(const mp_int *a, const mp_int *b, mp_int *c); | ||||||
| 
 | 
 | ||||||
|  | /* Checks the bit at position b and returns MP_YES
 | ||||||
|  |    if the bit is 1, MP_NO if it is 0 and MP_VAL | ||||||
|  |    in case of error */ | ||||||
|  | int mp_get_bit(const mp_int *a, int b); | ||||||
|  | 
 | ||||||
| /* c = a XOR b (two complement) */ | /* c = a XOR b (two complement) */ | ||||||
| int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c); | int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c); | ||||||
| 
 | 
 | ||||||
| @ -417,6 +423,9 @@ int mp_is_square(const mp_int *arg, int *ret); | |||||||
| /* computes the jacobi c = (a | n) (or Legendre if b is prime)  */ | /* computes the jacobi c = (a | n) (or Legendre if b is prime)  */ | ||||||
| int mp_jacobi(const mp_int *a, const mp_int *n, int *c); | int mp_jacobi(const mp_int *a, const mp_int *n, int *c); | ||||||
| 
 | 
 | ||||||
|  | /* computes the Kronecker symbol c = (a | p) (like jacobi() but with {a,p} in Z */ | ||||||
|  | int mp_kronecker(const mp_int *a, const mp_int *p, int *c); | ||||||
|  | 
 | ||||||
| /* used to setup the Barrett reduction for a given modulus b */ | /* used to setup the Barrett reduction for a given modulus b */ | ||||||
| int mp_reduce_setup(mp_int *a, const mp_int *b); | int mp_reduce_setup(mp_int *a, const mp_int *b); | ||||||
| 
 | 
 | ||||||
| @ -498,10 +507,27 @@ int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result); | |||||||
|  */ |  */ | ||||||
| int mp_prime_rabin_miller_trials(int size); | int mp_prime_rabin_miller_trials(int size); | ||||||
| 
 | 
 | ||||||
| /* performs t rounds of Miller-Rabin on "a" using the first
 | /* performs one strong Lucas-Selfridge test of "a".
 | ||||||
|  * t prime bases.  Also performs an initial sieve of trial |  * Sets result to 0 if composite or 1 if probable prime | ||||||
|  |  */ | ||||||
|  | int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result); | ||||||
|  | 
 | ||||||
|  | /* performs one Frobenius test of "a" as described by Paul Underwood.
 | ||||||
|  |  * Sets result to 0 if composite or 1 if probable prime | ||||||
|  |  */ | ||||||
|  | int mp_prime_frobenius_underwood(const mp_int *N, int *result); | ||||||
|  | 
 | ||||||
|  | /* performs t random rounds of Miller-Rabin on "a" additional to
 | ||||||
|  |  * bases 2 and 3.  Also performs an initial sieve of trial | ||||||
|  * division.  Determines if "a" is prime with probability |  * division.  Determines if "a" is prime with probability | ||||||
|  * of error no more than (1/4)**t. |  * of error no more than (1/4)**t. | ||||||
|  |  * Both a strong Lucas-Selfridge to complete the BPSW test | ||||||
|  |  * and a separate Frobenius test are available at compile time. | ||||||
|  |  * With t<0 a deterministic test is run for primes up to | ||||||
|  |  * 318665857834031151167461. With t<13 (abs(t)-13) additional | ||||||
|  |  * tests with sequential small primes are run starting at 43. | ||||||
|  |  * Is Fips 186.4 compliant if called with t as computed by | ||||||
|  |  * mp_prime_rabin_miller_trials(); | ||||||
|  * |  * | ||||||
|  * Sets result to 1 if probably prime, 0 otherwise |  * Sets result to 1 if probably prime, 0 otherwise | ||||||
|  */ |  */ | ||||||
|  | |||||||
							
								
								
									
										103
									
								
								tommath_class.h
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								tommath_class.h
									
									
									
									
									
								
							| @ -10,6 +10,7 @@ | |||||||
|  * The library is free for all purposes without any express |  * The library is free for all purposes without any express | ||||||
|  * guarantee it works. |  * guarantee it works. | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
| #if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) | #if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) | ||||||
| #if defined(LTM2) | #if defined(LTM2) | ||||||
| #   define LTM3 | #   define LTM3 | ||||||
| @ -60,6 +61,7 @@ | |||||||
| #   define BN_MP_FREAD_C | #   define BN_MP_FREAD_C | ||||||
| #   define BN_MP_FWRITE_C | #   define BN_MP_FWRITE_C | ||||||
| #   define BN_MP_GCD_C | #   define BN_MP_GCD_C | ||||||
|  | #   define BN_MP_GET_BIT_C | ||||||
| #   define BN_MP_GET_DOUBLE_C | #   define BN_MP_GET_DOUBLE_C | ||||||
| #   define BN_MP_GET_INT_C | #   define BN_MP_GET_INT_C | ||||||
| #   define BN_MP_GET_LONG_C | #   define BN_MP_GET_LONG_C | ||||||
| @ -78,6 +80,7 @@ | |||||||
| #   define BN_MP_JACOBI_C | #   define BN_MP_JACOBI_C | ||||||
| #   define BN_MP_KARATSUBA_MUL_C | #   define BN_MP_KARATSUBA_MUL_C | ||||||
| #   define BN_MP_KARATSUBA_SQR_C | #   define BN_MP_KARATSUBA_SQR_C | ||||||
|  | #   define BN_MP_KRONECKER_C | ||||||
| #   define BN_MP_LCM_C | #   define BN_MP_LCM_C | ||||||
| #   define BN_MP_LSHD_C | #   define BN_MP_LSHD_C | ||||||
| #   define BN_MP_MOD_C | #   define BN_MP_MOD_C | ||||||
| @ -96,12 +99,14 @@ | |||||||
| #   define BN_MP_NEG_C | #   define BN_MP_NEG_C | ||||||
| #   define BN_MP_OR_C | #   define BN_MP_OR_C | ||||||
| #   define BN_MP_PRIME_FERMAT_C | #   define BN_MP_PRIME_FERMAT_C | ||||||
|  | #   define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C | ||||||
| #   define BN_MP_PRIME_IS_DIVISIBLE_C | #   define BN_MP_PRIME_IS_DIVISIBLE_C | ||||||
| #   define BN_MP_PRIME_IS_PRIME_C | #   define BN_MP_PRIME_IS_PRIME_C | ||||||
| #   define BN_MP_PRIME_MILLER_RABIN_C | #   define BN_MP_PRIME_MILLER_RABIN_C | ||||||
| #   define BN_MP_PRIME_NEXT_PRIME_C | #   define BN_MP_PRIME_NEXT_PRIME_C | ||||||
| #   define BN_MP_PRIME_RABIN_MILLER_TRIALS_C | #   define BN_MP_PRIME_RABIN_MILLER_TRIALS_C | ||||||
| #   define BN_MP_PRIME_RANDOM_EX_C | #   define BN_MP_PRIME_RANDOM_EX_C | ||||||
|  | #   define BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C | ||||||
| #   define BN_MP_RADIX_SIZE_C | #   define BN_MP_RADIX_SIZE_C | ||||||
| #   define BN_MP_RADIX_SMAP_C | #   define BN_MP_RADIX_SMAP_C | ||||||
| #   define BN_MP_RAND_C | #   define BN_MP_RAND_C | ||||||
| @ -174,6 +179,7 @@ | |||||||
| #   define BN_MP_CMP_C | #   define BN_MP_CMP_C | ||||||
| #   define BN_MP_CMP_D_C | #   define BN_MP_CMP_D_C | ||||||
| #   define BN_MP_ADD_C | #   define BN_MP_ADD_C | ||||||
|  | #   define BN_MP_CMP_MAG_C | ||||||
| #   define BN_MP_EXCH_C | #   define BN_MP_EXCH_C | ||||||
| #   define BN_MP_CLEAR_MULTI_C | #   define BN_MP_CLEAR_MULTI_C | ||||||
| #endif | #endif | ||||||
| @ -439,6 +445,10 @@ | |||||||
| #   define BN_MP_CLEAR_C | #   define BN_MP_CLEAR_C | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if defined(BN_MP_GET_BIT_C) | ||||||
|  | #   define BN_MP_ISZERO_C | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if defined(BN_MP_GET_DOUBLE_C) | #if defined(BN_MP_GET_DOUBLE_C) | ||||||
| #   define BN_MP_ISNEG_C | #   define BN_MP_ISNEG_C | ||||||
| #endif | #endif | ||||||
| @ -527,14 +537,9 @@ | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if defined(BN_MP_JACOBI_C) | #if defined(BN_MP_JACOBI_C) | ||||||
|  | #   define BN_MP_KRONECKER_C | ||||||
| #   define BN_MP_ISNEG_C | #   define BN_MP_ISNEG_C | ||||||
| #   define BN_MP_CMP_D_C | #   define BN_MP_CMP_D_C | ||||||
| #   define BN_MP_ISZERO_C |  | ||||||
| #   define BN_MP_INIT_COPY_C |  | ||||||
| #   define BN_MP_CNT_LSB_C |  | ||||||
| #   define BN_MP_DIV_2D_C |  | ||||||
| #   define BN_MP_MOD_C |  | ||||||
| #   define BN_MP_CLEAR_C |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if defined(BN_MP_KARATSUBA_MUL_C) | #if defined(BN_MP_KARATSUBA_MUL_C) | ||||||
| @ -559,6 +564,18 @@ | |||||||
| #   define BN_MP_CLEAR_C | #   define BN_MP_CLEAR_C | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if defined(BN_MP_KRONECKER_C) | ||||||
|  | #   define BN_MP_ISZERO_C | ||||||
|  | #   define BN_MP_ISEVEN_C | ||||||
|  | #   define BN_MP_INIT_COPY_C | ||||||
|  | #   define BN_MP_CNT_LSB_C | ||||||
|  | #   define BN_MP_DIV_2D_C | ||||||
|  | #   define BN_MP_CMP_D_C | ||||||
|  | #   define BN_MP_COPY_C | ||||||
|  | #   define BN_MP_MOD_C | ||||||
|  | #   define BN_MP_CLEAR_C | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if defined(BN_MP_LCM_C) | #if defined(BN_MP_LCM_C) | ||||||
| #   define BN_MP_INIT_MULTI_C | #   define BN_MP_INIT_MULTI_C | ||||||
| #   define BN_MP_GCD_C | #   define BN_MP_GCD_C | ||||||
| @ -684,16 +701,49 @@ | |||||||
| #   define BN_MP_CLEAR_C | #   define BN_MP_CLEAR_C | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if defined(BN_MP_PRIME_FROBENIUS_UNDERWOOD_C) | ||||||
|  | #   define BN_MP_PRIME_IS_PRIME_C | ||||||
|  | #   define BN_MP_INIT_MULTI_C | ||||||
|  | #   define BN_MP_SET_LONG_C | ||||||
|  | #   define BN_MP_SQR_C | ||||||
|  | #   define BN_MP_SUB_D_C | ||||||
|  | #   define BN_MP_KRONECKER_C | ||||||
|  | #   define BN_MP_GCD_C | ||||||
|  | #   define BN_MP_ADD_D_C | ||||||
|  | #   define BN_MP_SET_C | ||||||
|  | #   define BN_MP_COUNT_BITS_C | ||||||
|  | #   define BN_MP_MUL_2_C | ||||||
|  | #   define BN_MP_MUL_D_C | ||||||
|  | #   define BN_MP_ADD_C | ||||||
|  | #   define BN_MP_MUL_C | ||||||
|  | #   define BN_MP_SUB_C | ||||||
|  | #   define BN_MP_MOD_C | ||||||
|  | #   define BN_MP_GET_BIT_C | ||||||
|  | #   define BN_MP_EXCH_C | ||||||
|  | #   define BN_MP_ISZERO_C | ||||||
|  | #   define BN_MP_CMP_C | ||||||
|  | #   define BN_MP_CLEAR_MULTI_C | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if defined(BN_MP_PRIME_IS_DIVISIBLE_C) | #if defined(BN_MP_PRIME_IS_DIVISIBLE_C) | ||||||
| #   define BN_MP_MOD_D_C | #   define BN_MP_MOD_D_C | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if defined(BN_MP_PRIME_IS_PRIME_C) | #if defined(BN_MP_PRIME_IS_PRIME_C) | ||||||
|  | #   define BN_MP_ISEVEN_C | ||||||
|  | #   define BN_MP_IS_SQUARE_C | ||||||
| #   define BN_MP_CMP_D_C | #   define BN_MP_CMP_D_C | ||||||
| #   define BN_MP_PRIME_IS_DIVISIBLE_C | #   define BN_MP_PRIME_IS_DIVISIBLE_C | ||||||
| #   define BN_MP_INIT_C | #   define BN_MP_INIT_SET_C | ||||||
| #   define BN_MP_SET_C |  | ||||||
| #   define BN_MP_PRIME_MILLER_RABIN_C | #   define BN_MP_PRIME_MILLER_RABIN_C | ||||||
|  | #   define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C | ||||||
|  | #   define BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C | ||||||
|  | #   define BN_MP_READ_RADIX_C | ||||||
|  | #   define BN_MP_CMP_C | ||||||
|  | #   define BN_MP_SET_C | ||||||
|  | #   define BN_MP_COUNT_BITS_C | ||||||
|  | #   define BN_MP_RAND_C | ||||||
|  | #   define BN_MP_DIV_2D_C | ||||||
| #   define BN_MP_CLEAR_C | #   define BN_MP_CLEAR_C | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -717,7 +767,7 @@ | |||||||
| #   define BN_MP_MOD_D_C | #   define BN_MP_MOD_D_C | ||||||
| #   define BN_MP_INIT_C | #   define BN_MP_INIT_C | ||||||
| #   define BN_MP_ADD_D_C | #   define BN_MP_ADD_D_C | ||||||
| #   define BN_MP_PRIME_MILLER_RABIN_C | #   define BN_MP_PRIME_IS_PRIME_C | ||||||
| #   define BN_MP_CLEAR_C | #   define BN_MP_CLEAR_C | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -733,6 +783,37 @@ | |||||||
| #   define BN_MP_ADD_D_C | #   define BN_MP_ADD_D_C | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if defined(BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C) | ||||||
|  | #   define BN_MP_PRIME_IS_PRIME_C | ||||||
|  | #   define BN_MP_MUL_D_C | ||||||
|  | #   define BN_MP_MUL_SI_C | ||||||
|  | #   define BN_MP_INIT_C | ||||||
|  | #   define BN_MP_SET_LONG_C | ||||||
|  | #   define BN_MP_MUL_C | ||||||
|  | #   define BN_MP_CLEAR_C | ||||||
|  | #   define BN_MP_INIT_MULTI_C | ||||||
|  | #   define BN_MP_GCD_C | ||||||
|  | #   define BN_MP_CMP_D_C | ||||||
|  | #   define BN_MP_CMP_C | ||||||
|  | #   define BN_MP_KRONECKER_C | ||||||
|  | #   define BN_MP_ADD_D_C | ||||||
|  | #   define BN_MP_CNT_LSB_C | ||||||
|  | #   define BN_MP_DIV_2D_C | ||||||
|  | #   define BN_MP_SET_C | ||||||
|  | #   define BN_MP_MUL_2_C | ||||||
|  | #   define BN_MP_COUNT_BITS_C | ||||||
|  | #   define BN_MP_MOD_C | ||||||
|  | #   define BN_MP_SQR_C | ||||||
|  | #   define BN_MP_SUB_C | ||||||
|  | #   define BN_MP_GET_BIT_C | ||||||
|  | #   define BN_MP_ADD_C | ||||||
|  | #   define BN_MP_ISODD_C | ||||||
|  | #   define BN_MP_DIV_2_C | ||||||
|  | #   define BN_MP_SUB_D_C | ||||||
|  | #   define BN_MP_ISZERO_C | ||||||
|  | #   define BN_MP_CLEAR_MULTI_C | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if defined(BN_MP_RADIX_SIZE_C) | #if defined(BN_MP_RADIX_SIZE_C) | ||||||
| #   define BN_MP_ISZERO_C | #   define BN_MP_ISZERO_C | ||||||
| #   define BN_MP_COUNT_BITS_C | #   define BN_MP_COUNT_BITS_C | ||||||
| @ -1133,8 +1214,8 @@ | |||||||
| #   define LTM_LAST | #   define LTM_LAST | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #include "tommath_superclass.h" | #include <tommath_superclass.h> | ||||||
| #include "tommath_class.h" | #include <tommath_class.h> | ||||||
| #else | #else | ||||||
| #   define LTM_LAST | #   define LTM_LAST | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user