From dc8c55fc4b3fd785bcb0c36c49b5456ad6f009f0 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:29:35 -0600 Subject: [PATCH] Move `TranscriptRng` into `RangeProofTranscript` --- src/range_proof.rs | 31 +++++++++++++++---------------- src/transcripts.rs | 36 +++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/range_proof.rs b/src/range_proof.rs index 436d038..429cf38 100644 --- a/src/range_proof.rs +++ b/src/range_proof.rs @@ -278,7 +278,7 @@ where } // Start a new transcript and generate the transcript RNG - let (mut transcript, mut transcript_rng) = RangeProofTranscript::

::new( + let mut transcript = RangeProofTranscript::

::new( transcript_label, &statement.generators.h_base().compress(), statement.generators.g_bases_compressed(), @@ -322,7 +322,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(&mut transcript_rng) + Scalar::random_not_zero(transcript.as_mut_rng()) }); } let a = statement.generators.precomp().vartime_mixed_multiscalar_mul( @@ -332,7 +332,7 @@ where ); // Update transcript, get challenges, and update RNG - let (y, z) = transcript.challenges_y_z(&mut transcript_rng, rng, &a.compress())?; + let (y, z) = transcript.challenges_y_z(rng, &a.compress())?; let z_square = z * z; @@ -418,7 +418,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(&mut transcript_rng)) + .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) .collect(), ) }; @@ -432,7 +432,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(&mut transcript_rng)) + .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) .collect(), ) }; @@ -466,7 +466,6 @@ where // Update transcript, get challenge, and update RNG let e = transcript.challenge_round_e( - &mut transcript_rng, rng, &li.last() .ok_or(ProofError::InvalidLength("Bad inner product vector length".to_string()))? @@ -511,8 +510,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(&mut transcript_rng)); - let s = Zeroizing::new(Scalar::random_not_zero(&mut transcript_rng)); + 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 d = if let Some(seed_nonce) = statement.seed_nonce { Zeroizing::new( (0..extension_degree) @@ -523,7 +522,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(&mut transcript_rng)) + .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) .collect(), ) }; @@ -537,7 +536,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(&mut transcript_rng)) + .map(|_| Scalar::random_not_zero(transcript.as_mut_rng())) .collect(), ) }; @@ -553,7 +552,7 @@ where } // Update transcript, get challenge, and update RNG - let e = transcript.challenge_final_e(&mut transcript_rng, rng, &a1.compress(), &b.compress())?; + let e = transcript.challenge_final_e(rng, &a1.compress(), &b.compress())?; let e_square = e * e; let r1 = *r + a_li[0] * e; @@ -825,7 +824,7 @@ where } // Start the transcript - let (mut transcript, mut transcript_rng) = RangeProofTranscript::new( + let mut transcript = RangeProofTranscript::new( transcript_label, &h_base_compressed, g_bases_compressed, @@ -838,17 +837,17 @@ where )?; // Reconstruct challenges - let (y, z) = transcript.challenges_y_z(&mut transcript_rng, rng, &proof.a)?; + let (y, z) = transcript.challenges_y_z(rng, &proof.a)?; let challenges = proof .li .iter() .zip(proof.ri.iter()) - .map(|(l, r)| transcript.challenge_round_e(&mut transcript_rng, rng, l, r)) + .map(|(l, r)| transcript.challenge_round_e(rng, l, r)) .collect::, ProofError>>()?; - let e = transcript.challenge_final_e(&mut transcript_rng, rng, &proof.a1, &proof.b)?; + let e = transcript.challenge_final_e(rng, &proof.a1, &proof.b)?; // Batch weight (may not be equal to a zero valued scalar) - this may not be zero ever - let weight = Scalar::random_not_zero(&mut transcript_rng); + let weight = Scalar::random_not_zero(transcript.as_mut_rng()); // Compute challenge inverses in a batch let mut challenges_inv = challenges.clone(); diff --git a/src/transcripts.rs b/src/transcripts.rs index ffb2026..0cee8d6 100644 --- a/src/transcripts.rs +++ b/src/transcripts.rs @@ -43,6 +43,7 @@ where { transcript: Transcript, bytes: Option>>, + rng: TranscriptRng, _phantom: PhantomData

, } @@ -65,7 +66,7 @@ where statement: &RangeStatement

, witness: Option<&RangeWitness>, external_rng: &mut R, - ) -> Result<(Self, TranscriptRng), ProofError> { + ) -> Result { // Initialize the transcript with parameters and statement let mut transcript = Transcript::new(label.as_bytes()); transcript.domain_separator(b"Bulletproofs+", b"Range Proof"); @@ -108,22 +109,19 @@ where }; // Set up the RNG - let transcript_rng = Self::build_rng(&transcript, bytes.as_ref(), external_rng); - - Ok(( - Self { - transcript, - bytes, - _phantom: PhantomData, - }, - transcript_rng, - )) + let rng = Self::build_rng(&transcript, bytes.as_ref(), external_rng); + + Ok(Self { + transcript, + bytes, + rng, + _phantom: PhantomData, + }) } // Construct the `y` and `z` challenges and update the RNG pub(crate) fn challenges_y_z( &mut self, - transcript_rng: &mut TranscriptRng, external_rng: &mut R, a: &P::Compressed, ) -> Result<(Scalar, Scalar), ProofError> { @@ -131,7 +129,7 @@ where self.transcript.validate_and_append_point(b"A", a)?; // Update the RNG - *transcript_rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), external_rng); + self.rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), external_rng); // Return the challenges Ok(( @@ -143,7 +141,6 @@ where /// Construct an inner-product round `e` challenge and update the RNG pub(crate) fn challenge_round_e( &mut self, - transcript_rng: &mut TranscriptRng, external_rng: &mut R, l: &P::Compressed, r: &P::Compressed, @@ -153,7 +150,7 @@ where self.transcript.validate_and_append_point(b"R", r)?; // Update the RNG - *transcript_rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), external_rng); + self.rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), external_rng); // Return the challenge self.transcript.challenge_scalar(b"e") @@ -162,7 +159,6 @@ where /// Construct the final `e` challenge and update the RNG pub(crate) fn challenge_final_e( &mut self, - transcript_rng: &mut TranscriptRng, external_rng: &mut R, a1: &P::Compressed, b: &P::Compressed, @@ -172,7 +168,7 @@ where self.transcript.validate_and_append_point(b"B", b)?; // Update the RNG - *transcript_rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), external_rng); + self.rng = Self::build_rng(&self.transcript, self.bytes.as_ref(), external_rng); // Return the challenge self.transcript.challenge_scalar(b"e") @@ -196,4 +192,10 @@ where transcript.build_rng().finalize(external_rng) } } + + /// Get a mutable reference to the transcript RNG. + /// This is suitable for passing into functions that use it to generate random data. + pub(crate) fn as_mut_rng(&mut self) -> &mut TranscriptRng { + &mut self.rng + } }