提交 aff0825c 编写于 作者: B Bodo Möller

Tolerate negative numbers in BN_is_prime.

上级 e74231ed
...@@ -404,9 +404,10 @@ int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx); ...@@ -404,9 +404,10 @@ int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add, BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg); BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *), int BN_is_prime(const BIGNUM *p,int nchecks,
void (*callback)(int,int,void *),
BN_CTX *ctx,void *cb_arg); BN_CTX *ctx,void *cb_arg);
int BN_is_prime_fasttest(BIGNUM *p,int nchecks, int BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg, void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
int do_trial_division); int do_trial_division);
void ERR_load_BN_strings(void ); void ERR_load_BN_strings(void );
......
...@@ -203,7 +203,7 @@ extern "C" { ...@@ -203,7 +203,7 @@ extern "C" {
BN_ULLONG t; \ BN_ULLONG t; \
t=(BN_ULLONG)(a)*(a); \ t=(BN_ULLONG)(a)*(a); \
(r0)=Lw(t); \ (r0)=Lw(t); \
(r1)=Hw(t); ] (r1)=Hw(t); \
} }
#elif defined(BN_UMULT_HIGH) #elif defined(BN_UMULT_HIGH)
......
...@@ -154,13 +154,13 @@ err: ...@@ -154,13 +154,13 @@ err:
return(found ? rnd : NULL); return(found ? rnd : NULL);
} }
int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
BN_CTX *ctx_passed, void *cb_arg) BN_CTX *ctx_passed, void *cb_arg)
{ {
return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0); return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0);
} }
int BN_is_prime_fasttest(BIGNUM *a, int checks, int BN_is_prime_fasttest(const BIGNUM *a, int checks,
void (*callback)(int,int,void *), void (*callback)(int,int,void *),
BN_CTX *ctx_passed, void *cb_arg, BN_CTX *ctx_passed, void *cb_arg,
int do_trial_division) int do_trial_division)
...@@ -168,15 +168,13 @@ int BN_is_prime_fasttest(BIGNUM *a, int checks, ...@@ -168,15 +168,13 @@ int BN_is_prime_fasttest(BIGNUM *a, int checks,
int i, j, ret = -1; int i, j, ret = -1;
int k; int k;
BN_CTX *ctx = NULL; BN_CTX *ctx = NULL;
BIGNUM *a1, *a1_odd, *check; /* taken from ctx */ BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
BN_MONT_CTX *mont = NULL; BN_MONT_CTX *mont = NULL;
BIGNUM *A;
if (checks == BN_prime_checks) if (checks == BN_prime_checks)
checks = BN_prime_checks_for_size(BN_num_bits(a)); checks = BN_prime_checks_for_size(BN_num_bits(a));
if (a->neg) /* for now, refuse to handle negative numbers */
return -1;
/* first look for small factors */ /* first look for small factors */
if (!BN_is_odd(a)) if (!BN_is_odd(a))
return(0); return(0);
...@@ -193,47 +191,56 @@ int BN_is_prime_fasttest(BIGNUM *a, int checks, ...@@ -193,47 +191,56 @@ int BN_is_prime_fasttest(BIGNUM *a, int checks,
else else
if ((ctx=BN_CTX_new()) == NULL) if ((ctx=BN_CTX_new()) == NULL)
goto err; goto err;
a1 = &(ctx->bn[ctx->tos++]); /* A := abs(a) */
a1_odd = &(ctx->bn[ctx->tos++]); if (a->neg)
{
A = &(ctx->bn[ctx->tos++]);
BN_copy(A, a);
A->neg = 0;
}
else
A = a;
A1 = &(ctx->bn[ctx->tos++]);
A1_odd = &(ctx->bn[ctx->tos++]);
check = &(ctx->bn[ctx->tos++]);; check = &(ctx->bn[ctx->tos++]);;
/* compute a1 := a - 1 */ /* compute A1 := A - 1 */
if (!BN_copy(a1, a)) if (!BN_copy(A1, A))
goto err; goto err;
if (!BN_sub_word(a1, 1)) if (!BN_sub_word(A1, 1))
goto err; goto err;
if (BN_is_zero(a1)) if (BN_is_zero(A1))
{ {
ret = 0; ret = 0;
goto err; goto err;
} }
/* write a1 as a1_odd * 2^k */ /* write A1 as A1_odd * 2^k */
k = 1; k = 1;
while (!BN_is_bit_set(a1, k)) while (!BN_is_bit_set(A1, k))
k++; k++;
if (!BN_rshift(a1_odd, a1, k)) if (!BN_rshift(A1_odd, A1, k))
goto err; goto err;
/* Montgomery setup for computations mod a */ /* Montgomery setup for computations mod A */
mont = BN_MONT_CTX_new(); mont = BN_MONT_CTX_new();
if (mont == NULL) if (mont == NULL)
goto err; goto err;
if (!BN_MONT_CTX_set(mont, a, ctx)) if (!BN_MONT_CTX_set(mont, A, ctx))
goto err; goto err;
for (i = 0; i < checks; i++) for (i = 0; i < checks; i++)
{ {
if (!BN_pseudo_rand(check, BN_num_bits(a1), 0, 0)) if (!BN_pseudo_rand(check, BN_num_bits(A1), 0, 0))
goto err; goto err;
if (BN_cmp(check, a1) >= 0) if (BN_cmp(check, A1) >= 0)
if (!BN_sub(check, check, a1)) if (!BN_sub(check, check, A1))
goto err; goto err;
if (!BN_add_word(check, 1)) if (!BN_add_word(check, 1))
goto err; goto err;
/* now 1 <= check < a */ /* now 1 <= check < A */
j = witness(check, a, a1, a1_odd, k, ctx, mont); j = witness(check, A, A1, A1_odd, k, ctx, mont);
if (j == -1) goto err; if (j == -1) goto err;
if (j) if (j)
{ {
...@@ -245,7 +252,11 @@ int BN_is_prime_fasttest(BIGNUM *a, int checks, ...@@ -245,7 +252,11 @@ int BN_is_prime_fasttest(BIGNUM *a, int checks,
ret=1; ret=1;
err: err:
if (ctx_passed != NULL) if (ctx_passed != NULL)
ctx_passed->tos -= 3; /* a1, a1_odd, check */ {
ctx_passed->tos -= 3; /* A1, A1_odd, check */
if (a != A)
--ctx_passed->tos; /* A */
}
else if (ctx != NULL) else if (ctx != NULL)
BN_CTX_free(ctx); BN_CTX_free(ctx);
if (mont != NULL) if (mont != NULL)
......
...@@ -167,6 +167,8 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, ...@@ -167,6 +167,8 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
/* step 4 */ /* step 4 */
r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random); r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random);
if (ctx3->tos)
goto err;
if (r > 0) if (r > 0)
break; break;
if (r != 0) if (r != 0)
......
...@@ -11,11 +11,12 @@ BN_generate_prime, BN_is_prime, BN_is_prime_fasttest - Generate primes and test ...@@ -11,11 +11,12 @@ BN_generate_prime, BN_is_prime, BN_is_prime_fasttest - Generate primes and test
BIGNUM *BN_generate_prime(BIGNUM *ret, int num, int safe, BIGNUM *add, BIGNUM *BN_generate_prime(BIGNUM *ret, int num, int safe, BIGNUM *add,
BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg); BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg);
int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int, int, int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int, int,
void *), BN_CTX *ctx, void *cb_arg); void *), BN_CTX *ctx, void *cb_arg);
int BN_is_prime_fasttest(BIGNUM *a, int checks, void (*callback)(int, int BN_is_prime_fasttest(const BIGNUM *a, int checks,
int, void *), BN_CTX *ctx, void *cb_arg, int do_trial_division); void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg,
int do_trial_division);
=head1 DESCRIPTION =head1 DESCRIPTION
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册