crypt_io/hash/mod.rs
1//! Cryptographic hash functions.
2//!
3//! Three algorithms ship in 0.4.0, exposed through a consistent free-function
4//! API plus matching streaming hashers for inputs that don't fit in memory:
5//!
6//! | Algorithm | One-shot | Streaming | Output | Feature |
7//! |------------|-----------------------|-------------------|--------|---------------|
8//! | BLAKE3 | [`blake3()`] | [`Blake3Hasher`] | 32 B | `hash-blake3` |
9//! | BLAKE3 XOF | [`blake3_long()`] | [`Blake3Hasher`] | N B | `hash-blake3` |
10//! | SHA-256 | [`sha256()`] | [`Sha256Hasher`] | 32 B | `hash-sha2` |
11//! | SHA-512 | [`sha512()`] | [`Sha512Hasher`] | 64 B | `hash-sha2` |
12//!
13//! # Choosing a hash
14//!
15//! Pick **BLAKE3** unless you have a reason not to. It is the fastest
16//! cryptographic hash on every modern platform — typically 4–10× faster
17//! than SHA-256 on x86_64 with `AVX2`, and faster still on the wide vector
18//! units of Apple Silicon. It is also tree-structured and SIMD-friendly,
19//! so very large inputs hash at near-memcpy bandwidth.
20//!
21//! Pick **SHA-256** when you need ecosystem interop — TLS, JWT, Bitcoin,
22//! certificate fingerprints, any spec that names SHA-256 explicitly.
23//!
24//! Pick **SHA-512** when interop demands the wider output (some
25//! certificate authorities, some old protocols) or when running on a
26//! 64-bit machine where SHA-512 happens to be faster than SHA-256 (it
27//! processes 64-bit words natively).
28//!
29//! # No-key, no-MAC
30//!
31//! These functions hash data only. For keyed hashing (BLAKE3 keyed mode,
32//! HMAC-SHA2), see the [`mac`](../mac/index.html) module — that's the
33//! Phase 0.5.0 surface and is the right home for authentication-tag
34//! semantics. Using a raw hash function as a MAC is a security mistake;
35//! we do not expose `Hash::with_key` here for that reason.
36//!
37//! # Example
38//!
39//! ```
40//! # #[cfg(feature = "hash-blake3")] {
41//! use crypt_io::hash;
42//!
43//! let digest = hash::blake3(b"the quick brown fox");
44//! assert_eq!(digest.len(), 32);
45//! # }
46//! ```
47//!
48//! With a streaming hasher:
49//!
50//! ```
51//! # #[cfg(feature = "hash-blake3")] {
52//! use crypt_io::hash::Blake3Hasher;
53//!
54//! let mut h = Blake3Hasher::new();
55//! h.update(b"first chunk");
56//! h.update(b" second chunk");
57//! let digest = h.finalize();
58//! assert_eq!(digest.len(), 32);
59//! # }
60//! ```
61
62#[cfg(feature = "hash-blake3")]
63mod blake3_impl;
64#[cfg(feature = "hash-sha2")]
65mod sha2_impl;
66
67#[cfg(feature = "hash-blake3")]
68pub use self::blake3_impl::{Blake3Hasher, blake3, blake3_long};
69#[cfg(feature = "hash-sha2")]
70pub use self::sha2_impl::{Sha256Hasher, Sha512Hasher, sha256, sha512};
71
72/// Length of a BLAKE3 digest, in bytes. Equal to `32`.
73#[cfg(feature = "hash-blake3")]
74pub const BLAKE3_OUTPUT_LEN: usize = 32;
75
76/// Length of a SHA-256 digest, in bytes. Equal to `32`.
77#[cfg(feature = "hash-sha2")]
78pub const SHA256_OUTPUT_LEN: usize = 32;
79
80/// Length of a SHA-512 digest, in bytes. Equal to `64`.
81#[cfg(feature = "hash-sha2")]
82pub const SHA512_OUTPUT_LEN: usize = 64;