1
1
from __future__ import absolute_import
2
2
3
+ from typing import (
4
+ cast ,
5
+ )
6
+
7
+ from py_ecc .typing import (
8
+ Field ,
9
+ FQ2Point2D ,
10
+ FQ12Point2D ,
11
+ GeneralPoint ,
12
+ Point2D ,
13
+ )
14
+
3
15
from .bn128_field_elements import (
4
16
field_modulus ,
5
17
FQ ,
23
35
b12 = FQ12 ([3 ] + [0 ] * 11 )
24
36
25
37
# Generator for curve over FQ
26
- G1 = ( FQ ( 1 ), FQ (2 ))
38
+ G1 = cast ( Point2D [ FQ ], ( FQ ( 1 ), FQ (2 ) ))
27
39
# Generator for twisted curve over FQ2
28
40
G2 = (
29
41
FQ2 ([
42
54
43
55
44
56
# Check if a point is the point at infinity
45
- def is_inf (pt ) :
57
+ def is_inf (pt : GeneralPoint [ Field ]) -> bool :
46
58
return pt is None
47
59
48
60
49
61
# Check that a point is on the curve defined by y**2 == x**3 + b
50
- def is_on_curve (pt , b ) :
62
+ def is_on_curve (pt : Point2D [ Field ] , b : Field ) -> bool :
51
63
if is_inf (pt ):
52
64
return True
53
65
x , y = pt
54
66
return y ** 2 - x ** 3 == b
55
67
56
68
57
69
assert is_on_curve (G1 , b )
58
- assert is_on_curve (G2 , b2 )
70
+ assert is_on_curve (cast ( Point2D [ FQ2 ], G2 ) , b2 )
59
71
60
72
61
73
# Elliptic curve doubling
62
- def double (pt ) :
74
+ def double (pt : Point2D [ Field ]) -> Point2D [ Field ] :
63
75
x , y = pt
64
76
m = 3 * x ** 2 / (2 * y )
65
77
newx = m ** 2 - 2 * x
66
78
newy = - m * newx + m * x - y
67
- return newx , newy
79
+ return ( newx , newy )
68
80
69
81
70
82
# Elliptic curve addition
71
- def add (p1 , p2 ):
83
+ def add (p1 : Point2D [Field ],
84
+ p2 : Point2D [Field ]) -> Point2D [Field ]:
72
85
if p1 is None or p2 is None :
73
86
return p1 if p2 is None else p2
74
87
x1 , y1 = p1
@@ -86,7 +99,7 @@ def add(p1, p2):
86
99
87
100
88
101
# Elliptic curve point multiplication
89
- def multiply (pt , n ) :
102
+ def multiply (pt : Point2D [ Field ] , n : int ) -> Point2D [ Field ] :
90
103
if n == 0 :
91
104
return None
92
105
elif n == 1 :
@@ -97,7 +110,7 @@ def multiply(pt, n):
97
110
return add (multiply (double (pt ), int (n // 2 )), pt )
98
111
99
112
100
- def eq (p1 , p2 ) :
113
+ def eq (p1 : GeneralPoint [ Field ] , p2 : GeneralPoint [ Field ]) -> bool :
101
114
return p1 == p2
102
115
103
116
@@ -106,14 +119,14 @@ def eq(p1, p2):
106
119
107
120
108
121
# Convert P => -P
109
- def neg (pt ) :
122
+ def neg (pt : Point2D [ Field ]) -> Point2D [ Field ] :
110
123
if pt is None :
111
124
return None
112
125
x , y = pt
113
126
return (x , - y )
114
127
115
128
116
- def twist (pt ) :
129
+ def twist (pt : FQ2Point2D ) -> FQ12Point2D :
117
130
if pt is None :
118
131
return None
119
132
_x , _y = pt
@@ -122,12 +135,12 @@ def twist(pt):
122
135
ycoeffs = [_y .coeffs [0 ] - _y .coeffs [1 ] * 9 , _y .coeffs [1 ]]
123
136
# Isomorphism into subfield of Z[p] / w**12 - 18 * w**6 + 82,
124
137
# where w**6 = x
125
- nx = FQ12 ([xcoeffs [0 ]] + [0 ] * 5 + [xcoeffs [1 ]] + [0 ] * 5 )
126
- ny = FQ12 ([ycoeffs [0 ]] + [0 ] * 5 + [ycoeffs [1 ]] + [0 ] * 5 )
138
+ nx = FQ12 ([int ( xcoeffs [0 ]) ] + [0 ] * 5 + [int ( xcoeffs [1 ]) ] + [0 ] * 5 )
139
+ ny = FQ12 ([int ( ycoeffs [0 ]) ] + [0 ] * 5 + [int ( ycoeffs [1 ]) ] + [0 ] * 5 )
127
140
# Divide x coord by w**2 and y coord by w**3
128
- return ( nx * w ** 2 , ny * w ** 3 )
141
+ return cast ( FQ12Point2D , ( nx * w ** 2 , ny * w ** 3 ) )
129
142
130
143
131
- G12 = twist (G2 )
144
+ G12 = twist (cast ( FQ2Point2D , G2 ) )
132
145
# Check that the twist creates a point that is on the curve
133
146
assert is_on_curve (G12 , b12 )
0 commit comments