From 3c4ee60279006d504995b0cc8b8f7ec2f131c6b0 Mon Sep 17 00:00:00 2001 From: Marcella Hastings Date: Thu, 17 Aug 2023 09:45:16 -0400 Subject: [PATCH] fix validation bug in new signer #470 --- src/protocol.rs | 6 +++++ src/sign/non_interactive_sign/participant.rs | 27 +++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/protocol.rs b/src/protocol.rs index 86039ac5..d4ec71ae 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -322,6 +322,12 @@ pub(crate) mod participant_config { participant } + /// Returns the total number of participants specified in the config + /// (both other and self). + pub fn count(&self) -> usize { + self.other_ids.len() + 1 + } + pub(crate) fn into_parts(self) -> (ParticipantIdentifier, Vec) { (self.id, self.other_ids) } diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index a0f8db8b..96ac0222 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -5,6 +5,8 @@ // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. +use std::collections::HashSet; + use generic_array::{typenum::U32, GenericArray}; use k256::{ ecdsa::{signature::DigestVerifier, VerifyingKey}, @@ -202,6 +204,20 @@ impl ProtocolParticipant for SignParticipant { Self: Sized, { let config = ParticipantConfig::new(id, &other_participant_ids)?; + + // The input must contain exactly one public key per particpant ID. + let public_key_pids = input + .public_key_shares + .iter() + .map(|share| share.participant()) + .collect::>(); + let pids = std::iter::once(id) + .chain(other_participant_ids) + .collect::>(); + if public_key_pids != pids || config.count() != input.public_key_shares.len() { + Err(CallerError::BadInput)? + } + Ok(Self { sid, config, @@ -550,12 +566,11 @@ mod test { keygen.public_key_shares().to_vec(), ) }); - let mut quorum = - std::iter::zip(ParticipantConfig::random_quorum(quorum_size, rng)?, inputs) - .map(|(config, input)| { - SignParticipant::new(sid, config.id(), config.other_ids().to_vec(), input) - }) - .collect::>>()?; + let mut quorum = std::iter::zip(configs, inputs) + .map(|(config, input)| { + SignParticipant::new(sid, config.id(), config.other_ids().to_vec(), input) + }) + .collect::>>()?; // Prepare caching of data (outputs and messages) for protocol execution let mut outputs = HashMap::with_capacity(quorum_size);