mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
* Add dkg crate * Remove F_len and G_len They're generally no longer used. * Replace hash_to_vec with a provided method around associated type H: Digest Part of trying to minimize this trait so it can be moved elsewhere. Vec, which isn't std, may have been a blocker. * Encrypt secret shares within the FROST library Reduces requirements on callers in order to be correct. * Update usage of Zeroize within FROST * Inline functions in key_gen There was no reason to have them separated as they were. sign probably has the same statement available, yet that isn't the focus right now. * Add a ciphersuite package which provides hash_to_F * Set the Ciphersuite version to something valid * Have ed448 export Scalar/FieldElement/Point at the top level * Move FROST over to Ciphersuite * Correct usage of ff in ciphersuite * Correct documentation handling * Move Schnorr signatures to their own crate * Remove unused feature from schnorr * Fix Schnorr tests * Split DKG into a separate crate * Add serialize to Commitments and SecretShare Helper for buf = vec![]; .write(buf).unwrap(); buf * Move FROST over to the new dkg crate * Update Monero lib to latest FROST * Correct ethereum's usage of features * Add serialize to GeneratorProof * Add serialize helper function to FROST * Rename AddendumSerialize to WriteAddendum * Update processor * Slight fix to processor
73 lines
2.3 KiB
Rust
73 lines
2.3 KiB
Rust
use rand_core::OsRng;
|
|
|
|
use group::{ff::Field, Group};
|
|
|
|
use multiexp::BatchVerifier;
|
|
|
|
use ciphersuite::{Ciphersuite, Ristretto};
|
|
use crate::SchnorrSignature;
|
|
|
|
pub(crate) fn core_sign<C: Ciphersuite>() {
|
|
let private_key = C::random_nonzero_F(&mut OsRng);
|
|
let nonce = C::random_nonzero_F(&mut OsRng);
|
|
let challenge = C::random_nonzero_F(&mut OsRng); // Doesn't bother to craft an HRAm
|
|
assert!(SchnorrSignature::<C>::sign(private_key, nonce, challenge)
|
|
.verify(C::generator() * private_key, 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 core_verify<C: Ciphersuite>() {
|
|
assert!(!SchnorrSignature::<C> { 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 core_batch_verify<C: Ciphersuite>() {
|
|
// Create 5 signatures
|
|
let mut keys = vec![];
|
|
let mut challenges = vec![];
|
|
let mut sigs = vec![];
|
|
for i in 0 .. 5 {
|
|
keys.push(C::random_nonzero_F(&mut OsRng));
|
|
challenges.push(C::random_nonzero_F(&mut OsRng));
|
|
sigs.push(SchnorrSignature::<C>::sign(keys[i], 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], 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], challenges[i]);
|
|
}
|
|
if let Err(blame) = batch.verify_with_vartime_blame() {
|
|
assert!((blame == 1) || (blame == 2));
|
|
} else {
|
|
panic!("Batch verification considered malleated signatures valid");
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test() {
|
|
core_sign::<Ristretto>();
|
|
core_verify::<Ristretto>();
|
|
core_batch_verify::<Ristretto>();
|
|
}
|