CuriousStudent

pointpy

Mar 8th, 2023
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.76 KB | None | 0 0
  1. from unittest import TestCase
  2.  
  3. class Point:
  4.  
  5. def __init__(self, x, y, a, b):
  6. self.a = a
  7. self.b = b
  8. self.x = x
  9. self.y = y
  10. if self.x is None and self.y is None:
  11. return
  12.  
  13. # TODO 1 - Implement a check if the point is on the curve.
  14.  
  15. #raise ValueError('({}, {}) is not on the curve'.format(x, y))
  16.  
  17. def __eq__(self, other):
  18. return self.x == other.x and self.y == other.y \
  19. and self.a == other.a and self.b == other.b
  20.  
  21. def __ne__(self, other):
  22. # this should be the inverse of the == operator
  23. return not (self == other)
  24.  
  25. def __repr__(self):
  26. if self.x is None:
  27. return 'Point(infinity)'
  28. elif isinstance(self.x, FieldElement):
  29. return 'Point({},{})_{}_{} FieldElement({})'.format(
  30. self.x.num, self.y.num, self.a.num, self.b.num, self.x.prime)
  31. else:
  32. return 'Point({},{})_{}_{}'.format(self.x, self.y, self.a, self.b)
  33.  
  34. def __add__(self, other):
  35. if self.a != other.a or self.b != other.b:
  36. raise TypeError('Points {}, {} are not on the same curve'.format(self, other))
  37. # Case 0.0: self is the point at infinity, return other
  38. if self.x is None:
  39. return other
  40. # Case 0.1: other is the point at infinity, return self
  41. if other.x is None:
  42. return self
  43.  
  44. # TODO 2 - Implement point add when self.x == other.x and self.y != other.y. Result is point at infinity
  45.  
  46.  
  47.  
  48. # Case 2: self.x ≠ other.x
  49. # Formula (x3,y3)==(x1,y1)+(x2,y2)
  50. # s=(y2-y1)/(x2-x1)
  51. # x3=s**2-x1-x2
  52. # y3=s*(x1-x3)-y1
  53. if self.x != other.x:
  54. s = (other.y - self.y) / (other.x - self.x)
  55. x = s**2 - self.x - other.x
  56. y = s * (self.x - x) - self.y
  57. return self.__class__(x, y, self.a, self.b)
  58.  
  59. # Case 4: if we are tangent to the vertical line,
  60. # we return the point at infinity
  61. # note instead of figuring out what 0 is for each type
  62. # we just use 0 * self.x
  63. if self == other and self.y == 0 * self.x:
  64. return self.__class__(None, None, self.a, self.b)
  65.  
  66.  
  67. # Formula (x3,y3)=(x1,y1)+(x1,y1)
  68. # s=(3*x1**2+a)/(2*y1)
  69. # x3=s**2-2*x1
  70. # y3=s*(x1-x3)-y1
  71. if self == other:
  72. # TODO 3 - Implement point add when self == other
  73.  
  74.  
  75. def __rmul__(self, coefficient):
  76. coef = coefficient
  77. current = self
  78. result = self.__class__(None, None, self.a, self.b)
  79. while coef:
  80. if coef & 1:
  81. result += current
  82. current += current
  83. coef >>= 1
  84. return result
  85.  
  86.  
  87. class PointTest(TestCase):
  88.  
  89. def test_ne(self):
  90. a = Point(x=3, y=-7, a=5, b=7)
  91. b = Point(x=18, y=77, a=5, b=7)
  92. self.assertTrue(a != b)
  93. self.assertFalse(a != a)
  94.  
  95. def test_on_curve(self):
  96. with self.assertRaises(ValueError):
  97. Point(x=-2, y=4, a=5, b=7)
  98. # these should not raise an error
  99. Point(x=3, y=-7, a=5, b=7)
  100. Point(x=18, y=77, a=5, b=7)
  101.  
  102. def test_add0(self):
  103. a = Point(x=None, y=None, a=5, b=7)
  104. b = Point(x=2, y=5, a=5, b=7)
  105. c = Point(x=2, y=-5, a=5, b=7)
  106. self.assertEqual(a + b, b)
  107. self.assertEqual(b + a, b)
  108. self.assertEqual(b + c, a)
  109.  
  110. def test_add1(self):
  111. a = Point(x=3, y=7, a=5, b=7)
  112. b = Point(x=-1, y=-1, a=5, b=7)
  113. self.assertEqual(a + b, Point(x=2, y=-5, a=5, b=7))
  114.  
  115. def test_add2(self):
  116. a = Point(x=-1, y=1, a=5, b=7)
  117. self.assertEqual(a + a, Point(x=18, y=-77, a=5, b=7))
  118.  
  119.  
  120.  
Advertisement
Add Comment
Please, Sign In to add comment