fixes for MP_8BIT and mx32, prefinal design
This commit is contained in:
		
							parent
							
								
									8cb2b5e216
								
							
						
					
					
						commit
						f4449362c0
					
				| @ -42,7 +42,8 @@ int mp_get_bit(const mp_int *a, int b) | |||||||
|       return MP_VAL; |       return MP_VAL; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    bit = (mp_digit)1 << ((mp_digit)b % DIGIT_BIT); |    bit = (mp_digit)(1) << (b % DIGIT_BIT); | ||||||
|  | 
 | ||||||
|    isset = a->dp[limb] & bit; |    isset = a->dp[limb] & bit; | ||||||
|    return (isset != 0) ? MP_YES : MP_NO; |    return (isset != 0) ? MP_YES : MP_NO; | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,24 +14,23 @@ | |||||||
|  * guarantee it works. |  * 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 | #ifdef MP_8BIT | ||||||
| /*
 | /*
 | ||||||
|  * floor of positive solution of |  * floor of positive solution of | ||||||
|  * (2^16)-1 = (a+4)*(2*a+5) |  * (2^16)-1 = (a+4)*(2*a+5) | ||||||
|  * TODO: that is too small, would have to use a bigint for a instead |  * 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 | #define LTM_FROBENIUS_UNDERWOOD_A 177 | ||||||
| /*
 |  | ||||||
|  * 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 | #else | ||||||
| /*
 |  | ||||||
|  * 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 | #define LTM_FROBENIUS_UNDERWOOD_A 32764 | ||||||
| #endif | #endif | ||||||
| int mp_prime_frobenius_underwood(const mp_int *N, int *result) | int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||||
| @ -78,8 +77,9 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | |||||||
|          goto LBL_FU_ERR; |          goto LBL_FU_ERR; | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  |    /* Tell it a composite and set return value accordingly */ | ||||||
|    if (a >= LTM_FROBENIUS_UNDERWOOD_A) { |    if (a >= LTM_FROBENIUS_UNDERWOOD_A) { | ||||||
|       e = MP_VAL; |       e = MP_ITER; | ||||||
|       goto LBL_FU_ERR; |       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 */ | ||||||
| @ -113,6 +113,7 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | |||||||
|       if ((e = mp_mul_2(&tz,&T2z)) != MP_OKAY) { |       if ((e = mp_mul_2(&tz,&T2z)) != MP_OKAY) { | ||||||
|          goto LBL_FU_ERR; |          goto LBL_FU_ERR; | ||||||
|       } |       } | ||||||
|  | 
 | ||||||
|       /* a = 0 at about 50% of the cases (non-square and odd input) */ |       /* a = 0 at about 50% of the cases (non-square and odd input) */ | ||||||
|       if (a != 0) { |       if (a != 0) { | ||||||
|          if ((e = mp_mul_d(&sz,(mp_digit)a,&T1z)) != MP_OKAY) { |          if ((e = mp_mul_d(&sz,(mp_digit)a,&T1z)) != MP_OKAY) { | ||||||
| @ -122,6 +123,7 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | |||||||
|             goto LBL_FU_ERR; |             goto LBL_FU_ERR; | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|  | 
 | ||||||
|       if ((e = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) { |       if ((e = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) { | ||||||
|          goto LBL_FU_ERR; |          goto LBL_FU_ERR; | ||||||
|       } |       } | ||||||
| @ -151,9 +153,7 @@ int mp_prime_frobenius_underwood(const mp_int *N, int *result) | |||||||
|           *  sz   = temp |           *  sz   = temp | ||||||
|           */ |           */ | ||||||
|          if (a == 0) { |          if (a == 0) { | ||||||
|             if ((e = mp_mul_2(&sz,&T1z)) != MP_OKAY) { |             if ((e = mp_mul_2(&sz,&T1z)) != MP_OKAY) {               goto LBL_FU_ERR;            } | ||||||
|                goto LBL_FU_ERR; |  | ||||||
|             } |  | ||||||
|          } else { |          } else { | ||||||
|             if ((e = mp_mul_d(&sz, (mp_digit) ap2, &T1z)) != MP_OKAY) { |             if ((e = mp_mul_d(&sz, (mp_digit) ap2, &T1z)) != MP_OKAY) { | ||||||
|                goto LBL_FU_ERR; |                goto LBL_FU_ERR; | ||||||
| @ -189,3 +189,4 @@ LBL_FU_ERR: | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | #endif | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ | |||||||
|  * guarantee it works. |  * guarantee it works. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| // portable integer log of two with small footprint
 | /* portable integer log of two with small footprint */ | ||||||
| static unsigned int floor_ilog2(int value) | static unsigned int floor_ilog2(int value) | ||||||
| { | { | ||||||
|    unsigned int r = 0; |    unsigned int r = 0; | ||||||
| @ -71,7 +71,7 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | |||||||
|       } |       } | ||||||
|    } |    } | ||||||
| #ifdef MP_8BIT | #ifdef MP_8BIT | ||||||
|    // The search in the loop above was exhaustive in this case
 |    /* The search in the loop above was exhaustive in this case */ | ||||||
|    if (a->used == 1 && PRIME_SIZE >= 31) { |    if (a->used == 1 && PRIME_SIZE >= 31) { | ||||||
|       return MP_OKAY; |       return MP_OKAY; | ||||||
|    } |    } | ||||||
| @ -113,31 +113,41 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | |||||||
|       goto LBL_B; |       goto LBL_B; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
| 
 | /*
 | ||||||
| #ifdef MP_8BIT |  * Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite | ||||||
|    if(t >= 0 && t < 8) { |  * slow so if speed is an issue, define LTM_USE_FIPS_ONLY to use M-R tests with | ||||||
|       t = 8; |  * 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 | #else | ||||||
| /* commented out for testing purposes */ |  | ||||||
| /* #ifdef LTM_USE_STRONG_LUCAS_SELFRIDGE_TEST */ |  | ||||||
|       if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) { |       if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) { | ||||||
|          goto LBL_B; |          goto LBL_B; | ||||||
|       } |       } | ||||||
|       if (res == MP_NO) { |       if (res == MP_NO) { | ||||||
|          goto LBL_B; |          goto LBL_B; | ||||||
|       } |       } | ||||||
| /* #endif */ | #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; |  | ||||||
|    } |  | ||||||
|    if (res == MP_NO) { |  | ||||||
|       goto LBL_B; |  | ||||||
|    } |    } | ||||||
| #endif | #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. |       abs(t) extra rounds of M-R to extend the range of primes it can find if t < 0. | ||||||
| @ -147,7 +157,7 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result) | |||||||
|       The caller has to check the size. |       The caller has to check the size. | ||||||
| 
 | 
 | ||||||
|       Not for cryptographic use because with known bases strong M-R pseudoprimes can |       Not for cryptographic use because with known bases strong M-R pseudoprimes can | ||||||
|       be constructed. Use at least one MM-R test with a random base (t >= 1). |       be constructed. Use at least one M-R test with a random base (t >= 1). | ||||||
| 
 | 
 | ||||||
|       The 1119 bit large number |       The 1119 bit large number | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,6 +14,11 @@ | |||||||
|  * guarantee it works. |  * 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 |  *  8-bit is just too small. You can try the Frobenius test | ||||||
|  *  but that frobenius test can fail, too, for the same reason. |  *  but that frobenius test can fail, too, for the same reason. | ||||||
| @ -401,3 +406,4 @@ LBL_LS_ERR: | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
|  | #endif | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								doc/bn.tex
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								doc/bn.tex
									
									
									
									
									
								
							| @ -1829,7 +1829,7 @@ You should always still perform a trial division before a Miller-Rabin test thou | |||||||
| \begin{alltt} | \begin{alltt} | ||||||
| int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) | int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) | ||||||
| \end{alltt} | \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 as a compile-time option in \texttt{mp\_prime\_is\_prime} and can be excluded | 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. | from the Libtommath build if not needed. | ||||||
| 
 | 
 | ||||||
| \section{Frobenius (Underwood)  Test} | \section{Frobenius (Underwood)  Test} | ||||||
| @ -1837,8 +1837,11 @@ from the Libtommath build if not needed. | |||||||
| \begin{alltt} | \begin{alltt} | ||||||
| int mp_prime_frobenius_underwood(const mp_int *N, int *result) | int mp_prime_frobenius_underwood(const mp_int *N, int *result) | ||||||
| \end{alltt} | \end{alltt} | ||||||
| Performs the variant of the Frobenius test as described by Paul Underwood. The single internal use is as a compile-time option in | Performs the variant of the Frobenius test as described by Paul Underwood. The single internal use is in | ||||||
| \texttt{mp\_prime\_is\_prime} and can be excluded from the Libtommath build if not needed. | \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. | ||||||
| @ -1852,13 +1855,14 @@ 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 two rounds of Miller-Rabin with bases 2 and 3. It is possible, although only at | 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 | ||||||
| the compile time of this library for now, to include a strong Lucas-Selfridge test and/or a Frobenius test. See file |  | ||||||
| \texttt{bn\_mp\_prime\_is\_prime.c} for the necessary details. It shall be noted that both functions are much slower than | \texttt{bn\_mp\_prime\_is\_prime.c} for the necessary details. It shall be noted that both functions are much slower than | ||||||
| the Miller-Rabin test. | 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. | 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 | 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 | $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 | Miller-Rabin test will be performed but note that $-t$ is bounded by $1 \le -t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number | ||||||
|  | |||||||
| @ -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 */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user