From 6f776ff004ca4d1555b71ca370cc31716f93df3d Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 13 Aug 2022 03:00:16 -0400 Subject: [PATCH] Recalculate the group key instead of serializing it Solves an issue with promotion. --- crypto/frost/src/lib.rs | 33 +++++++++++++++++++++---------- crypto/frost/src/tests/vectors.rs | 1 - 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/crypto/frost/src/lib.rs b/crypto/frost/src/lib.rs index 30b37bf0..bb1a16b0 100644 --- a/crypto/frost/src/lib.rs +++ b/crypto/frost/src/lib.rs @@ -22,7 +22,7 @@ pub mod tests; // Validate a map of serialized values to have the expected included participants pub(crate) fn validate_map( - map: &mut HashMap, + map: &HashMap, included: &[u16], ours: u16, ) -> Result<(), FrostError> { @@ -169,6 +169,22 @@ impl Debug for FrostCore { } impl FrostCore { + pub(crate) fn new( + params: FrostParams, + secret_share: C::F, + verification_shares: HashMap, + ) -> FrostCore { + #[cfg(debug_assertions)] + validate_map(&verification_shares, &(0 ..= params.n).collect::>(), 0).unwrap(); + + let t = (1 ..= params.t).collect::>(); + FrostCore { + params, + secret_share, + group_key: t.iter().map(|i| verification_shares[i] * lagrange::(*i, &t)).sum(), + verification_shares, + } + } pub fn params(&self) -> FrostParams { self.params } @@ -197,7 +213,6 @@ impl FrostCore { serialized.extend(&self.params.n.to_be_bytes()); serialized.extend(&self.params.i.to_be_bytes()); serialized.extend(self.secret_share.to_repr().as_ref()); - serialized.extend(self.group_key.to_bytes().as_ref()); for l in 1 ..= self.params.n { serialized.extend(self.verification_shares[&l].to_bytes().as_ref()); } @@ -235,8 +250,6 @@ impl FrostCore { let secret_share = C::read_F(cursor).map_err(|_| FrostError::InternalError("invalid secret share"))?; - let group_key = - C::read_G(cursor).map_err(|_| FrostError::InternalError("invalid group key"))?; let mut verification_shares = HashMap::new(); for l in 1 ..= n { @@ -246,13 +259,11 @@ impl FrostCore { ); } - Ok(FrostCore { - params: FrostParams::new(t, n, i) - .map_err(|_| FrostError::InternalError("invalid parameters"))?, + Ok(FrostCore::new( + FrostParams::new(t, n, i).map_err(|_| FrostError::InternalError("invalid parameters"))?, secret_share, - group_key, verification_shares, - }) + )) } } @@ -317,12 +328,14 @@ impl FrostKeys { self.core.secret_share } + /// Returns the group key with any offset applied pub fn group_key(&self) -> C::G { self.core.group_key + (C::GENERATOR * self.offset.unwrap_or_else(C::F::zero)) } + /// Returns all participants' verification shares without any offsetting pub(crate) fn verification_shares(&self) -> HashMap { - self.core.verification_shares.clone() + self.core.verification_shares() } pub fn serialized_len(n: u16) -> usize { diff --git a/crypto/frost/src/tests/vectors.rs b/crypto/frost/src/tests/vectors.rs index a0582503..0c792a26 100644 --- a/crypto/frost/src/tests/vectors.rs +++ b/crypto/frost/src/tests/vectors.rs @@ -43,7 +43,6 @@ fn vectors_to_multisig_keys(vectors: &Vectors) -> HashMap