Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed range of random produced in BN_is_prime_fasttest_ex() #6547

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 13 additions & 15 deletions crypto/bn/bn_prime.c
Expand Up @@ -154,19 +154,21 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
int i, j, ret = -1;
int k;
BN_CTX *ctx = NULL;
BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
BIGNUM *A1, *A1_odd, *A3, *check; /* taken from ctx */
BN_MONT_CTX *mont = NULL;

if (BN_cmp(a, BN_value_one()) <= 0)
/* Take care of the really small primes 2 & 3 */
if (BN_is_word(a, 2) || BN_is_word(a, 3))
return 1;

/* Check odd and bigger than 1 */
if (!BN_is_odd(a) || BN_cmp(a, BN_value_one()) <= 0)
return 0;

if (checks == BN_prime_checks)
checks = BN_prime_checks_for_size(BN_num_bits(a));

/* first look for small factors */
if (!BN_is_odd(a))
/* a is even => a is prime if and only if a == 2 */
return BN_is_word(a, 2);
if (do_trial_division) {
for (i = 1; i < NUMPRIMES; i++) {
BN_ULONG mod = BN_mod_word(a, primes[i]);
Expand All @@ -186,20 +188,18 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
BN_CTX_start(ctx);

A1 = BN_CTX_get(ctx);
A3 = BN_CTX_get(ctx);
A1_odd = BN_CTX_get(ctx);
check = BN_CTX_get(ctx);
if (check == NULL)
goto err;

/* compute A1 := a - 1 */
if (!BN_copy(A1, a))
goto err;
if (!BN_sub_word(A1, 1))
if (!BN_copy(A1, a) || !BN_sub_word(A1, 1))
goto err;
if (BN_is_zero(A1)) {
ret = 0;
/* compute A3 := a - 3 */
if (!BN_copy(A3, a) || !BN_sub_word(A3, 3))
goto err;
}

/* write A1 as A1_odd * 2^k */
k = 1;
Expand All @@ -216,11 +216,9 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
goto err;

for (i = 0; i < checks; i++) {
if (!BN_priv_rand_range(check, A1))
goto err;
if (!BN_add_word(check, 1))
/* 1 < check < a-1 */
if (!BN_priv_rand_range(check, A3) || !BN_add_word(check, 2))
goto err;
/* now 1 <= check < a */

j = witness(check, a, A1, A1_odd, k, ctx, mont);
if (j == -1)
Expand Down
48 changes: 36 additions & 12 deletions test/bntest.c
Expand Up @@ -2128,25 +2128,48 @@ static int test_smallprime(void)
return st;
}

static int test_3_is_prime(void)
static int primes[] = { 2, 3, 5, 7, 17863 };

static int test_is_prime(int i)
{
int ret = 0;
BIGNUM *r = NULL;
int trial;

/*
* For a long time, small primes were not considered prime when
* do_trial_division was set.
*/
if (!TEST_ptr(r = BN_new())
|| !TEST_true(BN_set_word(r, 3))
|| !TEST_int_eq(BN_is_prime_fasttest_ex(r, 3 /* nchecks */, ctx,
0 /* do_trial_division */, NULL), 1)
|| !TEST_int_eq(BN_is_prime_fasttest_ex(r, 3 /* nchecks */, ctx,
1 /* do_trial_division */, NULL), 1))
if (!TEST_ptr(r = BN_new()))
goto err;

for (trial = 0; trial <= 1; ++trial) {
if (!TEST_true(BN_set_word(r, primes[i]))
|| !TEST_int_eq(BN_is_prime_fasttest_ex(r, 1, ctx, trial, NULL),
1))
goto err;
}

ret = 1;
err:
BN_free(r);
return ret;
}

static int not_primes[] = { -1, 0, 1, 4 };

static int test_not_prime(int i)
{
int ret = 0;
BIGNUM *r = NULL;
int trial;

if (!TEST_ptr(r = BN_new()))
goto err;

for (trial = 0; trial <= 1; ++trial) {
if (!TEST_true(BN_set_word(r, not_primes[i]))
|| !TEST_false(BN_is_prime_fasttest_ex(r, 1, ctx, trial, NULL)))
goto err;
}

ret = 1;
err:
BN_free(r);
return ret;
Expand Down Expand Up @@ -2250,7 +2273,8 @@ int setup_tests(void)
ADD_TEST(test_gf2m_modsqrt);
ADD_TEST(test_gf2m_modsolvequad);
#endif
ADD_TEST(test_3_is_prime);
ADD_ALL_TESTS(test_is_prime, (int)OSSL_NELEM(primes));
ADD_ALL_TESTS(test_not_prime, (int)OSSL_NELEM(not_primes));
} else {
ADD_ALL_TESTS(run_file_tests, n);
}
Expand Down