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 }