Coverage Report

Created: 2026-04-12 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/math/numbertheory/primality.cpp
Line
Count
Source
1
/*
2
* (C) 2016,2018 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#include <botan/internal/primality.h>
8
9
#include <botan/bigint.h>
10
#include <botan/numthry.h>
11
#include <botan/rng.h>
12
#include <botan/internal/barrett.h>
13
#include <botan/internal/monty.h>
14
#include <botan/internal/monty_exp.h>
15
16
namespace Botan {
17
18
855
bool is_lucas_probable_prime(const BigInt& C, const Barrett_Reduction& mod_C) {
19
855
   BOTAN_ARG_CHECK(C.signum() >= 0, "Argument must be non-negative");
20
21
855
   if(C == 2 || C == 3 || C == 5 || C == 7 || C == 11 || C == 13) {
22
0
      return true;
23
0
   }
24
25
855
   if(C <= 1 || C.is_even()) {
26
0
      return false;
27
0
   }
28
29
855
   BigInt D = BigInt::from_word(5);
30
31
2.79k
   for(;;) {
32
2.79k
      const int32_t j = jacobi(D, C);
33
2.79k
      if(j == 0) {
34
0
         return false;
35
0
      }
36
37
2.79k
      if(j == -1) {
38
855
         break;
39
855
      }
40
41
      // Check 5, -7, 9, -11, 13, -15, 17, ...
42
1.93k
      if(D.signum() < 0) {
43
617
         D.flip_sign();
44
617
         D += 2;
45
1.32k
      } else {
46
1.32k
         D += 2;
47
1.32k
         D.flip_sign();
48
1.32k
      }
49
50
1.93k
      if(D == 17 && is_perfect_square(C).signum() != 0) {
51
0
         return false;
52
0
      }
53
1.93k
   }
54
55
855
   if(D.signum() < 0) {
56
704
      D += C;
57
704
   }
58
59
855
   const BigInt K = C + 1;
60
855
   const size_t K_bits = K.bits() - 1;
61
62
855
   BigInt U = BigInt::one();
63
855
   BigInt V = BigInt::one();
64
65
855
   BigInt Ut;
66
855
   BigInt Vt;
67
855
   BigInt U2;
68
855
   BigInt V2;
69
70
430k
   for(size_t i = 0; i != K_bits; ++i) {
71
429k
      const bool k_bit = K.get_bit(K_bits - 1 - i);
72
73
429k
      Ut = mod_C.multiply(U, V);
74
75
429k
      Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U)));
76
429k
      Vt.ct_cond_add(Vt.is_odd(), C);
77
429k
      Vt >>= 1;
78
429k
      Vt = mod_C.reduce(Vt);
79
80
429k
      U = Ut;
81
429k
      V = Vt;
82
83
429k
      U2 = mod_C.reduce(Ut + Vt);
84
429k
      U2.ct_cond_add(U2.is_odd(), C);
85
429k
      U2 >>= 1;
86
87
429k
      V2 = mod_C.reduce(Vt + mod_C.multiply(Ut, D));
88
429k
      V2.ct_cond_add(V2.is_odd(), C);
89
429k
      V2 >>= 1;
90
91
429k
      U.ct_cond_assign(k_bit, U2);
92
429k
      V.ct_cond_assign(k_bit, V2);
93
429k
   }
94
95
855
   return (U == 0);
96
855
}
97
98
1.19k
bool is_bailie_psw_probable_prime(const BigInt& n, const Barrett_Reduction& mod_n) {
99
1.19k
   if(n == 2) {
100
0
      return true;
101
1.19k
   } else if(n <= 1 || n.is_even()) {
102
35
      return false;
103
35
   }
104
105
1.15k
   const Montgomery_Params monty_n(n, mod_n);
106
1.15k
   const auto base = BigInt::from_word(2);
107
1.15k
   return passes_miller_rabin_test(n, mod_n, monty_n, base) && is_lucas_probable_prime(n, mod_n);
108
1.19k
}
109
110
bool passes_miller_rabin_test(const BigInt& n,
111
                              const Barrett_Reduction& mod_n,
112
                              const Montgomery_Params& monty_n,
113
4.72k
                              const BigInt& a) {
114
4.72k
   if(n < 3 || n.is_even()) {
115
0
      return false;
116
0
   }
117
118
4.72k
   BOTAN_ASSERT_NOMSG(n > 1);
119
120
4.72k
   const BigInt n_minus_1 = n - 1;
121
   /*
122
   * This unpoison is not ideal but realistically there is no way to
123
   * hide the number of loop iterations (below). The main user of
124
   * secret primes is RSA and we always generate RSA primes such that
125
   * p == 3 (mod 4), which means s is always 1.
126
   */
