|
@@ -2,9 +2,28 @@
|
|
|
class Point:
|
|
|
|
|
|
def __init__(self, x, y, curve):
|
|
|
+ self.curve = curve
|
|
|
self.x = x
|
|
|
self.y = y
|
|
|
- self.curve = curve
|
|
|
+
|
|
|
+ def copy(self):
|
|
|
+ return Point(
|
|
|
+ curve = self.curve,
|
|
|
+ x = self.x,
|
|
|
+ y = self.y,
|
|
|
+ )
|
|
|
+
|
|
|
+ def initXY(self, x, y):
|
|
|
+ return Point(
|
|
|
+ curve = self.curve,
|
|
|
+ x = x,
|
|
|
+ y = y
|
|
|
+ )
|
|
|
+
|
|
|
+ def pointNull(self):
|
|
|
+ return Point(
|
|
|
+ curve = self.curve
|
|
|
+ )
|
|
|
|
|
|
def isNone(self):
|
|
|
return self.x is None or self.y is None or self.curve is None
|
|
@@ -32,34 +51,58 @@ class Point:
|
|
|
#assert is_on_curve(point1)
|
|
|
#assert is_on_curve(point2)
|
|
|
if self.isNone():
|
|
|
- return point
|
|
|
+ return point.copy()
|
|
|
if point.isNone():
|
|
|
- return self
|
|
|
+ return self.copy()
|
|
|
if self.x == point.x and self.y != point.y:
|
|
|
# p + (-p) = 0, симметричная точка
|
|
|
- return Point()
|
|
|
+ return self.pointNull()
|
|
|
# вычисление наклона прямой, прходящей через 2 точки
|
|
|
m = self.getIncline(point)
|
|
|
# вычисление результирующих координат
|
|
|
rx = m * m - self.x - point.x
|
|
|
ry = self.y + m * (rx - self.x)
|
|
|
- return Point(
|
|
|
- curve = self.curve,
|
|
|
+ return self.initXY(
|
|
|
x = rx % self.curve.p,
|
|
|
- y = -ry % self.curve.p,
|
|
|
+ y = -ry % self.curve.p,
|
|
|
)
|
|
|
|
|
|
# Унарный -
|
|
|
def __neg__(self):
|
|
|
- return Point(
|
|
|
- curve = self.curve,
|
|
|
+ return self.initXY(
|
|
|
x = self.x,
|
|
|
- y = -self.y % curve.p,
|
|
|
+ y = -self.y % self.curve.p,
|
|
|
)
|
|
|
|
|
|
- # Сравнение
|
|
|
+ # Сравнение. Точки считаются равны, если они совпадают по оси x
|
|
|
def __eq__(self, point):
|
|
|
# Точки считаются равны при совпадении по оси x
|
|
|
return self.x == point.x
|
|
|
|
|
|
+ # Умножение
|
|
|
+ def __mul__(self, k):
|
|
|
+ #assert is_on_curve(point)
|
|
|
+ if self.isNone() or self.curve.n == 0:
|
|
|
+ return Point()
|
|
|
+
|
|
|
+ if k < 0:
|
|
|
+ # k * point = -k * (-point)
|
|
|
+ return -self * -k
|
|
|
+
|
|
|
+ res = Point(
|
|
|
+ x = 0,
|
|
|
+ y = 0,
|
|
|
+ curve = self.curve
|
|
|
+ )
|
|
|
+ addend = self.copy()
|
|
|
+ while k:
|
|
|
+ if k & 1:
|
|
|
+ # Add.
|
|
|
+ res = res + addend
|
|
|
+ # Double.
|
|
|
+ addend = addend + addend
|
|
|
+ k >>= 1
|
|
|
+ #assert is_on_curve(result)
|
|
|
+ return res
|
|
|
+
|
|
|
|