probably_prime: run more than one Miller-Rabin round

R=rsc
http://codereview.appspot.com/462041
This commit is contained in:
Russ Cox 2010-03-11 18:04:42 -08:00
parent a1afc8529d
commit 1619f52cbc

View file

@ -9,7 +9,7 @@
int int
probably_prime(mpint *n, int nrep) probably_prime(mpint *n, int nrep)
{ {
int j, k, rep, nbits, isprime = 1; int j, k, rep, nbits, isprime;
mpint *nm1, *q, *x, *y, *r; mpint *nm1, *q, *x, *y, *r;
if(n->sign < 0) if(n->sign < 0)
@ -49,32 +49,37 @@ probably_prime(mpint *n, int nrep)
mpright(nm1, k, q); /* q = (n-1)/2**k */ mpright(nm1, k, q); /* q = (n-1)/2**k */
for(rep = 0; rep < nrep; rep++){ for(rep = 0; rep < nrep; rep++){
for(;;){
/* x = random in [2, n-2] */ /* find x = random in [2, n-2] */
r = mprand(nbits, prng, nil); r = mprand(nbits, prng, nil);
mpmod(r, nm1, x); mpmod(r, nm1, x);
mpfree(r); mpfree(r);
if(mpcmp(x, mpone) <= 0) if(mpcmp(x, mpone) > 0)
continue; break;
}
/* y = x**q mod n */ /* y = x**q mod n */
mpexp(x, q, n, y); mpexp(x, q, n, y);
if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0) if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0)
goto done; continue;
for(j = 1; j < k; j++){ for(j = 1;; j++){
if(j >= k) {
isprime = 0;
goto done;
}
mpmul(y, y, x); mpmul(y, y, x);
mpmod(x, n, y); /* y = y*y mod n */ mpmod(x, n, y); /* y = y*y mod n */
if(mpcmp(y, nm1) == 0) if(mpcmp(y, nm1) == 0)
goto done; break;
if(mpcmp(y, mpone) == 0){ if(mpcmp(y, mpone) == 0){
isprime = 0; isprime = 0;
goto done; goto done;
} }
} }
isprime = 0;
} }
isprime = 1;
done: done:
mpfree(y); mpfree(y);
mpfree(x); mpfree(x);