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 */
|
if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) {
|
||||||
/* #ifdef LTM_USE_STRONG_LUCAS_SELFRIDGE_TEST */
|
goto LBL_B;
|
||||||
if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) {
|
}
|
||||||
goto LBL_B;
|
if (res == MP_NO) {
|
||||||
}
|
goto LBL_B;
|
||||||
if (res == MP_NO) {
|
}
|
||||||
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