Skip to main content

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