Commit f7695101 authored by Niels Möller's avatar Niels Möller
Browse files

(_nettle_generate_pocklington_prime): New

argument top_bits_set, to optionally generate primes with the two
most significant bits set. Reordered argument list.
(nettle_random_prime): Likewise, added top_bits_set argument.
Invoke progress callback when a prime is generated.

Rev: nettle/bignum-random-prime.c:1.6
Rev: nettle/bignum.h:1.7
parent 60a9b1b1
...@@ -255,35 +255,50 @@ miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a) ...@@ -255,35 +255,50 @@ miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a)
/* Generate a prime number p of size bits with 2 p0q dividing (p-1). /* Generate a prime number p of size bits with 2 p0q dividing (p-1).
p0 must be of size >= ceil(bits/2) + 1. The extra factor q can be p0 must be of size >= ceil(bits/2) + 1. The extra factor q can be
omitted. */ omitted. If top_bits_set is one, the top most two bits are one,
suitable for RSA primes. */
void void
_nettle_generate_pocklington_prime (mpz_t p, unsigned bits, mpz_t r, _nettle_generate_pocklington_prime (mpz_t p, mpz_t r,
unsigned bits, int top_bits_set,
void *ctx, nettle_random_func random, void *ctx, nettle_random_func random,
const mpz_t p0, const mpz_t p0,
const mpz_t q, const mpz_t q,
const mpz_t p0q) const mpz_t p0q)
{ {
mpz_t i, pm1,a; mpz_t r_min, r_range, pm1,a;
assert (2*mpz_sizeinbase (p0, 2) > bits + 1); assert (2*mpz_sizeinbase (p0, 2) > bits + 1);
mpz_init (i); mpz_init (r_min);
mpz_init (r_range);
mpz_init (pm1); mpz_init (pm1);
mpz_init (a); mpz_init (a);
/* i = floor (2^{bits-2} / p0q) */ if (top_bits_set)
mpz_init_set_ui (i, 1); {
mpz_mul_2exp (i, i, bits-2); /* i = floor (2^{bits-3} / p0q), then 3I + 3 <= r <= 4I, with I
mpz_fdiv_q (i, i, p0q); - 2 possible values. */
mpz_set_ui (r_min, 1);
mpz_mul_2exp (r_min, r_min, bits-3);
mpz_fdiv_q (r_min, r_min, p0q);
mpz_sub_ui (r_range, r_min, 2);
mpz_mul_ui (r_min, r_min, 3);
mpz_add_ui (r_min, r_min, 3);
}
else
{
/* i = floor (2^{bits-2} / p0q), I + 1 <= r <= 2I */
mpz_set_ui (r_range, 1);
mpz_mul_2exp (r_range, r_range, bits-2);
mpz_fdiv_q (r_range, r_range, p0q);
mpz_add_ui (r_min, r_range, 1);
}
for (;;) for (;;)
{ {
uint8_t buf[1]; uint8_t buf[1];
/* Generate r in the range i + 1 <= r <= 2*i */ nettle_mpz_random (r, ctx, random, r_range);
nettle_mpz_random (r, ctx, random, i); mpz_add (r, r, r_min);
mpz_add (r, r, i);
mpz_add_ui (r, r, 1);
/* Set p = 2*r*p0q + 1 */ /* Set p = 2*r*p0q + 1 */
mpz_mul_2exp(r, r, 1); mpz_mul_2exp(r, r, 1);
...@@ -319,18 +334,19 @@ _nettle_generate_pocklington_prime (mpz_t p, unsigned bits, mpz_t r, ...@@ -319,18 +334,19 @@ _nettle_generate_pocklington_prime (mpz_t p, unsigned bits, mpz_t r,
else if (miller_rabin_pocklington(p, pm1, r, a)) else if (miller_rabin_pocklington(p, pm1, r, a))
break; break;
} }
mpz_clear (i); mpz_clear (r_min);
mpz_clear (r_range);
mpz_clear (pm1); mpz_clear (pm1);
mpz_clear (a); mpz_clear (a);
} }
/* Generate random prime of a given size. Maurer's algorithm (Alg. /* Generate random prime of a given size. Maurer's algorithm (Alg.
6.42 Handbook of applied cryptography), but with ratio = 1/2 (like 6.42 Handbook of applied cryptography), but with ratio = 1/2 (like
the variant in fips186-3). FIXME: Force primes to start with two the variant in fips186-3). */
one bits? */
void void
nettle_random_prime(mpz_t p, unsigned bits, nettle_random_prime(mpz_t p, unsigned bits, int top_bits_set,
void *ctx, nettle_random_func random) void *random_ctx, nettle_random_func random,
void *progress_ctx, nettle_progress_func progress)
{ {
assert (bits >= 3); assert (bits >= 3);
if (bits <= 10) if (bits <= 10)
...@@ -339,7 +355,9 @@ nettle_random_prime(mpz_t p, unsigned bits, ...@@ -339,7 +355,9 @@ nettle_random_prime(mpz_t p, unsigned bits,
unsigned choices; unsigned choices;
uint8_t buf; uint8_t buf;
random (ctx, sizeof(buf), &buf); assert (!top_bits_set);
random (random_ctx, sizeof(buf), &buf);
first = prime_by_size[bits-3]; first = prime_by_size[bits-3];
choices = prime_by_size[bits-2] - first; choices = prime_by_size[bits-2] - first;
...@@ -353,10 +371,12 @@ nettle_random_prime(mpz_t p, unsigned bits, ...@@ -353,10 +371,12 @@ nettle_random_prime(mpz_t p, unsigned bits,
unsigned long x; unsigned long x;
unsigned j; unsigned j;
assert (!top_bits_set);
highbit = 1L << (bits - 1); highbit = 1L << (bits - 1);
again: again:
random (ctx, sizeof(buf), buf); random (random_ctx, sizeof(buf), buf);
x = READ_UINT24(buf); x = READ_UINT24(buf);
x &= (highbit - 1); x &= (highbit - 1);
x |= highbit | 1; x |= highbit | 1;
...@@ -379,11 +399,16 @@ nettle_random_prime(mpz_t p, unsigned bits, ...@@ -379,11 +399,16 @@ nettle_random_prime(mpz_t p, unsigned bits,
/* Bit size ceil(k/2) + 1, slightly larger than used in Alg. 4.62 /* Bit size ceil(k/2) + 1, slightly larger than used in Alg. 4.62
in Handbook of Applied Cryptography (which seems to be in Handbook of Applied Cryptography (which seems to be
incorrect for odd k). */ incorrect for odd k). */
nettle_random_prime (q, (bits+3)/2, ctx, random); nettle_random_prime (q, (bits+3)/2, 0, random_ctx, random,
progress_ctx, progress);
_nettle_generate_pocklington_prime (p, bits, r, ctx, random, _nettle_generate_pocklington_prime (p, r, bits, top_bits_set,
random_ctx, random,
q, NULL, q); q, NULL, q);
if (progress)
progress (progress_ctx, 'x');
mpz_clear (q); mpz_clear (q);
mpz_clear (r); mpz_clear (r);
} }
......
...@@ -86,11 +86,13 @@ nettle_next_prime(mpz_t p, mpz_t n, unsigned count, unsigned prime_limit, ...@@ -86,11 +86,13 @@ nettle_next_prime(mpz_t p, mpz_t n, unsigned count, unsigned prime_limit,
void *progress_ctx, nettle_progress_func progress); void *progress_ctx, nettle_progress_func progress);
void void
nettle_random_prime(mpz_t p, unsigned bits, nettle_random_prime(mpz_t p, unsigned bits, int top_bits_set,
void *ctx, nettle_random_func random); void *ctx, nettle_random_func random,
void *progress_ctx, nettle_progress_func progress);
void void
_nettle_generate_pocklington_prime (mpz_t p, unsigned bits, mpz_t r, _nettle_generate_pocklington_prime (mpz_t p, mpz_t r,
unsigned bits, int top_bits_set,
void *ctx, nettle_random_func random, void *ctx, nettle_random_func random,
const mpz_t p0, const mpz_t p0,
const mpz_t q, const mpz_t q,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment