pub struct EncryptedChoice<G: Group, S: ProveSum<G>> { /* private fields */ }
Expand description
Zero or more encrypted choices from n
options (n >= 1
) together with zero-knowledge
proofs of correctness.
§Construction
The choice is represented as a vector of n
choice ciphertexts of Boolean values (0 or 1),
where the ciphertexts for the chosen options encrypt 1 and the other ciphertexts encrypt 0.
This ensures that multiple EncryptedChoice
s can be added (e.g., within a voting protocol).
Zero-knowledge proofs are:
- A
RingProof
attesting that alln
ciphertexts encrypt 0 or 1. This proof can be obtained viaSelf::range_proof()
. - A
LogEqualityProof
attesting that the encrypted values sum up to 1. Combined with the range proof, this means that exactly one of encrypted values is 1, and all others are 0. This proof can be obtained viaSelf::sum_proof()
. This proof is absent for aMultiChoice
setup (sum_proof()
just returns()
).
§Examples
§Single-choice setup
let mut rng = thread_rng();
let (pk, sk) = Keypair::<Ristretto>::generate(&mut rng).into_tuple();
let choice_params = ChoiceParams::single(pk, 5);
let choice = 2;
let enc = EncryptedChoice::single(&choice_params, choice, &mut rng);
let choices = enc.verify(&choice_params)?;
// `choices` is a slice of 5 Boolean value ciphertexts
assert_eq!(choices.len(), 5);
let lookup_table = DiscreteLogTable::new(0..=1);
for (idx, &v) in choices.iter().enumerate() {
assert_eq!(
sk.decrypt(v, &lookup_table),
Some((idx == choice) as u64)
);
}
§Multi-choice setup
let mut rng = thread_rng();
let (pk, sk) = Keypair::<Ristretto>::generate(&mut rng).into_tuple();
let choice_params = ChoiceParams::multi(pk, 5);
let choices = [true, false, true, true, false];
let enc = EncryptedChoice::new(&choice_params, &choices, &mut rng);
let recovered_choices = enc.verify(&choice_params)?;
let lookup_table = DiscreteLogTable::new(0..=1);
for (idx, &v) in recovered_choices.iter().enumerate() {
assert_eq!(sk.decrypt(v, &lookup_table), Some(choices[idx] as u64));
}
Implementations§
Source§impl<G: Group> EncryptedChoice<G, SingleChoice>
impl<G: Group> EncryptedChoice<G, SingleChoice>
Sourcepub fn single<R: CryptoRng + RngCore>(
params: &ChoiceParams<G, SingleChoice>,
choice: usize,
rng: &mut R,
) -> Self
pub fn single<R: CryptoRng + RngCore>( params: &ChoiceParams<G, SingleChoice>, choice: usize, rng: &mut R, ) -> Self
Creates a new encrypted choice.
§Panics
Panics if choice
exceeds the maximum index allowed by params
.
Source§impl<G: Group, S: ProveSum<G>> EncryptedChoice<G, S>
impl<G: Group, S: ProveSum<G>> EncryptedChoice<G, S>
Sourcepub fn new<R: CryptoRng + RngCore>(
params: &ChoiceParams<G, S>,
choices: &[bool],
rng: &mut R,
) -> Self
pub fn new<R: CryptoRng + RngCore>( params: &ChoiceParams<G, S>, choices: &[bool], rng: &mut R, ) -> Self
Creates an encrypted multi-choice.
For a SingleChoice
polling, it is caller’s responsibility to ensure that choices
contains exactly one true
value; otherwise, the produced proof will not verify.
§Panics
Panics if the length of choices
differs from the number of options specified in params
.
Sourcepub fn verify(
&self,
params: &ChoiceParams<G, S>,
) -> Result<&[Ciphertext<G>], ChoiceVerificationError>
pub fn verify( &self, params: &ChoiceParams<G, S>, ) -> Result<&[Ciphertext<G>], ChoiceVerificationError>
Verifies the zero-knowledge proofs in this choice and returns Boolean ciphertexts for all options.
§Errors
Returns an error if the choice
is malformed or its proofs fail verification.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of encrypted choices. This value is equal to
ChoiceParams::options_count()
with which the encryption was created.
Sourcepub fn choices_unchecked(&self) -> &[Ciphertext<G>]
pub fn choices_unchecked(&self) -> &[Ciphertext<G>]
Returns ciphertexts for all options without checking the validity of this choice.
Sourcepub fn range_proof(&self) -> &RingProof<G>
pub fn range_proof(&self) -> &RingProof<G>
Returns the range proof for the choice ciphertexts.
Trait Implementations§
Source§impl<G: Clone + Group, S: Clone + ProveSum<G>> Clone for EncryptedChoice<G, S>
impl<G: Clone + Group, S: Clone + ProveSum<G>> Clone for EncryptedChoice<G, S>
Source§fn clone(&self) -> EncryptedChoice<G, S>
fn clone(&self) -> EncryptedChoice<G, S>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<'de, G: Group, S: ProveSum<G>> Deserialize<'de> for EncryptedChoice<G, S>
impl<'de, G: Group, S: ProveSum<G>> Deserialize<'de> for EncryptedChoice<G, S>
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl<G, S> Freeze for EncryptedChoice<G, S>
impl<G, S> RefUnwindSafe for EncryptedChoice<G, S>where
<S as ProveSum<G>>::Proof: RefUnwindSafe,
<G as ScalarOps>::Scalar: RefUnwindSafe,
<G as ElementOps>::Element: RefUnwindSafe,
impl<G, S> Send for EncryptedChoice<G, S>
impl<G, S> Sync for EncryptedChoice<G, S>
impl<G, S> Unpin for EncryptedChoice<G, S>
impl<G, S> UnwindSafe for EncryptedChoice<G, S>where
<S as ProveSum<G>>::Proof: UnwindSafe,
<G as ScalarOps>::Scalar: UnwindSafe,
<G as ElementOps>::Element: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)