Skip to content

Commit ccc0d94

Browse files
committed
PR feedback and update parameters name
1 parent d2f58b8 commit ccc0d94

File tree

3 files changed

+58
-49
lines changed

3 files changed

+58
-49
lines changed

eth/beacon/aggregation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ def aggregate_votes(bitfield: bytes,
5555
)
5656
)
5757

58-
return bitfield, bls.aggregate_sigs(sigs)
58+
return bitfield, bls.aggregate_signatures(sigs)

eth/utils/bls.py

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434

3535

3636
G2_cofactor = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109 # noqa: E501
37-
qmod = q ** 2 - 1
37+
FQ2_order = q ** 2 - 1
3838
eighth_roots_of_unity = [
39-
FQ2([1, 1]) ** ((qmod * k) // 8)
39+
FQ2([1, 1]) ** ((FQ2_order * k) // 8)
4040
for k in range(8)
4141
]
4242

@@ -63,27 +63,30 @@ def modular_squareroot(value: int) -> FQP:
6363
if both solutions have equal imaginary component the value with higher real
6464
component is favored.
6565
"""
66-
candidate_squareroot = value ** ((qmod + 8) // 16)
66+
candidate_squareroot = value ** ((FQ2_order + 8) // 16)
6767
check = candidate_squareroot ** 2 / value
6868
if check in eighth_roots_of_unity[::2]:
6969
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
7271
return x1 if (x1.coeffs[1], x1.coeffs[0]) > (x2.coeffs[1], x2.coeffs[0]) else x2
7372
return None
7473

7574

7675
def hash_to_G2(message: bytes, domain: int) -> Tuple[FQ2, FQ2, FQ2]:
7776
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
8184
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
8588
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
8790

8891
return multiply(
8992
(x_coordinate, y_coordinate, FQ2([1, 0])),
@@ -155,45 +158,49 @@ def privtopub(k: int) -> int:
155158
return compress_G1(multiply(G1, k))
156159

157160

158-
def verify(m: bytes, pub: int, sig: bytes, domain: int) -> bool:
161+
def verify(message: bytes, pubkey: int, signature: bytes, domain: int) -> bool:
159162
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+
)
162169
)
163170
return final_exponentiation == FQ12.one()
164171

165172

166-
def aggregate_sigs(sigs: Sequence[bytes]) -> Tuple[int, int]:
173+
def aggregate_signatures(signatures: Sequence[bytes]) -> Tuple[int, int]:
167174
o = Z2
168-
for s in sigs:
175+
for s in signatures:
169176
o = FQP_point_to_FQ2_point(add(o, decompress_G2(s)))
170177
return compress_G2(o)
171178

172179

173-
def aggregate_pubs(pubs: Sequence[int]) -> int:
180+
def aggregate_pubkeys(pubkeys: Sequence[int]) -> int:
174181
o = Z1
175-
for p in pubs:
182+
for p in pubkeys:
176183
o = add(o, decompress_G1(p))
177184
return compress_G1(o)
178185

179186

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,
183190
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
186193

187194
o = FQ12([1] + [0] * 11)
188-
for m in set(msgs):
195+
for m_pubs in set(messages):
189196
# aggregate the pubs
190197
group_pub = Z1
191198
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]))
194201

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)
197204

198205
final_exponentiation = final_exponentiate(o)
199206
return final_exponentiation == FQ12.one()

tests/core/bls-utils/test_bls.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
multiply,
1313
sign,
1414
privtopub,
15-
aggregate_sigs,
16-
aggregate_pubs,
15+
aggregate_signatures,
16+
aggregate_pubkeys,
1717
verify,
1818
verify_multiple,
1919
)
@@ -57,37 +57,39 @@ def test_signature_aggregation(msg, privkeys):
5757
domain = 0
5858
sigs = [sign(msg, k, domain=domain) for k in privkeys]
5959
pubs = [privtopub(k) for k in privkeys]
60-
aggsig = aggregate_sigs(sigs)
61-
aggpub = aggregate_pubs(pubs)
60+
aggsig = aggregate_signatures(sigs)
61+
aggpub = aggregate_pubkeys(pubs)
6262
assert verify(msg, aggpub, aggsig, domain=domain)
6363

6464

6565
@pytest.mark.parametrize(
66-
'msg_1, msg_2, privkeys',
66+
'msg_1, msg_2, privkeys_1, privkeys_2',
6767
[
68-
(b'cow', b'wow', [1, 5, 124, 735, 127409812145, 90768492698215092512159, 0]),
68+
(b'cow', b'wow', tuple(range(10)), tuple(range(10))),
69+
(b'cow', b'wow', (0, 1, 2, 3), (4, 5, 6, 7)),
70+
(b'cow', b'wow', (0, 1, 2, 3), (2, 3, 4, 5)),
6971
]
7072
)
71-
def test_multi_aggregation(msg_1, msg_2, privkeys):
73+
def test_multi_aggregation(msg_1, msg_2, privkeys_1, privkeys_2):
7274
domain = 0
73-
sigs_1 = [sign(msg_1, k, domain=domain) for k in privkeys]
7475

75-
pubs_1 = [privtopub(k) for k in privkeys]
76-
aggsig_1 = aggregate_sigs(sigs_1)
77-
aggpub_1 = aggregate_pubs(pubs_1)
76+
sigs_1 = [sign(msg_1, k, domain=domain) for k in privkeys_1]
77+
pubs_1 = [privtopub(k) for k in privkeys_1]
78+
aggsig_1 = aggregate_signatures(sigs_1)
79+
aggpub_1 = aggregate_pubkeys(pubs_1)
7880

79-
sigs_2 = [sign(msg_2, k, domain=domain) for k in privkeys]
80-
pubs_2 = [privtopub(k) for k in privkeys]
81-
aggsig_2 = aggregate_sigs(sigs_2)
82-
aggpub_2 = aggregate_pubs(pubs_2)
81+
sigs_2 = [sign(msg_2, k, domain=domain) for k in privkeys_2]
82+
pubs_2 = [privtopub(k) for k in privkeys_2]
83+
aggsig_2 = aggregate_signatures(sigs_2)
84+
aggpub_2 = aggregate_pubkeys(pubs_2)
8385

8486
msgs = [msg_1, msg_2]
8587
pubs = [aggpub_1, aggpub_2]
86-
aggsig = aggregate_sigs([aggsig_1, aggsig_2])
88+
aggsig = aggregate_signatures([aggsig_1, aggsig_2])
8789

8890
assert verify_multiple(
89-
pubs=pubs,
90-
msgs=msgs,
91-
sig=aggsig,
91+
pubkeys=pubs,
92+
messages=msgs,
93+
signature=aggsig,
9294
domain=domain,
9395
)

0 commit comments

Comments
 (0)