-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathecc.py
135 lines (109 loc) · 4.8 KB
/
ecc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
from extended_euclid import Extended_Euclid
class Curve:
# Curve constructor
def __init__(self, a, b, p):
self.param_a = a
self.param_b = b
self.param_p = p
class Point:
# Point constructor
def __init__(self, x, y):
self.x = x
self.y = y
self.is_neutral = False
# this point is a neutral element!
if self.x == float('inf') and self.y == float('inf'):
self.is_neutral = True
class Elliptic_Curves:
def __init__(self):
pass
# checks if a proved point is on a provided curve
def check(self, verbosity, point, curve):
if verbosity>=1:
print("[INFO]: Checking if point ({}, {}) is on curve".format(point.x, point.y))
# can't be on the curve if point is neutral element
if point.is_neutral == True:
return 1
# check if point is actually on the curve, return result
y = (point.y * point.y) % curve.param_p
x = (point.x * point.x * point.x + curve.param_a * point.x + curve.param_b) % curve.param_p
if y == x:
return 1
else:
return 0
# doubles a point on a provided curve and returns the new point as a point object
def point_double(self, verbosity, point, curve):
Ex = Extended_Euclid()
# make sure the point is on the curve before proceeding
if self.check(verbosity, point, curve) == 0:
if(verbosity>=0):
print("[ERROR]: Point is not on curve.")
return 0
# first check for neutrality, then double the point & return the new point
if point.is_neutral == True:
new_x = float('inf')
new_y = float('inf')
else:
inv = Ex.eea(verbosity, ((2*point.y)%curve.param_p), curve.param_p)
s = ((3*(point.x*point.x))+curve.param_a)*inv
new_x = (s*s - point.x - point.x) % curve.param_p
new_y = (s*(point.x - new_x)-point.y) % curve.param_p
point3 = Point(new_x, new_y)
return point3
# adds two points together on a provided curve and returns the new point as a point object
def point_add(self, verbosity, point1, point2, curve):
Ex = Extended_Euclid()
k = 1
# make sure the points are on the curve before proceeding
if self.check(verbosity, point1, curve) == 0:
if(verbosity>=0):
print("[ERROR]: Point 1 is not on curve.")
return(0)
if self.check(verbosity, point2, curve) == 0:
if(verbosity>=0):
print("[ERROR]: Point 2 is not on curve.")
return(0)
if(verbosity>=1):
print("[INFO]: Computing ({}, {}) + ({}, {})".format(point1.x, point1.y, point2.x, point2.y))
# first check for neutrality
if point1.is_neutral == True:
new_x = point2.x
new_y = point2.y
k = 0
if point2.is_neutral == True:
new_x = point1.x
new_y = point1.y
k = 0
# result is the neutral element
if point1.x == point2.x and point1.y == (-point2.y)%curve.param_p:
new_x = float('inf')
new_y = float('inf')
k = 0
# points are the same, so use point_double instead
if point1.x == point2.x and point1.y == point2.y:
return self.point_double(verbosity, point1, curve)
# add the points & return the new point
if k != 0:
inv = Ex.eea(verbosity, ((point2.x - point1.x)%curve.param_p), curve.param_p)
s = ((point2.y - point1.y)*inv) % curve.param_p
new_x = (s*s - point1.x - point2.x) % curve.param_p
new_y = (s*(point1.x - new_x)-point1.y) % curve.param_p
point3 = Point(new_x, new_y)
return(point3)
# substracts two points from each other on a provided curve and returns the new point as a point object
def point_substract(self, verbosity, point1, point2, curve):
# are the points on the curve?
if self.check(verbosity, point1, curve) == 0:
print("[ERROR]: Point 1 is not on curve.")
return(0)
if self.check(verbosity, point2, curve) == 0:
print("[ERROR]: Point 2 is not on curve.")
return(0)
if(verbosity>=1):
print("[INFO]: Computing ({}, {}) - ({}, {})".format(point1.x, point1.y, point2.x, point2.y))
# check for neutrality, then modify second point & pass on to point_add
if point2.is_neutral == True:
neg_point2 = point2
else:
neg_point2 = Point(point2.x, (-point2.y % curve.param_p))
return self.point_add(verbosity, point1, neg_point2, curve)