Compare commits

...

2 Commits

Author SHA1 Message Date
fd8e52b520
adopt BIP-340 for all Secp256k1 networks in EXODUS
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-09-09 03:41:28 +03:00
a6e87c20d6
corrected text for genesis generation message
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-09-09 03:31:24 +03:00
11 changed files with 117 additions and 111 deletions

10
Cargo.lock generated
View File

@ -3363,10 +3363,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "frost-secp256k1" name = "frost-secp256k1-tr"
version = "2.2.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f6974379aee791f2f9e0db47c37d9e4c77ea8a8233e488ae8949ce4c6864e96" checksum = "ff8a25b14bfd5d25deba5edce61ec99c3afb752a1d26630a196bba4cb1c4ca5e"
dependencies = [ dependencies = [
"document-features", "document-features",
"frost-core", "frost-core",
@ -3684,7 +3684,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-exodus" name = "ghost-exodus"
version = "0.0.8" version = "0.0.9"
dependencies = [ dependencies = [
"chacha20poly1305", "chacha20poly1305",
"frame-benchmarking", "frame-benchmarking",
@ -3693,7 +3693,7 @@ dependencies = [
"frame-system", "frame-system",
"frost-core", "frost-core",
"frost-ed25519", "frost-ed25519",
"frost-secp256k1", "frost-secp256k1-tr",
"ghost-helpers", "ghost-helpers",
"ghost-networks", "ghost-networks",
"ghost-traits", "ghost-traits",
@ -4085,7 +4085,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-traits" name = "ghost-traits"
version = "0.4.5" version = "0.4.6"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"frost-core", "frost-core",

View File

@ -89,7 +89,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features =
scale-info = { version = "2.5.0", default-features = false } scale-info = { version = "2.5.0", default-features = false }
subxt = { version = "0.37.0", default-features = false } subxt = { version = "0.37.0", default-features = false }
frost-secp256k1 = { version = "2.2.0", default-features = false, features = ["serialization"] } frost-secp256k1-tr = { version = "2.2.0", default-features = false, features = ["serialization"] }
frost-ed25519 = { version = "2.2.0", default-features = false, features = ["serialization"] } frost-ed25519 = { version = "2.2.0", default-features = false, features = ["serialization"] }
chacha20poly1305 = { version = "0.10.1", default-features = false, features = ["alloc"] } chacha20poly1305 = { version = "0.10.1", default-features = false, features = ["alloc"] }
frost-core = { version = "2.2.0", default-features = false } frost-core = { version = "2.2.0", default-features = false }
@ -345,7 +345,7 @@ curve25519-dalek = { opt-level = 3 }
ed25519-dalek = { opt-level = 3 } ed25519-dalek = { opt-level = 3 }
flate2 = { opt-level = 3 } flate2 = { opt-level = 3 }
frost-core = { opt-level = 3 } frost-core = { opt-level = 3 }
frost-secp256k1 = { opt-level = 3 } frost-secp256k1-tr = { opt-level = 3 }
futures-channel = { opt-level = 3 } futures-channel = { opt-level = 3 }
hash-db = { opt-level = 3 } hash-db = { opt-level = 3 }
hashbrown = { opt-level = 3 } hashbrown = { opt-level = 3 }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-exodus" name = "ghost-exodus"
version = "0.0.8" version = "0.0.9"
description = "Threshold signature generation with DKG included" description = "Threshold signature generation with DKG included"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
@ -28,7 +28,7 @@ sp-core = { workspace = true }
sp-std = { workspace = true } sp-std = { workspace = true }
sp-io = { workspace = true } sp-io = { workspace = true }
frost-secp256k1 = { workspace = true } frost-secp256k1-tr = { workspace = true }
frost-ed25519 = { workspace = true } frost-ed25519 = { workspace = true }
frost-core = { workspace = true } frost-core = { workspace = true }
rand_chacha = { workspace = true } rand_chacha = { workspace = true }
@ -75,7 +75,7 @@ std = [
"sp-core/std", "sp-core/std",
"sp-std/std", "sp-std/std",
"sp-io/std", "sp-io/std",
"frost-secp256k1/std", "frost-secp256k1-tr/std",
"frost-ed25519/std", "frost-ed25519/std",
"frost-core/std", "frost-core/std",
"ghost-traits/std", "ghost-traits/std",

View File

@ -35,7 +35,7 @@ impl DistributedKeyGeneration<AuthIndex, ExodusError> for NetworkCurve {
$field2:ident : $action2:tt, $field2:ident : $action2:tt,
) => {{ ) => {{
let secret_package = <$package_type>::deserialize(secret_package_bytes) let secret_package = <$package_type>::deserialize(secret_package_bytes)
.map_err(|_| ExodusError::DeserializationError)?; .map_err(|_| ExodusError::DeserializationError)?;
let min_signers = *secret_package.min_signers(); let min_signers = *secret_package.min_signers();
@ -64,7 +64,7 @@ impl DistributedKeyGeneration<AuthIndex, ExodusError> for NetworkCurve {
); );
new_secret_package.serialize() new_secret_package.serialize()
.map_err(|_| ExodusError::SerializationError) .map_err(|_| ExodusError::SerializationError)
}}; }};
} }
@ -285,15 +285,18 @@ impl DistributedKeyGeneration<AuthIndex, ExodusError> for NetworkCurve {
_ => ExodusError::Unknown, _ => ExodusError::Unknown,
})?; })?;
let key_package = key_package.normalize_package();
let pubkey_package = pubkey_package.normalize_package();
let key_package_bytes = key_package.serialize() let key_package_bytes = key_package.serialize()
.map_err(|_| ExodusError::SerializationError)?; .map_err(|_| ExodusError::SerializationError)?;
let verifying_shares_merkle_tree = let verifying_shares_merkle_tree =
Self::build_merkle_tree( Self::build_merkle_tree(
pubkey_package.verifying_shares(), pubkey_package.verifying_shares(),
|verifying_share| verifying_share.serialize() |verifying_share| verifying_share.serialize()
.map_err(|_| ExodusError::SerializationError) .map_err(|_| ExodusError::SerializationError)
)?; )?;
let (_, merkle_proof) = let (_, merkle_proof) =
Self::generate_merkle_proof_from_tree( Self::generate_merkle_proof_from_tree(
@ -337,15 +340,4 @@ impl DistributedKeyGeneration<AuthIndex, ExodusError> for NetworkCurve {
.map_err(|_| ExodusError::SerializationError) .map_err(|_| ExodusError::SerializationError)
}) })
} }
fn dkg_decompress_key(
&self,
verifying_key_bytes: &[u8],
) -> Result<Vec<u8>, ExodusError> {
with_ciphersuite!(self, |f| {
let verifying_key = f::VerifyingKey::deserialize(verifying_key_bytes)
.map_err(|_| ExodusError::DeserializationError)?;
decomporess_key(verifying_key)
})
}
} }

