Python,Sympy和椭圆曲线

时间:2018-04-17 22:05:36

标签: python python-3.x sympy proof elliptic-curve

我正在尝试在python中编写一个简单的椭圆曲线实现。

所以我有一个简单的Elliptic Curve类:

class EllipticCurve:

    O ="O";

    def __init__(self,a,b):
        self.a = a
        self.b = b

    def __eq__(self, other):
        if isinstance(other, EllipticCurve):
            return self.a == other.a and self.b == other.b
        return NotImplemented

    def __ne__(self, other):
        result = self.__eq__(other)
        if result is NotImplemented:
            return result
        return not result

    @property
    def discriminant(self):
        return 4*a**3+27*b**2

和椭圆曲线上的点类:

class Point:

def __init__(self,ec):
    self.ec = ec
    self = ec.O

def __init__(self,ec,x,y):
    self.ec = ec
    self.x = x
    self.y = y

def __add__(self, other):

    if self.ec != other.ec:
        raise ValueError('These points are on different curves')
    if self == self.ec.O:
        return Point(ec, other.x, other.y)
    if other == self.ec.O:
        return Point(ec, self.x, self.y)
    if self.x==other.x and self.y==-other.y:
        return O
    if self==other:
        k = 3*(self.x**2+self.ec.a)/(2*self.y)
        x3 = k**2-self.x-other.x
        return Point(self.ec, x3,k*(self.x-x3)-self.y)

    k = (other.y-self.y)/(other.x-self.x)
    x3 = k ** 2 - self.x - other.x
    return Point(self.ec, x3, k*(self.x - x3) - self.y)

def __eq__(self, other):
    if isinstance(other, Point):
        return self.x == other.x and self.y == other.y and self.ec == other.ec
    return NotImplemented

def __ne__(self, other):
    result = self.__eq__(other)
    if result is NotImplemented:
        return result
    return not result

def __neg__(self):
    if self==self.ec.O:
        return O
    return Point(E,self.x,-self.y)

def __sub__(self, other):
    return self + -other

虽然我想为它们添加一些功能,但它们可以使用a,b和x,y的实际int值。

然而,我的问题是当我尝试使用sympy并对a,b和x,y使用'symbols'时。 理想情况下,我的目标是计算证明椭圆曲线上3个点的关联属性,即(P + Q)+ R = P +(Q + R)。

现在,我能够得到P + Q的正确结果:

a,b = symbols('a b')
x1,y1 = symbols('x1 y1')
x2,y2 = symbols('x2 y2')
x3,y3 = symbols('x3 y3')

E = EllipticCurve(a,b)
P = Point(E,x1,y1)
Q = Point(E,x2,y2)
R = Point(E,x3,y3)

P+Q

print(simplify((P+Q).x))

输出正确:

  

-x1 - x2 +(y1 - y2)** 2 /(x1 - x2)** 2

此外,如果我这样做:

expr = (P+Q)+R
print(simplify(expr.x))

我也是(我认为)正确的:

  

x1 + x2 - x3 +(y1 + y3 - (y1 - y2)*(2 * x1 + x2 - (y1 - y2)** 2 /(x1 - x2)** 2)/(x1 - x2 ))** 2 /(x1 + x2 + x3 - (y1 - y2)** 2 /(x1 - x2)** 2)** 2 - (y1 - y2)** 2 /(x1 - x2)* * 2

但是,如果我这样做:

expr = (P+Q)+R
expr2 = P+(Q+R)

print(simplify((expr-expr2).x))

这需要永远,如果我尝试:

expr = (P+Q)+R
expr2 = P+(Q+R)

print((expr-expr2).x)

它还返回一个看似合理的表达式,我认为是正确的。 但我需要简化它并返回0来证明expr和expr2是相等的。

有关我做错的任何建议吗?

1 个答案:

答案 0 :(得分:0)

print((expr-expr2).x)

在一般情况下,您可能无法获得0,因为您的结果表达式取决于x1,y1,x2,y2,x3,y3,它们互不依赖,并且这些点不属于相同的椭圆曲线,结果将不会为0。如果尝试使用(expr-expr2).x.subs ...使用不同的args xi,yi,则可以检查(expr-expr2).x是否为零常数。