8 #include <botan/numthry.h> 9 #include <botan/reducer.h> 10 #include <botan/internal/mp_core.h> 11 #include <botan/internal/bit_ops.h> 21 class MillerRabin_Test
24 bool is_witness(
const BigInt& nonce);
25 MillerRabin_Test(
const BigInt& num);
27 BigInt n, r, n_minus_1;
29 Fixed_Exponent_Power_Mod pow_mod;
30 Modular_Reducer reducer;
37 bool MillerRabin_Test::is_witness(
const BigInt& a)
39 if(a < 2 || a >= n_minus_1)
42 BigInt y = pow_mod(a);
43 if(y == 1 || y == n_minus_1)
46 for(
size_t i = 1; i != s; ++i)
48 y = reducer.square(y);
64 MillerRabin_Test::MillerRabin_Test(
const BigInt& num)
66 if(num.is_even() || num < 3)
74 pow_mod = Fixed_Exponent_Power_Mod(r, n);
75 reducer = Modular_Reducer(n);
81 size_t miller_rabin_test_iterations(
size_t bits,
size_t level)
83 struct mapping {
size_t bits;
size_t verify_iter;
size_t check_iter; };
85 static const mapping tests[] = {
121 for(
size_t i = 0; tests[i].bits; ++i)
123 if(bits <= tests[i].bits)
126 return tests[i].verify_iter;
128 return tests[i].check_iter;
130 return std::max<size_t>(tests[i].check_iter / 4, 1);
134 return level > 0 ? 2 : 1;
148 for(
size_t i = 0; i != n.
size(); ++i)
158 low_zero += BOTAN_MP_WORD_BITS;
171 if(a == 1 || b == 1)
return 1;
185 if(x >= y) { x -= y; x >>= 1; }
186 else { y -= x; y >>= 1; }
197 return ((a * b) /
gcd(a, b));
205 throw Invalid_Argument(
"ct_inverse_mod_odd_modulus: arguments must be non-negative");
229 BigInt mp1o2 = (mod + 1) >> 1;
231 const size_t mod_words = mod.
sig_words();
239 v.grow_to(mod_words);
248 size_t bits = 2 * mod.
bits();
253 const word odd = a.
is_odd();
269 const word odd_u = u.
is_odd();
274 const word odd_a = a_w[0] & 1;
293 const word odd_u = u_w[0] & 1;
325 return ct_inverse_mod_odd_modulus(n % mod, mod);
327 BigInt x = mod, y = n, u = mod, v = n;
328 BigInt A = 1, B = 0, C = 0, D = 1;
330 while(u.is_nonzero())
334 for(
size_t i = 0; i != zero_bits; ++i)
336 if(A.
is_odd() || B.is_odd())
343 for(
size_t i = 0; i != zero_bits; ++i)
345 if(C.is_odd() || D.is_odd())
350 if(u >= v) { u -= v; A -= C; B -= D; }
351 else { v -= u; C -= A; D -= B; }
357 while(D.is_negative()) D += mod;
358 while(D >= mod) D -= mod;
381 const size_t PREF_NONCE_BITS = 128;
393 for(
size_t i = 0;
PRIMES[i]; ++i)
407 const size_t NONCE_BITS =
std::min(n.
bits() - 2, PREF_NONCE_BITS);
409 MillerRabin_Test mr(n);
414 const size_t tests = miller_rabin_test_iterations(n.
bits(), level);
416 for(
size_t i = 0; i != tests; ++i)
419 while(nonce < 2 || nonce >= (n-1))
422 if(mr.is_witness(nonce))
const size_t PRIME_TABLE_SIZE
void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift)
void set_exponent(const BigInt &) const
BigInt gcd(const BigInt &a, const BigInt &b)
SecureVector< word > & get_reg()
std::invalid_argument Invalid_Argument
word word_at(size_t n) const
const word * data() const
bool primality_test(const BigInt &n, RandomNumberGenerator &rng, size_t level)
void randomize(RandomNumberGenerator &rng, size_t bitsize=0)
word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size)
void bigint_cnd_swap(word cnd, word x[], word y[], size_t size)
size_t low_zero_bits(const BigInt &n)
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
word bigint_cnd_add(word cnd, word x[], const word y[], size_t size)
void set_base(const BigInt &) const
const u16bit BOTAN_DLL PRIMES[]
void swap(Botan::MemoryRegion< T > &x, Botan::MemoryRegion< T > &y)
void bigint_cnd_abs(word cnd, word x[], size_t size)
BigInt lcm(const BigInt &a, const BigInt &b)