View File

@ -17,6 +17,13 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
fn header_bytes_len(&self) -> usize { 5 } fn header_bytes_len(&self) -> usize { 5 }
fn signature_bytes_len(&self) -> usize {
match self {
NetworkCurve::Secp256k1 => 64,
NetworkCurve::Ed25519 => 64,
}
}
fn element_bytes_len(&self) -> usize { fn element_bytes_len(&self) -> usize {
match self { match self {
NetworkCurve::Secp256k1 => 33, NetworkCurve::Secp256k1 => 33,
@ -76,7 +83,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
<InnerGroup as frost_core::Group>::Serialization::try_from(group_commitment_bytes.as_ref()) <InnerGroup as frost_core::Group>::Serialization::try_from(group_commitment_bytes.as_ref())
.map_err(|_| ExodusError::DeserializationError)?; .map_err(|_| ExodusError::DeserializationError)?;
let group_commitment_element = let mut group_commitment_element =
<InnerGroup as frost_core::Group>::deserialize(&group_commitment_serialization) <InnerGroup as frost_core::Group>::deserialize(&group_commitment_serialization)
.map_err(|_| ExodusError::DeserializationError)?; .map_err(|_| ExodusError::DeserializationError)?;
@ -95,15 +102,6 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
let verifying_key = f::VerifyingKey::deserialize(verifying_key_bytes) let verifying_key = f::VerifyingKey::deserialize(verifying_key_bytes)
.map_err(|_| ExodusError::DeserializationError)?; .map_err(|_| ExodusError::DeserializationError)?;
let challenge = frost_core::challenge(
&group_commitment_element,
&verifying_key,
message,
).map_err(|err| match err {
f::Error::SerializationError => ExodusError::SerializationError,
_ => ExodusError::Unknown,
})?;
let hiding_element_serialization = let hiding_element_serialization =
<InnerGroup as frost_core::Group>::Serialization::try_from(nonce_hiding_bytes.as_ref()) <InnerGroup as frost_core::Group>::Serialization::try_from(nonce_hiding_bytes.as_ref())
.map_err(|_| ExodusError::DeserializationError)?; .map_err(|_| ExodusError::DeserializationError)?;
@ -120,9 +118,27 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
<InnerGroup as frost_core::Group>::deserialize(&binding_element_serialization) <InnerGroup as frost_core::Group>::deserialize(&binding_element_serialization)
.map_err(|_| ExodusError::DeserializationError)?; .map_err(|_| ExodusError::DeserializationError)?;
let r_i_element = hiding_element + (binding_element * binding_factor_scalar); let mut r_i_element = hiding_element + (binding_element * binding_factor_scalar);
let group_commitment_wrapper =
frost_core::GroupCommitment::<Ciphersuite>::from_element(group_commitment_element);
if !group_commitment_wrapper.is_normalized() {
r_i_element = -r_i_element;
group_commitment_element = -group_commitment_element;
}
let challenge = <Ciphersuite as frost_core::Ciphersuite>::challenge(
&group_commitment_element,
&verifying_key,
message,
).map_err(|err| match err {
f::Error::SerializationError => ExodusError::SerializationError,
_ => ExodusError::Unknown,
})?;
let commitment_share = let commitment_share =
frost_core::round1::GroupCommitmentShare::from_element(r_i_element); frost_core::round1::GroupCommitmentShare::from_element(r_i_element);
signature_share.verify( signature_share.verify(
identifier, identifier,
@ -259,7 +275,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
let hiding_serialization = <InnerGroup as frost_core::Group>::Serialization::try_from(hiding_bytes.as_ref()).ok()?; let hiding_serialization = <InnerGroup as frost_core::Group>::Serialization::try_from(hiding_bytes.as_ref()).ok()?;
let hiding_nonce = f::round1::NonceCommitment::deserialize(&hiding_serialization).ok()?; let hiding_nonce = f::round1::NonceCommitment::deserialize(&hiding_serialization).ok()?;
let binding_serialization = <InnerGroup as frost_core::Group>::Serialization::try_from((*binding_bytes).as_ref()).ok()?; let binding_serialization = <InnerGroup as frost_core::Group>::Serialization::try_from((*binding_bytes).as_ref()).ok()?;
let binding_nonce = f::round1::NonceCommitment::deserialize(&binding_serialization).ok()?; let binding_nonce = f::round1::NonceCommitment::deserialize(&binding_serialization).ok()?;
let commitments = f::round1::SigningCommitments::new(hiding_nonce, binding_nonce); let commitments = f::round1::SigningCommitments::new(hiding_nonce, binding_nonce);
@ -275,14 +291,14 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
let signing_package = f::SigningPackage::new(signing_commitments, message); let signing_package = f::SigningPackage::new(signing_commitments, message);
let binding_factors_list_wrapped = let binding_factors_list_wrapped =
frost_core::compute_binding_factor_list(&signing_package, &verifying_key, &[]) frost_core::compute_binding_factor_list::<Ciphersuite>(&signing_package, &verifying_key, &[])
.map_err(|err| match err { .map_err(|err| match err {
f::Error::SerializationError => ExodusError::SerializationError, f::Error::SerializationError => ExodusError::SerializationError,
_ => ExodusError::Unknown, _ => ExodusError::Unknown,
})?; })?;
let group_commitment = let group_commitment =
frost_core::compute_group_commitment(&signing_package, &binding_factors_list_wrapped) frost_core::compute_group_commitment::<Ciphersuite>(&signing_package, &binding_factors_list_wrapped)
.map_err(|err| match err { .map_err(|err| match err {
f::Error::IdentityCommitment => ExodusError::IdentityCommitment, f::Error::IdentityCommitment => ExodusError::IdentityCommitment,
f::Error::UnknownIdentifier => ExodusError::UnknownIdentifier, f::Error::UnknownIdentifier => ExodusError::UnknownIdentifier,
@ -306,7 +322,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
}) })
.flatten()?; .flatten()?;
Some((identifier, binding_factor)) Some((identifier, binding_factor))
}) })
.collect::<BTreeMap<_, _>>(); .collect::<BTreeMap<_, _>>();
@ -328,7 +344,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature<AuthIndex, ExodusError> for
&binding_factor_tree, &binding_factor_tree,
authority_index, authority_index,
|binding_factor| { |binding_factor| {
let serialized = <InnerField as frost_core::Field>::serialize(binding_factor); let serialized = <InnerField as frost_core::Field>::serialize(binding_factor);
Ok(serialized.as_ref().to_vec()) Ok(serialized.as_ref().to_vec())
} }
)?; )?;

