dcrypt_algorithms/hash/
mod.rs

1//! Cryptographic hash function implementations with enhanced type safety
2//!
3//! This module provides implementations of various cryptographic hash functions
4//! with improved type-level guarantees and method chaining for ergonomic usage.
5
6#[cfg(not(feature = "std"))]
7use alloc::vec::Vec;
8
9use crate::error::Result;
10use crate::types::Digest;
11
12pub mod blake2;
13pub mod keccak; // Added module
14pub mod sha1;
15pub mod sha2;
16pub mod sha3;
17pub mod shake;
18
19// Re-exports
20pub use blake2::{Blake2b, Blake2s};
21pub use keccak::Keccak256; // Export Keccak256
22pub use sha1::Sha1;
23pub use sha2::{Sha224, Sha256, Sha384, Sha512};
24pub use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
25pub use shake::{Shake128, Shake256};
26
27/// A byte-vector hash result for backward compatibility.
28pub type Hash = Vec<u8>;
29
30/// Marker trait for hash algorithms with compile-time guarantees
31pub trait HashAlgorithm {
32    /// Output size in bytes
33    const OUTPUT_SIZE: usize;
34
35    /// Block size in bytes
36    const BLOCK_SIZE: usize;
37
38    /// Static algorithm identifier for compile-time checking
39    const ALGORITHM_ID: &'static str;
40
41    /// Algorithm name for display purposes
42    fn name() -> String {
43        Self::ALGORITHM_ID.to_string()
44    }
45}
46
47/// Trait for cryptographic hash functions with improved type safety.
48///
49/// Example usage of the enhanced hash functions:
50///
51/// ```
52/// use dcrypt_algorithms::hash::{EnhancedSha256, HashFunction};
53///
54/// // One-shot API
55/// let digest = EnhancedSha256::digest(b"hello world").unwrap();
56///
57/// // Incremental API with method chaining
58/// let digest = EnhancedSha256::new()
59///     .update(b"hello ").unwrap()
60///     .update(b"world").unwrap()
61///     .finalize().unwrap();
62///
63/// // Verification
64/// assert!(EnhancedSha256::verify(b"hello world", &digest).unwrap());
65/// ```
66pub trait HashFunction: Sized {
67    /// The algorithm type that defines constants and properties
68    type Algorithm: HashAlgorithm;
69
70    /// The output digest type with size guarantees
71    type Output: AsRef<[u8]> + AsMut<[u8]> + Clone;
72
73    /// Creates a new instance of the hash function.
74    fn new() -> Self;
75
76    /// Updates the hash state with `data`, returning self for chaining.
77    fn update(&mut self, data: &[u8]) -> Result<&mut Self>;
78
79    /// Finalizes and returns the digest.
80    fn finalize(&mut self) -> Result<Self::Output>;
81
82    /// Finalizes, returns the digest, and resets state.
83    fn finalize_reset(&mut self) -> Result<Self::Output> {
84        let h = self.finalize()?;
85        *self = Self::new();
86        Ok(h)
87    }
88
89    /// The output size in bytes.
90    fn output_size() -> usize {
91        Self::Algorithm::OUTPUT_SIZE
92    }
93
94    /// The internal block size in bytes.
95    fn block_size() -> usize {
96        Self::Algorithm::BLOCK_SIZE
97    }
98
99    /// Convenience: one-shot digest computation with fluent interface.
100    fn digest(data: &[u8]) -> Result<Self::Output> {
101        let mut hasher = Self::new();
102        hasher.update(data)?;
103        hasher.finalize()
104    }
105
106    /// Human-readable name.
107    fn name() -> String {
108        Self::Algorithm::name()
109    }
110
111    /// Convenience method to verify a hash against input data
112    fn verify(data: &[u8], expected: &Self::Output) -> Result<bool>
113    where
114        Self::Output: PartialEq,
115    {
116        let computed = Self::digest(data)?;
117        Ok(computed == *expected)
118    }
119}
120
121/// Implementation of enhanced Sha256 using the new trait structure
122#[derive(Clone)]
123pub struct EnhancedSha256 {
124    inner: sha2::Sha256,
125}
126
127/// Marker type for SHA-256 algorithm
128pub enum Sha256Algorithm {}
129
130impl HashAlgorithm for Sha256Algorithm {
131    const OUTPUT_SIZE: usize = 32;
132    const BLOCK_SIZE: usize = 64;
133    const ALGORITHM_ID: &'static str = "SHA-256";
134}
135
136impl HashFunction for EnhancedSha256 {
137    type Algorithm = Sha256Algorithm;
138    type Output = Digest<32>;
139
140    fn new() -> Self {
141        Self {
142            inner: sha2::Sha256::new(),
143        }
144    }
145
146    fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
147        self.inner.update(data)?;
148        Ok(self)
149    }
150
151    fn finalize(&mut self) -> Result<Self::Output> {
152        self.inner.finalize()
153    }
154}