如何改进此椭圆曲线分解代码?

时间:2019-01-14 06:51:54

标签: python-3.x elliptic-curve prime-factoring

首先,我非常菜鸟:)我没有深入研究椭圆曲线。我只是在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的边界是否值得,还是应该修复此算法的大部分内容?

感谢您的帮助,对于语言不好(如果有问题)表示抱歉;;

0 个答案:

没有答案