Fix misc compilation errors

This commit is contained in:
Luke Parker
2025-08-18 07:19:40 -04:00
parent 5e60ea9718
commit ceede14f5c
19 changed files with 47 additions and 61 deletions

3
Cargo.lock generated
View File

@@ -8050,6 +8050,7 @@ dependencies = [
"bitcoin", "bitcoin",
"blake2", "blake2",
"ciphersuite", "ciphersuite",
"dkg-musig",
"dockertest", "dockertest",
"frame-system", "frame-system",
"frost-schnorrkel", "frost-schnorrkel",
@@ -8109,6 +8110,7 @@ dependencies = [
"blake2", "blake2",
"borsh", "borsh",
"ciphersuite", "ciphersuite",
"dkg-musig",
"env_logger", "env_logger",
"flexible-transcript", "flexible-transcript",
"frost-schnorrkel", "frost-schnorrkel",
@@ -8480,6 +8482,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bitcoin-serai", "bitcoin-serai",
"blake2",
"borsh", "borsh",
"ciphersuite", "ciphersuite",
"const-hex", "const-hex",

View File

@@ -27,6 +27,7 @@ blake2 = { version = "0.10", default-features = false, features = ["std"] }
transcript = { package = "flexible-transcript", path = "../crypto/transcript", default-features = false, features = ["std", "recommended"] } transcript = { package = "flexible-transcript", path = "../crypto/transcript", default-features = false, features = ["std", "recommended"] }
ciphersuite = { path = "../crypto/ciphersuite", default-features = false, features = ["std"] } ciphersuite = { path = "../crypto/ciphersuite", default-features = false, features = ["std"] }
schnorr = { package = "schnorr-signatures", path = "../crypto/schnorr", default-features = false, features = ["std"] } schnorr = { package = "schnorr-signatures", path = "../crypto/schnorr", default-features = false, features = ["std"] }
dkg-musig = { path = "../crypto/dkg/musig", default-features = false, features = ["std"] }
frost = { package = "modular-frost", path = "../crypto/frost" } frost = { package = "modular-frost", path = "../crypto/frost" }
frost-schnorrkel = { path = "../crypto/schnorrkel" } frost-schnorrkel = { path = "../crypto/schnorrkel" }

View File

@@ -361,8 +361,8 @@ async fn dkg_test() {
assert!(signature.verify( assert!(signature.verify(
&*serai_client::validator_sets::primitives::set_keys_message(&set, &[], &key_pair), &*serai_client::validator_sets::primitives::set_keys_message(&set, &[], &key_pair),
&serai_client::Public( &serai_client::Public(
frost::dkg::musig::musig_key::<Ristretto>( dkg_musig::musig_key_vartime::<Ristretto>(
&serai_client::validator_sets::primitives::musig_context(set.into()), serai_client::validator_sets::primitives::musig_context(set.into()),
&self.spec.validators().into_iter().map(|(validator, _)| validator).collect::<Vec<_>>() &self.spec.validators().into_iter().map(|(validator, _)| validator).collect::<Vec<_>>()
) )
.unwrap() .unwrap()

View File

@@ -67,12 +67,8 @@ use ciphersuite::{
group::{ff::PrimeField, GroupEncoding}, group::{ff::PrimeField, GroupEncoding},
Ciphersuite, Ristretto, Ciphersuite, Ristretto,
}; };
use frost::{ use dkg_musig::musig;
FrostError, use frost::{FrostError, dkg::Participant, ThresholdKeys, sign::*};
dkg::{Participant, musig::musig},
ThresholdKeys,
sign::*,
};
use frost_schnorrkel::Schnorrkel; use frost_schnorrkel::Schnorrkel;
use scale::Encode; use scale::Encode;
@@ -119,7 +115,7 @@ impl<T: DbTxn, C: Encode> SigningProtocol<'_, T, C> {
let algorithm = Schnorrkel::new(b"substrate"); let algorithm = Schnorrkel::new(b"substrate");
let keys: ThresholdKeys<Ristretto> = let keys: ThresholdKeys<Ristretto> =
musig(&musig_context(self.spec.set().into()), self.key, participants) musig(musig_context(self.spec.set().into()), self.key.clone(), participants)
.expect("signing for a set we aren't in/validator present multiple times") .expect("signing for a set we aren't in/validator present multiple times")
.into(); .into();

View File

@@ -37,7 +37,7 @@ pub fn key_gen() -> (HashMap<Participant, ThresholdKeys<Secp256k1>>, PublicKey)
group_key += ProjectivePoint::GENERATOR; group_key += ProjectivePoint::GENERATOR;
} }
for keys in keys.values_mut() { for keys in keys.values_mut() {
*keys = keys.offset(offset); *keys = keys.clone().offset(offset);
} }
let public_key = PublicKey::new(group_key).unwrap(); let public_key = PublicKey::new(group_key).unwrap();

View File

@@ -34,6 +34,7 @@ borsh = { version = "1", default-features = false, features = ["std", "derive",
serde_json = { version = "1", default-features = false, features = ["std"] } serde_json = { version = "1", default-features = false, features = ["std"] }
# Cryptography # Cryptography
blake2 = { version = "0.10", default-features = false, features = ["std"] }
ciphersuite = { path = "../crypto/ciphersuite", default-features = false, features = ["std", "ristretto"] } ciphersuite = { path = "../crypto/ciphersuite", default-features = false, features = ["std", "ristretto"] }
transcript = { package = "flexible-transcript", path = "../crypto/transcript", default-features = false, features = ["std"] } transcript = { package = "flexible-transcript", path = "../crypto/transcript", default-features = false, features = ["std"] }

View File

@@ -10,7 +10,7 @@ use ciphersuite::group::GroupEncoding;
use dkg_pedpop::*; use dkg_pedpop::*;
use frost::{ use frost::{
curve::{Ciphersuite, Ristretto}, curve::{Ciphersuite, Ristretto},
dkg::{DkgError, Participant, ThresholdParams, ThresholdCore, ThresholdKeys}, dkg::{Participant, ThresholdParams, ThresholdKeys},
}; };
use log::info; use log::info;
@@ -54,8 +54,8 @@ impl GeneratedKeysDb {
let mut substrate_keys = vec![]; let mut substrate_keys = vec![];
let mut network_keys = vec![]; let mut network_keys = vec![];
while !keys_ref.is_empty() { while !keys_ref.is_empty() {
substrate_keys.push(ThresholdKeys::new(ThresholdCore::read(&mut keys_ref).unwrap())); substrate_keys.push(ThresholdKeys::read(&mut keys_ref).unwrap());
let mut these_network_keys = ThresholdKeys::new(ThresholdCore::read(&mut keys_ref).unwrap()); let mut these_network_keys = ThresholdKeys::read(&mut keys_ref).unwrap();
N::tweak_keys(&mut these_network_keys); N::tweak_keys(&mut these_network_keys);
network_keys.push(these_network_keys); network_keys.push(these_network_keys);
} }
@@ -65,7 +65,7 @@ impl GeneratedKeysDb {
fn save_keys<N: Network>( fn save_keys<N: Network>(
txn: &mut impl DbTxn, txn: &mut impl DbTxn,
id: &KeyGenId, id: &KeyGenId,
substrate_keys: &[ThresholdCore<Ristretto>], substrate_keys: &[ThresholdKeys<Ristretto>],
network_keys: &[ThresholdKeys<N::Curve>], network_keys: &[ThresholdKeys<N::Curve>],
) { ) {
let mut keys = Zeroizing::new(vec![]); let mut keys = Zeroizing::new(vec![]);
@@ -181,15 +181,19 @@ impl<N: Network, D: Db> KeyGen<N, D> {
) -> ProcessorMessage { ) -> ProcessorMessage {
const SUBSTRATE_KEY_CONTEXT: &str = "substrate"; const SUBSTRATE_KEY_CONTEXT: &str = "substrate";
const NETWORK_KEY_CONTEXT: &str = "network"; const NETWORK_KEY_CONTEXT: &str = "network";
let context = |id: &KeyGenId, key| { let context = |id: &KeyGenId, key| -> [u8; 32] {
// TODO2: Also embed the chain ID/genesis block // TODO2: Also embed the chain ID/genesis block
format!( <blake2::Blake2s256 as blake2::digest::Digest>::digest(
"Serai Key Gen. Session: {:?}, Network: {:?}, Attempt: {}, Key: {}", format!(
id.session, "Serai Key Gen. Session: {:?}, Network: {:?}, Attempt: {}, Key: {}",
N::NETWORK, id.session,
id.attempt, N::NETWORK,
key, id.attempt,
key,
)
.as_bytes(),
) )
.into()
}; };
let rng = |label, id: KeyGenId| { let rng = |label, id: KeyGenId| {
@@ -246,19 +250,10 @@ impl<N: Network, D: Db> KeyGen<N, D> {
match machine.generate_secret_shares(rng, commitments) { match machine.generate_secret_shares(rng, commitments) {
Ok(res) => Ok(res), Ok(res) => Ok(res),
Err(e) => match e { Err(e) => match e {
DkgError::ZeroParameter(_, _) | PedPoPError::InvalidCommitments(i) => {
DkgError::InvalidThreshold(_, _) |
DkgError::InvalidParticipant(_, _) |
DkgError::InvalidSigningSet |
DkgError::InvalidShare { .. } => unreachable!("{e:?}"),
DkgError::InvalidParticipantQuantity(_, _) |
DkgError::DuplicatedParticipant(_) |
DkgError::MissingParticipant(_) => {
panic!("coordinator sent invalid DKG commitments: {e:?}")
}
DkgError::InvalidCommitments(i) => {
Err(ProcessorMessage::InvalidCommitments { id, faulty: i })? Err(ProcessorMessage::InvalidCommitments { id, faulty: i })?
} }
_ => panic!("unknown error: {e:?}"),
}, },
} }
} }
@@ -396,7 +391,7 @@ impl<N: Network, D: Db> KeyGen<N, D> {
m: usize, m: usize,
machine: KeyMachine<C>, machine: KeyMachine<C>,
shares_ref: &mut HashMap<Participant, &[u8]>, shares_ref: &mut HashMap<Participant, &[u8]>,
) -> Result<ThresholdCore<C>, ProcessorMessage> { ) -> Result<ThresholdKeys<C>, ProcessorMessage> {
let params = ThresholdParams::new( let params = ThresholdParams::new(
params.t(), params.t(),
params.n(), params.n(),
@@ -421,17 +416,7 @@ impl<N: Network, D: Db> KeyGen<N, D> {
(match machine.calculate_share(rng, shares) { (match machine.calculate_share(rng, shares) {
Ok(res) => res, Ok(res) => res,
Err(e) => match e { Err(e) => match e {
DkgError::ZeroParameter(_, _) | PedPoPError::InvalidShare { participant, blame } => {
DkgError::InvalidThreshold(_, _) |
DkgError::InvalidParticipant(_, _) |
DkgError::InvalidSigningSet |
DkgError::InvalidCommitments(_) => unreachable!("{e:?}"),
DkgError::InvalidParticipantQuantity(_, _) |
DkgError::DuplicatedParticipant(_) |
DkgError::MissingParticipant(_) => {
panic!("coordinator sent invalid DKG shares: {e:?}")
}
DkgError::InvalidShare { participant, blame } => {
Err(ProcessorMessage::InvalidShare { Err(ProcessorMessage::InvalidShare {
id, id,
accuser: params.i(), accuser: params.i(),
@@ -439,6 +424,7 @@ impl<N: Network, D: Db> KeyGen<N, D> {
blame: Some(blame.map(|blame| blame.serialize())).flatten(), blame: Some(blame.map(|blame| blame.serialize())).flatten(),
})? })?
} }
_ => panic!("unknown error: {e:?}"),
}, },
}) })
.complete(), .complete(),
@@ -468,7 +454,7 @@ impl<N: Network, D: Db> KeyGen<N, D> {
Ok(keys) => keys, Ok(keys) => keys,
Err(msg) => return msg, Err(msg) => return msg,
}; };
let these_network_keys = let mut these_network_keys =
match handle_machine(&mut rng, id, params, m, machines.1, &mut shares_ref) { match handle_machine(&mut rng, id, params, m, machines.1, &mut shares_ref) {
Ok(keys) => keys, Ok(keys) => keys,
Err(msg) => return msg, Err(msg) => return msg,
@@ -487,7 +473,6 @@ impl<N: Network, D: Db> KeyGen<N, D> {
} }
} }
let mut these_network_keys = ThresholdKeys::new(these_network_keys);
N::tweak_keys(&mut these_network_keys); N::tweak_keys(&mut these_network_keys);
substrate_keys.push(these_substrate_keys); substrate_keys.push(these_substrate_keys);
@@ -556,7 +541,6 @@ impl<N: Network, D: Db> KeyGen<N, D> {
blame.clone().and_then(|blame| EncryptionKeyProof::read(&mut blame.as_slice()).ok()); blame.clone().and_then(|blame| EncryptionKeyProof::read(&mut blame.as_slice()).ok());
let substrate_blame = AdditionalBlameMachine::new( let substrate_blame = AdditionalBlameMachine::new(
&mut rand_core::OsRng,
context(&id, SUBSTRATE_KEY_CONTEXT), context(&id, SUBSTRATE_KEY_CONTEXT),
params.n(), params.n(),
substrate_commitment_msgs, substrate_commitment_msgs,
@@ -564,7 +548,6 @@ impl<N: Network, D: Db> KeyGen<N, D> {
.unwrap() .unwrap()
.blame(accuser, accused, substrate_share, substrate_blame); .blame(accuser, accused, substrate_share, substrate_blame);
let network_blame = AdditionalBlameMachine::new( let network_blame = AdditionalBlameMachine::new(
&mut rand_core::OsRng,
context(&id, NETWORK_KEY_CONTEXT), context(&id, NETWORK_KEY_CONTEXT),
params.n(), params.n(),
network_commitment_msgs, network_commitment_msgs,

View File

@@ -648,7 +648,7 @@ impl Network for Bitcoin {
const MAX_OUTPUTS: usize = MAX_OUTPUTS; const MAX_OUTPUTS: usize = MAX_OUTPUTS;
fn tweak_keys(keys: &mut ThresholdKeys<Self::Curve>) { fn tweak_keys(keys: &mut ThresholdKeys<Self::Curve>) {
*keys = tweak_keys(keys); *keys = tweak_keys(keys.clone());
// Also create a scanner to assert these keys, and all expected paths, are usable // Also create a scanner to assert these keys, and all expected paths, are usable
scanner(keys.group_key()); scanner(keys.group_key());
} }

View File

@@ -408,7 +408,7 @@ impl<D: Db> Network for Ethereum<D> {
fn tweak_keys(keys: &mut ThresholdKeys<Self::Curve>) { fn tweak_keys(keys: &mut ThresholdKeys<Self::Curve>) {
while PublicKey::new(keys.group_key()).is_none() { while PublicKey::new(keys.group_key()).is_none() {
*keys = keys.offset(<Secp256k1 as Ciphersuite>::F::ONE); *keys = keys.clone().offset(<Secp256k1 as Ciphersuite>::F::ONE);
} }
} }

View File

@@ -666,7 +666,7 @@ impl Network for Monero {
keys: ThresholdKeys<Self::Curve>, keys: ThresholdKeys<Self::Curve>,
transaction: SignableTransaction, transaction: SignableTransaction,
) -> Result<Self::TransactionMachine, NetworkError> { ) -> Result<Self::TransactionMachine, NetworkError> {
match transaction.0.clone().multisig(&keys) { match transaction.0.clone().multisig(keys) {
Ok(machine) => Ok(machine), Ok(machine) => Ok(machine),
Err(e) => panic!("failed to create a multisig machine for TX: {e}"), Err(e) => panic!("failed to create a multisig machine for TX: {e}"),
} }

View File

@@ -6,7 +6,7 @@ use ciphersuite::group::GroupEncoding;
use frost::{ use frost::{
curve::Ristretto, curve::Ristretto,
Participant, Participant,
dkg::tests::{key_gen, clone_without}, tests::{key_gen, clone_without},
}; };
use sp_application_crypto::{RuntimePublic, sr25519::Public}; use sp_application_crypto::{RuntimePublic, sr25519::Public};

View File

@@ -6,7 +6,7 @@ use ciphersuite::group::GroupEncoding;
use frost::{ use frost::{
curve::Ristretto, curve::Ristretto,
Participant, Participant,
dkg::tests::{key_gen, clone_without}, tests::{key_gen, clone_without},
}; };
use sp_application_crypto::{RuntimePublic, sr25519::Public}; use sp_application_crypto::{RuntimePublic, sr25519::Public};

View File

@@ -6,7 +6,7 @@ use rand_core::{RngCore, OsRng};
use ciphersuite::group::GroupEncoding; use ciphersuite::group::GroupEncoding;
use frost::{ use frost::{
Participant, ThresholdKeys, Participant, ThresholdKeys,
dkg::tests::{key_gen, clone_without}, tests::{key_gen, clone_without},
}; };
use serai_db::{DbTxn, Db, MemDb}; use serai_db::{DbTxn, Db, MemDb};

View File

@@ -4,7 +4,7 @@ use std::collections::HashMap;
use rand_core::OsRng; use rand_core::OsRng;
use ciphersuite::group::GroupEncoding; use ciphersuite::group::GroupEncoding;
use frost::{Participant, dkg::tests::key_gen}; use frost::{Participant, tests::key_gen};
use tokio::time::timeout; use tokio::time::timeout;

View File

@@ -48,6 +48,7 @@ hex = "0.4"
blake2 = "0.10" blake2 = "0.10"
ciphersuite = { path = "../../crypto/ciphersuite", features = ["ristretto"] } ciphersuite = { path = "../../crypto/ciphersuite", features = ["ristretto"] }
dkg-musig = { path = "../../crypto/dkg/musig" }
frost = { package = "modular-frost", path = "../../crypto/frost", features = ["tests"] } frost = { package = "modular-frost", path = "../../crypto/frost", features = ["tests"] }
schnorrkel = { path = "../../crypto/schnorrkel", package = "frost-schnorrkel" } schnorrkel = { path = "../../crypto/schnorrkel", package = "frost-schnorrkel" }

View File

@@ -4,7 +4,7 @@ use rand_core::{RngCore, OsRng};
use zeroize::Zeroizing; use zeroize::Zeroizing;
use ciphersuite::{Ciphersuite, Ristretto}; use ciphersuite::{Ciphersuite, Ristretto};
use frost::dkg::musig::musig; use dkg_musig::musig;
use schnorrkel::Schnorrkel; use schnorrkel::Schnorrkel;
use sp_core::{sr25519::Signature, Pair as PairTrait}; use sp_core::{sr25519::Signature, Pair as PairTrait};
@@ -99,7 +99,7 @@ async fn set_values(serai: &Serai, values: &Values) {
assert_eq!(Ristretto::generator() * secret_key, public_key); assert_eq!(Ristretto::generator() * secret_key, public_key);
let threshold_keys = let threshold_keys =
musig::<Ristretto>(&musig_context(set), &Zeroizing::new(secret_key), &[public_key]).unwrap(); musig::<Ristretto>(musig_context(set), Zeroizing::new(secret_key), &[public_key]).unwrap();
let sig = frost::tests::sign_without_caching( let sig = frost::tests::sign_without_caching(
&mut OsRng, &mut OsRng,

View File

@@ -10,7 +10,7 @@ use sp_core::{
}; };
use ciphersuite::{Ciphersuite, Ristretto}; use ciphersuite::{Ciphersuite, Ristretto};
use frost::dkg::musig::musig; use dkg_musig::musig;
use schnorrkel::Schnorrkel; use schnorrkel::Schnorrkel;
use serai_client::{ use serai_client::{
@@ -46,8 +46,7 @@ pub async fn set_keys(
assert_eq!(Ristretto::generator() * secret_key, pub_keys[i]); assert_eq!(Ristretto::generator() * secret_key, pub_keys[i]);
threshold_keys.push( threshold_keys.push(
musig::<Ristretto>(&musig_context(set.into()), &Zeroizing::new(secret_key), &pub_keys) musig::<Ristretto>(musig_context(set.into()), Zeroizing::new(secret_key), &pub_keys).unwrap(),
.unwrap(),
); );
} }

View File

@@ -112,7 +112,7 @@ pub fn musig_context(set: ValidatorSet) -> [u8; 32] {
const DST: &[u8] = b"ValidatorSets-musig_key"; const DST: &[u8] = b"ValidatorSets-musig_key";
context[.. DST.len()].copy_from_slice(DST); context[.. DST.len()].copy_from_slice(DST);
let set = set.encode(); let set = set.encode();
context[DST.len() .. (DST.len() + set.len())].copy_from_slice(set.len()); context[DST.len() .. (DST.len() + set.len())].copy_from_slice(&set);
context context
} }

View File

@@ -1,3 +1,5 @@
use std::collections::HashMap;
use ciphersuite::{Ciphersuite, Ristretto}; use ciphersuite::{Ciphersuite, Ristretto};
use dockertest::DockerTest; use dockertest::DockerTest;