127
4.72k
   const size_t s = CT::driveby_unpoison(low_zero_bits(n_minus_1));
128
4.72k
   const BigInt nm1_s = n_minus_1 >> s;
129
4.72k
   const size_t n_bits = n.bits();
130
131
4.72k
   const size_t powm_window = 4;
132
133
4.72k
   auto powm_a_n = monty_precompute(monty_n, a, powm_window);
134
135
4.72k
   BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits).value();
136
137
4.72k
   if(y == 1 || y == n_minus_1) {
138
1.13k
      return true;
139
1.13k
   }
140
141
377k
   for(size_t i = 1; i != s; ++i) {
142
377k
      y = mod_n.square(y);
143
144
377k
      if(y == 1) {  // found a non-trivial square root
145
1
         return false;
146
1
      }
147
148
      /*
149
      -1 is the trivial square root of unity, so ``a`` is not a
150
      witness for this number - give up
151
      */
152
377k
      if(y == n_minus_1) {
153
3.00k
         return true;
154
3.00k
      }
155
377k
   }
156
157
576
   return false;
158
3.58k
}
159
160
bool is_miller_rabin_probable_prime(const BigInt& n,
161
                                    const Barrett_Reduction& mod_n,
162
                                    const Montgomery_Params& monty_n,
163
                                    RandomNumberGenerator& rng,
164
275
                                    size_t test_iterations) {
165
275
   if(n < 3 || n.is_even()) {
166
0
      return false;
167
0
   }
168
169
3.61k
   for(size_t i = 0; i != test_iterations; ++i) {
170
3.56k
      const BigInt a = BigInt::random_integer(rng, BigInt::from_word(2), n);
171
172
3.56k
      if(!passes_miller_rabin_test(n, mod_n, monty_n, a)) {
173
223
         return false;
174
223
      }
175
3.56k
   }
176
177
   // Failed to find a counterexample
178
52
   return true;
179
275
}
180
181
247
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random) {
182
247
   const size_t base = (prob + 2) / 2;  // worst case 4^-t error rate
183
184
   /*
185
   * If the candidate prime was maliciously constructed, we can't rely
186
   * on arguments based on p being random.
187
   */
188
247
   if(!random) {
189
246
      return base;
190
246
   }
191
192
   /*
193
   * For randomly chosen numbers we can use the estimates from
194
   * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
195
   *
196
   * These values are derived from the inequality for p(k,t) given on
197
   * the second page.
198
   */
199
1
   if(prob <= 128) {
200
1
      if(n_bits >= 1536) {
201
0
         return 4;  // < 2^-133
202
0
      }
203
1
      if(n_bits >= 1024) {
204
0
         return 6;  // < 2^-133
205
0
      }
206
1
      if(n_bits >= 512) {
207
0
         return 12;  // < 2^-129
208
0
      }
209
1
      if(n_bits >= 256) {
210
1
         return 29;  // < 2^-128
211
1
      }
212
1
   }
213
214
   /*
215
   If the user desires a smaller error probability than we have
216
   precomputed error estimates for, just fall back to using the worst
217
   case error rate.
218
   */
219
0
   return base;
220
1
}
221
222
}  // namespace Botan