• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5111374265

29 May 2023 11:19AM UTC coverage: 92.227% (+0.5%) from 91.723%
5111374265

push

github

randombit
Next release will be 3.1.0. Update release notes

75588 of 81959 relevant lines covered (92.23%)

11886470.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.32
/src/lib/math/numbertheory/numthry.cpp
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

21
namespace Botan {
22

23
namespace {
24

25
void sub_abs(BigInt& z, const BigInt& x, const BigInt& y) {
5,361,991✔
26
   const size_t x_sw = x.sig_words();
5,361,991✔
27
   const size_t y_sw = y.sig_words();
5,361,991✔
28
   z.resize(std::max(x_sw, y_sw));
5,418,779✔
29

30
   bigint_sub_abs(z.mutable_data(), x.data(), x_sw, y.data(), y_sw);
5,361,991✔
31
}
5,361,991✔
32

33
}  // namespace
34

35
/*
36
* Tonelli-Shanks algorithm
37
*/
38
BigInt sqrt_modulo_prime(const BigInt& a, const BigInt& p) {
6,762✔
39
   BOTAN_ARG_CHECK(p > 1, "invalid prime");
6,762✔
40
   BOTAN_ARG_CHECK(a < p, "value to solve for must be less than p");
6,762✔
41
   BOTAN_ARG_CHECK(a >= 0, "value to solve for must not be negative");
6,762✔
42

43
   // some very easy cases
44
   if(p == 2 || a <= 1)
13,522✔
45
      return a;
6,765✔
46

47
   BOTAN_ARG_CHECK(p.is_odd(), "invalid prime");
13,518✔
48

49
   if(jacobi(a, p) != 1)  // not a quadratic residue
6,759✔
50
      return BigInt::from_s32(-1);
2,645✔
51

52
   Modular_Reducer mod_p(p);
4,114✔
53
   auto monty_p = std::make_shared<Montgomery_Params>(p, mod_p);
4,114✔
54

55
   if(p % 4 == 3)  // The easy case
4,114✔
56
   {
57
      return monty_exp_vartime(monty_p, a, ((p + 1) >> 2));
18,175✔
58
   }
59

60
   // Otherwise we have to use Shanks-Tonelli
61
   size_t s = low_zero_bits(p - 1);
479✔
62
   BigInt q = p >> s;
479✔
63

64
   q -= 1;
479✔
65
   q >>= 1;
479✔
66

67
   BigInt r = monty_exp_vartime(monty_p, a, q);
479✔
68
   BigInt n = mod_p.multiply(a, mod_p.square(r));
479✔
69
   r = mod_p.multiply(r, a);
479✔
70

71
   if(n == 1)
479✔
72
      return r;
10✔
73

74
   // find random quadratic nonresidue z
75
   word z = 2;
76
   for(;;) {
4,826✔
77
      if(jacobi(BigInt::from_word(z), p) == -1)  // found one
9,652✔
78
         break;
79

80
      z += 1;  // try next z
4,358✔
81

82
      /*
83
      * The expected number of tests to find a non-residue modulo a
84
      * prime is 2. If we have not found one after 256 then almost
85
      * certainly we have been given a non-prime p.
86
      */
87
      if(z >= 256)
4,358✔
88
         return BigInt::from_s32(-1);
1✔
89
   }
90

91
   BigInt c = monty_exp_vartime(monty_p, BigInt::from_word(z), (q << 1) + 1);
2,808✔
92

93
   while(n > 1) {
21,616✔
94
      q = n;
21,154✔
95

96
      size_t i = 0;
21,154✔
97
      while(q != 1) {
1,036,970✔
98
         q = mod_p.square(q);
1,015,822✔
99
         ++i;
1,015,822✔
100

101
         if(i >= s) {
1,015,822✔
102
            return BigInt::from_s32(-1);
6✔
103
         }
104
      }
105

106
      BOTAN_ASSERT_NOMSG(s >= (i + 1));  // No underflow!
21,148✔
107
      c = monty_exp_vartime(monty_p, c, BigInt::power_of_2(s - i - 1));
84,592✔
108
      r = mod_p.multiply(r, c);
21,148✔
109
      c = mod_p.square(c);
21,148✔
110
      n = mod_p.multiply(n, c);
21,148✔
111

112
      // s decreases as the algorithm proceeds
113
      BOTAN_ASSERT_NOMSG(s >= i);
21,148✔
114
      s = i;
115
   }
116

117
   return r;
468✔
118
}
9,193✔
119

120
/*
121
* Calculate the Jacobi symbol
122
*/
123
int32_t jacobi(const BigInt& a, const BigInt& n) {
109,620✔
124
   if(n.is_even() || n < 2)
328,860✔
125
      throw Invalid_Argument("jacobi: second argument must be odd and > 1");
×
126

127
   BigInt x = a % n;
109,620✔
128
   BigInt y = n;
109,620✔
129
   int32_t J = 1;
109,620✔
130

131
   while(y > 1) {
1,127,132✔
132
      x %= y;
924,539✔
133
      if(x > y / 2) {
2,773,617✔
134
         x = y - x;
401,356✔
135
         if(y % 4 == 3)
401,356✔
136
            J = -J;
195,869✔
137
      }
138
      if(x.is_zero())
1,325,895✔
139
         return 0;
140

141
      size_t shifts = low_zero_bits(x);
907,892✔
142
      x >>= shifts;
907,892✔
143
      if(shifts % 2) {
907,892✔
144
         word y_mod_8 = y % 8;
265,883✔
145
         if(y_mod_8 == 3 || y_mod_8 == 5)
265,883✔
146
            J = -J;
139,347✔
147
      }
148

149
      if(x % 4 == 3 && y % 4 == 3)
907,892✔
150
         J = -J;
202,501✔
151
      std::swap(x, y);
1,017,512✔
152
   }
153
   return J;
154
}
202,615✔
155

156
/*
157
* Square a BigInt
158
*/
159
BigInt square(const BigInt& x) {
2,951,078✔
160
   BigInt z = x;
2,951,078✔
161
   secure_vector<word> ws;
2,951,078✔
162
   z.square(ws);
2,951,078✔
163
   return z;
2,951,078✔
164
}
2,951,078✔
165

166
/*
167
* Return the number of 0 bits at the end of n
168
*/
169
size_t low_zero_bits(const BigInt& n) {
1,159,000✔
170
   size_t low_zero = 0;
1,159,000✔
171

172
   auto seen_nonempty_word = CT::Mask<word>::cleared();
1,159,000✔
173

174
   for(size_t i = 0; i != n.size(); ++i) {
12,436,672✔
175
      const word x = n.word_at(i);
11,277,672✔
176

177
      // ctz(0) will return sizeof(word)
178
      const size_t tz_x = ctz(x);
11,277,672✔
179

180
      // if x > 0 we want to count tz_x in total but not any
181
      // further words, so set the mask after the addition
182
      low_zero += seen_nonempty_word.if_not_set_return(tz_x);
11,277,672✔
183

184
      seen_nonempty_word |= CT::Mask<word>::expand(x);
11,277,672✔
185
   }
186

187
   // if we saw no words with x > 0 then n == 0 and the value we have
188
   // computed is meaningless. Instead return BigInt::zero() in that case.
189
   return seen_nonempty_word.if_set_return(low_zero);
1,159,000✔
190
}
191

192
namespace {
193

194
size_t safegcd_loop_bound(size_t f_bits, size_t g_bits) {
22,057✔
195
   const size_t d = std::max(f_bits, g_bits);
22,057✔
196
   return 4 + 3 * d;
22,057✔
197
}
198

199
}  // namespace
200

201
/*
202
* Calculate the GCD
203
*/
204
BigInt gcd(const BigInt& a, const BigInt& b) {
22,065✔
205
   if(a.is_zero())
23,797✔
206
      return abs(b);
4✔
207
   if(b.is_zero())
42,143✔
208
      return abs(a);
2✔
209
   if(a == 1 || b == 1)
44,116✔
210
      return BigInt::one();
2✔
211

212
   // See https://gcd.cr.yp.to/safegcd-20190413.pdf fig 1.2
213

214
   BigInt f = a;
22,057✔
215
   BigInt g = b;
22,057✔
216
   f.const_time_poison();
22,057✔
217
   g.const_time_poison();
22,057✔
218

219
   f.set_sign(BigInt::Positive);
22,057✔
220
   g.set_sign(BigInt::Positive);
22,057✔
221

222
   const size_t common2s = std::min(low_zero_bits(f), low_zero_bits(g));
22,057✔
223
   CT::unpoison(common2s);
22,057✔
224

225
   f >>= common2s;
22,057✔
226
   g >>= common2s;
22,057✔
227

228
   f.ct_cond_swap(f.is_even(), g);
44,114✔
229

230
   int32_t delta = 1;
22,057✔
231

232
   const size_t loop_cnt = safegcd_loop_bound(f.bits(), g.bits());
22,057✔
233

234
   BigInt newg, t;
22,057✔
235
   for(size_t i = 0; i != loop_cnt; ++i) {
5,384,048✔
236
      sub_abs(newg, f, g);
5,361,991✔
237

238
      const bool need_swap = (g.is_odd() && delta > 0);
10,723,982✔
239

240
      // if(need_swap) { delta *= -1 } else { delta *= 1 }
241
      delta *= CT::Mask<uint8_t>::expand(need_swap).if_not_set_return(2) - 1;
5,361,991✔
242
      f.ct_cond_swap(need_swap, g);
5,361,991✔
243
      g.ct_cond_swap(need_swap, newg);
5,361,991✔
244

245
      delta += 1;
5,361,991✔
246

247
      g.ct_cond_add(g.is_odd(), f);
10,723,982✔
248
      g >>= 1;
5,361,991✔
249
   }
250

251
   f <<= common2s;
22,057✔
252

253
   f.const_time_unpoison();
22,057✔
254
   g.const_time_unpoison();
22,057✔
255

256
   BOTAN_ASSERT_NOMSG(g.is_zero());
44,114✔
257

258
   return f;
22,057✔
259
}
88,236✔
260

261
/*
262
* Calculate the LCM
263
*/
264
BigInt lcm(const BigInt& a, const BigInt& b) {
490✔
265
   if(a == b)
490✔
266
      return a;
×
267

268
   auto ab = a * b;
490✔
269
   ab.set_sign(BigInt::Positive);  // ignore the signs of a & b
490✔
270
   const auto g = gcd(a, b);
490✔
271
   return ct_divide(ab, g);
490✔
272
}
980✔
273

274
/*
275
* Modular Exponentiation
276
*/
277
BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) {
203✔
278
   if(mod.is_negative() || mod == 1) {
406✔
279
      return BigInt::zero();
×
280
   }
281

282
   if(base.is_zero() || mod.is_zero()) {
548✔
283
      if(exp.is_zero())
2✔
284
         return BigInt::one();
1✔
285
      return BigInt::zero();
×
286
   }
287

288
   Modular_Reducer reduce_mod(mod);
202✔
289

290
   const size_t exp_bits = exp.bits();
202✔
291

292
   if(mod.is_odd()) {
404✔
293
      auto monty_params = std::make_shared<Montgomery_Params>(mod, reduce_mod);
177✔
294
      return monty_exp(monty_params, reduce_mod.reduce(base), exp, exp_bits);
708✔
295
   }
177✔
296

297
   /*
298
   Support for even modulus is just a convenience and not considered
299
   cryptographically important, so this implementation is slow ...
300
   */
301
   BigInt accum = BigInt::one();
25✔
302
   BigInt g = reduce_mod.reduce(base);
25✔
303
   BigInt t;
25✔
304

305
   for(size_t i = 0; i != exp_bits; ++i) {
7,186✔
306
      t = reduce_mod.multiply(g, accum);
7,161✔
307
      g = reduce_mod.square(g);
7,161✔
308
      accum.ct_cond_assign(exp.get_bit(i), t);
14,322✔
309
   }
310
   return accum;
25✔
311
}
252✔
312

