首先,我非常菜鸟:)我没有深入研究椭圆曲线。我只是在Google上了解素数分解和椭圆曲线的一些基本知识。
我正在尝试使椭圆曲线分解算法的python3代码实现。我只是按照Lenstra's Elliptic Curve Method中的说明进行操作,并通过一些功能,类和已实现的错误,设法构建了代码:
from random import randint
from math import e as exp
from math import sqrt, log
class InvError(Exception):
def __init__(self, v):
self.value = v
def inv(a,n):
r1, s1, t1 = 1, 0, a
r2, s2, t2 = 0, 1, n
while t2:
q = t1//t2
r1, r2 = r2, r1-q*r2
s1, s2 = s2, s1-q*s2
t1, t2 = t2, t1-q*t2
if t1!=1: raise InvError(t1)
else: return r1
class ECpoint(object):
def __init__(self, A,B,N, x,y):
if (y*y - x*x*x - A*x - B)%N != 0: raise ValueError
self.A, self.B = A, B
self.N = N
self.x, self.y = x, y
def __add__(self, other):
A,B,N = self.A, self.B, self.N
Px, Py, Qx, Qy = self.x, self.y, other.x, other.y
if Px == Qx and Py == Qy:
s = (3*Px*Px + A)%N * inv((2*Py)%N, N) %N
else:
s = (Py-Qy)%N * inv((Px-Qx)%N, N) %N
x = (s*s - Px - Qx) %N
y = (s*(Px - x) - Py) %N
return ECpoint(A,B,N, x,y)
def __rmul__(self, other):
r = self; other -= 1
while True:
if other & 1:
r = r + self
if other==1: return r
other >>= 1
self = self+self
def ECM(n):
x0 = 2
y0 = 3
bound = max(int(exp**(1/2*sqrt(log(n)*log(log(n))))),100)
while True:
try:
a = randint(1,n-1)
inv(a,n)
b = (y0*y0 - x0*x0*x0 - a*x0) %n
inv(b,n)
inv((4*a*a*a + 27*b*b)%n, n)
P = ECpoint(a,b,n, x0,y0)
for k in range(2, bound):
inv(P.x, n)
inv(P.y, n)
P = k*P
#print(k,P)
except InvError as e:
d = e.value
if d==n: continue
else: return d, n//d
print(ECM(int(input())))
此代码获取一个复合数字作为输入,并打印两个平凡的除数。
该代码对于大多数输入都运行良好。问题是,它太慢了... 我测试了这段代码中60〜120位整数之间的一些数字(例如2 ^ 101-1、10 ^ 30-33等),我遇到的是它甚至比粗略的Pollard的p-1测试还慢这个:
def Pollard_pminus1(n):
if '0' not in bin(n)[3:]: base = 3
else: base = 2
if n % base == 0: return base, n//base
b = base; exp = 1
while True:
b = pow(b,exp,n)
d = gcd(b-1,n)
if d!=1: break
exp += 1
if d!=n: return d, n//d
对于大约50位数字的输入(根据Wikipedia,此范围应该是ECM的真正游乐场...),该程序甚至暂停一天。
我可以改善此代码的性能吗?优化值k的边界是否值得,还是应该修复此算法的大部分内容?
感谢您的帮助,对于语言不好(如果有问题)表示抱歉;;