Botan 3.6.1
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
9#include <botan/bigint.h>
10#include <botan/reducer.h>
11#include <botan/rng.h>
12#include <botan/internal/monty.h>
13#include <botan/internal/monty_exp.h>
14#include <algorithm>
15
16namespace Botan {
17
18bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) {
19 if(C == 2 || C == 3 || C == 5 || C == 7 || C == 11 || C == 13) {
20 return true;
21 }
22
23 if(C <= 1 || C.is_even()) {
24 return false;
25 }
26
28
29 for(;;) {
30 int32_t j = jacobi(D, C);
31 if(j == 0) {
32 return false;
33 }
34
35 if(j == -1) {
36 break;
37 }
38
39 // Check 5, -7, 9, -11, 13, -15, 17, ...
40 if(D.is_negative()) {
41 D.flip_sign();
42 D += 2;
43 } else {
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
53 const BigInt K = C + 1;
54 const size_t K_bits = K.bits() - 1;
55
56 BigInt U = BigInt::one();
57 BigInt V = BigInt::one();
58
59 BigInt Ut, Vt, U2, V2;
60
61 for(size_t i = 0; i != K_bits; ++i) {
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 if(n == 2) {
91 return true;
92 } else if(n <= 1 || n.is_even()) {
93 return false;
94 }
95
96 auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
97 const auto base = BigInt::from_word(2);
98 return passes_miller_rabin_test(n, mod_n, monty_n, base) && is_lucas_probable_prime(n, mod_n);
99}
100
102 Modular_Reducer mod_n(n);
103 return is_bailie_psw_probable_prime(n, mod_n);
104}
105
107 const Modular_Reducer& mod_n,
108 const std::shared_ptr<Montgomery_Params>& monty_n,
109 const BigInt& a) {
110 if(n < 3 || n.is_even()) {
111 return false;
112 }
113
114 BOTAN_ASSERT_NOMSG(n > 1);
115
116 const BigInt n_minus_1 = n - 1;
117 const size_t s = low_zero_bits(n_minus_1);
118 const BigInt nm1_s = n_minus_1 >> s;
119 const size_t n_bits = n.bits();
120
121 const size_t powm_window = 4;
122
123 auto powm_a_n = monty_precompute(monty_n, a, powm_window);
124
125 BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits);
126
127 if(y == 1 || y == n_minus_1) {
128 return true;
129 }
130
131 for(size_t i = 1; i != s; ++i) {
132 y = mod_n.square(y);
133
134 if(y == 1) { // found a non-trivial square root
135 return false;
136 }
137
138 /*
139 -1 is the trivial square root of unity, so ``a`` is not a
140 witness for this number - give up
141 */
142 if(y == n_minus_1) {
143 return true;
144 }
145 }
146
147 return false;
148}
149
151 const Modular_Reducer& mod_n,
153 size_t test_iterations) {
154 if(n < 3 || n.is_even()) {
155 return false;
156 }
157
158 auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
159
160 for(size_t i = 0; i != test_iterations; ++i) {
161 const BigInt a = BigInt::random_integer(rng, BigInt::from_word(2), n);
162
163 if(!passes_miller_rabin_test(n, mod_n, monty_n, a)) {
164 return false;
165 }
166 }
167
168 // Failed to find a counterexample
169 return true;
170}
171
172size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random) {
173 const size_t base = (prob + 2) / 2; // worst case 4^-t error rate
174
175 /*
176 * If the candidate prime was maliciously constructed, we can't rely
177 * on arguments based on p being random.
178 */
179 if(random == false) {
180 return base;
181 }
182
183 /*
184 * For randomly chosen numbers we can use the estimates from
185 * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
186 *
187 * These values are derived from the inequality for p(k,t) given on
188 * the second page.
189 */
190 if(prob <= 128) {
191 if(n_bits >= 1536) {
192 return 4; // < 2^-133
193 }
194 if(n_bits >= 1024) {
195 return 6; // < 2^-133
196 }
197 if(n_bits >= 512) {
198 return 12; // < 2^-129
199 }
200 if(n_bits >= 256) {
201 return 29; // < 2^-128
202 }
203 }
204
205 /*
206 If the user desires a smaller error probability than we have
207 precomputed error estimates for, just fall back to using the worst
208 case error rate.
209 */
210 return base;
211}
212
213} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
void ct_cond_add(bool predicate, const BigInt &value)
Definition bigint.cpp:437
bool is_odd() const
Definition bigint.h:446
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition big_rand.cpp:43
void ct_cond_assign(bool predicate, const BigInt &other)
Definition bigint.cpp:500
void flip_sign()
Definition bigint.h:587
static BigInt one()
Definition bigint.h:55
size_t bits() const
Definition bigint.cpp:295
bool is_even() const
Definition bigint.h:440
static BigInt from_word(word n)
Definition bigint.cpp:42
bool is_negative() const
Definition bigint.h:560
BigInt square(const BigInt &x) const
Definition reducer.h:45
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition reducer.h:32
BigInt reduce(const BigInt &x) const
Definition reducer.cpp:37
size_t low_zero_bits(const BigInt &n)
Definition numthry.cpp:167
bool passes_miller_rabin_test(const BigInt &n, const Modular_Reducer &mod_n, const std::shared_ptr< Montgomery_Params > &monty_n, const BigInt &a)
bool is_miller_rabin_probable_prime(const BigInt &n, const Modular_Reducer &mod_n, RandomNumberGenerator &rng, size_t test_iterations)
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:321
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
int32_t jacobi(const BigInt &a, const BigInt &n)
Definition numthry.cpp:116
bool is_lucas_probable_prime(const BigInt &C, const Modular_Reducer &mod_C)
Definition primality.cpp:18
BigInt monty_execute(const Montgomery_Exponentation_State &precomputed_state, const BigInt &k, size_t max_k_bits)
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)