Skip to content

Commit e733f5e

Browse files
resurrect groupby
1 parent fc65be3 commit e733f5e

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

py_ecc/bls/api.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
1+
from operator import (
2+
itemgetter,
3+
)
24
from secrets import (
35
randbelow,
46
)
@@ -7,6 +9,10 @@
79
Sequence,
810
Tuple,
911
)
12+
13+
from cytoolz.itertoolz import (
14+
groupby,
15+
)
1016
from eth_typing import (
1117
BLSPubkey,
1218
BLSSignature,
@@ -86,15 +92,20 @@ def aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
8692
return G1_to_pubkey(o)
8793

8894

89-
def _zip(pubkeys: Sequence[BLSPubkey],
90-
message_hashes: Sequence[Hash32])-> Iterator[Tuple[BLSPubkey, Hash32]]:
95+
def _group_key_by_msg(pubkeys: Sequence[BLSPubkey],
96+
message_hashes: Sequence[Hash32])-> Iterator[Tuple[G1Uncompressed, Hash32]]:
9197
if len(pubkeys) != len(message_hashes):
9298
raise ValidationError(
9399
"len(pubkeys) (%s) should be equal to len(message_hashes) (%s)" % (
94100
len(pubkeys), len(message_hashes)
95101
)
96102
)
97-
return zip(pubkeys, message_hashes)
103+
groups_dict = groupby(itemgetter(1), enumerate(message_hashes))
104+
for message_hash, group in groups_dict.items():
105+
agg_key = Z1
106+
for i, _ in group:
107+
agg_key = add(agg_key, pubkey_to_G1(pubkeys[i]))
108+
yield agg_key, message_hash
98109

99110

100111
def verify_multiple(pubkeys: Sequence[BLSPubkey],
@@ -103,10 +114,10 @@ def verify_multiple(pubkeys: Sequence[BLSPubkey],
103114
domain: int) -> bool:
104115

105116
o = FQ12.one()
106-
for pubkey, message_hash in _zip(pubkeys, message_hashes):
117+
for pubkey, message_hash in _group_key_by_msg(pubkeys, message_hashes):
107118
o *= pairing(
108119
hash_to_G2(message_hash, domain),
109-
pubkey_to_G1(pubkey),
120+
pubkey,
110121
final_exponentiate=False,
111122
)
112123
o *= pairing(signature_to_G2(signature), neg(G1), final_exponentiate=False)
@@ -131,10 +142,10 @@ def verify_multiple_multiple(
131142
random_ints = (1,) + tuple(2**randbelow(64) for _ in signatures[:-1])
132143
o = FQ12.one()
133144
for r_i, (pubkeys, message_hashes) in zip(random_ints, pubkeys_and_messages):
134-
for pubkey, message_hash in _zip(pubkeys, message_hashes):
145+
for pubkey, message_hash in _group_key_by_msg(pubkeys, message_hashes):
135146
o *= pairing(
136147
multiply(hash_to_G2(message_hash, domain), r_i),
137-
pubkey_to_G1(pubkey),
148+
pubkey,
138149
final_exponentiate=False,
139150
)
140151
agg_sig = Z2

0 commit comments

Comments
 (0)