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