Coverage Report

Created: 2026-04-01 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/math/numbertheory/numthry.cpp
Line
Count
Source
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
21
namespace Botan {
22
23
/*
24
* Tonelli-Shanks algorithm
25
*/
26
0
BigInt sqrt_modulo_prime(const BigInt& a, const BigInt& p) {
27
0
   BOTAN_ARG_CHECK(p > 1, "invalid prime");
28
0
   BOTAN_ARG_CHECK(a < p, "value to solve for must be less than p");
29
0
   BOTAN_ARG_CHECK(a >= 0, "value to solve for must not be negative");
30
31
   // some very easy cases
32
0
   if(p == 2 || a <= 1) {
33
0
      return a;
34
0
   }
35
36
0
   BOTAN_ARG_CHECK(p.is_odd(), "invalid prime");
37
38
0
   if(jacobi(a, p) != 1) {  // not a quadratic residue
39
0
      return BigInt::from_s32(-1);
40
0
   }
41
42
0
   auto mod_p = Barrett_Reduction::for_public_modulus(p);
43
0
   const Montgomery_Params monty_p(p, mod_p);
44
45
   // If p == 3 (mod 4) there is a simple solution
46
0
   if(p % 4 == 3) {
47
0
      return monty_exp_vartime(monty_p, a, ((p + 1) >> 2)).value();
48
0
   }
49
50
   // Otherwise we have to use Shanks-Tonelli
51
0
   size_t s = low_zero_bits(p - 1);
52
0
   BigInt q = p >> s;
53
54
0
   q -= 1;
55
0
   q >>= 1;
56
57
0
   BigInt r = monty_exp_vartime(monty_p, a, q).value();
58
0
   BigInt n = mod_p.multiply(a, mod_p.square(r));
59
0
   r = mod_p.multiply(r, a);
60
61
0
   if(n == 1) {
62
0
      return r;
63
0
   }
64
65
   // find random quadratic nonresidue z
66
0
   word z = 2;
67
0
   for(;;) {
68
0
      if(jacobi(BigInt::from_word(z), p) == -1) {  // found one
69
0
         break;
70
0
      }
71
72
0
      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
0
      if(z >= 256) {
80
0
         return BigInt::from_s32(-1);
81
0
      }
82
0
   }
83
84
0
   BigInt c = monty_exp_vartime(monty_p, BigInt::from_word(z), (q << 1) + 1).value();
85
86
0
   while(n > 1) {
87
0
      q = n;
88
89
0
      size_t i = 0;
90
0
      while(q != 1) {
91
0
         q = mod_p.square(q);
92
0
         ++i;
93
94
0
         if(i >= s) {
95
0
            return BigInt::from_s32(-1);
96
0
         }
97
0
      }
98
99
0
      BOTAN_ASSERT_NOMSG(s >= (i + 1));  // No underflow!
100
0
      c = monty_exp_vartime(monty_p, c, BigInt::power_of_2(s - i - 1)).value();
101
0
      r = mod_p.multiply(r, c);
102
0
      c = mod_p.square(c);
103
0
      n = mod_p.multiply(n, c);
104
105
      // s decreases as the algorithm proceeds
106
0
      BOTAN_ASSERT_NOMSG(s >= i);
107
0
      s = i;
108
0
   }
109
110
0
   return r;
111
0
}
112
113
/*
114
* Calculate the Jacobi symbol
115
*
116
* See Algorithm 2.149 in Handbook of Applied Cryptography
117
*/
118
190
int32_t jacobi(BigInt a, BigInt n) {
119
190
   BOTAN_ARG_CHECK(n.is_odd() && n >= 3, "Argument n must be an odd integer >= 3");
120
121
190
   if(a < 0 || a >= n) {
122
45
      a %= n;
123
45
   }
124
125
190
   if(a == 0) {
126
0
      return 0;
127
0
   }
128
190
   if(a == 1) {
129
0
      return 1;
130
0
   }
131
132
190
   int32_t s = 1;
133
134
500
   for(;;) {
135
500
      const size_t e = low_zero_bits(a);
136
500
      a >>= e;
137
500
      const word n_mod_8 = n.word_at(0) % 8;
138
500
      const word n_mod_4 = n_mod_8 % 4;
139
140
500
      if(e % 2 == 1 && (n_mod_8 == 3 || n_mod_8 == 5)) {
141
124
         s = -s;
142
124
      }
143
144
500
      if(n_mod_4 == 3 && a % 4 == 3) {
145
54
         s = -s;
146
54
      }
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
500
      if(a == 1) {
165
190
         return s;
166
190
      }
167
168
310
      std::swap(a, n);
169
170
310
      BOTAN_ASSERT_NOMSG(n.is_odd());
171
172
310
      a %= n;
173
174
310
      if(a == 0) {
175
0
         return 0;
176
0
      }
177
310
   }
178
190
}
179
180
/*
181
* Square a BigInt
182
*/
183
0
BigInt square(const BigInt& x) {
184
0
   BigInt z = x;
185
0
   secure_vector<word> ws;
186
0
   z.square(ws);
187
0
   return z;
188
0
}
189
190
/*
191
* Return the number of 0 bits at the end of n
192
*/
193
11.7k
size_t low_zero_bits(const BigInt& n) {
194
11.7k
   size_t low_zero = 0;
195
196
11.7k
   auto seen_nonempty_word = CT::Mask<word>::cleared();
197
198
105k
   for(size_t i = 0; i != n.size(); ++i) {
199
94.0k
      const word x = n.word_at(i);
200
201
      // ctz(0) will return sizeof(word)
202
94.0k
      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
94.0k
      low_zero += seen_nonempty_word.if_not_set_return(tz_x);
207
208
94.0k
      seen_nonempty_word |= CT::Mask<word>::expand(x);
209
94.0k
   }
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
11.7k
   return static_cast<size_t>(seen_nonempty_word.if_set_return(low_zero));
214
11.7k
}
215
216
/*
217
* Calculate the GCD in constant time
218
*/
219
0
BigInt gcd(const BigInt& a, const BigInt& b) {
220
0
   if(a.is_zero()) {
221
0
      return abs(b);
222
0
   }
223
0
   if(b.is_zero()) {
224
0
      return abs(a);
225
0
   }
226
227
0
   const size_t sz = std::max(a.sig_words(), b.sig_words());
228
0
   auto u = BigInt::with_capacity(sz);
229
0
   auto v = BigInt::with_capacity(sz);
230
0
   u += a;
231
0
   v += b;
232
233
0
   CT::poison_all(u, v);
234
235
0
   u.set_sign(BigInt::Positive);
236
0
   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
0
   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
0
   auto tmp = BigInt::with_capacity(sz);
247
0
   secure_vector<word> ws(sz * 2);
248
0
   size_t factors_of_two = 0;
249
0
   for(size_t i = 0; i != loop_cnt; ++i) {
250
0
      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
0
      auto u_gt_v = CT::Mask<word>::expand_bool(bigint_cmp(u._data(), u.size(), v._data(), v.size()) > 0);
254
0
      bigint_sub_abs(tmp.mutable_data(), u._data(), v._data(), sz, ws.data());
255
0
      u.ct_cond_assign((u_gt_v & both_odd).as_bool(), tmp);
256
0
      v.ct_cond_assign((~u_gt_v & both_odd).as_bool(), tmp);
257
258
0
      const auto u_is_even = CT::Mask<word>::expand_bool(u.is_even());
259
0
      const auto v_is_even = CT::Mask<word>::expand_bool(v.is_even());
260
0
      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
0
      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
0
      bigint_shr2(tmp.mutable_data(), u._data(), sz, 1);
268
0
      u.ct_cond_assign(u_is_even.as_bool(), tmp);
269
270
      // remove one factor of 2, if v is even
271
0
      bigint_shr2(tmp.mutable_data(), v._data(), sz, 1);
272
0
      v.ct_cond_assign(v_is_even.as_bool(), tmp);
273
0
   }
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
0
   BOTAN_DEBUG_ASSERT(u.is_zero() || v.is_zero());
279
0
   BOTAN_DEBUG_ASSERT(u.is_odd() || v.is_odd());
280
281
   // make sure that the GCD (without factors of two) is in u
282
0
   u.ct_cond_assign(u.is_even() /* .is_zero() would not be constant time */, v);
283
284
   // re-apply the factors of two
285
0
   u.ct_shift_left(factors_of_two);
286
287
0
   CT::unpoison_all(u, v);
288
289
0
   return u;
290
0
}
291
292
/*
293
* Calculate the LCM
294
*/
295
0
BigInt lcm(const BigInt& a, const BigInt& b) {
296
0
   if(a == b) {
297
0
      return a;
298
0
   }
299
300
0
   auto ab = a * b;
301
0
   ab.set_sign(BigInt::Positive);  // ignore the signs of a & b
302
0
   const auto g = gcd(a, b);
303
0
   return ct_divide(ab, g);
304
0
}
305
306
/*
307
* Modular Exponentiation
308
*/
309
0
BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) {
310
0
   if(mod.is_negative() || mod == 1) {
311
0
      return BigInt::zero();
312
0
   }
313
314
0
   if(base.is_zero() || mod.is_zero()) {
315
0
      if(exp.is_zero()) {
316
0
         return BigInt::one();
317
0
      }
318
0
      return BigInt::zero();
319
0
   }
320
321
0
   auto reduce_mod = Barrett_Reduction::for_secret_modulus(mod);
322
323
0
   const size_t exp_bits = exp.bits();
324
325
0
   if(mod.is_odd()) {
326
0
      const Montgomery_Params monty_params(mod, reduce_mod);
327
0
      return monty_exp(monty_params, ct_modulo(base, mod), exp, exp_bits).value();
328
0
   }
329
330
   /*
331
   Support for even modulus is just a convenience and not considered
332
   cryptographically important, so this implementation is slow ...
333
   */
334
0
   BigInt accum = BigInt::one();
335
0
   BigInt g = ct_modulo(base, mod);
336
0
   BigInt t;
337
338
0
   for(size_t i = 0; i != exp_bits; ++i) {
339
0
      t = reduce_mod.multiply(g, accum);
340
0
      g = reduce_mod.square(g);
341
0
      accum.ct_cond_assign(exp.get_bit(i), t);
342
0
   }
343
0
   return accum;
344
0
}
345
346
0
BigInt is_perfect_square(const BigInt& C) {
347
0
   if(C < 1) {
348
0
      throw Invalid_Argument("is_perfect_square requires C >= 1");
349
0
   }
350
0
   if(C == 1) {
351
0
      return BigInt::one();
352
0
   }
353
354
0
   const size_t n = C.bits();
355
0
   const size_t m = (n + 1) / 2;
356
0
   const BigInt B = C + BigInt::power_of_2(m);
357
358
0
   BigInt X = BigInt::power_of_2(m) - 1;
359
0
   BigInt X2 = (X * X);
360
361
0
   for(;;) {
362
0
      X = (X2 + C) / (2 * X);
363
0
      X2 = (X * X);
364
365
0
      if(X2 < B) {
366
0
         break;
367
0
      }
368
0
   }
369
370
0
   if(X2 == C) {
371
0
      return X;
372
0
   } else {
373
0
      return BigInt::zero();
374
0
   }
375
0
}
376
377
/*
378
* Test for primality using Miller-Rabin
379
*/
380
349
bool is_prime(const BigInt& n, RandomNumberGenerator& rng, size_t prob, bool is_random) {
381
349
   if(n == 2) {
382
0
      return true;
383
0
   }
384
349
   if(n <= 1 || n.is_even()) {
385
0
      return false;
386
0
   }
387
388
349
   const size_t n_bits = n.bits();
389
390
   // Fast path testing for small numbers (<= 65521)
391
349
   if(n_bits <= 16) {
392
0
      const uint16_t num = static_cast<uint16_t>(n.word_at(0));
393
394
0
      return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
395
0
   }
396
397
349
   auto mod_n = Barrett_Reduction::for_secret_modulus(n);
398
399
349
   if(rng.is_seeded()) {
400
349
      const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random);
401
402
349
      if(!is_miller_rabin_probable_prime(n, mod_n, rng, t)) {
403
0
         return false;
404
0
      }
405
406
349
      if(is_random) {
407
0
         return true;
408
349
      } else {
409
349
         return is_lucas_probable_prime(n, mod_n);
410
349
      }
411
349
   } else {
412
0
      return is_bailie_psw_probable_prime(n, mod_n);
413
0
   }
414
349
}
415
416
}  // namespace Botan