### For prime generation, use stronger variants of Pocklington's theorem.

parent 62f2e2d0
 2013-12-12 Niels Möller * bignum-random-prime.c (_nettle_generate_pocklington_prime): Use stronger variants of Pocklington's theorem, to allow p0 of size down to bits/3. 2013-12-15 Niels Möller 2013-12-15 Niels Möller * nettle-internal.h (NETTLE_MAX_BIGNUM_BITS) * nettle-internal.h (NETTLE_MAX_BIGNUM_BITS) ... ...
 ... @@ -167,7 +167,8 @@ prime_by_size = { ... @@ -167,7 +167,8 @@ prime_by_size = { }; }; /* Combined Miller-Rabin test to the base a, and checking the /* Combined Miller-Rabin test to the base a, and checking the conditions from Pocklington's theorem. */ conditions from Pocklington's theorem, nm1dq holds (n-1)/q, with q prime. */ static int static int miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a) miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a) { { ... @@ -229,34 +230,93 @@ miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a) ... @@ -229,34 +230,93 @@ miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a) return is_prime; return is_prime; } } /* The algorithm is based on the following special case of /* The most basic variant of Pocklingtons theorem: Pocklington's theorem: Assume that n = 1 + f q, where q is a prime, q > sqrt(n) - 1. If we Assume that q^e | (n-1), with q prime. If we can find an a such that can find an a such that a^{n-1} = 1 (mod n) a^{n-1} = 1 (mod n) gcd(a^f - 1, n) = 1 gcd(a^{(n-1)/q} - 1, n) = 1 then n is prime. then any prime divisor p of n satisfies p = 1 (mod q^e). Proof: Assume that n is composite, with smallest prime factor p <= Proof (Cohen, 8.3.2): Assume p is a prime factor of n. The central sqrt(n). Since q is prime, and q > sqrt(n) - 1 >= p - 1, q and p-1 idea of the proof is to consider the order, modulo p, of a. Denote are coprime, so that we can define u = q^{-1} (mod (p-1)). The this by d. assumption a^{n-1} = 1 (mod n) implies that also a^{n-1} = 1 (mod p). Since p is prime, we have a^{(p-1)} = 1 (mod p). Now, r = (n-1)/q = (n-1) u (mod (p-1)), and it follows that a^r = a^{(n-1) u} = 1 (mod p). Then p is a common factor of a^r - 1 and n. This contradicts gcd(a^r - 1, n) = 1, and concludes the proof. If n is specified as k bits, we need q of size ceil(k/2) + 1 bits a^{n-1} = 1 (mod n) implies a^{n-1} = 1 (mod p), hence d | (n-1). (or more) to make the theorem apply. Next, the condition gcd(a^{(n-1)/q} - 1, n) = 1 implies that a^{(n-1)/q} != 1, hence d does not divide (n-1)/q. Since q is prime, this means that q^e | d. Finally, we have a^{p-1} = 1 (mod p), hence d | (p-1). So q^e | d | (p-1), which gives the desired result: p = 1 (mod q^e). * Variant, slightly stronger than Fact 4.59, HAC: Assume n = 1 + 2rq, q an odd prime, r <= 2q, and a^{n-1} = 1 (mod n) gcd(a^{(n-1)/q} - 1, n) = 1 Then n is prime. Proof: By Pocklington's theorem, any prime factor p satisfies p = 1 (mod q). Neither 1 or q+1 are primes, hence p >= 1 + 2q. If n is composite, we have n >= (1+2q)^2. But the assumption r <= 2q implies n <= 1 + 4q^2, a contradiction. In bits, the requirement is that #n <= 2 #q, then r = (n-1)/2q < 2^{#n - #q} <= 2^#q = 2 2^{#q-1}< 2 q * Another variant with an extra test (Variant of Fact 4.42, HAC): Assume n = 1 + 2rq, n odd, q an odd prime, 8 q^3 >= n a^{n-1} = 1 (mod n) gcd(a^{(n-1)/q} - 1, n) = 1 Also let x = floor(r / 2q), y = r mod 2q, If y^2 - 4x is not a square, then n is prime. Proof (adapted from Maurer, Journal of Cryptology, 8 (1995)): Assume n is composite. There are at most two factors, both odd, n = (1+2m_1 q)(1+2m_2 q) = 1 + 4 m_1 m_2 q^2 + 2 (m_1 + m_2) q where we can assume m_1 >= m_2. Then the bound n <= 8 q^3 implies m_1 m_2 < 2q, restricting (m_1, m_2) to the domain 0 < m_2 < sqrt(2q), 0 < m_1 < 2q / m_2. We have the bound m_1 + m_2 < 2q / m_2 + m_2 <= 2q + 1 (maximum value for m_2 = 1) And the case m_1 = 2q, m_2 = 1 can be excluded, because it gives n > 8q^3. So in fact, m_1 + m_2 < 2q. Next, write r = (n-1)/2q = 2 m_1 m_2 q + m_1 + m_2. If follows that m_1 + m_2 = y and m_1 m_2 = x. m_1 and m_2 are thus the roots of the equation m^2 - y m + x = 0 which has integer roots iff y^2 - 4 x is the square of an integer. In bits, the requirement is that #n <= 3 #q, then n < 2^#n <= 2^{3 #q} = 8 2^{3 (#q-1)} < 8 q^3 */ */ /* 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/3). The extra factor q can be omitted. If top_bits_set is one, the top most two bits are one, omitted. If top_bits_set is one, the topmost two bits are set to suitable for RSA primes. */ one, suitable for RSA primes. Also returns r = (p-1)/q. */ void void _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, unsigned bits, int top_bits_set, unsigned bits, int top_bits_set, ... @@ -265,15 +325,34 @@ _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, ... @@ -265,15 +325,34 @@ _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, const mpz_t q, const mpz_t q, const mpz_t p0q) const mpz_t p0q) { { mpz_t r_min, r_range, pm1,a; mpz_t r_min, r_range, pm1, a, e; int need_square_test; assert (2*mpz_sizeinbase (p0, 2) > bits + 1); unsigned p0_bits; mpz_t x, y, p04; p0_bits = mpz_sizeinbase (p0, 2); assert (bits <= 3*p0_bits); assert (bits > p0_bits); need_square_test = (bits > 2 * p0_bits); mpz_init (r_min); mpz_init (r_min); mpz_init (r_range); mpz_init (r_range); mpz_init (pm1); mpz_init (pm1); mpz_init (a); mpz_init (a); if (need_square_test) { mpz_init (x); mpz_init (y); mpz_init (p04); mpz_mul_2exp (p04, p0, 2); } if (q) mpz_init (e); if (top_bits_set) if (top_bits_set) { { /* i = floor (2^{bits-3} / p0q), then 3I + 3 <= r <= 4I, with I /* i = floor (2^{bits-3} / p0q), then 3I + 3 <= r <= 4I, with I ... @@ -293,6 +372,7 @@ _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, ... @@ -293,6 +372,7 @@ _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, mpz_fdiv_q (r_range, r_range, p0q); mpz_fdiv_q (r_range, r_range, p0q); mpz_add_ui (r_min, r_range, 1); mpz_add_ui (r_min, r_range, 1); } } for (;;) for (;;) { { uint8_t buf; uint8_t buf; ... @@ -319,25 +399,54 @@ _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, ... @@ -319,25 +399,54 @@ _nettle_generate_pocklington_prime (mpz_t p, mpz_t r, if (q) if (q) { { mpz_t e; int is_prime; mpz_init (e); mpz_mul (e, r, q); mpz_mul (e, r, q); is_prime = miller_rabin_pocklington(p, pm1, e, a); if (!miller_rabin_pocklington(p, pm1, e, a)) mpz_clear (e); continue; if (is_prime) if (need_square_test) break; { /* Our e corresponds to 2r in the theorem */ mpz_tdiv_qr (x, y, e, p04); goto square_test; } } } else if (miller_rabin_pocklington(p, pm1, r, a)) else break; { if (!miller_rabin_pocklington(p, pm1, r, a)) continue; if (need_square_test) { mpz_tdiv_qr (x, y, r, p04); square_test: /* We have r' = 2r, x = floor (r/2q) = floor(r'/2q), and y' = r' - x 4q = 2 (r - x 2q) = 2y. Then y^2 - 4x is a square iff y'^2 - 16 x is a square. */ mpz_mul (y, y, y); mpz_submul_ui (y, x, 16); if (mpz_perfect_square_p (y)) continue; } } /* If we passed all the tests, we have found a prime. */ break; } } mpz_clear (r_min); mpz_clear (r_min); mpz_clear (r_range); mpz_clear (r_range); mpz_clear (pm1); mpz_clear (pm1); mpz_clear (a); mpz_clear (a); if (need_square_test) { mpz_clear (x); mpz_clear (y); mpz_clear (p04); } if (q) mpz_clear (e); } } /* Generate random prime of a given size. Maurer's algorithm (Alg. /* Generate random prime of a given size. Maurer's algorithm (Alg. ... ...
Supports Markdown
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