Python 3.x 具有属性误差的Lenstras椭圆曲线问题

Python 3.x 具有属性误差的Lenstras椭圆曲线问题,python-3.x,cryptography,attributeerror,factorization,Python 3.x,Cryptography,Attributeerror,Factorization,已经为编写了一些代码,我对它相当满意。然而,它只在某些时候起作用。添加点的函数应返回整数或点。在返回整数d的情况下,Lenstra代码块只需打印gcd(d,n)并退出即可。似乎在某些时候它没有退出,然后尝试将一个整数放入add函数,但该函数失败并出现属性错误。我试过修补,但似乎无法纠正 有人能告诉我发生了什么事或者如何更正代码吗?我很乐意回答任何问题,因为我不是一名程序员,我知道我的代码还远远不够整洁 from sympy import mod_inverse import math impor

已经为编写了一些代码,我对它相当满意。然而,它只在某些时候起作用。添加点的函数应返回整数或点。在返回整数d的情况下,Lenstra代码块只需打印gcd(d,n)并退出即可。似乎在某些时候它没有退出,然后尝试将一个整数放入add函数,但该函数失败并出现属性错误。我试过修补,但似乎无法纠正

有人能告诉我发生了什么事或者如何更正代码吗?我很乐意回答任何问题,因为我不是一名程序员,我知道我的代码还远远不够整洁

from sympy import mod_inverse
import math
import secrets
from collections import namedtuple
Point = namedtuple("Point", "x y")


def point_valid(P,a,b,p):
    O = 'Inf_Point'
    if P == O:
        return True
    else:
        return (P.y**2 - (P.x**3 + a*P.x + b)) % p == 0 and 0 <= P.x < p and 0 <= P.y < p


def inverse_point(P,p):
    O = 'Inf_Point'
    # Just calculates the inverse point
    if P == O:
        return P
    return Point(P.x, (-P.y) % p)


def point_add(P, Q, a, b, p):
    O = 'Inf_Point'
    # Checking that the points are valid if not raise an exception error
    if not (point_valid(P,a,b,p) and point_valid(Q,a,b,p)):
        raise ValueError("Invalid inputs")

    if P == O:
        R = Q
    elif Q == O:
        R = P
    elif Q == inverse_point(P,p):
        R = O
    else:
        if P == Q:
            try:
                inv = mod_inverse(2 * P.y,p)
            except ValueError:
                return 2 * P.y
            dydx = (3 * P.x**2 + a) * inv
        else:
            try:
                inv =  mod_inverse(Q.x - P.x,p)
            except ValueError:
                return Q.x - P.x
            dydx = (Q.y - P.y) * inv
        x = (dydx**2 - P.x - Q.x) % p
        y = (dydx * (P.x - x) - P.y) % p
        R = Point(x, y)

    # Making sure the result is on the curve
    assert point_valid(R,a,b,p)
    # Returning the result
    return R


def point_multiply(P,n,a,b,p):
    O = 'Inf_Point'
    Q = P
    R = O
    while n > 0:
        if n % 2 == 1:
            R = point_add(R,Q,a,b,p)
        Q = point_add(Q,Q,a,b,p)
        n = math.floor(n/2)
        if n > 0:
            continue
    return R



def random_curve(N):
    while True:
        A = secrets.randbelow(N)
        x = secrets.randbelow(N)
        y = secrets.randbelow(N)
        P = Point(x,y)
        B = (y**2 - x**3 - A*x) % N

        if (4*A**3 + 27*B**2) % N != 0:
            return (A,B,P)


def lenstra(N,B):
    a,b,P = random_curve(N)
    for i in range(2,B+1):
        if type(P)== int:
            d = math.gcd(P,N)
            if d < N:
                return d
            elif d == N:
                print('start again')
        Q = point_multiply(P,i,a,b,N)
        P = Q

print(lenstra(8453621,15))

在函数point_add()的开头,它似乎按预期工作,尽管我觉得这并不理想。

您没有检查
point_add
内的两个
point_multiply
调用返回的结果 如果返回的是
int
而不是点

我将建议一些非正统的东西,这会冒犯一些编程纯粹主义者。 我认为当发现可能的因素时,应该使用
异常
来发出信号。 在我看来,这将使你的代码更加清晰易懂,因为找到一个 因子是一种“例外”条件,它不会损害性能。下面是代码和 使用
NotInvertibleError
用户定义异常的最小修改,并且 还可以纠正一两个错误

导入数学
输入秘密
从集合导入namedtuple
进口交响乐
点=命名双倍(“点”,“x y”)
类NotInvertibleError(异常):
定义初始值(自身,值):
自我价值=价值
def mod_反向(a,m):
尝试:
返回同向模逆(a,m)
除值错误外:
提高不可逆性错误(a)
def点_有效(P、a、b、P):
O=‘Inf_点’
如果P==O:
返回真值
其他:
返回值(P.y**2-(P.x**3+a*P.x+b))%P==0和0:
持续
返回R
def随机_曲线(N):
尽管如此:
A=秘密。以下为随机数(N)
x=机密。以下为随机数(N)
y=秘密。随机数低于(N)
P=点(x,y)
B=(y**2-x**3-A*x)%N
如果(4*A**3+27*B**2)%N!=0:
返回(A、B、P)
def lenstra(N,B):
尽管如此:
a、 b,P=随机_曲线(N)
尝试:
对于范围(2,B+1)内的i:
Q=点乘以(P,i,a,b,N)
P=Q
不可逆错误除外,如e:
d=数学gcd(e值,N)
如果d
我强烈反对使用异常返回值, 但是对于一些因子分解算法,包括Lenstra的椭圆 特殊情况下的曲线分解,计算逆的失败, 是什么触发了因子的发现,因此 使用少量附加信息传播异常

Traceback (most recent call last):
  File "C:/Users/conta/PycharmProjects/Cryptography/Lenstras_Elliptic_Factor.py", line 99, in <module>
Point(x=6653683, y=2444813)
    print(lenstra(8453621,15))
Point(x=1943642, y=922559)
  File "C:/Users/conta/PycharmProjects/Cryptography/Lenstras_Elliptic_Factor.py", line 96, in lenstra
    Q = point_multiply(P,i,a,b,N)
  File "C:/Users/conta/PycharmProjects/Cryptography/Lenstras_Elliptic_Factor.py", line 65, in point_multiply
    R = point_add(R,Q,a,b,p)
  File "C:/Users/conta/PycharmProjects/Cryptography/Lenstras_Elliptic_Factor.py", line 27, in point_add
    if not (point_valid(P,a,b,p) and point_valid(Q,a,b,p)):
  File "C:/Users/conta/PycharmProjects/Cryptography/Lenstras_Elliptic_Factor.py", line 13, in point_valid
    return (P.y**2 - (P.x**3 + a*P.x + b)) % p == 0 and 0 <= P.x < p and 0 <= P.y < p
AttributeError: 'int' object has no attribute 'y'
 if type(Q) == int:
    return Q