From 036eded933c33d20f5caacfccf27688b7a0cd76f Mon Sep 17 00:00:00 2001 From: Nick Farrow Date: Fri, 22 Dec 2023 18:14:10 +1100 Subject: [PATCH] [frost] use polynomial internally --- schnorr_fun/src/frost.rs | 62 +++++++++++++++++----------------------- secp256kfun/src/poly.rs | 2 ++ 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/schnorr_fun/src/frost.rs b/schnorr_fun/src/frost.rs index e011edc4..38327557 100644 --- a/schnorr_fun/src/frost.rs +++ b/schnorr_fun/src/frost.rs @@ -145,7 +145,7 @@ //! in most applications: //! //! ``` -//! use schnorr_fun::{frost, fun::{ Scalar, nonce, Tag, derive_nonce_rng }}; +//! use schnorr_fun::{frost, fun::{ poly, Scalar, nonce, Tag, derive_nonce_rng }}; //! use sha2::Sha256; //! use rand_chacha::ChaCha20Rng; //! @@ -380,11 +380,9 @@ pub struct FrostKey { )) )] public_key: Point, - /// The image of each party's key share. - verification_shares: BTreeMap>, - /// Number of partial signatures required to create a combined signature under this key. - threshold: usize, - /// The tweak applied to this frost key, tracks the aggregate tweak. + // The public point polynomial that defines this FROST key. + point_polynomial: Vec, + /// The tweak applied to this frost key, tracks the aggregate tweak tweak: Scalar, /// Whether the secret keys need to be negated during signing (only used for EvenY keys). needs_negation: bool, @@ -399,19 +397,19 @@ impl FrostKey { /// The verification shares of each party in the key. /// /// The verification share is the image of their secret share. - pub fn verification_shares(&self) -> &BTreeMap> { - &self.verification_shares + pub fn verification_share(&self, index: &PartyIndex) -> Point { + poly::point_poly_eval(&self.point_polynomial, *index).normalize() } /// The threshold number of participants required in a signing coalition to produce a valid signature. pub fn threshold(&self) -> usize { - self.threshold + self.point_polynomial.len() } - /// The total number of signers in this frost multisignature. - pub fn n_signers(&self) -> usize { - self.verification_shares.len() - } + // /// The total number of signers in this frost multisignature. + // pub fn n_signers(&self) -> usize { + // self.verification_shares.len() + // } } impl FrostKey { @@ -421,13 +419,14 @@ impl FrostKey { /// /// [BIP340]: https://bips.xyz/340 pub fn into_xonly_key(self) -> FrostKey { - let (public_key, needs_negation) = self.public_key.into_point_with_even_y(); + let (public_key, needs_negation) = self.public_key().into_point_with_even_y(); let mut tweak = self.tweak; tweak.conditional_negate(needs_negation); FrostKey { public_key, - verification_shares: self.verification_shares, - threshold: self.threshold, + // verification_shares: self.verification_shares, + // threshold: self.threshold, + point_polynomial: self.point_polynomial, tweak, needs_negation, } @@ -454,8 +453,7 @@ impl FrostKey { Some(FrostKey { public_key, - verification_shares: self.verification_shares.clone(), - threshold: self.threshold, + point_polynomial: self.point_polynomial, tweak, needs_negation: self.needs_negation, }) @@ -486,10 +484,9 @@ impl FrostKey { Some(Self { public_key: new_public_key, + point_polynomial: self.point_polynomial, needs_negation, tweak: new_tweak, - verification_shares: self.verification_shares, - threshold: self.threshold, }) } } @@ -730,22 +727,18 @@ impl + Clone, NG> Frost { .non_zero() .ok_or(NewKeyGenError::ZeroFrostKey)?; - let verification_shares = point_polys - .keys() - .map(|party_index| { - ( - *party_index, - poly::point_poly_eval(&joint_poly, *party_index).normalize(), - ) - }) - .collect(); - Ok(KeyGen { point_polys, frost_key: FrostKey { - verification_shares, public_key, - threshold: joint_poly.len(), + point_polynomial: joint_poly + .into_iter() + .map(|coef| { + coef.non_zero() + .expect("polynomial coefficients should be random") + .normalize() + }) + .collect(), tweak: Scalar::zero(), needs_negation: false, }, @@ -946,10 +939,7 @@ impl + Clone, NG> Frost { lambda.conditional_negate(frost_key.needs_negation); let c = &session.challenge; let b = &session.binding_coeff; - let X = match frost_key.verification_shares().get(&index) { - Some(key) => key, - None => return false, - }; + let X = frost_key.verification_share(&index); let [R1, R2] = session .nonces .get(&index) diff --git a/secp256kfun/src/poly.rs b/secp256kfun/src/poly.rs index 776134de..f55031cf 100644 --- a/secp256kfun/src/poly.rs +++ b/secp256kfun/src/poly.rs @@ -81,6 +81,8 @@ pub fn lagrange_lambda( /// Find the coefficients of the polynomial that interpolates a set of points at unique indexes. /// /// Panics if the indexes are not unique. +/// +/// A vector with a tail of zero coefficients means the interpolation was overdetermined. pub fn interpolate_point_polynomial( indexes: Vec>, points: Vec,