`pub struct CommitmentEquivalenceProof<G: Group> { /* private fields */ }`

## Expand description

Zero-knowledge proof that an ElGamal ciphertext encrypts the same value as a Pedersen commitment.

This proof can be used to switch from frameworks applicable to ElGamal ciphertexts, to ones applicable to Pedersen commitments (e.g., Bulletproofs for range proofs).

## §Construction

We want to prove in zero knowledge the knowledge of scalars `r_e`

, `v`

, `r_c`

such as

```
R = [r_e]G; B = [v]G + [r_e]K;
// (R, B) is ElGamal ciphertext of `v` for public key `K`
C = [v]G + [r_c]H;
// C is Pedersen commitment to `v`
```

Here, we assume that the conventional group generator `G`

is shared between encryption and
commitment protocols.

An interactive version of the proof can be built as a sigma protocol:

**Commitment.**The prover generates 3 random scalars`e_r`

,`e_v`

and`e_c`

and commits to them via`E_r = [e_r]G`

,`E_b = [e_v]G + [e_r]K`

, and`E_c = [e_v]G + [e_c]H`

.**Challenge.**The verifier sends to the prover random scalar`c`

.**Response.**The prover computes the following scalars and sends them to the verifier.

```
s_r = e_r + c * r_e;
s_v = e_v + c * v;
s_c = e_c + c * r_c;
```

The verification equations are

```
[s_r]G ?= E_r + [c]R;
[s_v]G + [s_r]K ?= E_b + [c]B;
[s_v]G + [s_c]H ?= E_c + [c]C;
```

A non-interactive version of the proof is obtained by applying Fiat–Shamir transform. As with other proofs, it is more efficient to represent a proof as the challenge and responses (i.e., 4 scalars in total).

## §Examples

```
let blinding_base = // Blinding base for Pedersen commitments
// (e.g., from Bulletproofs)
let mut rng = thread_rng();
let (receiver, _) = Keypair::<Ristretto>::generate(&mut rng).into_tuple();
// Create an ElGamal ciphertext of `value` for `receiver`.
let value = 424242_u64;
let ciphertext = CiphertextWithValue::new(value, &receiver, &mut rng)
.generalize();
// Create a blinding factor for the Pedersen commitment of the same value.
let blinding = SecretKey::generate(&mut rng);
let (proof, commitment) = CommitmentEquivalenceProof::new(
&ciphertext,
&receiver,
&blinding,
blinding_base,
&mut Transcript::new(b"custom_proof"),
&mut rng,
);
// Use `commitment` and `blinding` in other proofs...
proof.verify(
&ciphertext.into(),
&receiver,
commitment,
blinding_base,
&mut Transcript::new(b"custom_proof"),
)?;
```

## Implementations§

source§### impl<G: Group> CommitmentEquivalenceProof<G>

### impl<G: Group> CommitmentEquivalenceProof<G>

source#### pub fn new<R: RngCore + CryptoRng>(
ciphertext: &CiphertextWithValue<G>,
receiver: &PublicKey<G>,
commitment_blinding: &SecretKey<G>,
commitment_blinding_base: G::Element,
transcript: &mut Transcript,
rng: &mut R
) -> (Self, G::Element)

#### pub fn new<R: RngCore + CryptoRng>( ciphertext: &CiphertextWithValue<G>, receiver: &PublicKey<G>, commitment_blinding: &SecretKey<G>, commitment_blinding_base: G::Element, transcript: &mut Transcript, rng: &mut R ) -> (Self, G::Element)

Creates a proof based on the `ciphertext`

for `receiver`

and `commitment_blinding`

with `commitment_blinding_base`

for a Pedersen commitment. (The latter two args
correspond to `r_c`

and `H`

in the *Construction* section, respectively.)

##### §Return value

Returns a proof together with the Pedersen commitment.

source#### pub fn verify(
&self,
ciphertext: &Ciphertext<G>,
receiver: &PublicKey<G>,
commitment: G::Element,
commitment_blinding_base: G::Element,
transcript: &mut Transcript
) -> Result<(), VerificationError>

#### pub fn verify( &self, ciphertext: &Ciphertext<G>, receiver: &PublicKey<G>, commitment: G::Element, commitment_blinding_base: G::Element, transcript: &mut Transcript ) -> Result<(), VerificationError>

##### §Errors

Returns an error if this proof does not verify.

## Trait Implementations§

source§### impl<G: Clone + Group> Clone for CommitmentEquivalenceProof<G>

### impl<G: Clone + Group> Clone for CommitmentEquivalenceProof<G>

source§#### fn clone(&self) -> CommitmentEquivalenceProof<G>

#### fn clone(&self) -> CommitmentEquivalenceProof<G>

1.0.0 · source§#### fn clone_from(&mut self, source: &Self)

#### fn clone_from(&mut self, source: &Self)

`source`

. Read more