Skip to main content

cryptography/hash/
mod.rs

1//! Hash functions, XOFs, and message-authentication helpers.
2//!
3//! The in-tree hash families currently cover:
4//!
5//! - RFC 1321 (`Md5`)
6//! - FIPS 180-4 (`Sha1`, SHA-2)
7//! - FIPS 202 (`Sha3_*`, `Shake*`)
8//! - RIPEMD-160 (`Ripemd160`)
9//! - FIPS 198-1 / RFC 2104 (`Hmac<H>`)
10//! - RFC 5869 (`Hkdf<H>`)
11//!
12//! The shared traits in this module are the glue that lets one keyed
13//! construction (`Hmac<H>`) work across multiple named hash families without
14//! reimplementing the HMAC state machine for each one.
15
16/// Minimal trait for fixed-output hash functions that can back HMAC.
17///
18/// SHA-1 and SHA-2 implementations behind this trait are Merkle-Damgard style
19/// hashes, so their raw outputs inherit the usual length-extension caveat.
20/// Use `Hmac<H>` for keyed authentication, or prefer SHA-3 / SHAKE when you
21/// specifically want sponge-based hashing semantics.
22pub trait Digest: Clone {
23    /// Byte-oriented block size used by the Merkle-Damgard or sponge API.
24    ///
25    /// For SHA-3, this is the Keccak rate in bytes, which is the block size
26    /// used by HMAC with the SHA-3 family.
27    const BLOCK_LEN: usize;
28    /// Digest size in bytes.
29    const OUTPUT_LEN: usize;
30
31    /// Create a fresh hashing state.
32    fn new() -> Self;
33
34    /// Absorb more input bytes.
35    fn update(&mut self, data: &[u8]);
36
37    /// Finalize the hash into `out`.
38    ///
39    /// The default one-shot `digest(...)` helper below allocates. Prefer the
40    /// concrete types' inherent `digest(...)` methods when you know the hash at
41    /// compile time and want a fixed-size array.
42    fn finalize_into(self, out: &mut [u8]);
43
44    /// Finalize in place and wipe the internal state.
45    ///
46    /// This exists primarily so keyed constructions such as `Hmac<H>` can
47    /// consume intermediate hash state without leaving key-derived chaining
48    /// values behind in memory.
49    fn finalize_reset(&mut self, out: &mut [u8]);
50
51    /// Best-effort zeroization of the internal state.
52    fn zeroize(&mut self);
53
54    /// Convenience helper for one-shot hashing.
55    #[must_use]
56    fn digest(data: &[u8]) -> Vec<u8> {
57        let mut h = Self::new();
58        h.update(data);
59        let mut out = vec![0u8; Self::OUTPUT_LEN];
60        h.finalize_into(&mut out);
61        out
62    }
63}
64
65/// Minimal trait for extendable-output functions.
66///
67/// The caller absorbs input incrementally and then squeezes as many output
68/// bytes as needed. The first `squeeze(...)` call transitions the XOF into
69/// output mode; later calls continue the same output stream.
70pub trait Xof {
71    /// Absorb more input bytes.
72    fn update(&mut self, data: &[u8]);
73
74    /// Finalize if needed and squeeze more output.
75    ///
76    /// The first call transitions the XOF from absorb mode to squeeze mode.
77    /// Subsequent calls continue producing output from the same stream. This
78    /// models sponge-based XOFs such as SHAKE, where the caller may not know
79    /// the required output length up front.
80    fn squeeze(&mut self, out: &mut [u8]);
81}
82
83pub mod hkdf;
84pub mod hmac;
85pub mod md5;
86pub mod ripemd160;
87pub mod sha1;
88pub mod sha2;
89pub mod sha3;