pub struct QuadraticVotingBallot<G: Group> { /* private fields */ }Expand description
Encrypted ballot for quadratic voting together with zero-knowledge proofs of correctness.
§Overview
Quadratic voting assumes a non-exclusive selection among n >= 1 predefined options.
Unlike with MultiChoice polling, a voter can cast more than
one vote for a single option. The additional votes come at a quadratic expense for the voter,
however. For example, to cast 4 votes for a certain option, a voter needs 16 credits,
while single votes for 4 different options are worth 4 credits.
The QuadraticVotingBallot construction assumes that there is a known number of credits
for each ballot (e.g., it is uniform across all eligible voters), and that votes are tallied
by a tallier or a federation of talliers that jointly control a SecretKey.
As such, the ballot is represented as follows:
- ElGamal
Ciphertextfor each ofnoptions (can be summed across all valid ballots to get vote totals that will be decrypted by the talliers) RangeProoffor each of these ciphertexts proving that the encrypted value is in range0..=VCiphertextfor the number of credits used by the ballot, and aRangeProofthat it is in range0..=C- Zero-knowledge
SumOfSquaresProofproving that the encrypted number of credits is computed correctly, i.e., as a sum of squares of the values encrypted in the vote ciphertexts.
Here, C (the number of credits) and V (max votes per option) are the protocol parameters
encapsulated in QuadraticVotingParams.
§Examples
let mut rng = rand::rng();
let (pk, sk) = Keypair::<Ristretto>::generate(&mut rng).into_tuple();
let params = QuadraticVotingParams::new(pk, 5, 20);
// 5 options, 20 credits (= 4 max votes per option)
assert_eq!(params.max_votes(), 4);
let votes = [4, 0, 0, 1, 1];
let ballot = QuadraticVotingBallot::new(¶ms, &votes, &mut rng);
let encrypted: Vec<_> = ballot.verify(¶ms)?.collect();
assert_eq!(encrypted.len(), 5);
let lookup = DiscreteLogTable::new(0..=params.max_votes());
let decrypted: Vec<_> = encrypted
.into_iter()
.map(|vote| sk.decrypt(vote, &lookup).unwrap())
.collect();
assert_eq!(decrypted, votes);Implementations§
Source§impl<G: Group> QuadraticVotingBallot<G>
impl<G: Group> QuadraticVotingBallot<G>
Sourcepub fn new<R: CryptoRng + RngCore>(
params: &QuadraticVotingParams<G>,
votes: &[u64],
rng: &mut R,
) -> Self
pub fn new<R: CryptoRng + RngCore>( params: &QuadraticVotingParams<G>, votes: &[u64], rng: &mut R, ) -> Self
Creates a ballot based on the provided parameters and voter’s votes.
§Panics
Panics if the length of votes differs from the number of options in params.
Sourcepub fn verify(
&self,
params: &QuadraticVotingParams<G>,
) -> Result<impl Iterator<Item = Ciphertext<G>> + '_, QuadraticVotingError>
pub fn verify( &self, params: &QuadraticVotingParams<G>, ) -> Result<impl Iterator<Item = Ciphertext<G>> + '_, QuadraticVotingError>
Verifies this ballot against the provided parameters.
§Errors
- Returns an error if verification fails.
Trait Implementations§
Source§impl<G: Clone + Group> Clone for QuadraticVotingBallot<G>
impl<G: Clone + Group> Clone for QuadraticVotingBallot<G>
Source§fn clone(&self) -> QuadraticVotingBallot<G>
fn clone(&self) -> QuadraticVotingBallot<G>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more