I have been trying to implement the Baillie-PSW primality test for a few days, and have ran into some problems. Sepcifically when trying to use the Lucas probable prime test. My question is not about Baile, but on how to generate the correct Lucas sequence modulo some number
For the first two psudoprimes my code gives the correct result, eg for 323
and 377
. However for the next psudoprime, both the standard implementation and the doubling version fails.
Trying to do modulo operations on V_1
completely breaks the doubling version of the Luckas sequence generator.
Any tips or suggestions on how to correctly implement the Lucas probable prime test in Python?
from fractions import gcd from math import log def luckas_sequence_standard(num, D=0): if D == 0: D = smallest_D(num) P = 1 Q = (1-D)/4 V0 = 2 V1 = P U0 = 0 U1 = 1 for _ in range(num): U2 = (P*U1 - Q*U0) % num U1, U0 = U2, U1 V2 = (P*V1 - Q*V0) % num V1, V0 = V2, V1 return U2%num, V2%num def luckas_sequence_doubling(num, D=0): if D == 0: D = smallest_D(num) P = 1 Q = (1 - D)/4 V0 = P U0 = 1 temp_num = num + 1 double = [] while temp_num > 1: if temp_num % 2 == 0: double.append(True) temp_num //= 2 else: double.append(False) temp_num += -1 k = 1 double.reverse() for is_double in double: if is_double: U1 = (U0*V0) % num V1 = V0**2 - 2*Q**k U0 = U1 V0 = V1 k *= 2 elif not is_double: U1 = ((P*U0 + V0)/2) % num V1 = (D*U0 + P*V0)/2 U0 = U1 V0 = V1 k += 1 return U1%num, V1%num def jacobi(a, m): if a in [0, 1]: return a elif gcd(a, m) != 1: return 0 elif a == 2: if m % 8 in [3, 5]: return -1 elif m % 8 in [1, 7]: return 1 if a % 2 == 0: return jacobi(2,m)*jacobi(a/2, m) elif a >= m or a < 0: return jacobi(a % m, m) elif a % 4 == 3 and m % 4 == 3: return -jacobi(m, a) return jacobi(m, a) def smallest_D(num): D = 5 k = 1 while k > 0 and jacobi(k*D, num) != -1: D += 2 k *= -1 return k*D if __name__ == '__main__': print luckas_sequence_standard(323) print luckas_sequence_doubling(323) print print luckas_sequence_standard(377) print luckas_sequence_doubling(377) print print luckas_sequence_standard(1159) print luckas_sequence_doubling(1159)