From ca72bf8c5d342fbd5de1cdf91f9a1bac5eda5ecf Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Tue, 24 Aug 2021 10:18:25 +0200 Subject: [PATCH 1/4] impl Arbitrary for private VoteTally --- chain-impl-mockchain/src/certificate/test.rs | 37 ++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/chain-impl-mockchain/src/certificate/test.rs b/chain-impl-mockchain/src/certificate/test.rs index d541d8b90..e4b605ad4 100644 --- a/chain-impl-mockchain/src/certificate/test.rs +++ b/chain-impl-mockchain/src/certificate/test.rs @@ -7,12 +7,17 @@ use crate::rewards::TaxType; use crate::vote; #[cfg(test)] use chain_core::mempack::{ReadBuf, Readable}; -use chain_crypto::{testing, Ed25519}; +use chain_crypto::{ + ec::ristretto255::{GroupElement, Scalar}, + testing, Ed25519, +}; use chain_time::DurationSeconds; +use chain_vote::TallyDecryptShare; #[cfg(test)] use quickcheck::TestResult; use quickcheck::{Arbitrary, Gen}; use quickcheck_macros::quickcheck; +use std::num::NonZeroU8; impl Arbitrary for PoolRetirement { fn arbitrary(g: &mut G) -> Self { @@ -246,7 +251,35 @@ impl Arbitrary for VoteCast { impl Arbitrary for VoteTally { fn arbitrary(g: &mut G) -> Self { let vote_plan_id = VotePlanId::arbitrary(g); - Self::new_public(vote_plan_id) + + let private = bool::arbitrary(g); + + if private { + let proposals_n = u8::arbitrary(g); + let mut inner = Vec::new(); + for _i in 0..proposals_n { + let n_options = NonZeroU8::arbitrary(g); + let mut buffer = + Vec::with_capacity(TallyDecryptShare::bytes_len(n_options.get() as usize)); + + for _j in 0..n_options.get() { + buffer.extend( + &GroupElement::from_hash(&u64::arbitrary(g).to_be_bytes()).to_bytes(), + ); + buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); + buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); + } + inner.push(DecryptedPrivateTallyProposal { + tally_result: (0..n_options.get()) + .map(|_| u64::arbitrary(g)) + .collect::>(), + decrypt_shares: Box::new([TallyDecryptShare::from_bytes(&buffer).unwrap()]), + }); + } + Self::new_private(vote_plan_id, DecryptedPrivateTally::new(inner)) + } else { + Self::new_public(vote_plan_id) + } } } From 940c443e4d2dd7c290d4f0bef90821434cc1acc6 Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Tue, 24 Aug 2021 11:38:39 +0200 Subject: [PATCH 2/4] refactor DecryptedPrivateTally arbitrary impl in fn --- chain-impl-mockchain/src/certificate/test.rs | 45 ++++++++++---------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/chain-impl-mockchain/src/certificate/test.rs b/chain-impl-mockchain/src/certificate/test.rs index e4b605ad4..15efbe84b 100644 --- a/chain-impl-mockchain/src/certificate/test.rs +++ b/chain-impl-mockchain/src/certificate/test.rs @@ -248,6 +248,28 @@ impl Arbitrary for VoteCast { } } +fn arbitrary_decrypted_private_tally(g: &mut G) -> DecryptedPrivateTally { + let proposals_n = u8::arbitrary(g); + let mut inner = Vec::new(); + for _i in 0..proposals_n { + let n_options = NonZeroU8::arbitrary(g); + let mut buffer = Vec::with_capacity(TallyDecryptShare::bytes_len(n_options.get() as usize)); + + for _j in 0..n_options.get() { + buffer.extend(&GroupElement::from_hash(&u64::arbitrary(g).to_be_bytes()).to_bytes()); + buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); + buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); + } + inner.push(DecryptedPrivateTallyProposal { + tally_result: (0..n_options.get()) + .map(|_| u64::arbitrary(g)) + .collect::>(), + decrypt_shares: Box::new([TallyDecryptShare::from_bytes(&buffer).unwrap()]), + }); + } + DecryptedPrivateTally::new(inner) +} + impl Arbitrary for VoteTally { fn arbitrary(g: &mut G) -> Self { let vote_plan_id = VotePlanId::arbitrary(g); @@ -255,28 +277,7 @@ impl Arbitrary for VoteTally { let private = bool::arbitrary(g); if private { - let proposals_n = u8::arbitrary(g); - let mut inner = Vec::new(); - for _i in 0..proposals_n { - let n_options = NonZeroU8::arbitrary(g); - let mut buffer = - Vec::with_capacity(TallyDecryptShare::bytes_len(n_options.get() as usize)); - - for _j in 0..n_options.get() { - buffer.extend( - &GroupElement::from_hash(&u64::arbitrary(g).to_be_bytes()).to_bytes(), - ); - buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); - buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); - } - inner.push(DecryptedPrivateTallyProposal { - tally_result: (0..n_options.get()) - .map(|_| u64::arbitrary(g)) - .collect::>(), - decrypt_shares: Box::new([TallyDecryptShare::from_bytes(&buffer).unwrap()]), - }); - } - Self::new_private(vote_plan_id, DecryptedPrivateTally::new(inner)) + Self::new_private(vote_plan_id, arbitrary_decrypted_private_tally(g)) } else { Self::new_public(vote_plan_id) } From 498e56d9b1ac363b5732fa45b4089f7183948c3d Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Tue, 24 Aug 2021 15:42:18 +0200 Subject: [PATCH 3/4] refactor Arbitrary VoteTally impl --- chain-impl-mockchain/src/certificate/test.rs | 42 +++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/chain-impl-mockchain/src/certificate/test.rs b/chain-impl-mockchain/src/certificate/test.rs index 15efbe84b..5789eb12b 100644 --- a/chain-impl-mockchain/src/certificate/test.rs +++ b/chain-impl-mockchain/src/certificate/test.rs @@ -4,19 +4,19 @@ use crate::block::BlockDate; use crate::fragment::ConfigParams; use crate::ledger::governance::TreasuryGovernanceAction; use crate::rewards::TaxType; +use crate::testing::data::CommitteeMembersManager; use crate::vote; #[cfg(test)] use chain_core::mempack::{ReadBuf, Readable}; -use chain_crypto::{ - ec::ristretto255::{GroupElement, Scalar}, - testing, Ed25519, -}; +use chain_crypto::{testing, Ed25519}; use chain_time::DurationSeconds; -use chain_vote::TallyDecryptShare; +use chain_vote::{Crs, EncryptedTally}; #[cfg(test)] use quickcheck::TestResult; use quickcheck::{Arbitrary, Gen}; use quickcheck_macros::quickcheck; +use rand::SeedableRng; +use rand_chacha::ChaChaRng; use std::num::NonZeroU8; impl Arbitrary for PoolRetirement { @@ -196,8 +196,6 @@ impl Arbitrary for Proposals { impl Arbitrary for VotePlan { fn arbitrary(g: &mut G) -> Self { - use rand_core::SeedableRng; - let vote_start = BlockDate::arbitrary(g); let vote_end = BlockDate::arbitrary(g); let committee_end = BlockDate::arbitrary(g); @@ -251,23 +249,37 @@ impl Arbitrary for VoteCast { fn arbitrary_decrypted_private_tally(g: &mut G) -> DecryptedPrivateTally { let proposals_n = u8::arbitrary(g); let mut inner = Vec::new(); - for _i in 0..proposals_n { + let mut rng = ChaChaRng::seed_from_u64(u64::arbitrary(g)); + let crs_seed = String::arbitrary(g).into_bytes(); + let committee_size = (g.next_u32() % 2 + 1) as usize; // very time consuming + let committee_manager = + CommitteeMembersManager::new(&mut rng, &crs_seed, committee_size, committee_size); + + for _ in 0..proposals_n { let n_options = NonZeroU8::arbitrary(g); - let mut buffer = Vec::with_capacity(TallyDecryptShare::bytes_len(n_options.get() as usize)); - for _j in 0..n_options.get() { - buffer.extend(&GroupElement::from_hash(&u64::arbitrary(g).to_be_bytes()).to_bytes()); - buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); - buffer.extend(&Scalar::from_u64(u64::arbitrary(g)).to_bytes()); + let encrypted_tally = EncryptedTally::new( + n_options.get() as usize, + committee_manager.election_pk(), + Crs::from_hash(&crs_seed), + ); + + let mut decrypte_shares = Vec::new(); + for i in 0..committee_size { + decrypte_shares.push( + encrypted_tally + .partial_decrypt(&mut rng, committee_manager.members()[i].secret_key()), + ); } + inner.push(DecryptedPrivateTallyProposal { tally_result: (0..n_options.get()) .map(|_| u64::arbitrary(g)) .collect::>(), - decrypt_shares: Box::new([TallyDecryptShare::from_bytes(&buffer).unwrap()]), + decrypt_shares: decrypte_shares.into_boxed_slice(), }); } - DecryptedPrivateTally::new(inner) + DecryptedPrivateTally::new(inner).unwrap() } impl Arbitrary for VoteTally { From 91818787a248158d8b64683f0da5575a61cecb98 Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Tue, 24 Aug 2021 16:57:39 +0200 Subject: [PATCH 4/4] increase tarpauling timeout --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e91ff405c..3ad65ead5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -267,6 +267,7 @@ jobs: uses: actions-rs/tarpaulin@v0.1 with: out-type: Html + timeout: 600 - name: Set branch name if: ${{ github.event_name == 'pull_request' }}