View File

@ -3,46 +3,53 @@ macro_rules! with_ciphersuite {
($curve:expr, |$alias:ident| $body:block) => { ($curve:expr, |$alias:ident| $body:block) => {
match $curve { match $curve {
NetworkCurve::Secp256k1 => { NetworkCurve::Secp256k1 => {
use k256::elliptic_curve::sec1::ToEncodedPoint; #[allow(unused_imports)]
use frost_secp256k1 as $alias; use frost_secp256k1_tr as $alias;
#[allow(unused_imports)] #[allow(unused_imports)]
use frost_secp256k1::Secp256K1Sha256 as Ciphersuite; use frost_secp256k1_tr::Secp256K1Sha256TR as Ciphersuite;
use $alias::keys::EvenY;
#[allow(dead_code)] #[allow(dead_code)]
fn decomporess_key( trait UniversalNormalizer {
verifying_key: $alias::VerifyingKey, fn normalize_package(self) -> Self;
) -> Result<Vec<u8>, ExodusError> { fn is_normalized(&self) -> bool;
let element = verifying_key.to_element(); }
if element == k256::ProjectivePoint::IDENTITY { impl<T: EvenY> UniversalNormalizer for T {
return Err(ExodusError::InvalidIdentityElement); #[inline]
fn normalize_package(self) -> Self {
self.into_even_y(None)
} }
let mut fixed_serialized = [0; 65]; #[inline]
let serialized_point = element.to_affine().to_encoded_point(false); fn is_normalized(&self) -> bool {
let serialized = serialized_point.as_bytes(); self.has_even_y()
fixed_serialized.copy_from_slice(serialized); }
Ok(fixed_serialized.to_vec())
} }
$body $body
}, },
NetworkCurve::Ed25519 => { NetworkCurve::Ed25519 => {
#[allow(unused_imports)]
use frost_ed25519 as $alias; use frost_ed25519 as $alias;
#[allow(unused_imports)] #[allow(unused_imports)]
use frost_ed25519::Ed25519Sha512 as Ciphersuite; use frost_ed25519::Ed25519Sha512 as Ciphersuite;
#[allow(dead_code)] #[allow(dead_code)]
fn decomporess_key( trait UniversalNormalizer {
verifying_key: $alias::VerifyingKey, fn normalize_package(self) -> Self;
) -> Result<Vec<u8>, ExodusError> { fn is_normalized(&self) -> bool;
verifying_key.serialize().map_err(|err| match err { }
f::Error::SerializationError => ExodusError::SerializationError,
_ => ExodusError::Unknown, impl<T> UniversalNormalizer for T {
}) #[inline]
fn normalize_package(self) -> Self { self }
#[inline]
fn is_normalized(&self) -> bool { true }
} }
$body $body

View File

@ -130,26 +130,17 @@ const fn postcard_varint_len(len: usize) -> usize {
else { 3 } else { 3 }
} }
const fn signature_bytes_len(
element_bytes_len: usize,
scalar_bytes_len: usize,
)-> usize {
let signature_bytes_len = element_bytes_len.saturating_add(scalar_bytes_len);
let signature_vec_prefix = postcard_varint_len(signature_bytes_len);
signature_bytes_len.saturating_add(signature_vec_prefix)
}
const fn round1_package_size( const fn round1_package_size(
commitments_count: usize, commitments_count: usize,
element_bytes_len: usize, element_bytes_len: usize,
scalar_bytes_len: usize, signature_bytes_len: usize,
header_bytes_len: usize header_bytes_len: usize
) -> usize { ) -> usize {
let commitments_bytes_len = commitments_count.saturating_mul(element_bytes_len); let commitments_bytes_len = commitments_count.saturating_mul(element_bytes_len);
let commitment_vec_prefix = postcard_varint_len(commitments_count); let commitment_vec_prefix = postcard_varint_len(commitments_count);
signature_bytes_len(element_bytes_len, scalar_bytes_len) postcard_varint_len(signature_bytes_len)
.saturating_add(signature_bytes_len)
.saturating_add(header_bytes_len) .saturating_add(header_bytes_len)
.saturating_add(commitment_vec_prefix) .saturating_add(commitment_vec_prefix)
.saturating_add(commitments_bytes_len) .saturating_add(commitments_bytes_len)
@ -264,11 +255,12 @@ impl<T: Config> Get<u32> for Round1MaxBytes<T> {
fn get() -> u32 { fn get() -> u32 {
let max_authorities = T::MaxAuthorities::get(); let max_authorities = T::MaxAuthorities::get();
let min_authorities = get_byzantium_quorum_threshold(max_authorities); let min_authorities = get_byzantium_quorum_threshold(max_authorities);
let max_signature_bytes = ELEMENT_MAX_BYTES + SCALAR_MAX_BYTES;
round1_package_size( round1_package_size(
min_authorities as usize, min_authorities as usize,
ELEMENT_MAX_BYTES as usize, ELEMENT_MAX_BYTES as usize,
SCALAR_MAX_BYTES as usize, max_signature_bytes as usize,
HEADER_MAX_BYTES as usize, HEADER_MAX_BYTES as usize,
) as u32 ) as u32
} }
@ -363,10 +355,8 @@ impl<T: Config> Get<u32> for SignatureShareMaxBytes<T> {
pub struct SignatureMaxBytes<T>(sp_std::marker::PhantomData<T>); pub struct SignatureMaxBytes<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> Get<u32> for SignatureMaxBytes<T> { impl<T: Config> Get<u32> for SignatureMaxBytes<T> {
fn get() -> u32 { fn get() -> u32 {
signature_bytes_len( let signature_max_bytes = ELEMENT_MAX_BYTES + SCALAR_MAX_BYTES;
ELEMENT_MAX_BYTES as usize, postcard_varint_len(signature_max_bytes as usize) as u32
SCALAR_MAX_BYTES as usize,
) as u32
} }
} }
@ -2533,6 +2523,7 @@ impl<T: Config> Pallet<T> {
dkg_qualification.intersect_indexes(&participants); dkg_qualification.intersect_indexes(&participants);
if dkg_qualification.count_ones::<AuthIndex>() < min_threshold { if dkg_qualification.count_ones::<AuthIndex>() < min_threshold {
dkg_qualification.nullify_indexes(); dkg_qualification.nullify_indexes();
return; return;
@ -2716,7 +2707,7 @@ impl<T: Config> Pallet<T> {
let expected_package_len = round1_package_size( let expected_package_len = round1_package_size(
expected_count, expected_count,
network_curve.element_bytes_len(), network_curve.element_bytes_len(),
network_curve.scalar_bytes_len(), network_curve.signature_bytes_len(),
network_curve.header_bytes_len(), network_curve.header_bytes_len(),
); );

View File

@ -15,8 +15,8 @@ use rand_chacha::rand_core::SeedableRng;
use rand_chacha::ChaCha20Rng; use rand_chacha::ChaCha20Rng;
use frost_core::Field; use frost_core::Field;
use frost_secp256k1::{ use frost_secp256k1_tr::{
Secp256K1Sha256, Secp256K1ScalarField, Identifier as Secp256K1Identifier, Secp256K1Sha256TR, Secp256K1ScalarField, Identifier as Secp256K1Identifier,
keys::{ keys::{
VerifyingShare as Secp256K1VerifyingShare, VerifyingShare as Secp256K1VerifyingShare,
SigningShare as Secp256K1SigningShare, SigningShare as Secp256K1SigningShare,
@ -1452,7 +1452,7 @@ fn test_merkle_tree_success_power_of_two_for_shares() {
let indices = (1..=32).collect::<Vec<AuthIndex>>(); let indices = (1..=32).collect::<Vec<AuthIndex>>();
let shares = generate_mock_secp256k1_shares(&indices); let shares = generate_mock_secp256k1_shares(&indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
|share| share.serialize().map_err(|_| ExodusError::SerializationError), |share| share.serialize().map_err(|_| ExodusError::SerializationError),
).unwrap(); ).unwrap();
@ -1465,7 +1465,7 @@ fn test_merkle_tree_success_power_of_two_for_shares() {
).unwrap(); ).unwrap();
let (shares_bytes, proof) = let (shares_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
&tree, &tree,
auth_index, auth_index,
@ -1489,7 +1489,7 @@ fn test_merkle_tree_success_power_of_two_for_scalar() {
let indices = (1..=32).collect::<Vec<AuthIndex>>(); let indices = (1..=32).collect::<Vec<AuthIndex>>();
let scalars = generate_mock_secp256k1_scalars(&indices); let scalars = generate_mock_secp256k1_scalars(&indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
|scalar| { |scalar| {
let serialized = <Secp256K1ScalarField as Field>::serialize(scalar); let serialized = <Secp256K1ScalarField as Field>::serialize(scalar);
@ -1505,7 +1505,7 @@ fn test_merkle_tree_success_power_of_two_for_scalar() {
).unwrap(); ).unwrap();
let (shares_bytes, proof) = let (shares_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
&tree, &tree,
auth_index, auth_index,
@ -1538,7 +1538,7 @@ fn test_random_sparse_combinations_stress_for_shares() {
let indices: Vec<AuthIndex> = unique_indices.into_iter().collect(); let indices: Vec<AuthIndex> = unique_indices.into_iter().collect();
let shares = generate_mock_secp256k1_shares(&indices); let shares = generate_mock_secp256k1_shares(&indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
|share| share.serialize().map_err(|_| ExodusError::SerializationError), |share| share.serialize().map_err(|_| ExodusError::SerializationError),
).unwrap(); ).unwrap();
@ -1547,7 +1547,7 @@ fn test_random_sparse_combinations_stress_for_shares() {
for &auth_index in &indices { for &auth_index in &indices {
let (shares_bytes, proof) = let (shares_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
&tree, &tree,
auth_index, auth_index,
@ -1576,7 +1576,7 @@ fn test_random_sparse_combinations_stress_for_scalars() {
let indices: Vec<AuthIndex> = unique_indices.into_iter().collect(); let indices: Vec<AuthIndex> = unique_indices.into_iter().collect();
let scalars = generate_mock_secp256k1_scalars(&indices); let scalars = generate_mock_secp256k1_scalars(&indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
|scalar| { |scalar| {
let serialized = <Secp256K1ScalarField as Field>::serialize(scalar); let serialized = <Secp256K1ScalarField as Field>::serialize(scalar);
@ -1588,7 +1588,7 @@ fn test_random_sparse_combinations_stress_for_scalars() {
for &auth_index in &indices { for &auth_index in &indices {
let (scalars_bytes, proof) = let (scalars_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
&tree, &tree,
auth_index, auth_index,
@ -1614,7 +1614,7 @@ fn test_participants_with_high_index_gap_for_shares() {
let indices = vec![1, 1023]; let indices = vec![1, 1023];
let shares = generate_mock_secp256k1_shares(&indices); let shares = generate_mock_secp256k1_shares(&indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
|share| share.serialize().map_err(|_| ExodusError::SerializationError), |share| share.serialize().map_err(|_| ExodusError::SerializationError),
).unwrap(); ).unwrap();
@ -1622,7 +1622,7 @@ fn test_participants_with_high_index_gap_for_shares() {
let root = *tree.last().unwrap(); let root = *tree.last().unwrap();
let (shares_bytes, proof) = let (shares_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
&tree, &tree,
1023, 1023,
@ -1646,7 +1646,7 @@ fn test_participants_with_high_index_gap_for_scalars() {
let indices = vec![1, 1023]; let indices = vec![1, 1023];
let scalars = generate_mock_secp256k1_scalars(&indices); let scalars = generate_mock_secp256k1_scalars(&indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
|scalar| { |scalar| {
let serialized = <Secp256K1ScalarField as Field>::serialize(scalar); let serialized = <Secp256K1ScalarField as Field>::serialize(scalar);
@ -1657,7 +1657,7 @@ fn test_participants_with_high_index_gap_for_scalars() {
let root = *tree.last().unwrap(); let root = *tree.last().unwrap();
let (scalars_bytes, proof) = let (scalars_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
&tree, &tree,
1023, 1023,
@ -1684,7 +1684,7 @@ fn test_regression_consecutive_vs_position_for_shares() {
let custom_indices = vec![2, 3]; let custom_indices = vec![2, 3];
let shares = generate_mock_secp256k1_shares(&custom_indices); let shares = generate_mock_secp256k1_shares(&custom_indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
|scalar| scalar.serialize().map_err(|_| ExodusError::SerializationError), |scalar| scalar.serialize().map_err(|_| ExodusError::SerializationError),
).unwrap(); ).unwrap();
@ -1692,7 +1692,7 @@ fn test_regression_consecutive_vs_position_for_shares() {
let root = *tree.last().unwrap(); let root = *tree.last().unwrap();
let (shares_bytes, proof) = let (shares_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
&tree, &tree,
2, 2,
@ -1709,7 +1709,7 @@ fn test_regression_consecutive_vs_position_for_scalars() {
let custom_indices = vec![2, 3]; let custom_indices = vec![2, 3];
let scalars = generate_mock_secp256k1_scalars(&custom_indices); let scalars = generate_mock_secp256k1_scalars(&custom_indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
|scalar| { |scalar| {
let serialized = <Secp256K1ScalarField as Field>::serialize(scalar); let serialized = <Secp256K1ScalarField as Field>::serialize(scalar);
@ -1720,7 +1720,7 @@ fn test_regression_consecutive_vs_position_for_scalars() {
let root = *tree.last().unwrap(); let root = *tree.last().unwrap();
let (scalars_bytes, proof) = let (scalars_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
&tree, &tree,
2, 2,
@ -1740,7 +1740,7 @@ fn test_attack_with_unknown_authority_index_for_shares() {
let custom_indices = vec![1, 2, 3]; let custom_indices = vec![1, 2, 3];
let shares = generate_mock_secp256k1_shares(&custom_indices); let shares = generate_mock_secp256k1_shares(&custom_indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
|scalar| scalar.serialize().map_err(|_| ExodusError::SerializationError), |scalar| scalar.serialize().map_err(|_| ExodusError::SerializationError),
).unwrap(); ).unwrap();
@ -1748,7 +1748,7 @@ fn test_attack_with_unknown_authority_index_for_shares() {
let root = *tree.last().unwrap(); let root = *tree.last().unwrap();
let (shares_bytes, proof) = let (shares_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&shares, &shares,
&tree, &tree,
2, 2,
@ -1765,7 +1765,7 @@ fn test_attack_with_unknown_authority_index_for_scalars() {
let custom_indices = vec![1, 2, 3]; let custom_indices = vec![1, 2, 3];
let scalars = generate_mock_secp256k1_scalars(&custom_indices); let scalars = generate_mock_secp256k1_scalars(&custom_indices);
let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256, _, _>( let tree = NetworkCurve::build_merkle_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
|scalar| { |scalar| {
let serialized = <Secp256K1ScalarField as Field>::serialize(scalar); let serialized = <Secp256K1ScalarField as Field>::serialize(scalar);
@ -1776,7 +1776,7 @@ fn test_attack_with_unknown_authority_index_for_scalars() {
let root = *tree.last().unwrap(); let root = *tree.last().unwrap();
let (scalars_bytes, proof) = let (scalars_bytes, proof) =
NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256, _, _>( NetworkCurve::generate_merkle_proof_from_tree::<Secp256K1Sha256TR, _, _>(
&scalars, &scalars,
&tree, &tree,
2, 2,
@ -2227,7 +2227,7 @@ fn curve_wrapper_for_dkg_works() {
#[test] #[test]
fn test_common_way_of_frost_usage() { fn test_common_way_of_frost_usage() {
use frost_secp256k1 as frost; use frost_secp256k1_tr as frost;
let mut rng = ChaCha20Rng::from_seed(Default::default()); let mut rng = ChaCha20Rng::from_seed(Default::default());

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-traits" name = "ghost-traits"
version = "0.4.5" version = "0.4.6"
description = "Shared traits including `GhostHasher`, `NetworkDataBasicHandler`, `BoundedBTreeMap`, `MerkleTree` and more." description = "Shared traits including `GhostHasher`, `NetworkDataBasicHandler`, `BoundedBTreeMap`, `MerkleTree` and more."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -17,6 +17,7 @@ pub trait FlexibleRoundOptimizedSchnorrThresholdSignature<A, E>: MerkleTreeBuild
fn header_bytes_len(&self) -> usize; fn header_bytes_len(&self) -> usize;
fn element_bytes_len(&self) -> usize; fn element_bytes_len(&self) -> usize;
fn signature_bytes_len(&self) -> usize;
fn scalar_bytes_len(&self) -> usize; fn scalar_bytes_len(&self) -> usize;
fn verify_signature_share( fn verify_signature_share(
@ -84,7 +85,6 @@ pub trait DistributedKeyGeneration<A, E>: MerkleTreeBuilder<A, E> {
) -> Self::Part3Result; ) -> Self::Part3Result;
fn dkg_derive_verifying_share(&self, sk: &[u8]) -> Result<Vec<u8>, E>; fn dkg_derive_verifying_share(&self, sk: &[u8]) -> Result<Vec<u8>, E>;
fn dkg_decompress_key(&self, vk: &[u8]) -> Result<Vec<u8>, E>;
} }
pub trait MerkleTreeBuilder<A, E>: IdentifierConverter<A, E> { pub trait MerkleTreeBuilder<A, E>: IdentifierConverter<A, E> {

View File

@ -599,7 +599,7 @@ if [ "$GENERATE_GENESIS" = true ]; then
echo " - $WALLET_KEY_PATH" echo " - $WALLET_KEY_PATH"
echo " - $STASH_KEY_PATH" echo " - $STASH_KEY_PATH"
echo "" echo ""
echo "IMPORTANT: Create a pool request to include these keys in the upcoming genesis." echo "IMPORTANT: Create a pull request to include these keys in the upcoming genesis."
echo "DO NOT DELETE THESE KEYS OR THE GENESIS WILL BE INVALID!" echo "DO NOT DELETE THESE KEYS OR THE GENESIS WILL BE INVALID!"
echo "Submit a PR with these keys to: https://git.ghostchain.io/ghostchain/ghost-node" echo "Submit a PR with these keys to: https://git.ghostchain.io/ghostchain/ghost-node"
echo "" echo ""