From 4a41d317afe415d3e10f1678deef56909253cb55 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Mon, 29 Jan 2024 12:15:18 +0100 Subject: [PATCH] chore(test): relax dkg ceremony constraints --- ferveo/src/dkg.rs | 34 +++++++++++++++------------ ferveo/src/lib.rs | 48 ++++++++++++++++++++++++++------------- ferveo/src/pvss.rs | 32 ++++++++++++++++++-------- ferveo/src/refresh.rs | 2 -- ferveo/src/test_common.rs | 28 +++++++++++++++++++---- 5 files changed, 99 insertions(+), 45 deletions(-) diff --git a/ferveo/src/dkg.rs b/ferveo/src/dkg.rs index f3c0dc15..0e955c08 100644 --- a/ferveo/src/dkg.rs +++ b/ferveo/src/dkg.rs @@ -111,7 +111,7 @@ impl PubliclyVerifiableDkg { me: &Validator, ) -> Result { let domain = ark_poly::GeneralEvaluationDomain::::new( - dkg_params.shares_num as usize, + validators.len(), ) .expect("unable to construct domain"); @@ -435,11 +435,13 @@ mod test_dealing { } )); let pvss = dkg.share(rng).unwrap(); - let unknown_validator_i = dkg.dkg_params.shares_num + 1; + // Need to make sure this falls outside of the validator set: + let unknown_validator_index = + dkg.dkg_params.shares_num + VALIDATORS_NUM + 1; let sender = Validator:: { - address: gen_address(unknown_validator_i as usize), + address: gen_address(unknown_validator_index as usize), public_key: ferveo_common::Keypair::::new(rng).public_key(), - share_index: dkg.dkg_params.shares_num + 5, // Not in the validator set + share_index: unknown_validator_index, }; // check that verification fails assert!(dkg.verify_message(&sender, &pvss).is_err()); @@ -589,14 +591,20 @@ mod test_dealing { #[cfg(test)] mod test_aggregation { use ark_ec::AffineRepr; + use test_case::test_case; use crate::{dkg::*, test_common::*, DkgState, Message}; - /// Test that if the security threshold is - /// met, we can create a final key - #[test] - fn test_aggregate() { - let (mut dkg, _) = setup_dealt_dkg(); + /// Test that if the security threshold is met, we can create a final key + #[test_case(4,4; "number of validators is equal to the number of shares")] + #[test_case(4,6; "number of validators is greater than the number of shares")] + fn test_aggregate(shares_num: u32, validators_num: u32) { + let security_threshold = shares_num - 1; + let (mut dkg, _) = setup_dealt_dkg_with_n_validators( + security_threshold, + shares_num, + validators_num, + ); let aggregate = dkg.aggregate().unwrap(); let sender = dkg.me.clone(); assert!(dkg.verify_message(&sender, &aggregate).is_ok()); @@ -604,8 +612,7 @@ mod test_aggregation { assert!(matches!(dkg.state, DkgState::Success { .. })); } - /// Test that aggregate only succeeds if we are in - /// the state [`DkgState::Dealt] + /// Test that aggregate only succeeds if we are in the state [`DkgState::Dealt] #[test] fn test_aggregate_state_guards() { let (mut dkg, _) = setup_dealt_dkg(); @@ -620,9 +627,8 @@ mod test_aggregation { assert!(dkg.aggregate().is_err()); } - /// Test that aggregate message fail to be verified - /// or applied unless dkg.state is - /// [`DkgState::Dealt`] + /// Test that aggregate message fail to be verified or applied unless + /// dkg.state is [`DkgState::Dealt`] #[test] fn test_aggregate_message_state_guards() { let (mut dkg, _) = setup_dealt_dkg(); diff --git a/ferveo/src/lib.rs b/ferveo/src/lib.rs index 0ca9252e..a022ce2d 100644 --- a/ferveo/src/lib.rs +++ b/ferveo/src/lib.rs @@ -204,14 +204,18 @@ mod test_dkg_full { (pvss_aggregated, decryption_shares, shared_secret) } - #[test_case(4; "number of shares (validators) is a power of 2")] - #[test_case(7; "number of shares (validators) is not a power of 2")] - fn test_dkg_simple_tdec(shares_num: u32) { + #[test_case(4, 4; "number of shares (validators) is a power of 2")] + #[test_case(7, 7; "number of shares (validators) is not a power of 2")] + #[test_case(4, 6; "number of validators is greater than the number of shares")] + fn test_dkg_simple_tdec(shares_num: u32, validators_num: u32) { let rng = &mut test_rng(); - let threshold = shares_num / 2 + 1; - let (dkg, validator_keypairs) = - setup_dealt_dkg_with(threshold, shares_num); + let security_threshold = shares_num / 2 + 1; + let (dkg, validator_keypairs) = setup_dealt_dkg_with_n_validators( + security_threshold, + shares_num, + validators_num, + ); let public_key = dkg.public_key(); let ciphertext = ferveo_tdec::encrypt::( @@ -239,15 +243,19 @@ mod test_dkg_full { assert_eq!(plaintext, MSG); } - #[test_case(4; "number of shares (validators) is a power of 2")] - #[test_case(7; "number of shares (validators) is not a power of 2")] - fn test_dkg_simple_tdec_precomputed(shares_num: u32) { + #[test_case(4, 4; "number of shares (validators) is a power of 2")] + #[test_case(7, 7; "number of shares (validators) is not a power of 2")] + #[test_case(4, 6; "number of validators is greater than the number of shares")] + fn test_dkg_simple_tdec_precomputed(shares_num: u32, validators_num: u32) { let rng = &mut test_rng(); // In precomputed variant, threshold must be equal to shares_num - let threshold = shares_num; - let (dkg, validator_keypairs) = - setup_dealt_dkg_with(threshold, shares_num); + let security_threshold = shares_num; + let (dkg, validator_keypairs) = setup_dealt_dkg_with_n_validators( + security_threshold, + shares_num, + validators_num, + ); let public_key = dkg.public_key(); let ciphertext = ferveo_tdec::encrypt::( SecretBox::new(MSG.to_vec()), @@ -301,12 +309,20 @@ mod test_dkg_full { assert_eq!(plaintext, MSG); } - #[test] - fn test_dkg_simple_tdec_share_verification() { + #[test_case(4, 4; "number of validators is equal to the number of shares")] + #[test_case(4, 6; "number of validators is greater than the number of shares")] + fn test_dkg_simple_tdec_share_verification( + shares_num: u32, + validators_num: u32, + ) { let rng = &mut test_rng(); + let security_threshold = shares_num / 2 + 1; - let (dkg, validator_keypairs) = - setup_dealt_dkg_with(SECURITY_THRESHOLD, SHARES_NUM); + let (dkg, validator_keypairs) = setup_dealt_dkg_with_n_validators( + security_threshold, + shares_num, + validators_num, + ); let public_key = dkg.public_key(); let ciphertext = ferveo_tdec::encrypt::( SecretBox::new(MSG.to_vec()), diff --git a/ferveo/src/pvss.rs b/ferveo/src/pvss.rs index af83aa81..aca5c068 100644 --- a/ferveo/src/pvss.rs +++ b/ferveo/src/pvss.rs @@ -448,16 +448,24 @@ mod test_pvss { use ark_bls12_381::Bls12_381 as EllipticCurve; use ark_ec::AffineRepr; use ark_ff::UniformRand; + use test_case::test_case; use super::*; use crate::{test_common::*, DkgParams}; - /// Test the happy flow that a pvss with the correct form is created + /// Test the happy flow such that the PVSS with the correct form is created /// and that appropriate validations pass - #[test] - fn test_new_pvss() { + #[test_case(4,4; "number of validators is equal to the number of shares")] + #[test_case(4,6; "number of validators is greater than the number of shares")] + fn test_new_pvss(shares_num: u32, validators_num: u32) { let rng = &mut ark_std::test_rng(); - let (dkg, _) = setup_dkg(0); + let security_threshold = shares_num - 1; + + let (dkg, _) = setup_dealt_dkg_with_n_validators( + security_threshold, + shares_num, + validators_num, + ); let s = ScalarField::rand(rng); let pvss = PubliclyVerifiableSS::::new(&s, &dkg, rng) .expect("Test failed"); @@ -479,7 +487,7 @@ mod test_pvss { } /// Check that if the proof of knowledge is wrong, - /// the optimistic verification of PVSS fails + /// then the optimistic verification of the PVSS fails #[test] fn test_verify_pvss_wrong_proof_of_knowledge() { let rng = &mut ark_std::test_rng(); @@ -548,10 +556,16 @@ mod test_pvss { } /// Check that happy flow of aggregating PVSS transcripts - /// Should have the correct form and validations pass - #[test] - fn test_aggregate_pvss() { - let (dkg, _) = setup_dealt_dkg(); + /// has the correct form and it's validations passes + #[test_case(4,4; "number of validators is equal to the number of shares")] + #[test_case(4,6; "number of validators is greater than the number of shares")] + fn test_aggregate_pvss(shares_num: u32, validators_num: u32) { + let security_threshold = shares_num - 1; + let (dkg, _) = setup_dealt_dkg_with_n_validators( + security_threshold, + shares_num, + validators_num, + ); let aggregate = aggregate(&dkg.vss); // Check that a polynomial of the correct degree was created assert_eq!( diff --git a/ferveo/src/refresh.rs b/ferveo/src/refresh.rs index 524e6569..b02eba3b 100644 --- a/ferveo/src/refresh.rs +++ b/ferveo/src/refresh.rs @@ -118,7 +118,6 @@ pub fn make_random_polynomial_with_root( #[cfg(test)] mod tests_refresh { - use std::collections::HashMap; use ark_bls12_381::Fr; @@ -316,7 +315,6 @@ mod tests_refresh { /// The output is M new shares (with M <= Ñ), with each of the M new shares substituting the /// original share (i.e., the original share is deleted). #[test_matrix([4, 7, 11, 16])] - fn tdec_simple_variant_share_refreshing(shares_num: usize) { let rng = &mut test_rng(); let threshold = shares_num * 2 / 3; diff --git a/ferveo/src/test_common.rs b/ferveo/src/test_common.rs index 4faae733..dce10e5d 100644 --- a/ferveo/src/test_common.rs +++ b/ferveo/src/test_common.rs @@ -18,6 +18,7 @@ pub const MSG: &[u8] = b"my-msg"; pub const AAD: &[u8] = b"my-aad"; pub const SECURITY_THRESHOLD: u32 = 3; pub const SHARES_NUM: u32 = 4; +pub const VALIDATORS_NUM: u32 = SHARES_NUM + 2; pub fn gen_keypairs(n: u32) -> Vec> { let rng = &mut ark_std::test_rng(); @@ -46,8 +47,9 @@ pub fn setup_dkg_for_n_validators( security_threshold: u32, shares_num: u32, my_validator_index: usize, + validators_num: u32, ) -> TestSetup { - let keypairs = gen_keypairs(shares_num); + let keypairs = gen_keypairs(validators_num); let validators = gen_validators(keypairs.as_slice()); let me = validators[my_validator_index].clone(); let dkg = PubliclyVerifiableDkg::new( @@ -67,6 +69,7 @@ pub fn setup_dkg(my_validator_index: usize) -> TestSetup { SECURITY_THRESHOLD, SHARES_NUM, my_validator_index, + VALIDATORS_NUM, ) } @@ -80,16 +83,29 @@ pub fn setup_dealt_dkg() -> TestSetup { pub fn setup_dealt_dkg_with( security_threshold: u32, shares_num: u32, +) -> TestSetup { + setup_dealt_dkg_with_n_validators( + security_threshold, + shares_num, + shares_num, + ) +} + +pub fn setup_dealt_dkg_with_n_validators( + security_threshold: u32, + shares_num: u32, + validators_num: u32, ) -> TestSetup { let rng = &mut ark_std::test_rng(); // Gather everyone's transcripts - let mut messages: Vec<_> = (0..shares_num) + let mut messages: Vec<_> = (0..validators_num) .map(|my_index| { let (mut dkg, _) = setup_dkg_for_n_validators( security_threshold, shares_num, my_index as usize, + validators_num, ); let me = dkg.me.clone(); let message = dkg.share(rng).unwrap(); @@ -98,8 +114,12 @@ pub fn setup_dealt_dkg_with( .collect(); // Create a test DKG instance - let (mut dkg, keypairs) = - setup_dkg_for_n_validators(security_threshold, shares_num, 0); + let (mut dkg, keypairs) = setup_dkg_for_n_validators( + security_threshold, + shares_num, + 0, + validators_num, + ); // The ordering of messages should not matter messages.shuffle(rng);