From be35e83e35598bc9ac9b6b3520f2a28f730fd7ec Mon Sep 17 00:00:00 2001 From: Cathie Yun <3314874+cathieyun@users.noreply.github.com> Date: Tue, 27 Dec 2022 13:07:50 -0800 Subject: [PATCH 1/4] Add commitment to public b vector, to remediate frozen heart vulnerability --- src/linear_proof.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/linear_proof.rs b/src/linear_proof.rs index 84fec0b1..8a9f3186 100644 --- a/src/linear_proof.rs +++ b/src/linear_proof.rs @@ -74,6 +74,9 @@ impl LinearProof { transcript.innerproduct_domain_sep(n as u64); transcript.append_point(b"C", &C); + for i in 0..n { + transcript.append_scalar(b"b_i", &b[i]); + } let lg_n = n.next_power_of_two().trailing_zeros() as usize; let mut L_vec = Vec::with_capacity(lg_n); @@ -165,7 +168,12 @@ impl LinearProof { b_vec: Vec, ) -> Result<(), ProofError> { transcript.innerproduct_domain_sep(n as u64); + assert_eq!(b_vec.len(), n); + transcript.append_point(b"C", &C); + for i in 0..n { + transcript.append_scalar(b"b_i", &b_vec[i]); + } let (x_vec, x_inv_vec, b_0) = self.verification_scalars(n, transcript, b_vec)?; transcript.append_point(b"S", &self.S); From 55e2569b6fe74a73c1cba4a8ca154ddc53ef5c19 Mon Sep 17 00:00:00 2001 From: Cathie Yun <3314874+cathieyun@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:00:08 -0700 Subject: [PATCH 2/4] Cleanup - add generators to transcript, return ProofError, derive n from b_vec --- src/errors.rs | 6 ++++ src/linear_proof.rs | 72 ++++++++++++++++++++++++++++----------------- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 776915d1..b5843952 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -37,6 +37,12 @@ pub enum ProofError { error("Invalid generators size, too few generators for proof") )] InvalidGeneratorsLength, + /// This error occurs when inputs are the incorrect length for the proof. + #[cfg_attr( + feature = "std", + error("Invalid input size, incorrect input length for proof") + )] + InvalidInputLength, /// This error results from an internal error during proving. /// /// The single-party prover is implemented by performing diff --git a/src/linear_proof.rs b/src/linear_proof.rs index 8a9f3186..0f604f2d 100644 --- a/src/linear_proof.rs +++ b/src/linear_proof.rs @@ -54,8 +54,31 @@ impl LinearProof { F: &RistrettoPoint, // Pedersen generator B, for committing to the blinding value B: &RistrettoPoint, - ) -> LinearProof { - let mut n = a_vec.len(); + ) -> Result { + let mut n = b_vec.len(); + // All of the input vectors must have the same length. + if G_vec.len() != n { + return Err(ProofError::InvalidGeneratorsLength); + } + if a_vec.len() != n { + return Err(ProofError::InvalidInputLength); + } + // All of the input vectors must have a length that is a power of two. + if !n.is_power_of_two() { + return Err(ProofError::InvalidInputLength); + } + + // Append all public data to the transcript + transcript.innerproduct_domain_sep(n as u64); + transcript.append_point(b"C", &C); + for b_i in &b_vec { + transcript.append_scalar(b"b_i", b_i); + } + for G_i in &G_vec { + transcript.append_point(b"G_i", &G_i.compress()); + } + transcript.append_point(b"F", &F.compress()); + transcript.append_point(b"B", &B.compress()); // Create slices G, H, a, b backed by their respective // vectors. This lets us reslice as we compress the lengths @@ -64,20 +87,6 @@ impl LinearProof { let mut a = &mut a_vec[..]; let mut b = &mut b_vec[..]; - // All of the input vectors must have the same length. - assert_eq!(G.len(), n); - assert_eq!(a.len(), n); - assert_eq!(b.len(), n); - - // All of the input vectors must have a length that is a power of two. - assert!(n.is_power_of_two()); - - transcript.innerproduct_domain_sep(n as u64); - transcript.append_point(b"C", &C); - for i in 0..n { - transcript.append_scalar(b"b_i", &b[i]); - } - let lg_n = n.next_power_of_two().trailing_zeros() as usize; let mut L_vec = Vec::with_capacity(lg_n); let mut R_vec = Vec::with_capacity(lg_n); @@ -143,18 +152,17 @@ impl LinearProof { let a_star = s_star + x_star * a[0]; let r_star = t_star + x_star * r; - LinearProof { + Ok(LinearProof { L_vec, R_vec, S, a: a_star, r: r_star, - } + }) } pub fn verify( &self, - n: usize, transcript: &mut Transcript, // Commitment to witness C: &CompressedRistretto, @@ -167,15 +175,24 @@ impl LinearProof { // Public scalar vector b b_vec: Vec, ) -> Result<(), ProofError> { - transcript.innerproduct_domain_sep(n as u64); - assert_eq!(b_vec.len(), n); + let n = b_vec.len(); + if G.len() != n { + return Err(ProofError::InvalidGeneratorsLength); + } + // Append all public data to the transcript + transcript.innerproduct_domain_sep(n as u64); transcript.append_point(b"C", &C); - for i in 0..n { - transcript.append_scalar(b"b_i", &b_vec[i]); + for b_i in &b_vec { + transcript.append_scalar(b"b_i", b_i); } - let (x_vec, x_inv_vec, b_0) = self.verification_scalars(n, transcript, b_vec)?; + for G_i in G { + transcript.append_point(b"G_i", &G_i.compress()); + } + transcript.append_point(b"F", &F.compress()); + transcript.append_point(b"B", &B.compress()); + let (x_vec, x_inv_vec, b_0) = self.verification_scalars(n, transcript, b_vec)?; transcript.append_point(b"S", &self.S); let x_star = transcript.challenge_scalar(b"x_star"); @@ -430,11 +447,12 @@ mod tests { G.clone(), &F, &B, - ); + ) + .unwrap(); let mut verifier_transcript = Transcript::new(b"linearprooftest"); assert!(proof - .verify(n, &mut verifier_transcript, &C, &G, &F, &B, b.clone()) + .verify(&mut verifier_transcript, &C, &G, &F, &B, b.clone()) .is_ok()); // Test serialization and deserialization @@ -444,7 +462,7 @@ mod tests { let deserialized_proof = LinearProof::from_bytes(&serialized_proof).unwrap(); let mut serde_verifier_transcript = Transcript::new(b"linearprooftest"); assert!(deserialized_proof - .verify(n, &mut serde_verifier_transcript, &C, &G, &F, &B, b) + .verify(&mut serde_verifier_transcript, &C, &G, &F, &B, b) .is_ok()); } From 664033fe42842b318f520188e7b706e3dcbdc619 Mon Sep 17 00:00:00 2001 From: Cathie Yun <3314874+cathieyun@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:09:03 -0700 Subject: [PATCH 3/4] Update benchmarks for new linear_proof API --- benches/linear_proof.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/benches/linear_proof.rs b/benches/linear_proof.rs index cd75a590..b262a920 100644 --- a/benches/linear_proof.rs +++ b/benches/linear_proof.rs @@ -64,7 +64,7 @@ fn create_linear_proof_helper(c: &mut Criterion) { G.clone(), &F, &B, - ); + ).unwrap(); }) }, TEST_SIZES, @@ -141,7 +141,7 @@ fn linear_verify(c: &mut Criterion) { G.clone(), &F, &B, - ); + ).unwrap(); (proof, C) }; @@ -150,7 +150,7 @@ fn linear_verify(c: &mut Criterion) { bench.iter(|| { let mut verifier_transcript = Transcript::new(b"LinearProofBenchmark"); proof - .verify(*n, &mut verifier_transcript, &C, &G, &F, &B, b.clone()) + .verify(&mut verifier_transcript, &C, &G, &F, &B, b.clone()) .unwrap(); }); }, From f4ab5c293a4eea3f6622860d797c5afa94d1afbc Mon Sep 17 00:00:00 2001 From: Cathie Yun <3314874+cathieyun@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:11:41 -0700 Subject: [PATCH 4/4] fmt --- benches/linear_proof.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/benches/linear_proof.rs b/benches/linear_proof.rs index b262a920..5adfb4d3 100644 --- a/benches/linear_proof.rs +++ b/benches/linear_proof.rs @@ -64,7 +64,8 @@ fn create_linear_proof_helper(c: &mut Criterion) { G.clone(), &F, &B, - ).unwrap(); + ) + .unwrap(); }) }, TEST_SIZES, @@ -141,7 +142,8 @@ fn linear_verify(c: &mut Criterion) { G.clone(), &F, &B, - ).unwrap(); + ) + .unwrap(); (proof, C) };