point.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. class Point:
  2. def __init__(self, x, y, curve):
  3. self.curve = curve
  4. self.x = x
  5. self.y = y
  6. def copy(self):
  7. return Point(
  8. curve = self.curve,
  9. x = self.x,
  10. y = self.y,
  11. )
  12. def initXY(self, x, y):
  13. return Point(
  14. curve = self.curve,
  15. x = x,
  16. y = y
  17. )
  18. def pointNull(self):
  19. return Point(
  20. curve = self.curve
  21. )
  22. def isNone(self):
  23. return self.x is None or self.y is None or self.curve is None
  24. def coords(self):
  25. return self.x, self.y
  26. # Вычисление наклона прямой, проходящей через 2 точки эллиптической кривой
  27. def getIncline(self, point):
  28. m = 0
  29. cur = self.curve
  30. x1, y1 = self.coords()
  31. x2, y2 = point.coords()
  32. if self.x == point.x:
  33. # точки равны.
  34. c = self.curve
  35. m = (3 * x1 * x1 + cur.a) * cur.inverseMod(2 * y1, curve.p)
  36. else:
  37. # точки не равны
  38. m = (y1 - y2) * cur.inverseMod(x1 - x2, cur.p)
  39. return m
  40. # Сложение
  41. def __add__(self, point):
  42. #assert is_on_curve(point1)
  43. #assert is_on_curve(point2)
  44. if self.isNone():
  45. return point.copy()
  46. if point.isNone():
  47. return self.copy()
  48. if self.x == point.x and self.y != point.y:
  49. # p + (-p) = 0, симметричная точка
  50. return self.pointNull()
  51. # вычисление наклона прямой, прходящей через 2 точки
  52. m = self.getIncline(point)
  53. # вычисление результирующих координат
  54. rx = m * m - self.x - point.x
  55. ry = self.y + m * (rx - self.x)
  56. return self.initXY(
  57. x = rx % self.curve.p,
  58. y = -ry % self.curve.p,
  59. )
  60. # Унарный -
  61. def __neg__(self):
  62. return self.initXY(
  63. x = self.x,
  64. y = -self.y % self.curve.p,
  65. )
  66. # Сравнение. Точки считаются равны, если они совпадают по оси x
  67. def __eq__(self, point):
  68. # Точки считаются равны при совпадении по оси x
  69. return self.x == point.x
  70. # Умножение
  71. def __mul__(self, k):
  72. #assert is_on_curve(point)
  73. if self.isNone() or self.curve.n == 0:
  74. return Point()
  75. if k < 0:
  76. # k * point = -k * (-point)
  77. return -self * -k
  78. res = Point(
  79. x = 0,
  80. y = 0,
  81. curve = self.curve
  82. )
  83. addend = self.copy()
  84. while k:
  85. if k & 1:
  86. # Add.
  87. res = res + addend
  88. # Double.
  89. addend = addend + addend
  90. k >>= 1
  91. #assert is_on_curve(result)
  92. return res