1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! # SHA‑512 Hasher Implementation
//!
//! This module provides [`Sha512Hasher`], a concrete [`Hasher`] that produces
//! 64‑byte digests using the SHA‑512 algorithm from the [`libvctrl_sha512`] crate.
//!
//! ## Why SHA‑512?
//!
//! SHA‑512 is the standard choice for `libvctrl` for several reasons:
//!
//! - **Strong security** – 256‑bit collision resistance and 512‑bit preimage
//! resistance. Even against quantum adversaries (Grover’s algorithm), the
//! effective security remains above 128 bits.
//! - **64‑bit friendly** – The compression function operates on 64‑bit words
//! and is highly optimised for modern 64‑bit processors (x86‑64, ARM64).
//! On these platforms, SHA‑512 is often faster than SHA‑256.
//! - **Standardised** – FIPS 180‑4 compliant. It is widely trusted in version
//! control systems (Git), digital signatures, and key derivation (HKDF).
//! - **Zero‑dependency implementation** – The `libvctrl_sha512` crate is a
//! pure‑Rust, `#![no_std]` implementation that has been audited. It adds
//! minimal supply‑chain risk.
//!
//! ## Usage
//!
//! The hasher is stateless and implements the [`Hasher`] trait, so it can be
//! used wherever a generic hasher is required. Because it contains no state,
//! it can be freely copied and shared.
//!
//! ```rust
//! use libvctrl_core::hash::Sha512Hasher;
//! use libvctrl_handler::Hasher;
//!
//! let hasher = Sha512Hasher;
//! let hash = hasher.hash(b"hello world");
//! assert_eq!(hash.as_bytes().len(), 64);
//! ```
//!
//! ## Compatibility with `libvctrl_sha512` v0.3.0
//!
//! This implementation calls [`libvctrl_sha512::Hash::hash`], which computes a
//! SHA‑512 digest and returns a `[u8; 64]`. The API has been stable since v0.1.0
//! and is fully compatible with v0.3.0.
//!
//! ## Performance
//!
//! `Sha512Hasher` delegates directly to the optimised SHA‑512 routine in
//! `libvctrl_sha512`. For benchmarks, see the `libvctrl_sha512` crate.
//! Hashing 1 KB of data takes a few microseconds on a modern x86‑64 CPU.
//! The `opt_size` feature in `libvctrl_sha512` can reduce binary size by about
//! 75% at a cost of roughly 16% lower throughput.
//!
//! ## Security
//!
//! The digest is produced by a FIPS‑compliant implementation. No `unsafe` code
//! is used. Constant‑time equality checking for hashes is provided by the
//! [`Hash`] type from `libvctrl_handler` and the [`verify`](libvctrl_sha512::utils::verify)
//! function.
//!
//! The `expect` call in [`hash`](Hasher::hash) will never panic because
//! SHA‑512 always produces exactly 64 bytes, a property verified by the
//! test vectors from FIPS 180‑4 and RFC 6234.
use ;
use Hash as Sha512Hash;
/// A [`Hasher`] implementation using SHA‑512.
///
/// This hasher is stateless (no interior state) and can be freely copied and
/// shared. Each call to [`hash`](Hasher::hash) produces a new 64‑byte digest
/// independently.
///
/// # Example
///
/// ```rust
/// use libvctrl_core::hash::Sha512Hasher;
/// use libvctrl_handler::Hasher;
///
/// let hasher = Sha512Hasher;
/// let digest = hasher.hash(b"some data");
/// assert_eq!(digest.as_bytes().len(), 64);
/// ```
///
/// # Why no streaming API?
///
/// The [`Hasher`] trait is intentionally minimal: a single `hash` method
/// that takes a complete byte slice. This is sufficient for version control
/// objects, which are always fully loaded before hashing. If you need
/// streaming hashing (e.g., for large files), you can build your own wrapper
/// that uses the streaming API of `libvctrl_sha512::Hash` directly and then
/// converts the result to a [`Hash`].
;