From f41e54a3691c18f6bdf0855a69c30edb5ea95b89 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Mon, 12 Feb 2024 10:33:13 -0600 Subject: [PATCH] Use transcript composition --- benches/range_proof.rs | 28 ++++--- src/lib.rs | 2 + src/protocols/transcript_protocol.rs | 8 +- src/range_proof.rs | 112 +++++++++++++++++---------- src/transcripts.rs | 21 +++-- tests/ristretto.rs | 21 ++--- 6 files changed, 115 insertions(+), 77 deletions(-) diff --git a/benches/range_proof.rs b/benches/range_proof.rs index 49d1475..c31e5b6 100644 --- a/benches/range_proof.rs +++ b/benches/range_proof.rs @@ -11,6 +11,7 @@ extern crate criterion; use criterion::{Criterion, SamplingMode}; use curve25519_dalek::scalar::Scalar; +use merlin::Transcript; use rand_chacha::ChaCha12Rng; use rand_core::{CryptoRngCore, SeedableRng}; use tari_bulletproofs_plus::{ @@ -92,7 +93,12 @@ fn create_aggregated_rangeproof_helper(bit_length: usize, extension_degree: Exte // Benchmark this code b.iter(|| { // 4. Create the aggregated proof - let _proof = RistrettoRangeProof::prove_with_rng(transcript_label, &statement, &witness, &mut rng); + let _proof = RistrettoRangeProof::prove_with_rng( + &mut Transcript::new(transcript_label.as_bytes()), + &statement, + &witness, + &mut rng, + ); }) }); } @@ -131,7 +137,7 @@ fn verify_aggregated_rangeproof_helper(bit_length: usize, extension_degree: Exte // 0. Batch data let mut statements = vec![]; let mut proofs = vec![]; - let mut transcript_labels = vec![]; + let mut transcripts = vec![]; // 1. Generators let generators = RangeParameters::init(bit_length, aggregation_factor, pederson_gens.clone()).unwrap(); @@ -163,17 +169,18 @@ fn verify_aggregated_rangeproof_helper(bit_length: usize, extension_degree: Exte let statement = RangeStatement::init(generators, commitments.clone(), minimum_values.clone(), seed_nonce).unwrap(); statements.push(statement.clone()); - transcript_labels.push(transcript_label); + let mut transcript = Transcript::new(transcript_label.as_bytes()); + transcripts.push(transcript.clone()); // 4. Create the proof - let proof = RistrettoRangeProof::prove_with_rng(transcript_label, &statement, &witness, &mut rng).unwrap(); + let proof = RistrettoRangeProof::prove_with_rng(&mut transcript, &statement, &witness, &mut rng).unwrap(); proofs.push(proof); // Benchmark this code b.iter(|| { // 5. Verify the aggregated proof let _masks = - RangeProof::verify_batch(&transcript_labels, &statements, &proofs, VerifyAction::VerifyOnly) + RangeProof::verify_batch(&mut transcripts.clone(), &statements, &proofs, VerifyAction::VerifyOnly) .unwrap(); }); }); @@ -218,7 +225,7 @@ fn verify_batched_rangeproofs_helper(bit_length: usize, extension_degree: Extens // Batch data let mut statements = vec![]; let mut proofs = vec![]; - let mut transcript_labels = vec![]; + let mut transcripts = vec![]; for _ in 0..number_of_range_proofs { // Witness data @@ -241,11 +248,12 @@ fn verify_batched_rangeproofs_helper(bit_length: usize, extension_degree: Extens ) .unwrap(); statements.push(statement.clone()); - transcript_labels.push(transcript_label); + let mut transcript = Transcript::new(transcript_label.as_bytes()); + transcripts.push(transcript.clone()); // Proof let proof = - RistrettoRangeProof::prove_with_rng(transcript_label, &statement, &witness, &mut rng).unwrap(); + RistrettoRangeProof::prove_with_rng(&mut transcript, &statement, &witness, &mut rng).unwrap(); proofs.push(proof); } @@ -255,7 +263,7 @@ fn verify_batched_rangeproofs_helper(bit_length: usize, extension_degree: Extens match extract_masks { VerifyAction::VerifyOnly => { let _masks = RangeProof::verify_batch( - &transcript_labels, + &mut transcripts.clone(), &statements, &proofs, VerifyAction::VerifyOnly, @@ -264,7 +272,7 @@ fn verify_batched_rangeproofs_helper(bit_length: usize, extension_degree: Extens }, VerifyAction::RecoverOnly => { let _masks = RangeProof::verify_batch( - &transcript_labels, + &mut transcripts.clone(), &statements, &proofs, VerifyAction::RecoverOnly, diff --git a/src/lib.rs b/src/lib.rs index af3c25d..7919ede 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,5 +34,7 @@ mod utils; pub use generators::bulletproof_gens::BulletproofGens; /// Bulletproofs+ generators and base points needed for a batch of range proofs pub use generators::pedersen_gens::PedersenGens; +/// Merlin transcripts +pub use merlin::Transcript; pub mod ristretto; diff --git a/src/protocols/transcript_protocol.rs b/src/protocols/transcript_protocol.rs index 4aeae68..41f8a17 100644 --- a/src/protocols/transcript_protocol.rs +++ b/src/protocols/transcript_protocol.rs @@ -15,8 +15,8 @@ use crate::{errors::ProofError, traits::FixedBytesRepr}; /// Defines a `TranscriptProtocol` trait for using a Merlin transcript. pub trait TranscriptProtocol { - /// Append a domain separator for the range proof with the given `label` and `message`. - fn domain_separator(&mut self, label: &'static [u8], message: &[u8]); + /// Append a domain separator for the range proof. + fn append_domain_separator(&mut self); /// Append a `point` with the given `label`. fn append_point(&mut self, label: &'static [u8], point: &P); @@ -37,8 +37,8 @@ pub trait TranscriptProtocol { } impl TranscriptProtocol for Transcript { - fn domain_separator(&mut self, label: &'static [u8], message: &[u8]) { - self.append_message(label, message); + fn append_domain_separator(&mut self) { + self.append_message(b"dom-sep", b"Bulletproofs+ Range Proof"); } fn append_point(&mut self, label: &'static [u8], point: &P) { diff --git a/src/range_proof.rs b/src/range_proof.rs index 6899592..41be9f2 100644 --- a/src/range_proof.rs +++ b/src/range_proof.rs @@ -116,7 +116,7 @@ const ENCODED_EXTENSION_SIZE: usize = 1; /// let mut statements_private = vec![]; /// let mut statements_public = vec![]; /// let mut proofs = vec![]; -/// let mut transcript_labels = vec![]; +/// let mut transcripts = vec![]; /// /// for aggregation_size in proof_batch { /// // 1. Generators @@ -176,16 +176,17 @@ const ENCODED_EXTENSION_SIZE: usize = 1; /// let public_statement = /// RangeStatement::init(generators.clone(), commitments, minimum_values.clone(), None).unwrap(); /// statements_public.push(public_statement.clone()); -/// transcript_labels.push(transcript_label); +/// let mut transcript = Transcript::new(transcript_label.as_bytes()); +/// transcripts.push(transcript.clone()); /// /// // 4. Create the proofs -/// let proof = RistrettoRangeProof::prove(transcript_label, &private_statement.clone(), &witness); +/// let proof = RistrettoRangeProof::prove(&mut transcript, &private_statement.clone(), &witness); /// proofs.push(proof.unwrap()); /// } /// /// // 5. Verify the entire batch as the commitment owner, i.e. the prover self /// let recovered_private_masks = RangeProof::verify_batch( -/// &transcript_labels, +/// &mut transcripts.clone(), /// &statements_private, /// &proofs, /// VerifyAction::RecoverAndVerify, @@ -195,7 +196,7 @@ const ENCODED_EXTENSION_SIZE: usize = 1; /// /// // 6. Verify the entire batch as public entity /// let recovered_public_masks = -/// RangeProof::verify_batch(&transcript_labels, &statements_public, &proofs, VerifyAction::VerifyOnly).unwrap(); +/// RangeProof::verify_batch(&mut transcripts, &statements_public, &proofs, VerifyAction::VerifyOnly).unwrap(); /// assert_eq!(public_masks, recovered_public_masks); /// /// # } @@ -218,17 +219,17 @@ where /// The prover must ensure that the commitments and witness opening data are consistent #[cfg(feature = "rand")] pub fn prove( - transcript_label: &'static str, + transcript: &mut Transcript, statement: &RangeStatement

, witness: &RangeWitness, ) -> Result { - Self::prove_with_rng(transcript_label, statement, witness, &mut OsRng) + Self::prove_with_rng(transcript, statement, witness, &mut OsRng) } /// Create a single or aggregated range proof for a single party that knows all the secrets /// The prover must ensure that the commitments and witness opening data are consistent pub fn prove_with_rng( - transcript_label: &'static str, + transcript: &mut Transcript, statement: &RangeStatement

, witness: &RangeWitness, rng: &mut R, @@ -282,8 +283,8 @@ where } // Start a new transcript and generate the transcript RNG - let mut transcript = RangeProofTranscript::::new( - transcript_label, + let mut range_proof_transcript = RangeProofTranscript::::new( + transcript, &statement.generators.h_base().compress(), statement.generators.g_bases_compressed(), bit_length, @@ -326,7 +327,7 @@ where nonce(&seed_nonce, "alpha", None, Some(k))? } else { // Zero is allowed by the protocol, but excluded by the implementation to be unambiguous - Scalar::random_not_zero(transcript.as_mut_rng()) + Scalar::random_not_zero(range_proof_transcript.as_mut_rng()) }); } let a = statement.generators.precomp().vartime_mixed_multiscalar_mul( @@ -336,7 +337,7 @@ where ); // Update transcript, get challenges, and update RNG - let (y, z) = transcript.challenges_y_z(&a.compress())?; + let (y, z) = range_proof_transcript.challenges_y_z(&a.compress())?; let z_square = z * z; @@ -422,7 +423,7 @@ where // Zero is allowed by the protocol, but excluded by the implementation to be unambiguous Zeroizing::new( (0..extension_degree) - .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) + .map(|_| Scalar::random_not_zero(range_proof_transcript.as_mut_rng())) .collect(), ) }; @@ -436,7 +437,7 @@ where // Zero is allowed by the protocol, but excluded by the implementation to be unambiguous Zeroizing::new( (0..extension_degree) - .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) + .map(|_| Scalar::random_not_zero(range_proof_transcript.as_mut_rng())) .collect(), ) }; @@ -469,7 +470,7 @@ where )); // Update transcript, get challenge, and update RNG - let e = transcript.challenge_round_e( + let e = range_proof_transcript.challenge_round_e( &li.last() .ok_or(ProofError::InvalidLength("Bad inner product vector length".to_string()))? .compress(), @@ -513,8 +514,8 @@ where // Random masks // Zero is allowed by the protocol, but excluded by the implementation to be unambiguous - let r = Zeroizing::new(Scalar::random_not_zero(transcript.as_mut_rng())); - let s = Zeroizing::new(Scalar::random_not_zero(transcript.as_mut_rng())); + let r = Zeroizing::new(Scalar::random_not_zero(range_proof_transcript.as_mut_rng())); + let s = Zeroizing::new(Scalar::random_not_zero(range_proof_transcript.as_mut_rng())); let d = if let Some(seed_nonce) = statement.seed_nonce { Zeroizing::new( (0..extension_degree) @@ -525,7 +526,7 @@ where // Zero is allowed by the protocol, but excluded by the implementation to be unambiguous Zeroizing::new( (0..extension_degree) - .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) + .map(|_| Scalar::random_not_zero(range_proof_transcript.as_mut_rng())) .collect(), ) }; @@ -539,7 +540,7 @@ where // Zero is allowed by the protocol, but excluded by the implementation to be unambiguous Zeroizing::new( (0..extension_degree) - .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) + .map(|_| Scalar::random_not_zero(range_proof_transcript.as_mut_rng())) .collect(), ) }; @@ -555,7 +556,7 @@ where } // Update transcript, get challenge, and update RNG - let e = transcript.challenge_final_e(&a1.compress(), &b.compress())?; + let e = range_proof_transcript.challenge_final_e(&a1.compress(), &b.compress())?; let e_square = e * e; let r1 = *r + a_li[0] * e; @@ -681,13 +682,13 @@ where /// Wrapper function for batch verification in different modes: mask recovery, verification, or both pub fn verify_batch( - transcript_labels: &[&'static str], + transcripts: &mut [Transcript], statements: &[RangeStatement

], proofs: &[RangeProof

], action: VerifyAction, ) -> Result>, ProofError> { // By definition, an empty batch fails - if statements.is_empty() || proofs.is_empty() || transcript_labels.is_empty() { + if statements.is_empty() || proofs.is_empty() || transcripts.is_empty() { return Err(ProofError::InvalidArgument( "Range statements or proofs length empty".to_string(), )); @@ -698,9 +699,9 @@ where "Range statements and proofs length mismatch".to_string(), )); } - if transcript_labels.len() != statements.len() { + if transcripts.len() != statements.len() { return Err(ProofError::InvalidArgument( - "Range statements and transcript labels length mismatch".to_string(), + "Range statements and transcripts length mismatch".to_string(), )); } @@ -714,7 +715,7 @@ where // If the batch fails, propagate the error; otherwise, store the masks and keep going if let Some((batch_statements, batch_proofs)) = chunks.next() { - let mut result = RangeProof::verify(transcript_labels, batch_statements, batch_proofs, action)?; + let mut result = RangeProof::verify(transcripts, batch_statements, batch_proofs, action)?; masks.append(&mut result); } @@ -725,7 +726,7 @@ where // Verify a batch of single and/or aggregated range proofs as a public entity, or recover the masks for single // range proofs by a party that can supply the optional seed nonces fn verify( - transcript_labels: &[&'static str], + transcripts: &mut [Transcript], statements: &[RangeStatement

], range_proofs: &[RangeProof

], extract_masks: VerifyAction, @@ -784,12 +785,12 @@ where // Generate challenges from all proofs in the batch, using the final transcript RNG of each to obtain a new // weight let mut batch_challenges = Vec::with_capacity(range_proofs.len()); - for (proof, statement, transcript_label) in izip!(range_proofs, statements, transcript_labels) { + for (proof, statement, transcript) in izip!(range_proofs, statements, transcripts) { let mut null_rng = NullRng; // Start the transcript, using `NullRng` since we don't need or want actual randomness there let mut transcript = RangeProofTranscript::new( - transcript_label, + transcript, &h_base_compressed, g_bases_compressed, bit_length, @@ -1430,8 +1431,13 @@ mod tests { .unwrap(), ); proofs.push( - RangeProof::prove_with_rng("test", statements.last().unwrap(), witnesses.last().unwrap(), &mut rng) - .unwrap(), + RangeProof::prove_with_rng( + &mut Transcript::new(b"Test"), + statements.last().unwrap(), + witnesses.last().unwrap(), + &mut rng, + ) + .unwrap(), ); } @@ -1603,7 +1609,8 @@ mod tests { None, ) .unwrap(); - let mut proof = RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).unwrap(); + let mut proof = + RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).unwrap(); // Mutate proof elements let mut bytes = [0u8; 32]; @@ -1660,7 +1667,7 @@ mod tests { None, ) .unwrap(); - assert!(RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).is_err()); + assert!(RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).is_err()); // Witness and statement extension degrees do not match let witness = RangeWitness::init(vec![CommitmentOpening::new(1u64, vec![Scalar::ONE, Scalar::ONE])]).unwrap(); @@ -1674,7 +1681,7 @@ mod tests { None, ) .unwrap(); - assert!(RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).is_err()); + assert!(RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).is_err()); // Witness value overflows bit length let witness = RangeWitness::init(vec![CommitmentOpening::new(16u64, vec![Scalar::ONE])]).unwrap(); @@ -1688,7 +1695,7 @@ mod tests { None, ) .unwrap(); - assert!(RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).is_err()); + assert!(RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).is_err()); // Witness opening is invalid for statement commitment let witness = RangeWitness::init(vec![CommitmentOpening::new(1u64, vec![Scalar::ONE])]).unwrap(); @@ -1702,7 +1709,7 @@ mod tests { None, ) .unwrap(); - assert!(RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).is_err()); + assert!(RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).is_err()); // Witness value does not meet minimum value promise let witness = RangeWitness::init(vec![CommitmentOpening::new(1u64, vec![Scalar::ONE])]).unwrap(); @@ -1716,7 +1723,7 @@ mod tests { None, ) .unwrap(); - assert!(RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).is_err()); + assert!(RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).is_err()); } #[test] @@ -1738,16 +1745,23 @@ mod tests { None, ) .unwrap(); - let mut proof = RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).unwrap(); + let mut proof = + RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).unwrap(); // Empty statement and proof vectors - assert!(RangeProof::verify_batch(&[], &[], &[proof.clone()], VerifyAction::VerifyOnly).is_err()); - assert!(RangeProof::verify_batch(&["test"], &[statement.clone()], &[], VerifyAction::VerifyOnly,).is_err()); + assert!(RangeProof::verify_batch(&mut [], &[], &[proof.clone()], VerifyAction::VerifyOnly).is_err()); + assert!(RangeProof::verify_batch( + &mut [Transcript::new(b"Test")], + &[statement.clone()], + &[], + VerifyAction::VerifyOnly, + ) + .is_err()); // Proof vector mismatches proof.li.pop(); assert!(RangeProof::verify_batch( - &["test"], + &mut [Transcript::new(b"Test")], &[statement.clone()], &[proof.clone()], VerifyAction::VerifyOnly, @@ -1755,7 +1769,13 @@ mod tests { .is_err()); proof.ri.pop(); - assert!(RangeProof::verify_batch(&["test"], &[statement], &[proof], VerifyAction::VerifyOnly,).is_err()); + assert!(RangeProof::verify_batch( + &mut [Transcript::new(b"Test")], + &[statement], + &[proof], + VerifyAction::VerifyOnly, + ) + .is_err()); } #[test] @@ -1782,10 +1802,16 @@ mod tests { None, ) .unwrap(); - let proof = RangeProof::prove_with_rng("test", &statement, &witness, &mut rng).unwrap(); + let proof = RangeProof::prove_with_rng(&mut Transcript::new(b"Test"), &statement, &witness, &mut rng).unwrap(); // The proof should verify - RangeProof::verify_batch(&["test"], &[statement], &[proof], VerifyAction::VerifyOnly).unwrap(); + RangeProof::verify_batch( + &mut [Transcript::new(b"Test")], + &[statement], + &[proof], + VerifyAction::VerifyOnly, + ) + .unwrap(); } #[test] diff --git a/src/transcripts.rs b/src/transcripts.rs index bdecf7b..12e945f 100644 --- a/src/transcripts.rs +++ b/src/transcripts.rs @@ -17,9 +17,9 @@ use crate::{ traits::{Compressable, FixedBytesRepr, Precomputable}, }; -/// A wrapper around a Merlin transcript. +/// A wrapper that handles a Merlin transcript. /// -/// This does the usual Fiat-Shamir operations: initialize a transcript, add proof messages, and get challenges. +/// This does the usual Fiat-Shamir operations: apply domain separation, add proof messages, and get challenges. /// /// But it does more! /// Following the design from [Merlin](https://merlin.cool/transcript/rng.html), it provides a random number generator. @@ -39,7 +39,7 @@ where P::Compressed: FixedBytesRepr + IsIdentity, R: CryptoRngCore, { - transcript: Transcript, + transcript: &'a mut Transcript, bytes: Option>>, transcript_rng: TranscriptRng, external_rng: &'a mut R, @@ -57,7 +57,7 @@ where /// The prover should include its `witness` here; the verifier should pass `None`. #[allow(clippy::too_many_arguments)] pub(crate) fn new( - label: &'static str, + transcript: &'a mut Transcript, h_base_compressed: &P::Compressed, g_base_compressed: &[P::Compressed], bit_length: usize, @@ -68,8 +68,7 @@ where external_rng: &'a mut R, ) -> Result { // Initialize the transcript with parameters and statement - let mut transcript = Transcript::new(label.as_bytes()); - transcript.domain_separator(b"Bulletproofs+", b"Range Proof"); + transcript.append_domain_separator(); transcript.validate_and_append_point(b"H", h_base_compressed)?; for item in g_base_compressed { transcript.validate_and_append_point(b"G", item)?; @@ -109,7 +108,7 @@ where }; // Set up the RNG - let rng = Self::build_rng(&transcript, bytes.as_ref(), external_rng); + let rng = Self::build_rng(transcript, bytes.as_ref(), external_rng); Ok(Self { transcript, @@ -126,7 +125,7 @@ where self.transcript.validate_and_append_point(b"A", a)?; // Update the RNG - self.transcript_rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), self.external_rng); + self.transcript_rng = Self::build_rng(self.transcript, self.bytes.as_ref(), self.external_rng); // Return the challenges Ok(( @@ -142,7 +141,7 @@ where self.transcript.validate_and_append_point(b"R", r)?; // Update the RNG - self.transcript_rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), self.external_rng); + self.transcript_rng = Self::build_rng(self.transcript, self.bytes.as_ref(), self.external_rng); // Return the challenge self.transcript.challenge_scalar(b"e") @@ -155,7 +154,7 @@ where self.transcript.validate_and_append_point(b"B", b)?; // Update the RNG - self.transcript_rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), self.external_rng); + self.transcript_rng = Self::build_rng(self.transcript, self.bytes.as_ref(), self.external_rng); // Return the challenge self.transcript.challenge_scalar(b"e") @@ -172,7 +171,7 @@ where } // Update the RNG - self.transcript_rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), self.external_rng); + self.transcript_rng = Self::build_rng(self.transcript, self.bytes.as_ref(), self.external_rng); // Return the transcript RNG self.transcript_rng diff --git a/tests/ristretto.rs b/tests/ristretto.rs index cf2647f..74bdd8d 100644 --- a/tests/ristretto.rs +++ b/tests/ristretto.rs @@ -4,6 +4,7 @@ #![allow(clippy::too_many_lines)] use curve25519_dalek::scalar::Scalar; +use merlin::Transcript; use rand_chacha::ChaCha12Rng; use rand_core::{CryptoRngCore, SeedableRng}; use tari_bulletproofs_plus::{ @@ -163,7 +164,7 @@ fn prove_and_verify( let mut statements_private = vec![]; let mut statements_public = vec![]; let mut proofs = vec![]; - let mut transcript_labels = vec![]; + let mut transcripts = vec![]; #[allow(clippy::cast_possible_truncation)] let value_max = (1u128 << (bit_length - 1)) as u64; @@ -220,9 +221,11 @@ fn prove_and_verify( .unwrap(); let public_statement = RangeStatement::init(generators.clone(), commitments, minimum_values.clone(), None).unwrap(); + let transcript = Transcript::new(transcript_label.as_bytes()); // 4. Create the proofs - let proof = RangeProof::prove_with_rng(transcript_label, &private_statement.clone(), &witness, &mut rng); + let proof = + RangeProof::prove_with_rng(&mut transcript.clone(), &private_statement.clone(), &witness, &mut rng); match promise_strategy { ProofOfMinimumValueStrategy::LargerThanValue => match proof { Ok(_) => { @@ -239,7 +242,7 @@ fn prove_and_verify( statements_private.push(private_statement); statements_public.push(public_statement); proofs.push(proof.unwrap()); - transcript_labels.push(transcript_label); + transcripts.push(transcript); }, }; } @@ -248,7 +251,7 @@ fn prove_and_verify( // 5. Verify the entire batch as the commitment owner, i.e. the prover self // --- Only recover the masks let recovered_private_masks = RangeProof::verify_batch( - &transcript_labels, + &mut transcripts.clone(), &statements_private.clone(), &proofs.clone(), VerifyAction::RecoverOnly, @@ -257,7 +260,7 @@ fn prove_and_verify( assert_eq!(private_masks, recovered_private_masks); // --- Recover the masks and verify the proofs let recovered_private_masks = RangeProof::verify_batch( - &transcript_labels, + &mut transcripts.clone(), &statements_private.clone(), &proofs.clone(), VerifyAction::RecoverAndVerify, @@ -266,7 +269,7 @@ fn prove_and_verify( assert_eq!(private_masks, recovered_private_masks); // --- Verify the proofs but do not recover the masks let recovered_private_masks = RangeProof::verify_batch( - &transcript_labels, + &mut transcripts.clone(), &statements_private.clone(), &proofs.clone(), VerifyAction::VerifyOnly, @@ -276,7 +279,7 @@ fn prove_and_verify( // 6. Verify the entire batch as public entity let recovered_public_masks = RangeProof::verify_batch( - &transcript_labels, + &mut transcripts.clone(), &statements_public, &proofs, VerifyAction::VerifyOnly, @@ -304,7 +307,7 @@ fn prove_and_verify( }); } let recovered_private_masks_changed = RistrettoRangeProof::verify_batch( - &transcript_labels, + &mut transcripts.clone(), &statements_private_changed, &proofs.clone(), VerifyAction::RecoverAndVerify, @@ -335,7 +338,7 @@ fn prove_and_verify( }); } match RangeProof::verify_batch( - &transcript_labels, + &mut transcripts, &statements_public_changed, &proofs, VerifyAction::VerifyOnly,