Botan 3.0.0-alpha0
Crypto and TLS for C&
primality.cpp
Go to the documentation of this file.
1/*
2* (C) 2016,2018 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/internal/primality.h>
8#include <botan/internal/monty_exp.h>
9#include <botan/bigint.h>
10#include <botan/internal/monty.h>
11#include <botan/reducer.h>
12#include <botan/rng.h>
13#include <algorithm>
14
15namespace Botan {
16
18 {
19 if(C == 2 || C == 3 || C == 5 || C == 7 || C == 11 || C == 13)
20 return true;
21
22 if(C <= 1 || C.is_even())
23 return false;
24
26
27 for(;;)
28 {
29 int32_t j = jacobi(D, C);
30 if(j == 0)
31 return false;
32
33 if(j == -1)
34 break;
35
36 // Check 5, -7, 9, -11, 13, -15, 17, ...
37 if(D.is_negative())
38 {
39 D.flip_sign();
40 D += 2;
41 }
42 else
43 {
44 D += 2;
45 D.flip_sign();
46 }
47
48 if(D == 17 && is_perfect_square(C).is_nonzero())
49 return false;
50 }
51
52 const BigInt K = C + 1;
53 const size_t K_bits = K.bits() - 1;
54
55 BigInt U = BigInt::one();
56 BigInt V = BigInt::one();
57
58 BigInt Ut, Vt, U2, V2;
59
60 for(size_t i = 0; i != K_bits; ++i)
61 {
62 const bool k_bit = K.get_bit(K_bits - 1 - i);
63
64 Ut = mod_C.multiply(U, V);
65
66 Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U)));
67 Vt.ct_cond_add(Vt.is_odd(), C);
68 Vt >>= 1;
69 Vt = mod_C.reduce(Vt);
70
71 U = Ut;
72 V = Vt;
73
74 U2 = mod_C.reduce(Ut + Vt);
75 U2.ct_cond_add(U2.is_odd(), C);
76 U2 >>= 1;
77
78 V2 = mod_C.reduce(Vt + Ut*D);
79 V2.ct_cond_add(V2.is_odd(), C);
80 V2 >>= 1;
81
82 U.ct_cond_assign(k_bit, U2);
83 V.ct_cond_assign(k_bit, V2);
84 }
85
86 return (U == 0);
87 }
88
90 {
91 if(n < 3 || n.is_even())
92 return false;
93
94 auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
95 const auto base = BigInt::from_word(2);
96 return passes_miller_rabin_test(n, mod_n, monty_n, base) && is_lucas_probable_prime(n, mod_n);
97 }
98
100 {
101 Modular_Reducer mod_n(n);
102 return is_bailie_psw_probable_prime(n, mod_n);
103 }
104
106 const Modular_Reducer& mod_n,
107 const std::shared_ptr<Montgomery_Params>& monty_n,
108 const BigInt& a)
109 {
110 if(n < 3 || n.is_even())
111 return false;
112
113 BOTAN_ASSERT_NOMSG(n > 1);
114
115 const BigInt n_minus_1 = n - 1;
116 const size_t s = low_zero_bits(n_minus_1);
117 const BigInt nm1_s = n_minus_1 >> s;
118 const size_t n_bits = n.bits();
119
120 const size_t powm_window = 4;
121
122 auto powm_a_n = monty_precompute(monty_n, a, powm_window);
123
124 BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits);
125
126 if(y == 1 || y == n_minus_1)
127 return true;
128
129 for(size_t i = 1; i != s; ++i)
130 {
131 y = mod_n.square(y);
132
133 if(y == 1) // found a non-trivial square root
134 return false;
135
136 /*
137 -1 is the trivial square root of unity, so ``a`` is not a
138 witness for this number - give up
139 */
140 if(y == n_minus_1)
141 return true;
142 }
143
144 return false;
145 }
146
148 const Modular_Reducer& mod_n,
150 size_t test_iterations)
151 {
152 if(n < 3 || n.is_even())
153 return false;
154
155 auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
156
157 for(size_t i = 0; i != test_iterations; ++i)
158 {
159 const BigInt a = BigInt::random_integer(rng, BigInt::from_word(2), n);
160
161 if(!passes_miller_rabin_test(n, mod_n, monty_n, a))
162 return false;
163 }
164
165 // Failed to find a counterexample
166 return true;
167 }
168
169
170size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
171 {
172 const size_t base = (prob + 2) / 2; // worst case 4^-t error rate
173
174 /*
175 * If the candidate prime was maliciously constructed, we can't rely
176 * on arguments based on p being random.
177 */
178 if(random == false)
179 return base;
180
181 /*
182 * For randomly chosen numbers we can use the estimates from
183 * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
184 *
185 * These values are derived from the inequality for p(k,t) given on
186 * the second page.
187 */
188 if(prob <= 128)
189 {
190 if(n_bits >= 1536)
191 return 4; // < 2^-133
192 if(n_bits >= 1024)
193 return 6; // < 2^-133
194 if(n_bits >= 512)
195 return 12; // < 2^-129
196 if(n_bits >= 256)
197 return 29; // < 2^-128
198 }
199
200 /*
201 If the user desires a smaller error probability than we have
202 precomputed error estimates for, just fall back to using the worst
203 case error rate.
204 */
205 return base;
206 }
207
208}
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:67
void ct_cond_add(bool predicate, const BigInt &value)
Definition: bigint.cpp:451
bool is_odd() const
Definition: bigint.h:418
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition: big_rand.cpp:45
void ct_cond_assign(bool predicate, const BigInt &other)
Definition: bigint.cpp:484
void flip_sign()
Definition: bigint.h:568
static BigInt one()
Definition: bigint.h:50
size_t bits() const
Definition: bigint.cpp:309
bool is_even() const
Definition: bigint.h:412
static BigInt from_word(word n)
Definition: bigint.cpp:43
bool is_negative() const
Definition: bigint.h:541
bool get_bit(size_t n) const
Definition: bigint.h:479
BigInt square(const BigInt &x) const
Definition: reducer.h:46
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
BigInt reduce(const BigInt &x) const
Definition: reducer.cpp:37
Definition: alg_id.cpp:13
size_t low_zero_bits(const BigInt &n)
Definition: numthry.cpp:181
bool passes_miller_rabin_test(const BigInt &n, const Modular_Reducer &mod_n, const std::shared_ptr< Montgomery_Params > &monty_n, const BigInt &a)
Definition: primality.cpp:105
bool is_miller_rabin_probable_prime(const BigInt &n, const Modular_Reducer &mod_n, RandomNumberGenerator &rng, size_t test_iterations)
Definition: primality.cpp:147
bool is_bailie_psw_probable_prime(const BigInt &n, const Modular_Reducer &mod_n)
Definition: primality.cpp:89
BigInt is_perfect_square(const BigInt &C)
Definition: numthry.cpp:338
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
Definition: primality.cpp:170
int32_t jacobi(const BigInt &a, const BigInt &n)
Definition: numthry.cpp:130
bool is_lucas_probable_prime(const BigInt &C, const Modular_Reducer &mod_C)
Definition: primality.cpp:17
BigInt monty_execute(const Montgomery_Exponentation_State &precomputed_state, const BigInt &k, size_t max_k_bits)
Definition: monty_exp.cpp:162
std::shared_ptr< const Montgomery_Exponentation_State > monty_precompute(const std::shared_ptr< const Montgomery_Params > &params, const BigInt &g, size_t window_bits, bool const_time)
Definition: monty_exp.cpp:154