@@ -153,6 +153,14 @@ pub const COMPRESSION_QUALITY: i32 = 6;
153153/// Encrypts a set of bytes and returns the encrypted data together with
154154/// the data map that is derived from the input data.
155155pub fn encrypt ( bytes : Bytes ) -> Result < ( DataMap , Vec < EncryptedChunk > ) > {
156+ encrypt_with_child_level ( bytes, 0 )
157+ }
158+
159+ /// Internal encryption that accepts a child_level for KDF domain separation.
160+ fn encrypt_with_child_level (
161+ bytes : Bytes ,
162+ child_level : usize ,
163+ ) -> Result < ( DataMap , Vec < EncryptedChunk > ) > {
156164 let file_size = bytes. len ( ) ;
157165 if file_size < MIN_ENCRYPTABLE_BYTES {
158166 return Err ( Error :: Generic ( format ! (
@@ -186,7 +194,7 @@ pub fn encrypt(bytes: Bytes) -> Result<(DataMap, Vec<EncryptedChunk>)> {
186194 }
187195
188196 // For chunks 2 onwards, we can encrypt immediately since we have the previous two hashes
189- let pki = get_pad_key_and_nonce ( chunk_index, & src_hashes, 0 ) ?;
197+ let pki = get_pad_key_and_nonce ( chunk_index, & src_hashes, child_level ) ?;
190198 let encrypted_content = encrypt:: encrypt_chunk ( chunk_data, pki) ?;
191199 let dst_hash = hash:: content_hash ( & encrypted_content) ;
192200
@@ -204,7 +212,7 @@ pub fn encrypt(bytes: Bytes) -> Result<(DataMap, Vec<EncryptedChunk>)> {
204212
205213 // Now process the first two chunks using the complete set of source hashes
206214 for ( chunk_index, chunk_data, src_hash, src_size) in first_chunks {
207- let pki = get_pad_key_and_nonce ( chunk_index, & src_hashes, 0 ) ?;
215+ let pki = get_pad_key_and_nonce ( chunk_index, & src_hashes, child_level ) ?;
208216 let encrypted_content = encrypt:: encrypt_chunk ( chunk_data, pki) ?;
209217 let dst_hash = hash:: content_hash ( & encrypted_content) ;
210218
@@ -252,8 +260,7 @@ pub fn encrypt(bytes: Bytes) -> Result<(DataMap, Vec<EncryptedChunk>)> {
252260/// * `Result<Bytes>` - The decrypted data or an error if chunks are missing/corrupted
253261pub ( crate ) fn decrypt_full_set ( data_map : & DataMap , chunks : & [ EncryptedChunk ] ) -> Result < Bytes > {
254262 let src_hashes = extract_hashes ( data_map) ;
255- // encrypt() always uses child_level=0 for key derivation, so decrypt must match
256- let child_level = 0 ;
263+ let child_level = data_map. child ( ) . unwrap_or ( 0 ) ;
257264
258265 // Create a mapping of chunk hashes to chunks for efficient lookup
259266 let chunk_map: HashMap < XorName , & EncryptedChunk > = chunks
@@ -327,8 +334,12 @@ pub(crate) fn decrypt_range(
327334 let mut all_bytes = Vec :: new ( ) ;
328335 for ( idx, chunk) in sorted_chunks. iter ( ) . enumerate ( ) {
329336 let chunk_idx = start_chunk + idx;
330- // encrypt() always uses child_level=0 for key derivation, so decrypt must match
331- let decrypted = decrypt_chunk ( chunk_idx, & chunk. content , & src_hashes, 0 ) ?;
337+ let decrypted = decrypt_chunk (
338+ chunk_idx,
339+ & chunk. content ,
340+ & src_hashes,
341+ data_map. child ( ) . unwrap_or ( 0 ) ,
342+ ) ?;
332343 all_bytes. extend_from_slice ( & decrypted) ;
333344 }
334345
@@ -362,22 +373,23 @@ where
362373 let mut all_chunks = Vec :: new ( ) ;
363374
364375 while data_map. len ( ) > 3 {
365- let child_level = data_map. child ( ) . unwrap_or ( 0 ) ;
376+ let next_child_level = data_map. child ( ) . map_or ( 1 , |c| c + 1 ) ;
366377 let bytes = data_map
367378 . to_bytes ( )
368379 . map ( Bytes :: from)
369380 . map_err ( |e| Error :: Generic ( format ! ( "Failed to serialize data map: {e}" ) ) ) ?;
370381
371- let ( mut new_data_map, encrypted_chunks) = encrypt ( bytes) ?;
382+ let ( mut new_data_map, encrypted_chunks) =
383+ encrypt_with_child_level ( bytes, next_child_level) ?;
372384
373385 // Store and collect chunks
374386 for chunk in & encrypted_chunks {
375387 store_chunk ( hash:: content_hash ( & chunk. content ) , chunk. content . clone ( ) ) ?;
376388 }
377389 all_chunks. extend ( encrypted_chunks) ;
378390
379- // Update data map for next iteration
380- new_data_map = DataMap :: with_child ( new_data_map. infos ( ) . to_vec ( ) , child_level + 1 ) ;
391+ // Tag the DataMap with the child_level used during encryption
392+ new_data_map = DataMap :: with_child ( new_data_map. infos ( ) . to_vec ( ) , next_child_level ) ;
381393 data_map = new_data_map;
382394 }
383395 Ok ( ( data_map, all_chunks) )
0 commit comments