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 ,
30
36
pairing ,
31
37
)
32
38
39
+ from .typing import (
40
+ G1Uncompressed ,
41
+ )
33
42
from .utils import (
34
43
G1_to_pubkey ,
35
44
G2_to_signature ,
@@ -86,15 +95,20 @@ def aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
86
95
return G1_to_pubkey (o )
87
96
88
97
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 ]]:
91
100
if len (pubkeys ) != len (message_hashes ):
92
101
raise ValidationError (
93
102
"len(pubkeys) (%s) should be equal to len(message_hashes) (%s)" % (
94
103
len (pubkeys ), len (message_hashes )
95
104
)
96
105
)
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
98
112
99
113
100
114
def verify_multiple (pubkeys : Sequence [BLSPubkey ],
@@ -103,10 +117,10 @@ def verify_multiple(pubkeys: Sequence[BLSPubkey],
103
117
domain : int ) -> bool :
104
118
105
119
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 ):
107
121
o *= pairing (
108
122
hash_to_G2 (message_hash , domain ),
109
- pubkey_to_G1 ( pubkey ) ,
123
+ pubkey ,
110
124
final_exponentiate = False ,
111
125
)
112
126
o *= pairing (signature_to_G2 (signature ), neg (G1 ), final_exponentiate = False )
@@ -131,10 +145,10 @@ def verify_multiple_multiple(
131
145
random_ints = (1 ,) + tuple (2 ** randbelow (64 ) for _ in signatures [:- 1 ])
132
146
o = FQ12 .one ()
133
147
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 ):
135
149
o *= pairing (
136
150
multiply (hash_to_G2 (message_hash , domain ), r_i ),
137
- pubkey_to_G1 ( pubkey ) ,
151
+ pubkey ,
138
152
final_exponentiate = False ,
139
153
)
140
154
agg_sig = Z2
0 commit comments