Botan 3.1.1
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/reducer.h>
12#include <botan/rng.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
23namespace {
24
25void sub_abs(BigInt& z, const BigInt& x, const BigInt& y) {
26 const size_t x_sw = x.sig_words();
27 const size_t y_sw = y.sig_words();
28 z.resize(std::max(x_sw, y_sw));
29
30 bigint_sub_abs(z.mutable_data(), x.data(), x_sw, y.data(), y_sw);
31}
32
33} // namespace
34
35/*
36* Tonelli-Shanks algorithm
37*/
39 BOTAN_ARG_CHECK(p > 1, "invalid prime");
40 BOTAN_ARG_CHECK(a < p, "value to solve for must be less than p");
41 BOTAN_ARG_CHECK(a >= 0, "value to solve for must not be negative");
42
43 // some very easy cases
44 if(p == 2 || a <= 1) {
45 return a;
46 }
47
48 BOTAN_ARG_CHECK(p.is_odd(), "invalid prime");
49
50 if(jacobi(a, p) != 1) { // not a quadratic residue
51 return BigInt::from_s32(-1);
52 }
53
54 Modular_Reducer mod_p(p);
55 auto monty_p = std::make_shared<Montgomery_Params>(p, mod_p);
56
57 // If p == 3 (mod 4) there is a simple solution
58 if(p % 4 == 3) {
59 return monty_exp_vartime(monty_p, a, ((p + 1) >> 2));
60 }
61
62 // Otherwise we have to use Shanks-Tonelli
63 size_t s = low_zero_bits(p - 1);
64 BigInt q = p >> s;
65
66 q -= 1;
67 q >>= 1;
68
69 BigInt r = monty_exp_vartime(monty_p, a, q);
70 BigInt n = mod_p.multiply(a, mod_p.square(r));
71 r = mod_p.multiply(r, a);
72
73 if(n == 1) {
74 return r;
75 }
76
77 // find random quadratic nonresidue z
78 word z = 2;
79 for(;;) {
80 if(jacobi(BigInt::from_word(z), p) == -1) { // found one
81 break;
82 }
83
84 z += 1; // try next z
85
86 /*
87 * The expected number of tests to find a non-residue modulo a
88 * prime is 2. If we have not found one after 256 then almost
89 * certainly we have been given a non-prime p.
90 */
91 if(z >= 256) {
92 return BigInt::from_s32(-1);
93 }
94 }
95
96 BigInt c = monty_exp_vartime(monty_p, BigInt::from_word(z), (q << 1) + 1);
97
98 while(n > 1) {
99 q = n;
100
101 size_t i = 0;
102 while(q != 1) {
103 q = mod_p.square(q);
104 ++i;
105
106 if(i >= s) {
107 return BigInt::from_s32(-1);
108 }
109 }
110
111 BOTAN_ASSERT_NOMSG(s >= (i + 1)); // No underflow!
112 c = monty_exp_vartime(monty_p, c, BigInt::power_of_2(s - i - 1));
113 r = mod_p.multiply(r, c);
114 c = mod_p.square(c);
115 n = mod_p.multiply(n, c);
116
117 // s decreases as the algorithm proceeds
118 BOTAN_ASSERT_NOMSG(s >= i);
119 s = i;
120 }
121
122 return r;
123}
124
125/*
126* Calculate the Jacobi symbol
127*/
128int32_t jacobi(const BigInt& a, const BigInt& n) {
129 if(n.is_even() || n < 2) {
130 throw Invalid_Argument("jacobi: second argument must be odd and > 1");
131 }
132
133 BigInt x = a % n;
134 BigInt y = n;
135 int32_t J = 1;
136
137 while(y > 1) {
138 x %= y;
139 if(x > y / 2) {
140 x = y - x;
141 if(y % 4 == 3) {
142 J = -J;
143 }
144 }
145 if(x.is_zero()) {
146 return 0;
147 }
148
149 size_t shifts = low_zero_bits(x);
150 x >>= shifts;
151 if(shifts % 2) {
152 word y_mod_8 = y % 8;
153 if(y_mod_8 == 3 || y_mod_8 == 5) {
154 J = -J;
155 }
156 }
157
158 if(x % 4 == 3 && y % 4 == 3) {
159 J = -J;
160 }
161 std::swap(x, y);
162 }
163 return J;
164}
165
166/*
167* Square a BigInt
168*/
170 BigInt z = x;
172 z.square(ws);
173 return z;
174}
175
176/*
177* Return the number of 0 bits at the end of n
178*/
179size_t low_zero_bits(const BigInt& n) {
180 size_t low_zero = 0;
181
182 auto seen_nonempty_word = CT::Mask<word>::cleared();
183
184 for(size_t i = 0; i != n.size(); ++i) {
185 const word x = n.word_at(i);
186
187 // ctz(0) will return sizeof(word)
188 const size_t tz_x = ctz(x);
189
190 // if x > 0 we want to count tz_x in total but not any
191 // further words, so set the mask after the addition
192 low_zero += seen_nonempty_word.if_not_set_return(tz_x);
193
194 seen_nonempty_word |= CT::Mask<word>::expand(x);
195 }
196
197 // if we saw no words with x > 0 then n == 0 and the value we have
198 // computed is meaningless. Instead return BigInt::zero() in that case.
199 return seen_nonempty_word.if_set_return(low_zero);
200}
201
202namespace {
203
204size_t safegcd_loop_bound(size_t f_bits, size_t g_bits) {
205 const size_t d = std::max(f_bits, g_bits);
206 return 4 + 3 * d;
207}
208
209} // namespace
210
211/*
212* Calculate the GCD
213*/
214BigInt gcd(const BigInt& a, const BigInt& b) {
215 if(a.is_zero()) {
216 return abs(b);
217 }
218 if(b.is_zero()) {
219 return abs(a);
220 }
221 if(a == 1 || b == 1) {
222 return BigInt::one();
223 }
224
225 // See https://gcd.cr.yp.to/safegcd-20190413.pdf fig 1.2
226
227 BigInt f = a;
228 BigInt g = b;
231
234
235 const size_t common2s = std::min(low_zero_bits(f), low_zero_bits(g));
236 CT::unpoison(common2s);
237
238 f >>= common2s;
239 g >>= common2s;
240
241 f.ct_cond_swap(f.is_even(), g);
242
243 int32_t delta = 1;
244
245 const size_t loop_cnt = safegcd_loop_bound(f.bits(), g.bits());
246
247 BigInt newg, t;
248 for(size_t i = 0; i != loop_cnt; ++i) {
249 sub_abs(newg, f, g);
250
251 const bool need_swap = (g.is_odd() && delta > 0);
252
253 // if(need_swap) { delta *= -1 } else { delta *= 1 }
254 delta *= CT::Mask<uint8_t>::expand(need_swap).if_not_set_return(2) - 1;
255 f.ct_cond_swap(need_swap, g);
256 g.ct_cond_swap(need_swap, newg);
257
258 delta += 1;
259
260 g.ct_cond_add(g.is_odd(), f);
261 g >>= 1;
262 }
263
264 f <<= common2s;
265
268
270
271 return f;
272}
273
274/*
275* Calculate the LCM
276*/
277BigInt lcm(const BigInt& a, const BigInt& b) {
278 if(a == b) {
279 return a;
280 }
281
282 auto ab = a * b;
283 ab.set_sign(BigInt::Positive); // ignore the signs of a & b
284 const auto g = gcd(a, b);
285 return ct_divide(ab, g);
286}
287
288/*
289* Modular Exponentiation
290*/
291BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) {
292 if(mod.is_negative() || mod == 1) {
293 return BigInt::zero();
294 }
295
296 if(base.is_zero() || mod.is_zero()) {
297 if(exp.is_zero()) {
298 return BigInt::one();
299 }
300 return BigInt::zero();
301 }
302
303 Modular_Reducer reduce_mod(mod);
304
305 const size_t exp_bits = exp.bits();
306
307 if(mod.is_odd()) {
308 auto monty_params = std::make_shared<Montgomery_Params>(mod, reduce_mod);
309 return monty_exp(monty_params, reduce_mod.reduce(base), exp, exp_bits);
310 }
311
312 /*
313 Support for even modulus is just a convenience and not considered
314 cryptographically important, so this implementation is slow ...
315 */
316 BigInt accum = BigInt::one();
317 BigInt g = reduce_mod.reduce(base);
318 BigInt t;
319
320 for(size_t i = 0; i != exp_bits; ++i) {
321 t = reduce_mod.multiply(g, accum);
322 g = reduce_mod.square(g);
323 accum.ct_cond_assign(exp.get_bit(i), t);
324 }
325 return accum;
326}
327
329 if(C < 1) {
330 throw Invalid_Argument("is_perfect_square requires C >= 1");
331 }
332 if(C == 1) {
333 return BigInt::one();
334 }
335
336 const size_t n = C.bits();
337 const size_t m = (n + 1) / 2;
338 const BigInt B = C + BigInt::power_of_2(m);
339
340 BigInt X = BigInt::power_of_2(m) - 1;
341 BigInt X2 = (X * X);
342
343 for(;;) {
344 X = (X2 + C) / (2 * X);
345 X2 = (X * X);
346
347 if(X2 < B) {
348 break;
349 }
350 }
351
352 if(X2 == C) {
353 return X;
354 } else {
355 return BigInt::zero();
356 }
357}
358
359/*
360* Test for primality using Miller-Rabin
361*/
362bool is_prime(const BigInt& n, RandomNumberGenerator& rng, size_t prob, bool is_random) {
363 if(n == 2) {
364 return true;
365 }
366 if(n <= 1 || n.is_even()) {
367 return false;
368 }
369
370 const size_t n_bits = n.bits();
371
372 // Fast path testing for small numbers (<= 65521)
373 if(n_bits <= 16) {
374 const uint16_t num = static_cast<uint16_t>(n.word_at(0));
375
376 return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
377 }
378
379 Modular_Reducer mod_n(n);
380
381 if(rng.is_seeded()) {
382 const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random);
383
384 if(is_miller_rabin_probable_prime(n, mod_n, rng, t) == false) {
385 return false;
386 }
387
388 if(is_random) {
389 return true;
390 } else {
391 return is_lucas_probable_prime(n, mod_n);
392 }
393 } else {
394 return is_bailie_psw_probable_prime(n, mod_n);
395 }
396}
397
398} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:59
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:29
void ct_cond_add(bool predicate, const BigInt &value)
Definition: bigint.cpp:424
static BigInt zero()
Definition: bigint.h:44
bool is_odd() const
Definition: bigint.h:412
void ct_cond_assign(bool predicate, const BigInt &other)
Definition: bigint.cpp:453
size_t size() const
Definition: bigint.h:572
static BigInt one()
Definition: bigint.h:49
word word_at(size_t n) const
Definition: bigint.h:514
size_t bits() const
Definition: bigint.cpp:290
bool is_even() const
Definition: bigint.h:406
static BigInt power_of_2(size_t n)
Definition: bigint.h:726
void const_time_poison() const
Definition: bigint.h:708
static BigInt from_s32(int32_t n)
Definition: bigint.cpp:49
void ct_cond_swap(bool predicate, BigInt &other)
Definition: bigint.cpp:433
static BigInt from_word(word n)
Definition: bigint.cpp:42
bool is_zero() const
Definition: bigint.h:424
BigInt & square(secure_vector< word > &ws)
Definition: big_ops2.cpp:183
bool is_negative() const
Definition: bigint.h:524
void const_time_unpoison() const
Definition: bigint.h:710
bool get_bit(size_t n) const
Definition: bigint.h:463
void set_sign(Sign sign)
Definition: bigint.h:556
static Mask< T > expand(T v)
Definition: ct_utils.h:109
static Mask< T > cleared()
Definition: ct_utils.h:104
BigInt square(const BigInt &x) const
Definition: reducer.h:43
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:30
BigInt reduce(const BigInt &x) const
Definition: reducer.cpp:37
virtual bool is_seeded() const =0
FE_25519 X
Definition: ge.cpp:25
void unpoison(const T *p, size_t n)
Definition: ct_utils.h:57
Definition: alg_id.cpp:13
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:291
BigInt monty_exp(std::shared_ptr< const Montgomery_Params > params_p, const BigInt &g, const BigInt &k, size_t max_k_bits)
Definition: monty_exp.h:41
BigInt lcm(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:277
BigInt square(const BigInt &x)
Definition: numthry.cpp:169
const uint16_t PRIMES[]
Definition: primes.cpp:12
size_t low_zero_bits(const BigInt &n)
Definition: numthry.cpp:179
BigInt abs(const BigInt &n)
Definition: numthry.h:22
CT::Mask< word > bigint_sub_abs(word z[], const word x[], const word y[], size_t N, word ws[])
Definition: mp_core.h:339
const size_t PRIME_TABLE_SIZE
Definition: numthry.h:167
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:362
bool is_miller_rabin_probable_prime(const BigInt &n, const Modular_Reducer &mod_n, RandomNumberGenerator &rng, size_t test_iterations)
Definition: primality.cpp:150
constexpr size_t ctz(T n)
Definition: bit_ops.h:102
BigInt monty_exp_vartime(std::shared_ptr< const Montgomery_Params > params_p, const BigInt &g, const BigInt &k)
Definition: monty_exp.h:49
void ct_divide(const BigInt &x, const BigInt &y, BigInt &q_out, BigInt &r_out)
Definition: divide.cpp:48
bool is_bailie_psw_probable_prime(const BigInt &n, const Modular_Reducer &mod_n)
Definition: primality.cpp:89
BigInt gcd(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:214
BigInt sqrt_modulo_prime(const BigInt &a, const BigInt &p)
Definition: numthry.cpp:38
BigInt is_perfect_square(const BigInt &C)
Definition: numthry.cpp:328
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
Definition: primality.cpp:172
int32_t jacobi(const BigInt &a, const BigInt &n)
Definition: numthry.cpp:128
bool is_lucas_probable_prime(const BigInt &C, const Modular_Reducer &mod_C)
Definition: primality.cpp:18
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:61