Skip to content

Commit a005da2

Browse files
committed
Refactoring in Naive Form
1 parent 212b193 commit a005da2

27 files changed

+987
-1940
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ chains
5656
# tox/pytest cache
5757
.cache
5858

59+
# mypy
60+
.mypy_cache/
61+
5962
# Test output logs
6063
logs
6164
### JetBrains template

py_ecc/BaseCurve.py

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
from abc import (
2+
abstractmethod,
3+
)
4+
5+
from typing import (
6+
cast,
7+
)
8+
9+
from py_ecc.field_elements import (
10+
FQP,
11+
)
12+
13+
from py_ecc.optimized_field_elements import (
14+
FQP as optimized_FQP,
15+
)
16+
17+
from py_ecc.new_typing import (
18+
Field,
19+
GeneralPoint,
20+
Point2D,
21+
)
22+
from py_ecc.new_typing import (
23+
Optimized_Field,
24+
Optimized_Point2D,
25+
Optimized_Point3D,
26+
)
27+
28+
29+
class BaseCurve:
30+
# Name of the curve can be "bn128" or "bls12_381"
31+
curve_name = None
32+
curve_order = None
33+
# Curve is y**2 = x**3 + b
34+
b = None
35+
# Twisted curve over FQ**2
36+
b2 = None
37+
# Extension curve over FQ**12; same b value as over FQ
38+
b12 = None
39+
# Generator for curve over FQ
40+
G1 = None
41+
# Generator for twisted curve over FQ2
42+
G2 = None
43+
# Generator for twisted curve over FQ12
44+
G12 = None
45+
# Point at infinity over FQ
46+
Z1 = None
47+
# Point at infinity for twisted curve over FQ2
48+
Z2 = None
49+
50+
def __init__(self, curve_properties, curve_name):
51+
self.curve_name = curve_name
52+
self.curve_order = curve_properties[curve_name]["curve_order"]
53+
self.b = curve_properties[curve_name]["b"]
54+
self.b2 = curve_properties[curve_name]["b2"]
55+
self.b12 = curve_properties[curve_name]["b12"]
56+
self.G1 = curve_properties[curve_name]["G1"]
57+
self.G2 = curve_properties[curve_name]["G2"]
58+
self.G12 = self.twist(cast(Point2D[FQP], self.G2))
59+
self.Z1 = curve_properties[curve_name]["Z1"]
60+
self.Z2 = curve_properties[curve_name]["Z2"]
61+
62+
def is_inf(self, pt: GeneralPoint[Field]) -> bool:
63+
"""
64+
Check if a point is the point at infinity
65+
"""
66+
return pt is None
67+
68+
def is_on_curve(self, pt: Point2D[Field], b: Field) -> bool:
69+
"""
70+
Check that a point is on the curve
71+
"""
72+
if self.is_inf(pt):
73+
return True
74+
x, y = pt
75+
return y**2 == x**3 + b
76+
77+
def double(self, pt: Point2D[Field]) -> Point2D[Field]:
78+
"""
79+
Elliptic Curve Doubling (P+P).
80+
"""
81+
x, y = pt
82+
m = (3 * x**2) / (2 * y)
83+
newx = m**2 - 2 * x
84+
newy = -m * newx + m * x - y
85+
return (newx, newy)
86+
87+
def add(self,
88+
p1: Point2D[Field],
89+
p2: Point2D[Field]) -> Point2D[Field]:
90+
"""
91+
Elliptic curve addition.
92+
"""
93+
if p1 is None or p2 is None:
94+
return p1 if p2 is None else p2
95+
x1, y1 = p1
96+
x2, y2 = p2
97+
if x2 == x1 and y2 == y1:
98+
return self.double(p1)
99+
elif x2 == x1:
100+
return None
101+
else:
102+
m = (y2 - y1) / (x2 - x1)
103+
newx = m**2 - x1 - x2
104+
newy = -m * newx + m * x1 - y1
105+
assert newy == (-m * newx + m * x2 - y2)
106+
return (newx, newy)
107+
108+
def multiply(self, pt: Point2D[Field], n: int) -> Point2D[Field]:
109+
"""
110+
Elliptic curve point multiplication.
111+
"""
112+
if n == 0:
113+
return None
114+
elif n == 1:
115+
return pt
116+
elif not n % 2:
117+
# print(n//2)
118+
return self.multiply(self.double(pt), n // 2)
119+
else:
120+
# print(n//2)
121+
return self.add(self.multiply(self.double(pt), n // 2), pt)
122+
123+
def eq(self, p1: GeneralPoint[Field], p2: GeneralPoint[Field]) -> bool:
124+
"""
125+
Check if 2 points are equal.
126+
"""
127+
return p1 == p2
128+
129+
def neg(self, pt: Point2D[Field]) -> Point2D[Field]:
130+
"""
131+
Gives the reflection of point wrt x-axis (P => -P).
132+
"""
133+
if pt is None:
134+
return None
135+
x, y = pt
136+
return (x, -y)
137+
138+
@abstractmethod
139+
def twist(self, pt: Point2D[FQP]) -> Point2D[FQP]:
140+
"""
141+
'Twist' a point in E(FQ2) into a point in E(FQ12)
142+
"""
143+
raise NotImplementedError("Must be implemented by subclasses")
144+
145+
146+
class BaseOptimizedCurve:
147+
# Name of the curve can be "bn128" or "bls12_381"
148+
curve_name = None
149+
curve_order = None
150+
# Curve is y**2 = x**3 + b
151+
b = None
152+
# Twisted curve over FQ**2
153+
b2 = None
154+
# Extension curve over FQ**12; same b value as over FQ
155+
b12 = None
156+
# Generator for curve over FQ
157+
G1 = None
158+
# Generator for twisted curve over FQ2
159+
G2 = None
160+
# Generator for curve over FQ12
161+
G12 = None
162+
# Point at infinity over FQ
163+
Z1 = None
164+
# Point at infinity for twisted curve over FQ2
165+
Z2 = None
166+
167+
def __init__(self, curve_properties, curve_name):
168+
self.curve_name = curve_name
169+
self.curve_order = curve_properties[curve_name]["curve_order"]
170+
self.b = curve_properties[curve_name]["b"]
171+
self.b2 = curve_properties[curve_name]["b2"]
172+
self.b12 = curve_properties[curve_name]["b12"]
173+
self.G1 = curve_properties[curve_name]["G1"]
174+
self.G2 = curve_properties[curve_name]["G2"]
175+
self.G12 = self.twist(cast(Optimized_Point3D[optimized_FQP], self.G2))
176+
self.Z1 = curve_properties[curve_name]["Z1"]
177+
self.Z2 = curve_properties[curve_name]["Z2"]
178+
179+
def is_inf(self, pt: Optimized_Point3D[Optimized_Field]) -> bool:
180+
"""
181+
Check if a point is the point at infinity
182+
"""
183+
return pt[-1] == (type(pt[-1]).zero(self.curve_name))
184+
185+
def is_on_curve(self, pt: Optimized_Point3D[Optimized_Field], b: Field) -> bool:
186+
"""
187+
Check that a point is on the curve defined by y**2 == x**3 + b
188+
"""
189+
if self.is_inf(pt):
190+
return True
191+
x, y, z = pt
192+
return y**2 * z == x**3 + (b * z**3)
193+
194+
def double(self, pt: Optimized_Point3D[Optimized_Field]) -> Optimized_Point3D[Optimized_Field]:
195+
"""
196+
Elliptic curve doubling
197+
"""
198+
x, y, z = pt
199+
W = 3 * x * x
200+
S = y * z
201+
B = x * y * S
202+
H = W * W - 8 * B
203+
S_squared = S * S
204+
newx = 2 * H * S
205+
newy = W * (4 * B - H) - 8 * y * y * S_squared
206+
newz = 8 * S * S_squared
207+
return (newx, newy, newz)
208+
209+
def add(self,
210+
p1: Optimized_Point3D[Optimized_Field],
211+
p2: Optimized_Point3D[Optimized_Field]) -> Optimized_Point3D[Optimized_Field]:
212+
"""
213+
Elliptic curve addition
214+
"""
215+
one, zero = type(p1[0]).one(self.curve_name), type(p1[0]).zero(self.curve_name)
216+
if p1[2] == zero or p2[2] == zero:
217+
return p1 if p2[2] == zero else p2
218+
x1, y1, z1 = p1
219+
x2, y2, z2 = p2
220+
U1 = y2 * z1
221+
U2 = y1 * z2
222+
V1 = x2 * z1
223+
V2 = x1 * z2
224+
if V1 == V2 and U1 == U2:
225+
return self.double(p1)
226+
elif V1 == V2:
227+
return (one, one, zero)
228+
U = U1 - U2
229+
V = V1 - V2
230+
V_squared = V * V
231+
V_squared_times_V2 = V_squared * V2
232+
V_cubed = V * V_squared
233+
W = z1 * z2
234+
A = U * U * W - V_cubed - 2 * V_squared_times_V2
235+
newx = V * A
236+
newy = U * (V_squared_times_V2 - A) - V_cubed * U2
237+
newz = V_cubed * W
238+
return (newx, newy, newz)
239+
240+
def multiply(self,
241+
pt: Optimized_Point3D[Optimized_Field],
242+
n: int) -> Optimized_Point3D[Optimized_Field]:
243+
"""
244+
Elliptic curve point multiplication
245+
"""
246+
if n == 0:
247+
return (
248+
type(pt[0]).one(self.curve_name),
249+
type(pt[0]).one(self.curve_name),
250+
type(pt[0]).zero(self.curve_name)
251+
)
252+
elif n == 1:
253+
return pt
254+
elif not n % 2:
255+
return self.multiply(self.double(pt), n // 2)
256+
else:
257+
return self.add(self.multiply(self.double(pt), int(n // 2)), pt)
258+
259+
def eq(self,
260+
p1: Optimized_Point3D[Optimized_Field],
261+
p2: Optimized_Point3D[Optimized_Field]) -> bool:
262+
"""
263+
Check if 2 points are equal.
264+
"""
265+
x1, y1, z1 = p1
266+
x2, y2, z2 = p2
267+
return x1 * z2 == x2 * z1 and y1 * z2 == y2 * z1
268+
269+
def normalize(self,
270+
pt: Optimized_Point3D[Optimized_Field]) -> Optimized_Point2D[Optimized_Field]:
271+
"""
272+
Convert the Jacobian Point to a normal point
273+
"""
274+
x, y, z = pt
275+
return (x / z, y / z)
276+
277+
def neg(self, pt: Optimized_Point3D[Optimized_Field]) -> Optimized_Point3D[Optimized_Field]:
278+
"""
279+
Gives the reflection of point wrt x-axis (P => -P).
280+
"""
281+
if pt is None:
282+
return None
283+
x, y, z = pt
284+
return (x, -y, z)
285+
286+
@abstractmethod
287+
def twist(self, pt: Optimized_Point3D[optimized_FQP]) -> Optimized_Point3D[optimized_FQP]:
288+
"""
289+
'Twist' a point in E(FQ2) into a point in E(FQ12)
290+
"""
291+
raise NotImplementedError("Must be implemented by subclasses")

py_ecc/bls12_381/__init__.py

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)