313
BigInt is_perfect_square(const BigInt& C) {
705✔
314
   if(C < 1)
705✔
315
      throw Invalid_Argument("is_perfect_square requires C >= 1");
×
316
   if(C == 1)
705✔
317
      return BigInt::one();
×
318

319
   const size_t n = C.bits();
705✔
320
   const size_t m = (n + 1) / 2;
705✔
321
   const BigInt B = C + BigInt::power_of_2(m);
705✔
322

323
   BigInt X = BigInt::power_of_2(m) - 1;
1,410✔
324
   BigInt X2 = (X * X);
705✔
325

326
   for(;;) {
1,671✔
327
      X = (X2 + C) / (2 * X);
5,013✔
328
      X2 = (X * X);
1,671✔
329

330
      if(X2 < B)
1,671✔
331
         break;
332
   }
333

334
   if(X2 == C)
705✔
335
      return X;
705✔
336
   else
337
      return BigInt::zero();
642✔
338
}
2,052✔
339

340
/*
341
* Test for primality using Miller-Rabin
342
*/
343
bool is_prime(const BigInt& n, RandomNumberGenerator& rng, size_t prob, bool is_random) {
53,373✔
344
   if(n == 2)
53,373✔
345
      return true;
346
   if(n <= 1 || n.is_even())
106,742✔
347
      return false;
348

349
   const size_t n_bits = n.bits();
53,369✔
350

351
   // Fast path testing for small numbers (<= 65521)
352
   if(n_bits <= 16) {
53,369✔
353
      const uint16_t num = static_cast<uint16_t>(n.word_at(0));
32,791✔
354

355
      return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
32,791✔
356
   }
357

358
   Modular_Reducer mod_n(n);
20,578✔
359

360
   if(rng.is_seeded()) {
20,578✔
361
      const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random);
20,578✔
362

363
      if(is_miller_rabin_probable_prime(n, mod_n, rng, t) == false)
20,578✔
364
         return false;
365

366
      if(is_random)
3,349✔
367
         return true;
368
      else
369
         return is_lucas_probable_prime(n, mod_n);
3,156✔
370
   } else {
371
      return is_bailie_psw_probable_prime(n, mod_n);
×
372
   }
373
}
20,578✔
374

375
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc