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