Skip to content

A NIZK PoK to prove knowledge of the preimage of an El Gamal cipherterxt

Notifications You must be signed in to change notification settings

driemworks/el-gamal-sigma-protocol

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Elliptic Curve El Gamal $\Sigma$ Protocol

This is a non-interactive zero-knowledge proof of knowedge (NIZKPoK) protocol to prove that you know the preimage of an El Gamal ciphertext. More specifically, it allows a prover to convince a verifier that a commitment is of the preimage of an El Gamal ciphertext. This protocol can be useful in situations where you want to prove knowledge of what the encrypted message is without revealing the data.

This is a work in progress and not safe for production use.

Usage

Setup

Build and test the project with cargo:

cargo build
cargo test

Usage

Example with JubJub (see the tests).

let mut rng = test_rng();
// the secret key
let x = <JubJub as Group>::ScalarField::rand(&mut rng);
let g: JubJub = JubJub::generator().into();
// the public key
let h: JubJub = g.mul(x).into();

let params = Params { g, h };

let (commitment, ciphertext, proof) = 
    ElGamalSigmaProtocol::prove(x, params.clone(), test_rng());
let result = 
    ElGamalSigmaProtocol::verify(commitment, ciphertext, proof, params);
assert_eq!(result, true);

Details

This section contains technical details on how the protocol works.

$\Sigma$-Protocols

A sigma protocol is an interactive public 3-move public coin flip protocol where a prover convinces a verifier that they know the witness $w$ of a public instance $x$ without disclosing $x$. With a Fiat-Shamir transform, this can be transformed into a non-interactive protocol, where each participant only makes a single move.

The Protocol

The protocol works over elliptic curves. Let $p$ be a large prime and choose a prime $q$ s.t. $q | p- 1$. We will assume we have an elliptic curve group $\mathbb{G}$ with an additive group operation (since we are using the arkworks library and the programming model assumes an additive operation).

Let $P$ be the prover and $V$ be the verifier. Choose $x \xleftarrow{R} \mathbb{Z}_q$ and set $H := xG$ where $G \in \mathbb{G}$ is a generator. Let $s \in \mathbb{Z}_q$ be the secret that we want to prove knowledge of. Then the protocol is as follows:

Prover

  1. Encrypt the message $s$ for the public key $H$ using El Gamal: $(c_1, c_2) = (kG, s(kH))$ where $k \xleftarrow{R} \mathbb{Z}_q$
  2. Calculate a (Pedersen) commitment $c = sG + sH$
  3. Choose $r \xleftarrow{R} \mathbb{Z}_q$ and set $t = kG$, $a = kH$.
  4. Compute $e = H(t, a, c_1, c_2, AUX)$
  5. Set $z = k + es$
  6. Send $(t, a, z, c, c_1, c_2)$ to the verifier.

Verifier

  1. Compute $e = H(t, a, c_1, c_2, AUX)$
  2. Check if $zG + zH == t + a + e*c$. If so, output $1$, otherwise output $0$.

This works since:

$zG + zH = (k + es)G + (k + es)H = kG + esG + kH + esH = t + e(sG) + a + e(sH) = t + a + e(sG + sH)$

Releases

No releases published

Packages

No packages published

Languages