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}