Coverage Report

Created: 2020-03-26 13:53

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