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
GandKin a prime-order group in which discrete log problem is believed to be hard. - Prover and verifier both know group elements
RandB, which presumably have the same discrete log in basesGandKrespectively. - 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 verifierX_G = [x]GandX_K = [x]K. - Challenge: The verifier sends to the prover random scalar
c. - Response: The prover computes scalar
s = x + crand 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
cis derived usingTranscriptAPI.
§Examples
let mut rng = rand::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>
Sourcepub 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_baseis the second discrete log base (Kin the notation above). The first log base is always theGroupgenerator.secretis the discrete log (rin the notation above).powersare[r]Gand[r]K, respectively. It is not checked whetherris a discrete log of these powers; if this is not the case, the constructed proof will notverify.
Sourcepub 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_baseis the second discrete log base (Kin the notation above). The first log base is always theGroupgenerator.powersare group elements presumably equal to[r]Gand[r]Krespectively, whereris a secret scalar.
§Errors
Returns an error if this proof does not verify.
Sourcepub 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.
Sourcepub 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