Skip to content

Commit fc34330

Browse files
committed
feat(protocols): enhance error handling and improve AND/OR composition
- feat: add error handling for prover_commit and prover_response in SigmaProtocol trait - feat: redesign AND/OR composition protocols to support any number of SchnorrProtocol instances - feat: enable Fiat-Shamir transformations for AND/OR composition protocols - test: implement comprehensive tests for new AND/OR protocol functionality
1 parent 240b6e6 commit fc34330

12 files changed

+474
-447
lines changed

src/errors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,8 @@ pub enum ProofError {
2323
NotImplemented(&'static str),
2424
/// Serialization of a group element/scalar failed
2525
#[error("Serialization of a group element/scalar failed")]
26+
/// Other error
2627
GroupSerializationFailure,
28+
#[error("Other")]
29+
Other,
2730
}

src/fiat_shamir.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ where
6262
&mut self,
6363
witness: &P::Witness,
6464
rng: &mut (impl RngCore + CryptoRng),
65-
) -> (P::Commitment, P::Challenge, P::Response) {
65+
) -> Result<(P::Commitment, P::Challenge, P::Response), ProofError> {
6666
let mut codec = self.hash_state.clone();
6767

68-
let (commitment, prover_state) = self.sigmap.prover_commit(witness, rng);
68+
let (commitment, prover_state) = self.sigmap.prover_commit(witness, rng)?;
6969
// Commitment data for challenge generation
7070
let mut data = Vec::new();
7171
for commit in &commitment {
@@ -74,13 +74,10 @@ where
7474
// Fiat Shamir challenge
7575
let challenge = codec.prover_message(&data).verifier_challenge();
7676
// Prover's response
77-
let response = self.sigmap.prover_response(prover_state, &challenge);
77+
let response = self.sigmap.prover_response(prover_state, &challenge)?;
7878
// Local verification of the proof
79-
assert!(self
80-
.sigmap
81-
.verifier(&commitment, &challenge, &response)
82-
.is_ok());
83-
(commitment, challenge, response)
79+
self.sigmap.verifier(&commitment, &challenge, &response)?;
80+
Ok((commitment, challenge, response))
8481
}
8582

8683
/// Verify a non-interactive proof and returns a Result: `Ok(())` if the proof verifies successfully, `Err(())` otherwise.
@@ -110,11 +107,12 @@ where
110107
&mut self,
111108
witness: &P::Witness,
112109
rng: &mut (impl RngCore + CryptoRng),
113-
) -> Vec<u8> {
114-
let (commitment, challenge, response) = self.prove(witness, rng);
115-
self.sigmap
110+
) -> Result<Vec<u8>, ProofError> {
111+
let (commitment, challenge, response) = self.prove(witness, rng)?;
112+
Ok(self
113+
.sigmap
116114
.serialize_batchable(&commitment, &challenge, &response)
117-
.unwrap()
115+
.unwrap())
118116
}
119117

120118
pub fn verify_batchable(&mut self, proof: &[u8]) -> Result<(), ProofError> {
@@ -144,17 +142,18 @@ where
144142
&mut self,
145143
witness: &P::Witness,
146144
rng: &mut (impl RngCore + CryptoRng),
147-
) -> Vec<u8> {
148-
let (commitment, challenge, response) = self.prove(witness, rng);
149-
self.sigmap
145+
) -> Result<Vec<u8>, ProofError> {
146+
let (commitment, challenge, response) = self.prove(witness, rng)?;
147+
Ok(self
148+
.sigmap
150149
.serialize_compact(&commitment, &challenge, &response)
151-
.unwrap()
150+
.unwrap())
152151
}
153152

154153
pub fn verify_compact(&mut self, proof: &[u8]) -> Result<(), ProofError> {
155154
let (challenge, response) = self.sigmap.deserialize_compact(proof).unwrap();
156155
// Compute the commitments
157-
let commitment = self.sigmap.get_commitment(&challenge, &response);
156+
let commitment = self.sigmap.get_commitment(&challenge, &response)?;
158157
// Verify the proof
159158
self.verify(&commitment, &challenge, &response)
160159
}

