@@ -6,7 +6,7 @@ use crate::{
66use anyhow:: anyhow;
77use bytes:: Buf ;
88use merkledb:: { prelude:: MerkleDBHighLevelMethodsV1 , Chunk , MerkleMemDB } ;
9- use merklehash:: MerkleHash ;
9+ use merklehash:: { DataHash , MerkleHash } ;
1010use std:: {
1111 cmp:: min,
1212 io:: { Cursor , Error , Read , Seek , Write } ,
@@ -378,8 +378,8 @@ impl CasObject {
378378 & self ,
379379 chunk_start_index : u32 ,
380380 chunk_end_index : u32 ,
381- key : & [ u8 ] ,
382- ) -> Result < MerkleHash , CasObjectError > {
381+ key : & [ u8 ; 32 ] ,
382+ ) -> Result < DataHash , CasObjectError > {
383383 self . validate_cas_object_info ( ) ?;
384384
385385 if chunk_end_index <= chunk_start_index || chunk_end_index > self . info . num_chunks {
@@ -388,18 +388,14 @@ impl CasObject {
388388
389389 // Collect relevant hashes
390390 let range_hashes = self . info . chunk_hashes [ chunk_start_index as usize ..chunk_end_index as usize ] . as_ref ( ) ;
391-
392- // TODO: Make this more robust, currently appends range hashes together, adds key to end
393- let mut combined: Vec < u8 > = range_hashes
391+ let combined: Vec < u8 > = range_hashes
394392 . iter ( )
395393 . flat_map ( |hash| hash. as_bytes ( ) . to_vec ( ) )
396394 . collect ( ) ;
397- combined. extend_from_slice ( key) ;
398-
399- // now hash the hashes + key and return
400- let range_hash = merklehash:: compute_data_hash ( & combined) ;
401395
402- Ok ( range_hash)
396+ // now apply hmac to hashes and return
397+ let range_hash = blake3:: keyed_hash ( key, combined. as_slice ( ) ) ;
398+ Ok ( DataHash :: from ( range_hash. as_bytes ( ) ) )
403399 }
404400
405401 /// Return end offset of all physical chunk contents (byte index at the beginning of footer)
@@ -689,56 +685,54 @@ mod tests {
689685 // Arrange
690686 let ( c, _cas_data, _raw_data, _raw_chunk_boundaries) =
691687 build_cas_object ( 3 , ChunkSize :: Fixed ( 100 ) , CompressionScheme :: None ) ;
692- let key = [ b'K' , b'E' , b'Y' ] ;
688+ let key: & [ u8 ; 32 ] = c . info . cashash . as_bytes ( ) . try_into ( ) . map_err ( |_| "The slice is not 32 bytes long" ) . unwrap ( ) ;
693689
694- let mut hashes: Vec < u8 > = c
690+ let hashes: Vec < u8 > = c
695691 . info
696692 . chunk_hashes
697693 . iter ( )
698694 . flat_map ( |hash| hash. as_bytes ( ) . to_vec ( ) )
699695 . collect ( ) ;
700- hashes . extend_from_slice ( & key ) ;
701- let expected_hash = merklehash :: compute_data_hash ( & hashes) ;
696+
697+ let expected_hash = blake3 :: keyed_hash ( key , hashes. as_slice ( ) ) ;
702698
703699 // Act & Assert
704- let range_hash = c. generate_chunk_range_hash ( 0 , 3 , & key) . unwrap ( ) ;
705- assert_eq ! ( range_hash, expected_hash) ;
700+ let range_hash = c. generate_chunk_range_hash ( 0 , 3 , key) . unwrap ( ) ;
701+ assert_eq ! ( range_hash, DataHash :: from ( expected_hash. as_bytes ( ) ) ) ;
706702 }
707703
708704 #[ test]
709705 fn test_generate_range_hash_partial ( ) {
710706 // Arrange
711707 let ( c, _cas_data, _raw_data, _raw_chunk_boundaries) =
712708 build_cas_object ( 5 , ChunkSize :: Fixed ( 100 ) , CompressionScheme :: None ) ;
713- let key = [ b'K' , b'E' , b'Y' , b'B' , b'A' , b'B' , b'Y' ] ;
709+ let key: & [ u8 ; 32 ] = c . info . cashash . as_bytes ( ) . try_into ( ) . map_err ( |_| "The slice is not 32 bytes long" ) . unwrap ( ) ;
714710
715- let mut hashes : Vec < u8 > = c. info . chunk_hashes . as_slice ( ) [ 1 ..=3 ] . to_vec ( ) . iter ( ) . flat_map ( |hash| hash. as_bytes ( ) . to_vec ( ) ) . collect ( ) ;
716- hashes. extend_from_slice ( & key) ;
717- let expected_hash = merklehash:: compute_data_hash ( & hashes) ;
711+ let hashes : Vec < u8 > = c. info . chunk_hashes . as_slice ( ) [ 1 ..=3 ] . to_vec ( ) . iter ( ) . flat_map ( |hash| hash. as_bytes ( ) . to_vec ( ) ) . collect ( ) ;
712+ let expected_hash = blake3:: keyed_hash ( key, hashes. as_slice ( ) ) ;
718713
719714 // Act & Assert
720- let range_hash = c. generate_chunk_range_hash ( 1 , 4 , & key) . unwrap ( ) ;
721- assert_eq ! ( range_hash, expected_hash) ;
715+ let range_hash = c. generate_chunk_range_hash ( 1 , 4 , key) . unwrap ( ) ;
716+ assert_eq ! ( range_hash, DataHash :: from ( expected_hash. as_bytes ( ) ) ) ;
722717
723- let mut hashes : Vec < u8 > = c. info . chunk_hashes . as_slice ( ) [ 0 ..1 ] . to_vec ( ) . iter ( ) . flat_map ( |hash| hash. as_bytes ( ) . to_vec ( ) ) . collect ( ) ;
724- hashes. extend_from_slice ( & key) ;
725- let expected_hash = merklehash:: compute_data_hash ( & hashes) ;
718+ let hashes : Vec < u8 > = c. info . chunk_hashes . as_slice ( ) [ 0 ..1 ] . to_vec ( ) . iter ( ) . flat_map ( |hash| hash. as_bytes ( ) . to_vec ( ) ) . collect ( ) ;
719+ let expected_hash = blake3:: keyed_hash ( key, hashes. as_slice ( ) ) ;
726720
727- let range_hash = c. generate_chunk_range_hash ( 0 , 1 , & key) . unwrap ( ) ;
728- assert_eq ! ( range_hash, expected_hash) ;
721+ let range_hash = c. generate_chunk_range_hash ( 0 , 1 , key) . unwrap ( ) ;
722+ assert_eq ! ( range_hash, DataHash :: from ( expected_hash. as_bytes ( ) ) ) ;
729723 }
730724
731725 #[ test]
732726 fn test_generate_range_hash_invalid_range ( ) {
733727 // Arrange
734728 let ( c, _cas_data, _raw_data, _raw_chunk_boundaries) =
735729 build_cas_object ( 5 , ChunkSize :: Fixed ( 100 ) , CompressionScheme :: None ) ;
736- let key = [ b'K' , b'E' , b'Y' , b'B' , b'A' , b'B' , b'Y' ] ;
737-
730+ let key: & [ u8 ; 32 ] = c . info . cashash . as_bytes ( ) . try_into ( ) . map_err ( |_| "The slice is not 32 bytes long" ) . unwrap ( ) ;
731+
738732 // Act & Assert
739- assert_eq ! ( c. generate_chunk_range_hash( 1 , 6 , & key) , Err ( CasObjectError :: InvalidArguments ) ) ;
740- assert_eq ! ( c. generate_chunk_range_hash( 100 , 10 , & key) , Err ( CasObjectError :: InvalidArguments ) ) ;
741- assert_eq ! ( c. generate_chunk_range_hash( 0 , 0 , & key) , Err ( CasObjectError :: InvalidArguments ) ) ;
733+ assert_eq ! ( c. generate_chunk_range_hash( 1 , 6 , key) , Err ( CasObjectError :: InvalidArguments ) ) ;
734+ assert_eq ! ( c. generate_chunk_range_hash( 100 , 10 , key) , Err ( CasObjectError :: InvalidArguments ) ) ;
735+ assert_eq ! ( c. generate_chunk_range_hash( 0 , 0 , key) , Err ( CasObjectError :: InvalidArguments ) ) ;
742736 }
743737
744738 #[ test]
0 commit comments