use crate::contract::Hasher;
use crate::error::Result;
use crate::hash::hasher;
hasher!(Blake3Hasher, "blake3", "BLAKE3 哈希器(无状态,可复用)。");
impl Hasher for Blake3Hasher {
fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
Ok(blake3::hash(data).as_bytes().to_vec())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn matches_official_test_vectors() {
let hasher = Blake3Hasher::new();
assert_eq!(
hasher.digest_hex(b"").unwrap(),
"af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262"
);
assert_eq!(
hasher.digest_hex(&[0x00]).unwrap(),
"2d3adedff11b61f14c886e35afa036736dcd87a74d27b5c1510225d0f592e213"
);
assert_eq!(hasher.digest(b"").unwrap().len(), 32);
}
#[test]
fn digest_hex_is_lowercase_hex() {
let hex = Blake3Hasher::new().digest_hex(b"abc").unwrap();
assert_eq!(hex.len(), 64);
assert!(
hex.bytes()
.all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
);
}
#[test]
fn distinct_inputs_distinct_digests() {
let hasher = Blake3Hasher::new();
assert_ne!(
hasher.digest(b"abc").unwrap(),
hasher.digest(b"abd").unwrap()
);
}
}