Botan 3.11.0
Crypto and TLS for C&
numthry.cpp
Go to the documentation of this file.
1/*
2* Number Theory Functions
3* (C) 1999-2011,2016,2018,2019 Jack Lloyd
4* (C) 2007,2008 Falko Strenzke, FlexSecure GmbH
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/numthry.h>
10
11#include <botan/exceptn.h>
12#include <botan/rng.h>
13#include <botan/internal/barrett.h>
14#include <botan/internal/ct_utils.h>
15#include <botan/internal/divide.h>
16#include <botan/internal/monty.h>
17#include <botan/internal/monty_exp.h>
18#include <botan/internal/mp_core.h>
19#include <botan/internal/primality.h>
20#include <algorithm>
21
22namespace Botan {
23
24/*
25* Tonelli-Shanks algorithm
26*/
28 BOTAN_ARG_CHECK(p > 1, "invalid prime");
29 BOTAN_ARG_CHECK(a < p, "value to solve for must be less than p");
30 BOTAN_ARG_CHECK(a >= 0, "value to solve for must not be negative");
31
32 // some very easy cases
33 if(p == 2 || a <= 1) {
34 return a;
35 }
36
37 BOTAN_ARG_CHECK(p.is_odd(), "invalid prime");
38
39 if(jacobi(a, p) != 1) { // not a quadratic residue
40 return BigInt::from_s32(-1);
41 }
42
44 const Montgomery_Params monty_p(p, mod_p);
45
46 // If p == 3 (mod 4) there is a simple solution
47 if(p % 4 == 3) {
48 return monty_exp_vartime(monty_p, a, ((p + 1) >> 2)).value();
49 }
50
51 // Otherwise we have to use Shanks-Tonelli
52 size_t s = low_zero_bits(p - 1);
53 BigInt q = p >> s;
54
55 q -= 1;
56 q >>= 1;
57
58 BigInt r = monty_exp_vartime(monty_p, a, q).value();
59 BigInt n = mod_p.multiply(a, mod_p.square(r));
60 r = mod_p.multiply(r, a);
61
62 if(n == 1) {
63 return r;
64 }
65
66 // find random quadratic nonresidue z
67 word z = 2;
68 for(;;) {
69 if(jacobi(BigInt::from_word(z), p) == -1) { // found one
70 break;
71 }
72
73 z += 1; // try next z
74
75 /*
76 * The expected number of tests to find a non-residue modulo a
77 * prime is 2. If we have not found one after 256 then almost
78 * certainly we have been given a non-prime p.
79 */
80 if(z >= 256) {
81 return BigInt::from_s32(-1);
82 }
83 }
84
85 BigInt c = monty_exp_vartime(monty_p, BigInt::from_word(z), (q << 1) + 1).value();
86
87 while(n > 1) {
88 q = n;
89
90 size_t i = 0;
91 while(q != 1) {
92 q = mod_p.square(q);
93 ++i;
94
95 if(i >= s) {
96 return BigInt::from_s32(-1);
97 }
98 }
99
100 BOTAN_ASSERT_NOMSG(s >= (i + 1)); // No underflow!
101 c = monty_exp_vartime(monty_p, c, BigInt::power_of_2(s - i - 1)).value();
102 r = mod_p.multiply(r, c);
103 c = mod_p.square(c);
104 n = mod_p.multiply(n, c);
105
106 // s decreases as the algorithm proceeds
107 BOTAN_ASSERT_NOMSG(s >= i);
108 s = i;
109 }
110
111 return r;
112}
113
114/*
115* Calculate the Jacobi symbol
116*
117* See Algorithm 2.149 in Handbook of Applied Cryptography
118*/
119int32_t jacobi(BigInt a, BigInt n) {
120 BOTAN_ARG_CHECK(n.is_odd() && n >= 3, "Argument n must be an odd integer >= 3");
121
122 if(a < 0 || a >= n) {
123 a %= n;
124 }
125
126 if(a == 0) {
127 return 0;
128 }
129 if(a == 1) {
130 return 1;
131 }
132
133 int32_t s = 1;
134
135 for(;;) {
136 const size_t e = low_zero_bits(a);
137 a >>= e;
138 const word n_mod_8 = n.word_at(0) % 8;
139 const word n_mod_4 = n_mod_8 % 4;
140
141 if(e % 2 == 1 && (n_mod_8 == 3 || n_mod_8 == 5)) {
142 s = -s;
143 }
144
145 if(n_mod_4 == 3 && a % 4 == 3) {
146 s = -s;
147 }
148
149 /*
150 * The HAC presentation of the algorithm uses recursion, which is not
151 * desirable or necessary.
152 *
153 * Instead we loop accumulating the product of the various jacobi()
154 * subcomputations into s, until we reach algorithm termination, which
155 * occurs in one of two ways.
156 *
157 * If a == 1 then the recursion has completed; we can return the value of s.
158 *
159 * Otherwise, after swapping and reducing, check for a == 0 [this value is
160 * called `n1` in HAC's presentation]. This would imply that jacobi(n1,a1)
161 * would have the value 0, due to Line 1 in HAC 2.149, in which case the
162 * entire product is zero, and we can immediately return that result.
163 */
164
165 if(a == 1) {
166 return s;
167 }
168
169 std::swap(a, n);
170
172
173 a %= n;
174
175 if(a == 0) {
176 return 0;
177 }
178 }
179}
180
181/*
182* Square a BigInt
183*/
185 BigInt z = x;
187 z.square(ws);
188 return z;
189}
190
191/*
192* Return the number of 0 bits at the end of n
193*/
194size_t low_zero_bits(const BigInt& n) {
195 size_t low_zero = 0;
196
197 auto seen_nonempty_word = CT::Mask<word>::cleared();
198
199 for(size_t i = 0; i != n.size(); ++i) {
200 const word x = n.word_at(i);
201
202 // ctz(0) will return sizeof(word)
203 const size_t tz_x = ctz(x);
204
205 // if x > 0 we want to count tz_x in total but not any
206 // further words, so set the mask after the addition
207 low_zero += seen_nonempty_word.if_not_set_return(tz_x);
208
209 seen_nonempty_word |= CT::Mask<word>::expand(x);
210 }
211
212 // if we saw no words with x > 0 then n == 0 and the value we have
213 // computed is meaningless. Instead return BigInt::zero() in that case.
214 return static_cast<size_t>(seen_nonempty_word.if_set_return(low_zero));
215}
216
217/*
218* Calculate the GCD in constant time
219*/
220BigInt gcd(const BigInt& a, const BigInt& b) {
221 if(a.is_zero()) {
222 return abs(b);
223 }
224 if(b.is_zero()) {
225 return abs(a);
226 }
227
228 const size_t sz = std::max(a.sig_words(), b.sig_words());
229 auto u = BigInt::with_capacity(sz);
230 auto v = BigInt::with_capacity(sz);
231 u += a;
232 v += b;
233
234 CT::poison_all(u, v);
235
236 u.set_sign(BigInt::Positive);
237 v.set_sign(BigInt::Positive);
238
239 // In the worst case we have two fully populated big ints. After right
240 // shifting so many times, we'll have reached the result for sure.
241 const size_t loop_cnt = u.bits() + v.bits();
242
243 // This temporary is big enough to hold all intermediate results of the
244 // algorithm. No reallocation will happen during the loop.
245 // Note however, that `ct_cond_assign()` will invalidate the 'sig_words'
246 // cache, which _does not_ shrink the capacity of the underlying buffer.
247 auto tmp = BigInt::with_capacity(sz);
248 secure_vector<word> ws(sz * 2);
249 size_t factors_of_two = 0;
250 for(size_t i = 0; i != loop_cnt; ++i) {
251 auto both_odd = CT::Mask<word>::expand_bool(u.is_odd()) & CT::Mask<word>::expand_bool(v.is_odd());
252
253 // Subtract the smaller from the larger if both are odd
254 auto u_gt_v = CT::Mask<word>::expand_bool(bigint_cmp(u._data(), u.size(), v._data(), v.size()) > 0);
255 bigint_sub_abs(tmp.mutable_data(), u._data(), v._data(), sz, ws.data());
256 u.ct_cond_assign((u_gt_v & both_odd).as_bool(), tmp);
257 v.ct_cond_assign((~u_gt_v & both_odd).as_bool(), tmp);
258
259 const auto u_is_even = CT::Mask<word>::expand_bool(u.is_even());
260 const auto v_is_even = CT::Mask<word>::expand_bool(v.is_even());
261 BOTAN_DEBUG_ASSERT((u_is_even | v_is_even).as_bool());
262
263 // When both are even, we're going to eliminate a factor of 2.
264 // We have to reapply this factor to the final result.
265 factors_of_two += (u_is_even & v_is_even).if_set_return(1);
266
267 // remove one factor of 2, if u is even
268 bigint_shr2(tmp.mutable_data(), u._data(), sz, 1);
269 u.ct_cond_assign(u_is_even.as_bool(), tmp);
270
271 // remove one factor of 2, if v is even
272 bigint_shr2(tmp.mutable_data(), v._data(), sz, 1);
273 v.ct_cond_assign(v_is_even.as_bool(), tmp);
274 }
275
276 // The GCD (without factors of two) is either in u or v, the other one is
277 // zero. The non-zero variable _must_ be odd, because all factors of two were
278 // removed in the loop iterations above.
279 BOTAN_DEBUG_ASSERT(u.is_zero() || v.is_zero());
280 BOTAN_DEBUG_ASSERT(u.is_odd() || v.is_odd());
281
282 // make sure that the GCD (without factors of two) is in u
283 u.ct_cond_assign(u.is_even() /* .is_zero() would not be constant time */, v);
284
285 // re-apply the factors of two
286 u.ct_shift_left(factors_of_two);
287
288 CT::unpoison_all(u, v);
289
290 return u;
291}
292
293/*
294* Calculate the LCM
295*/
296BigInt lcm(const BigInt& a, const BigInt& b) {
297 if(a == b) {
298 return a;
299 }
300
301 auto ab = a * b;
302 ab.set_sign(BigInt::Positive); // ignore the signs of a & b
303 const auto g = gcd(a, b);
304 return ct_divide(ab, g);
305}
306
307/*
308* Modular Exponentiation
309*/
310BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) {
311 if(mod.is_negative() || mod == 1) {
312 return BigInt::zero();
313 }
314
315 if(base.is_zero() || mod.is_zero()) {
316 if(exp.is_zero()) {
317 return BigInt::one();
318 }
319 return BigInt::zero();
320 }
321
323
324 const size_t exp_bits = exp.bits();
325
326 if(mod.is_odd()) {
327 const Montgomery_Params monty_params(mod, reduce_mod);
328 return monty_exp(monty_params, ct_modulo(base, mod), exp, exp_bits).value();
329 }
330
331 /*
332 Support for even modulus is just a convenience and not considered
333 cryptographically important, so this implementation is slow ...
334 */
335 BigInt accum = BigInt::one();
336 BigInt g = ct_modulo(base, mod);
337 BigInt t;
338
339 for(size_t i = 0; i != exp_bits; ++i) {
340 t = reduce_mod.multiply(g, accum);
341 g = reduce_mod.square(g);
342 accum.ct_cond_assign(exp.get_bit(i), t);
343 }
344 return accum;
345}
346
348 if(C < 1) {
349 throw Invalid_Argument("is_perfect_square requires C >= 1");
350 }
351 if(C == 1) {
352 return BigInt::one();
353 }
354
355 const size_t n = C.bits();
356 const size_t m = (n + 1) / 2;
357 const BigInt B = C + BigInt::power_of_2(m);
358
359 BigInt X = BigInt::power_of_2(m) - 1;
360 BigInt X2 = (X * X);
361
362 for(;;) {
363 X = (X2 + C) / (2 * X);
364 X2 = (X * X);
365
366 if(X2 < B) {
367 break;
368 }
369 }
370
371 if(X2 == C) {
372 return X;
373 } else {
374 return BigInt::zero();
375 }
376}
377
378/*
379* Test for primality using Miller-Rabin
380*/
381bool is_prime(const BigInt& n, RandomNumberGenerator& rng, size_t prob, bool is_random) {
382 if(n == 2) {
383 return true;
384 }
385 if(n <= 1 || n.is_even()) {
386 return false;
387 }
388
389 const size_t n_bits = n.bits();
390
391 // Fast path testing for small numbers (<= 65521)
392 if(n_bits <= 16) {
393 const uint16_t num = static_cast<uint16_t>(n.word_at(0));
394
395 return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
396 }
397
399
400 if(rng.is_seeded()) {
401 const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random);
402
403 if(!is_miller_rabin_probable_prime(n, mod_n, rng, t)) {
404 return false;
405 }
406
407 if(is_random) {
408 return true;
409 } else {
410 return is_lucas_probable_prime(n, mod_n);
411 }
412 } else {
413 return is_bailie_psw_probable_prime(n, mod_n);
414 }
415}
416
417} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:129
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
static Barrett_Reduction for_public_modulus(const BigInt &m)
Definition barrett.cpp:34
static Barrett_Reduction for_secret_modulus(const BigInt &m)
Definition barrett.cpp:23
static BigInt zero()
Definition bigint.h:50
size_t sig_words() const
Definition bigint.h:631
bool is_odd() const
Definition bigint.h:461
void ct_cond_assign(bool predicate, const BigInt &other)
Definition bigint.cpp:527
size_t size() const
Definition bigint.h:625
static BigInt one()
Definition bigint.h:55
word word_at(size_t n) const
Definition bigint.h:563
size_t bits() const
Definition bigint.cpp:307
bool is_even() const
Definition bigint.h:455
static BigInt power_of_2(size_t n)
Definition bigint.h:836
static BigInt from_s32(int32_t n)
Definition bigint.cpp:42
static BigInt from_word(word n)
Definition bigint.cpp:35
bool is_zero() const
Definition bigint.h:473
BigInt & square(secure_vector< word > &ws)
Definition big_ops2.cpp:175
bool is_negative() const
Definition bigint.h:575
bool get_bit(size_t n) const
Definition bigint.h:512
static BigInt with_capacity(size_t n)
Definition bigint.cpp:51
void set_sign(Sign sign)
Definition bigint.h:608
static constexpr Mask< T > expand(T v)
Definition ct_utils.h:392
static constexpr Mask< T > expand_bool(bool v)
Definition ct_utils.h:397
static constexpr Mask< T > cleared()
Definition ct_utils.h:387
BigInt value() const
Definition monty.cpp:246
virtual bool is_seeded() const =0
constexpr void poison_all(const Ts &... ts)
Definition ct_utils.h:201
constexpr void unpoison_all(const Ts &... ts)
Definition ct_utils.h:207
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition numthry.cpp:310
int32_t jacobi(BigInt a, BigInt n)
Definition numthry.cpp:119
constexpr void bigint_shr2(W y[], const W x[], size_t x_size, size_t shift)
Definition mp_core.h:368
Montgomery_Int monty_exp_vartime(const Montgomery_Params &params_p, const BigInt &g, const BigInt &k)
Definition monty_exp.h:54
bool is_lucas_probable_prime(const BigInt &C, const Barrett_Reduction &mod_C)
Definition primality.cpp:18
BigInt lcm(const BigInt &a, const BigInt &b)
Definition numthry.cpp:296
BigInt square(const BigInt &x)
Definition numthry.cpp:184
const uint16_t PRIMES[]
Definition primes.cpp:12
size_t low_zero_bits(const BigInt &n)
Definition numthry.cpp:194
BigInt abs(const BigInt &n)
Definition numthry.h:22
const size_t PRIME_TABLE_SIZE
Definition numthry.h:175
bool is_bailie_psw_probable_prime(const BigInt &n, const Barrett_Reduction &mod_n)
Definition primality.cpp:98
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition numthry.cpp:381
BigInt ct_modulo(const BigInt &x, const BigInt &y)
Definition divide.cpp:192
constexpr int32_t bigint_cmp(const W x[], size_t x_size, const W y[], size_t y_size)
Definition mp_core.h:426
consteval std::array< W, N > reduce_mod(const std::array< W, XN > &x, const std::array< W, N > &p)
void ct_divide(const BigInt &x, const BigInt &y, BigInt &q_out, BigInt &r_out)
Definition divide.cpp:51
constexpr auto bigint_sub_abs(W z[], const W x[], const W y[], size_t N, W ws[]) -> CT::Mask< W >
Definition mp_core.h:279
BigInt gcd(const BigInt &a, const BigInt &b)
Definition numthry.cpp:220
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68
BigInt sqrt_modulo_prime(const BigInt &a, const BigInt &p)
Definition numthry.cpp:27
BigInt is_perfect_square(const BigInt &C)
Definition numthry.cpp:347
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
bool is_miller_rabin_probable_prime(const BigInt &n, const Barrett_Reduction &mod_n, RandomNumberGenerator &rng, size_t test_iterations)
BOTAN_FORCE_INLINE constexpr size_t ctz(T n)
Definition bit_ops.h:115
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word
Definition types.h:119
Montgomery_Int monty_exp(const Montgomery_Params &params_p, const BigInt &g, const BigInt &k, size_t max_k_bits)
Definition monty_exp.h:46