我被要求向我的同学介绍 Williams 的 p+1 算法来分解整数,但我认为我没有做对。据我了解,该算法采用整数 N 来分解素数 p,q (N=pq),其中 p+1 是 B 平滑的。我理解为什么从这些前提开始,该算法有效(我已经写了证明),但我不知道如何正确实现和使用它。我认为必须按如下方式实施:
所以,这主要是我关于实现的问题,总体来说是关于 M 的构建,我猜这可能与 p+1 B 平滑度的事实有关。
关于用法,我实在不明白什么情况下该用这个方法,该用哪个B。我将在这里留下我的 Python3 代码和一个让我抓狂的案例,看看你是否可以帮助我。
import random
from math import floor, log, gcd
def is_prime(n): #funcion que determina si un numero es primo
for d in range(2,n):
if n%d == 0:
return False
return True
def primes_leq(B): #funcion para obtener los primos que son menor o igual que B
l=[]
for i in range(2,B+1):
if is_prime(i):
l.append(i)
return l
def matrix_square(A, mod):
return mat_mult(A,A,mod)
def mat_mult(A,B, mod):
if mod is not None:
return [[(A[0][0]*B[0][0] + A[0][1]*B[1][0])%mod, (A[0][0]*B[0][1] + A[0][1]*B[1][1])%mod],
[(A[1][0]*B[0][0] + A[1][1]*B[1][0])%mod, (A[1][0]*B[0][1] + A[1][1]*B[1][1])%mod]]
def matrix_pow(M, power, mod):
#Special definition for power=0:
if power <= 0:
return [[1,0],[0,1]]
powers = list(reversed([True if i=="1" else False for i in bin(power)[2:]])) #Order is 1,2,4,8,16,...
matrices = [None for _ in powers]
matrices[0] = M
for i in range(1,len(powers)):
matrices[i] = matrix_square(matrices[i-1], mod)
result = None
for matrix, power in zip(matrices, powers):
if power:
if result is None:
result = matrix
else:
result = mat_mult(result, matrix, mod)
return result
def williams(N, B):
flag = False
while not flag :
a = random.randint(1,N-1)
print("a : " + str(a))
x = gcd(a,N)
print("x : " + str(x))
if x != 1:
return x
else :
M = 1
A = [[0,1],[-1,a]]
for p in primes_leq(B):
M *= p **(floor(log(N,p)))
print("voy por aquí")
C = matrix_pow(A,M,N)
V = 2*C[0][0]+ a*C[0][1]
y = gcd(V-2,N)
print("y : " + str(y))
if y != 1 and y != N:
flag = True
return y
为了测试我的实现,我尝试遵循一些示例来检查我的分解是否正常工作。例如,我查看了 https://members.loria.fr/PZimmermann/records/Pplus1.html 并且尝试过
williams(2**439-1,10**5)
,我得到了 104110607 但我知道我应该得到 122551752733003055543 (如网页中所示)。据我了解,两者都是因数 N=2**439-1 的素数,但这不是与 N 是两个素数 p*q 的乘积的假设相矛盾吗?
感谢您的帮助,我们将不胜感激
我认为你错过了这个算法的要点......
当 M 是 p+1 的倍数时,您会发现 N(或平凡除数)的因数 p。
如果 p+1 是平滑的——假设 p+1 的所有因子都是 <= B -- then it becomes becomes possible to construct an M,即 all 这些可能因子的倍数,如下所示:
M=1
for x in all primes <= B:
let y = largest power of x such that y < N
M = M*y
您应该检查此循环产生的 M 的连续值。或者,您可以只检查所有连续的阶乘。关键是,在每次迭代中,你向M添加新的因子,当p+1的所有因子都在M中时,那么M当然会是p+1的倍数.
棘手的部分是 M 会变得非常大,并且你不能采用 M mod N。不过,您可以做的是计算所有 VM mod N,而不是实际计算每个 M,只需使用以下公式将 VM 的下标乘以适当的因子即可加法公式: Va+b = VaVb - Va-b
2439−1 具有两个以上素因数。如果你没有得到 你想要的,你应该除以你得到的并保留 继续商。
我们的同伴和朋友们以 p+1 的方式呈现威廉姆斯的方法,并以类似的方式进行了类似的操作,我们将继续采取行动,以解决数字问题或计算数字问题。没有任何人参与实施算法和数字的任务。 Llegaste a resolver tus dudas conrespecto a esto? Nos podrías echar una mano?