8#include <botan/internal/primality.h>
9#include <botan/numthry.h>
11#include <botan/internal/bit_ops.h>
12#include <botan/internal/ct_utils.h>
13#include <botan/internal/loadstor.h>
14#include <botan/reducer.h>
21class Prime_Sieve
final
24 Prime_Sieve(
const BigInt& init_value,
size_t sieve_size, word step,
bool check_2p1) :
27 m_check_2p1(check_2p1)
29 for(
size_t i = 0; i != m_sieve.size(); ++i)
30 m_sieve[i] = init_value %
PRIMES[i];
33 size_t sieve_size()
const {
return m_sieve.size(); }
35 bool check_2p1()
const {
return m_check_2p1; }
40 for(
size_t i = 0; i != m_sieve.size(); ++i)
42 m_sieve[i] = (m_sieve[i] + m_step) %
PRIMES[i];
58 passes &= ~CT::Mask<word>::is_equal(m_sieve[i], (
PRIMES[i] - 1) / 2);
62 return passes.is_set();
66 std::vector<word> m_sieve;
68 const bool m_check_2p1;
71#if defined(BOTAN_ENABLE_DEBUG_ASSERTS)
73bool no_small_multiples(
const BigInt& v,
const Prime_Sieve& sieve)
75 const size_t sieve_size = sieve.sieve_size();
76 const bool check_2p1 = sieve.check_2p1();
81 const BigInt v_x2_p1 = 2*v + 1;
83 for(
size_t i = 0; i != sieve_size; ++i)
90 if(v_x2_p1 %
PRIMES[i] == 0)
107 size_t bits,
const BigInt& coprime,
108 size_t equiv,
size_t modulo,
114 std::to_string(bits) +
" bits");
120 if(modulo == 0 || modulo >= 100000)
134 if(equiv != 1 || modulo != 2 || coprime != 0)
135 throw Not_Implemented(
"random_prime equiv/modulo/coprime options not usable for small primes");
157 const uint16_t small_prime =
PRIMES[idx];
165 const size_t MAX_ATTEMPTS = 32*1024;
179 p += (modulo - (p % modulo)) + equiv;
181 Prime_Sieve sieve(p, bits, modulo,
true);
183 for(
size_t attempt = 0; attempt <= MAX_ATTEMPTS; ++attempt)
211 if(
gcd(p - 1, coprime) > 1)
243 if(coprime <= 1 || coprime.
is_even() || coprime.
bits() > 64)
244 throw Invalid_Argument(
"generate_rsa_prime coprime must be small odd positive integer");
246 const size_t MAX_ATTEMPTS = 32*1024;
252 BigInt p(keygen_rng, bits);
269 Prime_Sieve sieve(p, bits, step,
false);
271 for(
size_t attempt = 0; attempt <= MAX_ATTEMPTS; ++attempt)
293 if(
gcd(p - 1, coprime) > 1)
312 std::to_string(bits) +
" bits");
314 const size_t error_bound = 128;
326 if(
is_prime(p, rng, error_bound,
true))
#define BOTAN_DEBUG_ASSERT(expr)
static BigInt from_word(word n)
static Mask< T > expand(T v)
void randomize(std::span< uint8_t > output)
int(* final)(unsigned char *, CTX *)
constexpr uint32_t load_le< uint32_t >(const uint8_t in[], size_t off)
BigInt random_prime(RandomNumberGenerator &rng, size_t bits, const BigInt &coprime, size_t equiv, size_t modulo, size_t prob)
constexpr size_t high_bit(T n)
const size_t PRIME_TABLE_SIZE
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
bool is_miller_rabin_probable_prime(const BigInt &n, const Modular_Reducer &mod_n, RandomNumberGenerator &rng, size_t test_iterations)
BigInt generate_rsa_prime(RandomNumberGenerator &keygen_rng, RandomNumberGenerator &prime_test_rng, size_t bits, const BigInt &coprime, size_t prob)
BigInt gcd(const BigInt &a, const BigInt &b)
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
BigInt random_safe_prime(RandomNumberGenerator &rng, size_t bits)
bool is_lucas_probable_prime(const BigInt &C, const Modular_Reducer &mod_C)