【发布时间】:2013-02-21 22:55:53
【问题描述】:
我正在尝试编写一个函数,该函数使用卢卡斯伪素测试来确定数字 n 是素数还是合数;目前,我正在使用标准测试,但是一旦我开始工作,我就会编写强测试。我正在阅读 Baillie 和 Wagstaff 的 paper,并在 trn.c 文件中关注 Thomas Nicely 的 implementation。
我知道完整的测试涉及几个步骤:用小素数进行除法,检查 n 是否不是正方形,对基数 2 执行强伪素数测试,最后是卢卡斯伪素数测试。我可以处理所有其他部分,但卢卡斯伪素测试有问题。这是我在 Python 中的实现:
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
def jacobi(a, m):
a = a % m; t = 1
while a != 0:
while a % 2 == 0:
a = a / 2
if m % 8 == 3 or m % 8 == 5:
t = -1 * t
a, m = m, a # swap a and m
if a % 4 == 3 and m % 4 == 3:
t = -1 * t
a = a % m
if m == 1:
return t
return 0
def isLucasPrime(n):
dAbs, sign, d = 5, 1, 5
while 1:
if 1 < gcd(d, n) > n:
return False
if jacobi(d, n) == -1:
break
dAbs, sign = dAbs + 2, sign * -1
d = dAbs * sign
p, q = 1, (1 - d) / 4
print "p, q, d =", p, q, d
u, v, u2, v2, q, q2 = 0, 2, 1, p, q, 2 * q
bits = []
t = (n + 1) / 2
while t > 0:
bits.append(t % 2)
t = t // 2
h = -1
while -1 * len(bits) <= h:
print "u, u2, v, v2, q, q2, bits, bits[h] = ",\
u, u2, v, v2, q, q2, bits, bits[h]
u2 = (u2 * v2) % n
v2 = (v2 * v2 - q2) % n
if bits[h] == 1:
u = u2 * v + u * v2
u = u if u % 2 == 0 else u + n
u = (u / 2) % n
v = (v2 * v) + (u2 * u * d)
v = v if v % 2 == 0 else v + n
v = (v / 2) % n
if -1 * len(bits) < h:
q = (q * q) % n
q2 = q + q
h = h - 1
return u == 0
当我运行它时,isLucasPrime 会为 83 和 89 等素数返回 False,这是不正确的。它还为复合 111 返回False,这是正确的。它为复合 323 返回 False,我知道它是 Lucas 伪素数,isLucasPrime 应该返回 True。事实上,isLucasPseudoprime 为我测试过的每个 n 返回 False。
我有几个问题:
1) 我不是 C/GMP 方面的专家,但在我看来,从右到左(从最不重要到最重要)很好地贯穿 (n+1)/2 的位,而其他作者则贯穿这些位左到右。上面显示的代码从左到右运行位,但我也尝试从右到左运行位,结果相同。哪个顺序是正确的?
2) Nicely 仅将 u 和 v 变量更新为 1 位在我看来很奇怪。它是否正确?我希望每次循环都更新所有四个 Lucas 链变量,因为链的索引在每一步都会增加。
3) 我做错了什么?
【问题讨论】:
标签: primes