use core::ops::Deref; use rand_core::OsRng; use zeroize::Zeroizing; use blake2::{digest::typenum::U32, Blake2b}; type Blake2b256 = Blake2b; use group::{ff::Field, Group}; use multiexp::BatchVerifier; use ciphersuite::{Ciphersuite, Ristretto}; use crate::{ SchnorrSignature, aggregate::{SchnorrAggregator, SchnorrAggregate}, }; pub(crate) fn sign() { let private_key = Zeroizing::new(C::random_nonzero_F(&mut OsRng)); let nonce = Zeroizing::new(C::random_nonzero_F(&mut OsRng)); let challenge = C::random_nonzero_F(&mut OsRng); // Doesn't bother to craft an HRAm assert!(SchnorrSignature::::sign(&private_key, nonce, challenge) .verify(C::generator() * private_key.deref(), challenge)); } // The above sign function verifies signing works // This verifies invalid signatures don't pass, using zero signatures, which should effectively be // random pub(crate) fn verify() { assert!(!SchnorrSignature:: { R: C::G::identity(), s: C::F::zero() } .verify(C::generator() * C::random_nonzero_F(&mut OsRng), C::random_nonzero_F(&mut OsRng))); } pub(crate) fn batch_verify() { // Create 5 signatures let mut keys = vec![]; let mut challenges = vec![]; let mut sigs = vec![]; for i in 0 .. 5 { keys.push(Zeroizing::new(C::random_nonzero_F(&mut OsRng))); challenges.push(C::random_nonzero_F(&mut OsRng)); sigs.push(SchnorrSignature::::sign( &keys[i], Zeroizing::new(C::random_nonzero_F(&mut OsRng)), challenges[i], )); } // Batch verify { let mut batch = BatchVerifier::new(5); for (i, sig) in sigs.iter().enumerate() { sig.batch_verify(&mut OsRng, &mut batch, i, C::generator() * keys[i].deref(), challenges[i]); } batch.verify_with_vartime_blame().unwrap(); } // Shift 1 from s from one to another and verify it fails // This test will fail if unique factors aren't used per-signature, hence its inclusion { let mut batch = BatchVerifier::new(5); for (i, mut sig) in sigs.clone().drain(..).enumerate() { if i == 1 { sig.s += C::F::one(); } if i == 2 { sig.s -= C::F::one(); } sig.batch_verify(&mut OsRng, &mut batch, i, C::generator() * keys[i].deref(), challenges[i]); } if let Err(blame) = batch.verify_with_vartime_blame() { assert!((blame == 1) || (blame == 2)); } else { panic!("Batch verification considered malleated signatures valid"); } } } pub(crate) fn aggregate() { // Create 5 signatures let mut keys = vec![]; let mut challenges = vec![]; let mut aggregator = SchnorrAggregator::::new(); for i in 0 .. 5 { keys.push(Zeroizing::new(C::random_nonzero_F(&mut OsRng))); challenges.push(C::random_nonzero_F(&mut OsRng)); aggregator.aggregate( C::generator() * keys[i].deref(), challenges[i], SchnorrSignature::::sign( &keys[i], Zeroizing::new(C::random_nonzero_F(&mut OsRng)), challenges[i], ), ); } let aggregate = aggregator.complete().unwrap(); let aggregate = SchnorrAggregate::::read::<&[u8]>(&mut aggregate.serialize().as_ref()).unwrap(); assert!(aggregate.verify::( keys .iter() .map(|key| C::generator() * key.deref()) .zip(challenges.iter().cloned()) .collect::>() .as_ref() )); } #[test] fn test() { sign::(); verify::(); batch_verify::(); aggregate::(); }