Skip to main content

oxicrypto_core/traits/
hash.rs

1use alloc::vec::Vec;
2
3use crate::CryptoError;
4
5/// Stateless hash function (SHA-2, SHA-3, BLAKE3, ...).
6pub trait Hash: Send + Sync {
7    /// Human-readable algorithm identifier (e.g. `"SHA-256"`).
8    #[must_use]
9    fn name(&self) -> &'static str;
10    /// Byte length of the digest output.
11    #[must_use]
12    fn output_len(&self) -> usize;
13    /// Hash `msg` and write the digest into `out`.
14    ///
15    /// Returns [`CryptoError::BufferTooSmall`] when `out.len() < self.output_len()`.
16    #[must_use = "result must be checked"]
17    fn hash(&self, msg: &[u8], out: &mut [u8]) -> Result<(), CryptoError>;
18    /// Convenience: hash `msg` and return the digest as a [`Vec<u8>`].
19    #[must_use = "result must be checked"]
20    fn hash_to_vec(&self, msg: &[u8]) -> Result<Vec<u8>, CryptoError> {
21        let mut out = alloc::vec![0u8; self.output_len()];
22        self.hash(msg, &mut out)?;
23        Ok(out)
24    }
25    /// Convenience: hash `msg` and return the digest as a fixed-size array.
26    ///
27    /// Returns [`CryptoError::BadInput`] if `N != self.output_len()`.
28    ///
29    /// This method requires `Self: Sized` to preserve `dyn Hash` object safety
30    /// (const-generic methods cannot be called on trait objects).
31    #[must_use = "result must be checked"]
32    fn hash_to_array<const N: usize>(&self, msg: &[u8]) -> Result<[u8; N], CryptoError>
33    where
34        Self: Sized,
35    {
36        if N != self.output_len() {
37            return Err(CryptoError::BadInput);
38        }
39        let mut out = [0u8; N];
40        self.hash(msg, &mut out)?;
41        Ok(out)
42    }
43}
44
45/// Incremental (streaming) hash computation.
46///
47/// Feed data in chunks with [`update`](StreamingHash::update), then call
48/// [`finalize`](StreamingHash::finalize) to obtain the digest.
49pub trait StreamingHash: Send {
50    /// Feed additional data into the hash state.
51    fn update(&mut self, data: &[u8]);
52    /// Consume the hasher and write the final digest into `out`.
53    ///
54    /// Returns [`CryptoError::BufferTooSmall`] if `out` is too short.
55    #[must_use = "result must be checked"]
56    fn finalize(self, out: &mut [u8]) -> Result<(), CryptoError>;
57    /// Reset the hasher to its initial state, allowing reuse.
58    fn reset(&mut self);
59}