Botan 3.13.0
Crypto and TLS for C&
make_prm.cpp
Go to the documentation of this file.
1/*
2* Prime Generation
3* (C) 1999-2007,2018,2019 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/primality.h>
9
10#include <botan/exceptn.h>
11#include <botan/numthry.h>
12#include <botan/rng.h>
13#include <botan/internal/barrett.h>
14#include <botan/internal/bit_ops.h>
15#include <botan/internal/ct_utils.h>
16#include <botan/internal/divide.h>
17#include <botan/internal/loadstor.h>
18#include <botan/internal/monty.h>
19#include <numeric>
20
21namespace Botan {
22
23namespace {
24
25class Prime_Sieve final {
26 public:
27 Prime_Sieve(const BigInt& init_value, size_t sieve_size, word step, bool check_2p1) :
28 m_sieve(std::min(sieve_size, PRIME_TABLE_SIZE)), m_step(step), m_check_2p1(check_2p1) {
29 for(size_t i = 0; i != m_sieve.size(); ++i) {
30 m_sieve[i] = ct_mod_word(init_value, PRIMES[i]);
31 }
32 }
33
34 size_t sieve_size() const { return m_sieve.size(); }
35
36 bool check_2p1() const { return m_check_2p1; }
37
38 bool next() {
39 auto passes = CT::Mask<word>::set();
40 for(size_t i = 0; i != m_sieve.size(); ++i) {
41 m_sieve[i] = sieve_step_incr(m_sieve[i], m_step, PRIMES[i]);
42
43 // If m_sieve[i] == 0 then val % p == 0 -> not prime
44 passes &= CT::Mask<word>::expand(m_sieve[i]);
45
46 if(this->check_2p1()) {
47 /*
48 If v % p == (p-1)/2 then 2*v+1 == 0 (mod p)
49
50 So if potentially generating a safe prime, we want to
51 avoid this value because 2*v+1 will certainly not be prime.
52
53 See "Safe Prime Generation with a Combined Sieve" M. Wiener
54 https://eprint.iacr.org/2003/186.pdf
55 */
56 passes &= ~CT::Mask<word>::is_equal(m_sieve[i], (PRIMES[i] - 1) / 2);
57 }
58 }
59
60 return passes.as_bool();
61 }
62
63 private:
64 // Return (v + step) % mod
65 //
66 // This assumes v is already < mod, which is an invariant of the sieve
67 static constexpr word sieve_step_incr(word v, word step, word mod) {
68 BOTAN_DEBUG_ASSERT(v < mod);
69 // The sieve step and primes are public so this modulo is ok
70 const word stepmod = (step >= mod) ? (step % mod) : step;
71
72 // This sum is at most 2*(mod-1)
73 const word next = (v + stepmod);
74 return next - CT::Mask<word>::is_gte(next, mod).if_set_return(mod);
75 }
76
77 std::vector<word> m_sieve;
78 const word m_step;
79 const bool m_check_2p1;
80};
81
82#if defined(BOTAN_ENABLE_DEBUG_ASSERTS)
83
84bool no_small_multiples(const BigInt& v, const Prime_Sieve& sieve) {
85 const size_t sieve_size = sieve.sieve_size();
86 const bool check_2p1 = sieve.check_2p1();
87
88 if(v.is_even())
89 return false;
90
91 const BigInt v_x2_p1 = 2 * v + 1;
92
93 for(size_t i = 0; i != sieve_size; ++i) {
94 if((v % PRIMES[i]) == 0)
95 return false;
96
97 if(check_2p1) {
98 if(v_x2_p1 % PRIMES[i] == 0)
99 return false;
100 }
101 }
102
103 return true;
104}
105
106#endif
107
108BigInt random_prime_with_sieve(RandomNumberGenerator& rng,
109 size_t bits,
110 const BigInt& coprime,
111 size_t equiv,
112 size_t modulo,
113 size_t prob,
114 bool sieve_check_2p1) {
115 const size_t MAX_ATTEMPTS = 32 * 1024;
116
117 const size_t mr_trials = miller_rabin_test_iterations(bits, prob, true);
118
119 // Variable time gcd here is fine since these are generation parameters, not secrets
120 if(std::gcd(equiv, modulo) != 1) {
121 throw Invalid_Argument("random_prime equiv and modulo must be relatively prime");
122 }
123
124 while(true) {
125 BigInt p(rng, bits);
126
127 // Force lowest and two top bits on
128 p.set_bit(bits - 1);
129 p.set_bit(bits - 2);
130 p.set_bit(0);
131
132 // Force p to be equal to equiv mod modulo
133 p += (modulo - (p % modulo)) + equiv;
134
135 Prime_Sieve sieve(p, bits, modulo, sieve_check_2p1);
136
137 for(size_t attempt = 0; attempt <= MAX_ATTEMPTS; ++attempt) {
138 p += modulo;
139
140 if(!sieve.next()) {
141 continue;
142 }
143
144 // here p can be even if modulo is odd, continue on in that case
145 if(p.is_even()) {
146 continue;
147 }
148
149 BOTAN_DEBUG_ASSERT(no_small_multiples(p, sieve));
150
152 const Montgomery_Params monty_p(p, mod_p);
153
154 if(coprime > 1) {
155 /*
156 First do a single M-R iteration to quickly eliminate most non-primes,
157 before doing the coprimality check which is expensive
158 */
159 if(!is_miller_rabin_probable_prime(p, mod_p, monty_p, rng, 1)) {
160 continue;
161 }
162
163 /*
164 * Check if p - 1 and coprime are relatively prime, using gcd.
165 * The gcd computation is const-time
166 */
167 if(gcd(p - 1, coprime) > 1) {
168 continue;
169 }
170 }
171
172 if(p.bits() > bits) {
173 break;
174 }
175
176 if(!is_miller_rabin_probable_prime(p, mod_p, monty_p, rng, mr_trials)) {
177 continue;
178 }
179
180 if(prob > 32 && !is_lucas_probable_prime(p, mod_p)) {
181 continue;
182 }
183
184 return p;
185 }
186 }
187}
188
189} // namespace
190
191/*
192* Generate a random prime
193*/
195 RandomNumberGenerator& rng, size_t bits, const BigInt& coprime, size_t equiv, size_t modulo, size_t prob) {
196 if(bits <= 1) {
197 throw Invalid_Argument("random_prime: Can't make a prime of " + std::to_string(bits) + " bits");
198 }
199 if(coprime.signum() < 0 || (coprime.signum() != 0 && coprime.is_even()) || coprime.bits() >= bits) {
200 throw Invalid_Argument("random_prime: invalid coprime");
201 }
202 // TODO(Botan4) reduce this to ~1000
203 if(modulo == 0 || modulo >= 100000) {
204 throw Invalid_Argument("random_prime: Invalid modulo value");
205 }
206
207 // TODO(Botan4) reject equiv > modulo instead of reducing here
208 equiv %= modulo;
209
210 if(equiv == 0) {
211 throw Invalid_Argument("random_prime Invalid value for equiv/modulo");
212 }
213
214 // Handle small values:
215
216 if(bits <= 16) {
217 if(equiv != 1 || modulo != 2 || coprime != 0) {
218 throw Not_Implemented("random_prime equiv/modulo/coprime options not usable for small primes");
219 }
220
221 if(bits == 2) {
222 return BigInt::from_word(((rng.next_byte() % 2) == 0 ? 2 : 3));
223 } else if(bits == 3) {
224 return BigInt::from_word(((rng.next_byte() % 2) == 0 ? 5 : 7));
225 } else if(bits == 4) {
226 return BigInt::from_word(((rng.next_byte() % 2) == 0 ? 11 : 13));
227 } else {
228 for(;;) {
229 // This is slightly biased, but for small primes it does not seem to matter
230 uint8_t b[4] = {0};
231 rng.randomize(b, 4);
232 const size_t idx = load_le<uint32_t>(b, 0) % PRIME_TABLE_SIZE;
233 const uint16_t small_prime = PRIMES[idx];
234
235 if(high_bit(small_prime) == bits) {
236 return BigInt::from_word(small_prime);
237 }
238 }
239 }
240 }
241
242 // The check_2p1 sieve filter is only appropriate when generating q for a
243 // safe prime; for arbitrary equiv/modulo it can pre-reject every candidate
244 // (eg equiv=1, modulo=3 makes the residue mod 3 always equal (3-1)/2).
245 return random_prime_with_sieve(rng, bits, coprime, equiv, modulo, prob, false);
246}
247
249 RandomNumberGenerator& prime_test_rng,
250 size_t bits,
251 const BigInt& coprime,
252 size_t prob) {
253 if(bits < 512) {
254 throw Invalid_Argument("generate_rsa_prime bits too small");
255 }
256
257 /*
258 * The restriction on coprime <= 64 bits is arbitrary but generally speaking
259 * very large RSA public exponents are a bad idea both for performance and due
260 * to attacks on small d.
261 */
262 if(coprime <= 1 || coprime.is_even() || coprime.bits() > 64) {
263 throw Invalid_Argument("generate_rsa_prime coprime must be small odd positive integer");
264 }
265
266 const size_t MAX_ATTEMPTS = 32 * 1024;
267
268 const size_t mr_trials = miller_rabin_test_iterations(bits, prob, true);
269
270 while(true) {
271 BigInt p(keygen_rng, bits);
272
273 auto scope = CT::scoped_poison(p);
274
275 /*
276 Force high two bits so multiplication always results in expected n bit integer
277
278 Force the two low bits, and step by 4, so the generated prime is always == 3 (mod 4).
279 This way when we perform the inversion modulo phi(n) it is always of the form 2*o
280 with o odd, which allows a fastpath and avoids leaking any information about the
281 structure of the prime.
282 */
283 p.set_bit(bits - 1);
284 p.set_bit(bits - 2);
285 p.set_bit(1);
286 p.set_bit(0);
287
288 const word step = 4;
289
290 Prime_Sieve sieve(p, bits, step, false);
291
292 for(size_t attempt = 0; attempt <= MAX_ATTEMPTS; ++attempt) {
293 p += step;
294
295 if(!sieve.next()) {
296 continue;
297 }
298
299 BOTAN_DEBUG_ASSERT(no_small_multiples(p, sieve));
300
302 const Montgomery_Params monty_p(p, mod_p);
303
304 /*
305 * Do a single primality test first before checking coprimality, since
306 * currently a single Miller-Rabin test is faster than computing gcd,
307 * and this eliminates almost all wasted gcd computations.
308 */
309 if(!is_miller_rabin_probable_prime(p, mod_p, monty_p, prime_test_rng, 1)) {
310 continue;
311 }
312
313 /*
314 * Check if p - 1 and coprime are relatively prime.
315 */
316 if(gcd(p - 1, coprime) > 1) {
317 continue;
318 }
319
320 if(p.bits() > bits) {
321 break;
322 }
323
324 if(is_miller_rabin_probable_prime(p, mod_p, monty_p, prime_test_rng, mr_trials)) {
325 return p;
326 }
327 }
328 }
329}
330
331/*
332* Generate a random safe prime
333*/
335 if(bits <= 64) {
336 throw Invalid_Argument("random_safe_prime: Can't make a prime of " + std::to_string(bits) + " bits");
337 }
338
339 const size_t error_bound = 128;
340
341 BigInt q;
342 BigInt p;
343 for(;;) {
344 /*
345 Generate q == 2 (mod 3), since otherwise [in the case of q == 1 (mod 3)],
346 2*q+1 == 3 (mod 3) and so certainly not prime.
347 */
348 q = random_prime_with_sieve(rng, bits - 1, BigInt::zero(), 2, 3, error_bound, true);
349 p = (q << 1) + 1;
350
351 if(is_prime(p, rng, error_bound, true)) {
352 return p;
353 }
354 }
355}
356
357} // namespace Botan
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:129
static Barrett_Reduction for_secret_modulus(const BigInt &m)
Definition barrett.cpp:23
static BigInt zero()
Definition bigint.h:50
int signum() const
Definition bigint.h:493
void set_bit(size_t n)
Definition bigint.h:516
size_t bits() const
Definition bigint.cpp:307
bool is_even() const
Definition bigint.h:481
static BigInt from_word(word n)
Definition bigint.cpp:35
static constexpr Mask< T > is_gte(T x, T y)
Definition ct_utils.h:468
static constexpr Mask< T > set()
Definition ct_utils.h:382
static constexpr Mask< T > expand(T v)
Definition ct_utils.h:392
void randomize(std::span< uint8_t > output)
Definition rng.h:86
constexpr auto scoped_poison(const Ts &... xs)
Definition ct_utils.h:222
word ct_mod_word(const BigInt &x, word y)
Definition divide.cpp:174
bool is_miller_rabin_probable_prime(const BigInt &n, const Barrett_Reduction &mod_n, const Montgomery_Params &monty_n, RandomNumberGenerator &rng, size_t test_iterations)
BigInt random_prime(RandomNumberGenerator &rng, size_t bits, const BigInt &coprime, size_t equiv, size_t modulo, size_t prob)
Definition make_prm.cpp:194
bool is_lucas_probable_prime(const BigInt &C, const Barrett_Reduction &mod_C)
Definition primality.cpp:18
const uint16_t PRIMES[]
Definition primes.cpp:12
const size_t PRIME_TABLE_SIZE
Definition numthry.h:177
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition numthry.cpp:381
BigInt generate_rsa_prime(RandomNumberGenerator &keygen_rng, RandomNumberGenerator &prime_test_rng, size_t bits, const BigInt &coprime, size_t prob)
Definition make_prm.cpp:248
BOTAN_FORCE_INLINE constexpr size_t high_bit(T n)
Definition bit_ops.h:73
BigInt gcd(const BigInt &a, const BigInt &b)
Definition numthry.cpp:220
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:495
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
BigInt random_safe_prime(RandomNumberGenerator &rng, size_t bits)
Definition make_prm.cpp:334
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word
The native machine word, used as the limb type for multiprecision integers.
Definition types.h:131