Skip to content

Commit 55b0596

Browse files
committed
tiger: implement TTH hash algorithm
1 parent 7287da1 commit 55b0596

File tree

3 files changed

+205
-10
lines changed

3 files changed

+205
-10
lines changed

tiger/src/lib.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#![forbid(unsafe_code)]
3434
#![warn(missing_docs, rust_2018_idioms)]
3535

36+
extern crate alloc;
37+
3638
pub use digest::{self, Digest};
3739

3840
use core::fmt;
@@ -50,6 +52,9 @@ mod compress;
5052
mod tables;
5153
use compress::compress;
5254

55+
mod tth;
56+
use tth::TigerTreeCore;
57+
5358
type State = [u64; 3];
5459
const S0: State = [
5560
0x0123_4567_89AB_CDEF,
@@ -91,7 +96,7 @@ impl UpdateCore for TigerCore {
9196
impl FixedOutputCore for TigerCore {
9297
#[inline]
9398
fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
94-
let bs = Self::BlockSize::U64 as u64;
99+
let bs = Self::BlockSize::U64;
95100
let pos = buffer.get_pos() as u64;
96101
let bit_len = 8 * (pos + bs * self.block_len);
97102

@@ -165,7 +170,7 @@ impl UpdateCore for Tiger2Core {
165170
impl FixedOutputCore for Tiger2Core {
166171
#[inline]
167172
fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
168-
let bs = Self::BlockSize::U64 as u64;
173+
let bs = Self::BlockSize::U64;
169174
let pos = buffer.get_pos() as u64;
170175
let bit_len = 8 * (pos + bs * self.block_len);
171176

@@ -180,11 +185,7 @@ impl Default for Tiger2Core {
180185
fn default() -> Self {
181186
Self {
182187
block_len: 0,
183-
state: [
184-
0x0123_4567_89AB_CDEF,
185-
0xFEDC_BA98_7654_3210,
186-
0xF096_A5B4_C3B2_E187,
187-
],
188+
state: S0,
188189
}
189190
}
190191
}
@@ -208,7 +209,9 @@ impl fmt::Debug for Tiger2Core {
208209
}
209210
}
210211

211-
/// Tiger hasher state.
212+
/// Tiger hasher.
212213
pub type Tiger = CoreWrapper<TigerCore>;
213-
/// Tiger2 hasher state.
214+
/// Tiger2 hasher.
214215
pub type Tiger2 = CoreWrapper<Tiger2Core>;
216+
/// TTH hasher.
217+
pub type TigerTree = CoreWrapper<TigerTreeCore>;

tiger/src/tth.rs

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
use crate::{Digest, Tiger, TigerCore};
2+
use alloc::vec::Vec;
3+
use core::fmt;
4+
use digest::{
5+
core_api::{
6+
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore,
7+
OutputSizeUser, Reset, UpdateCore,
8+
},
9+
typenum::Unsigned,
10+
typenum::U1024,
11+
HashMarker, Output,
12+
};
13+
14+
/// Core Tiger hasher state.
15+
#[derive(Clone)]
16+
pub struct TigerTreeCore {
17+
leaves: Vec<Output<TigerCore>>,
18+
hasher: Tiger,
19+
blocks_processed: usize,
20+
}
21+
22+
impl Default for TigerTreeCore {
23+
fn default() -> Self {
24+
Self {
25+
leaves: Vec::default(),
26+
hasher: Tiger::new_with_prefix([LEAF_SIG]),
27+
blocks_processed: 0,
28+
}
29+
}
30+
}
31+
32+
type DataBlockSize = U1024;
33+
const LEAF_SIG: u8 = 0u8;
34+
const NODE_SIG: u8 = 1u8;
35+
/// The number of TigerCore blocks in a TigerTree data block
36+
const LEAF_BLOCKS: usize = DataBlockSize::USIZE / <TigerCore as BlockSizeUser>::BlockSize::USIZE;
37+
38+
impl HashMarker for TigerTreeCore {}
39+
40+
impl BlockSizeUser for TigerTreeCore {
41+
type BlockSize = <TigerCore as BlockSizeUser>::BlockSize;
42+
}
43+
44+
impl BufferKindUser for TigerTreeCore {
45+
type BufferKind = <TigerCore as BufferKindUser>::BufferKind;
46+
}
47+
48+
impl OutputSizeUser for TigerTreeCore {
49+
type OutputSize = <TigerCore as OutputSizeUser>::OutputSize;
50+
}
51+
52+
impl TigerTreeCore {
53+
#[inline]
54+
fn finalize_blocks(&mut self) {
55+
let hasher = core::mem::replace(&mut self.hasher, Tiger::new_with_prefix([LEAF_SIG]));
56+
let hash = hasher.finalize();
57+
self.leaves.push(hash);
58+
self.blocks_processed = 0;
59+
}
60+
61+
#[inline]
62+
fn update_block(&mut self, block: Block<Self>) {
63+
self.hasher.update(block);
64+
self.blocks_processed += 1;
65+
if self.blocks_processed == LEAF_BLOCKS {
66+
self.finalize_blocks();
67+
}
68+
}
69+
}
70+
71+
impl UpdateCore for TigerTreeCore {
72+
#[inline]
73+
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
74+
for block in blocks {
75+
self.update_block(*block);
76+
}
77+
}
78+
}
79+
80+
impl FixedOutputCore for TigerTreeCore {
81+
#[inline]
82+
fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
83+
if buffer.get_pos() > 0 {
84+
self.hasher.update(buffer.get_data());
85+
self.blocks_processed += 1;
86+
}
87+
88+
if self.blocks_processed > 0 {
89+
self.finalize_blocks()
90+
}
91+
92+
let result = hash_nodes(self.leaves.as_slice());
93+
out.copy_from_slice(&result);
94+
}
95+
}
96+
97+
#[inline]
98+
fn hash_nodes(hashes: &[Output<TigerCore>]) -> Output<TigerCore> {
99+
match hashes.len() {
100+
0 => hash_nodes(&[Tiger::digest([LEAF_SIG])]),
101+
1 => hashes[0],
102+
_ => {
103+
let left_hashes = hashes.iter().step_by(2);
104+
105+
let right_hashes = hashes.iter().map(Some).skip(1).chain([None]).step_by(2);
106+
107+
let next_level_hashes: Vec<Output<TigerCore>> = left_hashes
108+
.zip(right_hashes)
109+
.map(|(left, right)| match right {
110+
Some(right) => Tiger::digest([&[NODE_SIG][..], left, right].concat()),
111+
None => *left,
112+
})
113+
.collect();
114+
115+
hash_nodes(next_level_hashes.as_slice())
116+
}
117+
}
118+
}
119+
120+
impl Reset for TigerTreeCore {
121+
#[inline]
122+
fn reset(&mut self) {
123+
*self = Default::default();
124+
}
125+
}
126+
127+
impl AlgorithmName for TigerTreeCore {
128+
fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
129+
f.write_str("TigerTree")
130+
}
131+
}
132+
133+
impl fmt::Debug for TigerTreeCore {
134+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135+
f.write_str("TigerTreeCore { ... }")
136+
}
137+
}

