Skip to content

Commit

Permalink
Further refinement of the deterministic part of prime_is_prime
Browse files Browse the repository at this point in the history
  • Loading branch information
czurnieden committed Apr 4, 2023
1 parent e1e24c6 commit 6fbbc0e
Showing 1 changed file with 42 additions and 14 deletions.
56 changes: 42 additions & 14 deletions mp_prime_is_prime.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ static unsigned int s_floor_ilog2(int value)
mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
{
mp_int b;
int ix;
int ix, bits;
bool res;
mp_err err;
mp_err err = MP_OKAY;

/* default to no */
*result = false;
Expand Down Expand Up @@ -59,11 +59,19 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
if ((err = s_mp_prime_is_divisible(a, &res)) != MP_OKAY) {
return err;
}

/* return if it was trivially divisible */
if (res) {
return MP_OKAY;
}
/* floor(log_2(a)) */
bits = mp_count_bits(a) - 1;

/* If the whole prime table up to p = 1619 has been tested, than all
numbers below 1621^2 = 2,627,641 are prime now. log_2(1621^2) ~ 21.33 */
if (bits < 21) {
*result = true;
return MP_OKAY;
}

/*
Run the Miller-Rabin test with base 2 for the BPSW test.
Expand All @@ -78,6 +86,15 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
if (!res) {
goto LBL_B;
}
/* If the whole prime table up to p = 1619 and the Miller-Rabin tests to base two
has been applied, than all numbers below 4,469,471 (~2^{22.1}) are prime now.
With 1659 SPSPs < 2^32 left */
#if ((defined S_MP_PRIME_IS_DIVISIBLE_C) && (MP_PRIME_TAB_SIZE >= 256))
if (bits < 22) {
*result = true;
goto LBL_B;
}
#endif
/*
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.
Expand All @@ -91,6 +108,15 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
goto LBL_B;
}

/* If the whole prime table up to p = 1619 and the Miller-Rabin tests to bases
two and three have been applied, than all numbers below 11,541,307 (~2^{23.5}) are prime now.
With 89 SPSPs < 2^32 left */
#if ((defined S_MP_PRIME_IS_DIVISIBLE_C) && (MP_PRIME_TAB_SIZE >= 256))
if (bits < 23) {
*result = true;
goto LBL_B;
}
#endif
/*
* Both, the Frobenius-Underwood test and the the extra strong Lucas test are quite
* slow so if speed is an issue, define LTM_USE_ONLY_MR to use M-R tests with
Expand Down Expand Up @@ -125,7 +151,7 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
if (t == 0) {
#ifndef LTM_USE_ONLY_MR
/* The BPSW version as used here has no counter-example below 2^64 */
if (mp_count_bits(a) < 64) {
if (bits < 64) {
*result = true;
goto LBL_B;
}
Expand All @@ -142,9 +168,7 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
The caller has to check the maximum size.
*/
if (t < 0) {
int p_max = 0, bits;
bits = mp_count_bits(a);

int p_max = 0;
#ifndef LTM_USE_ONLY_MR
if (bits < 64) {
/* Just complete the BPSW test */
Expand All @@ -155,8 +179,8 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
goto LBL_B;
}
#else
/* Base 2 has been done already at this point */

/* Base 2 has been done already at this point. Also possible: { (2, 3,) 5, 13} to avoid waste */
/* 2, 7, 61 found by Gerhard Jaeschke 1993 */
mp_digit bases32 = {7u, 61u};
/* 2, 325, 9375, 28178, 450775, 9780504, 1795265022 found by Jim Sinclair 2011 */
uint32_t bases64 = {325ull, 9375ull, 28178ull, 450775ull, 9780504ull, 1795265022ull};
Expand Down Expand Up @@ -196,21 +220,27 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
Comparing bigints is not free, so give the magnitude of "n" a rough check
before spending computing time.
*/
if (bits <= 78) {

else if ((bits >= 64) && (bits <= 78)) {
/* 0x437ae92817f9fc85b7e5 = 318665857834031151167461 */
if ((err = mp_read_radix(&b, "437ae92817f9fc85b7e5", 16)) != MP_OKAY) {
goto LBL_B;
}
if (mp_cmp(a, &b) == MP_LT) {
p_max = 12;
} else {
p_max = 13;
}
} else if ((bits > 78) && (bits < 82)) {
} else if ((bits >= 78) && (bits <= 81)) {
/* 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;
}
} else {
err = MP_VAL;
Expand All @@ -232,10 +262,9 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
Do "t" M-R tests with random bases between 3 and "a".
See Fips 186.4 p. 126ff
*/
else if (t > 0) {
if (t > 0) {
unsigned int mask;
int size_a;

/*
* 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
Expand Down Expand Up @@ -283,7 +312,6 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result)
for (ix = 0; ix < t; ix++) {
unsigned int fips_rand;
int len;

/* mp_rand() guarantees the first digit to be non-zero */
if ((err = mp_rand(&b, 1)) != MP_OKAY) {
goto LBL_B;
Expand Down

0 comments on commit 6fbbc0e

Please sign in to comment.