Skip to content

Commit 817889a

Browse files
authored
feat(rust/catalyst-voting): Vote proof (#54)
* initialize a new crate * add intentionally failed test * fix CI * fix * fix * update vscode setting.recommended.json * add a basic interfaces for the vote part * add basic elgamal encryption based on the ristretto255 group * add arithmetic tests for ristretto255 * fix tests * wip * add decryption algorithm, add tests * fix CI * remove unused std_ops_gen * add new voter module * add EncryptionRandomness random generation * add a tally function * fix * wip * add a babystep implementation * wip * refactor, add decrypt_tally_result * wip * wip * add voting test * remove rayon dependency for now * fix spelling, remove rayon * fix * remove unused anyhow dep * intentionally break the test * try * wip * update DecryptionTallySetup interface * add doctest example * refactor, make voting_test as integration test * fix baby_step_giant_step_test * move tally module into the seprate dir * add new proof.rs * refactor * add to_bytes, from_bytes functions for Scalar and GroupElement * add zk_dl_equality.rs * add hash module * update hash implementation * add dleq verify function, add tests * implement tally proof generation and tally proof verification * update voting_test with the tally proofs, fix verify_tally_proof * remove uneeded comment * fix * fix * fix spelling * fix comment * update rust docs * fix rustdoc tests * refactor * refactor * add zk_unit_vector_proof module * refactor * add polynomial generation * fix * wip * wip * finish proof generation * refactor * add new get_bit function * refactor bit calculation * wip * fix calculation * refactor imports * refactor * refactor * update tests * update comment * update test * refactor * fix doc tests * remove redundant polynomial test * refactor imports, add voter proof module * fix doc test * update * add error handling for `generate_voter_proof` * update voting_test * update test * fix spelling
1 parent 54d5275 commit 817889a

File tree

15 files changed

+831
-91
lines changed

15 files changed

+831
-91
lines changed

rust/catalyst-voting/src/crypto/babystep_giantstep.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use std::collections::HashMap;
55

6-
use super::group::{GroupElement, Scalar};
6+
use crate::crypto::group::{GroupElement, Scalar};
77

88
/// Default balance value.
99
/// Make steps asymmetric, in order to better use caching of baby steps.

rust/catalyst-voting/src/crypto/elgamal.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ use std::ops::{Add, Deref, Mul};
55

66
use rand_core::CryptoRngCore;
77

8-
use super::group::{GroupElement, Scalar};
8+
use crate::crypto::group::{GroupElement, Scalar};
99

1010
/// ``ElGamal`` secret key.
1111
#[derive(Debug, Clone, PartialEq, Eq)]
1212
pub struct SecretKey(Scalar);
1313

1414
/// ``ElGamal`` public key.
15-
#[derive(Debug, Clone, Eq, PartialEq)]
15+
#[derive(Clone, Debug, PartialEq, Eq)]
1616
pub struct PublicKey(GroupElement);
1717

1818
/// ``ElGamal`` ciphertext, encrypted message with the public key.
@@ -37,7 +37,7 @@ impl Deref for PublicKey {
3737

3838
impl SecretKey {
3939
/// Generate a random `SecretKey` value from the random number generator.
40-
pub fn generate<R: CryptoRngCore>(rng: &mut R) -> Self {
40+
pub fn random<R: CryptoRngCore>(rng: &mut R) -> Self {
4141
Self(Scalar::random(rng))
4242
}
4343

rust/catalyst-voting/src/crypto/group/ristretto255.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ impl Scalar {
4545
}
4646

4747
/// additive identity
48-
pub fn zero() -> Self {
48+
pub const fn zero() -> Self {
4949
Scalar(IScalar::ZERO)
5050
}
5151

5252
/// multiplicative identity
53-
pub fn one() -> Self {
53+
pub const fn one() -> Self {
5454
Scalar(IScalar::ONE)
5555
}
5656

@@ -190,6 +190,17 @@ mod tests {
190190
}
191191
}
192192

193+
impl Arbitrary for GroupElement {
194+
type Parameters = ();
195+
type Strategy = BoxedStrategy<Self>;
196+
197+
fn arbitrary_with((): Self::Parameters) -> Self::Strategy {
198+
any::<Scalar>()
199+
.prop_map(|s| GroupElement::GENERATOR.mul(&s))
200+
.boxed()
201+
}
202+
}
203+
193204
#[proptest]
194205
fn scalar_to_bytes_from_bytes_test(e1: Scalar) {
195206
let bytes = e1.to_bytes();

rust/catalyst-voting/src/crypto/hash.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use curve25519_dalek::digest::{
55
};
66

77
/// Blake2b-512 hasher instance.
8+
#[derive(Clone, Debug)]
89
pub struct Blake2b512Hasher(blake2b_simd::State);
910

1011
impl Blake2b512Hasher {

rust/catalyst-voting/src/crypto/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub(crate) mod elgamal;
55
pub(crate) mod group;
66
pub(crate) mod hash;
77
pub(crate) mod zk_dl_equality;
8+
pub(crate) mod zk_unit_vector;

rust/catalyst-voting/src/crypto/zk_dl_equality.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
1313
// cspell: words NIZK dlog
1414

15-
use curve25519_dalek::digest::Update;
15+
use curve25519_dalek::digest::Digest;
1616

17-
use super::{
17+
use crate::crypto::{
1818
group::{GroupElement, Scalar},
1919
hash::Blake2b512Hasher,
2020
};
@@ -55,12 +55,12 @@ fn calculate_challenge(
5555
a_1: &GroupElement, a_2: &GroupElement,
5656
) -> Scalar {
5757
let blake2b_hasher = Blake2b512Hasher::new()
58-
.chain(base_1.to_bytes())
59-
.chain(base_2.to_bytes())
60-
.chain(point_1.to_bytes())
61-
.chain(point_2.to_bytes())
62-
.chain(a_1.to_bytes())
63-
.chain(a_2.to_bytes());
58+
.chain_update(base_1.to_bytes())
59+
.chain_update(base_2.to_bytes())
60+
.chain_update(point_1.to_bytes())
61+
.chain_update(point_2.to_bytes())
62+
.chain_update(a_1.to_bytes())
63+
.chain_update(a_2.to_bytes());
6464

6565
Scalar::from_hash(blake2b_hasher)
6666
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//! ZK unit vector challenges calculation functionality
2+
3+
use curve25519_dalek::digest::Digest;
4+
5+
use crate::{
6+
crypto::{
7+
elgamal::Ciphertext, group::GroupElement, hash::Blake2b512Hasher,
8+
zk_unit_vector::randomness_announcements::Announcement,
9+
},
10+
PublicKey,
11+
};
12+
13+
/// Calculates the first challenge hash.
14+
pub(crate) fn calculate_first_challenge_hash(
15+
commitment_key: &GroupElement, public_key: &PublicKey, ciphertexts: &[Ciphertext],
16+
announcements: &[Announcement],
17+
) -> Blake2b512Hasher {
18+
let mut hash = Blake2b512Hasher::new()
19+
.chain_update(commitment_key.to_bytes())
20+
.chain_update(public_key.to_bytes());
21+
for c in ciphertexts {
22+
hash.update(c.first().to_bytes());
23+
hash.update(c.second().to_bytes());
24+
}
25+
for announcement in announcements {
26+
hash.update(announcement.i.to_bytes());
27+
hash.update(announcement.b.to_bytes());
28+
hash.update(announcement.a.to_bytes());
29+
}
30+
hash
31+
}
32+
33+
/// Calculates the second challenge hash.
34+
pub(crate) fn calculate_second_challenge_hash(
35+
mut com_1_hash: Blake2b512Hasher, ciphertexts: &[Ciphertext],
36+
) -> Blake2b512Hasher {
37+
for c in ciphertexts {
38+
com_1_hash.update(c.first().to_bytes());
39+
com_1_hash.update(c.second().to_bytes());
40+
}
41+
com_1_hash
42+
}

0 commit comments

Comments
 (0)