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:
parent
f17d90b96d
commit
a218ddce9b
@ -13,26 +13,59 @@
|
|||||||
* 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 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) {
|
||||||
|
puts("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) {
|
||||||
|
*result = 0;
|
||||||
|
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) {
|
||||||
|
*result = 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) {
|
||||||
@ -51,22 +84,218 @@ 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++) {
|
|
||||||
/* set the prime */
|
|
||||||
mp_set(&b, ltm_prime_tab[ix]);
|
|
||||||
|
|
||||||
if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
|
if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
|
||||||
goto LBL_B;
|
goto LBL_B;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == MP_NO) {
|
if (res == MP_NO) {
|
||||||
goto LBL_B;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
//#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
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 MM-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".
|
||||||
|
*/
|
||||||
|
/* 318665857834031151167461 */
|
||||||
|
if ((err = mp_read_radix(&b, "437ae92817f9fc85b7e5", 16)) != MP_OKAY) {
|
||||||
|
goto LBL_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp_cmp(a,&b) == MP_LT) {
|
||||||
|
p_max = 12;
|
||||||
|
}
|
||||||
|
/* 3317044064679887385961981 */
|
||||||
|
if ((err = mp_read_radix(&b, "2be6951adc5b22410a5fd", 16)) != MP_OKAY) {
|
||||||
|
goto LBL_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp_cmp(a,&b) == MP_LT) {
|
||||||
|
p_max = 13;
|
||||||
|
}
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
/* 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 << 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];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
len = (int) ((fips_rand & mask)/ DIGIT_BIT);
|
||||||
|
// Unlikely, but still possible.
|
||||||
|
if(len < 0){
|
||||||
|
ix--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((err = mp_rand(&b, len)) != MP_OKAY) {
|
||||||
|
goto LBL_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 +304,7 @@ LBL_B:
|
|||||||
mp_clear(&b);
|
mp_clear(&b);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ref: $Format:%D$ */
|
/* ref: $Format:%D$ */
|
||||||
|
86
doc/bn.tex
86
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,22 @@ 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.
|
||||||
|
|
||||||
|
\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 as 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 as a compile-time option in
|
||||||
|
\texttt{mp\_prime\_is\_prime} and can be excluded from the Libtommath build if not needed.
|
||||||
|
|
||||||
\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 +1852,28 @@ 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. It is possible, although only at
|
||||||
If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero. Note that $t$ is bounded by
|
the compile time of this library for now, to include a strong Lucas-Selfridge test and/or a Frobenius test. See file
|
||||||
$1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$).
|
\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.
|
||||||
|
|
||||||
|
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 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 +1883,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 +2054,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 +2080,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 +2133,12 @@ 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$.
|
||||||
|
|
||||||
|
\index{mp\_mul\_si}
|
||||||
|
\begin{alltt}
|
||||||
|
int mp_mul_si(mp_int *a, long b, mp_int *c);
|
||||||
|
\end{alltt}
|
||||||
|
Just like the functions above but with the ability to use a signed input as the small number.
|
||||||
|
|
||||||
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}
|
||||||
|
33
tommath.h
33
tommath.h
@ -298,6 +298,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);
|
||||||
|
|
||||||
@ -359,6 +364,10 @@ int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c);
|
|||||||
/* c = a * b */
|
/* c = a * b */
|
||||||
int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c);
|
int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c);
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
int mp_mul_si(const mp_int *a, long d, mp_int *c);
|
||||||
|
|
||||||
/* a/b => cb + d == a */
|
/* a/b => cb + d == a */
|
||||||
int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
|
int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
|
||||||
|
|
||||||
@ -417,6 +426,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 +510,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
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user