Skip to content

Commit 3026d7f

Browse files
committed
add decrypt_vote function
1 parent 2b8588d commit 3026d7f

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

rust/catalyst-voting/src/vote_protocol/voter/mod.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
mod decoding;
44
pub mod proof;
55

6-
use anyhow::ensure;
6+
use anyhow::{anyhow, bail, ensure};
77
use rand_core::CryptoRngCore;
88

9-
use super::committee::ElectionPublicKey;
9+
use super::committee::{ElectionPublicKey, ElectionSecretKey};
1010
use crate::crypto::{
11+
babystep_giantstep::BabyStepGiantStep,
1112
default_rng,
12-
elgamal::{encrypt, Ciphertext},
13+
elgamal::{decrypt, encrypt, Ciphertext},
1314
group::Scalar,
1415
};
1516

@@ -107,6 +108,33 @@ pub fn encrypt_vote_with_default_rng(
107108
encrypt_vote(vote, public_key, &mut default_rng())
108109
}
109110

111+
/// Decrypt the encrypted vote.
112+
/// **NOTE** make sure tha the provided `vote` is a valid one, by executing the
113+
/// `verify_voter_proof` on the underlying voter proof.
114+
/// If not valid encrypted vote is provided, unexpected results may occur.
115+
///
116+
/// # Errors
117+
/// - Ivalid provided encrypted vote, not a unit vector.
118+
pub fn decrypt_vote(vote: &EncryptedVote, secret_key: &ElectionSecretKey) -> anyhow::Result<Vote> {
119+
// Assuming that the provided encrypted vote is a correctly encoded unit vector,
120+
// the maximum log value is `1`.
121+
let setup = BabyStepGiantStep::new(1, None)?;
122+
123+
for (i, encrypted_choice_per_option) in vote.0.iter().enumerate() {
124+
let decrypted_choice_per_option = decrypt(encrypted_choice_per_option, &secret_key.0);
125+
let choice_per_option = setup
126+
.discrete_log(decrypted_choice_per_option)
127+
.map_err(|_| anyhow!("Ivalid provided encrypted vote, not a unit vector."))?;
128+
if choice_per_option == 1 {
129+
return Ok(Vote {
130+
choice: i,
131+
voting_options: vote.0.len(),
132+
});
133+
}
134+
}
135+
bail!("Ivalid provided encrypted vote, not a unit vector.")
136+
}
137+
110138
#[cfg(test)]
111139
mod tests {
112140
use proptest::{

rust/catalyst-voting/tests/voting_test.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use catalyst_voting::vote_protocol::{
88
tally, DecryptionTallySetup,
99
},
1010
voter::{
11-
encrypt_vote_with_default_rng,
11+
decrypt_vote, encrypt_vote_with_default_rng,
1212
proof::{generate_voter_proof_with_default_rng, verify_voter_proof, VoterProofCommitment},
1313
Vote,
1414
},
@@ -42,6 +42,15 @@ fn voting_test(voters: [Voter; 100]) {
4242
.map(|vote| encrypt_vote_with_default_rng(vote, &election_public_key))
4343
.unzip();
4444

45+
// Decrypting votes
46+
{
47+
let decrypted_votes: Vec<_> = encrypted_votes
48+
.iter()
49+
.map(|v| decrypt_vote(v, &election_secret_key).unwrap())
50+
.collect();
51+
assert_eq!(votes, decrypted_votes);
52+
}
53+
4554
// Verify encrypted votes
4655
{
4756
let voter_proofs: Vec<_> = votes

0 commit comments

Comments
 (0)