Botan 1.10.17

make_prm.cpp
Go to the documentation of this file.
1 /*
2 * Prime Generation
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/numthry.h>
9 #include <botan/parsing.h>
10 #include <algorithm>
11
12 namespace Botan {
13
14 /*
15 * Generate a random prime
16 */
17 BigInt random_prime(RandomNumberGenerator& rng,
18 size_t bits, const BigInt& coprime,
19 size_t equiv, size_t modulo)
20 {
21 if(bits <= 1)
22 throw Invalid_Argument("random_prime: Can't make a prime of " +
23 to_string(bits) + " bits");
24 else if(bits == 2)
25 return ((rng.next_byte() % 2) ? 2 : 3);
26 else if(bits == 3)
27 return ((rng.next_byte() % 2) ? 5 : 7);
28 else if(bits == 4)
29 return ((rng.next_byte() % 2) ? 11 : 13);
30
31 if(coprime <= 0)
32 throw Invalid_Argument("random_prime: coprime must be > 0");
33 if(modulo % 2 == 1 || modulo == 0)
34 throw Invalid_Argument("random_prime: Invalid modulo value");
35 if(equiv >= modulo || equiv % 2 == 0)
36 throw Invalid_Argument("random_prime: equiv must be < modulo, and odd");
37
38 while(true)
39 {
40 BigInt p(rng, bits);
41
42 // Force lowest and two top bits on
43 p.set_bit(bits - 1);
44 p.set_bit(bits - 2);
45 p.set_bit(0);
46
47 if(p % modulo != equiv)
48 p += (modulo - p % modulo) + equiv;
49
50 const size_t sieve_size = std::min(bits / 2, PRIME_TABLE_SIZE);
51 SecureVector<size_t> sieve(sieve_size);
52
53 for(size_t j = 0; j != sieve.size(); ++j)
54 sieve[j] = p % PRIMES[j];
55
56 size_t counter = 0;
57 while(true)
58 {
59 if(counter == 4096 || p.bits() > bits)
60 break;
61
62 bool passes_sieve = true;
63 ++counter;
64 p += modulo;
65
66 if(p.bits() > bits)
67 break;
68
69 for(size_t j = 0; j != sieve.size(); ++j)
70 {
71 sieve[j] = (sieve[j] + modulo) % PRIMES[j];
72 if(sieve[j] == 0)
73 passes_sieve = false;
74 }
75
76 if(!passes_sieve || gcd(p - 1, coprime) != 1)
77 continue;
78 if(check_prime(p, rng))
79 return p;
80 }
81 }
82 }
83
84 /*
85 * Generate a random safe prime
86 */
87 BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits)
88 {
89 if(bits <= 64)
90 throw Invalid_Argument("random_safe_prime: Can't make a prime of " +
91 to_string(bits) + " bits");
92
93 BigInt p;
94 do
95 p = (random_prime(rng, bits - 1) << 1) + 1;
96 while(!check_prime(p, rng));
97 return p;
98 }
99
100 }
Botan::PRIME_TABLE_SIZE
const size_t PRIME_TABLE_SIZE
Definition: numthry.h:220
Botan::BigInt
Definition: bigint.h:22
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::BigInt::bits
size_t bits() const
Definition: bigint.cpp:254
Botan::BigInt::set_bit
void set_bit(size_t n)
Definition: bigint.cpp:206
Botan::gcd
BigInt gcd(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:168
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan
Definition: algo_base.h:14
Botan::random_safe_prime
BigInt random_safe_prime(RandomNumberGenerator &rng, size_t bits)
Definition: make_prm.cpp:87
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::CT::min
T min(T a, T b)
Definition: ct_utils.h:127
Botan::to_string
std::string to_string(u64bit n, size_t min_len)
Definition: parsing.cpp:42
Botan::SecureVector
Definition: secmem.h:328
Botan::PRIMES
const u16bit BOTAN_DLL PRIMES[]
Definition: primes.cpp:12
Botan::RandomNumberGenerator::next_byte
byte next_byte()
Definition: rng.cpp:19
Botan::random_prime
BigInt random_prime(RandomNumberGenerator &rng, size_t bits, const BigInt &coprime, size_t equiv, size_t modulo)
Definition: make_prm.cpp:17
Botan::check_prime
bool check_prime(const BigInt &n, RandomNumberGenerator &rng)
Definition: numthry.h:143