Coverage Report

Created: 2020-02-14 15:38

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