use ark_ff::Zero;
use super::verifiers::{
verify_using_aggregated_auxiliary_public_keys, verify_with_distinct_messages,
};
use super::*;
use core::iter::once;
use double::PublicKeyInSignatureGroup;
use single::PublicKey;
#[derive(Clone)]
pub struct SignatureAggregatorAssumingPoP<E: EngineBLS> {
message: Message,
aggregated_publickey: PublicKey<E>,
signature: Signature<E>,
aggregated_auxiliary_public_key: PublicKeyInSignatureGroup<E>,
}
impl<E: EngineBLS> SignatureAggregatorAssumingPoP<E> {
pub fn new(message: Message) -> SignatureAggregatorAssumingPoP<E> {
SignatureAggregatorAssumingPoP {
message: message,
aggregated_publickey: PublicKey(E::PublicKeyGroup::zero()),
signature: Signature(E::SignatureGroup::zero()),
aggregated_auxiliary_public_key: PublicKeyInSignatureGroup(E::SignatureGroup::zero()),
}
}
pub fn add_signature(&mut self, signature: &Signature<E>) {
self.signature.0 += &signature.0;
}
pub fn add_publickey(&mut self, publickey: &PublicKey<E>) {
self.aggregated_publickey.0 += publickey.0;
}
pub fn add_auxiliary_public_key(
&mut self,
publickey_in_signature_group: &PublicKeyInSignatureGroup<E>,
) {
self.aggregated_auxiliary_public_key.0 += publickey_in_signature_group.0;
}
pub fn verify_using_aggregated_auxiliary_public_keys(&self) -> bool {
verify_using_aggregated_auxiliary_public_keys(
self,
true,
self.aggregated_auxiliary_public_key.0,
)
}
}
impl<'a, E: EngineBLS> Signed for &'a SignatureAggregatorAssumingPoP<E> {
type E = E;
type M = Message;
type PKG = PublicKey<Self::E>;
type PKnM = ::core::iter::Once<(Message, PublicKey<E>)>;
fn messages_and_publickeys(self) -> Self::PKnM {
once((self.message.clone(), self.aggregated_publickey)) }
fn signature(&self) -> Signature<E> {
self.signature
}
fn verify(self) -> bool {
verify_with_distinct_messages(self, true)
}
}
#[cfg(all(test, feature = "std"))]
mod tests {
use crate::Keypair;
use crate::Message;
use crate::UsualBLS;
use rand::thread_rng;
use ark_bls12_381::Bls12_381;
use super::*;
#[test]
fn verify_aggregate_single_message_single_signer() {
let good = Message::new(b"ctx", b"test message");
let mut keypair =
Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
let good_sig0 = keypair.sign(&good);
assert!(good_sig0.verify(&good, &keypair.public));
}
#[test]
fn verify_aggregate_single_message_multi_signers() {
let good = Message::new(b"ctx", b"test message");
let mut keypair0 =
Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
let good_sig0 = keypair0.sign(&good);
let mut keypair1 =
Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
let good_sig1 = keypair1.sign(&good);
let mut aggregated_sigs =
SignatureAggregatorAssumingPoP::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::new(good);
aggregated_sigs.add_signature(&good_sig0);
aggregated_sigs.add_signature(&good_sig1);
aggregated_sigs.add_publickey(&keypair0.public);
aggregated_sigs.add_publickey(&keypair1.public);
assert!(
aggregated_sigs.verify() == true,
"good aggregated signature of a single message with multiple key does not verify"
);
}
#[test]
fn verify_aggregate_single_message_repetative_signers() {
let good = Message::new(b"ctx", b"test message");
let mut keypair =
Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
let good_sig = keypair.sign(&good);
let mut aggregated_sigs =
SignatureAggregatorAssumingPoP::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::new(good);
aggregated_sigs.add_signature(&good_sig);
aggregated_sigs.add_signature(&good_sig);
aggregated_sigs.add_publickey(&keypair.public);
aggregated_sigs.add_publickey(&keypair.public);
assert!(
aggregated_sigs.verify() == true,
"good aggregate of a repetitive signature does not verify"
);
}
#[test]
fn aggregate_of_signature_of_a_wrong_message_should_not_verify() {
let good0 = Message::new(b"ctx", b"Space over Tab");
let bad1 = Message::new(b"ctx", b"Tab over Space");
let mut keypair0 =
Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
let good_sig0 = keypair0.sign(&good0);
let mut keypair1 =
Keypair::<UsualBLS<Bls12_381, ark_bls12_381::Config>>::generate(thread_rng());
let bad_sig1 = keypair1.sign(&bad1);
let mut aggregated_sigs = SignatureAggregatorAssumingPoP::<
UsualBLS<Bls12_381, ark_bls12_381::Config>,
>::new(good0);
aggregated_sigs.add_signature(&good_sig0);
aggregated_sigs.add_signature(&bad_sig1);
aggregated_sigs.add_publickey(&keypair0.public);
aggregated_sigs.add_publickey(&keypair1.public);
assert!(
aggregated_sigs.verify() == false,
"aggregated signature of a wrong message should not verify"
);
}
}