| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include |
|
2
|
|
|
|
|
|
|
#include |
|
3
|
|
|
|
|
|
|
#include |
|
4
|
|
|
|
|
|
|
#include |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
/* Primality related functions */ |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
#include "ptypes.h" |
|
9
|
|
|
|
|
|
|
#include "primality.h" |
|
10
|
|
|
|
|
|
|
#include "lucas_seq.h" |
|
11
|
|
|
|
|
|
|
#include "mulmod.h" |
|
12
|
|
|
|
|
|
|
#define FUNC_gcd_ui 1 |
|
13
|
|
|
|
|
|
|
#define FUNC_is_perfect_square |
|
14
|
|
|
|
|
|
|
#include "util.h" |
|
15
|
|
|
|
|
|
|
#include "montmath.h" /* Fast Montgomery math */ |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
/******************************************************************************/ |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
|
20
|
12710
|
|
|
|
|
|
static int jacobi_iu(IV in, UV m) { |
|
21
|
12710
|
|
|
|
|
|
int j = 1; |
|
22
|
12710
|
|
|
|
|
|
UV n = (in < 0) ? -in : in; |
|
23
|
|
|
|
|
|
|
|
|
24
|
12710
|
50
|
|
|
|
|
if (m <= 0 || (m%2) == 0) return 0; |
|
|
|
50
|
|
|
|
|
|
|
25
|
12710
|
100
|
|
|
|
|
if (in < 0 && (m%4) == 3) j = -j; |
|
|
|
100
|
|
|
|
|
|
|
26
|
42593
|
100
|
|
|
|
|
while (n != 0) { |
|
27
|
55483
|
100
|
|
|
|
|
while ((n % 2) == 0) { |
|
28
|
25600
|
|
|
|
|
|
n >>= 1; |
|
29
|
25600
|
100
|
|
|
|
|
if ( (m % 8) == 3 || (m % 8) == 5 ) j = -j; |
|
|
|
100
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
} |
|
31
|
29883
|
|
|
|
|
|
{ UV t = n; n = m; m = t; } |
|
32
|
29883
|
100
|
|
|
|
|
if ( (n % 4) == 3 && (m % 4) == 3 ) j = -j; |
|
|
|
100
|
|
|
|
|
|
|
33
|
29883
|
|
|
|
|
|
n = n % m; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
12710
|
100
|
|
|
|
|
return (m == 1) ? j : 0; |
|
36
|
|
|
|
|
|
|
} |
|
37
|
|
|
|
|
|
|
|
|
38
|
5614
|
|
|
|
|
|
static UV select_extra_strong_parameters(UV n, UV increment) { |
|
39
|
|
|
|
|
|
|
int j; |
|
40
|
5614
|
|
|
|
|
|
UV D, P = 3; |
|
41
|
|
|
|
|
|
|
while (1) { |
|
42
|
12602
|
|
|
|
|
|
D = P*P - 4; |
|
43
|
12602
|
|
|
|
|
|
j = jacobi_iu(D, n); |
|
44
|
12602
|
100
|
|
|
|
|
if (j == 0) { UV g = gcd_ui(D,n); if (g != 1 && g != n) return 0; } |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
45
|
12585
|
100
|
|
|
|
|
if (j == -1) break; |
|
46
|
6988
|
100
|
|
|
|
|
if (P == (3+20*increment) && is_perfect_square(n)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
47
|
6988
|
|
|
|
|
|
P += increment; |
|
48
|
6988
|
50
|
|
|
|
|
if (P > 65535) |
|
49
|
0
|
|
|
|
|
|
croak("lucas_extrastrong_params: P exceeded 65535"); |
|
50
|
|
|
|
|
|
|
} |
|
51
|
5597
|
50
|
|
|
|
|
if (P >= n) P %= n; /* Never happens with increment < 4 */ |
|
52
|
5597
|
|
|
|
|
|
return P; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
/* Fermat pseudoprime */ |
|
56
|
105
|
|
|
|
|
|
bool is_pseudoprime(UV const n, UV a) |
|
57
|
|
|
|
|
|
|
{ |
|
58
|
105
|
50
|
|
|
|
|
if (n < 3) return (n == 2); |
|
59
|
105
|
100
|
|
|
|
|
if (!(n&1) && !(a&1)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
60
|
105
|
50
|
|
|
|
|
if (a < 2) croak("Base %"UVuf" is invalid", a); |
|
61
|
105
|
50
|
|
|
|
|
if (a >= n) { |
|
62
|
0
|
|
|
|
|
|
a %= n; |
|
63
|
0
|
0
|
|
|
|
|
if (a <= 1) return (a == 1); |
|
64
|
0
|
0
|
|
|
|
|
if (a == n-1) return !(a & 1); |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
68
|
105
|
100
|
|
|
|
|
if (n & 1) { /* The Montgomery code only works for odd n */ |
|
69
|
103
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
70
|
103
|
100
|
|
|
|
|
const uint64_t monta = (a == 2) ? mont_get2(n) : mont_geta(a, n); |
|
71
|
103
|
|
|
|
|
|
return mont_powmod(monta, n-1, n) == mont1; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
#endif |
|
74
|
2
|
|
|
|
|
|
return powmod(a, n-1, n) == 1; /* a^(n-1) = 1 mod n */ |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
/* Euler (aka Euler-Jacobi) pseudoprime: a^((n-1)/2) = (a|n) mod n */ |
|
78
|
109
|
|
|
|
|
|
bool is_euler_pseudoprime(UV const n, UV a) |
|
79
|
|
|
|
|
|
|
{ |
|
80
|
109
|
50
|
|
|
|
|
if (n < 3) return (n == 2); |
|
81
|
109
|
50
|
|
|
|
|
if (!(n&1)) return 0; |
|
82
|
109
|
50
|
|
|
|
|
if (a < 2) croak("Base %"UVuf" is invalid", a); |
|
83
|
109
|
100
|
|
|
|
|
if (a > 2) { |
|
84
|
73
|
100
|
|
|
|
|
if (a >= n) { |
|
85
|
1
|
|
|
|
|
|
a %= n; |
|
86
|
1
|
50
|
|
|
|
|
if (a <= 1) return (a == 1); |
|
87
|
1
|
50
|
|
|
|
|
if (a == n-1) return !(a & 1); |
|
88
|
|
|
|
|
|
|
} |
|
89
|
72
|
50
|
|
|
|
|
if ((n % a) == 0) return 0; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
{ |
|
92
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
93
|
108
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
94
|
108
|
|
|
|
|
|
const uint64_t monta = mont_geta(a, n); |
|
95
|
108
|
|
|
|
|
|
UV ap = mont_powmod(monta, (n-1)>>1, n); |
|
96
|
108
|
100
|
|
|
|
|
if (ap != mont1 && ap != n-mont1) return 0; |
|
|
|
50
|
|
|
|
|
|
|
97
|
108
|
100
|
|
|
|
|
if (a == 2) { |
|
98
|
36
|
|
|
|
|
|
uint32_t nmod8 = n & 0x7; |
|
99
|
36
|
100
|
|
|
|
|
return (nmod8 == 1 || nmod8 == 7) ? (ap == mont1) : (ap == n-mont1); |
|
|
|
100
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
} else { |
|
101
|
72
|
100
|
|
|
|
|
return (kronecker_uu(a,n) >= 0) ? (ap == mont1) : (ap == n-mont1); |
|
102
|
|
|
|
|
|
|
} |
|
103
|
|
|
|
|
|
|
#else |
|
104
|
|
|
|
|
|
|
UV ap = powmod(a, (n-1)>>1, n); |
|
105
|
|
|
|
|
|
|
if (ap != 1 && ap != n-1) return 0; |
|
106
|
|
|
|
|
|
|
if (a == 2) { |
|
107
|
|
|
|
|
|
|
uint32_t nmod8 = n & 0x7; |
|
108
|
|
|
|
|
|
|
return (nmod8 == 1 || nmod8 == 7) ? (ap == 1) : (ap == n-1); |
|
109
|
|
|
|
|
|
|
} else { |
|
110
|
|
|
|
|
|
|
return (kronecker_uu(a,n) >= 0) ? (ap == 1) : (ap == n-1); |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
#endif |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
} |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
/* Colin Plumb's extended Euler Criterion test. |
|
117
|
|
|
|
|
|
|
* A tiny bit (~1 percent) faster than base 2 Fermat or M-R. |
|
118
|
|
|
|
|
|
|
* More stringent than base 2 Fermat, but a subset of base 2 M-R. |
|
119
|
|
|
|
|
|
|
*/ |
|
120
|
1195
|
|
|
|
|
|
bool is_euler_plumb_pseudoprime(UV const n) |
|
121
|
|
|
|
|
|
|
{ |
|
122
|
|
|
|
|
|
|
UV ap; |
|
123
|
1195
|
|
|
|
|
|
uint32_t nmod8 = n & 0x7; |
|
124
|
1195
|
50
|
|
|
|
|
if (n < 5) return (n == 2 || n == 3); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
125
|
1195
|
50
|
|
|
|
|
if (!(n&1)) return 0; |
|
126
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
127
|
|
|
|
|
|
|
{ |
|
128
|
1195
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
129
|
1195
|
|
|
|
|
|
const uint64_t mont2 = mont_get2(n); |
|
130
|
1195
|
100
|
|
|
|
|
ap = mont_powmod(mont2, (n-1) >> (1 + (nmod8 == 1)), n); |
|
131
|
1195
|
100
|
|
|
|
|
if (ap == mont1) return (nmod8 == 1 || nmod8 == 7); |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
132
|
770
|
100
|
|
|
|
|
if (ap == n-mont1) return (nmod8 == 1 || nmod8 == 3 || nmod8 == 5); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
#else |
|
135
|
|
|
|
|
|
|
ap = powmod(2, (n-1) >> (1 + (nmod8 == 1)), n); |
|
136
|
|
|
|
|
|
|
if (ap == 1) return (nmod8 == 1 || nmod8 == 7); |
|
137
|
|
|
|
|
|
|
if (ap == n-1) return (nmod8 == 1 || nmod8 == 3 || nmod8 == 5); |
|
138
|
|
|
|
|
|
|
#endif |
|
139
|
9
|
|
|
|
|
|
return 0; |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
|
|
142
|
301508
|
|
|
|
|
|
bool is_strong_pseudoprime(UV const n, UV a) |
|
143
|
|
|
|
|
|
|
{ |
|
144
|
301508
|
|
|
|
|
|
UV d = n-1; |
|
145
|
301508
|
|
|
|
|
|
int r, s = 0; |
|
146
|
301508
|
50
|
|
|
|
|
if (n < 3) return (n == 2); |
|
147
|
301508
|
100
|
|
|
|
|
if (!(n&1)) return 0; |
|
148
|
301507
|
100
|
|
|
|
|
if (a < 2) croak("Base %"UVuf" is invalid", a); |
|
149
|
301505
|
100
|
|
|
|
|
if (a >= n) a %= n; |
|
150
|
301505
|
100
|
|
|
|
|
if (a <= 1 || a == n-1) return 1; |
|
|
|
100
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
|
152
|
913185
|
100
|
|
|
|
|
while (!(d&1)) { s++; d >>= 1; } |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
/* n is a strong pseudoprime to base a if either: |
|
155
|
|
|
|
|
|
|
* a^d = 1 mod n |
|
156
|
|
|
|
|
|
|
* a^(d2^r) = -1 mod n for some r: 0 <= r <= s-1 |
|
157
|
|
|
|
|
|
|
*/ |
|
158
|
|
|
|
|
|
|
{ |
|
159
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
160
|
301450
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
161
|
301450
|
|
|
|
|
|
const uint64_t ma = mont_geta(a,n); |
|
162
|
|
|
|
|
|
|
uint64_t mx; |
|
163
|
|
|
|
|
|
|
|
|
164
|
301450
|
50
|
|
|
|
|
if (!ma) return 1; |
|
165
|
301450
|
|
|
|
|
|
mx = mont_powmod(ma, d, n); |
|
166
|
301450
|
100
|
|
|
|
|
if (mx != mont1 && mx != n-mont1) { |
|
|
|
100
|
|
|
|
|
|
|
167
|
388802
|
100
|
|
|
|
|
for (r = 1; r < s; r++) { |
|
168
|
253467
|
50
|
|
|
|
|
mx = mont_sqrmod(mx, n); |
|
169
|
253467
|
100
|
|
|
|
|
if (mx == n-mont1) break; |
|
170
|
197088
|
100
|
|
|
|
|
if (mx == mont1 ) return 0; |
|
171
|
|
|
|
|
|
|
} |
|
172
|
191714
|
100
|
|
|
|
|
if (r >= s) return 0; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
#else |
|
175
|
|
|
|
|
|
|
UV x = powmod(a, d, n); |
|
176
|
|
|
|
|
|
|
if (x != 1 && x != n-1) { |
|
177
|
|
|
|
|
|
|
for (r = 1; r < s; r++) { /* r=0 was just done, test r = 1 to s-1 */ |
|
178
|
|
|
|
|
|
|
x = sqrmod(x, n); |
|
179
|
|
|
|
|
|
|
if ( x == n-1 ) break; |
|
180
|
|
|
|
|
|
|
if ( x == 1 ) return 0; |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
if (r >= s) return 0; |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
#endif |
|
185
|
|
|
|
|
|
|
} |
|
186
|
166008
|
|
|
|
|
|
return 1; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
/* Miller-Rabin probabilistic primality test for multiple bases at a time. |
|
190
|
|
|
|
|
|
|
* Returns 1 if probably prime relative to the bases, 0 if composite. |
|
191
|
|
|
|
|
|
|
* Bases must be between 2 and n-2 |
|
192
|
|
|
|
|
|
|
*/ |
|
193
|
0
|
|
|
|
|
|
bool miller_rabin(UV const n, const UV *bases, int nbases) |
|
194
|
|
|
|
|
|
|
{ |
|
195
|
|
|
|
|
|
|
int i; |
|
196
|
|
|
|
|
|
|
/* For best performance, especially with montmath, we would do as much |
|
197
|
|
|
|
|
|
|
* as possible up front, then do the per-base loop. This code used to |
|
198
|
|
|
|
|
|
|
* do that, but we never actually used it with more than one base. */ |
|
199
|
|
|
|
|
|
|
|
|
200
|
0
|
0
|
|
|
|
|
for (i = 0; i < nbases; i++) |
|
201
|
0
|
0
|
|
|
|
|
if (!is_strong_pseudoprime(n, bases[i])) |
|
202
|
0
|
|
|
|
|
|
break; |
|
203
|
|
|
|
|
|
|
|
|
204
|
0
|
|
|
|
|
|
return i >= nbases; |
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
|
|
207
|
7918
|
|
|
|
|
|
bool BPSW(UV const n) |
|
208
|
|
|
|
|
|
|
{ |
|
209
|
7918
|
50
|
|
|
|
|
if (n < 7) return (n == 2 || n == 3 || n == 5); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
210
|
7918
|
50
|
|
|
|
|
if ((n % 2) == 0 || n == UV_MAX) return 0; |
|
|
|
50
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
#if !USE_MONTMATH |
|
213
|
|
|
|
|
|
|
return is_strong_pseudoprime(n, 2) |
|
214
|
|
|
|
|
|
|
&& is_almost_extra_strong_lucas_pseudoprime(n,1); |
|
215
|
|
|
|
|
|
|
#else |
|
216
|
|
|
|
|
|
|
{ |
|
217
|
7918
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
218
|
7918
|
|
|
|
|
|
const uint64_t mont2 = mont_get2(n); |
|
219
|
7918
|
|
|
|
|
|
uint64_t md, u = n-1; |
|
220
|
7918
|
|
|
|
|
|
int i, t = 0; |
|
221
|
|
|
|
|
|
|
UV P, V, d, s; |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
/* M-R with base 2 */ |
|
224
|
24087
|
100
|
|
|
|
|
while (!(u&1)) { t++; u >>= 1; } |
|
225
|
7918
|
|
|
|
|
|
md = mont_powmod(mont2, u, n); |
|
226
|
7918
|
100
|
|
|
|
|
if (md != mont1 && md != n-mont1) { |
|
|
|
100
|
|
|
|
|
|
|
227
|
9763
|
100
|
|
|
|
|
for (i=1; i
|
|
228
|
6216
|
100
|
|
|
|
|
md = mont_sqrmod(md, n); |
|
229
|
6216
|
100
|
|
|
|
|
if (md == mont1) return 0; |
|
230
|
6206
|
100
|
|
|
|
|
if (md == n-mont1) break; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
5324
|
100
|
|
|
|
|
if (i == t) |
|
233
|
3547
|
|
|
|
|
|
return 0; |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
/* AES Lucas test */ |
|
236
|
4361
|
|
|
|
|
|
P = select_extra_strong_parameters(n, 1); |
|
237
|
4361
|
50
|
|
|
|
|
if (P == 0) return 0; |
|
238
|
|
|
|
|
|
|
|
|
239
|
4361
|
|
|
|
|
|
d = n+1; |
|
240
|
4361
|
|
|
|
|
|
s = 0; |
|
241
|
13271
|
100
|
|
|
|
|
while ( (d & 1) == 0 ) { s++; d >>= 1; } |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
{ |
|
244
|
4361
|
|
|
|
|
|
const uint64_t montP = mont_geta(P, n); |
|
245
|
|
|
|
|
|
|
UV W, b; |
|
246
|
4361
|
100
|
|
|
|
|
W = submod( mont_mulmod( montP, montP, n), mont2, n); |
|
247
|
4361
|
|
|
|
|
|
V = montP; |
|
248
|
210887
|
100
|
|
|
|
|
{ UV v = d; b = 1; while (v >>= 1) b++; } |
|
249
|
210887
|
100
|
|
|
|
|
while (b-- > 1) { |
|
250
|
206526
|
100
|
|
|
|
|
UV T = submod( mont_mulmod(V, W, n), montP, n); |
|
251
|
206526
|
100
|
|
|
|
|
if ( (d >> (b-1)) & UVCONST(1) ) { |
|
252
|
110493
|
|
|
|
|
|
V = T; |
|
253
|
110493
|
100
|
|
|
|
|
W = submod( mont_mulmod(W, W, n), mont2, n); |
|
254
|
|
|
|
|
|
|
} else { |
|
255
|
96033
|
|
|
|
|
|
W = T; |
|
256
|
96033
|
100
|
|
|
|
|
V = submod( mont_mulmod(V, V, n), mont2, n); |
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
|
|
261
|
4361
|
100
|
|
|
|
|
if (V == mont2 || V == (n-mont2)) |
|
|
|
100
|
|
|
|
|
|
|
262
|
2416
|
|
|
|
|
|
return 1; |
|
263
|
4298
|
100
|
|
|
|
|
while (s-- > 1) { |
|
264
|
4277
|
100
|
|
|
|
|
if (V == 0) |
|
265
|
1924
|
|
|
|
|
|
return 1; |
|
266
|
2353
|
100
|
|
|
|
|
V = submod( mont_mulmod(V, V, n), mont2, n); |
|
267
|
2353
|
50
|
|
|
|
|
if (V == mont2) |
|
268
|
0
|
|
|
|
|
|
return 0; |
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
} |
|
271
|
21
|
|
|
|
|
|
return 0; |
|
272
|
|
|
|
|
|
|
#endif |
|
273
|
|
|
|
|
|
|
} |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
/******************************************************************************/ |
|
278
|
|
|
|
|
|
|
/******************************************************************************/ |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
/* Lucas tests: |
|
281
|
|
|
|
|
|
|
* 0: Standard |
|
282
|
|
|
|
|
|
|
* 1: Strong |
|
283
|
|
|
|
|
|
|
* 2: Stronger (Strong + page 1401 extra tests) |
|
284
|
|
|
|
|
|
|
* 3: Extra Strong (Mo/Jones/Grantham) |
|
285
|
|
|
|
|
|
|
* |
|
286
|
|
|
|
|
|
|
* None of them have any false positives for the BPSW test. Also see the |
|
287
|
|
|
|
|
|
|
* "almost extra strong" test. |
|
288
|
|
|
|
|
|
|
*/ |
|
289
|
170
|
|
|
|
|
|
bool is_lucas_pseudoprime(UV n, int strength) |
|
290
|
|
|
|
|
|
|
{ |
|
291
|
|
|
|
|
|
|
IV P, Q, D; |
|
292
|
|
|
|
|
|
|
UV U, V, Pu, Qu, Qk, d, s; |
|
293
|
|
|
|
|
|
|
|
|
294
|
170
|
100
|
|
|
|
|
if (n < 5) return (n == 2 || n == 3); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
295
|
166
|
100
|
|
|
|
|
if ((n % 2) == 0 || n == UV_MAX) return 0; |
|
|
|
50
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
|
297
|
113
|
100
|
|
|
|
|
if (strength < 3) { |
|
298
|
43
|
|
|
|
|
|
UV Du = 5; |
|
299
|
43
|
|
|
|
|
|
IV sign = 1; |
|
300
|
|
|
|
|
|
|
int j; |
|
301
|
|
|
|
|
|
|
while (1) { |
|
302
|
108
|
|
|
|
|
|
D = Du * sign; |
|
303
|
108
|
|
|
|
|
|
j = jacobi_iu(D, n); |
|
304
|
108
|
100
|
|
|
|
|
if (j != 1 && Du != n) break; |
|
|
|
100
|
|
|
|
|
|
|
305
|
65
|
50
|
|
|
|
|
if (Du == 21 && is_perfect_square(n)) return 0; |
|
|
|
0
|
|
|
|
|
|
|
306
|
65
|
|
|
|
|
|
Du += 2; |
|
307
|
65
|
|
|
|
|
|
sign = -sign; |
|
308
|
|
|
|
|
|
|
} |
|
309
|
43
|
100
|
|
|
|
|
if (j != -1) return 0; |
|
310
|
42
|
|
|
|
|
|
P = 1; |
|
311
|
42
|
|
|
|
|
|
Q = (1 - D) / 4; |
|
312
|
42
|
50
|
|
|
|
|
if (strength == 2 && Q == -1) P=Q=D=5; /* Method A* */ |
|
|
|
0
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
/* Check gcd(n,2QD). gcd(n,2D) already done. */ |
|
314
|
42
|
100
|
|
|
|
|
Qk = (Q >= 0) ? Q % n : n-(((UV)(-Q)) % n); |
|
315
|
42
|
50
|
|
|
|
|
if (gcd_ui(Qk,n) != 1) return 0; |
|
316
|
|
|
|
|
|
|
} else { |
|
317
|
70
|
|
|
|
|
|
P = select_extra_strong_parameters(n, 1); |
|
318
|
70
|
100
|
|
|
|
|
if (P == 0) return 0; |
|
319
|
53
|
|
|
|
|
|
Q = 1; |
|
320
|
53
|
|
|
|
|
|
D = P*P - 4; |
|
321
|
|
|
|
|
|
|
} |
|
322
|
95
|
50
|
|
|
|
|
MPUassert( D == (P*P - 4*Q) , "is_lucas_pseudoprime: incorrect DPQ"); |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
#if 0 /* Condition 2, V_n+1 = 2Q mod n */ |
|
325
|
|
|
|
|
|
|
{ UV us, vs; lucasuvmod(&us, &vs, P, Q, n+1, n); return (vs == addmod(Q,Q,n)); } |
|
326
|
|
|
|
|
|
|
#endif |
|
327
|
|
|
|
|
|
|
#if 0 /* Condition 3, n is a epsp(Q) */ |
|
328
|
|
|
|
|
|
|
return is_euler_pseudoprime(n,Qk); |
|
329
|
|
|
|
|
|
|
#endif |
|
330
|
|
|
|
|
|
|
|
|
331
|
95
|
|
|
|
|
|
d = n+1; |
|
332
|
95
|
|
|
|
|
|
s = 0; |
|
333
|
95
|
100
|
|
|
|
|
if (strength > 0) |
|
334
|
219
|
100
|
|
|
|
|
while ( (d & 1) == 0 ) { s++; d >>= 1; } |
|
335
|
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
337
|
|
|
|
|
|
|
{ |
|
338
|
95
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
339
|
95
|
|
|
|
|
|
const uint64_t mont2 = mont_get2(n); |
|
340
|
95
|
|
|
|
|
|
const uint64_t montP = (P == 1) ? mont1 |
|
341
|
148
|
100
|
|
|
|
|
: (P >= 0) ? mont_geta(P, n) |
|
342
|
53
|
50
|
|
|
|
|
: n - mont_geta(-P, n); |
|
343
|
95
|
|
|
|
|
|
const uint64_t montQ = (Q == 1) ? mont1 |
|
344
|
137
|
100
|
|
|
|
|
: (Q >= 0) ? mont_geta(Q, n) |
|
345
|
42
|
100
|
|
|
|
|
: n - mont_geta(-Q, n); |
|
346
|
73
|
|
|
|
|
|
const uint64_t montD = (D >= 0) ? mont_geta(D, n) |
|
347
|
95
|
100
|
|
|
|
|
: n - mont_geta(-D, n); |
|
348
|
|
|
|
|
|
|
UV b; |
|
349
|
1134
|
100
|
|
|
|
|
{ UV v = d; b = 0; while (v >>= 1) b++; } |
|
350
|
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
/* U, V, Qk, and mont* are in Montgomery space */ |
|
352
|
95
|
|
|
|
|
|
U = mont1; |
|
353
|
95
|
|
|
|
|
|
V = montP; |
|
354
|
|
|
|
|
|
|
|
|
355
|
95
|
100
|
|
|
|
|
if (Q == 1 || Q == -1) { /* Faster code for |Q|=1, also opt for P=1 */ |
|
|
|
100
|
|
|
|
|
|
|
356
|
69
|
|
|
|
|
|
int sign = Q; |
|
357
|
743
|
100
|
|
|
|
|
while (b--) { |
|
358
|
674
|
50
|
|
|
|
|
U = mont_mulmod(U, V, n); |
|
359
|
674
|
100
|
|
|
|
|
if (sign == 1) V = submod( mont_sqrmod(V,n), mont2, n); |
|
|
|
50
|
|
|
|
|
|
|
360
|
102
|
50
|
|
|
|
|
else V = addmod( mont_sqrmod(V,n), mont2, n); |
|
361
|
674
|
|
|
|
|
|
sign = 1; |
|
362
|
674
|
100
|
|
|
|
|
if ( (d >> b) & UVCONST(1) ) { |
|
363
|
295
|
50
|
|
|
|
|
UV t2 = mont_mulmod(U, montD, n); |
|
364
|
295
|
100
|
|
|
|
|
if (P == 1) { |
|
365
|
92
|
|
|
|
|
|
U = addmod(U, V, n); |
|
366
|
92
|
|
|
|
|
|
V = addmod(V, t2, n); |
|
367
|
|
|
|
|
|
|
} else { |
|
368
|
203
|
50
|
|
|
|
|
U = addmod( mont_mulmod(U, montP, n), V, n); |
|
369
|
203
|
50
|
|
|
|
|
V = addmod( mont_mulmod(V, montP, n), t2, n); |
|
370
|
|
|
|
|
|
|
} |
|
371
|
295
|
100
|
|
|
|
|
if (U & 1) { U = (n>>1) + (U>>1) + 1; } else { U >>= 1; } |
|
372
|
295
|
100
|
|
|
|
|
if (V & 1) { V = (n>>1) + (V>>1) + 1; } else { V >>= 1; } |
|
373
|
295
|
|
|
|
|
|
sign = Q; |
|
374
|
|
|
|
|
|
|
} |
|
375
|
|
|
|
|
|
|
} |
|
376
|
69
|
100
|
|
|
|
|
Qk = (sign == 1) ? mont1 : n-mont1; |
|
377
|
|
|
|
|
|
|
} else { |
|
378
|
26
|
|
|
|
|
|
Qk = montQ; |
|
379
|
391
|
100
|
|
|
|
|
while (b--) { |
|
380
|
365
|
50
|
|
|
|
|
U = mont_mulmod(U, V, n); |
|
381
|
365
|
50
|
|
|
|
|
V = submod( mont_sqrmod(V,n), addmod(Qk,Qk,n), n); |
|
382
|
365
|
50
|
|
|
|
|
Qk = mont_sqrmod(Qk,n); |
|
383
|
365
|
100
|
|
|
|
|
if ( (d >> b) & UVCONST(1) ) { |
|
384
|
186
|
50
|
|
|
|
|
UV t2 = mont_mulmod(U, montD, n); |
|
385
|
186
|
50
|
|
|
|
|
U = addmod( mont_mulmod(U, montP, n), V, n); |
|
386
|
186
|
100
|
|
|
|
|
if (U & 1) { U = (n>>1) + (U>>1) + 1; } else { U >>= 1; } |
|
387
|
186
|
50
|
|
|
|
|
V = addmod( mont_mulmod(V, montP, n), t2, n); |
|
388
|
186
|
100
|
|
|
|
|
if (V & 1) { V = (n>>1) + (V>>1) + 1; } else { V >>= 1; } |
|
389
|
186
|
50
|
|
|
|
|
Qk = mont_mulmod(Qk, montQ, n); |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
} |
|
392
|
|
|
|
|
|
|
} |
|
393
|
|
|
|
|
|
|
|
|
394
|
95
|
100
|
|
|
|
|
if (strength == 0) { |
|
395
|
23
|
100
|
|
|
|
|
if (U == 0) |
|
396
|
20
|
|
|
|
|
|
return 1; |
|
397
|
72
|
100
|
|
|
|
|
} else if (strength == 1) { |
|
398
|
19
|
100
|
|
|
|
|
if (U == 0) |
|
399
|
8
|
|
|
|
|
|
return 1; |
|
400
|
23
|
50
|
|
|
|
|
while (s--) { |
|
401
|
23
|
100
|
|
|
|
|
if (V == 0) |
|
402
|
11
|
|
|
|
|
|
return 1; |
|
403
|
12
|
50
|
|
|
|
|
if (s) { |
|
404
|
12
|
50
|
|
|
|
|
V = submod( mont_sqrmod(V,n), addmod(Qk,Qk,n), n); |
|
405
|
12
|
50
|
|
|
|
|
Qk = mont_sqrmod(Qk,n); |
|
406
|
|
|
|
|
|
|
} |
|
407
|
|
|
|
|
|
|
} |
|
408
|
53
|
50
|
|
|
|
|
} else if (strength == 2) { |
|
409
|
0
|
|
|
|
|
|
UV Ql = 0, Qj = 0; |
|
410
|
0
|
|
|
|
|
|
int qjacobi, is_slpsp = 0; |
|
411
|
0
|
0
|
|
|
|
|
if (U == 0) |
|
412
|
0
|
|
|
|
|
|
is_slpsp = 1; |
|
413
|
0
|
0
|
|
|
|
|
while (s--) { |
|
414
|
0
|
0
|
|
|
|
|
if (V == 0) |
|
415
|
0
|
|
|
|
|
|
is_slpsp = 1; |
|
416
|
0
|
|
|
|
|
|
Ql = Qk; |
|
417
|
0
|
0
|
|
|
|
|
V = submod( mont_sqrmod(V,n), addmod(Qk,Qk,n), n); |
|
418
|
0
|
0
|
|
|
|
|
Qk = mont_sqrmod(Qk,n); |
|
419
|
|
|
|
|
|
|
} |
|
420
|
0
|
0
|
|
|
|
|
if (!is_slpsp) return 0; /* slpsp */ |
|
421
|
0
|
0
|
|
|
|
|
if (V != addmod(montQ,montQ,n)) return 0; /* V_{n+1} != 2Q mod n */ |
|
422
|
0
|
|
|
|
|
|
qjacobi = jacobi_iu(Q,n); |
|
423
|
0
|
0
|
|
|
|
|
Qj = (qjacobi == 0) ? 0 : (qjacobi == 1) ? montQ : n-montQ; |
|
|
|
0
|
|
|
|
|
|
|
424
|
0
|
0
|
|
|
|
|
if (Ql != Qj) return 0; /* n is epsp base Q */ |
|
425
|
0
|
|
|
|
|
|
return 1; |
|
426
|
|
|
|
|
|
|
} else { |
|
427
|
53
|
100
|
|
|
|
|
if ( U == 0 && (V == mont2 || V == (n-mont2)) ) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
428
|
26
|
|
|
|
|
|
return 1; |
|
429
|
27
|
|
|
|
|
|
s--; |
|
430
|
58
|
100
|
|
|
|
|
while (s--) { |
|
431
|
50
|
100
|
|
|
|
|
if (V == 0) |
|
432
|
19
|
|
|
|
|
|
return 1; |
|
433
|
31
|
100
|
|
|
|
|
if (s) |
|
434
|
27
|
50
|
|
|
|
|
V = submod( mont_sqrmod(V,n), mont2, n); |
|
435
|
|
|
|
|
|
|
} |
|
436
|
|
|
|
|
|
|
} |
|
437
|
11
|
|
|
|
|
|
return 0; |
|
438
|
|
|
|
|
|
|
} |
|
439
|
|
|
|
|
|
|
#else |
|
440
|
|
|
|
|
|
|
Pu = ivmod(P,n); |
|
441
|
|
|
|
|
|
|
Qu = ivmod(Q,n); |
|
442
|
|
|
|
|
|
|
lucasuvmod(&U, &V, Pu, Qu, d, n); |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
if (strength == 0) { |
|
445
|
|
|
|
|
|
|
if (U == 0) |
|
446
|
|
|
|
|
|
|
return 1; |
|
447
|
|
|
|
|
|
|
} else if (strength == 1) { |
|
448
|
|
|
|
|
|
|
if (U == 0) |
|
449
|
|
|
|
|
|
|
return 1; |
|
450
|
|
|
|
|
|
|
/* Now check to see if V_{d*2^r} == 0 for any 0 <= r < s */ |
|
451
|
|
|
|
|
|
|
Qk = powmod(Qu, d, n); |
|
452
|
|
|
|
|
|
|
while (s--) { |
|
453
|
|
|
|
|
|
|
if (V == 0) |
|
454
|
|
|
|
|
|
|
return 1; |
|
455
|
|
|
|
|
|
|
if (s) { |
|
456
|
|
|
|
|
|
|
V = mulsubmod(V, V, addmod(Qk,Qk,n), n); |
|
457
|
|
|
|
|
|
|
Qk = sqrmod(Qk, n); |
|
458
|
|
|
|
|
|
|
} |
|
459
|
|
|
|
|
|
|
} |
|
460
|
|
|
|
|
|
|
} else if (strength == 2) { |
|
461
|
|
|
|
|
|
|
UV Ql = 0, Qj = 0; |
|
462
|
|
|
|
|
|
|
int qjacobi, is_slpsp = 0; |
|
463
|
|
|
|
|
|
|
if (U == 0) |
|
464
|
|
|
|
|
|
|
is_slpsp = 1; |
|
465
|
|
|
|
|
|
|
Qk = powmod(Qu, d, n); |
|
466
|
|
|
|
|
|
|
while (s--) { |
|
467
|
|
|
|
|
|
|
if (V == 0) |
|
468
|
|
|
|
|
|
|
is_slpsp = 1; |
|
469
|
|
|
|
|
|
|
Ql = Qk; |
|
470
|
|
|
|
|
|
|
V = mulsubmod(V, V, addmod(Qk,Qk,n), n); |
|
471
|
|
|
|
|
|
|
Qk = sqrmod(Qk, n); |
|
472
|
|
|
|
|
|
|
} |
|
473
|
|
|
|
|
|
|
if (!is_slpsp) return 0; /* slpsp */ |
|
474
|
|
|
|
|
|
|
if (V != addmod(Qu,Qu,n)) return 0; /* V_{n+1} != 2Q mod n */ |
|
475
|
|
|
|
|
|
|
qjacobi = jacobi_iu(Q,n); |
|
476
|
|
|
|
|
|
|
Qj = (qjacobi == 0 || Qu == 0) ? 0 : (qjacobi == 1) ? Qu : n-Qu; |
|
477
|
|
|
|
|
|
|
if (Ql != Qj) return 0; /* n is epsp base Q */ |
|
478
|
|
|
|
|
|
|
return 1; |
|
479
|
|
|
|
|
|
|
} else { |
|
480
|
|
|
|
|
|
|
if ( U == 0 && (V == 2 || V == (n-2)) ) |
|
481
|
|
|
|
|
|
|
return 1; |
|
482
|
|
|
|
|
|
|
/* Now check to see if V_{d*2^r} == 0 for any 0 <= r < s-1 */ |
|
483
|
|
|
|
|
|
|
s--; |
|
484
|
|
|
|
|
|
|
while (s--) { |
|
485
|
|
|
|
|
|
|
if (V == 0) |
|
486
|
|
|
|
|
|
|
return 1; |
|
487
|
|
|
|
|
|
|
if (s) |
|
488
|
|
|
|
|
|
|
V = mulsubmod(V, V, 2, n); |
|
489
|
|
|
|
|
|
|
} |
|
490
|
|
|
|
|
|
|
} |
|
491
|
|
|
|
|
|
|
return 0; |
|
492
|
|
|
|
|
|
|
#endif |
|
493
|
|
|
|
|
|
|
} |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
/* A generalization of Pari's shortcut to the extra-strong Lucas test. |
|
496
|
|
|
|
|
|
|
* |
|
497
|
|
|
|
|
|
|
* This only calculates and tests V, which means less work, but it does result |
|
498
|
|
|
|
|
|
|
* in a few more pseudoprimes than the full extra-strong test. |
|
499
|
|
|
|
|
|
|
* |
|
500
|
|
|
|
|
|
|
* I've added a gcd check at the top, which needs to be done and also results |
|
501
|
|
|
|
|
|
|
* in fewer pseudoprimes. Pari always does trial division to 100 first so |
|
502
|
|
|
|
|
|
|
* is unlikely to come up there. |
|
503
|
|
|
|
|
|
|
* |
|
504
|
|
|
|
|
|
|
* increment: 1 for Baillie OEIS, 2 for Pari. |
|
505
|
|
|
|
|
|
|
* |
|
506
|
|
|
|
|
|
|
* With increment = 1, these results will be a subset of the extra-strong |
|
507
|
|
|
|
|
|
|
* Lucas pseudoprimes. With increment = 2, we produce Pari's results. |
|
508
|
|
|
|
|
|
|
*/ |
|
509
|
1183
|
|
|
|
|
|
bool is_almost_extra_strong_lucas_pseudoprime(UV n, UV increment) |
|
510
|
|
|
|
|
|
|
{ |
|
511
|
|
|
|
|
|
|
UV P, V, W, d, s, b; |
|
512
|
|
|
|
|
|
|
|
|
513
|
1183
|
50
|
|
|
|
|
if (n < 13) return (n == 2 || n == 3 || n == 5 || n == 7 || n == 11); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
514
|
1183
|
50
|
|
|
|
|
if ((n % 2) == 0 || n == UV_MAX) return 0; |
|
|
|
50
|
|
|
|
|
|
|
515
|
1183
|
50
|
|
|
|
|
if (increment < 1 || increment > 256) |
|
|
|
50
|
|
|
|
|
|
|
516
|
0
|
|
|
|
|
|
croak("Invalid lucas parameter increment: %"UVuf"\n", increment); |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
/* Ensure small primes work with large increments. */ |
|
519
|
1183
|
50
|
|
|
|
|
if ( (increment >= 16 && n <= 331) || (increment > 148 && n <= 631) ) |
|
|
|
0
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
520
|
0
|
|
|
|
|
|
return is_prob_prime(n); |
|
521
|
|
|
|
|
|
|
|
|
522
|
1183
|
|
|
|
|
|
P = select_extra_strong_parameters(n, increment); |
|
523
|
1183
|
50
|
|
|
|
|
if (P == 0) return 0; |
|
524
|
|
|
|
|
|
|
|
|
525
|
1183
|
|
|
|
|
|
d = n+1; |
|
526
|
1183
|
|
|
|
|
|
s = 0; |
|
527
|
3533
|
100
|
|
|
|
|
while ( (d & 1) == 0 ) { s++; d >>= 1; } |
|
528
|
19375
|
100
|
|
|
|
|
{ UV v = d; b = 0; while (v >>= 1) b++; } |
|
529
|
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
531
|
|
|
|
|
|
|
{ |
|
532
|
1183
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
533
|
1183
|
|
|
|
|
|
const uint64_t mont2 = mont_get2(n); |
|
534
|
1183
|
|
|
|
|
|
const uint64_t montP = mont_geta(P, n); |
|
535
|
1183
|
50
|
|
|
|
|
W = submod( mont_mulmod( montP, montP, n), mont2, n); |
|
536
|
1183
|
|
|
|
|
|
V = montP; |
|
537
|
19375
|
100
|
|
|
|
|
while (b--) { |
|
538
|
18192
|
50
|
|
|
|
|
UV T = submod( mont_mulmod(V, W, n), montP, n); |
|
539
|
18192
|
100
|
|
|
|
|
if ( (d >> b) & UVCONST(1) ) { |
|
540
|
9362
|
|
|
|
|
|
V = T; |
|
541
|
9362
|
50
|
|
|
|
|
W = submod( mont_mulmod(W, W, n), mont2, n); |
|
542
|
|
|
|
|
|
|
} else { |
|
543
|
8830
|
|
|
|
|
|
W = T; |
|
544
|
8830
|
50
|
|
|
|
|
V = submod( mont_mulmod(V, V, n), mont2, n); |
|
545
|
|
|
|
|
|
|
} |
|
546
|
|
|
|
|
|
|
} |
|
547
|
|
|
|
|
|
|
|
|
548
|
1183
|
100
|
|
|
|
|
if (V == mont2 || V == (n-mont2)) |
|
|
|
100
|
|
|
|
|
|
|
549
|
683
|
|
|
|
|
|
return 1; |
|
550
|
500
|
|
|
|
|
|
s--; |
|
551
|
1077
|
50
|
|
|
|
|
while (s--) { |
|
552
|
1077
|
100
|
|
|
|
|
if (V == 0) |
|
553
|
500
|
|
|
|
|
|
return 1; |
|
554
|
577
|
50
|
|
|
|
|
if (s) |
|
555
|
577
|
50
|
|
|
|
|
V = submod( mont_mulmod(V, V, n), mont2, n); |
|
556
|
|
|
|
|
|
|
} |
|
557
|
0
|
|
|
|
|
|
return 0; |
|
558
|
|
|
|
|
|
|
} |
|
559
|
|
|
|
|
|
|
#else |
|
560
|
|
|
|
|
|
|
W = mulsubmod(P, P, 2, n); |
|
561
|
|
|
|
|
|
|
V = P; |
|
562
|
|
|
|
|
|
|
while (b--) { |
|
563
|
|
|
|
|
|
|
UV T = mulsubmod(V, W, P, n); |
|
564
|
|
|
|
|
|
|
if ( (d >> b) & UVCONST(1) ) { |
|
565
|
|
|
|
|
|
|
V = T; |
|
566
|
|
|
|
|
|
|
W = mulsubmod(W, W, 2, n); |
|
567
|
|
|
|
|
|
|
} else { |
|
568
|
|
|
|
|
|
|
W = T; |
|
569
|
|
|
|
|
|
|
V = mulsubmod(V, V, 2, n); |
|
570
|
|
|
|
|
|
|
} |
|
571
|
|
|
|
|
|
|
} |
|
572
|
|
|
|
|
|
|
if (V == 2 || V == (n-2)) |
|
573
|
|
|
|
|
|
|
return 1; |
|
574
|
|
|
|
|
|
|
while (s-- > 1) { |
|
575
|
|
|
|
|
|
|
if (V == 0) |
|
576
|
|
|
|
|
|
|
return 1; |
|
577
|
|
|
|
|
|
|
V = mulsubmod(V, V, 2, n); |
|
578
|
|
|
|
|
|
|
if (V == 2) |
|
579
|
|
|
|
|
|
|
return 0; |
|
580
|
|
|
|
|
|
|
} |
|
581
|
|
|
|
|
|
|
return 0; |
|
582
|
|
|
|
|
|
|
#endif |
|
583
|
|
|
|
|
|
|
} |
|
584
|
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
typedef struct { |
|
587
|
|
|
|
|
|
|
unsigned short div; |
|
588
|
|
|
|
|
|
|
unsigned short period; |
|
589
|
|
|
|
|
|
|
unsigned short offset; |
|
590
|
|
|
|
|
|
|
} _perrin; |
|
591
|
|
|
|
|
|
|
#define NPERRINDIV 19 |
|
592
|
|
|
|
|
|
|
/* 1112 mask bytes */ |
|
593
|
|
|
|
|
|
|
static const uint32_t _perrinmask[] = {22,523,514,65890,8519810,130,4259842,0,526338,2147483904U,1644233728,1,8194,1073774592,1024,134221824,128,512,181250,2048,0,1,134217736,1049600,524545,2147500288U,0,524290,536870912,32768,33554432,2048,0,2,2,256,65536,64,536875010,32768,256,64,0,32,1073741824,0,1048576,1048832,371200000,0,0,536887552,32,2147487744U,2097152,32768,1024,0,1024,536870912,128,512,0,0,512,0,2147483650U,45312,128,0,8388640,0,8388608,8388608,0,2048,4096,92800000,262144,0,65536,4,0,4,4,4194304,8388608,1075838976,536870956,0,134217728,8192,0,8192,8192,0,2,0,268435458,134223392,1073741824,268435968,2097152,67108864,0,8192,1073741840,0,0,128,0,0,512,1450000,8,131136,536870928,0,4,2097152,4096,64,0,32768,0,0,131072,371200000,2048,33570816,4096,32,1024,536870912,1048576,16384,0,8388608,0,0,0,2,512,0,128,0,134217728,2,32,0,0,0,0,8192,0,1073742080,536870912,0,4096,16777216,526336,32,0,65536,33554448,708,67108864,2048,0,0,536870912,0,536870912,33554432,33554432,2147483648U,512,64,0,1074003968,512,0,524288,0,0,0,67108864,524288,1048576,0,131076,0,33554432,131072,0,2,8390656,16384,16777216,134217744,0,131104,0,2,32768,0,0,0,1450000,32768,0,0,0,0,0,16,0,1024,16400,1048576,32,1024,0,260,536870912,269484032,0,16384,0,524290,0,0,512,65536,0,0,0,134217732,0,67108880,536887296,0,0,32,0,65568,0,524288,2147483648U,0,4096,4096,134217984,268500992,0,33554432,131072,0,0,0,16777216,0,0,0,0,0,524288,0,0,67108864,0,0,2,0,2,32,1024,0}; |
|
594
|
|
|
|
|
|
|
static const _perrin _perrindata[NPERRINDIV] = { |
|
595
|
|
|
|
|
|
|
{2, 7, 0}, |
|
596
|
|
|
|
|
|
|
{3, 13, 1}, |
|
597
|
|
|
|
|
|
|
{4, 14, 2}, |
|
598
|
|
|
|
|
|
|
{5, 24, 3}, |
|
599
|
|
|
|
|
|
|
{7, 48, 4}, |
|
600
|
|
|
|
|
|
|
{9, 39, 6}, |
|
601
|
|
|
|
|
|
|
{11, 120, 8}, |
|
602
|
|
|
|
|
|
|
{13, 183, 12}, |
|
603
|
|
|
|
|
|
|
{17, 288, 18}, |
|
604
|
|
|
|
|
|
|
{19, 180, 27}, |
|
605
|
|
|
|
|
|
|
{23, 22, 33}, |
|
606
|
|
|
|
|
|
|
{25, 120, 34}, |
|
607
|
|
|
|
|
|
|
{29, 871, 38}, |
|
608
|
|
|
|
|
|
|
{31, 993, 66}, |
|
609
|
|
|
|
|
|
|
{37, 1368, 98}, |
|
610
|
|
|
|
|
|
|
{41, 1723, 141}, |
|
611
|
|
|
|
|
|
|
{43, 231, 195}, |
|
612
|
|
|
|
|
|
|
{47, 2257, 203}, |
|
613
|
|
|
|
|
|
|
{223, 111, 274} |
|
614
|
|
|
|
|
|
|
}; |
|
615
|
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
/* Calculate signature using the doubling rule from Adams and Shanks 1982 */ |
|
617
|
20
|
|
|
|
|
|
static void calc_perrin_sig(UV* S, UV n) { |
|
618
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
619
|
20
|
|
|
|
|
|
uint64_t npi = 0, mont1; |
|
620
|
|
|
|
|
|
|
int i; |
|
621
|
|
|
|
|
|
|
#endif |
|
622
|
|
|
|
|
|
|
UV T[6], T01, T34, T45; |
|
623
|
|
|
|
|
|
|
int b; |
|
624
|
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
/* Signature for n = 1 */ |
|
626
|
20
|
|
|
|
|
|
S[0] = 1; S[1] = n-1; S[2] = 3; S[3] = 3; S[4] = 0; S[5] = 2; |
|
627
|
20
|
50
|
|
|
|
|
if (n <= 1) return; |
|
628
|
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
630
|
20
|
100
|
|
|
|
|
if ( (n&1) ) { |
|
631
|
18
|
|
|
|
|
|
npi = mont_inverse(n); |
|
632
|
18
|
|
|
|
|
|
mont1 = mont_get1(n); |
|
633
|
18
|
|
|
|
|
|
S[0] = mont1; S[1] = n-mont1; S[5] = addmod(mont1,mont1,n); |
|
634
|
18
|
|
|
|
|
|
S[2] = addmod(S[5],mont1,n); S[3] = S[2]; |
|
635
|
|
|
|
|
|
|
} |
|
636
|
|
|
|
|
|
|
#endif |
|
637
|
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
/* Bits in n */ |
|
639
|
571
|
100
|
|
|
|
|
{ UV v = n; b = 1; while (v >>= 1) b++; } |
|
640
|
|
|
|
|
|
|
|
|
641
|
571
|
100
|
|
|
|
|
while (b-- > 1) { |
|
642
|
|
|
|
|
|
|
/* Double */ |
|
643
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
644
|
551
|
100
|
|
|
|
|
if (n&1) { |
|
645
|
504
|
50
|
|
|
|
|
T[0] = submod(submod(mont_sqrmod(S[0],n), S[5],n), S[5],n); |
|
646
|
504
|
50
|
|
|
|
|
T[1] = submod(submod(mont_sqrmod(S[1],n), S[4],n), S[4],n); |
|
647
|
504
|
50
|
|
|
|
|
T[2] = submod(submod(mont_sqrmod(S[2],n), S[3],n), S[3],n); |
|
648
|
504
|
50
|
|
|
|
|
T[3] = submod(submod(mont_sqrmod(S[3],n), S[2],n), S[2],n); |
|
649
|
504
|
50
|
|
|
|
|
T[4] = submod(submod(mont_sqrmod(S[4],n), S[1],n), S[1],n); |
|
650
|
504
|
50
|
|
|
|
|
T[5] = submod(submod(mont_sqrmod(S[5],n), S[0],n), S[0],n); |
|
651
|
|
|
|
|
|
|
} else |
|
652
|
|
|
|
|
|
|
#endif |
|
653
|
|
|
|
|
|
|
{ |
|
654
|
47
|
|
|
|
|
|
T[0] = submod(submod(sqrmod(S[0],n), S[5],n), S[5],n); |
|
655
|
47
|
|
|
|
|
|
T[1] = submod(submod(sqrmod(S[1],n), S[4],n), S[4],n); |
|
656
|
47
|
|
|
|
|
|
T[2] = submod(submod(sqrmod(S[2],n), S[3],n), S[3],n); |
|
657
|
47
|
|
|
|
|
|
T[3] = submod(submod(sqrmod(S[3],n), S[2],n), S[2],n); |
|
658
|
47
|
|
|
|
|
|
T[4] = submod(submod(sqrmod(S[4],n), S[1],n), S[1],n); |
|
659
|
47
|
|
|
|
|
|
T[5] = submod(submod(sqrmod(S[5],n), S[0],n), S[0],n); |
|
660
|
|
|
|
|
|
|
} |
|
661
|
|
|
|
|
|
|
/* Move to S, filling in */ |
|
662
|
551
|
|
|
|
|
|
T01 = submod(T[2], T[1], n); |
|
663
|
551
|
|
|
|
|
|
T34 = submod(T[5], T[4], n); |
|
664
|
551
|
|
|
|
|
|
T45 = addmod(T34, T[3], n); |
|
665
|
551
|
100
|
|
|
|
|
if ( (n >> (b-1)) & 1U ) { |
|
666
|
245
|
|
|
|
|
|
S[0] = T[0]; S[1] = T01; S[2] = T[1]; |
|
667
|
245
|
|
|
|
|
|
S[3] = T[4]; S[4] = T45; S[5] = T[5]; |
|
668
|
|
|
|
|
|
|
} else { |
|
669
|
306
|
|
|
|
|
|
S[0] = T01; S[1] = T[1]; S[2] = addmod(T01,T[0],n); |
|
670
|
306
|
|
|
|
|
|
S[3] = T34; S[4] = T[4]; S[5] = T45; |
|
671
|
|
|
|
|
|
|
} |
|
672
|
|
|
|
|
|
|
} |
|
673
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
674
|
20
|
100
|
|
|
|
|
if (n&1) { /* Recover result from Montgomery form */ |
|
675
|
126
|
100
|
|
|
|
|
for (i = 0; i < 6; i++) |
|
676
|
108
|
50
|
|
|
|
|
S[i] = mont_recover(S[i],n); |
|
677
|
|
|
|
|
|
|
} |
|
678
|
|
|
|
|
|
|
#endif |
|
679
|
|
|
|
|
|
|
} |
|
680
|
|
|
|
|
|
|
|
|
681
|
20
|
|
|
|
|
|
bool is_perrin_pseudoprime(UV n, uint32_t restricted) |
|
682
|
|
|
|
|
|
|
{ |
|
683
|
|
|
|
|
|
|
int jacobi, i; |
|
684
|
|
|
|
|
|
|
UV S[6]; |
|
685
|
|
|
|
|
|
|
|
|
686
|
20
|
50
|
|
|
|
|
if (n < 3) return (n >= 2); |
|
687
|
20
|
100
|
|
|
|
|
if (!(n&1) && restricted > 2) return 0; /* Odds only for restrict > 2 */ |
|
|
|
50
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
/* Hard code the initial tests. 60% of composites caught by 4 tests. */ |
|
690
|
|
|
|
|
|
|
{ |
|
691
|
20
|
|
|
|
|
|
uint32_t n32 = n % 10920; |
|
692
|
20
|
100
|
|
|
|
|
if (!(n32&1) && !(( 22 >> (n32% 7)) & 1)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
693
|
20
|
50
|
|
|
|
|
if (!(n32%3) && !(( 523 >> (n32%13)) & 1)) return 0; |
|
|
|
0
|
|
|
|
|
|
|
694
|
20
|
100
|
|
|
|
|
if (!(n32%5) && !((65890 >> (n32%24)) & 1)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
695
|
20
|
50
|
|
|
|
|
if (!(n32%4) && !(( 514 >> (n32%14)) & 1)) return 0; |
|
|
|
0
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
} |
|
697
|
320
|
100
|
|
|
|
|
for (i = 4; i < NPERRINDIV; i++) { |
|
698
|
300
|
100
|
|
|
|
|
if ((n % _perrindata[i].div) == 0) { |
|
699
|
12
|
|
|
|
|
|
const uint32_t *mask = _perrinmask + _perrindata[i].offset; |
|
700
|
12
|
|
|
|
|
|
unsigned short mod = n % _perrindata[i].period; |
|
701
|
12
|
50
|
|
|
|
|
if (!((mask[mod/32] >> (mod%32)) & 1)) |
|
702
|
0
|
|
|
|
|
|
return 0; |
|
703
|
|
|
|
|
|
|
} |
|
704
|
|
|
|
|
|
|
} |
|
705
|
|
|
|
|
|
|
/* Depending on which filters are used, 10-20% of composites are left. */ |
|
706
|
|
|
|
|
|
|
|
|
707
|
20
|
|
|
|
|
|
calc_perrin_sig(S, n); |
|
708
|
|
|
|
|
|
|
|
|
709
|
20
|
50
|
|
|
|
|
if (S[4] != 0) return 0; /* P(n) = 0 mod n */ |
|
710
|
20
|
100
|
|
|
|
|
if (restricted == 0) return 1; |
|
711
|
|
|
|
|
|
|
|
|
712
|
5
|
100
|
|
|
|
|
if (S[1] != n-1) return 0; /* P(-n) = -1 mod n */ |
|
713
|
4
|
100
|
|
|
|
|
if (restricted == 1) return 1; |
|
714
|
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
/* Full restricted test looks for an acceptable signature. |
|
716
|
|
|
|
|
|
|
* |
|
717
|
|
|
|
|
|
|
* restrict = 2 is Adams/Shanks without quadratic form test |
|
718
|
|
|
|
|
|
|
* |
|
719
|
|
|
|
|
|
|
* restrict = 3 is Arno or Grantham: No qform, also reject mults of 2 and 23 |
|
720
|
|
|
|
|
|
|
* |
|
721
|
|
|
|
|
|
|
* See: |
|
722
|
|
|
|
|
|
|
* Adams/Shanks 1982 pages 257-261 |
|
723
|
|
|
|
|
|
|
* Arno 1991 pages 371-372 |
|
724
|
|
|
|
|
|
|
* Grantham 2000 pages 5-6 |
|
725
|
|
|
|
|
|
|
*/ |
|
726
|
|
|
|
|
|
|
|
|
727
|
3
|
|
|
|
|
|
jacobi = kronecker_su(-23,n); |
|
728
|
|
|
|
|
|
|
|
|
729
|
3
|
100
|
|
|
|
|
if (jacobi == -1) { /* Q-type */ |
|
730
|
|
|
|
|
|
|
|
|
731
|
1
|
|
|
|
|
|
UV B = S[2], B2 = sqrmod(B,n); |
|
732
|
1
|
|
|
|
|
|
UV A = submod(addmod(1,mulmod(B,3,n),n),B2,n); |
|
733
|
1
|
|
|
|
|
|
UV C = submod(mulmod(B2,3,n),2,n); |
|
734
|
1
|
50
|
|
|
|
|
if (S[0] == A && S[2] == B && S[3] == B && S[5] == C && |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
735
|
0
|
0
|
|
|
|
|
B != 3 && submod(mulmod(B2,B,n),B,n) == 1) { |
|
736
|
0
|
0
|
|
|
|
|
MPUverbose(2, "%"UVuf" Q-Type %"UVuf" -1 %"UVuf" %"UVuf" 0 %"UVuf"\n", n, A, B, B, C); |
|
737
|
0
|
|
|
|
|
|
return 1; |
|
738
|
|
|
|
|
|
|
} |
|
739
|
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
} else { /* S-Type or I-Type */ |
|
741
|
|
|
|
|
|
|
|
|
742
|
2
|
50
|
|
|
|
|
if (jacobi == 0 && n != 23 && restricted > 2) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
743
|
1
|
50
|
|
|
|
|
MPUverbose(2, "%"UVuf" Jacobi %d\n",n,jacobi); |
|
744
|
1
|
|
|
|
|
|
return 0; /* Adams/Shanks allows (-23|n) = 0 for S-Type */ |
|
745
|
|
|
|
|
|
|
} |
|
746
|
|
|
|
|
|
|
|
|
747
|
1
|
50
|
|
|
|
|
if (S[0] == 1 && S[2] == 3 && S[3] == 3 && S[5] == 2) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
748
|
1
|
50
|
|
|
|
|
MPUverbose(2, "%"UVuf" S-Type 1 -1 3 3 0 2\n",n); |
|
749
|
1
|
|
|
|
|
|
return 1; |
|
750
|
0
|
0
|
|
|
|
|
} else if (S[0] == 0 && S[5] == n-1 && S[2] != S[3] && |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
751
|
0
|
0
|
|
|
|
|
addmod(S[2],S[3],n) == n-3 && sqrmod(submod(S[2],S[3],n),n) == n-(23%n)) { |
|
|
|
0
|
|
|
|
|
|
|
752
|
0
|
0
|
|
|
|
|
MPUverbose(2, "%"UVuf" I-Type 0 -1 %"UVuf" %"UVuf" 0 -1\n",n, S[2], S[3]); |
|
753
|
0
|
|
|
|
|
|
return 1; |
|
754
|
|
|
|
|
|
|
} |
|
755
|
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
} |
|
757
|
1
|
50
|
|
|
|
|
MPUverbose(2, "%"UVuf" ? %2d ? %"UVuf" -1 %"UVuf" %"UVuf" 0 %"UVuf"\n", n, jacobi, S[0],S[2],S[3],S[5]); |
|
758
|
1
|
|
|
|
|
|
return 0; |
|
759
|
|
|
|
|
|
|
} |
|
760
|
|
|
|
|
|
|
|
|
761
|
28
|
|
|
|
|
|
bool is_frobenius_pseudoprime(UV n, IV P, IV Q) |
|
762
|
|
|
|
|
|
|
{ |
|
763
|
|
|
|
|
|
|
UV U, V, t, Vcomp; |
|
764
|
28
|
|
|
|
|
|
int k = 0; |
|
765
|
|
|
|
|
|
|
IV D; |
|
766
|
|
|
|
|
|
|
UV Du, Pu, Qu; |
|
767
|
|
|
|
|
|
|
|
|
768
|
28
|
50
|
|
|
|
|
if (n < 7) return (n == 2 || n == 3 || n == 5); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
769
|
28
|
50
|
|
|
|
|
if ((n % 2) == 0 || n == UV_MAX) return 0; |
|
|
|
50
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
|
|
771
|
28
|
50
|
|
|
|
|
if (P == 0 && Q == 0) { |
|
|
|
0
|
|
|
|
|
|
|
772
|
0
|
|
|
|
|
|
P = -1; Q = 2; |
|
773
|
0
|
0
|
|
|
|
|
if (n == 7) P = 1; /* So we don't test kronecker(-7,7) */ |
|
774
|
|
|
|
|
|
|
do { |
|
775
|
0
|
|
|
|
|
|
P += 2; |
|
776
|
0
|
0
|
|
|
|
|
if (P == 3) P = 5; /* P=3,Q=2 -> D=9-8=1 => k=1, so skip */ |
|
777
|
0
|
|
|
|
|
|
D = P*P-4*Q; |
|
778
|
0
|
|
|
|
|
|
Du = D >= 0 ? D : -D; |
|
779
|
0
|
|
|
|
|
|
k = kronecker_su(D, n); |
|
780
|
0
|
0
|
|
|
|
|
if (P == 10001 && is_perfect_square(n)) return 0; |
|
|
|
0
|
|
|
|
|
|
|
781
|
0
|
0
|
|
|
|
|
} while (k == 1); |
|
782
|
0
|
0
|
|
|
|
|
if (k == 0) return 0; |
|
783
|
|
|
|
|
|
|
/* D=P^2-8 will not be a perfect square */ |
|
784
|
0
|
0
|
|
|
|
|
MPUverbose(1, "%"UVuf" Frobenius (%"IVdf",%"IVdf") : x^2 - %"IVdf"x + %"IVdf"\n", n, P, Q, P, Q); |
|
785
|
0
|
|
|
|
|
|
Vcomp = 4; |
|
786
|
|
|
|
|
|
|
} else { |
|
787
|
28
|
|
|
|
|
|
D = P*P-4*Q; |
|
788
|
28
|
|
|
|
|
|
Du = D >= 0 ? D : -D; |
|
789
|
28
|
100
|
|
|
|
|
if (D != 5 && is_perfect_square(Du)) |
|
|
|
50
|
|
|
|
|
|
|
790
|
0
|
|
|
|
|
|
croak("Frobenius invalid P,Q: (%"IVdf",%"IVdf")", P, Q); |
|
791
|
|
|
|
|
|
|
} |
|
792
|
28
|
|
|
|
|
|
Pu = ivmod(P,n); |
|
793
|
28
|
|
|
|
|
|
Qu = ivmod(Q,n); |
|
794
|
|
|
|
|
|
|
|
|
795
|
28
|
|
|
|
|
|
t = gcd_ui(n, Pu*Qu*Du); |
|
796
|
28
|
50
|
|
|
|
|
if (t != 1) { |
|
797
|
0
|
0
|
|
|
|
|
if (t == n) return is_prob_prime(n); |
|
798
|
0
|
|
|
|
|
|
return 0; |
|
799
|
|
|
|
|
|
|
} |
|
800
|
28
|
50
|
|
|
|
|
if (k == 0) { |
|
801
|
28
|
|
|
|
|
|
k = kronecker_su(D, n); |
|
802
|
28
|
50
|
|
|
|
|
if (k == 0) return 0; |
|
803
|
28
|
100
|
|
|
|
|
Vcomp = (k == 1) ? 2 : addmod(Qu,Qu,n); |
|
804
|
|
|
|
|
|
|
} |
|
805
|
|
|
|
|
|
|
|
|
806
|
28
|
|
|
|
|
|
lucasuvmod(&U, &V, Pu, Qu, n-k, n); |
|
807
|
|
|
|
|
|
|
/* MPUverbose(1, "%"UVuf" Frobenius U = %"UVuf" V = %"UVuf"\n", n, U, V); */ |
|
808
|
28
|
50
|
|
|
|
|
if (U == 0 && V == Vcomp) return 1; |
|
|
|
50
|
|
|
|
|
|
|
809
|
0
|
|
|
|
|
|
return 0; |
|
810
|
|
|
|
|
|
|
} |
|
811
|
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
/* |
|
813
|
|
|
|
|
|
|
* Khashin, July 2018, https://arxiv.org/pdf/1807.07249.pdf |
|
814
|
|
|
|
|
|
|
* "Evaluation of the Effectiveness of the Frobenius Primality Test" |
|
815
|
|
|
|
|
|
|
* |
|
816
|
|
|
|
|
|
|
* See also the earlier https://arxiv.org/abs/1307.7920 |
|
817
|
|
|
|
|
|
|
* "Counterexamples for Frobenius primality test" |
|
818
|
|
|
|
|
|
|
* |
|
819
|
|
|
|
|
|
|
* 1. select c as first in [-1,2,3,4,5,6,...] where (c|n)=-1 |
|
820
|
|
|
|
|
|
|
* 2. Check this holds: |
|
821
|
|
|
|
|
|
|
* (2+sqrt(c)^n = 2-sqrt(c) mod n for c = -1,2 |
|
822
|
|
|
|
|
|
|
* (1+sqrt(c)^n = 1-sqrt(c) mod n for c = 3,4,5,6,... |
|
823
|
|
|
|
|
|
|
* |
|
824
|
|
|
|
|
|
|
* The paper claims there are no 64-bit counterexamples. |
|
825
|
|
|
|
|
|
|
*/ |
|
826
|
48
|
|
|
|
|
|
bool is_frobenius_khashin_pseudoprime(UV n) |
|
827
|
|
|
|
|
|
|
{ |
|
828
|
48
|
|
|
|
|
|
int k = 2; |
|
829
|
48
|
|
|
|
|
|
UV ea, ra, rb, a, b, d = n-1, c = 1; |
|
830
|
|
|
|
|
|
|
|
|
831
|
48
|
50
|
|
|
|
|
if (n < 7) return (n == 2 || n == 3 || n == 5); |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
832
|
0
|
0
|
|
|
|
|
if ((n % 2) == 0 || n == UV_MAX) return 0; |
|
|
|
0
|
|
|
|
|
|
|
833
|
0
|
0
|
|
|
|
|
if (is_perfect_square(n)) return 0; |
|
834
|
|
|
|
|
|
|
|
|
835
|
0
|
0
|
|
|
|
|
if (n % 4 == 3) c = d; |
|
836
|
0
|
0
|
|
|
|
|
else if (n % 8 == 5) c = 2; |
|
837
|
|
|
|
|
|
|
else |
|
838
|
|
|
|
|
|
|
do { /* c = first odd prime where (c|n)=-1 */ |
|
839
|
0
|
|
|
|
|
|
c += 2; |
|
840
|
0
|
0
|
|
|
|
|
if (c==9 || (c>=15 && (!(c%3) || !(c%5) || !(c%7) || !(c%11) || !(c%13)))) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
841
|
0
|
|
|
|
|
|
continue; |
|
842
|
0
|
|
|
|
|
|
k = kronecker_uu(c, n); |
|
843
|
0
|
0
|
|
|
|
|
} while (k == 1); |
|
844
|
0
|
0
|
|
|
|
|
if (k == 0 || (k == 2 && n % 3 == 0)) return 0; |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
847
|
|
|
|
|
|
|
{ |
|
848
|
0
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n); |
|
849
|
0
|
|
|
|
|
|
const uint64_t mont1 = mont_get1(n); |
|
850
|
0
|
|
|
|
|
|
const uint64_t montc = mont_geta(c, n); |
|
851
|
0
|
0
|
|
|
|
|
ra = a = ea = (k == 2) ? mont_get2(n) : mont1; |
|
852
|
0
|
|
|
|
|
|
rb = b = mont1; |
|
853
|
0
|
0
|
|
|
|
|
while (d) { |
|
854
|
0
|
0
|
|
|
|
|
if (d & 1) { |
|
855
|
0
|
|
|
|
|
|
UV ta=ra, tb=rb; |
|
856
|
0
|
0
|
|
|
|
|
ra = addmod( mont_mulmod(ta,a,n), mont_mulmod(mont_mulmod(tb,b,n),montc,n), n ); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
857
|
0
|
0
|
|
|
|
|
rb = addmod( mont_mulmod(tb,a,n), mont_mulmod(ta,b,n), n); |
|
|
|
0
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
} |
|
859
|
0
|
|
|
|
|
|
d >>= 1; |
|
860
|
0
|
0
|
|
|
|
|
if (d) { |
|
861
|
0
|
0
|
|
|
|
|
UV t = mont_mulmod(mont_mulmod(b,b,n),montc,n); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
862
|
0
|
0
|
|
|
|
|
b = mont_mulmod(b,a,n); |
|
863
|
0
|
|
|
|
|
|
b = addmod(b,b,n); |
|
864
|
0
|
0
|
|
|
|
|
a = addmod(mont_mulmod(a,a,n),t,n); |
|
865
|
|
|
|
|
|
|
} |
|
866
|
|
|
|
|
|
|
} |
|
867
|
0
|
0
|
|
|
|
|
return (ra == ea && rb == n-mont1); |
|
|
|
0
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
} |
|
869
|
|
|
|
|
|
|
#else |
|
870
|
|
|
|
|
|
|
ra = a = ea = (k == 2) ? 2 : 1; |
|
871
|
|
|
|
|
|
|
rb = b = 1; |
|
872
|
|
|
|
|
|
|
while (d) { |
|
873
|
|
|
|
|
|
|
if (d & 1) { |
|
874
|
|
|
|
|
|
|
/* This is faster than the 3-mulmod 5-addmod version */ |
|
875
|
|
|
|
|
|
|
UV ta=ra, tb=rb; |
|
876
|
|
|
|
|
|
|
ra = addmod( mulmod(ta,a,n), mulmod(mulmod(tb,b,n),c,n), n ); |
|
877
|
|
|
|
|
|
|
rb = addmod( mulmod(tb,a,n), mulmod(ta,b,n), n); |
|
878
|
|
|
|
|
|
|
} |
|
879
|
|
|
|
|
|
|
d >>= 1; |
|
880
|
|
|
|
|
|
|
if (d) { |
|
881
|
|
|
|
|
|
|
UV t = mulmod(sqrmod(b,n),c,n); |
|
882
|
|
|
|
|
|
|
b = mulmod(b,a,n); |
|
883
|
|
|
|
|
|
|
b = addmod(b,b,n); |
|
884
|
|
|
|
|
|
|
a = addmod(sqrmod(a,n),t,n); |
|
885
|
|
|
|
|
|
|
} |
|
886
|
|
|
|
|
|
|
} |
|
887
|
|
|
|
|
|
|
return (ra == ea && rb == n-1); |
|
888
|
|
|
|
|
|
|
#endif |
|
889
|
|
|
|
|
|
|
} |
|
890
|
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
/* |
|
892
|
|
|
|
|
|
|
* The Frobenius-Underwood test has no known counterexamples below 2^50, but |
|
893
|
|
|
|
|
|
|
* has not been extensively tested above that. This is the Minimal Lambda+2 |
|
894
|
|
|
|
|
|
|
* test from section 9 of "Quadratic Composite Tests" by Paul Underwood. |
|
895
|
|
|
|
|
|
|
* |
|
896
|
|
|
|
|
|
|
* It is generally slower than the AES Lucas test, but for large values is |
|
897
|
|
|
|
|
|
|
* competitive with the BPSW test. Since our BPSW is known to have no |
|
898
|
|
|
|
|
|
|
* counterexamples under 2^64, while the results of this test are unknown, |
|
899
|
|
|
|
|
|
|
* it is mainly useful for numbers larger than 2^64 as an additional |
|
900
|
|
|
|
|
|
|
* non-correlated test. |
|
901
|
|
|
|
|
|
|
*/ |
|
902
|
48
|
|
|
|
|
|
bool is_frobenius_underwood_pseudoprime(UV n) |
|
903
|
|
|
|
|
|
|
{ |
|
904
|
|
|
|
|
|
|
int j, bit; |
|
905
|
|
|
|
|
|
|
UV x, result, a, b, np1, len, t1; |
|
906
|
|
|
|
|
|
|
IV t; |
|
907
|
|
|
|
|
|
|
|
|
908
|
48
|
50
|
|
|
|
|
if (n < 7) return (n == 2 || n == 3 || n == 5); |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
909
|
0
|
0
|
|
|
|
|
if ((n % 2) == 0 || n == UV_MAX) return 0; |
|
|
|
0
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
|
|
911
|
0
|
0
|
|
|
|
|
for (x = 0; x < 1000000; x++) { |
|
912
|
0
|
0
|
|
|
|
|
if (x==2 || x==4 || x==7 || x==8 || x==10 || x==14 || x==16 || x==18) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
913
|
0
|
|
|
|
|
|
continue; |
|
914
|
0
|
|
|
|
|
|
t = (IV)(x*x) - 4; |
|
915
|
0
|
|
|
|
|
|
j = jacobi_iu(t, n); |
|
916
|
0
|
0
|
|
|
|
|
if (j == -1) break; |
|
917
|
0
|
0
|
|
|
|
|
if (j == 0 || (x == 20 && is_perfect_square(n))) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
918
|
0
|
|
|
|
|
|
return 0; |
|
919
|
|
|
|
|
|
|
} |
|
920
|
0
|
0
|
|
|
|
|
if (x >= 1000000) croak("FU test failure, unable to find suitable a"); |
|
921
|
0
|
|
|
|
|
|
t1 = gcd_ui(n, (x+4)*(2*x+5)); |
|
922
|
0
|
0
|
|
|
|
|
if (t1 != 1 && t1 != n) |
|
|
|
0
|
|
|
|
|
|
|
923
|
0
|
|
|
|
|
|
return 0; |
|
924
|
0
|
|
|
|
|
|
np1 = n+1; |
|
925
|
0
|
0
|
|
|
|
|
{ UV v = np1; len = 1; while (v >>= 1) len++; } |
|
926
|
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
928
|
|
|
|
|
|
|
{ |
|
929
|
0
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
930
|
0
|
|
|
|
|
|
const uint64_t mont2 = mont_get2(n); |
|
931
|
0
|
|
|
|
|
|
const uint64_t mont5 = mont_geta(5, n); |
|
932
|
|
|
|
|
|
|
|
|
933
|
0
|
|
|
|
|
|
x = mont_geta(x, n); |
|
934
|
0
|
|
|
|
|
|
a = mont1; |
|
935
|
0
|
|
|
|
|
|
b = mont2; |
|
936
|
|
|
|
|
|
|
|
|
937
|
0
|
0
|
|
|
|
|
if (x == 0) { |
|
938
|
0
|
|
|
|
|
|
result = mont5; |
|
939
|
0
|
0
|
|
|
|
|
for (bit = len-2; bit >= 0; bit--) { |
|
940
|
0
|
|
|
|
|
|
t1 = addmod(b, b, n); |
|
941
|
0
|
0
|
|
|
|
|
b = mont_mulmod(submod(b, a, n), addmod(b, a, n), n); |
|
942
|
0
|
0
|
|
|
|
|
a = mont_mulmod(a, t1, n); |
|
943
|
0
|
0
|
|
|
|
|
if ( (np1 >> bit) & UVCONST(1) ) { |
|
944
|
0
|
|
|
|
|
|
t1 = b; |
|
945
|
0
|
|
|
|
|
|
b = submod( addmod(b, b, n), a, n); |
|
946
|
0
|
|
|
|
|
|
a = addmod( addmod(a, a, n), t1, n); |
|
947
|
|
|
|
|
|
|
} |
|
948
|
|
|
|
|
|
|
} |
|
949
|
|
|
|
|
|
|
} else { |
|
950
|
0
|
|
|
|
|
|
UV multiplier = addmod(x, mont2, n); |
|
951
|
0
|
|
|
|
|
|
result = addmod( addmod(x, x, n), mont5, n); |
|
952
|
0
|
0
|
|
|
|
|
for (bit = len-2; bit >= 0; bit--) { |
|
953
|
0
|
0
|
|
|
|
|
t1 = addmod( mont_mulmod(a, x, n), addmod(b, b, n), n); |
|
954
|
0
|
0
|
|
|
|
|
b = mont_mulmod(submod(b, a, n), addmod(b, a, n), n); |
|
955
|
0
|
0
|
|
|
|
|
a = mont_mulmod(a, t1, n); |
|
956
|
0
|
0
|
|
|
|
|
if ( (np1 >> bit) & UVCONST(1) ) { |
|
957
|
0
|
|
|
|
|
|
t1 = b; |
|
958
|
0
|
|
|
|
|
|
b = submod( addmod(b, b, n), a, n); |
|
959
|
0
|
0
|
|
|
|
|
a = addmod( mont_mulmod(a, multiplier, n), t1, n); |
|
960
|
|
|
|
|
|
|
} |
|
961
|
|
|
|
|
|
|
} |
|
962
|
|
|
|
|
|
|
} |
|
963
|
0
|
0
|
|
|
|
|
return (a == 0 && b == result); |
|
|
|
0
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
} |
|
965
|
|
|
|
|
|
|
#else |
|
966
|
|
|
|
|
|
|
a = 1; |
|
967
|
|
|
|
|
|
|
b = 2; |
|
968
|
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
if (x == 0) { |
|
970
|
|
|
|
|
|
|
result = 5; |
|
971
|
|
|
|
|
|
|
for (bit = len-2; bit >= 0; bit--) { |
|
972
|
|
|
|
|
|
|
t1 = addmod(b, b, n); |
|
973
|
|
|
|
|
|
|
b = mulmod( submod(b, a, n), addmod(b, a, n), n); |
|
974
|
|
|
|
|
|
|
a = mulmod(a, t1, n); |
|
975
|
|
|
|
|
|
|
if ( (np1 >> bit) & UVCONST(1) ) { |
|
976
|
|
|
|
|
|
|
t1 = b; |
|
977
|
|
|
|
|
|
|
b = submod( addmod(b, b, n), a, n); |
|
978
|
|
|
|
|
|
|
a = addmod( addmod(a, a, n), t1, n); |
|
979
|
|
|
|
|
|
|
} |
|
980
|
|
|
|
|
|
|
} |
|
981
|
|
|
|
|
|
|
} else { |
|
982
|
|
|
|
|
|
|
UV multiplier = addmod(x, 2, n); |
|
983
|
|
|
|
|
|
|
result = addmod( addmod(x, x, n), 5, n); |
|
984
|
|
|
|
|
|
|
for (bit = len-2; bit >= 0; bit--) { |
|
985
|
|
|
|
|
|
|
t1 = addmod( mulmod(a, x, n), addmod(b, b, n), n); |
|
986
|
|
|
|
|
|
|
b = mulmod(submod(b, a, n), addmod(b, a, n), n); |
|
987
|
|
|
|
|
|
|
a = mulmod(a, t1, n); |
|
988
|
|
|
|
|
|
|
if ( (np1 >> bit) & UVCONST(1) ) { |
|
989
|
|
|
|
|
|
|
t1 = b; |
|
990
|
|
|
|
|
|
|
b = submod( addmod(b, b, n), a, n); |
|
991
|
|
|
|
|
|
|
a = addmod( mulmod(a, multiplier, n), t1, n); |
|
992
|
|
|
|
|
|
|
} |
|
993
|
|
|
|
|
|
|
} |
|
994
|
|
|
|
|
|
|
} |
|
995
|
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
MPUverbose(2, "%"UVuf" is %s with x = %"UVuf"\n", n, (a == 0 && b == result) ? "probably prime" : "composite", x); |
|
997
|
|
|
|
|
|
|
if (a == 0 && b == result) |
|
998
|
|
|
|
|
|
|
return 1; |
|
999
|
|
|
|
|
|
|
return 0; |
|
1000
|
|
|
|
|
|
|
#endif |
|
1001
|
|
|
|
|
|
|
} |
|
1002
|
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
/* We have a native-UV Lucas-Lehmer test with simple pretest. If 2^p-1 is |
|
1004
|
|
|
|
|
|
|
* prime but larger than a UV, we'll have to bail, and they'll run the nice |
|
1005
|
|
|
|
|
|
|
* GMP version. However, they're just asking if this is a Mersenne prime, and |
|
1006
|
|
|
|
|
|
|
* there are millions of CPU years that have gone into enumerating them, so |
|
1007
|
|
|
|
|
|
|
* instead we'll use a table. */ |
|
1008
|
|
|
|
|
|
|
#define NUM_KNOWN_MERSENNE_PRIMES 52 |
|
1009
|
|
|
|
|
|
|
static const uint32_t _mersenne_primes[NUM_KNOWN_MERSENNE_PRIMES] = {2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,2203,2281,3217,4253,4423,9689,9941,11213,19937,21701,23209,44497,86243,110503,132049,216091,756839,859433,1257787,1398269,2976221,3021377,6972593,13466917,20996011,24036583,25964951,30402457,32582657,37156667,42643801,43112609,57885161,74207281,77232917,82589933,136279841}; |
|
1010
|
|
|
|
|
|
|
#define LAST_CHECKED_MERSENNE 79711549 |
|
1011
|
2296
|
|
|
|
|
|
int is_mersenne_prime(UV p) |
|
1012
|
|
|
|
|
|
|
{ |
|
1013
|
|
|
|
|
|
|
int i; |
|
1014
|
120508
|
100
|
|
|
|
|
for (i = 0; i < NUM_KNOWN_MERSENNE_PRIMES; i++) |
|
1015
|
118238
|
100
|
|
|
|
|
if (p == _mersenne_primes[i]) |
|
1016
|
26
|
|
|
|
|
|
return 1; |
|
1017
|
2270
|
50
|
|
|
|
|
return (p < LAST_CHECKED_MERSENNE) ? 0 : -1; |
|
1018
|
|
|
|
|
|
|
} |
|
1019
|
0
|
|
|
|
|
|
bool lucas_lehmer(UV p) |
|
1020
|
|
|
|
|
|
|
{ |
|
1021
|
|
|
|
|
|
|
UV k, V, mp; |
|
1022
|
|
|
|
|
|
|
|
|
1023
|
0
|
0
|
|
|
|
|
if (p == 2) return 1; |
|
1024
|
0
|
0
|
|
|
|
|
if (!is_prob_prime(p)) return 0; |
|
1025
|
0
|
0
|
|
|
|
|
if (p > BITS_PER_WORD) croak("lucas_lehmer with p > BITS_PER_WORD"); |
|
1026
|
0
|
|
|
|
|
|
V = 4; |
|
1027
|
0
|
|
|
|
|
|
mp = UV_MAX >> (BITS_PER_WORD - p); |
|
1028
|
0
|
0
|
|
|
|
|
for (k = 3; k <= p; k++) { |
|
1029
|
0
|
|
|
|
|
|
V = mulsubmod(V, V, 2, mp); |
|
1030
|
|
|
|
|
|
|
} |
|
1031
|
0
|
|
|
|
|
|
return (V == 0); |
|
1032
|
|
|
|
|
|
|
} |
|
1033
|
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
/******************************************************************************/ |
|
1035
|
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
static const uint16_t mr_bases_hash32[256] = { /* requires div 2,3,5 */ |
|
1037
|
|
|
|
|
|
|
4816, 6332, 958, 6124, 1001, 1431, 9644, 3700, 9251,20069, 7085, 2484, |
|
1038
|
|
|
|
|
|
|
3255, 218, 4660, 732, 1863, 3716, 2480, 2120, 2464,38264, 3070, 2621, |
|
1039
|
|
|
|
|
|
|
1592,17862,15223, 2926, 9119, 2181,24932, 4407,10915,13832, 1965, 3646, |
|
1040
|
|
|
|
|
|
|
2470, 62, 8548, 449, 4440, 7656, 1065,10100, 6497, 1868,33282, 4277, |
|
1041
|
|
|
|
|
|
|
805, 636,11536, 34, 2065, 406, 6435, 1043,27985, 7134, 1357, 3056, |
|
1042
|
|
|
|
|
|
|
6077, 4704, 6174, 865,15190,14419, 38, 6161,18774, 3990, 976, 1267, |
|
1043
|
|
|
|
|
|
|
3251, 233, 7387, 241, 3871, 4331, 8780, 2233,30331, 1656, 462, 5585, |
|
1044
|
|
|
|
|
|
|
194,10300, 1072, 1197, 1573, 1144, 1273,19439, 696, 1477,15858, 2684, |
|
1045
|
|
|
|
|
|
|
6022, 80, 9726, 6731, 1132, 774, 2202, 3668,19479,10837, 183, 71, |
|
1046
|
|
|
|
|
|
|
403, 5245, 1995, 2019, 5209, 174, 503,13830,21013, 3284, 7164, 2607, |
|
1047
|
|
|
|
|
|
|
10769, 473, 119, 8227, 1216, 3550, 1450, 1399,45822, 609, 721, 47, |
|
1048
|
|
|
|
|
|
|
9665, 4242, 767, 4880,16037, 844, 333, 8560, 1907, 2532,13468, 302, |
|
1049
|
|
|
|
|
|
|
2589, 5546,14312, 1548,18013, 8452,12427, 4431,10248, 4022, 5545, 1399, |
|
1050
|
|
|
|
|
|
|
41507, 1160, 1865, 219, 1254, 3330,13627, 1070, 3304, 5537, 6085,26999, |
|
1051
|
|
|
|
|
|
|
10279, 5369, 4992,38919, 2191, 1663,46961, 6570,11876,21689, 2804, 1202, |
|
1052
|
|
|
|
|
|
|
5764, 275, 2862, 2139, 7799, 4646, 1696, 4964,19016,12891, 4282, 4741, |
|
1053
|
|
|
|
|
|
|
7274, 174, 541,26596, 7524, 2777, 1819, 339, 1399, 2636, 668, 291, |
|
1054
|
|
|
|
|
|
|
559, 4992, 520, 7874, 2544, 4618, 4122, 1128, 326, 275,13080, 156, |
|
1055
|
|
|
|
|
|
|
236, 7015, 6349,11673, 2632, 475, 4560, 1543, 78, 3611, 34, 3811, |
|
1056
|
|
|
|
|
|
|
137, 737,31269, 2522,13354, 2033, 8577, 3597, 9269, 3815, 2511, 8088, |
|
1057
|
|
|
|
|
|
|
903, 109,12454, 1985, 8065,17637, 1645, 1404, 6106, 3661, 328, 6160, |
|
1058
|
|
|
|
|
|
|
1602, 6601, 1491, 8657 |
|
1059
|
|
|
|
|
|
|
}; |
|
1060
|
|
|
|
|
|
|
/* Correct for any 32-bit input. */ |
|
1061
|
12798
|
|
|
|
|
|
bool MR32(uint32_t n) { |
|
1062
|
|
|
|
|
|
|
|
|
1063
|
12798
|
100
|
|
|
|
|
if (n < 11) return 0xAC >> n & 1; /* equal to 2, 3, 5 or 7 */ |
|
1064
|
12793
|
50
|
|
|
|
|
if (is_divis_2_3_5(n)) return 0; /* divis by 2, 3, or 5 */ |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1065
|
12793
|
|
|
|
|
|
return is_strong_pseudoprime(n, mr_bases_hash32[n >> 8 & 255]); |
|
1066
|
|
|
|
|
|
|
} |
|
1067
|
|
|
|
|
|
|
|
|
1068
|
|
|
|
|
|
|
/******************************************************************************/ |
|
1069
|
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
/********** PRIMALITY TEST **********/ |
|
1071
|
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
/******************************************************************************/ |
|
1073
|
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
/* |
|
1075
|
|
|
|
|
|
|
* For numbers under 3481 (59^2) everything handled by trial division. |
|
1076
|
|
|
|
|
|
|
* |
|
1077
|
|
|
|
|
|
|
* For numbers under 500k when we don't have fast ASM Montgomery math, |
|
1078
|
|
|
|
|
|
|
* do it with trial division. |
|
1079
|
|
|
|
|
|
|
* |
|
1080
|
|
|
|
|
|
|
* If input is 32-bit, use a hashed single base Miller-Rabin test. |
|
1081
|
|
|
|
|
|
|
* |
|
1082
|
|
|
|
|
|
|
* Otherwise (input is bigger than 32-bit), do trial division to 89, then |
|
1083
|
|
|
|
|
|
|
* call BPSW. This is typically about 25% slower than a big (300k+) hash |
|
1084
|
|
|
|
|
|
|
* table to allow two Miller-Rabin tests, and 20% faster than a reasonable |
|
1085
|
|
|
|
|
|
|
* size table allowing three M-R tests. |
|
1086
|
|
|
|
|
|
|
* |
|
1087
|
|
|
|
|
|
|
* See: |
|
1088
|
|
|
|
|
|
|
* - https://github.com/flintlib/flint/pull/2487 |
|
1089
|
|
|
|
|
|
|
* - https://github.com/JASory/machine-prime |
|
1090
|
|
|
|
|
|
|
* for examples of using the big table. |
|
1091
|
|
|
|
|
|
|
*/ |
|
1092
|
|
|
|
|
|
|
|
|
1093
|
547146
|
|
|
|
|
|
bool is_prob_prime(UV n) |
|
1094
|
|
|
|
|
|
|
{ |
|
1095
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 |
|
1096
|
547146
|
100
|
|
|
|
|
if (n > UVCONST(4294967295)) { /* input is >= 2^32, UV is 64-bit*/ |
|
1097
|
3714
|
100
|
|
|
|
|
if (is_divis_2_3_5_7(n)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1098
|
1693
|
100
|
|
|
|
|
if (!(n%11) || !(n%13) || !(n%17) || !(n%19) || |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1099
|
1279
|
100
|
|
|
|
|
!(n%23) || !(n%29) || !(n%31) || !(n%37) || |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1100
|
1693
|
100
|
|
|
|
|
!(n%41) || !(n%43) || !(n%47) || !(n%53)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1101
|
1021
|
100
|
|
|
|
|
if (!(n%59) || !(n%61) || !(n%67) || !(n%71)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1102
|
958
|
100
|
|
|
|
|
if (!(n%73) || !(n%79) || !(n%83) || !(n%89)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
/* AESLSP test costs about 1.5 Selfridges, vs. ~2.2 for strong Lucas. |
|
1104
|
|
|
|
|
|
|
* This makes the full BPSW test cost about 2.5x M-R tests for a prime. */ |
|
1105
|
919
|
|
|
|
|
|
return BPSW(n); |
|
1106
|
|
|
|
|
|
|
} |
|
1107
|
|
|
|
|
|
|
#endif |
|
1108
|
|
|
|
|
|
|
{ |
|
1109
|
543432
|
|
|
|
|
|
uint32_t x = n; |
|
1110
|
|
|
|
|
|
|
|
|
1111
|
543432
|
100
|
|
|
|
|
if (x < 11) return 0xAC >> x & 1; /* Bits 2, 3, 5 and 7 */ |
|
1112
|
|
|
|
|
|
|
|
|
1113
|
539051
|
100
|
|
|
|
|
if (is_divis_2_3_5_7(x)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1114
|
492139
|
100
|
|
|
|
|
if (x < 121) /* 11*11 */ return 1; |
|
1115
|
|
|
|
|
|
|
|
|
1116
|
490044
|
100
|
|
|
|
|
if (!(x%11) || !(x%13) || !(x%17) || !(x%19) || |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1117
|
365158
|
100
|
|
|
|
|
!(x%23) || !(x%29) || !(x%31) || !(x%37) || |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1118
|
490044
|
100
|
|
|
|
|
!(x%41) || !(x%43) || !(x%47) || !(x%53)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1119
|
292321
|
100
|
|
|
|
|
if (x < 3481) /* 59*59 */ return 1; |
|
1120
|
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
/* For tiny inputs, continue trial division. */ |
|
1122
|
|
|
|
|
|
|
if (!USE_MONTMATH && n < 500000) { |
|
1123
|
|
|
|
|
|
|
uint32_t f = 59; |
|
1124
|
|
|
|
|
|
|
uint32_t limit = isqrt(n); |
|
1125
|
|
|
|
|
|
|
while (f <= limit) { |
|
1126
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 2; |
|
1127
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 6; |
|
1128
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 4; |
|
1129
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 2; |
|
1130
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 4; |
|
1131
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 2; |
|
1132
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 4; |
|
1133
|
|
|
|
|
|
|
{ if ((x%f) == 0) return 0; } f += 6; |
|
1134
|
|
|
|
|
|
|
} |
|
1135
|
|
|
|
|
|
|
return 1; |
|
1136
|
|
|
|
|
|
|
} |
|
1137
|
|
|
|
|
|
|
|
|
1138
|
280328
|
|
|
|
|
|
return is_strong_pseudoprime(x, mr_bases_hash32[x >> 8 & 255]); |
|
1139
|
|
|
|
|
|
|
} |
|
1140
|
|
|
|
|
|
|
} |