34
34
35
35
36
36
G2_cofactor = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109 # noqa: E501
37
- qmod = q ** 2 - 1
37
+ FQ2_order = q ** 2 - 1
38
38
eighth_roots_of_unity = [
39
- FQ2 ([1 , 1 ]) ** ((qmod * k ) // 8 )
39
+ FQ2 ([1 , 1 ]) ** ((FQ2_order * k ) // 8 )
40
40
for k in range (8 )
41
41
]
42
42
@@ -63,27 +63,30 @@ def modular_squareroot(value: int) -> FQP:
63
63
if both solutions have equal imaginary component the value with higher real
64
64
component is favored.
65
65
"""
66
- candidate_squareroot = value ** ((qmod + 8 ) // 16 )
66
+ candidate_squareroot = value ** ((FQ2_order + 8 ) // 16 )
67
67
check = candidate_squareroot ** 2 / value
68
68
if check in eighth_roots_of_unity [::2 ]:
69
69
x1 = candidate_squareroot / eighth_roots_of_unity [eighth_roots_of_unity .index (check ) // 2 ]
70
- x2 = FQ2 ([- x1 .coeffs [0 ], - x1 .coeffs [1 ]])
71
- # x2 = - x2
70
+ x2 = FQ2 ([- x1 .coeffs [0 ], - x1 .coeffs [1 ]]) # x2 = -x1
72
71
return x1 if (x1 .coeffs [1 ], x1 .coeffs [0 ]) > (x2 .coeffs [1 ], x2 .coeffs [0 ]) else x2
73
72
return None
74
73
75
74
76
75
def hash_to_G2 (message : bytes , domain : int ) -> Tuple [FQ2 , FQ2 , FQ2 ]:
77
76
domain_in_bytes = domain .to_bytes (8 , 'big' )
78
- x1 = big_endian_to_int (hash (domain_in_bytes + b'\x01 ' + message ))
79
- x2 = big_endian_to_int (hash (domain_in_bytes + b'\x02 ' + message ))
80
- x_coordinate = FQ2 ([x1 , x2 ]) # x1 + x2 * i
77
+
78
+ # Initial candidate x coordinate
79
+ x_re = big_endian_to_int (hash (domain_in_bytes + b'\x01 ' + message ))
80
+ x_im = big_endian_to_int (hash (domain_in_bytes + b'\x02 ' + message ))
81
+ x_coordinate = FQ2 ([x_re , x_im ]) # x_re + x_im * i
82
+
83
+ # Test candidate y coordinates until a one is found
81
84
while 1 :
82
- x_cubed_plus_b2 = x_coordinate ** 3 + FQ2 ([4 , 4 ])
83
- y_coordinate = modular_squareroot (x_cubed_plus_b2 )
84
- if y_coordinate is not None :
85
+ y_coordinate_squared = x_coordinate ** 3 + FQ2 ([4 , 4 ]) # The curve is y^2 = x^3 + 4(i + 1 )
86
+ y_coordinate = modular_squareroot (y_coordinate_squared )
87
+ if y_coordinate is not None : # Check if quadratic residue found
85
88
break
86
- x_coordinate += FQ2 ([1 , 0 ]) # Add one until we get a quadratic residue
89
+ x_coordinate += FQ2 ([1 , 0 ]) # Add 1 and try again
87
90
88
91
return multiply (
89
92
(x_coordinate , y_coordinate , FQ2 ([1 , 0 ])),
@@ -155,45 +158,49 @@ def privtopub(k: int) -> int:
155
158
return compress_G1 (multiply (G1 , k ))
156
159
157
160
158
- def verify (m : bytes , pub : int , sig : bytes , domain : int ) -> bool :
161
+ def verify (message : bytes , pubkey : int , signature : bytes , domain : int ) -> bool :
159
162
final_exponentiation = final_exponentiate (
160
- pairing (FQP_point_to_FQ2_point (decompress_G2 (sig )), G1 , False ) *
161
- pairing (FQP_point_to_FQ2_point (hash_to_G2 (m , domain )), neg (decompress_G1 (pub )), False )
163
+ pairing (FQP_point_to_FQ2_point (decompress_G2 (signature )), G1 , False ) *
164
+ pairing (
165
+ FQP_point_to_FQ2_point (hash_to_G2 (message , domain )),
166
+ neg (decompress_G1 (pubkey )),
167
+ False
168
+ )
162
169
)
163
170
return final_exponentiation == FQ12 .one ()
164
171
165
172
166
- def aggregate_sigs ( sigs : Sequence [bytes ]) -> Tuple [int , int ]:
173
+ def aggregate_signatures ( signatures : Sequence [bytes ]) -> Tuple [int , int ]:
167
174
o = Z2
168
- for s in sigs :
175
+ for s in signatures :
169
176
o = FQP_point_to_FQ2_point (add (o , decompress_G2 (s )))
170
177
return compress_G2 (o )
171
178
172
179
173
- def aggregate_pubs ( pubs : Sequence [int ]) -> int :
180
+ def aggregate_pubkeys ( pubkeys : Sequence [int ]) -> int :
174
181
o = Z1
175
- for p in pubs :
182
+ for p in pubkeys :
176
183
o = add (o , decompress_G1 (p ))
177
184
return compress_G1 (o )
178
185
179
186
180
- def verify_multiple (pubs : Sequence [int ],
181
- msgs : Sequence [bytes ],
182
- sig : bytes ,
187
+ def verify_multiple (pubkeys : Sequence [int ],
188
+ messages : Sequence [bytes ],
189
+ signature : bytes ,
183
190
domain : int ) -> bool :
184
- len_msgs = len (msgs )
185
- assert len (pubs ) == len_msgs
191
+ len_msgs = len (messages )
192
+ assert len (pubkeys ) == len_msgs
186
193
187
194
o = FQ12 ([1 ] + [0 ] * 11 )
188
- for m in set (msgs ):
195
+ for m_pubs in set (messages ):
189
196
# aggregate the pubs
190
197
group_pub = Z1
191
198
for i in range (len_msgs ):
192
- if msgs [i ] == m :
193
- group_pub = add (group_pub , decompress_G1 (pubs [i ]))
199
+ if messages [i ] == m_pubs :
200
+ group_pub = add (group_pub , decompress_G1 (pubkeys [i ]))
194
201
195
- o *= pairing (hash_to_G2 (m , domain ), group_pub , False )
196
- o *= pairing (decompress_G2 (sig ), neg (G1 ), False )
202
+ o *= pairing (hash_to_G2 (m_pubs , domain ), group_pub , False )
203
+ o *= pairing (decompress_G2 (signature ), neg (G1 ), False )
197
204
198
205
final_exponentiation = final_exponentiate (o )
199
206
return final_exponentiation == FQ12 .one ()
0 commit comments