Skip to content

Commit

Permalink
[frost] add Frost::aggregate_binonces
Browse files Browse the repository at this point in the history
So it's clearer how you can avoid a coordinator
  • Loading branch information
LLFourn committed Jul 30, 2024
1 parent dda6cdf commit 4e22279
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 13 deletions.
4 changes: 2 additions & 2 deletions schnorr_fun/src/binonce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ impl<Z> HashInto for Nonce<Z> {

impl Nonce<Zero> {
/// Adds a bunch of binonces together (one for each party signing usually).
pub fn aggregate(nonces: impl Iterator<Item = Nonce<impl ZeroChoice>>) -> Self {
let agg = nonces.fold([Point::zero(); 2], |acc, nonce| {
pub fn aggregate(nonces: impl IntoIterator<Item = Nonce>) -> Self {
let agg = nonces.into_iter().fold([Point::zero(); 2], |acc, nonce| {
[g!(acc[0] + nonce.0[0]), g!(acc[1] + nonce.0[1])]
});

Expand Down
31 changes: 21 additions & 10 deletions schnorr_fun/src/frost/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,20 +703,31 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> Frost<H, NG> {
Ok((secret_share_with_image, keygen.frost_poly))
}

/// Aggregate the nonces of the signers so you can start a [`party_sign_session`] without a
/// coordinator.
///
/// [`party_sign_session`]: Self::party_sign_session
pub fn aggregate_binonces(
&self,
nonces: impl IntoIterator<Item = Nonce>,
) -> binonce::Nonce<Zero> {
binonce::Nonce::aggregate(nonces)
}

/// Start party signing session
pub fn party_sign_session(
&self,
shared_key: Point<EvenY>,
public_key: Point<EvenY>,
parties: BTreeSet<PartyIndex>,
agg_binonce: Nonce<Zero>,
agg_binonce: binonce::Nonce<Zero>,
message: Message,
) -> PartySignSession {
let binding_coeff = self.binding_coefficient(shared_key, agg_binonce, message);
let binding_coeff = self.binding_coefficient(public_key, agg_binonce, message);
let (final_nonce, binonce_needs_negation) = agg_binonce.bind(binding_coeff);
let challenge = self.schnorr.challenge(&final_nonce, &shared_key, message);
let challenge = self.schnorr.challenge(&final_nonce, &public_key, message);

PartySignSession {
shared_key,
public_key,
parties,
binding_coeff,
challenge,
Expand All @@ -736,22 +747,22 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> Frost<H, NG> {
/// If the number of nonces is less than the threshold.
pub fn coordinator_sign_session(
&self,
frost_poly: &SharedKey<EvenY>,
shared_key: &SharedKey<EvenY>,
mut nonces: BTreeMap<PartyIndex, Nonce>,
message: Message,
) -> CoordinatorSignSession {
if nonces.len() < frost_poly.threshold() {
if nonces.len() < shared_key.threshold() {
panic!("nonces' length was less than the threshold");
}

let agg_binonce = binonce::Nonce::aggregate(nonces.values().cloned());

let binding_coeff = self.binding_coefficient(frost_poly.key(), agg_binonce, message);
let binding_coeff = self.binding_coefficient(shared_key.key(), agg_binonce, message);
let (final_nonce, binonce_needs_negation) = agg_binonce.bind(binding_coeff);

let challenge = self
.schnorr
.challenge(&final_nonce, &frost_poly.key(), message);
.challenge(&final_nonce, &shared_key.key(), message);

for nonce in nonces.values_mut() {
nonce.conditional_negate(binonce_needs_negation);
Expand Down Expand Up @@ -799,7 +810,7 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> Frost<H, NG> {
secret_share: &PairedSecretShare<EvenY>,
secret_nonce: NonceKeyPair,
) -> Scalar<Public, Zero> {
if session.shared_key != secret_share.shared_key() {
if session.public_key != secret_share.shared_key() {
panic!("the share's shared key is not the same as the shared key of the session");
}
let secret_share = secret_share.secret_share();
Expand Down
7 changes: 6 additions & 1 deletion schnorr_fun/src/frost/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl CoordinatorSignSession {
serde(crate = "crate::fun::serde")
)]
pub struct PartySignSession {
pub(crate) shared_key: Point<EvenY>,
pub(crate) public_key: Point<EvenY>,
pub(crate) parties: BTreeSet<Scalar<Public>>,
pub(crate) challenge: Scalar<Public, Zero>,
pub(crate) binonce_needs_negation: bool,
Expand All @@ -76,4 +76,9 @@ impl PartySignSession {
pub fn final_nonce(&self) -> Point<EvenY> {
self.final_nonce
}

/// The public key the session was started under
pub fn public_key(&self) -> Point<EvenY> {
self.public_key
}
}

0 comments on commit 4e22279

Please sign in to comment.