w3f_bls/
multi_pop_aggregator.rs1use core::borrow::Borrow; use std::collections::HashMap;
39
40use ark_ff::Zero;
41
42use super::verifiers::verify_with_distinct_messages;
43use super::*;
44
45use single::PublicKey;
82#[derive(Clone)]
85pub struct MultiMessageSignatureAggregatorAssumingPoP<E: EngineBLS> {
86 messages_n_publickeys: HashMap<Message, PublicKey<E>>,
87 signature: Signature<E>,
88}
89
90impl<E: EngineBLS> MultiMessageSignatureAggregatorAssumingPoP<E> {
91 pub fn new() -> MultiMessageSignatureAggregatorAssumingPoP<E> {
92 MultiMessageSignatureAggregatorAssumingPoP {
93 messages_n_publickeys: HashMap::new(),
94 signature: Signature(E::SignatureGroup::zero()),
95 }
96 }
97
98 pub fn add_signature(&mut self, signature: &Signature<E>) {
103 self.signature.0 += &signature.0;
104 }
105
106 pub fn add_message_n_publickey(&mut self, message: &Message, publickey: &PublicKey<E>) {
111 self.messages_n_publickeys
112 .entry(message.clone())
113 .and_modify(|pk0| pk0.0 += &publickey.0)
114 .or_insert(*publickey);
115 }
116
117 pub fn aggregate<'a, S>(&mut self, signed: &'a S)
119 where
120 &'a S: Signed<E = E>,
121 <&'a S as Signed>::PKG: Borrow<PublicKey<E>>,
122 {
123 let signature = signed.signature();
124 for (message, pubickey) in signed.messages_and_publickeys() {
125 self.add_message_n_publickey(message.borrow(), pubickey.borrow());
126 }
127 self.add_signature(&signature);
128 }
129}
130
131impl<'a, E: EngineBLS> Signed for &'a MultiMessageSignatureAggregatorAssumingPoP<E> {
132 type E = E;
133
134 type M = &'a Message;
135 type PKG = &'a PublicKey<Self::E>;
136 type PKnM = ::std::collections::hash_map::Iter<'a, Message, PublicKey<E>>;
137
138 fn messages_and_publickeys(self) -> Self::PKnM {
139 self.messages_n_publickeys.iter()
140 }
141
142 fn signature(&self) -> Signature<E> {
143 self.signature
144 }
145
146 fn verify(self) -> bool {
147 verify_with_distinct_messages(self, true)
153 }
155}
156
157#[cfg(all(test, feature = "std"))]
158mod tests {
159
160 use crate::Keypair;
161 use crate::Message;
162 use crate::UsualBLS;
163 use rand::thread_rng;
164
165 use ark_bls12_381::Bls12_381;
166
167 use super::*;
168
169 #[test]
170 fn verify_aggregate_single_message_single_signer() {
171 let good = Message::new(b"ctx", b"test message");
172
173 let mut keypair =
174 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
175 let good_sig0 = keypair.sign(&good);
176 assert!(good_sig0.verify(&good, &keypair.public));
177 }
178
179 #[test]
180 fn verify_aggregate_single_message_multi_signers() {
181 let good = Message::new(b"ctx", b"test message");
182
183 let mut keypair0 =
184 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
185 let good_sig0 = keypair0.sign(&good);
186
187 let mut keypair1 =
188 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
189 let good_sig1 = keypair1.sign(&good);
190
191 let mut aggregated_sigs = MultiMessageSignatureAggregatorAssumingPoP::<
192 UsualBLS<Bls12_381, ark_bls12_381::Config>,
193 >::new();
194 aggregated_sigs.add_signature(&good_sig0);
195 aggregated_sigs.add_signature(&good_sig1);
196
197 aggregated_sigs.add_message_n_publickey(&good, &keypair0.public);
198 aggregated_sigs.add_message_n_publickey(&good, &keypair1.public);
199
200 assert!(
201 aggregated_sigs.verify() == true,
202 "good aggregated signature of a single message with multiple key does not verify"
203 );
204 }
205
206 #[test]
207 fn verify_aggregate_multi_messages_single_signer() {
208 let good0 = Message::new(b"ctx", b"Tab over Space");
209 let good1 = Message::new(b"ctx", b"Space over Tab");
210
211 let mut keypair =
212 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
213
214 let good_sig0 = keypair.sign(&good0);
215 let good_sig1 = keypair.sign(&good1);
216
217 let mut aggregated_sigs = MultiMessageSignatureAggregatorAssumingPoP::<
218 UsualBLS<Bls12_381, ark_bls12_381::Config>,
219 >::new();
220 aggregated_sigs.add_signature(&good_sig0);
221 aggregated_sigs.add_signature(&good_sig1);
222
223 aggregated_sigs.add_message_n_publickey(&good0, &keypair.public);
224 aggregated_sigs.add_message_n_publickey(&good1, &keypair.public);
225
226 assert!(
227 aggregated_sigs.verify() == true,
228 "good aggregated signature of multiple messages with a single key does not verify"
229 );
230 }
231
232 #[test]
233 fn verify_aggregate_multi_messages_multi_signers() {
234 let good0 = Message::new(b"ctx", b"in the beginning");
235 let good1 = Message::new(b"ctx", b"there was a flying spaghetti monster");
236
237 let mut keypair0 =
238 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
239 let good_sig0 = keypair0.sign(&good0);
240
241 let mut keypair1 =
242 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
243 let good_sig1 = keypair1.sign(&good1);
244
245 let mut aggregated_sigs = MultiMessageSignatureAggregatorAssumingPoP::<
246 UsualBLS<Bls12_381, ark_bls12_381::Config>,
247 >::new();
248 aggregated_sigs.add_signature(&good_sig0);
249 aggregated_sigs.add_signature(&good_sig1);
250
251 aggregated_sigs.add_message_n_publickey(&good0, &keypair0.public);
252 aggregated_sigs.add_message_n_publickey(&good1, &keypair1.public);
253
254 assert!(
255 aggregated_sigs.verify() == true,
256 "good aggregated signature of multiple messages with multiple keys does not verify"
257 );
258 }
259
260 #[test]
261 fn verify_aggregate_single_message_repetative_signers() {
262 let good = Message::new(b"ctx", b"test message");
263
264 let mut keypair =
265 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
266 let good_sig = keypair.sign(&good);
267
268 let mut aggregated_sigs = MultiMessageSignatureAggregatorAssumingPoP::<
269 UsualBLS<Bls12_381, ark_bls12_381::Config>,
270 >::new();
271 aggregated_sigs.add_signature(&good_sig);
272 aggregated_sigs.add_signature(&good_sig);
273
274 aggregated_sigs.add_message_n_publickey(&good, &keypair.public);
275 aggregated_sigs.add_message_n_publickey(&good, &keypair.public);
276
277 assert!(
278 aggregated_sigs.verify() == true,
279 "good aggregate of a repetitive signature does not verify"
280 );
281 }
282
283 #[test]
284 fn aggregate_of_signature_of_a_wrong_message_should_not_verify() {
285 let good0 = Message::new(b"ctx", b"Space over Tab");
286 let bad1 = Message::new(b"ctx", b"Tab over Space");
287
288 let mut keypair0 =
289 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
290 let good_sig0 = keypair0.sign(&good0);
291
292 let mut keypair1 =
293 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
294 let bad_sig1 = keypair1.sign(&bad1);
295
296 let mut aggregated_sigs = MultiMessageSignatureAggregatorAssumingPoP::<
297 UsualBLS<Bls12_381, ark_bls12_381::Config>,
298 >::new();
299 aggregated_sigs.add_signature(&good_sig0);
300 aggregated_sigs.add_signature(&bad_sig1);
301
302 aggregated_sigs.add_message_n_publickey(&good0, &keypair0.public);
303 aggregated_sigs.add_message_n_publickey(&good0, &keypair1.public);
304
305 assert!(
306 aggregated_sigs.verify() == false,
307 "aggregated signature of a wrong message should not verify"
308 );
309 }
310}