Skip to main content

sigma_proofs/
traits.rs

1//! Generic interface for 3-message Sigma protocols.
2//!
3//! This module defines the [`SigmaProtocol`] and [`SigmaProtocolSimulator`] traits,
4//! used to describe interactive zero-knowledge proofs of knowledge,
5//! such as Schnorr proofs, that follow the 3-message Sigma protocol structure.
6
7use crate::errors::Result;
8use alloc::vec::Vec;
9use group::Group;
10use spongefish::{Decoding, Encoding, NargDeserialize, NargSerialize};
11
12/// An automatic trait helper for sampling scalars from an RNG.
13///
14/// This trait is implemented for all types implementing `rand_core::RngCore`.
15/// Passing any cryptographically-secure random number generator (CSRNG) is
16/// recommended for creating proofs.
17pub trait ScalarRng {
18    fn random_scalars<G: Group, const N: usize>(&mut self) -> [G::Scalar; N];
19    fn random_scalars_vec<G: Group>(&mut self, n: usize) -> Vec<G::Scalar>;
20}
21
22pub type Transcript<P> = (
23    Vec<<P as SigmaProtocol>::Commitment>,
24    <P as SigmaProtocol>::Challenge,
25    Vec<<P as SigmaProtocol>::Response>,
26);
27
28/// A trait defining the behavior of a generic Sigma protocol.
29///
30/// A Sigma protocol is a 3-message proof protocol where a prover can convince
31/// a verifier of knowledge of a witness for a given public statement
32/// without revealing the witness.
33///
34/// ## Associated Types
35/// - `Commitment`: The prover's initial commitment.
36/// - `ProverState`: The prover's internal state needed to compute a response.
37/// - `Response`: The prover's response to a verifier's challenge.
38/// - `Witness`: The prover's secret knowledge.
39/// - `Challenge`: The verifier's challenge value.
40///
41///  ## Minimal Implementation
42/// Types implementing [`SigmaProtocol`] must define:
43/// - `prover_commit` — Generates a commitment and internal state.
44/// - `prover_response` — Computes a response to a challenge.
45/// - `verifier` — Verifies a full transcript `(commitment, challenge, response)`.
46///
47/// ## Serialization
48/// Implementors must also provide methods for serialization and deserialization
49/// of each component of the proof.
50/// Required methods:
51/// - `serialize_commitment` / `deserialize_commitment`
52/// - `serialize_challenge` / `deserialize_challenge`
53/// - `serialize_response` / `deserialize_response`
54///
55/// These functions should encode/decode each component into/from a compact binary format.
56///
57/// ## Identification
58/// To allow transcript hash binding and protocol distinction,
59/// implementors must provide:
60/// - `protocol_identifier` — A fixed byte identifier of the protocol.
61/// - `instance_label` — A label specific to the instance being proven.
62pub trait SigmaProtocol {
63    type Commitment: Encoding<[u8]> + NargSerialize + NargDeserialize;
64    type Challenge: Decoding<[u8]>;
65    type Response: Encoding<[u8]> + NargSerialize + NargDeserialize;
66    type ProverState;
67    type Witness;
68
69    /// First step of the protocol. Given the witness and RNG, this generates:
70    /// - A public commitment to send to the verifier.
71    /// - The internal state to use when computing the response.
72    fn prover_commit(
73        &self,
74        witness: &Self::Witness,
75        rng: &mut impl ScalarRng,
76    ) -> Result<(Vec<Self::Commitment>, Self::ProverState)>;
77
78    /// Computes the prover's response to a challenge based on the prover state.
79    fn prover_response(
80        &self,
81        state: Self::ProverState,
82        challenge: &Self::Challenge,
83    ) -> Result<Vec<Self::Response>>;
84
85    /// Final step of the protocol: checks that the commitment, challenge, and response form a valid transcript.
86    ///
87    /// Returns:
88    /// - `Ok(())` if the transcript is valid.
89    /// - `Err(())` otherwise.
90    fn verifier(
91        &self,
92        commitment: &[Self::Commitment],
93        challenge: &Self::Challenge,
94        response: &[Self::Response],
95    ) -> Result<()>;
96
97    fn commitment_len(&self) -> usize;
98
99    fn response_len(&self) -> usize;
100
101    fn protocol_identifier(&self) -> [u8; 64];
102
103    fn instance_label(&self) -> impl AsRef<[u8]>;
104}
105
106/// A trait defining the behavior of a Sigma protocol for which simulation of transcripts is necessary.
107///
108/// Every Sigma protocol can be simulated, but in practice, this is primarily used
109/// for proving security properties (zero-knowledge, soundness, etc.).
110///
111/// Some protocols (e.g. OR compositions) require simulation capabilities during actual proof generation.
112///
113/// ## Minimal Implementation
114/// Types implementing [`SigmaProtocolSimulator`] must define:
115/// - `simulate_proof`
116/// - `simulate_transcript`
117pub trait SigmaProtocolSimulator: SigmaProtocol {
118    /// Generates a random response (e.g. for simulation or OR composition).
119    ///
120    /// Typically used to simulate a proof without a witness.
121    fn simulate_response(&self, rng: &mut impl ScalarRng) -> Vec<Self::Response>;
122
123    /// Simulates a commitment for which ('commitment', 'challenge', 'response') is a valid transcript.
124    ///
125    /// This function allows to omit commitment in compact proofs of the type ('challenge', 'response').
126    fn simulate_commitment(
127        &self,
128        challenge: &Self::Challenge,
129        response: &[Self::Response],
130    ) -> Result<Vec<Self::Commitment>>;
131
132    /// Generates a full simulated proof transcript (commitment, challenge, response)
133    /// without requiring knowledge of a witness.
134    fn simulate_transcript(&self, rng: &mut impl ScalarRng) -> Result<Transcript<Self>>;
135}