# Struct elastic_elgamal::LogEqualityProof

source · `pub struct LogEqualityProof<G: Group> { /* private fields */ }`

## Expand description

Zero-knowledge proof of equality of two discrete logarithms in different bases, aka Chaum–Pedersen protocol.

## §Construction

This proof is a result of the Fiat–Shamir transform applied to a standard ZKP of equality of the two discrete logs in different bases.

- Public parameters of the proof are the two bases
`G`

and`K`

in a prime-order group in which discrete log problem is believed to be hard. - Prover and verifier both know group elements
`R`

and`B`

, which presumably have the same discrete log in bases`G`

and`K`

respectively. - Prover additionally knows the discrete log in question:
`r = dlog_G(R) = dlog_K(B)`

.

The interactive proof is specified as a sigma protocol (see, e.g., this course) as follows:

**Commitment:**The prover generates random scalar`x`

. The prover sends to the verifier`X_G = [x]G`

and`X_K = [x]K`

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

.**Response:**The prover computes scalar`s = x + cr`

and sends it to the verifier.

Verification equations are:

```
[s]G ?= X_G + [c]R;
[s]K ?= X_K + [c]B.
```

In the non-interactive version of the proof, challenge `c`

is derived from `hash(M)`

,
where `hash()`

is a cryptographically secure hash function, and `M`

is an optional message
verified together with the proof (cf. public-key digital signatures). If `M`

is set, we
use a proof as a *signature of knowledge*. This allows to tie the proof to the context,
so it cannot be (re)used in other contexts.

To reduce the size of the proof, we use the trick underpinning ring signature constructions.
Namely, we represent the proof as `(c, s)`

; during verification, we restore `X_G`

, `X_K`

from the original verification equations above.

## §Implementation details

- The proof is serialized as 2 scalars:
`(c, s)`

. - Proof generation is constant-time. Verification is
**not**constant-time. - Challenge
`c`

is derived using`Transcript`

API.

## §Examples

```
let mut rng = thread_rng();
let (log_base, _) =
Keypair::<Ristretto>::generate(&mut rng).into_tuple();
let (power_g, discrete_log) =
Keypair::<Ristretto>::generate(&mut rng).into_tuple();
let power_k = log_base.as_element() * discrete_log.expose_scalar();
let proof = LogEqualityProof::new(
&log_base,
&discrete_log,
(power_g.as_element(), power_k),
&mut Transcript::new(b"custom_proof"),
&mut rng,
);
proof.verify(
&log_base,
(power_g.as_element(), power_k),
&mut Transcript::new(b"custom_proof"),
)?;
```

## Implementations§

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

### impl<G: Group> LogEqualityProof<G>

source#### pub fn new<R: CryptoRng + RngCore>(
log_base: &PublicKey<G>,
secret: &SecretKey<G>,
powers: (G::Element, G::Element),
transcript: &mut Transcript,
rng: &mut R
) -> Self

#### pub fn new<R: CryptoRng + RngCore>( log_base: &PublicKey<G>, secret: &SecretKey<G>, powers: (G::Element, G::Element), transcript: &mut Transcript, rng: &mut R ) -> Self

Creates a new proof.

##### §Parameters

`log_base`

is the second discrete log base (`K`

in the notation above). The first log base is always the`Group`

generator.`secret`

is the discrete log (`r`

in the notation above).`powers`

are`[r]G`

and`[r]K`

, respectively. It is**not**checked whether`r`

is a discrete log of these powers; if this is not the case, the constructed proof will not`verify`

.

source#### pub fn verify(
&self,
log_base: &PublicKey<G>,
powers: (G::Element, G::Element),
transcript: &mut Transcript
) -> Result<(), VerificationError>

#### pub fn verify( &self, log_base: &PublicKey<G>, powers: (G::Element, G::Element), transcript: &mut Transcript ) -> Result<(), VerificationError>

Verifies this proof.

##### §Parameters

`log_base`

is the second discrete log base (`K`

in the notation above). The first log base is always the`Group`

generator.`powers`

are group elements presumably equal to`[r]G`

and`[r]K`

respectively, where`r`

is a secret scalar.

##### §Errors

Returns an error if this proof does not verify.

source#### pub fn to_bytes(self) -> Vec<u8> ⓘ

#### pub fn to_bytes(self) -> Vec<u8> ⓘ

Serializes this proof into bytes. As described above,
the is serialized as 2 scalars: `(c, s)`

, i.e., challenge and response.

source#### pub fn from_bytes(bytes: &[u8]) -> Option<Self>

#### pub fn from_bytes(bytes: &[u8]) -> Option<Self>

Attempts to parse the proof from `bytes`

. Returns `None`

if `bytes`

do not represent
a well-formed proof.

## Trait Implementations§

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

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

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

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

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

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

`source`

. Read more