Expand description

ZK-proof of paillier encryption in range. Called Пenc or Renc in the CGGMP21 paper.

§Description

A party P has key, pkey - public and private keys in paillier cryptosystem. P also has plaintext, nonce, and ciphertext = key.encrypt_with(plaintext, nonce).

P wants to prove that plaintext is at most l bits, without disclosing it, the pkey, and nonce

§Example

use paillier_zk::{paillier_encryption_in_range as p, IntegerExt};
use rug::{Integer, Complete};

let shared_state_prover = sha2::Sha256::default();
let shared_state_verifier = sha2::Sha256::default();

let mut rng = rand_core::OsRng;

// 0. Setup: prover and verifier share common Ring-Pedersen parameters:

let aux: p::Aux = pregenerated::verifier_aux();
let security = p::SecurityParams {
    l: 1024,
    epsilon: 128,
    q: (Integer::ONE << 128_u32).into(),
};

// 1. Setup: prover prepares the paillier keys

let private_key: fast_paillier::DecryptionKey =
    pregenerated::prover_decryption_key();
let key = private_key.encryption_key();

// 2. Setup: prover has some plaintext and encrypts it

let plaintext = Integer::from_rng_pm(&(Integer::ONE << security.l).complete(), &mut rng);
let (ciphertext, nonce) = key.encrypt_with_random(&mut rng, &plaintext)?;

// 3. Prover computes a non-interactive proof that plaintext is at most 1024 bits:

let data = p::Data { key, ciphertext: &ciphertext };
let (commitment, proof) = p::non_interactive::prove(
    shared_state_prover,
    &aux,
    data,
    p::PrivateData {
        plaintext: &plaintext,
        nonce: &nonce,
    },
    &security,
    &mut rng,
)?;

// 4. Prover sends this data to verifier

send(&data, &commitment, &proof);

// 5. Verifier receives the data and the proof and verifies it

let (data, commitment, proof) = recv();
p::non_interactive::verify(
    shared_state_verifier,
    &aux,
    data,
    &commitment,
    &security,
    &proof,
);

If the verification succeeded, verifier can continue communication with prover

Modules§

  • 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.
  • The non-interactive version of proof. Completed in one round, for example see the documentation of parent module.

Structs§

Type Aliases§