#[cfg(any(
feature = "strobe",
feature = "identity",
feature = "blake2b",
feature = "blake2s",
feature = "blake3"
))]
macro_rules! derive_write {
($name:ident) => {
impl<const S: usize> core2::io::Write for $name<S> {
fn write(&mut self, buf: &[u8]) -> core2::io::Result<usize> {
use multihash_derive::Hasher as _;
self.update(buf);
Ok(buf.len())
}
fn flush(&mut self) -> core2::io::Result<()> {
Ok(())
}
}
};
}
#[cfg(any(feature = "blake2b", feature = "blake2s", feature = "blake3"))]
macro_rules! derive_hasher_blake {
($module:ident, $name:ident) => {
#[derive(Debug)]
pub struct $name<const S: usize> {
state: $module::State,
digest: [u8; S],
}
impl<const S: usize> Default for $name<S> {
fn default() -> Self {
let mut params = $module::Params::new();
params.hash_length(S);
Self {
state: params.to_state(),
digest: [0; S],
}
}
}
impl<const S: usize> multihash_derive::Hasher for $name<S> {
fn update(&mut self, input: &[u8]) {
self.state.update(input);
}
fn finalize(&mut self) -> &[u8] {
let digest = self.state.finalize();
let digest_bytes = digest.as_bytes();
let digest_out = &mut self.digest[..digest_bytes.len().max(S)];
digest_out.copy_from_slice(digest_bytes);
digest_out
}
fn reset(&mut self) {
let Self { state, .. } = Self::default();
self.state = state;
}
}
derive_write!($name);
};
}
#[cfg(feature = "blake2b")]
pub mod blake2b {
derive_hasher_blake!(blake2b_simd, Blake2bHasher);
pub type Blake2b256 = Blake2bHasher<32>;
pub type Blake2b512 = Blake2bHasher<64>;
}
#[cfg(feature = "blake2s")]
pub mod blake2s {
derive_hasher_blake!(blake2s_simd, Blake2sHasher);
pub type Blake2s128 = Blake2sHasher<16>;
pub type Blake2s256 = Blake2sHasher<32>;
}
#[cfg(feature = "blake3")]
pub mod blake3 {
#[derive(Debug)]
pub struct Blake3Hasher<const S: usize> {
hasher: ::blake3::Hasher,
digest: [u8; S],
}
impl<const S: usize> Blake3Hasher<S> {
pub fn finalize_xof_fill(&mut self, digest_out: &mut [u8]) {
let mut digest = self.hasher.finalize_xof();
digest.fill(digest_out)
}
}
impl<const S: usize> Default for Blake3Hasher<S> {
fn default() -> Self {
let hasher = ::blake3::Hasher::new();
Self {
hasher,
digest: [0; S],
}
}
}
impl<const S: usize> multihash_derive::Hasher for Blake3Hasher<S> {
fn update(&mut self, input: &[u8]) {
self.hasher.update(input);
}
fn finalize(&mut self) -> &[u8] {
let mut output = self.hasher.finalize_xof();
output.fill(&mut self.digest);
&self.digest
}
fn reset(&mut self) {
self.hasher.reset();
}
}
derive_write!(Blake3Hasher);
pub type Blake3_256 = Blake3Hasher<32>;
}
#[cfg(any(
feature = "sha1",
feature = "sha2",
feature = "sha3",
feature = "ripemd"
))]
macro_rules! derive_rustcrypto_hasher {
($module:ty, $name:ident, $size:expr) => {
#[derive(Debug)]
pub struct $name {
state: $module,
digest: [u8; $size],
}
impl Default for $name {
fn default() -> Self {
$name {
state: Default::default(),
digest: [0; $size],
}
}
}
impl ::multihash_derive::Hasher for $name {
fn update(&mut self, input: &[u8]) {
use digest::Digest;
self.state.update(input)
}
fn finalize(&mut self) -> &[u8] {
use digest::Digest;
let digest = self.state.clone().finalize();
let digest_bytes = digest.as_slice();
let digest_out = &mut self.digest[..digest_bytes.len().max($size)];
digest_out.copy_from_slice(digest_bytes);
digest_out
}
fn reset(&mut self) {
use digest::Digest;
self.state.reset();
}
}
impl core2::io::Write for $name {
fn write(&mut self, buf: &[u8]) -> core2::io::Result<usize> {
use multihash_derive::Hasher as _;
self.update(buf);
Ok(buf.len())
}
fn flush(&mut self) -> core2::io::Result<()> {
Ok(())
}
}
};
}
#[cfg(feature = "sha1")]
pub mod sha1 {
derive_rustcrypto_hasher!(::sha1::Sha1, Sha1, 20);
}
#[cfg(feature = "sha2")]
pub mod sha2 {
derive_rustcrypto_hasher!(::sha2::Sha256, Sha2_256, 32);
derive_rustcrypto_hasher!(::sha2::Sha512, Sha2_512, 64);
}
#[cfg(feature = "sha3")]
pub mod sha3 {
derive_rustcrypto_hasher!(::sha3::Sha3_224, Sha3_224, 28);
derive_rustcrypto_hasher!(::sha3::Sha3_256, Sha3_256, 32);
derive_rustcrypto_hasher!(::sha3::Sha3_384, Sha3_384, 48);
derive_rustcrypto_hasher!(::sha3::Sha3_512, Sha3_512, 64);
derive_rustcrypto_hasher!(::sha3::Keccak224, Keccak224, 28);
derive_rustcrypto_hasher!(::sha3::Keccak256, Keccak256, 32);
derive_rustcrypto_hasher!(::sha3::Keccak384, Keccak384, 48);
derive_rustcrypto_hasher!(::sha3::Keccak512, Keccak512, 64);
}
#[cfg(feature = "ripemd")]
pub mod ripemd {
derive_rustcrypto_hasher!(::ripemd::Ripemd160, Ripemd160, 20);
derive_rustcrypto_hasher!(::ripemd::Ripemd256, Ripemd256, 32);
derive_rustcrypto_hasher!(::ripemd::Ripemd320, Ripemd320, 40);
}
#[cfg(feature = "strobe")]
pub mod strobe {
use strobe_rs::{SecParam, Strobe};
pub struct StrobeHasher<const S: usize> {
strobe: Strobe,
initialized: bool,
digest: [u8; S],
}
impl<const S: usize> Default for StrobeHasher<S> {
fn default() -> Self {
Self {
strobe: Strobe::new(b"StrobeHash", SecParam::B128),
initialized: false,
digest: [0; S],
}
}
}
impl<const S: usize> multihash_derive::Hasher for StrobeHasher<S> {
fn update(&mut self, input: &[u8]) {
self.strobe.ad(input, self.initialized);
self.initialized = true;
}
fn finalize(&mut self) -> &[u8] {
self.strobe.clone().prf(&mut self.digest, false);
&self.digest
}
fn reset(&mut self) {
let Self { strobe, .. } = Self::default();
self.strobe = strobe;
self.initialized = false;
}
}
derive_write!(StrobeHasher);
pub type Strobe256 = StrobeHasher<32>;
pub type Strobe512 = StrobeHasher<64>;
}