w3f_bls/
single_pop_aggregator.rs1use ark_ff::Zero;
38
39use super::verifiers::{
40 verify_using_aggregated_auxiliary_public_keys, verify_with_distinct_messages,
41};
42use super::*;
43
44use digest::DynDigest;
45
46use core::iter::once;
84
85use double::PublicKeyInSignatureGroup;
86use single::PublicKey;
87
88#[derive(Clone)]
89pub struct SignatureAggregatorAssumingPoP<E: EngineBLS> {
90 message: Message,
91 aggregated_publickey: PublicKey<E>,
92 signature: Signature<E>,
93 aggregated_auxiliary_public_key: PublicKeyInSignatureGroup<E>,
94}
95
96impl<E: EngineBLS> SignatureAggregatorAssumingPoP<E> {
97 pub fn new(message: Message) -> SignatureAggregatorAssumingPoP<E> {
98 SignatureAggregatorAssumingPoP {
99 message: message,
100 aggregated_publickey: PublicKey(E::PublicKeyGroup::zero()),
101 signature: Signature(E::SignatureGroup::zero()),
102 aggregated_auxiliary_public_key: PublicKeyInSignatureGroup(E::SignatureGroup::zero()),
103 }
104 }
105
106 pub fn add_signature(&mut self, signature: &Signature<E>) {
110 self.signature.0 += &signature.0;
111 }
112
113 pub fn add_publickey(&mut self, publickey: &PublicKey<E>) {
118 self.aggregated_publickey.0 += publickey.0;
119 }
120
121 pub fn add_auxiliary_public_key(
123 &mut self,
124 publickey_in_signature_group: &PublicKeyInSignatureGroup<E>,
125 ) {
126 self.aggregated_auxiliary_public_key.0 += publickey_in_signature_group.0;
127 }
128
129 pub fn aggregated_publickey(&self) -> PublicKey<E> {
132 self.aggregated_publickey
133 }
134
135 pub fn verify_using_aggregated_auxiliary_public_keys<
151 RandomOracle: DynDigest + Default + Clone,
152 >(
153 &self,
154 ) -> bool {
155 verify_using_aggregated_auxiliary_public_keys::<E, RandomOracle>(
156 self,
157 true,
158 self.aggregated_auxiliary_public_key.0,
159 )
160 }
161}
162
163impl<'a, E: EngineBLS> Signed for &'a SignatureAggregatorAssumingPoP<E> {
164 type E = E;
165
166 type M = Message;
167 type PKG = PublicKey<Self::E>;
168 type PKnM = ::core::iter::Once<(Message, PublicKey<E>)>;
169
170 fn messages_and_publickeys(self) -> Self::PKnM {
171 once((self.message.clone(), self.aggregated_publickey)) }
173
174 fn signature(&self) -> Signature<E> {
175 self.signature
176 }
177
178 fn verify(self) -> bool {
179 verify_with_distinct_messages(self, true)
185 }
187}
188
189#[cfg(all(test, feature = "std"))]
190mod tests {
191
192 use crate::EngineBLS;
193 use crate::Keypair;
194 use crate::Message;
195 use crate::TinyBLS;
196 use crate::UsualBLS;
197 use rand::thread_rng;
198 use sha2::Sha256;
199
200 use ark_bls12_377::Bls12_377;
201 use ark_bls12_381::Bls12_381;
202
203 use super::*;
204
205 #[test]
206 fn verify_aggregate_single_message_single_signer() {
207 let good = Message::new(b"ctx", b"test message");
208
209 let mut keypair =
210 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
211 let good_sig0 = keypair.sign(&good);
212 assert!(good_sig0.verify(&good, &keypair.public));
213 }
214
215 #[test]
216 fn verify_aggregate_single_message_multi_signers() {
217 let good = Message::new(b"ctx", b"test message");
218
219 let mut keypair0 =
220 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
221 let good_sig0 = keypair0.sign(&good);
222
223 let mut keypair1 =
224 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
225 let good_sig1 = keypair1.sign(&good);
226
227 let mut aggregated_sigs =
228 SignatureAggregatorAssumingPoP::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::new(good);
229 aggregated_sigs.add_signature(&good_sig0);
230 aggregated_sigs.add_signature(&good_sig1);
231
232 aggregated_sigs.add_publickey(&keypair0.public);
233 aggregated_sigs.add_publickey(&keypair1.public);
234
235 assert!(
236 aggregated_sigs.verify() == true,
237 "good aggregated signature of a single message with multiple key does not verify"
238 );
239 }
240
241 #[test]
242 fn verify_aggregate_single_message_repetative_signers() {
243 let good = Message::new(b"ctx", b"test message");
244
245 let mut keypair =
246 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
247 let good_sig = keypair.sign(&good);
248
249 let mut aggregated_sigs =
250 SignatureAggregatorAssumingPoP::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::new(good);
251 aggregated_sigs.add_signature(&good_sig);
252 aggregated_sigs.add_signature(&good_sig);
253
254 aggregated_sigs.add_publickey(&keypair.public);
255 aggregated_sigs.add_publickey(&keypair.public);
256
257 assert!(
258 aggregated_sigs.verify() == true,
259 "good aggregate of a repetitive signature does not verify"
260 );
261 }
262
263 #[test]
264 fn aggregate_of_signature_of_a_wrong_message_should_not_verify() {
265 let good0 = Message::new(b"ctx", b"Space over Tab");
266 let bad1 = Message::new(b"ctx", b"Tab over Space");
267
268 let mut keypair0 =
269 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
270 let good_sig0 = keypair0.sign(&good0);
271
272 let mut keypair1 =
273 Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
274 let bad_sig1 = keypair1.sign(&bad1);
275
276 let mut aggregated_sigs = SignatureAggregatorAssumingPoP::<
277 UsualBLS<Bls12_381, ark_bls12_381::Config>,
278 >::new(good0);
279 aggregated_sigs.add_signature(&good_sig0);
280 aggregated_sigs.add_signature(&bad_sig1);
281
282 aggregated_sigs.add_publickey(&keypair0.public);
283 aggregated_sigs.add_publickey(&keypair1.public);
284
285 assert!(
286 aggregated_sigs.verify() == false,
287 "aggregated signature of a wrong message should not verify"
288 );
289 }
290
291 #[test]
292 fn test_aggregate_tiny_sigs_and_verify_in_g1() {
293 let message = Message::new(b"ctx", b"test message");
294 let mut keypairs: Vec<_> = (0..3)
295 .into_iter()
296 .map(|_| Keypair::<TinyBLS<Bls12_377, ark_bls12_377::Config>>::generate(thread_rng()))
297 .collect();
298 let pub_keys_in_sig_grp: Vec<PublicKeyInSignatureGroup<TinyBLS377>> = keypairs
299 .iter()
300 .map(|k| k.into_public_key_in_signature_group())
301 .collect();
302
303 let mut aggregator = SignatureAggregatorAssumingPoP::<TinyBLS377>::new(message.clone());
304 let mut aggregated_public_key =
305 PublicKey::<TinyBLS377>(<TinyBLS377 as EngineBLS>::PublicKeyGroup::zero());
306
307 for k in &mut keypairs {
308 aggregator.add_signature(&k.sign(&message));
309 aggregated_public_key.0 += k.public.0;
310 }
311
312 let mut verifier_aggregator = SignatureAggregatorAssumingPoP::<TinyBLS377>::new(message);
313
314 verifier_aggregator.add_signature(&aggregator.signature);
315 verifier_aggregator.add_publickey(&aggregated_public_key);
316
317 for k in &pub_keys_in_sig_grp {
318 verifier_aggregator.add_auxiliary_public_key(k);
319 }
320
321 assert!(
322 verifier_aggregator.verify_using_aggregated_auxiliary_public_keys::<Sha256>(),
323 "verifying with honest auxilary public key should pass"
324 );
325
326 verifier_aggregator
328 .add_auxiliary_public_key(&keypairs[0].into_public_key_in_signature_group());
329 assert!(
330 !verifier_aggregator.verify_using_aggregated_auxiliary_public_keys::<Sha256>(),
331 "verification using non-matching auxilary public key should fail"
332 );
333 }
334}