Skip to content

Commit

Permalink
implement tally proof generation and tally proof verification
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-Leshiy committed Oct 2, 2024
1 parent c275f5a commit ae6c00c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
8 changes: 8 additions & 0 deletions rust/catalyst-voting/src/crypto/elgamal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ impl Deref for SecretKey {
}
}

impl Deref for PublicKey {
type Target = GroupElement;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl SecretKey {
/// Generate a random `SecretKey` value from the random number generator.
pub fn generate<R: CryptoRngCore>(rng: &mut R) -> Self {
Expand Down
8 changes: 2 additions & 6 deletions rust/catalyst-voting/src/crypto/zk_dl_equality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
//! points `point_1` and `point_2`. The witness, on the other hand
//! is the discrete logarithm, `dlog`.
#![allow(dead_code, unused_variables)]

use curve25519_dalek::digest::Update;

use super::{
Expand Down Expand Up @@ -41,10 +39,8 @@ pub fn verify_dleq_proof(
proof: &DleqProof, base_1: &GroupElement, base_2: &GroupElement, point_1: &GroupElement,
point_2: &GroupElement,
) -> bool {
let r1 = base_1 * &proof.1;
let r2 = base_2 * &proof.1;
let a_1 = &r1 - &(point_1 * &proof.0);
let a_2 = &r2 - &(point_2 * &proof.0);
let a_1 = &(base_1 * &proof.1) - &(point_1 * &proof.0);
let a_2 = &(base_2 * &proof.1) - &(point_2 * &proof.0);

let challenge = calculate_challenge(base_1, base_2, point_1, point_2, &a_1, &a_2);
challenge == proof.0
Expand Down
47 changes: 44 additions & 3 deletions rust/catalyst-voting/src/tally/proof.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,56 @@
//! Tally proof generation and verification procedures.
//! It allows to transparently verify the correctness of decryption tally procedure.
use std::ops::Mul;

use rand_core::CryptoRngCore;

use super::EncryptedTally;
use crate::SecretKey;
use crate::{
crypto::{
group::{GroupElement, Scalar},
zk_dl_equality::{generate_dleq_proof, verify_dleq_proof, DleqProof},
},
PublicKey, SecretKey,
};

/// Tally proof struct.
#[allow(clippy::module_name_repetitions)]
pub struct TallyProof(DleqProof);

/// Generates a tally proof.
/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#tally-proof)
#[allow(clippy::module_name_repetitions)]
pub fn generate_tally_proof<R: CryptoRngCore>(
_tally_result: &EncryptedTally, _secret_key: &SecretKey, _rng: &mut R,
) {
encrypted_tally: &EncryptedTally, secret_key: &SecretKey, rng: &mut R,
) -> TallyProof {
let randomness = Scalar::random(rng);
let e1 = encrypted_tally.0.first();
let d = e1.mul(secret_key);

let proof = generate_dleq_proof(
&GroupElement::GENERATOR,
e1,
&secret_key.public_key(),
&d,
secret_key,
&randomness,
);

TallyProof(proof)
}

/// Verifies a tally proof.
/// More detailed described [here](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/voting_transaction/crypto/#tally-proof)
#[must_use]
#[allow(clippy::module_name_repetitions)]
pub fn verify_tally_proof(
encrypted_tally: &EncryptedTally, tally: u64, public_key: &PublicKey, proof: &TallyProof,
) -> bool {
let tally = Scalar::from(tally);
let e1 = encrypted_tally.0.first();
let e2 = encrypted_tally.0.second();
let d = &GroupElement::GENERATOR.mul(&tally) - e2;

verify_dleq_proof(&proof.0, &GroupElement::GENERATOR, e1, public_key, &d)
}

0 comments on commit ae6c00c

Please sign in to comment.