mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Generalize out the FROST test for signing/signing with an offset
Moves Schnorr signature tests from test_curve to the new test_schnorr, which is more a test_frost. Relevant to https://github.com/serai-dex/serai/issues/9.
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
use std::{marker::PhantomData, rc::Rc, collections::HashMap};
|
||||
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use ff::Field;
|
||||
|
||||
use crate::{Curve, schnorr, algorithm::SchnorrSignature};
|
||||
use crate::{
|
||||
Curve, MultisigKeys, schnorr::{self, SchnorrSignature}, algorithm::{Hram, Schnorr},
|
||||
tests::{key_gen, algorithm_machines, sign as sign_test}
|
||||
};
|
||||
|
||||
pub(crate) fn sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
pub(crate) fn core_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
|
||||
@@ -20,7 +25,7 @@ pub(crate) fn sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
// 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) {
|
||||
pub(crate) fn core_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
assert!(
|
||||
!schnorr::verify::<C>(
|
||||
C::generator_table() * C::F::random(&mut *rng),
|
||||
@@ -30,7 +35,7 @@ pub(crate) fn verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
// Create 5 signatures
|
||||
let mut keys = vec![];
|
||||
let mut challenges = vec![];
|
||||
@@ -71,3 +76,56 @@ pub(crate) fn batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sign_core<R: RngCore + CryptoRng, C: Curve>(
|
||||
rng: &mut R,
|
||||
group_key: C::G,
|
||||
keys: &HashMap<u16, Rc<MultisigKeys<C>>>
|
||||
) {
|
||||
const MESSAGE: &'static [u8] = b"Hello, World!";
|
||||
|
||||
let machines = algorithm_machines(rng, Schnorr::<C, TestHram<C>>::new(), keys);
|
||||
let sig = sign_test(&mut *rng, machines, MESSAGE);
|
||||
assert!(schnorr::verify(group_key, TestHram::<C>::hram(&sig.R, &group_key, MESSAGE), &sig));
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TestHram<C: Curve> {
|
||||
_curve: PhantomData<C>
|
||||
}
|
||||
impl<C: Curve> Hram<C> for TestHram<C> {
|
||||
#[allow(non_snake_case)]
|
||||
fn hram(R: &C::G, A: &C::G, m: &[u8]) -> C::F {
|
||||
C::hash_to_F(b"challenge", &[&C::G_to_bytes(R), &C::G_to_bytes(A), m].concat())
|
||||
}
|
||||
}
|
||||
|
||||
fn sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
let keys = key_gen::<_, C>(&mut *rng);
|
||||
sign_core(rng, keys[&1].group_key(), &keys);
|
||||
}
|
||||
|
||||
fn sign_with_offset<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
let mut keys = key_gen::<_, C>(&mut *rng);
|
||||
let group_key = keys[&1].group_key();
|
||||
|
||||
let offset = C::hash_to_F(b"FROST Test sign_with_offset", b"offset");
|
||||
for i in 1 ..= u16::try_from(keys.len()).unwrap() {
|
||||
keys.insert(i, Rc::new(keys[&i].offset(offset)));
|
||||
}
|
||||
let offset_key = group_key + (C::generator_table() * offset);
|
||||
|
||||
sign_core(rng, offset_key, &keys);
|
||||
}
|
||||
|
||||
pub fn test_schnorr<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
// Test Schnorr signatures work as expected
|
||||
// This is a bit unnecessary, as they should for any valid curve, yet this establishes sanity
|
||||
core_sign::<_, C>(rng);
|
||||
core_verify::<_, C>(rng);
|
||||
core_batch_verify::<_, C>(rng);
|
||||
|
||||
// Test Schnorr signatures under FROST
|
||||
sign::<_, C>(rng);
|
||||
sign_with_offset::<_, C>(rng);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user