|
@@ -1,6 +1,7 @@
|
1
|
1
|
# Finding lucas pseudoprimes
|
2
|
2
|
from math import sqrt, gcd, floor, log
|
3
|
3
|
from time import process_time
|
|
4
|
+from psimp import trd, hund_div
|
4
|
5
|
|
5
|
6
|
def isqrt(n):
|
6
|
7
|
""" Find the integer square root of n via newton's method, code via
|
|
@@ -179,15 +180,75 @@ def LucasPrime(n):
|
179
|
180
|
lnum = LucasFast(n + 1, 1, q, n)
|
180
|
181
|
return lnum[0] == 0
|
181
|
182
|
|
|
183
|
+def StrongLucasPrime(n):
|
|
184
|
+ """Strong version of the Lucas probable prime test
|
|
185
|
+ """
|
|
186
|
+ if n < 2:
|
|
187
|
+ return False
|
|
188
|
+ if n == 2:
|
|
189
|
+ return True
|
|
190
|
+ if n % 2 == 0:
|
|
191
|
+ return False
|
|
192
|
+ d = FirstD(n)
|
|
193
|
+ if d == 0:
|
|
194
|
+ return False
|
|
195
|
+ s, od = trd(n + 1)
|
|
196
|
+ p = 1
|
|
197
|
+ q = (1 - d) // 4
|
|
198
|
+ uc, vc = Lucas(0, p, q)
|
|
199
|
+ dk = floor(log(od, 2))
|
|
200
|
+ tp = 2**dk
|
|
201
|
+ krunn = od
|
|
202
|
+ ks = 0
|
|
203
|
+ for i in range(dk + 1):
|
|
204
|
+ un = (uc * vc)
|
|
205
|
+ vn = (pow(vc, 2, n) - 2 * pow(q, ks, n))
|
|
206
|
+ uc = un % n
|
|
207
|
+ vc = vn % n
|
|
208
|
+ ks = ks * 2
|
|
209
|
+ if krunn >= tp:
|
|
210
|
+ krunn = krunn - tp
|
|
211
|
+ ks = ks + 1
|
|
212
|
+ un = p * uc + vc
|
|
213
|
+ if un % 2 != 0:
|
|
214
|
+ un = un + n
|
|
215
|
+ vn = (p * p - 4 * q) * uc + p * vc
|
|
216
|
+ if vn % 2 != 0:
|
|
217
|
+ vn = vn + n
|
|
218
|
+ uc = (un // 2) % n
|
|
219
|
+ vc = (vn // 2) % n
|
|
220
|
+ tp = tp // 2
|
|
221
|
+ if uc == 0:
|
|
222
|
+ return True
|
|
223
|
+ if vc == 0:
|
|
224
|
+ return True
|
|
225
|
+ for r in range(1, s):
|
|
226
|
+ un = (uc * vc)
|
|
227
|
+ vn = (pow(vc, 2, n) - 2 * pow(q, ks, n))
|
|
228
|
+ uc = un % n
|
|
229
|
+ vc = vn % n
|
|
230
|
+ if vc == 0:
|
|
231
|
+ return True
|
|
232
|
+ ks = ks * 2
|
|
233
|
+ return False
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+#print(StrongLucasPrime(7))
|
182
|
238
|
|
183
|
239
|
np = 0
|
184
|
240
|
|
185
|
|
-for i in range(1000):
|
186
|
|
- lp = LucasPrime(i)
|
|
241
|
+for i in range(10000):
|
|
242
|
+ lp = StrongLucasPrime(i)
|
187
|
243
|
if lp:
|
188
|
244
|
np = np + 1
|
189
|
|
- print("{}:\t{}".format(i, lp))
|
|
245
|
+ print("{}:\t{};\t{}".format(i, lp, np))
|
190
|
246
|
|
191
|
247
|
print(np)
|
192
|
248
|
|
|
249
|
+print(StrongLucasPrime(5459))
|
|
250
|
+print(hund_div(5459))
|
|
251
|
+print(StrongLucasPrime(5777))
|
|
252
|
+print(hund_div(5777))
|
|
253
|
+
|
193
|
254
|
|