tiger/tests/mod.rs

+56-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use digest::dev::{feed_rand_16mib, fixed_reset_test};
22
use digest::new_test;
33
use hex_literal::hex;
4-
use tiger::{Digest, Tiger, Tiger2};
4+
use tiger::{Digest, Tiger, Tiger2, TigerTree};
55

66
new_test!(tiger, "tiger", tiger::Tiger, fixed_reset_test);
77
new_test!(tiger2, "tiger2", tiger::Tiger2, fixed_reset_test);
@@ -25,3 +25,58 @@ fn tiger2_rand() {
2525
hex!("1bb7a80144c97f831fdefb635477776dd6c164048ce5895d")[..]
2626
);
2727
}
28+
29+
#[test]
30+
fn tiger_empty() {
31+
let mut h = Tiger::new();
32+
h.update(b"");
33+
assert_eq!(
34+
h.finalize()[..],
35+
hex!("3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3")[..]
36+
);
37+
}
38+
39+
#[test]
40+
fn tth_empty() {
41+
let mut h = TigerTree::new();
42+
h.update(b"");
43+
assert_eq!(
44+
h.finalize()[..],
45+
hex!("5d9ed00a030e638bdb753a6a24fb900e5a63b8e73e6c25b6")[..]
46+
);
47+
}
48+
49+
#[test]
50+
fn tth_one_block() {
51+
let mut h = TigerTree::new();
52+
let content = hex!("deadbeef");
53+
h.update(content);
54+
assert_eq!(
55+
h.finalize()[..],
56+
hex!("f527ab1ddbc4cced8572e0cf7a968604ebccb9414eb438dc")[..]
57+
);
58+
}
59+
60+
#[test]
61+
fn tth_two_blocks() {
62+
let content = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
63+
assert!((1025..2049).contains(&content.len()));
64+
let mut h = TigerTree::new();
65+
h.update(content);
66+
assert_eq!(
67+
h.finalize()[..],
68+
hex!("db67d9e452c3af6c329fb664737bc2378aa364b74c3468bb")[..]
69+
);
70+
}
71+
72+
#[test]
73+
fn tth_three_blocks() {
74+
let content = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef8badf00d");
75+
assert!((2049..3073).contains(&content.len()));
76+
let mut h = TigerTree::new();
77+
h.update(content);
78+
assert_eq!(
79+
h.finalize()[..],
80+
hex!("f3a63c92019cffb7527e9adfa57a1ecb783728f67b06fed0")[..]
81+
);
82+
}

0 commit comments

Comments
 (0)