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 Ciphertext for each of n options (can be summed across all valid ballots to get vote totals that will be decrypted by the talliers)
  • RangeProof for each of these ciphertexts proving that the encrypted value is in range 0..=V
  • Ciphertext for the number of credits used by the ballot, and a RangeProof that it is in range 0..=C
  • Zero-knowledge SumOfSquaresProof proving 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 = thread_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(&params, &votes, &mut rng);
let encrypted: Vec<_> = ballot.verify(&params)?.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>

source

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.

source

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>

source§

fn clone(&self) -> QuadraticVotingBallot<G>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<G: Debug + Group> Debug for QuadraticVotingBallot<G>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, G: Group> Deserialize<'de> for QuadraticVotingBallot<G>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<G: Group> Serialize for QuadraticVotingBallot<G>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,