1
-
1
+ from operator import (
2
+ itemgetter ,
3
+ )
2
4
from secrets import (
3
5
randbelow ,
4
6
)
7
9
Sequence ,
8
10
Tuple ,
9
11
)
12
+
13
+ from cytoolz .itertoolz import (
14
+ groupby ,
15
+ )
10
16
from eth_typing import (
11
17
BLSPubkey ,
12
18
BLSSignature ,
@@ -86,15 +92,20 @@ def aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
86
92
return G1_to_pubkey (o )
87
93
88
94
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 ]]:
91
97
if len (pubkeys ) != len (message_hashes ):
92
98
raise ValidationError (
93
99
"len(pubkeys) (%s) should be equal to len(message_hashes) (%s)" % (
94
100
len (pubkeys ), len (message_hashes )
95
101
)
96
102
)
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
98
109
99
110
100
111
def verify_multiple (pubkeys : Sequence [BLSPubkey ],
@@ -103,10 +114,10 @@ def verify_multiple(pubkeys: Sequence[BLSPubkey],
103
114
domain : int ) -> bool :
104
115
105
116
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 ):
107
118
o *= pairing (
108
119
hash_to_G2 (message_hash , domain ),
109
- pubkey_to_G1 ( pubkey ) ,
120
+ pubkey ,
110
121
final_exponentiate = False ,
111
122
)
112
123
o *= pairing (signature_to_G2 (signature ), neg (G1 ), final_exponentiate = False )
@@ -131,10 +142,10 @@ def verify_multiple_multiple(
131
142
random_ints = (1 ,) + tuple (2 ** randbelow (64 ) for _ in signatures [:- 1 ])
132
143
o = FQ12 .one ()
133
144
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 ):
135
146
o *= pairing (
136
147
multiply (hash_to_G2 (message_hash , domain ), r_i ),
137
- pubkey_to_G1 ( pubkey ) ,
148
+ pubkey ,
138
149
final_exponentiate = False ,
139
150
)
140
151
agg_sig = Z2
0 commit comments