mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Have modular-frost compile again
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -4877,6 +4877,7 @@ dependencies = [
|
|||||||
"dalek-ff-group",
|
"dalek-ff-group",
|
||||||
"digest 0.10.7",
|
"digest 0.10.7",
|
||||||
"dkg",
|
"dkg",
|
||||||
|
"dkg-recovery",
|
||||||
"flexible-transcript",
|
"flexible-transcript",
|
||||||
"hex",
|
"hex",
|
||||||
"minimal-ed448",
|
"minimal-ed448",
|
||||||
|
|||||||
@@ -40,12 +40,14 @@ multiexp = { path = "../multiexp", version = "0.4", default-features = false, fe
|
|||||||
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1", default-features = false, features = ["std"] }
|
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
dkg = { path = "../dkg", version = "0.6", default-features = false, features = ["std"] }
|
dkg = { path = "../dkg", version = "0.6", default-features = false, features = ["std"] }
|
||||||
|
dkg-recovery = { path = "../dkg/recovery", default-features = false, features = ["std"], optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
serde_json = { version = "1", default-features = false, features = ["std"] }
|
serde_json = { version = "1", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
dkg = { path = "../dkg" }
|
dkg = { path = "../dkg", default-features = false, features = ["std"] }
|
||||||
|
dkg-recovery = { path = "../dkg/recovery", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
ed25519 = ["dalek-ff-group", "ciphersuite/ed25519"]
|
ed25519 = ["dalek-ff-group", "ciphersuite/ed25519"]
|
||||||
@@ -56,4 +58,4 @@ p256 = ["ciphersuite/p256"]
|
|||||||
|
|
||||||
ed448 = ["minimal-ed448", "ciphersuite/ed448"]
|
ed448 = ["minimal-ed448", "ciphersuite/ed448"]
|
||||||
|
|
||||||
tests = ["hex", "rand_core/getrandom"]
|
tests = ["hex", "rand_core/getrandom", "dkg-recovery"]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::collections::HashMap;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// Distributed key generation protocol.
|
/// Distributed key generation protocol.
|
||||||
pub use dkg::{self, Participant, ThresholdParams, ThresholdCore, ThresholdKeys, ThresholdView};
|
pub use dkg::{self, Participant, ThresholdParams, ThresholdKeys, ThresholdView};
|
||||||
|
|
||||||
/// Curve trait and provided curves/HRAMs, forming various ciphersuites.
|
/// Curve trait and provided curves/HRAMs, forming various ciphersuites.
|
||||||
pub mod curve;
|
pub mod curve;
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
|
use core::ops::Deref;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use zeroize::{Zeroize, Zeroizing};
|
||||||
use rand_core::{RngCore, CryptoRng};
|
use rand_core::{RngCore, CryptoRng};
|
||||||
|
|
||||||
pub use dkg::tests::{key_gen, musig_key_gen, recover_key};
|
use ciphersuite::{
|
||||||
|
group::ff::{Field, PrimeField},
|
||||||
|
Ciphersuite,
|
||||||
|
};
|
||||||
|
use dkg::Interpolation;
|
||||||
|
pub use dkg_recovery::recover_key;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Curve, Participant, ThresholdKeys, FrostError,
|
Curve, Participant, ThresholdParams, ThresholdKeys, FrostError,
|
||||||
algorithm::{Algorithm, Hram, IetfSchnorr},
|
algorithm::{Algorithm, Hram, IetfSchnorr},
|
||||||
sign::{Writable, PreprocessMachine, SignMachine, SignatureMachine, AlgorithmMachine},
|
sign::{Writable, PreprocessMachine, SignMachine, SignatureMachine, AlgorithmMachine},
|
||||||
};
|
};
|
||||||
@@ -26,6 +33,56 @@ pub const PARTICIPANTS: u16 = 5;
|
|||||||
/// Constant threshold of participants to use when signing.
|
/// Constant threshold of participants to use when signing.
|
||||||
pub const THRESHOLD: u16 = ((PARTICIPANTS * 2) / 3) + 1;
|
pub const THRESHOLD: u16 = ((PARTICIPANTS * 2) / 3) + 1;
|
||||||
|
|
||||||
|
/// Create a key, for testing purposes.
|
||||||
|
pub fn key_gen<R: RngCore + CryptoRng, C: Ciphersuite>(
|
||||||
|
rng: &mut R,
|
||||||
|
) -> HashMap<Participant, ThresholdKeys<C>> {
|
||||||
|
let coefficients: [_; THRESHOLD as usize] =
|
||||||
|
core::array::from_fn(|_| Zeroizing::new(C::F::random(&mut *rng)));
|
||||||
|
|
||||||
|
fn polynomial<F: PrimeField + Zeroize>(
|
||||||
|
coefficients: &[Zeroizing<F>],
|
||||||
|
l: Participant,
|
||||||
|
) -> Zeroizing<F> {
|
||||||
|
let l = F::from(u64::from(u16::from(l)));
|
||||||
|
// This should never be reached since Participant is explicitly non-zero
|
||||||
|
assert!(l != F::ZERO, "zero participant passed to polynomial");
|
||||||
|
let mut share = Zeroizing::new(F::ZERO);
|
||||||
|
for (idx, coefficient) in coefficients.iter().rev().enumerate() {
|
||||||
|
*share += coefficient.deref();
|
||||||
|
if idx != (coefficients.len() - 1) {
|
||||||
|
*share *= l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
share
|
||||||
|
}
|
||||||
|
|
||||||
|
let group_key = C::generator() * *coefficients[0];
|
||||||
|
let mut secret_shares = HashMap::with_capacity(PARTICIPANTS as usize);
|
||||||
|
let mut verification_shares = HashMap::with_capacity(PARTICIPANTS as usize);
|
||||||
|
for i in 1 ..= PARTICIPANTS {
|
||||||
|
let i = Participant::new(i).unwrap();
|
||||||
|
let secret_share = polynomial(&coefficients, i);
|
||||||
|
secret_shares.insert(i, secret_share.clone());
|
||||||
|
verification_shares.insert(i, C::generator() * *secret_share);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut res = HashMap::with_capacity(PARTICIPANTS as usize);
|
||||||
|
for i in 1 ..= PARTICIPANTS {
|
||||||
|
let i = Participant::new(i).unwrap();
|
||||||
|
let keys = ThresholdKeys::new(
|
||||||
|
ThresholdParams::new(THRESHOLD, PARTICIPANTS, i).unwrap(),
|
||||||
|
Interpolation::Lagrange,
|
||||||
|
secret_shares.remove(&i).unwrap(),
|
||||||
|
verification_shares.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(keys.group_key(), group_key);
|
||||||
|
res.insert(i, keys);
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
/// Clone a map without a specific value.
|
/// Clone a map without a specific value.
|
||||||
pub fn clone_without<K: Clone + core::cmp::Eq + core::hash::Hash, V: Clone>(
|
pub fn clone_without<K: Clone + core::cmp::Eq + core::hash::Hash, V: Clone>(
|
||||||
map: &HashMap<K, V>,
|
map: &HashMap<K, V>,
|
||||||
@@ -238,12 +295,6 @@ pub fn test_schnorr<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
|||||||
test_schnorr_with_keys::<_, _, H>(&mut *rng, &keys)
|
test_schnorr_with_keys::<_, _, H>(&mut *rng, &keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test a basic Schnorr signature, yet with MuSig.
|
|
||||||
pub fn test_musig_schnorr<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
|
||||||
let keys = musig_key_gen(&mut *rng);
|
|
||||||
test_schnorr_with_keys::<_, _, H>(&mut *rng, &keys)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test an offset Schnorr signature.
|
/// Test an offset Schnorr signature.
|
||||||
pub fn test_offset_schnorr<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
pub fn test_offset_schnorr<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
||||||
const MSG: &[u8] = b"Hello, World!";
|
const MSG: &[u8] = b"Hello, World!";
|
||||||
@@ -290,7 +341,6 @@ pub fn test_schnorr_blame<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mu
|
|||||||
/// Run a variety of tests against a ciphersuite.
|
/// Run a variety of tests against a ciphersuite.
|
||||||
pub fn test_ciphersuite<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
pub fn test_ciphersuite<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(rng: &mut R) {
|
||||||
test_schnorr::<R, C, H>(rng);
|
test_schnorr::<R, C, H>(rng);
|
||||||
test_musig_schnorr::<R, C, H>(rng);
|
|
||||||
test_offset_schnorr::<R, C, H>(rng);
|
test_offset_schnorr::<R, C, H>(rng);
|
||||||
test_schnorr_blame::<R, C, H>(rng);
|
test_schnorr_blame::<R, C, H>(rng);
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,10 @@ use transcript::{Transcript, RecommendedTranscript};
|
|||||||
|
|
||||||
use ciphersuite::group::{ff::Field, Group, GroupEncoding};
|
use ciphersuite::group::{ff::Field, Group, GroupEncoding};
|
||||||
|
|
||||||
pub use dkg::tests::{key_gen, recover_key};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Curve, Participant, ThresholdView, ThresholdKeys, FrostError,
|
Curve, Participant, ThresholdView, ThresholdKeys, FrostError,
|
||||||
algorithm::Algorithm,
|
algorithm::Algorithm,
|
||||||
tests::{algorithm_machines, sign},
|
tests::{key_gen, algorithm_machines, sign},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use ciphersuite::group::{ff::PrimeField, GroupEncoding};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
curve::Curve,
|
curve::Curve,
|
||||||
Participant, ThresholdCore, ThresholdKeys,
|
Participant, ThresholdKeys,
|
||||||
algorithm::{Hram, IetfSchnorr},
|
algorithm::{Hram, IetfSchnorr},
|
||||||
sign::{
|
sign::{
|
||||||
Writable, Nonce, GeneratorCommitments, NonceCommitments, Commitments, Preprocess,
|
Writable, Nonce, GeneratorCommitments, NonceCommitments, Commitments, Preprocess,
|
||||||
@@ -115,7 +115,7 @@ fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<Participant,
|
|||||||
|
|
||||||
let mut keys = HashMap::new();
|
let mut keys = HashMap::new();
|
||||||
for i in 1 ..= u16::try_from(shares.len()).unwrap() {
|
for i in 1 ..= u16::try_from(shares.len()).unwrap() {
|
||||||
// Manually re-implement the serialization for ThresholdCore to import this data
|
// Manually re-implement the serialization for ThresholdKeys to import this data
|
||||||
let mut serialized = vec![];
|
let mut serialized = vec![];
|
||||||
serialized.extend(u32::try_from(C::ID.len()).unwrap().to_le_bytes());
|
serialized.extend(u32::try_from(C::ID.len()).unwrap().to_le_bytes());
|
||||||
serialized.extend(C::ID);
|
serialized.extend(C::ID);
|
||||||
@@ -128,14 +128,14 @@ fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<Participant,
|
|||||||
serialized.extend(share.to_bytes().as_ref());
|
serialized.extend(share.to_bytes().as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
let these_keys = ThresholdCore::<C>::read::<&[u8]>(&mut serialized.as_ref()).unwrap();
|
let these_keys = ThresholdKeys::<C>::read::<&[u8]>(&mut serialized.as_ref()).unwrap();
|
||||||
assert_eq!(these_keys.params().t(), vectors.threshold);
|
assert_eq!(these_keys.params().t(), vectors.threshold);
|
||||||
assert_eq!(usize::from(these_keys.params().n()), shares.len());
|
assert_eq!(usize::from(these_keys.params().n()), shares.len());
|
||||||
let participant = Participant::new(i).unwrap();
|
let participant = Participant::new(i).unwrap();
|
||||||
assert_eq!(these_keys.params().i(), participant);
|
assert_eq!(these_keys.params().i(), participant);
|
||||||
assert_eq!(these_keys.secret_share().deref(), &shares[usize::from(i - 1)]);
|
assert_eq!(these_keys.secret_share().deref(), &shares[usize::from(i - 1)]);
|
||||||
assert_eq!(hex::encode(these_keys.group_key().to_bytes().as_ref()), vectors.group_key);
|
assert_eq!(hex::encode(these_keys.group_key().to_bytes().as_ref()), vectors.group_key);
|
||||||
keys.insert(participant, ThresholdKeys::new(these_keys));
|
keys.insert(participant, these_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
keys
|
keys
|
||||||
@@ -157,7 +157,7 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||||||
let secret =
|
let secret =
|
||||||
C::read_F::<&[u8]>(&mut hex::decode(&vectors.group_secret).unwrap().as_ref()).unwrap();
|
C::read_F::<&[u8]>(&mut hex::decode(&vectors.group_secret).unwrap().as_ref()).unwrap();
|
||||||
assert_eq!(C::generator() * secret, group_key);
|
assert_eq!(C::generator() * secret, group_key);
|
||||||
assert_eq!(recover_key(&keys), secret);
|
assert_eq!(*recover_key(&keys.values().cloned().collect::<Vec<_>>()).unwrap(), secret);
|
||||||
|
|
||||||
let mut machines = vec![];
|
let mut machines = vec![];
|
||||||
for i in &vectors.included {
|
for i in &vectors.included {
|
||||||
|
|||||||
Reference in New Issue
Block a user