diff --git a/frost-core/CHANGELOG.md b/frost-core/CHANGELOG.md index 7ddbe73e..3bb812e8 100644 --- a/frost-core/CHANGELOG.md +++ b/frost-core/CHANGELOG.md @@ -17,6 +17,18 @@ Entries are listed in reverse chronological order. `VerifiableSecretSharingCommitment::serialize()`, `NonceCommitment::serialize()`, `Signature::serialize()`, `VerifyingKey::serialize()` can now all return an error. +* Changed the `serialize()` and `deserialize()` methods of all Scalar- and + Element-wrapping structs; instead of taking or returning a + `Field::Serialization` or `Element::Serialization` traits (which are usually + defined by ciphersuites as arrays of specific sizes), they simply respectively + take `&[u8]` and return `Vec`, exactly as the other structs, which should + greatly simplify non-serde serialization code. You can port existing code with + e.g. `x.serialize().as_ref()` -> `x.serialize()` and + `X::deserialize(bytes.try_into().unwrap())` -> `X::deserialize(&bytes)`. +* Removed the `ops::{Mul, MulAssign, Sub}` implementation for `Identifier`. + These were being used internally, but library users shouldn't need to use them. + If you have low-level code that relied on it, use `Identifier::{new, + to_scalar}` to handle the underlying scalar. * Removed `batch::Item::into()` which created a batch Item from a triple of VerifyingKey, Signature and message. Use the new `batch::Item::new()` instead (which can return an error). diff --git a/frost-core/src/identifier.rs b/frost-core/src/identifier.rs index 5525197b..afc209eb 100644 --- a/frost-core/src/identifier.rs +++ b/frost-core/src/identifier.rs @@ -5,10 +5,9 @@ use std::{ hash::{Hash, Hasher}, }; -use crate::{Ciphersuite, Error, Field, FieldError, Group, Scalar}; - -#[cfg(feature = "serde")] -use crate::serialization::ScalarSerialization; +use crate::{ + serialization::SerializableScalar, Ciphersuite, Error, Field, FieldError, Group, Scalar, +}; /// A FROST participant identifier. /// @@ -18,23 +17,31 @@ use crate::serialization::ScalarSerialization; #[derive(Copy, Clone, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))] -#[cfg_attr(feature = "serde", serde(try_from = "ScalarSerialization"))] -#[cfg_attr(feature = "serde", serde(into = "ScalarSerialization"))] -pub struct Identifier(Scalar); +#[cfg_attr(feature = "serde", serde(transparent))] +pub struct Identifier(SerializableScalar); impl Identifier where C: Ciphersuite, { /// Create a new Identifier from a scalar. For internal use only. - fn new(scalar: Scalar) -> Result> { + #[cfg_attr(feature = "internals", visibility::make(pub))] + #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] + pub(crate) fn new(scalar: Scalar) -> Result> { if scalar == <::Field>::zero() { Err(FieldError::InvalidZeroScalar.into()) } else { - Ok(Self(scalar)) + Ok(Self(SerializableScalar(scalar))) } } + /// Get the inner scalar. + #[cfg_attr(feature = "internals", visibility::make(pub))] + #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] + pub(crate) fn to_scalar(&self) -> Scalar { + self.0 .0 + } + /// Derive an Identifier from an arbitrary byte string. /// /// This feature is not part of the specification and is just a convenient @@ -50,39 +57,14 @@ where } /// Serialize the identifier using the ciphersuite encoding. - pub fn serialize(&self) -> <::Field as Field>::Serialization { - <::Field>::serialize(&self.0) + pub fn serialize(&self) -> Vec { + self.0.serialize() } /// Deserialize an Identifier from a serialized buffer. /// Returns an error if it attempts to deserialize zero. - pub fn deserialize( - buf: &<::Field as Field>::Serialization, - ) -> Result> { - let scalar = <::Field>::deserialize(buf)?; - Self::new(scalar) - } -} - -#[cfg(feature = "serde")] -impl TryFrom> for Identifier -where - C: Ciphersuite, -{ - type Error = Error; - - fn try_from(value: ScalarSerialization) -> Result { - Self::deserialize(&value.0) - } -} - -#[cfg(feature = "serde")] -impl From> for ScalarSerialization -where - C: Ciphersuite, -{ - fn from(value: Identifier) -> Self { - Self(value.serialize()) + pub fn deserialize(bytes: &[u8]) -> Result> { + Ok(Self(SerializableScalar::deserialize(bytes)?)) } } @@ -94,9 +76,7 @@ where { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Identifier") - .field(&hex::encode( - <::Field>::serialize(&self.0).as_ref(), - )) + .field(&hex::encode(self.serialize())) .finish() } } @@ -107,9 +87,7 @@ where C: Ciphersuite, { fn hash(&self, state: &mut H) { - <::Field>::serialize(&self.0) - .as_ref() - .hash(state) + self.serialize().hash(state) } } @@ -118,8 +96,10 @@ where C: Ciphersuite, { fn cmp(&self, other: &Self) -> std::cmp::Ordering { - let serialized_self = <::Field>::little_endian_serialize(&self.0); - let serialized_other = <::Field>::little_endian_serialize(&other.0); + let serialized_self = + <::Field>::little_endian_serialize(&self.to_scalar()); + let serialized_other = + <::Field>::little_endian_serialize(&other.to_scalar()); // The default cmp uses lexicographic order; so we need the elements in big endian serialized_self .as_ref() @@ -138,37 +118,6 @@ where } } -impl std::ops::Mul> for Identifier -where - C: Ciphersuite, -{ - type Output = Scalar; - - fn mul(self, scalar: Scalar) -> Scalar { - self.0 * scalar - } -} - -impl std::ops::MulAssign> for Scalar -where - C: Ciphersuite, -{ - fn mul_assign(&mut self, identifier: Identifier) { - *self = *self * identifier.0 - } -} - -impl std::ops::Sub for Identifier -where - C: Ciphersuite, -{ - type Output = Self; - - fn sub(self, rhs: Identifier) -> Self::Output { - Self(self.0 - rhs.0) - } -} - impl TryFrom for Identifier where C: Ciphersuite, @@ -191,7 +140,7 @@ where sum = sum + one; } } - Ok(Self(sum)) + Self::new(sum) } } } diff --git a/frost-core/src/keys.rs b/frost-core/src/keys.rs index 75ffc8fd..cc8cd8ae 100644 --- a/frost-core/src/keys.rs +++ b/frost-core/src/keys.rs @@ -17,13 +17,11 @@ use rand_core::{CryptoRng, RngCore}; use zeroize::{DefaultIsZeroes, Zeroize}; use crate::{ - serialization::SerializableElement, Ciphersuite, Element, Error, Field, Group, GroupError, - Header, Identifier, Scalar, SigningKey, VerifyingKey, + serialization::{SerializableElement, SerializableScalar}, + Ciphersuite, Element, Error, Field, Group, Header, Identifier, Scalar, SigningKey, + VerifyingKey, }; -#[cfg(feature = "serde")] -use crate::serialization::ScalarSerialization; - #[cfg(feature = "serialization")] use crate::serialization::{Deserialize, Serialize}; @@ -83,44 +81,41 @@ pub(crate) fn default_identifiers(max_signers: u16) -> Vec(pub(crate) Scalar); +#[cfg_attr(feature = "serde", serde(transparent))] +pub struct SigningShare(pub(crate) SerializableScalar); impl SigningShare where C: Ciphersuite, { /// Create a new [`SigningShare`] from a scalar. - #[cfg(feature = "internals")] - pub fn new(scalar: Scalar) -> Self { - Self(scalar) + #[cfg_attr(feature = "internals", visibility::make(pub))] + #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] + pub(crate) fn new(scalar: Scalar) -> Self { + Self(SerializableScalar(scalar)) } /// Get the inner scalar. - #[cfg(feature = "internals")] - pub fn to_scalar(&self) -> Scalar { - self.0 + #[cfg_attr(feature = "internals", visibility::make(pub))] + #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] + pub(crate) fn to_scalar(&self) -> Scalar { + self.0 .0 } /// Deserialize from bytes - pub fn deserialize( - bytes: <::Field as Field>::Serialization, - ) -> Result> { - <::Field>::deserialize(&bytes) - .map(|scalar| Self(scalar)) - .map_err(|e| e.into()) + pub fn deserialize(bytes: &[u8]) -> Result> { + Ok(Self(SerializableScalar::deserialize(bytes)?)) } /// Serialize to bytes - pub fn serialize(&self) -> <::Field as Field>::Serialization { - <::Field>::serialize(&self.0) + pub fn serialize(&self) -> Vec { + self.0.serialize() } /// Computes the signing share from a list of coefficients. #[cfg_attr(feature = "internals", visibility::make(pub))] pub(crate) fn from_coefficients(coefficients: &[Scalar], peer: Identifier) -> Self { - Self(evaluate_polynomial(peer, coefficients)) + Self::new(evaluate_polynomial(peer, coefficients)) } } @@ -138,7 +133,7 @@ where C: Ciphersuite, { fn default() -> Self { - Self(<::Field>::zero()) + Self::new(<::Field>::zero()) } } @@ -154,32 +149,7 @@ where fn from_hex>(hex: T) -> Result { let v: Vec = FromHex::from_hex(hex).map_err(|_| "invalid hex")?; - match v.try_into() { - Ok(bytes) => Self::deserialize(bytes).map_err(|_| "malformed secret encoding"), - Err(_) => Err("malformed secret encoding"), - } - } -} - -#[cfg(feature = "serde")] -impl TryFrom> for SigningShare -where - C: Ciphersuite, -{ - type Error = Error; - - fn try_from(value: ScalarSerialization) -> Result { - Self::deserialize(value.0) - } -} - -#[cfg(feature = "serde")] -impl From> for ScalarSerialization -where - C: Ciphersuite, -{ - fn from(value: SigningShare) -> Self { - Self(value.serialize()) + Self::deserialize(&v).map_err(|_| "malformed scalar") } } @@ -212,15 +182,13 @@ where } /// Deserialize from bytes - pub fn deserialize(bytes: ::Serialization) -> Result> { - ::deserialize(&bytes) - .map(|element| Self(SerializableElement(element))) - .map_err(|e| e.into()) + pub fn deserialize(bytes: &[u8]) -> Result> { + Ok(Self(SerializableElement::deserialize(bytes)?)) } /// Serialize to bytes - pub fn serialize(&self) -> Result<::Serialization, Error> { - Ok(::serialize(&self.0 .0)?) + pub fn serialize(&self) -> Result, Error> { + self.0.serialize() } /// Computes a verifying share for a peer given the group commitment. @@ -265,7 +233,7 @@ where C: Ciphersuite, { fn from(secret: SigningShare) -> VerifyingShare { - VerifyingShare::new(::generator() * secret.0 as Scalar) + VerifyingShare::new(::generator() * secret.to_scalar()) } } @@ -288,16 +256,14 @@ where Self(SerializableElement(value)) } - /// returns serialized element - pub fn serialize(&self) -> Result<::Serialization, Error> { - Ok(::serialize(&self.0 .0)?) + /// Deserialize from bytes + pub fn deserialize(bytes: &[u8]) -> Result> { + Ok(Self(SerializableElement::deserialize(bytes)?)) } - /// Creates a new commitment from a coefficient input - pub fn deserialize( - coefficient: ::Serialization, - ) -> Result, Error> { - Ok(Self::new(::deserialize(&coefficient)?)) + /// Serialize to bytes + pub fn serialize(&self) -> Result, Error> { + self.0.serialize() } /// Returns inner element value @@ -352,21 +318,23 @@ where } /// Returns serialized coefficent commitments - pub fn serialize(&self) -> Result::Serialization>, Error> { - Ok(self - .0 + pub fn serialize(&self) -> Result>, Error> { + self.0 .iter() - .map(|cc| <::Group as Group>::serialize(&cc.value())) - .collect::>()?) + .map(|cc| cc.serialize()) + .collect::>>() } - /// Returns VerifiableSecretSharingCommitment from a vector of serialized CoefficientCommitments - pub fn deserialize( - serialized_coefficient_commitments: Vec<::Serialization>, - ) -> Result> { + /// Returns VerifiableSecretSharingCommitment from a iterator of serialized + /// CoefficientCommitments (e.g. a Vec>). + pub fn deserialize(serialized_coefficient_commitments: I) -> Result> + where + I: IntoIterator, + V: AsRef<[u8]>, + { let mut coefficient_commitments = Vec::new(); - for cc in serialized_coefficient_commitments { - coefficient_commitments.push(CoefficientCommitment::::deserialize(cc)?); + for cc in serialized_coefficient_commitments.into_iter() { + coefficient_commitments.push(CoefficientCommitment::::deserialize(cc.as_ref())?); } Ok(Self::new(coefficient_commitments)) @@ -449,7 +417,7 @@ where /// /// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-14.html#appendix-C.2-4 pub fn verify(&self) -> Result<(VerifyingShare, VerifyingKey), Error> { - let f_result = ::generator() * self.signing_share.0; + let f_result = ::generator() * self.signing_share.to_scalar(); let result = evaluate_vss(self.identifier, &self.commitment); if !(f_result == result) { @@ -579,10 +547,10 @@ fn evaluate_polynomial( ) -> Scalar { let mut value = <::Field>::zero(); - let ell_scalar = identifier; + let ell = identifier; for coeff in coefficients.iter().skip(1).rev() { value = value + *coeff; - value *= ell_scalar; + value = value * ell.to_scalar(); } value = value + *coefficients @@ -600,7 +568,7 @@ fn evaluate_vss( identifier: Identifier, commitment: &VerifiableSecretSharingCommitment, ) -> Element { - let i = identifier; + let i = identifier.to_scalar(); let (_, result) = commitment.0.iter().fold( (<::Field>::one(), ::identity()), @@ -942,7 +910,7 @@ pub fn reconstruct( compute_lagrange_coefficient(&identifiers, None, key_package.identifier)?; // Compute y = f(0) via polynomial interpolation of these t-of-n solutions ('points) of f - secret = secret + (lagrange_coefficient * key_package.signing_share().0); + secret = secret + (lagrange_coefficient * key_package.signing_share().to_scalar()); } Ok(SigningKey { scalar: secret }) diff --git a/frost-core/src/keys/dkg.rs b/frost-core/src/keys/dkg.rs index dd09bda5..177642f1 100644 --- a/frost-core/src/keys/dkg.rs +++ b/frost-core/src/keys/dkg.rs @@ -522,11 +522,11 @@ pub fn part3( // // > Each P_i calculates their long-lived private signing share by computing // > s_i = ∑^n_{ℓ=1} f_ℓ(i), stores s_i securely, and deletes each f_ℓ(i). - signing_share = signing_share + f_ell_i.0; + signing_share = signing_share + f_ell_i.to_scalar(); } signing_share = signing_share + round2_secret_package.secret_share; - let signing_share = SigningShare(signing_share); + let signing_share = SigningShare::new(signing_share); // Round 2, Step 4 // diff --git a/frost-core/src/keys/repairable.rs b/frost-core/src/keys/repairable.rs index 169e0ab8..e8de73b4 100644 --- a/frost-core/src/keys/repairable.rs +++ b/frost-core/src/keys/repairable.rs @@ -56,7 +56,7 @@ fn compute_last_random_value( // Calculate Lagrange Coefficient for helper_i let zeta_i = compute_lagrange_coefficient(helpers, Some(participant), share_i.identifier)?; - let lhs = zeta_i * share_i.signing_share.0; + let lhs = zeta_i * share_i.signing_share.to_scalar(); let mut out: BTreeMap, Scalar> = helpers .iter() @@ -123,7 +123,7 @@ pub fn repair_share_step_3( SecretShare { header: Header::default(), identifier, - signing_share: SigningShare(share), + signing_share: SigningShare::new(share), commitment: commitment.clone(), } } diff --git a/frost-core/src/lib.rs b/frost-core/src/lib.rs index 96c5cba6..c433b99c 100644 --- a/frost-core/src/lib.rs +++ b/frost-core/src/lib.rs @@ -21,6 +21,7 @@ use derive_getters::Getters; #[cfg(any(test, feature = "test-impl"))] use hex::FromHex; use rand_core::{CryptoRng, RngCore}; +use serialization::SerializableScalar; use zeroize::Zeroize; pub mod batch; @@ -57,7 +58,7 @@ pub use verifying_key::VerifyingKey; /// A type refinement for the scalar field element representing the per-message _[challenge]_. /// /// [challenge]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-14.html#name-signature-challenge-computa -#[derive(Clone)] +#[derive(Copy, Clone)] #[cfg_attr(feature = "internals", visibility::make(pub))] #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] pub(crate) struct Challenge( @@ -69,16 +70,21 @@ where C: Ciphersuite, { /// Creates a challenge from a scalar. - #[cfg(feature = "internals")] - pub fn from_scalar( + #[cfg_attr(feature = "internals", visibility::make(pub))] + #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] + #[allow(dead_code)] + pub(crate) fn from_scalar( scalar: <<::Group as Group>::Field as Field>::Scalar, ) -> Self { Self(scalar) } /// Return the underlying scalar. - #[cfg(feature = "internals")] - pub fn to_scalar(self) -> <<::Group as Group>::Field as Field>::Scalar { + #[cfg_attr(feature = "internals", visibility::make(pub))] + #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] + pub(crate) fn to_scalar( + self, + ) -> <<::Group as Group>::Field as Field>::Scalar { self.0 } } @@ -190,8 +196,8 @@ where C: Ciphersuite, { /// Serializes [`BindingFactor`] to bytes. - pub fn serialize(&self) -> <::Field as Field>::Serialization { - <::Field>::serialize(&self.0) + pub fn serialize(&self) -> Vec { + SerializableScalar::(self.0).serialize() } } @@ -306,12 +312,12 @@ fn compute_lagrange_coefficient( } if let Some(x) = x { - num *= x - *x_j; - den *= x_i - *x_j; + num = num * (x.to_scalar() - x_j.to_scalar()); + den = den * (x_i.to_scalar() - x_j.to_scalar()); } else { // Both signs inverted just to avoid requiring Neg (-*xj) - num *= *x_j; - den *= *x_j - x_i; + num = num * x_j.to_scalar(); + den = den * (x_j.to_scalar() - x_i.to_scalar()); } } if !x_i_found { @@ -588,7 +594,7 @@ where let mut z = <::Field>::zero(); for signature_share in signature_shares.values() { - z = z + signature_share.share; + z = z + signature_share.to_scalar(); } let signature = Signature { diff --git a/frost-core/src/round1.rs b/frost-core/src/round1.rs index bfc11c1b..94cb4a88 100644 --- a/frost-core/src/round1.rs +++ b/frost-core/src/round1.rs @@ -13,12 +13,10 @@ use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; use crate::{ - serialization::SerializableElement, Ciphersuite, Element, Error, Field, Group, Header, Scalar, + serialization::{SerializableElement, SerializableScalar}, + Ciphersuite, Element, Error, Field, Group, Header, }; -#[cfg(feature = "serde")] -use crate::serialization::ScalarSerialization; - #[cfg(feature = "serialization")] use crate::serialization::{Deserialize, Serialize}; @@ -28,9 +26,8 @@ use super::{keys::SigningShare, Identifier}; #[derive(Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))] -#[cfg_attr(feature = "serde", serde(try_from = "ScalarSerialization"))] -#[cfg_attr(feature = "serde", serde(into = "ScalarSerialization"))] -pub struct Nonce(pub(super) Scalar); +#[cfg_attr(feature = "serde", serde(transparent))] +pub struct Nonce(pub(super) SerializableScalar); impl Nonce where @@ -55,35 +52,41 @@ where Self::nonce_generate_from_random_bytes(secret, random_bytes) } + fn from_scalar(scalar: <<::Group as Group>::Field as Field>::Scalar) -> Self { + Self(SerializableScalar(scalar)) + } + + pub(crate) fn to_scalar( + self, + ) -> <<::Group as Group>::Field as Field>::Scalar { + self.0 .0 + } + /// Generates a nonce from the given random bytes. /// This function allows testing and MUST NOT be made public. pub(crate) fn nonce_generate_from_random_bytes( secret: &SigningShare, random_bytes: [u8; 32], ) -> Self { - let secret_enc = <::Field>::serialize(&secret.0); + let secret_enc = secret.0.serialize(); let input: Vec = random_bytes .iter() - .chain(secret_enc.as_ref().iter()) + .chain(secret_enc.iter()) .cloned() .collect(); - Self(C::H3(input.as_slice())) + Self::from_scalar(C::H3(input.as_slice())) } /// Deserialize [`Nonce`] from bytes - pub fn deserialize( - bytes: <::Field as Field>::Serialization, - ) -> Result> { - <::Field>::deserialize(&bytes) - .map(|scalar| Self(scalar)) - .map_err(|e| e.into()) + pub fn deserialize(bytes: &[u8]) -> Result> { + Ok(Self(SerializableScalar::deserialize(bytes)?)) } /// Serialize [`Nonce`] to bytes - pub fn serialize(&self) -> <::Field as Field>::Serialization { - <::Field>::serialize(&self.0) + pub fn serialize(&self) -> Vec { + self.0.serialize() } } @@ -92,7 +95,7 @@ where C: Ciphersuite, { fn zeroize(&mut self) { - *self = Nonce(<::Field>::zero()); + *self = Nonce::from_scalar(<::Field>::zero()); } } @@ -105,32 +108,7 @@ where fn from_hex>(hex: T) -> Result { let v: Vec = FromHex::from_hex(hex).map_err(|_| "invalid hex")?; - match v.try_into() { - Ok(bytes) => Self::deserialize(bytes).map_err(|_| "malformed nonce encoding"), - Err(_) => Err("malformed nonce encoding"), - } - } -} - -#[cfg(feature = "serde")] -impl TryFrom> for Nonce -where - C: Ciphersuite, -{ - type Error = Error; - - fn try_from(value: ScalarSerialization) -> Result { - Self::deserialize(value.0) - } -} - -#[cfg(feature = "serde")] -impl From> for ScalarSerialization -where - C: Ciphersuite, -{ - fn from(value: Nonce) -> Self { - Self(value.serialize()) + Self::deserialize(&v).map_err(|_| "malformed nonce encoding") } } @@ -154,15 +132,13 @@ where } /// Deserialize [`NonceCommitment`] from bytes - pub fn deserialize(bytes: ::Serialization) -> Result> { - ::deserialize(&bytes) - .map(|element| Self::new(element)) - .map_err(|e| e.into()) + pub fn deserialize(bytes: &[u8]) -> Result> { + Ok(Self(SerializableElement::deserialize(bytes)?)) } /// Serialize [`NonceCommitment`] to bytes - pub fn serialize(&self) -> Result<::Serialization, Error> { - Ok(::serialize(&self.0 .0)?) + pub fn serialize(&self) -> Result, Error> { + self.0.serialize() } } @@ -196,7 +172,7 @@ where C: Ciphersuite, { fn from(nonce: &Nonce) -> Self { - Self::new(::generator() * nonce.0) + Self::new(::generator() * nonce.to_scalar()) } } @@ -209,12 +185,7 @@ where fn from_hex>(hex: T) -> Result { let v: Vec = FromHex::from_hex(hex).map_err(|_| "invalid hex")?; - match v.try_into() { - Ok(bytes) => { - Self::deserialize(bytes).map_err(|_| "malformed nonce commitment encoding") - } - Err(_) => Err("malformed nonce commitment encoding"), - } + Self::deserialize(&v).map_err(|_| "malformed nonce commitment encoding") } } diff --git a/frost-core/src/round2.rs b/frost-core/src/round2.rs index f71bddef..a244d762 100644 --- a/frost-core/src/round2.rs +++ b/frost-core/src/round2.rs @@ -7,72 +7,46 @@ use crate::{ challenge, Challenge, Ciphersuite, Error, Field, Group, {round1, *}, }; -#[cfg(feature = "serde")] -use crate::serialization::ScalarSerialization; - -// Used to help encoding a SignatureShare. Since it has a Scalar it can't -// be directly encoded with serde, so we use this struct to wrap the scalar. -#[cfg(feature = "serde")] -#[derive(Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))] -#[cfg_attr(feature = "serde", serde(try_from = "ScalarSerialization"))] -#[cfg_attr(feature = "serde", serde(into = "ScalarSerialization"))] -struct SignatureShareHelper(Scalar); - -#[cfg(feature = "serde")] -impl TryFrom> for SignatureShareHelper -where - C: Ciphersuite, -{ - type Error = Error; - - fn try_from(value: ScalarSerialization) -> Result { - <::Field>::deserialize(&value.0) - .map(|scalar| Self(scalar)) - .map_err(|e| e.into()) - } -} - -#[cfg(feature = "serde")] -impl From> for ScalarSerialization -where - C: Ciphersuite, -{ - fn from(value: SignatureShareHelper) -> Self { - Self(<::Field>::serialize(&value.0)) - } -} - /// A participant's signature share, which the coordinator will aggregate with all other signer's /// shares into the joint signature. #[derive(Clone, Copy, Eq, PartialEq, Getters)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))] #[cfg_attr(feature = "serde", serde(deny_unknown_fields))] -#[cfg_attr(feature = "serde", serde(try_from = "SignatureShareSerialization"))] -#[cfg_attr(feature = "serde", serde(into = "SignatureShareSerialization"))] +#[cfg_attr(feature = "serde", serde(transparent))] pub struct SignatureShare { /// This participant's signature over the message. - pub(crate) share: Scalar, + pub(crate) share: SerializableScalar, } impl SignatureShare where C: Ciphersuite, { + pub(crate) fn new( + scalar: <<::Group as Group>::Field as Field>::Scalar, + ) -> Self { + Self { + share: SerializableScalar(scalar), + } + } + + pub(crate) fn to_scalar( + self, + ) -> <<::Group as Group>::Field as Field>::Scalar { + self.share.0 + } + /// Deserialize [`SignatureShare`] from bytes - pub fn deserialize( - bytes: <::Field as Field>::Serialization, - ) -> Result> { - <::Field>::deserialize(&bytes) - .map(|scalar| Self { share: scalar }) - .map_err(|e| e.into()) + pub fn deserialize(bytes: &[u8]) -> Result> { + Ok(Self { + share: SerializableScalar::deserialize(bytes)?, + }) } /// Serialize [`SignatureShare`] to bytes - pub fn serialize(&self) -> <::Field as Field>::Serialization { - <::Field>::serialize(&self.share) + pub fn serialize(&self) -> Vec { + self.share.serialize() } /// Tests if a signature share issued by a participant is valid before @@ -92,7 +66,7 @@ where lambda_i: Scalar, challenge: &Challenge, ) -> Result<(), Error> { - if (::generator() * self.share) + if (::generator() * self.to_scalar()) != (group_commitment_share.0 + (verifying_share.to_element() * challenge.0 * lambda_i)) { return Err(Error::InvalidSignatureShare { @@ -104,41 +78,6 @@ where } } -#[cfg(feature = "serde")] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] -struct SignatureShareSerialization { - /// Serialization header - pub(crate) header: Header, - share: SignatureShareHelper, -} - -#[cfg(feature = "serde")] -impl From> for SignatureShare -where - C: Ciphersuite, -{ - fn from(value: SignatureShareSerialization) -> Self { - Self { - share: value.share.0, - } - } -} - -#[cfg(feature = "serde")] -impl From> for SignatureShareSerialization -where - C: Ciphersuite, -{ - fn from(value: SignatureShare) -> Self { - Self { - header: Header::default(), - share: SignatureShareHelper(value.share), - } - } -} - impl Debug for SignatureShare where C: Ciphersuite, @@ -160,11 +99,11 @@ fn compute_signature_share( key_package: &keys::KeyPackage, challenge: Challenge, ) -> SignatureShare { - let z_share: <::Field as Field>::Scalar = signer_nonces.hiding.0 - + (signer_nonces.binding.0 * binding_factor.0) - + (lambda_i * key_package.signing_share.0 * challenge.0); + let z_share: <::Field as Field>::Scalar = signer_nonces.hiding.to_scalar() + + (signer_nonces.binding.to_scalar() * binding_factor.0) + + (lambda_i * key_package.signing_share.to_scalar() * challenge.to_scalar()); - SignatureShare:: { share: z_share } + SignatureShare::::new(z_share) } /// Performed once by each participant selected for the signing operation. diff --git a/frost-core/src/serialization.rs b/frost-core/src/serialization.rs index eda0bdec..fe6afd4f 100644 --- a/frost-core/src/serialization.rs +++ b/frost-core/src/serialization.rs @@ -1,25 +1,41 @@ //! Serialization support. -use crate::Ciphersuite; +use crate::{Ciphersuite, FieldError}; -#[cfg(feature = "serde")] -use crate::{Field, Group}; - -#[cfg(feature = "serialization")] -use crate::Error; - -use crate::Element; +use crate::{Element, Error, Field, Group}; -#[cfg(feature = "serde")] +#[derive(Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "internals", visibility::make(pub))] #[cfg_attr(docsrs, doc(cfg(feature = "internals")))] /// Helper struct to serialize a Scalar. -pub(crate) struct ScalarSerialization( - pub <<::Group as Group>::Field as Field>::Serialization, +pub(crate) struct SerializableScalar( + pub <<::Group as Group>::Field as Field>::Scalar, ); +impl SerializableScalar +where + C: Ciphersuite, +{ + /// Serialize a Scalar. + pub fn serialize(&self) -> Vec { + <::Field>::serialize(&self.0) + .as_ref() + .to_vec() + } + + /// Deserialize a Scalar from a serialized buffer. + pub fn deserialize(bytes: &[u8]) -> Result> { + let serialized: <::Field as Field>::Serialization = bytes + .to_vec() + .try_into() + .map_err(|_| FieldError::MalformedScalar)?; + let scalar = <::Field>::deserialize(&serialized)?; + Ok(Self(scalar)) + } +} + #[cfg(feature = "serde")] -impl serde::Serialize for ScalarSerialization +impl serde::Serialize for SerializableScalar where C: Ciphersuite, { @@ -27,12 +43,13 @@ where where S: serde::Serializer, { - serdect::array::serialize_hex_lower_or_bin(&self.0.as_ref(), serializer) + let serialized = <::Group as Group>::Field::serialize(&self.0); + serdect::array::serialize_hex_lower_or_bin(&serialized.as_ref(), serializer) } } #[cfg(feature = "serde")] -impl<'de, C> serde::Deserialize<'de> for ScalarSerialization +impl<'de, C> serde::Deserialize<'de> for SerializableScalar where C: Ciphersuite, { @@ -51,13 +68,36 @@ where let array = bytes .try_into() .map_err(|_| serde::de::Error::custom("invalid byte length"))?; - Ok(Self(array)) + <::Group as Group>::Field::deserialize(&array) + .map(|scalar| Self(scalar)) + .map_err(serde::de::Error::custom) } } #[derive(Clone, Copy, PartialEq, Eq)] pub(crate) struct SerializableElement(pub(crate) Element); +impl SerializableElement +where + C: Ciphersuite, +{ + /// Serialize an Element. Returns and error if it's the identity. + pub fn serialize(&self) -> Result, Error> { + Ok(::serialize(&self.0)?.as_ref().to_vec()) + } + + /// Deserialized an Element. Returns an error if it's malformed or is the + /// identity. + pub fn deserialize(bytes: &[u8]) -> Result> { + let serialized: ::Serialization = bytes + .to_vec() + .try_into() + .map_err(|_| FieldError::MalformedScalar)?; + let scalar = ::deserialize(&serialized)?; + Ok(Self(scalar)) + } +} + #[cfg(feature = "serde")] impl serde::Serialize for SerializableElement where diff --git a/frost-core/src/signature.rs b/frost-core/src/signature.rs index a55b0db2..5df7d89c 100644 --- a/frost-core/src/signature.rs +++ b/frost-core/src/signature.rs @@ -1,7 +1,5 @@ //! Schnorr signatures over prime order groups (or subgroups) -use debugless_unwrap::DebuglessUnwrap; - use crate::{Ciphersuite, Element, Error, Field, Group, Scalar}; /// A Schnorr signature over some prime order group (or subgroup). @@ -30,34 +28,30 @@ where } /// Converts bytes as [`Ciphersuite::SignatureSerialization`] into a `Signature`. - pub fn deserialize(bytes: C::SignatureSerialization) -> Result> { + pub fn deserialize(bytes: &[u8]) -> Result> { // To compute the expected length of the encoded point, encode the generator // and get its length. Note that we can't use the identity because it can be encoded // shorter in some cases (e.g. P-256, which uses SEC1 encoding). let generator = ::generator(); let mut R_bytes = Vec::from(::serialize(&generator)?.as_ref()); - let R_bytes_len = R_bytes.len(); - R_bytes[..].copy_from_slice( - bytes - .as_ref() - .get(0..R_bytes_len) - .ok_or(Error::MalformedSignature)?, - ); - - let R_serialization = &R_bytes.try_into().map_err(|_| Error::MalformedSignature)?; - let one = <::Field as Field>::zero(); let mut z_bytes = Vec::from(<::Field as Field>::serialize(&one).as_ref()); - let z_bytes_len = z_bytes.len(); + if bytes.len() != R_bytes_len + z_bytes_len { + return Err(Error::MalformedSignature); + } + + R_bytes[..].copy_from_slice(bytes.get(0..R_bytes_len).ok_or(Error::MalformedSignature)?); + + let R_serialization = &R_bytes.try_into().map_err(|_| Error::MalformedSignature)?; + // We extract the exact length of bytes we expect, not just the remaining bytes with `bytes[R_bytes_len..]` z_bytes[..].copy_from_slice( bytes - .as_ref() .get(R_bytes_len..R_bytes_len + z_bytes_len) .ok_or(Error::MalformedSignature)?, ); @@ -70,14 +64,14 @@ where }) } - /// Converts this signature to its [`Ciphersuite::SignatureSerialization`] in bytes. - pub fn serialize(&self) -> Result> { + /// Converts this signature to its byte serialization. + pub fn serialize(&self) -> Result, Error> { let mut bytes = vec![]; bytes.extend(::serialize(&self.R)?.as_ref()); bytes.extend(<::Field>::serialize(&self.z).as_ref()); - Ok(bytes.try_into().debugless_unwrap()) + Ok(bytes) } } @@ -93,10 +87,7 @@ where S: serde::Serializer, { serdect::slice::serialize_hex_lower_or_bin( - &self - .serialize() - .map_err(serde::ser::Error::custom)? - .as_ref(), + &self.serialize().map_err(serde::ser::Error::custom)?, serializer, ) } @@ -114,12 +105,9 @@ where D: serde::Deserializer<'de>, { let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?; - let array = bytes - .try_into() - .map_err(|_| serde::de::Error::custom("invalid byte length"))?; - let identifier = Signature::deserialize(array) + let signature = Signature::deserialize(&bytes) .map_err(|err| serde::de::Error::custom(format!("{err}")))?; - Ok(identifier) + Ok(signature) } } diff --git a/frost-core/src/signing_key.rs b/frost-core/src/signing_key.rs index 03e13156..7032e37e 100644 --- a/frost-core/src/signing_key.rs +++ b/frost-core/src/signing_key.rs @@ -2,7 +2,10 @@ use rand_core::{CryptoRng, RngCore}; -use crate::{random_nonzero, Ciphersuite, Error, Field, Group, Scalar, Signature, VerifyingKey}; +use crate::{ + random_nonzero, serialization::SerializableScalar, Ciphersuite, Error, Field, Group, Scalar, + Signature, VerifyingKey, +}; /// A signing key for a Schnorr signature on a FROST [`Ciphersuite::Group`]. #[derive(Copy, Clone, PartialEq, Eq)] @@ -25,18 +28,13 @@ where } /// Deserialize from bytes - pub fn deserialize( - bytes: <::Field as Field>::Serialization, - ) -> Result, Error> { - let scalar = - <::Field as Field>::deserialize(&bytes).map_err(Error::from)?; - - Self::from_scalar(scalar) + pub fn deserialize(bytes: &[u8]) -> Result, Error> { + Self::from_scalar(SerializableScalar::deserialize(bytes)?.0) } /// Serialize `SigningKey` to bytes - pub fn serialize(&self) -> <::Field as Field>::Serialization { - <::Field as Field>::serialize(&self.scalar) + pub fn serialize(&self) -> Vec { + SerializableScalar::(self.scalar).serialize() } /// Create a signature `msg` using this `SigningKey`. diff --git a/frost-core/src/tests/ciphersuite_generic.rs b/frost-core/src/tests/ciphersuite_generic.rs index 5fdba722..0adf1d1f 100644 --- a/frost-core/src/tests/ciphersuite_generic.rs +++ b/frost-core/src/tests/ciphersuite_generic.rs @@ -15,7 +15,7 @@ use crate::Ciphersuite; pub fn check_zero_key_fails() { let zero = <<::Group as Group>::Field>::zero(); let encoded_zero = <<::Group as Group>::Field>::serialize(&zero); - let r = SigningKey::::deserialize(encoded_zero); + let r = SigningKey::::deserialize(encoded_zero.as_ref()); assert_eq!(r, Err(Error::MalformedSigningKey)); } @@ -47,9 +47,8 @@ pub fn check_share_generation(mut rng: R assert_eq!( frost::keys::reconstruct::(&key_packages) .unwrap() - .serialize() - .as_ref(), - secret.serialize().as_ref() + .serialize(), + secret.serialize() ); // Test error cases @@ -332,10 +331,13 @@ fn check_aggregate_corrupted_share( mut signature_shares: BTreeMap, frost::round2::SignatureShare>, pubkey_package: frost::keys::PublicKeyPackage, ) { + use crate::round2::SignatureShare; + let one = <::Group as Group>::Field::one(); // Corrupt a share let id = *signature_shares.keys().next().unwrap(); - signature_shares.get_mut(&id).unwrap().share = signature_shares[&id].share + one; + *signature_shares.get_mut(&id).unwrap() = + SignatureShare::new(signature_shares[&id].to_scalar() + one); let e = frost::aggregate(&signing_package, &signature_shares, &pubkey_package).unwrap_err(); assert_eq!(e.culprit(), Some(id)); assert_eq!(e, Error::InvalidSignatureShare { culprit: id }); diff --git a/frost-core/src/tests/coefficient_commitment.rs b/frost-core/src/tests/coefficient_commitment.rs index 6218d167..92e2f345 100644 --- a/frost-core/src/tests/coefficient_commitment.rs +++ b/frost-core/src/tests/coefficient_commitment.rs @@ -22,7 +22,7 @@ pub fn check_serialization_of_coefficient_commitment::serialize(&element).unwrap(); let coeff_commitment = - frost::keys::CoefficientCommitment::::deserialize(serialized_element).unwrap(); + frost::keys::CoefficientCommitment::::deserialize(serialized_element.as_ref()).unwrap(); assert!(expected == coeff_commitment); } @@ -50,7 +50,8 @@ pub fn check_create_coefficient_commitment_error( ) .debugless_unwrap(); - let coeff_commitment = frost::keys::CoefficientCommitment::::deserialize(serialized); + let coeff_commitment = + frost::keys::CoefficientCommitment::::deserialize(serialized.as_ref()); assert!(coeff_commitment.is_err()); } diff --git a/frost-core/src/tests/proptests.rs b/frost-core/src/tests/proptests.rs index 06a3925f..9b0fbcb9 100644 --- a/frost-core/src/tests/proptests.rs +++ b/frost-core/src/tests/proptests.rs @@ -60,11 +60,11 @@ where // conversion to raw bytes to exercise those code paths. let _sig = { let bytes = self.sig.serialize().unwrap(); - Signature::::deserialize(bytes) + Signature::::deserialize(&bytes) }; // Check that the verification key is a valid key. - let _pub_key = VerifyingKey::::deserialize(self.vk.serialize().unwrap()) + let _pub_key = VerifyingKey::::deserialize(&self.vk.serialize().unwrap()) .expect("The test verification key to be well-formed."); // Check that signature validation has the expected result. diff --git a/frost-core/src/tests/repairable.rs b/frost-core/src/tests/repairable.rs index 8c187a85..671f255f 100644 --- a/frost-core/src/tests/repairable.rs +++ b/frost-core/src/tests/repairable.rs @@ -142,7 +142,7 @@ pub fn check_repair_share_step_1(mut rng rhs = rhs + v; } - let lhs = lagrange_coefficient * helper_4.signing_share.0; + let lhs = lagrange_coefficient * helper_4.signing_share.to_scalar(); assert!(lhs == rhs) } @@ -202,7 +202,7 @@ pub fn check_repair_share_step_3( generate_scalar_from_byte_string::(sigmas["sigma_sum"].as_str().unwrap()); let actual: SecretShare = SecretShare::new( Identifier::try_from(2).unwrap(), - SigningShare(actual_sigma), + SigningShare::new(actual_sigma), commitment, ); diff --git a/frost-core/src/tests/vectors.rs b/frost-core/src/tests/vectors.rs index 837e8929..be483e40 100644 --- a/frost-core/src/tests/vectors.rs +++ b/frost-core/src/tests/vectors.rs @@ -34,8 +34,7 @@ pub fn parse_test_vectors(json_vectors: &Value) -> TestVectors(json_vectors: &Value) -> TestVectors::Field as Field>::Serialization::try_from( - hex::decode(signer["sig_share"].as_str().unwrap()).unwrap(), - ) - .debugless_unwrap(); + let sig_share = hex::decode(signer["sig_share"].as_str().unwrap()).unwrap(); - let signature_share = SignatureShare::::deserialize(sig_share).unwrap(); + let signature_share = SignatureShare::::deserialize(&sig_share).unwrap(); signature_shares.insert(i.try_into().unwrap(), signature_share); } diff --git a/frost-core/src/tests/vectors_dkg.rs b/frost-core/src/tests/vectors_dkg.rs index 1b06a21a..b05f53f5 100644 --- a/frost-core/src/tests/vectors_dkg.rs +++ b/frost-core/src/tests/vectors_dkg.rs @@ -66,7 +66,8 @@ pub fn parse_test_vectors_dkg(json_vectors: &Value) -> DKGTestVe round2_packages.insert(participant_2_id, build_round_2_package(json_vectors, 2)); round2_packages.insert(participant_3_id, build_round_2_package(json_vectors, 3)); - let secret = SigningKey::deserialize(json_to_scalar::(&participant["signing_key"])).unwrap(); + let secret = + SigningKey::deserialize(json_to_scalar::(&participant["signing_key"]).as_ref()).unwrap(); let coefficient = <::Field as Field>::deserialize(&json_to_scalar::( &participant["coefficient"], @@ -76,13 +77,15 @@ pub fn parse_test_vectors_dkg(json_vectors: &Value) -> DKGTestVe let public_key_package = build_public_key_package(json_vectors); let verifying_share = - VerifyingShare::deserialize(json_to_element::(&participant["verifying_share"])).unwrap(); + VerifyingShare::deserialize(json_to_element::(&participant["verifying_share"]).as_ref()) + .unwrap(); let verifying_key = - VerifyingKey::deserialize(json_to_element::(&inputs["verifying_key"])).unwrap(); + VerifyingKey::deserialize(json_to_element::(&inputs["verifying_key"]).as_ref()).unwrap(); let signing_share = - SigningShare::deserialize(json_to_scalar::(&participant["signing_share"])).unwrap(); + SigningShare::deserialize(json_to_scalar::(&participant["signing_share"]).as_ref()) + .unwrap(); let key_package = KeyPackage { header: Header::default(), @@ -114,18 +117,15 @@ fn build_round_1_package( .as_array() .unwrap() .iter() - .map(|v| json_to_element::(v)) - .collect(); + .map(|v| json_to_element::(v).as_ref().to_vec()) + .collect::>>(); let commitment = VerifiableSecretSharingCommitment::deserialize(vss_commitment).unwrap(); let proof_of_knowledge = Signature::deserialize( - C::SignatureSerialization::try_from( - hex::decode(participant["proof_of_knowledge"].as_str().unwrap()).unwrap(), - ) - .debugless_unwrap(), + &hex::decode(participant["proof_of_knowledge"].as_str().unwrap()).unwrap(), ) - .unwrap(); + .debugless_unwrap(); Round1Package { header: Header::default(), @@ -140,9 +140,9 @@ fn build_round_2_package( ) -> Round2Package { let inputs = &json_vectors["inputs"]; - let signing_share = SigningShare::deserialize(json_to_scalar::( - &inputs["1"]["signing_shares"][sender_num.to_string()], - )) + let signing_share = SigningShare::deserialize( + json_to_scalar::(&inputs["1"]["signing_shares"][sender_num.to_string()]).as_ref(), + ) .unwrap(); Round2Package { @@ -163,15 +163,15 @@ fn build_public_key_package(json_vectors: &Value) -> PublicKeyPa as u16) .try_into() .unwrap(); - let verifying_share = VerifyingShare::deserialize(json_to_element::( - &inputs[i.to_string()]["verifying_share"], - )) + let verifying_share = VerifyingShare::deserialize( + json_to_element::(&inputs[i.to_string()]["verifying_share"]).as_ref(), + ) .unwrap(); verifying_shares.insert(participant_id, verifying_share); } let verifying_key = - VerifyingKey::deserialize(json_to_element::(&inputs["verifying_key"])).unwrap(); + VerifyingKey::deserialize(json_to_element::(&inputs["verifying_key"]).as_ref()).unwrap(); PublicKeyPackage { header: Header::default(), diff --git a/frost-core/src/tests/vss_commitment.rs b/frost-core/src/tests/vss_commitment.rs index 31b5d4cb..2b975a83 100644 --- a/frost-core/src/tests/vss_commitment.rs +++ b/frost-core/src/tests/vss_commitment.rs @@ -45,7 +45,7 @@ pub fn check_serialize_vss_commitment(mu assert!(expected .iter() .zip(vss_commitment.iter()) - .all(|(e, c)| e.as_ref() == c.as_ref())); + .all(|(e, c)| e.as_ref() == c)); } /// Test deserialize VerifiableSecretSharingCommitment diff --git a/frost-core/src/verifying_key.rs b/frost-core/src/verifying_key.rs index 2effd05e..fc533c2f 100644 --- a/frost-core/src/verifying_key.rs +++ b/frost-core/src/verifying_key.rs @@ -38,17 +38,13 @@ where } /// Deserialize from bytes - pub fn deserialize( - bytes: ::Serialization, - ) -> Result, Error> { - ::deserialize(&bytes) - .map(|element| VerifyingKey::new(element)) - .map_err(|e| e.into()) + pub fn deserialize(bytes: &[u8]) -> Result, Error> { + Ok(Self::new(SerializableElement::deserialize(bytes)?.0)) } /// Serialize `VerifyingKey` to bytes - pub fn serialize(&self) -> Result<::Serialization, Error> { - Ok(::serialize(&self.element.0)?) + pub fn serialize(&self) -> Result, Error> { + self.element.serialize() } /// Verify a purported `signature` with a pre-hashed [`Challenge`] made by this verification @@ -118,9 +114,6 @@ where fn from_hex>(hex: T) -> Result { let v: Vec = FromHex::from_hex(hex).map_err(|_| "invalid hex")?; - match v.try_into() { - Ok(bytes) => Self::deserialize(bytes).map_err(|_| "malformed verifying key encoding"), - Err(_) => Err("malformed verifying key encoding"), - } + Self::deserialize(&v).map_err(|_| "malformed verifying key encoding") } } diff --git a/frost-ed25519/tests/helpers/mod.rs b/frost-ed25519/tests/helpers/mod.rs index ec68f588..2a936ac3 100644 --- a/frost-ed25519/tests/helpers/mod.rs +++ b/frost-ed25519/tests/helpers/mod.rs @@ -14,11 +14,11 @@ pub fn verify_signature( group_pubkey: frost_core::VerifyingKey, ) { let sig = { - let bytes: [u8; 64] = group_signature.serialize().unwrap(); + let bytes: [u8; 64] = group_signature.serialize().unwrap().try_into().unwrap(); ed25519_dalek::Signature::from(bytes) }; let pub_key = { - let bytes = group_pubkey.serialize().unwrap(); + let bytes = group_pubkey.serialize().unwrap().try_into().unwrap(); ed25519_dalek::VerifyingKey::from_bytes(&bytes).unwrap() }; // Check that signature validation has the expected result. diff --git a/frost-ed25519/tests/helpers/samples.rs b/frost-ed25519/tests/helpers/samples.rs index 9f9cc79f..6f22aed3 100644 --- a/frost-ed25519/tests/helpers/samples.rs +++ b/frost-ed25519/tests/helpers/samples.rs @@ -36,8 +36,8 @@ fn scalar1() -> Scalar { pub fn signing_nonces() -> SigningNonces { let serialized_scalar1 = <::Group as Group>::Field::serialize(&scalar1()); let serialized_scalar2 = <::Group as Group>::Field::serialize(&scalar1()); - let hiding_nonce = Nonce::deserialize(serialized_scalar1).unwrap(); - let binding_nonce = Nonce::deserialize(serialized_scalar2).unwrap(); + let hiding_nonce = Nonce::deserialize(serialized_scalar1.as_ref()).unwrap(); + let binding_nonce = Nonce::deserialize(serialized_scalar2.as_ref()).unwrap(); SigningNonces::from_nonces(hiding_nonce, binding_nonce) } @@ -46,8 +46,10 @@ pub fn signing_nonces() -> SigningNonces { pub fn signing_commitments() -> SigningCommitments { let serialized_element1 = ::Group::serialize(&element1()).unwrap(); let serialized_element2 = ::Group::serialize(&element2()).unwrap(); - let hiding_nonce_commitment = NonceCommitment::deserialize(serialized_element1).unwrap(); - let binding_nonce_commitment = NonceCommitment::deserialize(serialized_element2).unwrap(); + let hiding_nonce_commitment = + NonceCommitment::deserialize(serialized_element1.as_ref()).unwrap(); + let binding_nonce_commitment = + NonceCommitment::deserialize(serialized_element2.as_ref()).unwrap(); SigningCommitments::new(hiding_nonce_commitment, binding_nonce_commitment) } @@ -65,7 +67,7 @@ pub fn signing_package() -> SigningPackage { pub fn signature_share() -> SignatureShare { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - SignatureShare::deserialize(serialized_scalar).unwrap() + SignatureShare::deserialize(serialized_scalar.as_ref()).unwrap() } /// Generate a sample SecretShare. @@ -73,7 +75,7 @@ pub fn secret_share() -> SecretShare { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); @@ -85,10 +87,10 @@ pub fn key_package() -> KeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); KeyPackage::new(identifier, signing_share, verifying_share, verifying_key, 2) } @@ -97,9 +99,9 @@ pub fn key_package() -> KeyPackage { pub fn public_key_package() -> PublicKeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); let verifying_shares = BTreeMap::from([(identifier, verifying_share)]); PublicKeyPackage::new(verifying_shares, verifying_key) @@ -114,12 +116,10 @@ pub fn round1_package() -> round1::Package { .iter() .chain(serialized_scalar.as_ref().iter()) .cloned() - .collect::>() - .try_into() - .unwrap(); + .collect::>(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); - let signature = Signature::deserialize(serialized_signature).unwrap(); + let signature = Signature::deserialize(&serialized_signature).unwrap(); round1::Package::new(vss_commitment, signature) } @@ -127,7 +127,7 @@ pub fn round1_package() -> round1::Package { /// Generate a sample round2::Package. pub fn round2_package() -> round2::Package { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); round2::Package::new(signing_share) } diff --git a/frost-ed25519/tests/recreation_tests.rs b/frost-ed25519/tests/recreation_tests.rs index 7fa11b79..0b1d44f1 100644 --- a/frost-ed25519/tests/recreation_tests.rs +++ b/frost-ed25519/tests/recreation_tests.rs @@ -54,7 +54,7 @@ fn check_signature_share_recreation() { let encoded = signature_share.serialize(); - let new_signature_share = SignatureShare::deserialize(encoded).unwrap(); + let new_signature_share = SignatureShare::deserialize(&encoded).unwrap(); assert!(signature_share == new_signature_share); } diff --git a/frost-ed25519/tests/serialization_tests.rs b/frost-ed25519/tests/serialization_tests.rs index fbe26a41..9acd53be 100644 --- a/frost-ed25519/tests/serialization_tests.rs +++ b/frost-ed25519/tests/serialization_tests.rs @@ -49,8 +49,11 @@ fn check_signing_package_postcard_serialization() { fn check_signature_share_postcard_serialization() { let signature_share = samples::signature_share(); let bytes = signature_share.serialize(); - assert_snapshot!(hex::encode(bytes)); - assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signature_share, + SignatureShare::deserialize(&bytes).unwrap() + ); } #[test] fn check_secret_share_postcard_serialization() { diff --git a/frost-ed448/tests/helpers/samples.rs b/frost-ed448/tests/helpers/samples.rs index 10d077f2..ec556736 100644 --- a/frost-ed448/tests/helpers/samples.rs +++ b/frost-ed448/tests/helpers/samples.rs @@ -36,8 +36,8 @@ fn scalar1() -> Scalar { pub fn signing_nonces() -> SigningNonces { let serialized_scalar1 = <::Group as Group>::Field::serialize(&scalar1()); let serialized_scalar2 = <::Group as Group>::Field::serialize(&scalar1()); - let hiding_nonce = Nonce::deserialize(serialized_scalar1).unwrap(); - let binding_nonce = Nonce::deserialize(serialized_scalar2).unwrap(); + let hiding_nonce = Nonce::deserialize(serialized_scalar1.as_ref()).unwrap(); + let binding_nonce = Nonce::deserialize(serialized_scalar2.as_ref()).unwrap(); SigningNonces::from_nonces(hiding_nonce, binding_nonce) } @@ -46,8 +46,10 @@ pub fn signing_nonces() -> SigningNonces { pub fn signing_commitments() -> SigningCommitments { let serialized_element1 = ::Group::serialize(&element1()).unwrap(); let serialized_element2 = ::Group::serialize(&element2()).unwrap(); - let hiding_nonce_commitment = NonceCommitment::deserialize(serialized_element1).unwrap(); - let binding_nonce_commitment = NonceCommitment::deserialize(serialized_element2).unwrap(); + let hiding_nonce_commitment = + NonceCommitment::deserialize(serialized_element1.as_ref()).unwrap(); + let binding_nonce_commitment = + NonceCommitment::deserialize(serialized_element2.as_ref()).unwrap(); SigningCommitments::new(hiding_nonce_commitment, binding_nonce_commitment) } @@ -65,7 +67,7 @@ pub fn signing_package() -> SigningPackage { pub fn signature_share() -> SignatureShare { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - SignatureShare::deserialize(serialized_scalar).unwrap() + SignatureShare::deserialize(serialized_scalar.as_ref()).unwrap() } /// Generate a sample SecretShare. @@ -73,7 +75,7 @@ pub fn secret_share() -> SecretShare { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); @@ -85,10 +87,10 @@ pub fn key_package() -> KeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); KeyPackage::new(identifier, signing_share, verifying_share, verifying_key, 2) } @@ -97,9 +99,9 @@ pub fn key_package() -> KeyPackage { pub fn public_key_package() -> PublicKeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); let verifying_shares = BTreeMap::from([(identifier, verifying_share)]); PublicKeyPackage::new(verifying_shares, verifying_key) @@ -114,12 +116,10 @@ pub fn round1_package() -> round1::Package { .iter() .chain(serialized_scalar.as_ref().iter()) .cloned() - .collect::>() - .try_into() - .unwrap(); + .collect::>(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); - let signature = Signature::deserialize(serialized_signature).unwrap(); + let signature = Signature::deserialize(&serialized_signature).unwrap(); round1::Package::new(vss_commitment, signature) } @@ -127,7 +127,7 @@ pub fn round1_package() -> round1::Package { /// Generate a sample round2::Package. pub fn round2_package() -> round2::Package { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); round2::Package::new(signing_share) } diff --git a/frost-ed448/tests/recreation_tests.rs b/frost-ed448/tests/recreation_tests.rs index 1caababa..e51f8b6e 100644 --- a/frost-ed448/tests/recreation_tests.rs +++ b/frost-ed448/tests/recreation_tests.rs @@ -54,7 +54,7 @@ fn check_signature_share_recreation() { let encoded = signature_share.serialize(); - let new_signature_share = SignatureShare::deserialize(encoded).unwrap(); + let new_signature_share = SignatureShare::deserialize(&encoded).unwrap(); assert!(signature_share == new_signature_share); } diff --git a/frost-ed448/tests/serialization_tests.rs b/frost-ed448/tests/serialization_tests.rs index 761e56b7..60a56b9a 100644 --- a/frost-ed448/tests/serialization_tests.rs +++ b/frost-ed448/tests/serialization_tests.rs @@ -49,8 +49,11 @@ fn check_signing_package_postcard_serialization() { fn check_signature_share_postcard_serialization() { let signature_share = samples::signature_share(); let bytes = signature_share.serialize(); - assert_snapshot!(hex::encode(bytes)); - assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signature_share, + SignatureShare::deserialize(&bytes).unwrap() + ); } #[test] fn check_secret_share_postcard_serialization() { diff --git a/frost-p256/tests/helpers/samples.rs b/frost-p256/tests/helpers/samples.rs index 8e5cc484..340bc763 100644 --- a/frost-p256/tests/helpers/samples.rs +++ b/frost-p256/tests/helpers/samples.rs @@ -36,8 +36,8 @@ fn scalar1() -> Scalar { pub fn signing_nonces() -> SigningNonces { let serialized_scalar1 = <::Group as Group>::Field::serialize(&scalar1()); let serialized_scalar2 = <::Group as Group>::Field::serialize(&scalar1()); - let hiding_nonce = Nonce::deserialize(serialized_scalar1).unwrap(); - let binding_nonce = Nonce::deserialize(serialized_scalar2).unwrap(); + let hiding_nonce = Nonce::deserialize(serialized_scalar1.as_ref()).unwrap(); + let binding_nonce = Nonce::deserialize(serialized_scalar2.as_ref()).unwrap(); SigningNonces::from_nonces(hiding_nonce, binding_nonce) } @@ -46,8 +46,10 @@ pub fn signing_nonces() -> SigningNonces { pub fn signing_commitments() -> SigningCommitments { let serialized_element1 = ::Group::serialize(&element1()).unwrap(); let serialized_element2 = ::Group::serialize(&element2()).unwrap(); - let hiding_nonce_commitment = NonceCommitment::deserialize(serialized_element1).unwrap(); - let binding_nonce_commitment = NonceCommitment::deserialize(serialized_element2).unwrap(); + let hiding_nonce_commitment = + NonceCommitment::deserialize(serialized_element1.as_ref()).unwrap(); + let binding_nonce_commitment = + NonceCommitment::deserialize(serialized_element2.as_ref()).unwrap(); SigningCommitments::new(hiding_nonce_commitment, binding_nonce_commitment) } @@ -65,7 +67,7 @@ pub fn signing_package() -> SigningPackage { pub fn signature_share() -> SignatureShare { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - SignatureShare::deserialize(serialized_scalar).unwrap() + SignatureShare::deserialize(serialized_scalar.as_ref()).unwrap() } /// Generate a sample SecretShare. @@ -73,7 +75,7 @@ pub fn secret_share() -> SecretShare { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); @@ -85,10 +87,10 @@ pub fn key_package() -> KeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); KeyPackage::new(identifier, signing_share, verifying_share, verifying_key, 2) } @@ -97,9 +99,9 @@ pub fn key_package() -> KeyPackage { pub fn public_key_package() -> PublicKeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); let verifying_shares = BTreeMap::from([(identifier, verifying_share)]); PublicKeyPackage::new(verifying_shares, verifying_key) @@ -114,12 +116,10 @@ pub fn round1_package() -> round1::Package { .iter() .chain(serialized_scalar.as_ref().iter()) .cloned() - .collect::>() - .try_into() - .unwrap(); + .collect::>(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); - let signature = Signature::deserialize(serialized_signature).unwrap(); + let signature = Signature::deserialize(&serialized_signature).unwrap(); round1::Package::new(vss_commitment, signature) } @@ -127,7 +127,7 @@ pub fn round1_package() -> round1::Package { /// Generate a sample round2::Package. pub fn round2_package() -> round2::Package { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); round2::Package::new(signing_share) } diff --git a/frost-p256/tests/recreation_tests.rs b/frost-p256/tests/recreation_tests.rs index 41ea2802..a24e57f5 100644 --- a/frost-p256/tests/recreation_tests.rs +++ b/frost-p256/tests/recreation_tests.rs @@ -54,7 +54,7 @@ fn check_signature_share_recreation() { let encoded = signature_share.serialize(); - let new_signature_share = SignatureShare::deserialize(encoded).unwrap(); + let new_signature_share = SignatureShare::deserialize(&encoded).unwrap(); assert!(signature_share == new_signature_share); } diff --git a/frost-p256/tests/serialization_tests.rs b/frost-p256/tests/serialization_tests.rs index a920b6c2..187e7fc9 100644 --- a/frost-p256/tests/serialization_tests.rs +++ b/frost-p256/tests/serialization_tests.rs @@ -49,8 +49,11 @@ fn check_signing_package_postcard_serialization() { fn check_signature_share_postcard_serialization() { let signature_share = samples::signature_share(); let bytes = signature_share.serialize(); - assert_snapshot!(hex::encode(bytes)); - assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signature_share, + SignatureShare::deserialize(&bytes).unwrap() + ); } #[test] fn check_secret_share_postcard_serialization() { diff --git a/frost-rerandomized/src/lib.rs b/frost-rerandomized/src/lib.rs index 72d4f7de..29536ab1 100644 --- a/frost-rerandomized/src/lib.rs +++ b/frost-rerandomized/src/lib.rs @@ -22,13 +22,12 @@ pub use frost_core; use frost_core::{ self as frost, keys::{KeyPackage, PublicKeyPackage, SigningShare, VerifyingShare}, + serialization::SerializableScalar, Ciphersuite, Error, Field, Group, Scalar, SigningPackage, VerifyingKey, }; #[cfg(feature = "serde")] use frost_core::serde; -#[cfg(feature = "serde")] -use frost_core::serialization::ScalarSerialization; // When pulled into `reddsa`, that has its own sibling `rand_core` import. // For the time being, we do not re-export this `rand_core`. @@ -69,7 +68,7 @@ impl Randomize for KeyPackage { let signing_share = self.signing_share(); let randomized_signing_share = - SigningShare::new(signing_share.to_scalar() + randomized_params.randomizer.0); + SigningShare::new(signing_share.to_scalar() + randomized_params.randomizer.to_scalar()); let randomized_key_package = KeyPackage::new( *self.identifier(), @@ -155,10 +154,18 @@ where #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))] -#[cfg_attr(feature = "serde", serde(try_from = "ScalarSerialization"))] -#[cfg_attr(feature = "serde", serde(into = "ScalarSerialization"))] +#[cfg_attr(feature = "serde", serde(transparent))] #[cfg_attr(feature = "serde", serde(crate = "self::serde"))] -pub struct Randomizer(Scalar); +pub struct Randomizer(SerializableScalar); + +impl Randomizer +where + C: Ciphersuite, +{ + pub(crate) fn to_scalar(self) -> Scalar { + self.0 .0 + } +} impl Randomizer where @@ -194,7 +201,7 @@ where .concat(), ) .ok_or(Error::SerializationError)?; - Ok(Self(randomizer)) + Ok(Self(SerializableScalar(randomizer))) } } @@ -209,43 +216,18 @@ where /// reasons with specifications on how the randomizer must be generated. Use /// [`Randomizer::new()`] instead. pub fn from_scalar(scalar: Scalar) -> Self { - Self(scalar) + Self(SerializableScalar(scalar)) } /// Serialize the identifier using the ciphersuite encoding. - pub fn serialize(&self) -> <::Field as Field>::Serialization { - <::Field>::serialize(&self.0) + pub fn serialize(&self) -> Vec { + self.0.serialize() } /// Deserialize an Identifier from a serialized buffer. /// Returns an error if it attempts to deserialize zero. - pub fn deserialize( - buf: &<::Field as Field>::Serialization, - ) -> Result> { - let scalar = <::Field>::deserialize(buf)?; - Ok(Self(scalar)) - } -} - -#[cfg(feature = "serde")] -impl TryFrom> for Randomizer -where - C: Ciphersuite, -{ - type Error = Error; - - fn try_from(value: ScalarSerialization) -> Result { - Self::deserialize(&value.0) - } -} - -#[cfg(feature = "serde")] -impl From> for ScalarSerialization -where - C: Ciphersuite, -{ - fn from(value: Randomizer) -> Self { - Self(value.serialize()) + pub fn deserialize(buf: &[u8]) -> Result> { + Ok(Self(SerializableScalar::deserialize(buf)?)) } } @@ -255,9 +237,7 @@ where { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("Randomizer") - .field(&hex::encode( - <::Field>::serialize(&self.0).as_ref(), - )) + .field(&hex::encode(self.0.serialize())) .finish() } } @@ -304,7 +284,7 @@ where group_verifying_key: &VerifyingKey, randomizer: Randomizer, ) -> Self { - let randomizer_element = ::generator() * randomizer.0; + let randomizer_element = ::generator() * randomizer.to_scalar(); let verifying_key_element = group_verifying_key.to_element(); let randomized_verifying_key_element = verifying_key_element + randomizer_element; let randomized_verifying_key = VerifyingKey::::new(randomized_verifying_key_element); diff --git a/frost-ristretto255/tests/helpers/samples.rs b/frost-ristretto255/tests/helpers/samples.rs index 97651126..f598c53f 100644 --- a/frost-ristretto255/tests/helpers/samples.rs +++ b/frost-ristretto255/tests/helpers/samples.rs @@ -36,8 +36,8 @@ fn scalar1() -> Scalar { pub fn signing_nonces() -> SigningNonces { let serialized_scalar1 = <::Group as Group>::Field::serialize(&scalar1()); let serialized_scalar2 = <::Group as Group>::Field::serialize(&scalar1()); - let hiding_nonce = Nonce::deserialize(serialized_scalar1).unwrap(); - let binding_nonce = Nonce::deserialize(serialized_scalar2).unwrap(); + let hiding_nonce = Nonce::deserialize(serialized_scalar1.as_ref()).unwrap(); + let binding_nonce = Nonce::deserialize(serialized_scalar2.as_ref()).unwrap(); SigningNonces::from_nonces(hiding_nonce, binding_nonce) } @@ -46,8 +46,10 @@ pub fn signing_nonces() -> SigningNonces { pub fn signing_commitments() -> SigningCommitments { let serialized_element1 = ::Group::serialize(&element1()).unwrap(); let serialized_element2 = ::Group::serialize(&element2()).unwrap(); - let hiding_nonce_commitment = NonceCommitment::deserialize(serialized_element1).unwrap(); - let binding_nonce_commitment = NonceCommitment::deserialize(serialized_element2).unwrap(); + let hiding_nonce_commitment = + NonceCommitment::deserialize(serialized_element1.as_ref()).unwrap(); + let binding_nonce_commitment = + NonceCommitment::deserialize(serialized_element2.as_ref()).unwrap(); SigningCommitments::new(hiding_nonce_commitment, binding_nonce_commitment) } @@ -65,7 +67,7 @@ pub fn signing_package() -> SigningPackage { pub fn signature_share() -> SignatureShare { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - SignatureShare::deserialize(serialized_scalar).unwrap() + SignatureShare::deserialize(serialized_scalar.as_ref()).unwrap() } /// Generate a sample SecretShare. @@ -73,7 +75,7 @@ pub fn secret_share() -> SecretShare { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); @@ -85,10 +87,10 @@ pub fn key_package() -> KeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); KeyPackage::new(identifier, signing_share, verifying_share, verifying_key, 2) } @@ -97,9 +99,9 @@ pub fn key_package() -> KeyPackage { pub fn public_key_package() -> PublicKeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); let verifying_shares = BTreeMap::from([(identifier, verifying_share)]); PublicKeyPackage::new(verifying_shares, verifying_key) @@ -114,12 +116,10 @@ pub fn round1_package() -> round1::Package { .iter() .chain(serialized_scalar.as_ref().iter()) .cloned() - .collect::>() - .try_into() - .unwrap(); + .collect::>(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); - let signature = Signature::deserialize(serialized_signature).unwrap(); + let signature = Signature::deserialize(&serialized_signature).unwrap(); round1::Package::new(vss_commitment, signature) } @@ -127,7 +127,7 @@ pub fn round1_package() -> round1::Package { /// Generate a sample round2::Package. pub fn round2_package() -> round2::Package { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); round2::Package::new(signing_share) } diff --git a/frost-ristretto255/tests/recreation_tests.rs b/frost-ristretto255/tests/recreation_tests.rs index c12cad7e..a8ed937c 100644 --- a/frost-ristretto255/tests/recreation_tests.rs +++ b/frost-ristretto255/tests/recreation_tests.rs @@ -54,7 +54,7 @@ fn check_signature_share_recreation() { let encoded = signature_share.serialize(); - let new_signature_share = SignatureShare::deserialize(encoded).unwrap(); + let new_signature_share = SignatureShare::deserialize(&encoded).unwrap(); assert!(signature_share == new_signature_share); } diff --git a/frost-ristretto255/tests/serialization_tests.rs b/frost-ristretto255/tests/serialization_tests.rs index 0578a64a..ffc5dd8b 100644 --- a/frost-ristretto255/tests/serialization_tests.rs +++ b/frost-ristretto255/tests/serialization_tests.rs @@ -49,8 +49,11 @@ fn check_signing_package_postcard_serialization() { fn check_signature_share_postcard_serialization() { let signature_share = samples::signature_share(); let bytes = signature_share.serialize(); - assert_snapshot!(hex::encode(bytes)); - assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signature_share, + SignatureShare::deserialize(&bytes).unwrap() + ); } #[test] fn check_secret_share_postcard_serialization() { diff --git a/frost-secp256k1/tests/helpers/samples.rs b/frost-secp256k1/tests/helpers/samples.rs index ff22aec8..3afe78f9 100644 --- a/frost-secp256k1/tests/helpers/samples.rs +++ b/frost-secp256k1/tests/helpers/samples.rs @@ -36,8 +36,8 @@ fn scalar1() -> Scalar { pub fn signing_nonces() -> SigningNonces { let serialized_scalar1 = <::Group as Group>::Field::serialize(&scalar1()); let serialized_scalar2 = <::Group as Group>::Field::serialize(&scalar1()); - let hiding_nonce = Nonce::deserialize(serialized_scalar1).unwrap(); - let binding_nonce = Nonce::deserialize(serialized_scalar2).unwrap(); + let hiding_nonce = Nonce::deserialize(serialized_scalar1.as_ref()).unwrap(); + let binding_nonce = Nonce::deserialize(serialized_scalar2.as_ref()).unwrap(); SigningNonces::from_nonces(hiding_nonce, binding_nonce) } @@ -46,8 +46,10 @@ pub fn signing_nonces() -> SigningNonces { pub fn signing_commitments() -> SigningCommitments { let serialized_element1 = ::Group::serialize(&element1()).unwrap(); let serialized_element2 = ::Group::serialize(&element2()).unwrap(); - let hiding_nonce_commitment = NonceCommitment::deserialize(serialized_element1).unwrap(); - let binding_nonce_commitment = NonceCommitment::deserialize(serialized_element2).unwrap(); + let hiding_nonce_commitment = + NonceCommitment::deserialize(serialized_element1.as_ref()).unwrap(); + let binding_nonce_commitment = + NonceCommitment::deserialize(serialized_element2.as_ref()).unwrap(); SigningCommitments::new(hiding_nonce_commitment, binding_nonce_commitment) } @@ -65,7 +67,7 @@ pub fn signing_package() -> SigningPackage { pub fn signature_share() -> SignatureShare { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - SignatureShare::deserialize(serialized_scalar).unwrap() + SignatureShare::deserialize(serialized_scalar.as_ref()).unwrap() } /// Generate a sample SecretShare. @@ -73,7 +75,7 @@ pub fn secret_share() -> SecretShare { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); @@ -85,10 +87,10 @@ pub fn key_package() -> KeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); KeyPackage::new(identifier, signing_share, verifying_share, verifying_key, 2) } @@ -97,9 +99,9 @@ pub fn key_package() -> KeyPackage { pub fn public_key_package() -> PublicKeyPackage { let identifier = 42u16.try_into().unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap(); + let verifying_share = VerifyingShare::deserialize(serialized_element.as_ref()).unwrap(); let serialized_element = ::Group::serialize(&element1()).unwrap(); - let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap(); + let verifying_key = VerifyingKey::deserialize(serialized_element.as_ref()).unwrap(); let verifying_shares = BTreeMap::from([(identifier, verifying_share)]); PublicKeyPackage::new(verifying_shares, verifying_key) @@ -114,12 +116,10 @@ pub fn round1_package() -> round1::Package { .iter() .chain(serialized_scalar.as_ref().iter()) .cloned() - .collect::>() - .try_into() - .unwrap(); + .collect::>(); let vss_commitment = VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap(); - let signature = Signature::deserialize(serialized_signature).unwrap(); + let signature = Signature::deserialize(&serialized_signature).unwrap(); round1::Package::new(vss_commitment, signature) } @@ -127,7 +127,7 @@ pub fn round1_package() -> round1::Package { /// Generate a sample round2::Package. pub fn round2_package() -> round2::Package { let serialized_scalar = <::Group as Group>::Field::serialize(&scalar1()); - let signing_share = SigningShare::deserialize(serialized_scalar).unwrap(); + let signing_share = SigningShare::deserialize(serialized_scalar.as_ref()).unwrap(); round2::Package::new(signing_share) } diff --git a/frost-secp256k1/tests/recreation_tests.rs b/frost-secp256k1/tests/recreation_tests.rs index 0806e55f..bb2f8315 100644 --- a/frost-secp256k1/tests/recreation_tests.rs +++ b/frost-secp256k1/tests/recreation_tests.rs @@ -54,7 +54,7 @@ fn check_signature_share_recreation() { let encoded = signature_share.serialize(); - let new_signature_share = SignatureShare::deserialize(encoded).unwrap(); + let new_signature_share = SignatureShare::deserialize(&encoded).unwrap(); assert!(signature_share == new_signature_share); } diff --git a/frost-secp256k1/tests/serialization_tests.rs b/frost-secp256k1/tests/serialization_tests.rs index 0a304a49..d02c45be 100644 --- a/frost-secp256k1/tests/serialization_tests.rs +++ b/frost-secp256k1/tests/serialization_tests.rs @@ -49,8 +49,11 @@ fn check_signing_package_postcard_serialization() { fn check_signature_share_postcard_serialization() { let signature_share = samples::signature_share(); let bytes = signature_share.serialize(); - assert_snapshot!(hex::encode(bytes)); - assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signature_share, + SignatureShare::deserialize(&bytes).unwrap() + ); } #[test] fn check_secret_share_postcard_serialization() {