| 
					
				 | 
			
			
				@@ -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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 |