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