#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use crate::error::Result;
use crate::types::Digest;
pub mod blake2;
pub mod keccak; pub mod sha1;
pub mod sha2;
pub mod sha3;
pub mod shake;
pub use blake2::{Blake2b, Blake2s};
pub use keccak::Keccak256; pub use sha1::Sha1;
pub use sha2::{Sha224, Sha256, Sha384, Sha512};
pub use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
pub use shake::{Shake128, Shake256};
pub type Hash = Vec<u8>;
pub trait HashAlgorithm {
const OUTPUT_SIZE: usize;
const BLOCK_SIZE: usize;
const ALGORITHM_ID: &'static str;
fn name() -> String {
Self::ALGORITHM_ID.to_string()
}
}
pub trait HashFunction: Sized {
type Algorithm: HashAlgorithm;
type Output: AsRef<[u8]> + AsMut<[u8]> + Clone;
fn new() -> Self;
fn update(&mut self, data: &[u8]) -> Result<&mut Self>;
fn finalize(&mut self) -> Result<Self::Output>;
fn finalize_reset(&mut self) -> Result<Self::Output> {
let h = self.finalize()?;
*self = Self::new();
Ok(h)
}
fn output_size() -> usize {
Self::Algorithm::OUTPUT_SIZE
}
fn block_size() -> usize {
Self::Algorithm::BLOCK_SIZE
}
fn digest(data: &[u8]) -> Result<Self::Output> {
let mut hasher = Self::new();
hasher.update(data)?;
hasher.finalize()
}
fn name() -> String {
Self::Algorithm::name()
}
fn verify(data: &[u8], expected: &Self::Output) -> Result<bool>
where
Self::Output: PartialEq,
{
let computed = Self::digest(data)?;
Ok(computed == *expected)
}
}
#[derive(Clone)]
pub struct EnhancedSha256 {
inner: sha2::Sha256,
}
pub enum Sha256Algorithm {}
impl HashAlgorithm for Sha256Algorithm {
const OUTPUT_SIZE: usize = 32;
const BLOCK_SIZE: usize = 64;
const ALGORITHM_ID: &'static str = "SHA-256";
}
impl HashFunction for EnhancedSha256 {
type Algorithm = Sha256Algorithm;
type Output = Digest<32>;
fn new() -> Self {
Self {
inner: sha2::Sha256::new(),
}
}
fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
self.inner.update(data)?;
Ok(self)
}
fn finalize(&mut self) -> Result<Self::Output> {
self.inner.finalize()
}
}