Coverage Report

Created: 2024-02-25 06:16

/src/botan/src/lib/math/numbertheory/primality.cpp
Line
Count
Source (jump to first uncovered line)
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/reducer.h>
11
#include <botan/rng.h>
12
#include <botan/internal/monty.h>
13
#include <botan/internal/monty_exp.h>
14
#include <algorithm>
15
16
namespace Botan {
17
18
1.38k
bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) {
19
1.38k
   if(C == 2 || C == 3 || C == 5 || C == 7 || C == 11 || C == 13) {
20
86
      return true;
21
86
   }
22
23
1.30k
   if(C <= 1 || C.is_even()) {
24
0
      return false;
25
0
   }
26
27
1.30k
   BigInt D = BigInt::from_word(5);
28
29
3.73k
   for(;;) {
30
3.73k
      int32_t j = jacobi(D, C);
31
3.73k
      if(j == 0) {
32
0
         return false;
33
0
      }
34
35
3.73k
      if(j == -1) {
36
1.30k
         break;
37
1.30k
      }
38
39
      // Check 5, -7, 9, -11, 13, -15, 17, ...
40
2.42k
      if(D.is_negative()) {
41
856
         D.flip_sign();
42
856
         D += 2;
43
1.57k
      } else {
44
1.57k
         D += 2;
45
1.57k
         D.flip_sign();
46
1.57k
      }
47
48
2.42k
      if(D == 17 && is_perfect_square(C).is_nonzero()) {
49
0
         return false;
50
0
      }
51
2.42k
   }
52
53
1.30k
   const BigInt K = C + 1;
54
1.30k
   const size_t K_bits = K.bits() - 1;
55
56
1.30k
   BigInt U = BigInt::one();
57
1.30k
   BigInt V = BigInt::one();
58
59
1.30k
   BigInt Ut, Vt, U2, V2;
60
61
393k
   for(size_t i = 0; i != K_bits; ++i) {
62
392k
      const bool k_bit = K.get_bit(K_bits - 1 - i);
63
64
392k
      Ut = mod_C.multiply(U, V);
65
66
392k
      Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U)));
67
392k
      Vt.ct_cond_add(Vt.is_odd(), C);
68
392k
      Vt >>= 1;
69
392k
      Vt = mod_C.reduce(Vt);
70
71
392k
      U = Ut;
72
392k
      V = Vt;
73
74
392k
      U2 = mod_C.reduce(Ut + Vt);
75
392k
      U2.ct_cond_add(U2.is_odd(), C);
76
392k
      U2 >>= 1;
77
78
392k
      V2 = mod_C.reduce(Vt + Ut * D);
79
392k
      V2.ct_cond_add(V2.is_odd(), C);
80
392k
      V2 >>= 1;
81
82
392k
      U.ct_cond_assign(k_bit, U2);
83
392k
      V.ct_cond_assign(k_bit, V2);
84
392k
   }
85
86
1.30k
   return (U == 0);
87
1.30k
}
88
89
284
bool is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n) {
90
284
   if(n == 2) {
91
21
      return true;
92
263
   } else if(n <= 1 || n.is_even()) {
93
41
      return false;
94
41
   }
95
96
222
   auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
97
222
   const auto base = BigInt::from_word(2);
98
222
   return passes_miller_rabin_test(n, mod_n, monty_n, base) && is_lucas_probable_prime(n, mod_n);
99
284
}
100
101
0
bool is_bailie_psw_probable_prime(const BigInt& n) {
102
0
   Modular_Reducer mod_n(n);
103
0
   return is_bailie_psw_probable_prime(n, mod_n);
104
0
}
105
106
bool passes_miller_rabin_test(const BigInt& n,
107
                              const Modular_Reducer& mod_n,
108
                              const std::shared_ptr<Montgomery_Params>& monty_n,
109
75.2k
                              const BigInt& a) {
110
75.2k
   if(n < 3 || n.is_even()) {
111
0
      return false;
112
0
   }
113
114
75.2k
   BOTAN_ASSERT_NOMSG(n > 1);
115
116
75.2k
   const BigInt n_minus_1 = n - 1;
117
75.2k
   const size_t s = low_zero_bits(n_minus_1);
118
75.2k
   const BigInt nm1_s = n_minus_1 >> s;
119
75.2k
   const size_t n_bits = n.bits();
120
121
75.2k
   const size_t powm_window = 4;
122
123
75.2k
   auto powm_a_n = monty_precompute(monty_n, a, powm_window);
124
125
75.2k
   BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits);
126
127
75.2k
   if(y == 1 || y == n_minus_1) {
128
41.3k
      return true;
129
41.3k
   }
130
131
73.2k
   for(size_t i = 1; i != s; ++i) {
132
57.7k
      y = mod_n.square(y);
133
134
57.7k
      if(y == 1) {  // found a non-trivial square root
135
10
         return false;
136
10
      }
137
138
      /*
139
      -1 is the trivial square root of unity, so ``a`` is not a
140
      witness for this number - give up
141
      */
142
57.7k
      if(y == n_minus_1) {
143
18.2k
         return true;
144
18.2k
      }
145
57.7k
   }
146
147
15.5k
   return false;
148
33.8k
}
149
150
bool is_miller_rabin_probable_prime(const BigInt& n,
151
                                    const Modular_Reducer& mod_n,
152
                                    RandomNumberGenerator& rng,
153
16.8k
                                    size_t test_iterations) {
154
16.8k
   if(n < 3 || n.is_even()) {
155
0
      return false;
156
0
   }
157
158
16.8k
   auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
159
160
76.5k
   for(size_t i = 0; i != test_iterations; ++i) {
161
75.1k
      const BigInt a = BigInt::random_integer(rng, BigInt::from_word(2), n);
162
163
75.1k
      if(!passes_miller_rabin_test(n, mod_n, monty_n, a)) {
164
15.4k
         return false;
165
15.4k
      }
166
75.1k
   }
167
168
   // Failed to find a counterexample
169
1.38k
   return true;
170
16.8k
}
171
172
1.42k
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random) {
173
1.42k
   const size_t base = (prob + 2) / 2;  // worst case 4^-t error rate
174
175
   /*
176
   * If the candidate prime was maliciously constructed, we can't rely
177
   * on arguments based on p being random.
178
   */
179
1.42k
   if(random == false) {
180
234
      return base;
181
234
   }
182
183
   /*
184
   * For randomly chosen numbers we can use the estimates from
185
   * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
186
   *
187
   * These values are derived from the inequality for p(k,t) given on
188
   * the second page.
189
   */
190
1.18k
   if(prob <= 128) {
191
1.18k
      if(n_bits >= 1536) {
192
0
         return 4;  // < 2^-133
193
0
      }
194
1.18k
      if(n_bits >= 1024) {
195
0
         return 6;  // < 2^-133
196
0
      }
197
1.18k
      if(n_bits >= 512) {
198
5
         return 12;  // < 2^-129
199
5
      }
200
1.18k
      if(n_bits >= 256) {
201
604
         return 29;  // < 2^-128
202
604
      }
203
1.18k
   }
204
205
   /*
206
   If the user desires a smaller error probability than we have
207
   precomputed error estimates for, just fall back to using the worst
208
   case error rate.
209
   */
210
578
   return base;
211
1.18k
}
212
213
}  // namespace Botan