Skip to content

Commit 3acdb62

Browse files
committed
Merge branch 'main' of github.com:mmaker/sigma-rs into victor/branch-1
2 parents ab6b25a + f9025ee commit 3acdb62

20 files changed

+411
-166
lines changed

Cargo.toml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,21 @@ exclude = [
2222
[dependencies]
2323
ff = { version = "0.13", features = ["derive"] }
2424
group = "0.13.0"
25-
hex = "0.4"
2625
num-bigint = "0.4.6"
2726
num-traits = "0.2.19"
2827
rand = "0.8.5"
29-
serde = "1"
30-
serde_derive = "1"
31-
sha2 = "0.10"
3228
sha3 = "0.10.8"
33-
subtle = "2.6.1"
3429
thiserror = "1"
3530
tiny-keccak = { version = "2.0.2", features = ["fips202"] }
3631

3732
[dev-dependencies]
38-
bincode = "2"
3933
bls12_381 = "0.8.0"
40-
criterion = { version = "0.6", features = ["html_reports"] }
4134
curve25519-dalek = { version = "4", default-features = false, features = ["serde", "rand_core", "alloc", "digest", "precomputed-tables", "group"] }
42-
hex-literal = "1.0.0"
35+
hex = "0.4"
4336
json = "0.12.4"
4437
sha2 = "0.10"
4538
sigma-rs = { path = ".", features = ["test-utils"] }
39+
subtle = "2.6.1"
4640

4741
[profile.dev]
4842
# Makes tests run much faster at the cost of slightly longer builds and worse debug info.

src/codec/keccak_codec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! # Keccak-based Fiat-Shamir Codec for vector tests
22
//!
3-
//! This module implements a **Fiat-Shamir codec** using the Keccak-f[1600] permutation
3+
//! This module implements a **Fiat-Shamir codec** using the Keccak-f\[1600\] permutation
44
//! in a duplex sponge construction
55
//!
66
//! It includes:
@@ -17,7 +17,7 @@
1717
//! - The `verifier_challenge` logic performs SHAKE-style domain separation and modulus reduction via `num-bigint`.
1818
//!
1919
//! ## Components
20-
//! - `KeccakPermutationState`: Low-level Keccak-f[1600] state representation
20+
//! - `KeccakPermutationState`: Low-level Keccak-f\[1600\] state representation
2121
//! - `KeccakDuplexSponge`: Duplex sponge over 200-byte state buffer
2222
//! - `ByteSchnorrCodec`: Fiat-Shamir codec compatible with Sage Schnorr proofs
2323
use crate::codec::r#trait::{Codec, DuplexSpongeInterface};

src/codec/shake_codec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
//! Implementation of a Fiat-Shamir codec using SHAKE128
22
//!
3-
//! This module defines `ShakeCodec`, a concrete implementation of the `Codec`
3+
//! This module defines [`ShakeCodec`], a concrete implementation of the [`Codec`]
44
//! trait. It uses the SHAKE128 extendable output function (XOF) from the Keccak family
55
//! to generate Fiat-Shamir challenges for Sigma protocols.
66
//!
77
//! It allows commitments (group elements) to be absorbed into a codec,
88
//! and produces scalar challenges by squeezing bytes from the hash state.
99
//!
1010
//! # Usage
11-
//! - The prover and verifier absorb the same messages into identical `ShakeCodec` instances.
11+
//! - The prover and verifier absorb the same messages into identical [`ShakeCodec`] instances.
1212
//! - The prover and the verifier then squeeze the hash to generate a challenge scalar for the protocol. The verifier can check that the prover used the challenge output by the codec because he owns an identical codec.
1313
1414
use ff::PrimeField;

src/codec/trait.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Codec Trait
22
//!
3-
//! This module defines the `Codec` trait, a generic interface to manage codecs of a protocol execution.
3+
//! This module defines the [`Codec`] trait, a generic interface to manage codecs of a protocol execution.
44
55
pub trait DuplexSpongeInterface {
66
fn new(iv: &[u8]) -> Self;
@@ -17,7 +17,7 @@ pub trait DuplexSpongeInterface {
1717
/// The output is deterministic for a given set of input. Thus, both Prover and Verifier can generate the codec on their sides and ensure the same inputs have been used in both side of the protocol.
1818
///
1919
/// ## Minimal Implementation
20-
/// Types implementing `Codec` must define:
20+
/// Types implementing [`Codec`] must define:
2121
/// - `new`
2222
/// - `prover_message`
2323
/// - `verifier_challenge`

src/errors.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,19 @@
66
//! These errors include:
77
//! - Verification failures (e.g., when a proof does not verify correctly).
88
//! - Mismatched parameters during batch verification.
9-
//! - Not implemented methods
10-
//! - Group element/scalar serialization failed
9+
//! - Unimplemented methods.
10+
//! - Group element or scalar serialization failures.
1111
use thiserror::Error;
1212
/// An error during proving or verification, such as a verification failure.
1313
#[derive(Debug, Error)]
1414
pub enum ProofError {
1515
/// Something is wrong with the proof, causing a verification failure.
1616
#[error("Verification failed.")]
1717
VerificationFailure,
18-
/// Occurs during batch verification if the batch parameters do not have the right size.
18+
/// Indicates a mismatch in parameter sizes during batch verification.
1919
#[error("Mismatched parameter sizes for batch verification.")]
2020
ProofSizeMismatch,
21-
/// Occurs when a feature is not implemented yet.
22-
#[error("The method is not yet implemented for this struct")]
23-
NotImplemented(&'static str),
24-
/// Serialization of a group element/scalar failed
25-
#[error("Serialization of a group element/scalar failed")]
21+
/// Serialization of a group element/scalar has failed.
22+
#[error("Serialization of a group element/scalar failed.")]
2623
GroupSerializationFailure,
27-
/// Other error
28-
#[error("Other")]
29-
Other,
3024
}

src/fiat_shamir.rs

Lines changed: 100 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Fiat-Shamir transformation for Sigma protocols.
22
//!
3-
//! This module defines `NISigmaProtocol`, a generic non-interactive Sigma protocol wrapper,
3+
//! This module defines [`NISigmaProtocol`], a generic non-interactive Sigma protocol wrapper,
44
//! based on applying the Fiat-Shamir heuristic using a codec.
55
//!
66
//! It transforms an interactive Sigma protocol into a non-interactive one,
@@ -9,11 +9,13 @@
99
//!
1010
//! # Usage
1111
//! This struct is generic over:
12-
//! - `P`: the underlying Sigma protocol (`SigmaProtocol` trait).
13-
//! - `C`: the codec (`Codec` trait).
14-
//! - `G`: the group used for commitments and operations (`Group` trait).
12+
//! - `P`: the underlying Sigma protocol ([`SigmaProtocol`] trait).
13+
//! - `C`: the codec ([`Codec`] trait).
14+
//! - `G`: the group used for commitments and operations ([`Group`] trait).
1515
16-
use crate::{codec::Codec, CompactProtocol, ProofError, SigmaProtocol};
16+
use crate::codec::Codec;
17+
use crate::errors::ProofError;
18+
use crate::traits::{CompactProtocol, SigmaProtocol};
1719

1820
use group::{Group, GroupEncoding};
1921
use rand::{CryptoRng, RngCore};
@@ -26,7 +28,7 @@ type Transcript<P> = (
2628

2729
/// A Fiat-Shamir transformation of a Sigma protocol into a non-interactive proof.
2830
///
29-
/// `NISigmaProtocol` wraps an interactive Sigma protocol `P`
31+
/// [`NISigmaProtocol`] wraps an interactive Sigma protocol `P`
3032
/// and a hash-based codec `C`, to produce non-interactive proofs.
3133
///
3234
/// It manages the domain separation, codec reset,
@@ -55,7 +57,14 @@ where
5557
P: SigmaProtocol<Commitment = Vec<G>, Challenge = <G as Group>::Scalar>,
5658
C: Codec<Challenge = <G as Group>::Scalar> + Clone,
5759
{
58-
/// Creates a new non-interactive Sigma protocol, identified by a domain separator (usually fixed per protocol instantiation), and an initialized Sigma protocol instance.
60+
/// Constructs a new [`NISigmaProtocol`] instance.
61+
///
62+
/// # Parameters
63+
/// - `iv`: Domain separation tag for the hash function (e.g., protocol name or context).
64+
/// - `instance`: An instance of the interactive Sigma protocol.
65+
///
66+
/// # Returns
67+
/// A new [`NISigmaProtocol`] that can generate and verify non-interactive proofs.
5968
pub fn new(iv: &[u8], instance: P) -> Self {
6069
let hash_state = C::new(iv);
6170
Self {
@@ -64,7 +73,23 @@ where
6473
}
6574
}
6675

67-
/// Produces a non-interactive proof for a witness.
76+
/// Generates a non-interactive proof for a witness.
77+
///
78+
/// Executes the interactive protocol steps (commit, derive challenge via hash, respond),
79+
/// and checks the result locally for consistency.
80+
///
81+
/// # Parameters
82+
/// - `witness`: The secret witness for the Sigma protocol.
83+
/// - `rng`: A cryptographically secure random number generator.
84+
///
85+
/// # Returns
86+
/// A tuple of:
87+
/// - `P::Commitment`: The prover's commitment(s).
88+
/// - `P::Challenge`: The challenge derived via Fiat-Shamir.
89+
/// - `P::Response`: The prover's response.
90+
///
91+
/// # Panics
92+
/// Panics if local verification fails.
6893
pub fn prove(
6994
&mut self,
7095
witness: &P::Witness,
@@ -93,7 +118,21 @@ where
93118
Ok((commitment, challenge, response))
94119
}
95120

96-
/// Verify a non-interactive proof and returns a Result: `Ok(())` if the proof verifies successfully, `Err(())` otherwise.
121+
/// Verifies a non-interactive proof using the Fiat-Shamir transformation.
122+
///
123+
/// # Parameters
124+
/// - `commitment`: The commitment(s) sent by the prover.
125+
/// - `challenge`: The challenge allegedly derived via Fiat-Shamir.
126+
/// - `response`: The prover's response to the challenge.
127+
///
128+
/// # Returns
129+
/// - `Ok(())` if the proof is valid.
130+
/// - `Err(ProofError::VerificationFailure)` if the challenge is invalid or the response fails to verify.
131+
///
132+
/// # Errors
133+
/// - Returns `ProofError::VerificationFailure` if:
134+
/// - The challenge doesn't match the recomputed one from the commitment.
135+
/// - The response fails verification under the Sigma protocol.
97136
pub fn verify(
98137
&mut self,
99138
commitment: &P::Commitment,
@@ -115,7 +154,17 @@ where
115154
false => Err(ProofError::VerificationFailure),
116155
}
117156
}
118-
157+
/// Generates a batchable, serialized non-interactive proof.
158+
///
159+
/// # Parameters
160+
/// - `witness`: The secret witness.
161+
/// - `rng`: A cryptographically secure random number generator.
162+
///
163+
/// # Returns
164+
/// A serialized proof suitable for batch verification.
165+
///
166+
/// # Panics
167+
/// Panics if serialization fails (should not happen under correct implementation).
119168
pub fn prove_batchable(
120169
&mut self,
121170
witness: &P::Witness,
@@ -135,6 +184,19 @@ where
135184
.unwrap())
136185
}
137186

187+
/// Verifies a batchable non-interactive proof.
188+
///
189+
/// # Parameters
190+
/// - `proof`: A serialized batchable proof.
191+
///
192+
/// # Returns
193+
/// - `Ok(())` if the proof is valid.
194+
/// - `Err(ProofError)` if deserialization or verification fails.
195+
///
196+
/// # Errors
197+
/// - Returns `ProofError::VerificationFailure` if:
198+
/// - The challenge doesn't match the recomputed one from the commitment.
199+
/// - The response fails verification under the Sigma protocol.
138200
pub fn verify_batchable(&mut self, proof: &[u8]) -> Result<(), ProofError> {
139201
let (commitment, response) = self.sigmap.deserialize_batchable(proof).unwrap();
140202

@@ -158,6 +220,19 @@ where
158220
P: SigmaProtocol<Commitment = Vec<G>, Challenge = <G as Group>::Scalar> + CompactProtocol,
159221
C: Codec<Challenge = <G as Group>::Scalar> + Clone,
160222
{
223+
/// Generates a compact serialized proof.
224+
///
225+
/// Uses a more space-efficient representation compared to batchable proofs.
226+
///
227+
/// # Parameters
228+
/// - `witness`: The secret witness.
229+
/// - `rng`: A cryptographically secure random number generator.
230+
///
231+
/// # Returns
232+
/// A compact, serialized proof.
233+
///
234+
/// # Panics
235+
/// Panics if serialization fails.
161236
pub fn prove_compact(
162237
&mut self,
163238
witness: &P::Witness,
@@ -170,6 +245,21 @@ where
170245
.unwrap())
171246
}
172247

248+
/// Verifies a compact proof.
249+
///
250+
/// Recomputes the commitment from the challenge and response, then verifies it.
251+
///
252+
/// # Parameters
253+
/// - `proof`: A compact serialized proof.
254+
///
255+
/// # Returns
256+
/// - `Ok(())` if the proof is valid.
257+
/// - `Err(ProofError)` if deserialization or verification fails.
258+
///
259+
/// # Errors
260+
/// - Returns `ProofError::VerificationFailure` if:
261+
/// - Deserialization fails.
262+
/// - The recomputed commitment or response is invalid under the Sigma protocol.
173263
pub fn verify_compact(&mut self, proof: &[u8]) -> Result<(), ProofError> {
174264
let (challenge, response) = self.sigmap.deserialize_compact(proof).unwrap();
175265
// Compute the commitments

0 commit comments

Comments
 (0)