1pub const BLOCK_LEN: usize = 64;
10pub const CHUNK_LEN: usize = 1024;
11
12#[derive(Clone, Debug)]
13pub struct ChunkState(crate::ChunkState);
14
15impl ChunkState {
16 pub fn new(chunk_counter: u64) -> Self {
19 Self(crate::ChunkState::new(
20 crate::IV,
21 chunk_counter,
22 0,
23 crate::platform::Platform::detect(),
24 ))
25 }
26
27 #[inline]
28 pub fn len(&self) -> usize {
29 self.0.len()
30 }
31
32 #[inline]
33 pub fn update(&mut self, input: &[u8]) -> &mut Self {
34 self.0.update(input);
35 self
36 }
37
38 pub fn finalize(&self, is_root: bool) -> crate::Hash {
39 let output = self.0.output();
40 if is_root {
41 output.root_hash()
42 } else {
43 output.chaining_value().into()
44 }
45 }
46}
47
48pub fn parent_cv(
51 left_child: &crate::Hash,
52 right_child: &crate::Hash,
53 is_root: bool,
54) -> crate::Hash {
55 let output = crate::parent_node_output(
56 left_child.as_bytes(),
57 right_child.as_bytes(),
58 crate::IV,
59 0,
60 crate::platform::Platform::detect(),
61 );
62 if is_root {
63 output.root_hash()
64 } else {
65 output.chaining_value().into()
66 }
67}
68
69#[cfg(test)]
70mod test {
71 use super::*;
72
73 #[test]
74 fn test_chunk() {
75 assert_eq!(
76 crate::hash(b"foo"),
77 ChunkState::new(0).update(b"foo").finalize(true)
78 );
79 }
80
81 #[test]
82 fn test_parents() {
83 let mut hasher = crate::Hasher::new();
84 let mut buf = [0; crate::CHUNK_LEN];
85
86 buf[0] = 'a' as u8;
87 hasher.update(&buf);
88 let chunk0_cv = ChunkState::new(0).update(&buf).finalize(false);
89
90 buf[0] = 'b' as u8;
91 hasher.update(&buf);
92 let chunk1_cv = ChunkState::new(1).update(&buf).finalize(false);
93
94 hasher.update(b"c");
95 let chunk2_cv = ChunkState::new(2).update(b"c").finalize(false);
96
97 let parent = parent_cv(&chunk0_cv, &chunk1_cv, false);
98 let root = parent_cv(&parent, &chunk2_cv, true);
99 assert_eq!(hasher.finalize(), root);
100 }
101}