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}