Skip to content

Commit 6f3382d

Browse files
resurrect groupby
1 parent fc65be3 commit 6f3382d

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

py_ecc/bls/api.py

Lines changed: 22 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,
@@ -30,6 +36,9 @@
3036
pairing,
3137
)
3238

39+
from .typing import (
40+
G1Uncompressed,
41+
)
3342
from .utils import (
3443
G1_to_pubkey,
3544
G2_to_signature,
@@ -86,15 +95,20 @@ def aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
8695
return G1_to_pubkey(o)
8796

8897

89-
def _zip(pubkeys: Sequence[BLSPubkey],
90-
message_hashes: Sequence[Hash32])-> Iterator[Tuple[BLSPubkey, Hash32]]:
98+
def _group_key_by_msg(pubkeys: Sequence[BLSPubkey],
99+
message_hashes: Sequence[Hash32])-> Iterator[Tuple[G1Uncompressed, Hash32]]:
91100
if len(pubkeys) != len(message_hashes):
92101
raise ValidationError(
93102
"len(pubkeys) (%s) should be equal to len(message_hashes) (%s)" % (
94103
len(pubkeys), len(message_hashes)
95104
)
96105
)
97-
return zip(pubkeys, message_hashes)
106+
groups_dict = groupby(itemgetter(1), enumerate(message_hashes))
107+
for message_hash, group in groups_dict.items():
108+
agg_key = Z1
109+
for i, _ in group:
110+
agg_key = add(agg_key, pubkey_to_G1(pubkeys[i]))
111+
yield agg_key, message_hash
98112

99113

100114
def verify_multiple(pubkeys: Sequence[BLSPubkey],
@@ -103,10 +117,10 @@ def verify_multiple(pubkeys: Sequence[BLSPubkey],
103117
domain: int) -> bool:
104118

105119
o = FQ12.one()
106-
for pubkey, message_hash in _zip(pubkeys, message_hashes):
120+
for pubkey, message_hash in _group_key_by_msg(pubkeys, message_hashes):
107121
o *= pairing(
108122
hash_to_G2(message_hash, domain),
109-
pubkey_to_G1(pubkey),
123+
pubkey,
110124
final_exponentiate=False,
111125
)
112126
o *= pairing(signature_to_G2(signature), neg(G1), final_exponentiate=False)
@@ -131,10 +145,10 @@ def verify_multiple_multiple(
131145
random_ints = (1,) + tuple(2**randbelow(64) for _ in signatures[:-1])
132146
o = FQ12.one()
133147
for r_i, (pubkeys, message_hashes) in zip(random_ints, pubkeys_and_messages):
134-
for pubkey, message_hash in _zip(pubkeys, message_hashes):
148+
for pubkey, message_hash in _group_key_by_msg(pubkeys, message_hashes):
135149
o *= pairing(
136150
multiply(hash_to_G2(message_hash, domain), r_i),
137-
pubkey_to_G1(pubkey),
151+
pubkey,
138152
final_exponentiate=False,
139153
)
140154
agg_sig = Z2

0 commit comments

Comments
 (0)