version 1.1.6.1, 2003/09/16 21:20:26 |
version 1.2, 2003/11/21 11:57:03 |
|
|
|
|
|
|
/* |
/* |
* Debugging defines |
* Debugging defines |
*/ |
*/ |
|
|
/* define DEBUG_LARGE 1 */ |
/* define DEBUG_LARGE 1 */ |
|
|
|
|
time(&time_now); |
time(&time_now); |
gtm = gmtime(&time_now); |
gtm = gmtime(&time_now); |
|
|
res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ", |
res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ", |
gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, |
gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, |
gtm->tm_hour, gtm->tm_min, gtm->tm_sec, |
gtm->tm_hour, gtm->tm_min, gtm->tm_sec, |
|
|
largememory = memory; |
largememory = memory; |
|
|
/* |
/* |
* Set power to the length in bits of the prime to be generated. |
* Set power to the length in bits of the prime to be generated. |
* This is changed to 1 less than the desired safe prime moduli p. |
* This is changed to 1 less than the desired safe prime moduli p. |
*/ |
*/ |
if (power > TEST_MAXIMUM) { |
if (power > TEST_MAXIMUM) { |
error("Too many bits: %u > %lu", power, TEST_MAXIMUM); |
error("Too many bits: %u > %lu", power, TEST_MAXIMUM); |
return (-1); |
return (-1); |
|
|
power--; /* decrement before squaring */ |
power--; /* decrement before squaring */ |
|
|
/* |
/* |
* The density of ordinary primes is on the order of 1/bits, so the |
* The density of ordinary primes is on the order of 1/bits, so the |
* density of safe primes should be about (1/bits)**2. Set test range |
* density of safe primes should be about (1/bits)**2. Set test range |
* to something well above bits**2 to be reasonably sure (but not |
* to something well above bits**2 to be reasonably sure (but not |
* guaranteed) of catching at least one safe prime. |
* guaranteed) of catching at least one safe prime. |
*/ |
*/ |
largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER)); |
largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER)); |
|
|
/* |
/* |
* Need idea of how much memory is available. We don't have to use all |
* Need idea of how much memory is available. We don't have to use all |
* of it. |
* of it. |
*/ |
*/ |
if (largememory > LARGE_MAXIMUM) { |
if (largememory > LARGE_MAXIMUM) { |
logit("Limited memory: %u MB; limit %lu MB", |
logit("Limited memory: %u MB; limit %lu MB", |
|
|
q = BN_new(); |
q = BN_new(); |
|
|
/* |
/* |
* Generate random starting point for subprime search, or use |
* Generate random starting point for subprime search, or use |
* specified parameter. |
* specified parameter. |
*/ |
*/ |
largebase = BN_new(); |
largebase = BN_new(); |
if (start == NULL) |
if (start == NULL) |
|
|
|
|
time(&time_start); |
time(&time_start); |
|
|
logit("%.24s Sieve next %u plus %u-bit", ctime(&time_start), |
logit("%.24s Sieve next %u plus %u-bit", ctime(&time_start), |
largenumbers, power); |
largenumbers, power); |
debug2("start point: 0x%s", BN_bn2hex(largebase)); |
debug2("start point: 0x%s", BN_bn2hex(largebase)); |
|
|
/* |
/* |
* TinySieve |
* TinySieve |
*/ |
*/ |
for (i = 0; i < tinybits; i++) { |
for (i = 0; i < tinybits; i++) { |
if (BIT_TEST(TinySieve, i)) |
if (BIT_TEST(TinySieve, i)) |
continue; /* 2*i+3 is composite */ |
continue; /* 2*i+3 is composite */ |
|
|
} |
} |
|
|
/* |
/* |
* Start the small block search at the next possible prime. To avoid |
* Start the small block search at the next possible prime. To avoid |
* fencepost errors, the last pass is skipped. |
* fencepost errors, the last pass is skipped. |
*/ |
*/ |
for (smallbase = TINY_NUMBER + 3; |
for (smallbase = TINY_NUMBER + 3; |
smallbase < (SMALL_MAXIMUM - TINY_NUMBER); |
smallbase < (SMALL_MAXIMUM - TINY_NUMBER); |
smallbase += TINY_NUMBER) { |
smallbase += TINY_NUMBER) { |
|
|
} |
} |
|
|
/* |
/* |
* SmallSieve |
* SmallSieve |
*/ |
*/ |
for (i = 0; i < smallbits; i++) { |
for (i = 0; i < smallbits; i++) { |
if (BIT_TEST(SmallSieve, i)) |
if (BIT_TEST(SmallSieve, i)) |
continue; /* 2*i+smallbase is composite */ |
continue; /* 2*i+smallbase is composite */ |
|
|
* The result is a list of so-call "safe" primes |
* The result is a list of so-call "safe" primes |
*/ |
*/ |
int |
int |
prime_test(FILE *in, FILE *out, u_int32_t trials, |
prime_test(FILE *in, FILE *out, u_int32_t trials, |
u_int32_t generator_wanted) |
u_int32_t generator_wanted) |
{ |
{ |
BIGNUM *q, *p, *a; |
BIGNUM *q, *p, *a; |
|
|
count_possible++; |
count_possible++; |
|
|
/* |
/* |
* The (1/4)^N performance bound on Miller-Rabin is |
* The (1/4)^N performance bound on Miller-Rabin is |
* extremely pessimistic, so don't spend a lot of time |
* extremely pessimistic, so don't spend a lot of time |
* really verifying that q is prime until after we know |
* really verifying that q is prime until after we know |
* that p is also prime. A single pass will weed out the |
* that p is also prime. A single pass will weed out the |
* vast majority of composite q's. |
* vast majority of composite q's. |
*/ |
*/ |
if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) { |
if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) { |
|
|
count_in); |
count_in); |
continue; |
continue; |
} |
} |
|
|
/* |
/* |
* q is possibly prime, so go ahead and really make sure |
* q is possibly prime, so go ahead and really make sure |
* that p is prime. If it is, then we can go back and do |
* that p is prime. If it is, then we can go back and do |
* the same for q. If p is composite, chances are that |
* the same for q. If p is composite, chances are that |
* will show up on the first Rabin-Miller iteration so it |
* will show up on the first Rabin-Miller iteration so it |
* doesn't hurt to specify a high iteration count. |
* doesn't hurt to specify a high iteration count. |
*/ |
*/ |
|
|
} |
} |
debug("%10u: q is almost certainly prime", count_in); |
debug("%10u: q is almost certainly prime", count_in); |
|
|
if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN), |
if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN), |
in_tries, in_size, generator_known, p)) { |
in_tries, in_size, generator_known, p)) { |
res = -1; |
res = -1; |
break; |
break; |
|
|
BN_CTX_free(ctx); |
BN_CTX_free(ctx); |
|
|
logit("%.24s Found %u safe primes of %u candidates in %ld seconds", |
logit("%.24s Found %u safe primes of %u candidates in %ld seconds", |
ctime(&time_stop), count_out, count_possible, |
ctime(&time_stop), count_out, count_possible, |
(long) (time_stop - time_start)); |
(long) (time_stop - time_start)); |
|
|
return (res); |
return (res); |