src/group_morphism.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,7 @@ where
174174
self.morphism
175175
.group_elements
176176
.extend(iter::repeat(G::identity()).take(n));
177-
let points = (start..start + n)
178-
.map(PointVar)
179-
.collect::<Vec<_>>();
177+
let points = (start..start + n).map(PointVar).collect::<Vec<_>>();
180178
self.morphism.num_elements += n;
181179
points
182180
}

src/proof_builder.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616
use group::{Group, GroupEncoding};
1717
use rand::{CryptoRng, RngCore};
1818

19-
use crate::{
20-
codec::ShakeCodec, GroupMorphismPreimage, NISigmaProtocol, PointVar, ProofError, ScalarVar,
21-
SchnorrProtocol,
22-
};
19+
use crate::{codec::ShakeCodec, NISigmaProtocol, PointVar, ProofError, ScalarVar, SchnorrProtocol};
2320

2421
/// A builder that helps construct Sigma proofs for linear group relations.
2522
///
@@ -44,7 +41,7 @@ where
4441
{
4542
/// Creates a new proof builder with a Schnorr protocol instance using the given domain separator.
4643
pub fn new(domain_sep: &[u8]) -> Self {
47-
let schnorr_protocol = SchnorrProtocol(GroupMorphismPreimage::<G>::new());
44+
let schnorr_protocol = SchnorrProtocol::<G>::new();
4845
let protocol = NISigmaProtocol::<SchnorrProtocol<G>, ShakeCodec<G>, G>::new(
4946
domain_sep,
5047
schnorr_protocol,
@@ -59,36 +56,36 @@ where
5956
/// - `lhs`: The variable representing the left-hand group element
6057
/// - `rhs`: A list of (scalar variable, point variable) tuples for the linear combination
6158
pub fn append_equation(&mut self, lhs: PointVar, rhs: &[(ScalarVar, PointVar)]) {
62-
self.protocol.sigmap.0.append_equation(lhs, rhs);
59+
self.protocol.sigmap.append_equation(lhs, rhs);
6360
}
6461

6562
/// Allocates `n` scalar variables for use in the proof.
6663
///
6764
/// Returns a vector of `ScalarVar` indices.
6865
pub fn allocate_scalars(&mut self, n: usize) -> Vec<ScalarVar> {
69-
self.protocol.sigmap.0.allocate_scalars(n)
66+
self.protocol.sigmap.allocate_scalars(n)
7067
}
7168

7269
/// Allocates `n` point variables (group elements) for use in the proof.
7370
///
7471
/// Returns a vector of `PointVar` indices.
7572
pub fn allocate_elements(&mut self, n: usize) -> Vec<PointVar> {
76-
self.protocol.sigmap.0.allocate_elements(n)
73+
self.protocol.sigmap.allocate_elements(n)
7774
}
7875

7976
/// Assigns specific group elements to point variables (indices).
8077
///
8178
/// # Parameters
8279
/// - `elements`: A list of `(PointVar, GroupElement)` pairs
8380
pub fn set_elements(&mut self, elements: &[(PointVar, G)]) {
84-
self.protocol.sigmap.0.set_elements(elements);
81+
self.protocol.sigmap.set_elements(elements);
8582
}
8683

8784
/// Returns the expected group element results (`lhs`) of the current equations.
8885
///
8986
/// This corresponds to the image values of the equations under the morphism.
9087
pub fn image(&self) -> Vec<G> {
91-
self.protocol.sigmap.0.image()
88+
self.protocol.sigmap.image()
9289
}
9390

9491
/// Generates a non-interactive zero-knowledge proof for the current statement using the given witness.
@@ -103,7 +100,7 @@ where
103100
&mut self,
104101
witness: &[<G as Group>::Scalar],
105102
rng: &mut (impl RngCore + CryptoRng),
106-
) -> Vec<u8> {
103+
) -> Result<Vec<u8>, ProofError> {
107104
let witness_tmp = witness.to_vec();
108105
self.protocol.prove_batchable(&witness_tmp, rng)
109106
}
@@ -131,7 +128,7 @@ where
131128
&mut self,
132129
witness: &[<G as Group>::Scalar],
133130
rng: &mut (impl RngCore + CryptoRng),
134-
) -> Vec<u8> {
131+
) -> Result<Vec<u8>, ProofError> {
135132
let witness_tmp = witness.to_vec();
136133
self.protocol.prove_compact(&witness_tmp, rng)
137134
}

0 commit comments

Comments
 (0)