diff --git a/Cargo.lock b/Cargo.lock index c8a2afa..6c18e90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3363,10 +3363,10 @@ dependencies = [ ] [[package]] -name = "frost-secp256k1" +name = "frost-secp256k1-tr" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f6974379aee791f2f9e0db47c37d9e4c77ea8a8233e488ae8949ce4c6864e96" +checksum = "ff8a25b14bfd5d25deba5edce61ec99c3afb752a1d26630a196bba4cb1c4ca5e" dependencies = [ "document-features", "frost-core", @@ -3684,7 +3684,7 @@ dependencies = [ [[package]] name = "ghost-exodus" -version = "0.0.8" +version = "0.0.9" dependencies = [ "chacha20poly1305", "frame-benchmarking", @@ -3693,7 +3693,7 @@ dependencies = [ "frame-system", "frost-core", "frost-ed25519", - "frost-secp256k1", + "frost-secp256k1-tr", "ghost-helpers", "ghost-networks", "ghost-traits", @@ -4085,7 +4085,7 @@ dependencies = [ [[package]] name = "ghost-traits" -version = "0.4.5" +version = "0.4.6" dependencies = [ "frame-support", "frost-core", diff --git a/Cargo.toml b/Cargo.toml index 09168f8..b47d70e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,7 +89,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = scale-info = { version = "2.5.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"] } chacha20poly1305 = { version = "0.10.1", default-features = false, features = ["alloc"] } frost-core = { version = "2.2.0", default-features = false } @@ -345,7 +345,7 @@ curve25519-dalek = { opt-level = 3 } ed25519-dalek = { opt-level = 3 } flate2 = { opt-level = 3 } frost-core = { opt-level = 3 } -frost-secp256k1 = { opt-level = 3 } +frost-secp256k1-tr = { opt-level = 3 } futures-channel = { opt-level = 3 } hash-db = { opt-level = 3 } hashbrown = { opt-level = 3 } diff --git a/pallets/exodus/Cargo.toml b/pallets/exodus/Cargo.toml index 1ff2a83..749929c 100644 --- a/pallets/exodus/Cargo.toml +++ b/pallets/exodus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghost-exodus" -version = "0.0.8" +version = "0.0.9" description = "Threshold signature generation with DKG included" license.workspace = true authors.workspace = true @@ -28,7 +28,7 @@ sp-core = { workspace = true } sp-std = { workspace = true } sp-io = { workspace = true } -frost-secp256k1 = { workspace = true } +frost-secp256k1-tr = { workspace = true } frost-ed25519 = { workspace = true } frost-core = { workspace = true } rand_chacha = { workspace = true } @@ -75,7 +75,7 @@ std = [ "sp-core/std", "sp-std/std", "sp-io/std", - "frost-secp256k1/std", + "frost-secp256k1-tr/std", "frost-ed25519/std", "frost-core/std", "ghost-traits/std", diff --git a/pallets/exodus/src/impls/dkg.rs b/pallets/exodus/src/impls/dkg.rs index 10938b6..0cef728 100644 --- a/pallets/exodus/src/impls/dkg.rs +++ b/pallets/exodus/src/impls/dkg.rs @@ -35,7 +35,7 @@ impl DistributedKeyGeneration for NetworkCurve { $field2:ident : $action2:tt, ) => {{ let secret_package = <$package_type>::deserialize(secret_package_bytes) - .map_err(|_| ExodusError::DeserializationError)?; + .map_err(|_| ExodusError::DeserializationError)?; let min_signers = *secret_package.min_signers(); @@ -64,7 +64,7 @@ impl DistributedKeyGeneration for NetworkCurve { ); new_secret_package.serialize() - .map_err(|_| ExodusError::SerializationError) + .map_err(|_| ExodusError::SerializationError) }}; } @@ -285,15 +285,18 @@ impl DistributedKeyGeneration for NetworkCurve { _ => ExodusError::Unknown, })?; + let key_package = key_package.normalize_package(); + let pubkey_package = pubkey_package.normalize_package(); + let key_package_bytes = key_package.serialize() .map_err(|_| ExodusError::SerializationError)?; let verifying_shares_merkle_tree = - Self::build_merkle_tree( - pubkey_package.verifying_shares(), - |verifying_share| verifying_share.serialize() - .map_err(|_| ExodusError::SerializationError) - )?; + Self::build_merkle_tree( + pubkey_package.verifying_shares(), + |verifying_share| verifying_share.serialize() + .map_err(|_| ExodusError::SerializationError) + )?; let (_, merkle_proof) = Self::generate_merkle_proof_from_tree( @@ -337,15 +340,4 @@ impl DistributedKeyGeneration for NetworkCurve { .map_err(|_| ExodusError::SerializationError) }) } - - fn dkg_decompress_key( - &self, - verifying_key_bytes: &[u8], - ) -> Result, ExodusError> { - with_ciphersuite!(self, |f| { - let verifying_key = f::VerifyingKey::deserialize(verifying_key_bytes) - .map_err(|_| ExodusError::DeserializationError)?; - decomporess_key(verifying_key) - }) - } } diff --git a/pallets/exodus/src/impls/frost.rs b/pallets/exodus/src/impls/frost.rs index 7230b93..3e3423a 100644 --- a/pallets/exodus/src/impls/frost.rs +++ b/pallets/exodus/src/impls/frost.rs @@ -17,6 +17,13 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for 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 { match self { NetworkCurve::Secp256k1 => 33, @@ -76,7 +83,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for ::Serialization::try_from(group_commitment_bytes.as_ref()) .map_err(|_| ExodusError::DeserializationError)?; - let group_commitment_element = + let mut group_commitment_element = ::deserialize(&group_commitment_serialization) .map_err(|_| ExodusError::DeserializationError)?; @@ -95,15 +102,6 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for let verifying_key = f::VerifyingKey::deserialize(verifying_key_bytes) .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 = ::Serialization::try_from(nonce_hiding_bytes.as_ref()) .map_err(|_| ExodusError::DeserializationError)?; @@ -120,9 +118,27 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for ::deserialize(&binding_element_serialization) .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::::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 = ::challenge( + &group_commitment_element, + &verifying_key, + message, + ).map_err(|err| match err { + f::Error::SerializationError => ExodusError::SerializationError, + _ => ExodusError::Unknown, + })?; + let commitment_share = - frost_core::round1::GroupCommitmentShare::from_element(r_i_element); + frost_core::round1::GroupCommitmentShare::from_element(r_i_element); signature_share.verify( identifier, @@ -259,7 +275,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for let hiding_serialization = ::Serialization::try_from(hiding_bytes.as_ref()).ok()?; let hiding_nonce = f::round1::NonceCommitment::deserialize(&hiding_serialization).ok()?; - let binding_serialization = ::Serialization::try_from((*binding_bytes).as_ref()).ok()?; + let binding_serialization = ::Serialization::try_from((*binding_bytes).as_ref()).ok()?; let binding_nonce = f::round1::NonceCommitment::deserialize(&binding_serialization).ok()?; let commitments = f::round1::SigningCommitments::new(hiding_nonce, binding_nonce); @@ -275,14 +291,14 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for let signing_package = f::SigningPackage::new(signing_commitments, message); let binding_factors_list_wrapped = - frost_core::compute_binding_factor_list(&signing_package, &verifying_key, &[]) + frost_core::compute_binding_factor_list::(&signing_package, &verifying_key, &[]) .map_err(|err| match err { f::Error::SerializationError => ExodusError::SerializationError, _ => ExodusError::Unknown, })?; let group_commitment = - frost_core::compute_group_commitment(&signing_package, &binding_factors_list_wrapped) + frost_core::compute_group_commitment::(&signing_package, &binding_factors_list_wrapped) .map_err(|err| match err { f::Error::IdentityCommitment => ExodusError::IdentityCommitment, f::Error::UnknownIdentifier => ExodusError::UnknownIdentifier, @@ -306,7 +322,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for }) .flatten()?; - Some((identifier, binding_factor)) + Some((identifier, binding_factor)) }) .collect::>(); @@ -328,7 +344,7 @@ impl FlexibleRoundOptimizedSchnorrThresholdSignature for &binding_factor_tree, authority_index, |binding_factor| { - let serialized = ::serialize(binding_factor); + let serialized = ::serialize(binding_factor); Ok(serialized.as_ref().to_vec()) } )?; diff --git a/pallets/exodus/src/impls/mod.rs b/pallets/exodus/src/impls/mod.rs index 36a7353..047e986 100644 --- a/pallets/exodus/src/impls/mod.rs +++ b/pallets/exodus/src/impls/mod.rs @@ -3,46 +3,53 @@ macro_rules! with_ciphersuite { ($curve:expr, |$alias:ident| $body:block) => { match $curve { NetworkCurve::Secp256k1 => { - use k256::elliptic_curve::sec1::ToEncodedPoint; - use frost_secp256k1 as $alias; + #[allow(unused_imports)] + use frost_secp256k1_tr as $alias; #[allow(unused_imports)] - use frost_secp256k1::Secp256K1Sha256 as Ciphersuite; + use frost_secp256k1_tr::Secp256K1Sha256TR as Ciphersuite; + + use $alias::keys::EvenY; #[allow(dead_code)] - fn decomporess_key( - verifying_key: $alias::VerifyingKey, - ) -> Result, ExodusError> { - let element = verifying_key.to_element(); + trait UniversalNormalizer { + fn normalize_package(self) -> Self; + fn is_normalized(&self) -> bool; + } - if element == k256::ProjectivePoint::IDENTITY { - return Err(ExodusError::InvalidIdentityElement); + impl UniversalNormalizer for T { + #[inline] + fn normalize_package(self) -> Self { + self.into_even_y(None) } - let mut fixed_serialized = [0; 65]; - let serialized_point = element.to_affine().to_encoded_point(false); - let serialized = serialized_point.as_bytes(); - fixed_serialized.copy_from_slice(serialized); - - Ok(fixed_serialized.to_vec()) + #[inline] + fn is_normalized(&self) -> bool { + self.has_even_y() + } } $body }, NetworkCurve::Ed25519 => { + #[allow(unused_imports)] use frost_ed25519 as $alias; #[allow(unused_imports)] use frost_ed25519::Ed25519Sha512 as Ciphersuite; #[allow(dead_code)] - fn decomporess_key( - verifying_key: $alias::VerifyingKey, - ) -> Result, ExodusError> { - verifying_key.serialize().map_err(|err| match err { - f::Error::SerializationError => ExodusError::SerializationError, - _ => ExodusError::Unknown, - }) + trait UniversalNormalizer { + fn normalize_package(self) -> Self; + fn is_normalized(&self) -> bool; + } + + impl UniversalNormalizer for T { + #[inline] + fn normalize_package(self) -> Self { self } + + #[inline] + fn is_normalized(&self) -> bool { true } } $body diff --git a/pallets/exodus/src/lib.rs b/pallets/exodus/src/lib.rs index 70cd6ba..cd7f1f6 100644 --- a/pallets/exodus/src/lib.rs +++ b/pallets/exodus/src/lib.rs @@ -130,26 +130,17 @@ const fn postcard_varint_len(len: usize) -> usize { 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( commitments_count: usize, element_bytes_len: usize, - scalar_bytes_len: usize, + signature_bytes_len: usize, header_bytes_len: usize ) -> usize { let commitments_bytes_len = commitments_count.saturating_mul(element_bytes_len); 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(commitment_vec_prefix) .saturating_add(commitments_bytes_len) @@ -264,11 +255,12 @@ impl Get for Round1MaxBytes { fn get() -> u32 { let max_authorities = T::MaxAuthorities::get(); let min_authorities = get_byzantium_quorum_threshold(max_authorities); + let max_signature_bytes = ELEMENT_MAX_BYTES + SCALAR_MAX_BYTES; round1_package_size( min_authorities as usize, ELEMENT_MAX_BYTES as usize, - SCALAR_MAX_BYTES as usize, + max_signature_bytes as usize, HEADER_MAX_BYTES as usize, ) as u32 } @@ -363,10 +355,8 @@ impl Get for SignatureShareMaxBytes { pub struct SignatureMaxBytes(sp_std::marker::PhantomData); impl Get for SignatureMaxBytes { fn get() -> u32 { - signature_bytes_len( - ELEMENT_MAX_BYTES as usize, - SCALAR_MAX_BYTES as usize, - ) as u32 + let signature_max_bytes = ELEMENT_MAX_BYTES + SCALAR_MAX_BYTES; + postcard_varint_len(signature_max_bytes as usize) as u32 } } @@ -2533,6 +2523,7 @@ impl Pallet { dkg_qualification.intersect_indexes(&participants); + if dkg_qualification.count_ones::() < min_threshold { dkg_qualification.nullify_indexes(); return; @@ -2716,7 +2707,7 @@ impl Pallet { let expected_package_len = round1_package_size( expected_count, network_curve.element_bytes_len(), - network_curve.scalar_bytes_len(), + network_curve.signature_bytes_len(), network_curve.header_bytes_len(), ); diff --git a/pallets/exodus/src/tests.rs b/pallets/exodus/src/tests.rs index b95b5cc..7e54f9e 100644 --- a/pallets/exodus/src/tests.rs +++ b/pallets/exodus/src/tests.rs @@ -15,8 +15,8 @@ use rand_chacha::rand_core::SeedableRng; use rand_chacha::ChaCha20Rng; use frost_core::Field; -use frost_secp256k1::{ - Secp256K1Sha256, Secp256K1ScalarField, Identifier as Secp256K1Identifier, +use frost_secp256k1_tr::{ + Secp256K1Sha256TR, Secp256K1ScalarField, Identifier as Secp256K1Identifier, keys::{ VerifyingShare as Secp256K1VerifyingShare, SigningShare as Secp256K1SigningShare, @@ -1452,7 +1452,7 @@ fn test_merkle_tree_success_power_of_two_for_shares() { let indices = (1..=32).collect::>(); let shares = generate_mock_secp256k1_shares(&indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &shares, |share| share.serialize().map_err(|_| ExodusError::SerializationError), ).unwrap(); @@ -1465,7 +1465,7 @@ fn test_merkle_tree_success_power_of_two_for_shares() { ).unwrap(); let (shares_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &shares, &tree, auth_index, @@ -1489,7 +1489,7 @@ fn test_merkle_tree_success_power_of_two_for_scalar() { let indices = (1..=32).collect::>(); let scalars = generate_mock_secp256k1_scalars(&indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &scalars, |scalar| { let serialized = ::serialize(scalar); @@ -1505,7 +1505,7 @@ fn test_merkle_tree_success_power_of_two_for_scalar() { ).unwrap(); let (shares_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &scalars, &tree, auth_index, @@ -1538,7 +1538,7 @@ fn test_random_sparse_combinations_stress_for_shares() { let indices: Vec = unique_indices.into_iter().collect(); let shares = generate_mock_secp256k1_shares(&indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &shares, |share| share.serialize().map_err(|_| ExodusError::SerializationError), ).unwrap(); @@ -1547,7 +1547,7 @@ fn test_random_sparse_combinations_stress_for_shares() { for &auth_index in &indices { let (shares_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &shares, &tree, auth_index, @@ -1576,7 +1576,7 @@ fn test_random_sparse_combinations_stress_for_scalars() { let indices: Vec = unique_indices.into_iter().collect(); let scalars = generate_mock_secp256k1_scalars(&indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &scalars, |scalar| { let serialized = ::serialize(scalar); @@ -1588,7 +1588,7 @@ fn test_random_sparse_combinations_stress_for_scalars() { for &auth_index in &indices { let (scalars_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &scalars, &tree, auth_index, @@ -1614,7 +1614,7 @@ fn test_participants_with_high_index_gap_for_shares() { let indices = vec![1, 1023]; let shares = generate_mock_secp256k1_shares(&indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &shares, |share| share.serialize().map_err(|_| ExodusError::SerializationError), ).unwrap(); @@ -1622,7 +1622,7 @@ fn test_participants_with_high_index_gap_for_shares() { let root = *tree.last().unwrap(); let (shares_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &shares, &tree, 1023, @@ -1646,7 +1646,7 @@ fn test_participants_with_high_index_gap_for_scalars() { let indices = vec![1, 1023]; let scalars = generate_mock_secp256k1_scalars(&indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &scalars, |scalar| { let serialized = ::serialize(scalar); @@ -1657,7 +1657,7 @@ fn test_participants_with_high_index_gap_for_scalars() { let root = *tree.last().unwrap(); let (scalars_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &scalars, &tree, 1023, @@ -1684,7 +1684,7 @@ fn test_regression_consecutive_vs_position_for_shares() { let custom_indices = vec![2, 3]; let shares = generate_mock_secp256k1_shares(&custom_indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &shares, |scalar| scalar.serialize().map_err(|_| ExodusError::SerializationError), ).unwrap(); @@ -1692,7 +1692,7 @@ fn test_regression_consecutive_vs_position_for_shares() { let root = *tree.last().unwrap(); let (shares_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &shares, &tree, 2, @@ -1709,7 +1709,7 @@ fn test_regression_consecutive_vs_position_for_scalars() { let custom_indices = vec![2, 3]; let scalars = generate_mock_secp256k1_scalars(&custom_indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &scalars, |scalar| { let serialized = ::serialize(scalar); @@ -1720,7 +1720,7 @@ fn test_regression_consecutive_vs_position_for_scalars() { let root = *tree.last().unwrap(); let (scalars_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &scalars, &tree, 2, @@ -1740,7 +1740,7 @@ fn test_attack_with_unknown_authority_index_for_shares() { let custom_indices = vec![1, 2, 3]; let shares = generate_mock_secp256k1_shares(&custom_indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &shares, |scalar| scalar.serialize().map_err(|_| ExodusError::SerializationError), ).unwrap(); @@ -1748,7 +1748,7 @@ fn test_attack_with_unknown_authority_index_for_shares() { let root = *tree.last().unwrap(); let (shares_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &shares, &tree, 2, @@ -1765,7 +1765,7 @@ fn test_attack_with_unknown_authority_index_for_scalars() { let custom_indices = vec![1, 2, 3]; let scalars = generate_mock_secp256k1_scalars(&custom_indices); - let tree = NetworkCurve::build_merkle_tree::( + let tree = NetworkCurve::build_merkle_tree::( &scalars, |scalar| { let serialized = ::serialize(scalar); @@ -1776,7 +1776,7 @@ fn test_attack_with_unknown_authority_index_for_scalars() { let root = *tree.last().unwrap(); let (scalars_bytes, proof) = - NetworkCurve::generate_merkle_proof_from_tree::( + NetworkCurve::generate_merkle_proof_from_tree::( &scalars, &tree, 2, @@ -2227,7 +2227,7 @@ fn curve_wrapper_for_dkg_works() { #[test] 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()); diff --git a/pallets/traits/Cargo.toml b/pallets/traits/Cargo.toml index 6d30e06..e243aa3 100644 --- a/pallets/traits/Cargo.toml +++ b/pallets/traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghost-traits" -version = "0.4.5" +version = "0.4.6" description = "Shared traits including `GhostHasher`, `NetworkDataBasicHandler`, `BoundedBTreeMap`, `MerkleTree` and more." license.workspace = true authors.workspace = true diff --git a/pallets/traits/src/exodus.rs b/pallets/traits/src/exodus.rs index b8fb9d6..6ddd7ce 100644 --- a/pallets/traits/src/exodus.rs +++ b/pallets/traits/src/exodus.rs @@ -17,6 +17,7 @@ pub trait FlexibleRoundOptimizedSchnorrThresholdSignature: MerkleTreeBuild fn header_bytes_len(&self) -> usize; fn element_bytes_len(&self) -> usize; + fn signature_bytes_len(&self) -> usize; fn scalar_bytes_len(&self) -> usize; fn verify_signature_share( @@ -84,7 +85,6 @@ pub trait DistributedKeyGeneration: MerkleTreeBuilder { ) -> Self::Part3Result; fn dkg_derive_verifying_share(&self, sk: &[u8]) -> Result, E>; - fn dkg_decompress_key(&self, vk: &[u8]) -> Result, E>; } pub trait MerkleTreeBuilder: IdentifierConverter {