From b1edf95df5c3f60133fb4adcec219d6c0e2f1c17 Mon Sep 17 00:00:00 2001 From: AnthonyMikh Date: Fri, 11 Oct 2019 12:12:33 +0300 Subject: [PATCH] Strip down allocation in serialization of R1CSProof (#298) Add `InnerProductProof::to_bytes_iter`. This semantically equivalent to `proof.to_bytes().into_iter()` except: 1. It borrows the proof; 2. It doesn't allocate --- src/inner_product_proof.rs | 15 +++++++++++++++ src/r1cs/proof.rs | 3 +-- src/range_proof/mod.rs | 3 +-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/inner_product_proof.rs b/src/inner_product_proof.rs index 52285650..63af382d 100644 --- a/src/inner_product_proof.rs +++ b/src/inner_product_proof.rs @@ -349,6 +349,21 @@ impl InnerProductProof { buf } + /// Converts the proof into a byte iterator over serialized view of the proof. + /// The layout of the inner product proof is: + /// * \\(n\\) pairs of compressed Ristretto points \\(L_0, R_0 \dots, L_{n-1}, R_{n-1}\\), + /// * two scalars \\(a, b\\). + #[inline] + pub(crate) fn to_bytes_iter(&self) -> impl Iterator + '_ { + self.L_vec + .iter() + .zip(self.R_vec.iter()) + .flat_map(|(l, r)| l.as_bytes().iter().chain(r.as_bytes())) + .chain(self.a.as_bytes()) + .chain(self.b.as_bytes()) + .copied() + } + /// Deserializes the proof from a byte slice. /// Returns an error in the following cases: /// * the slice does not have \\(2n+2\\) 32-byte elements, diff --git a/src/r1cs/proof.rs b/src/r1cs/proof.rs index dd24de69..aa384e1d 100644 --- a/src/r1cs/proof.rs +++ b/src/r1cs/proof.rs @@ -104,8 +104,7 @@ impl R1CSProof { buf.extend_from_slice(self.t_x.as_bytes()); buf.extend_from_slice(self.t_x_blinding.as_bytes()); buf.extend_from_slice(self.e_blinding.as_bytes()); - // XXX this costs an extra alloc - buf.extend_from_slice(self.ipp_proof.to_bytes().as_slice()); + buf.extend(self.ipp_proof.to_bytes_iter()); buf } diff --git a/src/range_proof/mod.rs b/src/range_proof/mod.rs index 592d81d4..8a38d692 100644 --- a/src/range_proof/mod.rs +++ b/src/range_proof/mod.rs @@ -494,8 +494,7 @@ impl RangeProof { buf.extend_from_slice(self.t_x.as_bytes()); buf.extend_from_slice(self.t_x_blinding.as_bytes()); buf.extend_from_slice(self.e_blinding.as_bytes()); - // XXX this costs an extra alloc - buf.extend_from_slice(self.ipp_proof.to_bytes().as_slice()); + buf.extend(self.ipp_proof.to_bytes_iter()); buf }