Skip to content

Commit ec8eb9d

Browse files
committed
add private_choice, public_choice methods
1 parent 3026d7f commit ec8eb9d

File tree

2 files changed

+45
-26
lines changed
  • rust/catalyst-voting/src

2 files changed

+45
-26
lines changed

rust/catalyst-voting/src/txs/v1/mod.rs

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ use crate::{
5151
hash::{digest::Digest, Blake2b256Hasher, Blake2b512Hasher},
5252
},
5353
vote_protocol::{
54-
committee::ElectionPublicKey,
54+
committee::{ElectionPublicKey, ElectionSecretKey},
5555
voter::{
56-
encrypt_vote_with_default_rng,
56+
decrypt_vote, encrypt_vote_with_default_rng,
5757
proof::{generate_voter_proof, verify_voter_proof, VoterProof, VoterProofCommitment},
5858
EncryptedVote, Vote,
5959
},
@@ -163,6 +163,33 @@ impl Tx {
163163
matches!(self.vote, VotePayload::Private(_, _))
164164
}
165165

166+
/// Returns public voting choice.
167+
///
168+
/// # Errors
169+
/// - Not a public vote
170+
pub fn public_choice(&self) -> anyhow::Result<u8> {
171+
if let VotePayload::Public(choice) = &self.vote {
172+
Ok(*choice)
173+
} else {
174+
Err(anyhow::anyhow!("Not a public vote"))
175+
}
176+
}
177+
178+
/// Returns private voting choice.
179+
///
180+
/// # Errors
181+
/// - Not a private vote
182+
#[allow(clippy::cast_possible_truncation)]
183+
pub fn private_choice(&self, secret_key: &ElectionSecretKey) -> anyhow::Result<u8> {
184+
if let VotePayload::Private(vote, _) = &self.vote {
185+
let vote = decrypt_vote(vote, secret_key)?;
186+
let choice = vote.choice() as u8;
187+
Ok(choice)
188+
} else {
189+
Err(anyhow::anyhow!("Not a private vote"))
190+
}
191+
}
192+
166193
/// Verify transaction signature
167194
///
168195
/// # Errors
@@ -262,27 +289,6 @@ impl VotePayload {
262289

263290
Ok(Self::Private(encrypted_vote, voter_proof))
264291
}
265-
266-
// #[allow(clippy::cast_possible_truncation, dead_code)]
267-
// fn choice(&self, secret_key: &ElectionSecretKey) -> anyhow::Result<u8> {
268-
// match self {
269-
// Self::Public(choice) => Ok(*choice),
270-
// Self::Private(vote, _) => {
271-
// // Making a tally and decryption tally procedure on one vote to retrieve
272-
// the // original voting choice.
273-
// // Assuming that the voting power argument must be equals to 1.
274-
// let setup = DecryptionTallySetup::new(1)?;
275-
// for voting_option in 0..vote.voting_options() {
276-
// let tally = tally(voting_option, &[vote.clone()], &[1])?;
277-
// let choice_for_voting_option = decrypt_tally(&tally, secret_key,
278-
// &setup)?; if choice_for_voting_option == 1 {
279-
// return Ok(voting_option as u8);
280-
// }
281-
// }
282-
// bail!("Invalid encrypted vote, not a unit vector");
283-
// },
284-
// }
285-
// }
286292
}
287293

288294
#[cfg(test)]
@@ -312,6 +318,8 @@ mod tests {
312318
assert!(!tx.is_private());
313319
tx.verify_signature().unwrap();
314320
tx.verify_proof(&election_public_key).unwrap();
321+
assert_eq!(tx.public_choice().unwrap(), choice);
322+
assert!(tx.private_choice(&election_secret_key).is_err());
315323

316324
let tx = Tx::new_private_with_default_rng(
317325
vote_plan_id,
@@ -326,5 +334,7 @@ mod tests {
326334
assert!(tx.is_private());
327335
tx.verify_signature().unwrap();
328336
tx.verify_proof(&election_public_key).unwrap();
337+
assert_eq!(tx.private_choice(&election_secret_key).unwrap(), choice);
338+
assert!(tx.public_choice().is_err());
329339
}
330340
}

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ impl Vote {
6464
})
6565
}
6666

67+
/// Get the voter's choice.
68+
#[must_use]
69+
pub fn choice(&self) -> usize {
70+
self.choice
71+
}
72+
6773
/// Transform the vote into the unit vector.
6874
fn to_unit_vector(&self) -> Vec<Scalar> {
6975
(0..self.voting_options)
@@ -114,7 +120,7 @@ pub fn encrypt_vote_with_default_rng(
114120
/// If not valid encrypted vote is provided, unexpected results may occur.
115121
///
116122
/// # Errors
117-
/// - Ivalid provided encrypted vote, not a unit vector.
123+
/// - Ivalid encrypted vote, not a valid unit vector.
118124
pub fn decrypt_vote(vote: &EncryptedVote, secret_key: &ElectionSecretKey) -> anyhow::Result<Vote> {
119125
// Assuming that the provided encrypted vote is a correctly encoded unit vector,
120126
// the maximum log value is `1`.
@@ -124,15 +130,15 @@ pub fn decrypt_vote(vote: &EncryptedVote, secret_key: &ElectionSecretKey) -> any
124130
let decrypted_choice_per_option = decrypt(encrypted_choice_per_option, &secret_key.0);
125131
let choice_per_option = setup
126132
.discrete_log(decrypted_choice_per_option)
127-
.map_err(|_| anyhow!("Ivalid provided encrypted vote, not a unit vector."))?;
133+
.map_err(|_| anyhow!("Ivalid encrypted vote, not a valid unit vector."))?;
128134
if choice_per_option == 1 {
129135
return Ok(Vote {
130136
choice: i,
131137
voting_options: vote.0.len(),
132138
});
133139
}
134140
}
135-
bail!("Ivalid provided encrypted vote, not a unit vector.")
141+
bail!("Ivalid encrypted vote, not a valid unit vector.")
136142
}
137143

138144
#[cfg(test)]
@@ -160,20 +166,23 @@ mod tests {
160166
let voting_options = 3;
161167

162168
let vote = Vote::new(0, voting_options).unwrap();
169+
assert_eq!(vote.choice(), 0);
163170
assert_eq!(vote.to_unit_vector(), vec![
164171
Scalar::one(),
165172
Scalar::zero(),
166173
Scalar::zero()
167174
]);
168175

169176
let vote = Vote::new(1, voting_options).unwrap();
177+
assert_eq!(vote.choice(), 1);
170178
assert_eq!(vote.to_unit_vector(), vec![
171179
Scalar::zero(),
172180
Scalar::one(),
173181
Scalar::zero()
174182
]);
175183

176184
let vote = Vote::new(2, voting_options).unwrap();
185+
assert_eq!(vote.choice(), 2);
177186
assert_eq!(vote.to_unit_vector(), vec![
178187
Scalar::zero(),
179188
Scalar::zero(),

0 commit comments

Comments
 (0)