繁体   English   中英

如何在python中添加椭圆曲线点?

[英]How to add elliptic curve points in python?

我正在尝试实现一个简单的椭圆曲线加密程序,但我无法得到预期的 output 加倍并添加点P直到12P 。曲线方程是y^2 = x^3 +ax + b mod p 根据这个网站3P = [10, 6]P = [5, 1]而我得到3p = [10, 5] 我使用的方程式可以在Wikipedia上找到。

P = [5, 1]
prime = 17
a = 2
b = 2

def gcdExtended(a, b):
     if a == 0:
          return b, 0, 1
     gcd, x1, y1 = gcdExtended(b % a, a)
     x = y1 - (b // a) * x1
     y = x1
     return gcd, x, y

def double_point(point: list):
     x = point[0]
     y = point[1]

     s = ((3*(x**2)+a) * (gcdExtended(2*y, prime)[1])) % prime

     newx = (s**2 - x - x) % prime
     newy = (s * (x - newx) - y) % prime

     return [newx, newy]

def add_points(P: list, Q: list):
     x1 = P[0]
     y1 = P[1]
     x2 = Q[0]
     y2 = Q[1]

     s = ((y2 - y1) * ((gcdExtended(x2-x1, prime))[1] % prime)) % prime

     newx = (s**2 - x1 - x2) % prime
     newy = (s * (x1 - newx) - y1) % prime

     return [newx, newy]

Q = P
index = 2
while True:
     if Q[0] == P[0] and Q[1] == P[1]:
          print("doubling")
          Q = double_point(P)
     else:
          print("adding")
          Q = add_points(Q, P)

     if index == 12 :
          break

     print(f"{index}P = {Q}")
     index += 1

如果点[5,1]依次相加,得到如下序列:

 1P = [ 5,  1]          
 2P = [ 6,  3]
 3P = [10,  6]
 4P = [ 3,  1]
 5P = [ 9, 16]
 6P = [16, 13]
 7P = [ 0,  6]
 8P = [13,  7]
 9P = [ 7,  6]
10P = [ 7, 11]
11P = [13, 10]
12P = [ 0, 11]
13P = [16,  4]
14P = [ 9,  1]
15P = [ 3, 16]
16P = [10, 11]
17P = [ 6, 14]
18P = [ 5, 16]
19P = point at infinity

这可以验证例如here

发布代码中的问题是确定模逆的方法gcdExtended(a, b)仅对正数ab有效。 虽然在double_pointadd_points b的值为prime ( = 17 > 0 ), a可以取负值。

gcdExtended通常为负a返回错误值:

  • 5 或 -12 的模逆是 7:5 x 7 mod17 = 35 mod17 = 1 和 7 x (-12) mod17 = -84 mod17 = 85 mod17 = 1。
  • 这些值的gcdExtended返回: gcdExtended(5, 17)[1] = 7 (为真)和gcdExtended(-12, 17)[1] = -7 (为假)。

要允许a负值,例如可以定义以下方法,请参见此处

def sign(x): 
    return 1 if x >= 0 else -1

def gcdExtendedGeneralized(a, b):
    gcd, x1, y1 = gcdExtended(abs(a), b)
    return gcd, (sign(a) * x1) % b, y1 % b

gcdExtendedgcdExtendedGeneralized中将double_point替换为add_points可以提供正确的值(请注意,当前实现不考虑无穷远点)。

您在add_points中交换了PQ 在计算 s 时还有一个小的简化:

def add_points(P: list, Q: list):
    x1 = P[0]
    y1 = P[1]
    x2 = Q[0]
    y2 = Q[1]

    #s = ((y2 - y1) * ((gcdExtended(x2-x1, prime))[1] % prime)) % prime
    s = (y2-y1) * (gcdExtended(x2-x1, prime)[1] % prime)

    newx = (s**2 - x1 - x2) % prime
    newy = (s * (x1 - newx) - y1) % prime

    return [newx, newy]

Q = P
index = 2
while True:
    if Q[0] == P[0] and Q[1] == P[1]:
        print("doubling")
        Q = double_point(P)
    else:
        print("adding")
        Q = add_points(P, Q)

    if index == 12 :
        break

    print(f"{index}P = {Q}")
    index += 1

这导致

doubling
2P = [6, 3]
adding
3P = [10, 6]
adding
4P = [3, 1]
adding
5P = [9, 16]
adding
6P = [16, 13]
adding
7P = [0, 6]
adding
8P = [13, 8]
adding
9P = [8, 7]
adding
10P = [8, 10]
adding
11P = [13, 9]
adding

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM