1
0
Fork 0
mirror of https://github.com/BLAKE3-team/BLAKE3 synced 2024-05-23 12:56:07 +02:00

Add fn hash_block to guts

provides an efficient way to compute the hash for multiple chunks that do
not start at chunk 0, as part of a larger tree.

This is useful for crates like bao, abao and bao-tree, especially when using
chunk groups.

Adding this required to disable some assertions that contained assumptions
that are no longer true.
This commit is contained in:
Ruediger Klaehn 2023-07-29 23:52:00 +03:00
parent 12823b8760
commit c8b199b0a6
2 changed files with 46 additions and 6 deletions

View File

@ -9,6 +9,12 @@
pub const BLOCK_LEN: usize = 64;
pub const CHUNK_LEN: usize = 1024;
pub fn hash_block(start_chunk: u64, data: &[u8], is_root: bool) -> crate::Hash {
let mut hasher = crate::Hasher::new_with_start_chunk(start_chunk);
hasher.update(data);
hasher.finalize_node(is_root)
}
#[derive(Clone, Debug)]
pub struct ChunkState(crate::ChunkState);
@ -98,4 +104,12 @@ mod test {
let root = parent_cv(&parent, &chunk2_cv, true);
assert_eq!(hasher.finalize(), root);
}
#[test]
fn test_hash_block() {
assert_eq!(
crate::hash(b"foo"),
hash_block(0, b"foo", true)
);
}
}

View File

@ -409,6 +409,18 @@ impl Output {
Hash(platform::le_bytes_from_words_32(&cv))
}
fn hash(&self, is_root: bool) -> Hash {
// debug_assert_eq!(self.counter, 0);
let mut cv = self.input_chaining_value;
let mut flags = self.flags;
if is_root {
flags |= ROOT;
}
self.platform
.compress_in_place(&mut cv, &self.block, self.block_len, 0, flags);
Hash(platform::le_bytes_from_words_32(&cv))
}
fn root_output_block(&self) -> [u8; 2 * OUT_LEN] {
self.platform.compress_xof(
&self.input_chaining_value,
@ -977,6 +989,15 @@ impl Hasher {
Self::new_internal(IV, 0)
}
/// Construct a new `Hasher` with a start chunk
fn new_with_start_chunk(start_chunk: u64) -> Self {
Self {
key: *IV,
chunk_state: ChunkState::new(IV, start_chunk, 0, Platform::detect()),
cv_stack: ArrayVec::new(),
}
}
/// Construct a new `Hasher` for the keyed hash function. See
/// [`keyed_hash`].
///
@ -1246,7 +1267,7 @@ impl Hasher {
// also. Convert it directly into an Output. Otherwise, we need to
// merge subtrees below.
if self.cv_stack.is_empty() {
debug_assert_eq!(self.chunk_state.chunk_counter, 0);
// debug_assert_eq!(self.chunk_state.chunk_counter, 0);
return self.chunk_state.output();
}
@ -1265,11 +1286,11 @@ impl Hasher {
let mut output: Output;
let mut num_cvs_remaining = self.cv_stack.len();
if self.chunk_state.len() > 0 {
debug_assert_eq!(
self.cv_stack.len(),
self.chunk_state.chunk_counter.count_ones() as usize,
"cv stack does not need a merge"
);
// debug_assert_eq!(
// self.cv_stack.len(),
// self.chunk_state.chunk_counter.count_ones() as usize,
// "cv stack does not need a merge"
// );
output = self.chunk_state.output();
} else {
debug_assert!(self.cv_stack.len() >= 2);
@ -1304,6 +1325,11 @@ impl Hasher {
self.final_output().root_hash()
}
fn finalize_node(&self, is_root: bool) -> Hash {
let output = self.final_output();
output.hash(is_root)
}
/// Finalize the hash state and return an [`OutputReader`], which can
/// supply any number of output bytes.
///