1
0
Fork 0
mirror of https://github.com/BLAKE3-team/BLAKE3 synced 2024-05-04 02:36:08 +02:00
BLAKE3/src/guts.rs
Cesar Eduardo Barros 9f509a8f1f Inline trivial functions
For the Read and Write traits, this also allows the compiler to see that
the return value is always Ok, allowing it to remove the Err case from
the caller as dead code.
2020-01-12 18:27:42 -05:00

96 lines
2.5 KiB
Rust

// This module is for incremental use cases like the `bao` crate, which need to
// get their hands on internal chunk and parent chaining values. The vast
// majority of users should ignore this and use the publicly documented
// interface instead.
#[derive(Clone, Debug)]
pub struct ChunkState(crate::ChunkState);
impl ChunkState {
// Currently this type only supports the regular hash mode. If an
// incremental user needs keyed_hash or derive_key, we can add that.
pub fn new(chunk_counter: u64) -> Self {
Self(crate::ChunkState::new(
crate::IV,
chunk_counter,
0,
crate::platform::Platform::detect(),
))
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn update(&mut self, input: &[u8]) -> &mut Self {
self.0.update(input);
self
}
pub fn finalize(&self, is_root: bool) -> crate::Hash {
let output = self.0.output();
if is_root {
output.root_hash()
} else {
output.chaining_value().into()
}
}
}
// As above, this currently assumes the regular hash mode. If an incremental
// user needs keyed_hash or derive_key, we can add that.
pub fn parent_cv(
left_child: &crate::Hash,
right_child: &crate::Hash,
is_root: bool,
) -> crate::Hash {
let output = crate::parent_node_output(
left_child.as_bytes(),
right_child.as_bytes(),
crate::IV,
0,
crate::platform::Platform::detect(),
);
if is_root {
output.root_hash()
} else {
output.chaining_value().into()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_chunk() {
assert_eq!(
crate::hash(b"foo"),
ChunkState::new(0).update(b"foo").finalize(true)
);
}
#[test]
fn test_parents() {
let mut hasher = crate::Hasher::new();
let mut buf = [0; crate::CHUNK_LEN];
buf[0] = 'a' as u8;
hasher.update(&buf);
let chunk0_cv = ChunkState::new(0).update(&buf).finalize(false);
buf[0] = 'b' as u8;
hasher.update(&buf);
let chunk1_cv = ChunkState::new(1).update(&buf).finalize(false);
hasher.update(b"c");
let chunk2_cv = ChunkState::new(2).update(b"c").finalize(false);
let parent = parent_cv(&chunk0_cv, &chunk1_cv, false);
let root = parent_cv(&parent, &chunk2_cv, true);
assert_eq!(hasher.finalize(), root);
}
}