From 97e7ffda9fd275b5426c45b91dcfcaecc5ab09f6 Mon Sep 17 00:00:00 2001 From: Peter Nose Date: Thu, 5 Sep 2024 11:31:48 +0200 Subject: [PATCH] secret-sharing/src/churp: Verify the number of shareholders --- secret-sharing/src/churp/handoff.rs | 18 ++++++++++++++++++ secret-sharing/src/churp/switch.rs | 17 ++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/secret-sharing/src/churp/handoff.rs b/secret-sharing/src/churp/handoff.rs index 2ba19e469f7..1ea78bc8b3d 100644 --- a/secret-sharing/src/churp/handoff.rs +++ b/secret-sharing/src/churp/handoff.rs @@ -169,12 +169,21 @@ where /// Creates a new handoff where the given shareholders will generate /// a random secret and receive corresponding secret shares. pub fn new(threshold: u8, me: G::Scalar, shareholders: Vec) -> Result { + // The number of shareholders must be at least threshold t + 2, + // ensuring that even if t Byzantine dealers reveal their secret, + // an honest shareholder cannot compute the combined bivariate + // polynomial. + if shareholders.len() < threshold as usize + 2 { + return Err(Error::NotEnoughShareholders.into()); + } + let share_distribution = DimensionSwitch::new_full_share_distribution( threshold, me, shareholders, HandoffKind::DealingPhase, )?; + share_distribution.skip_accumulating()?; share_distribution.start_merging(None)?; @@ -219,12 +228,17 @@ where /// Creates a new handoff where the secret shares of the given shareholders /// will be randomized. pub fn new(threshold: u8, me: G::Scalar, shareholders: Vec) -> Result { + if shareholders.len() < threshold as usize + 1 { + return Err(Error::NotEnoughShareholders.into()); + } + let share_distribution = DimensionSwitch::new_full_share_distribution( threshold, me, shareholders, HandoffKind::CommitteeUnchanged, )?; + share_distribution.skip_accumulating()?; Ok(Self { share_distribution }) @@ -278,6 +292,10 @@ where /// Creates a new handoff where the shared secret will be transferred /// to a new committee composed of the given shareholders. pub fn new(threshold: u8, me: G::Scalar, shareholders: Vec) -> Result { + if shareholders.len() < threshold as usize + 1 { + return Err(Error::NotEnoughShareholders.into()); + } + let share_reduction = DimensionSwitch::new_share_reduction( threshold, me, diff --git a/secret-sharing/src/churp/switch.rs b/secret-sharing/src/churp/switch.rs index af6a470648d..ca24399a0db 100644 --- a/secret-sharing/src/churp/switch.rs +++ b/secret-sharing/src/churp/switch.rs @@ -494,16 +494,7 @@ where handoff: HandoffKind, shareholder: Option>>, ) -> Result { - // During the dealing phase, the number of shares must be at least - // threshold + 2, ensuring that even if t Byzantine dealers reveal - // their secret, an honest shareholder cannot compute the combined - // bivariate polynomial. - let min = match handoff { - HandoffKind::DealingPhase => threshold as usize + 2, - HandoffKind::CommitteeUnchanged => 1, - HandoffKind::CommitteeChanged => 1, - }; - if shareholders.len() < min { + if shareholders.is_empty() { return Err(Error::NotEnoughShareholders.into()); } @@ -775,13 +766,13 @@ mod tests { let me = prepare_shareholder(1); let shareholders = prepare_shareholders(&[1, 2, 3]); - // Dealing phase requires at least threshold + 2 dealers. + // There should be at least 1 shareholder. let res = BivariateShares::::new( threshold, me, - shareholders.clone(), + vec![], DimensionSwitchKind::ShareReduction, - HandoffKind::DealingPhase, + hkind, None, ); assert!(res.is_err());