changes and bigfixes, see pull-request #113 at https://github.com/libtom/libtommath/pull/113 for details
This commit is contained in:
		
							parent
							
								
									38e8f93bdb
								
							
						
					
					
						commit
						934dd31738
					
				| @ -27,6 +27,21 @@ int mp_get_bit(const mp_int *a, int b) | ||||
|    } | ||||
| 
 | ||||
|    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 << ((mp_digit)b % DIGIT_BIT); | ||||
|    isset = a->dp[limb] & bit; | ||||
|    return (isset != 0) ? MP_YES : MP_NO; | ||||
|  | ||||
| @ -101,14 +101,16 @@ int mp_kronecker(const mp_int *a, const mp_int *p, int *c) | ||||
|       } | ||||
| 
 | ||||
|       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
 | ||||
|          /*
 | ||||
|           * 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
 | ||||
|          /* compute k = (-1)^((a1-1)*(p1-1)/4) * k */ | ||||
|          if (a1.dp[0] & p1.dp[0] & 2u) { | ||||
|             k = -k; | ||||
|          } | ||||
| @ -128,9 +130,9 @@ int mp_kronecker(const mp_int *a, const mp_int *p, int *c) | ||||
| 
 | ||||
| LBL_KRON: | ||||
|    mp_clear(&r); | ||||
| LBL_KRON_0: | ||||
|    mp_clear(&a1); | ||||
| LBL_KRON_1: | ||||
|    mp_clear(&a1); | ||||
| LBL_KRON_0: | ||||
|    mp_clear(&p1); | ||||
|    return e; | ||||
| } | ||||
|  | ||||
| @ -16,17 +16,23 @@ | ||||
| 
 | ||||
| 
 | ||||
| #ifdef MP_8BIT | ||||
| // floor of positive solution of
 | ||||
| // (2^16)-1 = (a+4)*(2*a+5)
 | ||||
| // TODO: that is too small, would have to use a bigint for a instead
 | ||||
| /*
 | ||||
|  * floor of positive solution of | ||||
|  * (2^16)-1 = (a+4)*(2*a+5) | ||||
|  * TODO: that is too small, would have to use a bigint for a instead | ||||
|  */ | ||||
| #define LTM_FROBENIUS_UNDERWOOD_A 177 | ||||
| // commented out to allow Travis's tests to run
 | ||||
| // Don't forget to switch in back on in production or we'll find it at TDWTF.com!
 | ||||
| //#warning "Frobenius test not fully usable with MP_8BIT!"
 | ||||
| /*
 | ||||
|  * Commented out to allow Travis's tests to run | ||||
|  * Don't forget to switch it back on in production or we'll find it at TDWTF.com! | ||||
|  */ | ||||
|  /* #warning "Frobenius test not fully usable with MP_8BIT!" */ | ||||
| #else | ||||
| // floor of positive solution of
 | ||||
| // (2^31)-1 = (a+4)*(2*a+5)
 | ||||
| // TODO: that might be too small
 | ||||
| /*
 | ||||
|  * floor of positive solution of | ||||
|  * (2^31)-1 = (a+4)*(2*a+5) | ||||
|  * TODO: that might be too small | ||||
|  */ | ||||
| #define LTM_FROBENIUS_UNDERWOOD_A 32764 | ||||
| #endif | ||||
| int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||
| @ -43,11 +49,11 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||
|    } | ||||
| 
 | ||||
|    for (a = 0; a < LTM_FROBENIUS_UNDERWOOD_A; a++) { | ||||
|       //TODO: That's ugly! No, really, it is!
 | ||||
|       /* 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)
 | ||||
|       /* (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; | ||||
|       } | ||||
| @ -69,7 +75,7 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||
|       } | ||||
| 
 | ||||
|       if (j == 0) { | ||||
|          // composite
 | ||||
|          /* composite */ | ||||
|          goto LBL_FU_ERR; | ||||
|       } | ||||
|    } | ||||
| @ -77,7 +83,7 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||
|       e = MP_VAL; | ||||
|       goto LBL_FU_ERR; | ||||
|    } | ||||
|    // Composite if N and (a+4)*(2*a+5) are not coprime
 | ||||
