1-
1+ from operator import (
2+ itemgetter ,
3+ )
24from secrets import (
35 randbelow ,
46)
79 Sequence ,
810 Tuple ,
911)
12+
13+ from cytoolz .itertoolz import (
14+ groupby ,
15+ )
1016from 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
100111def 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