-/* $OpenBSD: moduli.c,v 1.1 2003/07/28 09:49:56 djm Exp $ */
+/* $OpenBSD: moduli.c,v 1.5 2003/12/22 09:16:57 djm Exp $ */
/*
* Copyright 1994 Phil Karn <karn@qualcomm.com>
* Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
#include <openssl/bn.h>
-
-/*
- * Debugging defines
- */
-
-/* define DEBUG_LARGE 1 */
-/* define DEBUG_SMALL 1 */
-/* define DEBUG_TEST 1 */
-
/*
* File output defines
*/
#define QTEST_JACOBI (0x08)
#define QTEST_ELLIPTIC (0x10)
-/* Size: decimal.
+/*
+ * Size: decimal.
* Specifies the number of the most significant bit (0 to M).
- ** WARNING: internally, usually 1 to N.
+ * WARNING: internally, usually 1 to N.
*/
#define QSIZE_MINIMUM (511)
time(&time_now);
gtm = gmtime(&time_now);
-
+
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_hour, gtm->tm_min, gtm->tm_sec,
{
u_int32_t r, u;
- debug2("sieve_large %u", s);
+ debug3("sieve_large %u", s);
largetries++;
/* r = largebase mod s */
r = BN_mod_word(largebase, s);
largememory = memory;
/*
- * 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.
- */
+ * 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.
+ */
if (power > TEST_MAXIMUM) {
error("Too many bits: %u > %lu", power, TEST_MAXIMUM);
return (-1);
power--; /* decrement before squaring */
/*
- * 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
- * to something well above bits**2 to be reasonably sure (but not
- * guaranteed) of catching at least one safe prime.
+ * 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
+ * to something well above bits**2 to be reasonably sure (but not
+ * guaranteed) of catching at least one safe prime.
*/
largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER));
/*
- * Need idea of how much memory is available. We don't have to use all
- * of it.
+ * Need idea of how much memory is available. We don't have to use all
+ * of it.
*/
if (largememory > LARGE_MAXIMUM) {
logit("Limited memory: %u MB; limit %lu MB",
q = BN_new();
/*
- * Generate random starting point for subprime search, or use
- * specified parameter.
+ * Generate random starting point for subprime search, or use
+ * specified parameter.
*/
largebase = BN_new();
if (start == NULL)
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);
debug2("start point: 0x%s", BN_bn2hex(largebase));
/*
- * TinySieve
- */
+ * TinySieve
+ */
for (i = 0; i < tinybits; i++) {
if (BIT_TEST(TinySieve, i))
continue; /* 2*i+3 is composite */
}
/*
- * Start the small block search at the next possible prime. To avoid
- * fencepost errors, the last pass is skipped.
- */
+ * Start the small block search at the next possible prime. To avoid
+ * fencepost errors, the last pass is skipped.
+ */
for (smallbase = TINY_NUMBER + 3;
smallbase < (SMALL_MAXIMUM - TINY_NUMBER);
smallbase += TINY_NUMBER) {
}
/*
- * SmallSieve
- */
+ * SmallSieve
+ */
for (i = 0; i < smallbits; i++) {
if (BIT_TEST(SmallSieve, i))
continue; /* 2*i+smallbase is composite */
* The result is a list of so-call "safe" primes
*/
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)
{
BIGNUM *q, *p, *a;
debug2("%10u: known composite", count_in);
continue;
}
+
/* tries */
in_tries = strtoul(cp, &cp, 10);
in_size += 1;
generator_known = 0;
break;
- default:
+ case QTYPE_UNSTRUCTURED:
+ case QTYPE_SAFE:
+ case QTYPE_SCHNOOR:
+ case QTYPE_STRONG:
+ case QTYPE_UNKNOWN:
debug2("%10u: (%u)", count_in, in_type);
a = p;
BN_hex2bn(&a, cp);
/* q = (p-1) / 2 */
BN_rshift(q, p, 1);
break;
+ default:
+ debug2("Unknown prime type");
+ break;
}
/*
in_tries += trials;
else
in_tries = trials;
+
/*
* guess unknown generator
*/
else {
u_int32_t r = BN_mod_word(p, 10);
- if (r == 3 || r == 7) {
+ if (r == 3 || r == 7)
generator_known = 5;
- }
}
}
/*
continue;
}
+ /*
+ * Primes with no known generator are useless for DH, so
+ * skip those.
+ */
+ if (generator_known == 0) {
+ debug2("%10u: no known generator", count_in);
+ continue;
+ }
+
count_possible++;
/*
- * The (1/4)^N performance bound on Miller-Rabin is
- * extremely pessimistic, so don't spend a lot of time
- * really verifying that q is prime until after we know
- * that p is also prime. A single pass will weed out the
+ * The (1/4)^N performance bound on Miller-Rabin is
+ * extremely pessimistic, so don't spend a lot of time
+ * really verifying that q is prime until after we know
+ * that p is also prime. A single pass will weed out the
* vast majority of composite q's.
*/
if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) {
- debug2("%10u: q failed first possible prime test",
+ debug("%10u: q failed first possible prime test",
count_in);
continue;
}
-
+
/*
- * 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
- * the same for q. If p is composite, chances are that
+ * 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
+ * the same for q. If p is composite, chances are that
* will show up on the first Rabin-Miller iteration so it
* doesn't hurt to specify a high iteration count.
*/
if (!BN_is_prime(p, trials, NULL, ctx, NULL)) {
- debug2("%10u: p is not prime", count_in);
+ debug("%10u: p is not prime", count_in);
continue;
}
debug("%10u: p 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)) {
res = -1;
break;
BN_CTX_free(ctx);
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));
return (res);