|
3 | 3 | mod decoding; |
4 | 4 | pub mod proof; |
5 | 5 |
|
6 | | -use anyhow::ensure; |
| 6 | +use anyhow::{anyhow, bail, ensure}; |
7 | 7 | use rand_core::CryptoRngCore; |
8 | 8 |
|
9 | | -use super::committee::ElectionPublicKey; |
| 9 | +use super::committee::{ElectionPublicKey, ElectionSecretKey}; |
10 | 10 | use crate::crypto::{ |
| 11 | + babystep_giantstep::BabyStepGiantStep, |
11 | 12 | default_rng, |
12 | | - elgamal::{encrypt, Ciphertext}, |
| 13 | + elgamal::{decrypt, encrypt, Ciphertext}, |
13 | 14 | group::Scalar, |
14 | 15 | }; |
15 | 16 |
|
@@ -107,6 +108,33 @@ pub fn encrypt_vote_with_default_rng( |
107 | 108 | encrypt_vote(vote, public_key, &mut default_rng()) |
108 | 109 | } |
109 | 110 |
|
| 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 | + |
110 | 138 | #[cfg(test)] |
111 | 139 | mod tests { |
112 | 140 | use proptest::{ |
|
0 commit comments