|    /* 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; | ||||
|    } | ||||
| @ -101,14 +107,14 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||
| 
 | ||||
|    for (i = length - 2; i >= 0; i--) { | ||||
|       /*
 | ||||
|          temp = (sz*(a*sz+2*tz))%N; | ||||
|          tz   = ((tz-sz)*(tz+sz))%N; | ||||
|          sz   = temp; | ||||
|        * 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; | ||||
|       } | ||||
|       // TODO: is this small saving worth the branch?
 | ||||
|       /* 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; | ||||
| @ -141,9 +147,9 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||
|       } | ||||
|       if (isset == MP_YES) { | ||||
|          /*
 | ||||
|              temp = (a+2) * sz + tz | ||||
|              tz   = 2 * tz - sz | ||||
|              sz   = temp | ||||
|           *  temp = (a+2) * sz + tz | ||||
|           *  tz   = 2 * tz - sz | ||||
|           *  sz   = temp | ||||
|           */ | ||||
|          if (a == 0) { | ||||
|             if ((e = mp_mul_2(&sz,&T1z)) != MP_OKAY) { | ||||
|  | ||||
| @ -119,16 +119,16 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | ||||
|       t = 8; | ||||
|    } | ||||
| #else | ||||
| // commented out for testing purposes
 | ||||
| //#ifdef LTM_USE_STRONG_LUCAS_SELFRIDGE_TEST
 | ||||
| /* commented out for testing purposes */ | ||||
| /* #ifdef LTM_USE_STRONG_LUCAS_SELFRIDGE_TEST */ | ||||
|    if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) { | ||||
|       goto LBL_B; | ||||
|    } | ||||
|    if (res == MP_NO) { | ||||
|       goto LBL_B; | ||||
|    } | ||||
| //#endif
 | ||||
| // commented out for testing purposes
 | ||||
| /* #endif */ | ||||
| /* commented out for testing purposes */ | ||||
| #ifdef LTM_USE_FROBENIUS_UNDERWOOD_TEST | ||||
|    if ((err = mp_prime_frobenius_underwood(a, &res)) != MP_OKAY) { | ||||
|       goto LBL_B; | ||||
| @ -223,12 +223,14 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | ||||
|        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.
 | ||||
|       /*
 | ||||
|        * 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 << floor_ilog2(size_a)) - 1u; | ||||
|       /*
 | ||||
| @ -266,16 +268,20 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | ||||
|         need to be prime. | ||||
|       */ | ||||
|       for (ix = 0; ix < t; ix++) { | ||||
|          // mp_rand() guarantees the first digit to be non-zero
 | ||||
|          /* 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.
 | ||||
|          /* 
 | ||||
|           * 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.
 | ||||
|          /*
 | ||||
|           * 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; | ||||
| @ -285,19 +291,21 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | ||||
|             fips_rand &= mask; | ||||
|          } | ||||
| #endif | ||||
|          // Ceil, because small numbers have a right to live, too,
 | ||||
|          /* Ceil, because small numbers have a right to live, too, */ | ||||
|          len = (int) ( (fips_rand + DIGIT_BIT) / DIGIT_BIT); | ||||
|          // Unlikely.
 | ||||
|          /*  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.
 | ||||
|          /*
 | ||||
|           * 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
 | ||||
|          /* All "a" < 2^8 have been caught before */ | ||||
|          if(len == 1){ | ||||
|             len++; | ||||
|          } | ||||
| @ -305,15 +313,17 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | ||||
|          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"
 | ||||
|          /*
 | ||||
|           * 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.
 | ||||
|          /* Although the chance for b <= 3 is miniscule, try again. */ | ||||
|          if (mp_cmp_d(&b,3) != MP_GT) { | ||||
|             ix--; | ||||
|             continue; | ||||
|  | ||||
| @ -28,16 +28,16 @@ | ||||
|     liability arising from its use | ||||
| 
 | ||||
|     The multi-line comments are made by Thomas R. Nicely and are copied verbatim. | ||||
|     Single-line comments are by the code-portist. | ||||
|     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) | ||||
| { | ||||
|    // TODO: choose better variable names!
 | ||||
|    /* CZ TODO: choose better variable names! */ | ||||
|    mp_int Dz, gcd, Np1, Uz, Vz, U2mz, V2mz, Qmz, Q2mz, Qkdz, T1z, T2z, T3z, T4z, Q2kdz; | ||||
|    // TODO: Some of them need the full 32 bit, hence the (temporary) exclusion of MP_8BIT
 | ||||
|    /* 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; | ||||
| @ -131,9 +131,13 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) | ||||
|    } | ||||
|    s = mp_cnt_lsb(&Np1); | ||||
| 
 | ||||
|    // this should round towards zero because
 | ||||
|    // Thomas R. Nicely used GMP's mpz_tdiv_q_2exp()
 | ||||
|    // and mp_div_2d() is equivalent
 | ||||
|    /* 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; | ||||
|    } | ||||
| @ -211,7 +215,7 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) | ||||
|       if ((e = mp_sqr(&Qmz,&Qmz)) != MP_OKAY) { | ||||
|          goto LBL_LS_ERR; | ||||
|       } | ||||
|       /* prevents overflow */ // still necessary without a fixed prealloc'd mem.?
 | ||||
|       /* prevents overflow */ /* CZ  still necessary without a fixed prealloc'd mem.? */ | ||||
|       if ((e = mp_mod(&Qmz,a,&Qmz)) != MP_OKAY) { | ||||
|          goto LBL_LS_ERR; | ||||
|       } | ||||
| @ -255,9 +259,11 @@ int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) | ||||
|                goto LBL_LS_ERR; | ||||
|             } | ||||
|          } | ||||
|          // 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.
 | ||||
|          /* 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; | ||||
|          } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user