Files
serai/crypto/frost/src/tests/schnorr.rs

74 lines
2.2 KiB
Rust
Raw Normal View History

use rand_core::{RngCore, CryptoRng};
use ff::Field;
use crate::{Curve, schnorr, algorithm::SchnorrSignature};
pub(crate) fn sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
let private_key = C::F::random(&mut *rng);
let nonce = C::F::random(&mut *rng);
let challenge = C::F::random(rng); // Doesn't bother to craft an HRAM
assert!(
schnorr::verify::<C>(
C::generator_table() * private_key,
challenge,
&schnorr::sign(private_key, nonce, 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<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
assert!(
!schnorr::verify::<C>(
C::generator_table() * C::F::random(&mut *rng),
C::F::random(rng),
&SchnorrSignature { R: C::generator_table() * C::F::zero(), s: C::F::zero() }
)
);
}
2022-05-25 00:57:00 -04:00
pub(crate) fn batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
// Create 5 signatures
2022-05-25 00:57:00 -04:00
let mut keys = vec![];
let mut challenges = vec![];
let mut sigs = vec![];
for i in 0 .. 5 {
2022-05-25 00:57:00 -04:00
keys.push(C::F::random(&mut *rng));
challenges.push(C::F::random(&mut *rng));
sigs.push(schnorr::sign::<C>(keys[i], C::F::random(&mut *rng), challenges[i]));
}
// Batch verify
let triplets = (0 .. 5).map(
2022-05-25 00:57:00 -04:00
|i| (u16::try_from(i + 1).unwrap(), C::generator_table() * keys[i], challenges[i], sigs[i])
).collect::<Vec<_>>();
schnorr::batch_verify(rng, &triplets).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 triplets = triplets.clone();
triplets[1].3.s += C::F::one();
triplets[2].3.s -= C::F::one();
if let Err(blame) = schnorr::batch_verify(rng, &triplets) {
assert_eq!(blame, 2);
} else {
assert!(false);
}
}
// Make sure a completely invalid signature fails when included
for i in 0 .. 5 {
let mut triplets = triplets.clone();
triplets[i].3.s = C::F::random(&mut *rng);
if let Err(blame) = schnorr::batch_verify(rng, &triplets) {
assert_eq!(blame, u16::try_from(i + 1).unwrap());
} else {
assert!(false);
}
2022-05-25 00:57:00 -04:00
}
}