diff --git a/ferveo/src/api.rs b/ferveo/src/api.rs index caa0d9b4..cbe4059e 100644 --- a/ferveo/src/api.rs +++ b/ferveo/src/api.rs @@ -272,7 +272,9 @@ fn make_pvss_map(messages: &[ValidatorMessage]) -> PVSSMap { } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct AggregatedTranscript(PubliclyVerifiableSS); +pub struct AggregatedTranscript( + pub(crate) PubliclyVerifiableSS, +); impl AggregatedTranscript { pub fn new(messages: &[ValidatorMessage]) -> Result { @@ -658,10 +660,14 @@ mod test_ferveo_api { // implementation for aggregation and aggregate verification. // Here, we focus on testing user-facing APIs for server and client users. - #[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 greater than the number of shares")] - fn server_side_local_verification(shares_num: u32, validators_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 greater than the number of shares")] + // fn server_side_local_verification(shares_num: u32, validators_num: u32) { + #[test] + fn server_side_local_verification() { + let shares_num = 4; + let validators_num = 4; let rng = &mut StdRng::seed_from_u64(0); let security_threshold = shares_num / 2 + 1; @@ -689,16 +695,19 @@ mod test_ferveo_api { // for every test case // Should fail if the number of validators is less than the number of messages - assert!(good_aggregate - .verify(messages.len() as u32 - 1, &messages) - .is_err()); + assert!(matches!( + good_aggregate.verify(messages.len() as u32 - 1, &messages), + Err(Error::InvalidAggregateVerificationParameters(_, _)) + )); // Should fail if no transcripts are provided let mut dkg = Dkg::new(TAU, shares_num, security_threshold, &validators, &me) .unwrap(); - let result = dkg.aggregate_transcripts(&[]); - assert!(result.is_err()); + assert!(matches!( + dkg.aggregate_transcripts(&[]), + Err(Error::NoTranscriptsToAggregate) + )); // Not enough transcripts let mut dkg = @@ -708,8 +717,10 @@ mod test_ferveo_api { assert!(not_enough_messages.len() < security_threshold as usize); let insufficient_aggregate = dkg.aggregate_transcripts(not_enough_messages).unwrap(); - let result = insufficient_aggregate.verify(validators_num, &messages); - assert!(result.is_err()); + assert!(matches!( + insufficient_aggregate.verify(validators_num, &messages), + Err(Error::InvalidTranscriptAggregate) + )); // Unexpected transcripts in the aggregate or transcripts from a different ritual // Using same DKG parameters, but different DKG instances and validators @@ -725,8 +736,10 @@ mod test_ferveo_api { ); let mixed_messages = [&messages[..2], &bad_messages[..1]].concat(); let bad_aggregate = dkg.aggregate_transcripts(&mixed_messages).unwrap(); - let result = bad_aggregate.verify(validators_num, &messages); - assert!(result.is_err()); + assert!(matches!( + bad_aggregate.verify(validators_num, &messages), + Err(Error::InvalidTranscriptAggregate) + )); } #[test_case(4, 4; "number of shares (validators) is a power of 2")] @@ -761,21 +774,27 @@ mod test_ferveo_api { // Test negative cases // Should fail if the number of validators is less than the number of messages - assert!(good_aggregate - .verify(messages.len() as u32 - 1, messages) - .is_err()); + assert!(matches!( + good_aggregate.verify(messages.len() as u32 - 1, messages), + Err(Error::InvalidAggregateVerificationParameters(_, _)) + )); // Should fail if no transcripts are provided - let result = AggregatedTranscript::new(&[]); - assert!(result.is_err()); + assert!(matches!( + AggregatedTranscript::new(&[]), + Err(Error::NoTranscriptsToAggregate) + )); // Not enough transcripts let not_enough_messages = &messages[..security_threshold as usize - 1]; assert!(not_enough_messages.len() < security_threshold as usize); let insufficient_aggregate = AggregatedTranscript::new(not_enough_messages).unwrap(); - let result = insufficient_aggregate.verify(validators_num, messages); - assert!(result.is_err()); + let _result = insufficient_aggregate.verify(validators_num, messages); + assert!(matches!( + insufficient_aggregate.verify(validators_num, messages), + Err(Error::InvalidTranscriptAggregate) + )); // Unexpected transcripts in the aggregate or transcripts from a different ritual // Using same DKG parameters, but different DKG instances and validators @@ -788,7 +807,9 @@ mod test_ferveo_api { ); let mixed_messages = [&messages[..2], &bad_messages[..1]].concat(); let bad_aggregate = AggregatedTranscript::new(&mixed_messages).unwrap(); - let result = bad_aggregate.verify(validators_num, messages); - assert!(result.is_err()); + assert!(matches!( + bad_aggregate.verify(validators_num, messages), + Err(Error::InvalidTranscriptAggregate) + )); } } diff --git a/ferveo/src/pvss.rs b/ferveo/src/pvss.rs index 34695bd3..5108f6b9 100644 --- a/ferveo/src/pvss.rs +++ b/ferveo/src/pvss.rs @@ -154,6 +154,7 @@ impl PubliclyVerifiableSS { .values() .map(|validator| { // ek_{i}^{eval_i}, i = validator index + // TODO: Replace with regular, single-element exponentiation fast_multiexp( // &evals.evals[i..i] = &evals.evals[i] &[evals[validator.share_index as usize]], // one share per validator @@ -399,9 +400,9 @@ pub(crate) fn aggregate( let mut shares = batch_to_projective_g2::(&first_pvss.shares); - // So now we're iterating over the PVSS instances, and adding their coefficients and shares, and their sigma + // So now we're iterating over the PVSS instances, and adding their coefficients and shares, and their // sigma is the sum of all the sigma_i, which is the proof of knowledge of the secret polynomial - // Aggregating is just adding the corresponding values in PVSS instances, so PVSS_i = PVSS_(i-1) PVSS_i + // Aggregating is just adding the corresponding values in PVSS instances, so PVSS = PVSS + PVSS_i for next_pvss in pvss_iter { sigma = (sigma + next_pvss.sigma).into(); coeffs