Expand description
ZK-proof of paillier encryption in range with El-Gamal commitment. Called Пenc-elg or Renc-elg in the CGGMP24 paper.
§Description
Common (public) inputs: verifier’s Aux data, SecurityParams containing
$\ell$ and $\varepsilon$, curve E, Paillier public key, a ciphertext,
and elliptic points $A, B, X$.
Prover secret inputs: plaintext, nonce, scalars $a, b$, such that:
plaintext$\in \pm 2^\ell$ciphertext == key.encrypt_with(plaintext, nonce)- $A = a \cdot G$
- $B = b \cdot G$
- $X = (a b + \text{plaintext}) \cdot G$
Proof guarantees that plaintext $\in \pm 2^{\ell + \varepsilon}$.
§Example
use paillier_zk::{paillier_encryption_in_range_with_el_gamal as p, IntegerExt};
use fast_paillier::backend::Integer;
use generic_ec::{Point, Scalar, curves::Secp256k1 as E};
let shared_state = "some shared state";
let mut rng = rand_core::OsRng;
// Both parties know predefined security parameters and verifier's aux data
let aux: p::Aux = pregenerated::verifier_aux();
let security = p::SecurityParams {
l: 256,
epsilon: 512,
};
// ...and someone's encryption key
let key: fast_paillier::EncryptionKey =
pregenerated::someone_encryption_key();
// Prover knows its secret `pdata` and `a`
let a = Scalar::random(&mut rng);
let pdata = p::PrivateData {
plaintext: &Integer::from_rng_half_pm(&mut rng, &(Integer::one() << security.l)),
nonce: &Integer::sample_in_mult_group_of(&mut rng, key.n()),
b: &Scalar::random(&mut rng),
};
// Both parties know the public data
let data = p::Data {
key: &key,
ciphertext: &key
.encrypt_with(pdata.plaintext, pdata.nonce)
.unwrap(),
a: &(Point::generator() * a),
b: &(Point::generator() * pdata.b),
x: &(Point::generator() * (a * pdata.b + pdata.plaintext.to_scalar())),
};
// Prover computes a non-interactive proof:
let proof = p::non_interactive::prove::<E, sha2::Sha256>(
&shared_state,
&aux,
data,
pdata,
&security,
&mut rng,
)?;
// Prover sends this data to verifier
send(&data, &proof);
// Verifier receives the data and the proof and verifies it
let (data, proof) = recv();
p::non_interactive::verify::<E, sha2::Sha256>(
&shared_state,
&aux,
data,
&proof,
&security,
);If the verification succeeded, verifier can continue communication with prover
Modules§
- interactive
- The interactive version of the ZK proof. Should be completed in 3 rounds: prover commits to data, verifier responds with a random challenge, and prover gives proof with commitment and challenge.
- non_
interactive - The non-interactive version of proof. Completed in one round, for example see the documentation of parent module.
Structs§
- Aux
- Auxiliary data known to both prover and verifier
- Commitment
- Prover’s public commitment
- Data
- Public data that both parties know
- Invalid
Proof - Error indicating that proof is invalid
- NiProof
- The non-interactive ZK proof. Computed by
non_interactive::prove. Combines commitment and proof. - Private
Commitment - Prover’s secret commitment nonce
- Private
Data - Private data of prover
- Proof
- Range Proof with El-Gamal commitment. Computed by
interactive::prove - Security
Params - Security parameters for proof. Choosing the values is a tradeoff between security, speed and correctness
Type Aliases§
- Challenge
- Verifier’s challenge to prover. Can be obtained deterministically by
non_interactive::challengeor randomly byinteractive::challenge