4040//! assert!(proof.verify(&mut hasher, &digests[1], 1, &root).is_ok());
4141//! ```
4242
43- use bytes:: Buf ;
44- use commonware_codec:: { FixedSize , ReadExt } ;
43+ use bytes:: { Buf , BufMut } ;
44+ use commonware_codec:: { EncodeSize , Read , ReadRangeExt , Write } ;
4545use commonware_cryptography:: Hasher ;
4646use thiserror:: Error ;
4747
48+ /// There should never be more than 255 siblings in a proof (would mean the Binary Merkle Tree
49+ /// has more than 2^255 leaves).
50+ const MAX_SIBLINGS : usize = u8:: MAX as usize ;
51+
4852/// Errors that can occur when working with a Binary Merkle Tree (BMT).
4953#[ derive( Error , Debug ) ]
5054pub enum Error {
@@ -247,53 +251,33 @@ impl<H: Hasher> Proof<H> {
247251 Err ( Error :: InvalidProof ( computed. to_string ( ) , root. to_string ( ) ) )
248252 }
249253 }
254+ }
250255
251- /// Serializes the proof as the concatenation of each hash.
252- pub fn serialize ( & self ) -> Vec < u8 > {
253- // There should never be more than 255 siblings in a proof (would mean the Binary Merkle Tree
254- // has more than 2^255 leaves).
255- assert ! (
256- self . siblings. len( ) <= u8 :: MAX as usize ,
257- "too many siblings in proof"
258- ) ;
259-
260- // Serialize the proof as the concatenation of each hash.
261- let bytes_len = self . siblings . len ( ) * H :: Digest :: SIZE ;
262- let mut bytes = Vec :: with_capacity ( bytes_len) ;
263- for hash in & self . siblings {
264- bytes. extend_from_slice ( hash. as_ref ( ) ) ;
265- }
266- bytes
256+ impl < H : Hasher > Write for Proof < H > {
257+ fn write ( & self , writer : & mut impl BufMut ) {
258+ self . siblings . write ( writer) ;
267259 }
260+ }
268261
269- /// Deserializes a proof from its canonical serialized representation.
270- pub fn deserialize ( mut buf : & [ u8 ] ) -> Result < Self , Error > {
271- // It is ok to have an empty proof (just means the provided leaf is the root).
272-
273- // If the remaining buffer is not a multiple of the hash size, it's invalid.
274- if buf. remaining ( ) % H :: Digest :: SIZE != 0 {
275- return Err ( Error :: UnalignedProof ) ;
276- }
277-
278- // If the number of siblings is too large, it's invalid.
279- let num_siblings = buf. len ( ) / H :: Digest :: SIZE ;
280- if num_siblings > u8:: MAX as usize {
281- return Err ( Error :: TooManySiblings ( num_siblings) ) ;
282- }
262+ impl < H : Hasher > Read for Proof < H > {
263+ type Cfg = ( ) ;
283264
284- // Deserialize the siblings
285- let mut siblings = Vec :: with_capacity ( num_siblings) ;
286- for _ in 0 ..num_siblings {
287- let hash = H :: Digest :: read ( & mut buf) . map_err ( |_| Error :: InvalidDigest ) ?;
288- siblings. push ( hash) ;
289- }
265+ fn read_cfg ( reader : & mut impl Buf , _: & Self :: Cfg ) -> Result < Self , commonware_codec:: Error > {
266+ let siblings = Vec :: < H :: Digest > :: read_range ( reader, ..=MAX_SIBLINGS ) ?;
290267 Ok ( Self { siblings } )
291268 }
292269}
293270
271+ impl < H : Hasher > EncodeSize for Proof < H > {
272+ fn encode_size ( & self ) -> usize {
273+ self . siblings . encode_size ( )
274+ }
275+ }
276+
294277#[ cfg( test) ]
295278mod tests {
296279 use super :: * ;
280+ use commonware_codec:: { DecodeExt , Encode } ;
297281 use commonware_cryptography:: {
298282 hash,
299283 sha256:: { Digest , Sha256 } ,
@@ -323,8 +307,8 @@ mod tests {
323307 ) ;
324308
325309 // Serialize and deserialize the proof
326- let serialized = proof. serialize ( ) ;
327- let deserialized = Proof :: < Sha256 > :: deserialize ( & serialized) . unwrap ( ) ;
310+ let mut serialized = proof. encode ( ) ;
311+ let deserialized = Proof :: < Sha256 > :: decode ( & mut serialized) . unwrap ( ) ;
328312 assert ! (
329313 deserialized
330314 . verify( & mut hasher, leaf, i as u32 , & root)
@@ -725,11 +709,11 @@ mod tests {
725709
726710 // Generate a valid proof for leaf at index 1.
727711 let proof = tree. proof ( 1 ) . unwrap ( ) ;
728- let mut serialized = proof. serialize ( ) ;
712+ let mut serialized = proof. encode ( ) ;
729713
730714 // Truncate one byte.
731- serialized. pop ( ) ;
732- assert ! ( Proof :: <Sha256 >:: deserialize ( & serialized) . is_err( ) ) ;
715+ serialized. truncate ( serialized . len ( ) - 1 ) ;
716+ assert ! ( Proof :: <Sha256 >:: decode ( & mut serialized) . is_err( ) ) ;
733717 }
734718
735719 #[ test]
@@ -747,11 +731,11 @@ mod tests {
747731
748732 // Generate a valid proof for leaf at index 1.
749733 let proof = tree. proof ( 1 ) . unwrap ( ) ;
750- let mut serialized = proof. serialize ( ) ;
734+ let mut serialized = proof. encode ( ) ;
751735
752736 // Append an extra byte.
753- serialized. push ( 0u8 ) ;
754- assert ! ( Proof :: <Sha256 >:: deserialize ( & serialized) . is_err( ) ) ;
737+ serialized. extend_from_slice ( & [ 0u8 ] ) ;
738+ assert ! ( Proof :: <Sha256 >:: decode ( & mut serialized) . is_err( ) ) ;
755739 }
756740
757741 #[ test]
0 commit comments