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