Skip to content

Commit 8c7e50e

Browse files
committed
fix: remove CustomSchnorrProtocol's duplicated impl.
1 parent 02e495f commit 8c7e50e

File tree

12 files changed

+324
-375
lines changed

12 files changed

+324
-375
lines changed

examples/simple_composition.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use group::Group;
66
use rand::rngs::OsRng;
77
use sigma_rs::{
88
codec::Shake128DuplexSponge,
9-
composition::{Protocol, ProtocolWitness},
9+
composition::{ComposedRelation, ProtocolWitness},
1010
errors::Error,
1111
LinearRelation, Nizk,
1212
};
@@ -18,7 +18,7 @@ type ProofResult<T> = Result<T, Error>;
1818
/// 1. Knowledge of discrete log: P1 = x1 * G
1919
/// 2. Knowledge of DLEQ: (P2 = x2 * G, Q = x2 * H)
2020
#[allow(non_snake_case)]
21-
fn create_relation(P1: G, P2: G, Q: G, H: G) -> Protocol<G> {
21+
fn create_relation(P1: G, P2: G, Q: G, H: G) -> ComposedRelation<G> {
2222
// First relation: discrete logarithm P1 = x1 * G
2323
let mut rel1 = LinearRelation::<G>::new();
2424
let x1 = rel1.allocate_scalar();
@@ -40,9 +40,9 @@ fn create_relation(P1: G, P2: G, Q: G, H: G) -> Protocol<G> {
4040
rel2.set_element(Q_var, Q);
4141

4242
// Compose into OR protocol
43-
let proto1 = Protocol::from(rel1);
44-
let proto2 = Protocol::from(rel2);
45-
Protocol::Or(vec![proto1, proto2])
43+
let proto1 = ComposedRelation::from(rel1);
44+
let proto2 = ComposedRelation::from(rel2);
45+
ComposedRelation::Or(vec![proto1, proto2])
4646
}
4747

4848
/// Prove knowledge of one of the witnesses (we know x2 for the DLEQ)
@@ -52,9 +52,9 @@ fn prove(P1: G, x2: Scalar, H: G) -> ProofResult<Vec<u8>> {
5252
let P2 = G::generator() * x2;
5353
let Q = H * x2;
5454

55-
let protocol = create_relation(P1, P2, Q, H);
55+
let instance = create_relation(P1, P2, Q, H);
5656
let witness = ProtocolWitness::Or(1, vec![ProtocolWitness::Simple(vec![x2])]);
57-
let nizk = Nizk::<_, Shake128DuplexSponge<G>>::new(b"or_proof_example", protocol);
57+
let nizk = Nizk::<_, Shake128DuplexSponge<G>>::new(b"or_proof_example", instance);
5858

5959
nizk.prove_batchable(&witness, &mut OsRng)
6060
}

src/composition.rs

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,22 @@ use crate::{
4040
/// # Type Parameters
4141
/// - `G`: A cryptographic group implementing [`Group`] and [`GroupEncoding`].
4242
#[derive(Clone)]
43-
pub enum Protocol<G: PrimeGroup> {
43+
pub enum ComposedRelation<G: PrimeGroup> {
4444
Simple(SchnorrProof<G>),
45-
And(Vec<Protocol<G>>),
46-
Or(Vec<Protocol<G>>),
45+
And(Vec<ComposedRelation<G>>),
46+
Or(Vec<ComposedRelation<G>>),
4747
}
4848

49-
impl<G> From<SchnorrProof<G>> for Protocol<G>
49+
impl<G> From<SchnorrProof<G>> for ComposedRelation<G>
5050
where
5151
G: PrimeGroup,
5252
{
5353
fn from(value: SchnorrProof<G>) -> Self {
54-
Protocol::Simple(value)
54+
ComposedRelation::Simple(value)
5555
}
5656
}
5757

58-
impl<G> From<LinearRelation<G>> for Protocol<G>
58+
impl<G> From<LinearRelation<G>> for ComposedRelation<G>
5959
where
6060
G: PrimeGroup,
6161
{
@@ -105,7 +105,7 @@ pub enum ProtocolWitness<G: PrimeGroup> {
105105
// Structure representing the Challenge type of Protocol as SigmaProtocol
106106
type ProtocolChallenge<G> = <SchnorrProof<G> as SigmaProtocol>::Challenge;
107107

108-
impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
108+
impl<G: PrimeGroup> SigmaProtocol for ComposedRelation<G> {
109109
type Commitment = ProtocolCommitment<G>;
110110
type ProverState = ProtocolProverState<G>;
111111
type Response = ProtocolResponse<G>;
@@ -118,15 +118,15 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
118118
rng: &mut (impl rand::Rng + rand::CryptoRng),
119119
) -> Result<(Self::Commitment, Self::ProverState), Error> {
120120
match (self, witness) {
121-
(Protocol::Simple(p), ProtocolWitness::Simple(w)) => {
121+
(ComposedRelation::Simple(p), ProtocolWitness::Simple(w)) => {
122122
p.prover_commit(w, rng).map(|(c, s)| {
123123
(
124124
ProtocolCommitment::Simple(c),
125125
ProtocolProverState::Simple(s),
126126
)
127127
})
128128
}
129-
(Protocol::And(ps), ProtocolWitness::And(ws)) => {
129+
(ComposedRelation::And(ps), ProtocolWitness::And(ws)) => {
130130
if ps.len() != ws.len() {
131131
return Err(Error::InvalidInstanceWitnessPair);
132132
}
@@ -144,7 +144,7 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
144144
ProtocolProverState::And(prover_states),
145145
))
146146
}
147-
(Protocol::Or(ps), ProtocolWitness::Or(w_index, w)) => {
147+
(ComposedRelation::Or(ps), ProtocolWitness::Or(w_index, w)) => {
148148
let mut commitments = Vec::new();
149149
let mut simulated_challenges = Vec::new();
150150
let mut simulated_responses = Vec::new();
@@ -178,10 +178,10 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
178178
challenge: &Self::Challenge,
179179
) -> Result<Self::Response, Error> {
180180
match (self, state) {
181-
(Protocol::Simple(p), ProtocolProverState::Simple(state)) => p
181+
(ComposedRelation::Simple(p), ProtocolProverState::Simple(state)) => p
182182
.prover_response(state, challenge)
183183
.map(ProtocolResponse::Simple),
184-
(Protocol::And(ps), ProtocolProverState::And(states)) => {
184+
(ComposedRelation::And(ps), ProtocolProverState::And(states)) => {
185185
if ps.len() != states.len() {
186186
return Err(Error::InvalidInstanceWitnessPair);
187187
}
@@ -194,7 +194,7 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
194194
Ok(ProtocolResponse::And(responses?))
195195
}
196196
(
197-
Protocol::Or(ps),
197+
ComposedRelation::Or(ps),
198198
ProtocolProverState::Or(
199199
w_index,
200200
real_state,
@@ -234,11 +234,11 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
234234
response: &Self::Response,
235235
) -> Result<(), Error> {
236236
match (self, commitment, response) {
237-
(Protocol::Simple(p), ProtocolCommitment::Simple(c), ProtocolResponse::Simple(r)) => {
237+
(ComposedRelation::Simple(p), ProtocolCommitment::Simple(c), ProtocolResponse::Simple(r)) => {
238238
p.verifier(c, challenge, r)
239239
}
240240
(
241-
Protocol::And(ps),
241+
ComposedRelation::And(ps),
242242
ProtocolCommitment::And(commitments),
243243
ProtocolResponse::And(responses),
244244
) => ps
@@ -247,7 +247,7 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
247247
.zip(responses)
248248
.try_for_each(|((p, c), r)| p.verifier(c, challenge, r)),
249249
(
250-
Protocol::Or(ps),
250+
ComposedRelation::Or(ps),
251251
ProtocolCommitment::Or(commitments),
252252
ProtocolResponse::Or(challenges, responses),
253253
) => {
@@ -267,9 +267,9 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
267267

268268
fn serialize_commitment(&self, commitment: &Self::Commitment) -> Vec<u8> {
269269
match (self, commitment) {
270-
(Protocol::Simple(p), ProtocolCommitment::Simple(c)) => p.serialize_commitment(c),
271-
(Protocol::And(ps), ProtocolCommitment::And(commitments))
272-
| (Protocol::Or(ps), ProtocolCommitment::Or(commitments)) => ps
270+
(ComposedRelation::Simple(p), ProtocolCommitment::Simple(c)) => p.serialize_commitment(c),
271+
(ComposedRelation::And(ps), ProtocolCommitment::And(commitments))
272+
| (ComposedRelation::Or(ps), ProtocolCommitment::Or(commitments)) => ps
273273
.iter()
274274
.zip(commitments)
275275
.flat_map(|(p, c)| p.serialize_commitment(c))
@@ -284,18 +284,18 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
284284

285285
fn instance_label(&self) -> impl AsRef<[u8]> {
286286
match self {
287-
Protocol::Simple(p) => {
287+
ComposedRelation::Simple(p) => {
288288
let label = p.instance_label();
289289
label.as_ref().to_vec()
290290
}
291-
Protocol::And(ps) => {
291+
ComposedRelation::And(ps) => {
292292
let mut bytes = Vec::new();
293293
for p in ps {
294294
bytes.extend(p.instance_label().as_ref());
295295
}
296296
bytes
297297
}
298-
Protocol::Or(ps) => {
298+
ComposedRelation::Or(ps) => {
299299
let mut bytes = Vec::new();
300300
for p in ps {
301301
bytes.extend(p.instance_label().as_ref());
@@ -309,19 +309,19 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
309309
let mut hasher = Sha3_256::new();
310310

311311
match self {
312-
Protocol::Simple(p) => {
312+
ComposedRelation::Simple(p) => {
313313
// take the digest of the simple protocol id
314314
hasher.update([0u8; 32]);
315315
hasher.update(p.protocol_identifier());
316316
}
317-
Protocol::And(protocols) => {
317+
ComposedRelation::And(protocols) => {
318318
let mut hasher = Sha3_256::new();
319319
hasher.update([1u8; 32]);
320320
for p in protocols {
321321
hasher.update(p.protocol_identifier());
322322
}
323323
}
324-
Protocol::Or(protocols) => {
324+
ComposedRelation::Or(protocols) => {
325325
let mut hasher = Sha3_256::new();
326326
hasher.update([2u8; 32]);
327327
for p in protocols {
@@ -335,15 +335,15 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
335335

336336
fn serialize_response(&self, response: &Self::Response) -> Vec<u8> {
337337
match (self, response) {
338-
(Protocol::Simple(p), ProtocolResponse::Simple(r)) => p.serialize_response(r),
339-
(Protocol::And(ps), ProtocolResponse::And(responses)) => {
338+
(ComposedRelation::Simple(p), ProtocolResponse::Simple(r)) => p.serialize_response(r),
339+
(ComposedRelation::And(ps), ProtocolResponse::And(responses)) => {
340340
let mut bytes = Vec::new();
341341
for (i, p) in ps.iter().enumerate() {
342342
bytes.extend(p.serialize_response(&responses[i]));
343343
}
344344
bytes
345345
}
346-
(Protocol::Or(ps), ProtocolResponse::Or(challenges, responses)) => {
346+
(ComposedRelation::Or(ps), ProtocolResponse::Or(challenges, responses)) => {
347347
let mut bytes = Vec::new();
348348
for (i, p) in ps.iter().enumerate() {
349349
bytes.extend(&serialize_scalars::<G>(&[challenges[i]]));
@@ -357,11 +357,11 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
357357

358358
fn deserialize_commitment(&self, data: &[u8]) -> Result<Self::Commitment, Error> {
359359
match self {
360-
Protocol::Simple(p) => {
360+
ComposedRelation::Simple(p) => {
361361
let c = p.deserialize_commitment(data)?;
362362
Ok(ProtocolCommitment::Simple(c))
363363
}
364-
Protocol::And(ps) | Protocol::Or(ps) => {
364+
ComposedRelation::And(ps) | ComposedRelation::Or(ps) => {
365365
let mut cursor = 0;
366366
let mut commitments = Vec::with_capacity(ps.len());
367367

@@ -373,8 +373,8 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
373373
}
374374

375375
Ok(match self {
376-
Protocol::And(_) => ProtocolCommitment::And(commitments),
377-
Protocol::Or(_) => ProtocolCommitment::Or(commitments),
376+
ComposedRelation::And(_) => ProtocolCommitment::And(commitments),
377+
ComposedRelation::Or(_) => ProtocolCommitment::Or(commitments),
378378
_ => unreachable!(),
379379
})
380380
}
@@ -388,11 +388,11 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
388388

389389
fn deserialize_response(&self, data: &[u8]) -> Result<Self::Response, Error> {
390390
match self {
391-
Protocol::Simple(p) => {
391+
ComposedRelation::Simple(p) => {
392392
let r = p.deserialize_response(data)?;
393393
Ok(ProtocolResponse::Simple(r))
394394
}
395-
Protocol::And(ps) => {
395+
ComposedRelation::And(ps) => {
396396
let mut cursor = 0;
397397
let mut responses = Vec::with_capacity(ps.len());
398398
for p in ps {
@@ -403,7 +403,7 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
403403
}
404404
Ok(ProtocolResponse::And(responses))
405405
}
406-
Protocol::Or(ps) => {
406+
ComposedRelation::Or(ps) => {
407407
let ch_bytes_len = <G::Scalar as PrimeField>::Repr::default().as_ref().len();
408408
let mut cursor = 0;
409409
let mut challenges = Vec::with_capacity(ps.len());
@@ -425,25 +425,25 @@ impl<G: PrimeGroup> SigmaProtocol for Protocol<G> {
425425
}
426426
}
427427

428-
impl<G: PrimeGroup> SigmaProtocolSimulator for Protocol<G> {
428+
impl<G: PrimeGroup> SigmaProtocolSimulator for ComposedRelation<G> {
429429
fn simulate_commitment(
430430
&self,
431431
challenge: &Self::Challenge,
432432
response: &Self::Response,
433433
) -> Result<Self::Commitment, Error> {
434434
match (self, response) {
435-
(Protocol::Simple(p), ProtocolResponse::Simple(r)) => Ok(ProtocolCommitment::Simple(
435+
(ComposedRelation::Simple(p), ProtocolResponse::Simple(r)) => Ok(ProtocolCommitment::Simple(
436436
p.simulate_commitment(challenge, r)?,
437437
)),
438-
(Protocol::And(ps), ProtocolResponse::And(rs)) => {
438+
(ComposedRelation::And(ps), ProtocolResponse::And(rs)) => {
439439
let commitments = ps
440440
.iter()
441441
.zip(rs)
442442
.map(|(p, r)| p.simulate_commitment(challenge, r))
443443
.collect::<Result<Vec<_>, _>>()?;
444444
Ok(ProtocolCommitment::And(commitments))
445445
}
446-
(Protocol::Or(ps), ProtocolResponse::Or(challenges, rs)) => {
446+
(ComposedRelation::Or(ps), ProtocolResponse::Or(challenges, rs)) => {
447447
let commitments = ps
448448
.iter()
449449
.zip(challenges)
@@ -458,11 +458,11 @@ impl<G: PrimeGroup> SigmaProtocolSimulator for Protocol<G> {
458458

459459
fn simulate_response<R: rand::Rng + rand::CryptoRng>(&self, rng: &mut R) -> Self::Response {
460460
match self {
461-
Protocol::Simple(p) => ProtocolResponse::Simple(p.simulate_response(rng)),
462-
Protocol::And(ps) => {
461+
ComposedRelation::Simple(p) => ProtocolResponse::Simple(p.simulate_response(rng)),
462+
ComposedRelation::And(ps) => {
463463
ProtocolResponse::And(ps.iter().map(|p| p.simulate_response(rng)).collect())
464464
}
465-
Protocol::Or(ps) => {
465+
ComposedRelation::Or(ps) => {
466466
let mut challenges = Vec::with_capacity(ps.len());
467467
let mut responses = Vec::with_capacity(ps.len());
468468
for _ in 0..ps.len() {
@@ -481,15 +481,15 @@ impl<G: PrimeGroup> SigmaProtocolSimulator for Protocol<G> {
481481
rng: &mut R,
482482
) -> Result<(Self::Commitment, Self::Challenge, Self::Response), Error> {
483483
match self {
484-
Protocol::Simple(p) => {
484+
ComposedRelation::Simple(p) => {
485485
let (c, ch, r) = p.simulate_transcript(rng)?;
486486
Ok((
487487
ProtocolCommitment::Simple(c),
488488
ch,
489489
ProtocolResponse::Simple(r),
490490
))
491491
}
492-
Protocol::And(ps) => {
492+
ComposedRelation::And(ps) => {
493493
let challenge = G::Scalar::random(&mut *rng);
494494
let mut responses = Vec::with_capacity(ps.len());
495495
for p in ps.iter() {
@@ -507,7 +507,7 @@ impl<G: PrimeGroup> SigmaProtocolSimulator for Protocol<G> {
507507
ProtocolResponse::And(responses),
508508
))
509509
}
510-
Protocol::Or(ps) => {
510+
ComposedRelation::Or(ps) => {
511511
let mut commitments = Vec::with_capacity(ps.len());
512512
let mut challenges = Vec::with_capacity(ps.len());
513513
let mut responses = Vec::with_capacity(ps.len());
@@ -529,7 +529,7 @@ impl<G: PrimeGroup> SigmaProtocolSimulator for Protocol<G> {
529529
}
530530
}
531531

532-
impl<G: PrimeGroup> Protocol<G> {
532+
impl<G: PrimeGroup> ComposedRelation<G> {
533533
/// Convert this Protocol into a non-interactive zero-knowledge proof
534534
/// using the Shake128DuplexSponge codec and a specified session identifier.
535535
///
@@ -544,7 +544,7 @@ impl<G: PrimeGroup> Protocol<G> {
544544
pub fn into_nizk(
545545
self,
546546
session_identifier: &[u8],
547-
) -> Nizk<Protocol<G>, Shake128DuplexSponge<G>> {
547+
) -> Nizk<ComposedRelation<G>, Shake128DuplexSponge<G>> {
548548
Nizk::new(session_identifier, self)
549549
}
550550
}

src/linear_relation/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,10 @@ impl<G: PrimeGroup> TryFrom<&LinearRelation<G>> for CanonicalLinearRelation<G> {
522522
}
523523

524524
// If the image is the identity, then the relation must be trivial, or else the proof will be unsound
525-
if !relation.image().is_ok_and(|img| img.iter().all(|&x| x != G::identity())) {
525+
if !relation
526+
.image()
527+
.is_ok_and(|img| img.iter().all(|&x| x != G::identity()))
528+
{
526529
return Err(Error::InvalidInstanceWitnessPair);
527530
}
528531

@@ -531,7 +534,12 @@ impl<G: PrimeGroup> TryFrom<&LinearRelation<G>> for CanonicalLinearRelation<G> {
531534
return Err(Error::InvalidInstanceWitnessPair);
532535
}
533536

534-
if relation.linear_map.linear_combinations.iter().any(|lc| lc.0.is_empty()) {
537+
if relation
538+
.linear_map
539+
.linear_combinations
540+
.iter()
541+
.any(|lc| lc.0.is_empty())
542+
{
535543
return Err(Error::InvalidInstanceWitnessPair);
536544
}
537545

0 commit comments

Comments
 (0)