class Point: def __init__(self, x, y, curve): self.x = x self.y = y self.curve = curve def isNone(self): return self.x is None or self.y is None or self.curve is None def coords(self): return self.x, self.y # Вычисление наклона прямой, проходящей через 2 точки эллиптической кривой def getIncline(self, point): m = 0 cur = self.curve x1, y1 = self.coords() x2, y2 = point.coords() if self.x == point.x: # точки равны. c = self.curve m = (3 * x1 * x1 + cur.a) * cur.inverseMod(2 * y1, curve.p) else: # точки не равны m = (y1 - y2) * cur.inverseMod(x1 - x2, cur.p) return m # Сложение def __add__(self, point): #assert is_on_curve(point1) #assert is_on_curve(point2) if self.isNone(): return point if point.isNone(): return self if self.x == point.x and self.y != point.y: # p + (-p) = 0, симметричная точка return Point() # вычисление наклона прямой, прходящей через 2 точки m = self.getIncline(point) # вычисление результирующих координат rx = m * m - self.x - point.x ry = self.y + m * (rx - self.x) return Point( curve = self.curve, x = rx % self.curve.p, y = -ry % self.curve.p, ) # Унарный - def __neg__(self): return Point( curve = self.curve, x = self.x, y = -self.y % curve.p, ) # Сравнение def __eq__(self, point): # Точки считаются равны при совпадении по оси x return self.x == point.x