libvctrl_sha512
Overview
libvctrl_sha512 is a zero‑dependency, #![no_std] Rust crate that provides a complete, production‑ready implementation of the following cryptographic primitives:
- SHA‑512 – FIPS 180‑4 compliant hash function (streaming and one‑shot).
- HMAC‑SHA‑512 – Keyed‑hash message authentication (RFC 2104).
- HKDF‑SHA‑512 – HMAC‑based key derivation (RFC 5869).
- SHA‑384 (optional, enabled by default) – A truncated variant of SHA‑512 with a different initialisation vector, together with its HMAC and HKDF counterparts.
All modules are built on a shared, highly optimised SHA‑512 compression function. The crate is designed for use in embedded systems, WebAssembly, kernels, and any environment where a minimal, auditable, and high‑performance cryptographic library is required. It is a member of the larger libvctrl workspace but has no dependencies on other workspace crates and is fully self‑contained.
Architecture
The library’s design separates the core SHA‑512 engine from the HMAC and HKDF constructions via a macro‑based instantiation pattern. The diagram below illustrates the dependency graph between the public modules and the macro layer.
graph TD
SHA512[sha512::Hash<br/>Core compression,<br/>padding, digest]
HMAC[hmac::HMAC<br/>generated by impl_hmac!]
HKDF[hkdf::HKDF<br/>generated by impl_hkdf!]
SHA384[sha384::Hash<br/>wraps sha512::Hash<br/>with SHA‑384 IV]
HMAC384[sha384::HMAC<br/>impl_hmac! for SHA‑384]
HKDF384[sha384::HKDF<br/>impl_hkdf! for SHA‑384]
SHA512 --> HMAC
HMAC --> HKDF
SHA512 --> SHA384
SHA384 --> HMAC384
HMAC384 --> HKDF384
SHA512 -->|load_be, store_be, verify| UTILS[utils]
style SHA512 fill:#e8e8e8,stroke:#333
style HMAC fill:#d4e6f1,stroke:#333
style HKDF fill:#d4e6f1,stroke:#333
Key architectural decisions:
- Macro‑based code generation – The
impl_hmac!andimpl_hkdf!macros accept any hash type (sha512::Hashorsha384::Hash) and produce a fully functionalHMAC/HKDFstruct. This eliminates code duplication and ensures identical behaviour across the two hash sizes. - SHA‑384 as a thin wrapper –
sha384::Hashinternally uses the full SHA‑512Stateand compression logic, overriding only the initialisation vector and truncating the final 64‑byte digest to 48 bytes. This guarantees that SHA‑384 outputs are exactly the leftmost 384 bits of a SHA‑512 computation performed with the SHA‑384 IV. no_stdcompliance – The entire crate relies only oncore, making it suitable for bare‑metal and WebAssembly targets. No heap allocations are performed; all buffers are stack‑allocated with fixed sizes.- Side‑channel resistance – All verification operations (hash comparison, HMAC tag verification) use a non‑branching, XOR‑accumulation‑based comparison (
utils::verify) that does not leak timing information. A volatile read forces the compiler to emit the comparison as written, preventing dead‑code elimination or short‑circuiting.
SHA‑512 Compression Flow
The following sequence outlines the Merkle‑Damgard construction used for a single message block.
sequenceDiagram
participant Input as Message block (128 bytes)
participant W as Schedule W (16×u64)
participant State as Working state (8×u64)
participant Out as Digest state (8×u64)
Input->>W: load_be into 16 words
W->>State: copy current digest state
loop 80 rounds (4×20)
W->>State: f(i, K[i]) with message schedule expansion
end
State->>Out: add working state to digest state (word-wise wrap)
Out-->>Input: ready for next block
After all full blocks are processed, the final incomplete block is padded with a 1 bit, zeros, and a 128‑bit big‑endian message length, then processed similarly.
HMAC Construction
flowchart LR
K[Key] --> P1["Pad to 128 bytes<br/>or hash if longer"]
P1 --> I[ipad XOR padded key]
P1 --> O[opad XOR padded key]
I --> H1["SHA-512(ipad || message)"]
H1 --> H2["SHA-512(opad || H1)"]
H2 --> MAC[64‑byte tag]
HKDF Two‑Step Derivation
flowchart LR
IKM[Input Key Material] --> EXT(HKDF‑Extract<br/>HMAC‑SHA‑512 with salt as key)
SALT[Optional Salt] --> EXT
EXT --> PRK[64‑byte PRK]
PRK --> EXP(HKDF‑Expand<br/>iterative HMAC with info & counter)
INFO[Info String] --> EXP
EXP --> OKM[Output Key Material]
Core Features
- SHA‑512 (FIPS 180‑4) – Streaming and one‑shot hashing; constant‑time digest verification.
- HMAC‑SHA‑512 (RFC 2104) – One‑shot and incremental MAC generation; automatic key hashing for keys > 128 bytes; constant‑time tag verification.
- HKDF‑SHA‑512 (RFC 5869) – Extract‑then‑expand key derivation; supports arbitrary output lengths up to 16 320 bytes.
- SHA‑384 support – Feature‑gated (
sha384); providessha384::Hash,sha384::HMAC, andsha384::HKDFwith 48‑byte outputs. - Zero external dependencies – Only the
corecrate; noalloc, nostd, no third‑party libraries. no_stdcompatible – Works on bare‑metal, kernels, and WebAssembly.- Constant‑time comparison –
utils::verifyprevents timing side‑channel leakage during all verification operations. - Memory zeroisation – HMAC contexts zero the padded key on drop; hash state can be explicitly cleared with
zeroize(). - Feature flags – Optional SHA‑384 inclusion (
sha384) and code‑size optimisation (opt_size). - Fully documented – Every public item has doc‑comments; all examples are tested as doctests.
Technology Stack
- Language: Rust (edition 2024)
- Frameworks/Libraries: None (pure Rust, core only)
- License: ISC
- Repository: https://github.com/mroczect/libvctrl
Project Structure
libvctrl_sha512/
├── Cargo.toml
├── README.md
├── src/
│ ├── lib.rs # Crate root, macro definitions, public re‑exports
│ ├── sha512.rs # SHA‑512 hasher, state, and block compression
│ ├── sha384.rs # SHA‑384 wrapper (only with feature "sha384")
│ ├── hmac.rs # HMAC‑SHA‑512 instantiated via impl_hmac!
│ ├── hkdf.rs # HKDF‑SHA‑512 instantiated via impl_hkdf!
│ └── utils.rs # Endian helpers, constant‑time verify, constants
├── benches/
│ ├── sha512_bench.rs
│ └── sha384_bench.rs (requires "sha384" feature)
└── tests/ # (integration tests can be placed here)
Getting Started
Prerequisites
- Rust toolchain (stable) version 1.85 or later (edition 2024).
- No external libraries or system dependencies.
Installation
Add the crate to your Cargo.toml:
[]
= "2.0.0"
Feature Flags
| Flag | Default | Description |
|---|---|---|
sha384 |
Yes | Enable SHA‑384, HMAC‑SHA‑384, and HKDF‑SHA‑384. |
opt_size |
No | Prioritise smaller binary size over raw speed. |
Example with default features disabled:
= { = "2.0.0", = false }
Configuration
No environment variables or configuration files are needed. The crate compiles with #![no_std]; it does not require an allocator.
Usage
SHA‑512 Hashing
use Hash;
// One‑shot
let digest = hash;
assert_eq!;
// Streaming
let mut hasher = new;
hasher.update;
hasher.update;
assert_eq!;
// Constant‑time verification
let mut verifier = new;
verifier.update;
assert!;
HMAC‑SHA‑512
use HMAC;
let key = b"super secret";
let msg = b"important data";
// One‑shot
let mac = HMACmac;
// Streaming
let mut hmac = HMACnew;
hmac.update;
hmac.update;
assert_eq!;
// Verify in constant time
assert!;
HKDF‑SHA‑512
use HKDF;
let ikm = b"input key material";
let salt = b"random salt";
let info = b"encryption key";
// Extract
let prk = HKDFextract;
assert_eq!;
// Expand
let mut aes_key = ;
HKDFexpand;
SHA‑384 & Friends
Enable the sha384 feature (on by default) and import from the sha384 module:
use ;
let digest = hash;
assert_eq!;
let mac = HMACmac;
assert_eq!;
let prk = HKDFextract;
assert_eq!;
API Reference / Core Modules
Crate Root
The crate re‑exports the most frequently used types and constants:
| Item | Description |
|---|---|
Hash |
SHA‑512 hasher (sha512::Hash) |
HMAC |
HMAC‑SHA‑512 (hmac::HMAC) |
HKDF |
HKDF‑SHA‑512 (hkdf::HKDF) |
BLOCKBYTES |
SHA‑512 block size (128) |
BYTES |
SHA‑512 output size (64) |
utils Module
Low‑level helpers exposed for advanced use cases.
| Function / Constant | Description |
|---|---|
BLOCKBYTES: usize = 128 |
SHA‑512 block size. |
BYTES: usize = 64 |
SHA‑512 output length. |
load_be(base, offset) -> u64 |
Load a big‑endian u64 from a byte slice. |
store_be(base, offset, x) |
Store a u64 as big‑endian bytes. |
verify(x, y) -> bool |
Constant‑time slice comparison; returns true if x == y. |
sha512 Module – SHA‑512 Hasher
Hash struct
new()– Creates a hasher with the standard SHA‑512 initial vector.update()– Feeds arbitrary bytes; can be called any number of times.finalize()– Pads the message according to FIPS 180‑4 and returns the 64‑byte digest. Consumes the hasher.hash()– One‑shot convenience function.verify()– Finalizes and compares the digest againstexpectedusing constant‑time comparison. Returnstrueon match.zeroize()– Overwrites all internal state with zeros and inserts a compiler fence.
hmac Module – HMAC‑SHA‑512
HMAC struct
mac()– One‑shot HMAC computation. Keys longer than 128 bytes are hashed first.new()– Creates a streaming context; the key is processed immediately.update()– Incrementally feeds input data.finalize()– Produces the 64‑byte authentication tag and consumes the context.finalize_verify()– Finalizes and compares the tag in constant time.verify()– One‑shot verification equivalent tomac+ constant‑time comparison.- The
Dropimplementation zeroes the padded key buffer.
hkdf Module – HKDF‑SHA‑512
HKDF struct (stateless, zero‑sized)
;
extract()– Computes a 64‑byte pseudorandom key (PRK) from salt and input keying material.expand()– Derives output keying material (OKM) of arbitrary lengthout.len().- Panics if
prkis not exactly 64 bytes, or ifout.len() > 16 320(the RFC 5869 maximum).
- Panics if
sha384 Module (feature sha384)
Provides SHA‑384, HMAC‑SHA‑384, and HKDF‑SHA‑384. The API is identical to the SHA‑512 counterparts, but all outputs are 48 bytes.
| Type | Analogue to |
|---|---|
sha384::Hash |
sha512::Hash |
sha384::HMAC |
hmac::HMAC |
sha384::HKDF |
hkdf::HKDF |
Example:
use Hash;
let digest = hash;
assert_eq!;
Testing
Unit Tests and Doctests
Run the full test suite (including all doc examples) with:
Doctests are guaranteed to be accurate; they are compiled and executed as part of the test run. The suite also covers internal edge cases such as HMAC with empty keys, long keys, and HKDF length limits.
Benchmarks
Benchmarks are written using Criterion. To execute them:
Two benchmark suites are included:
sha512_bench– Measures throughput for SHA‑512 and HMAC‑SHA‑512.sha384_bench(requiressha384feature) – Same for SHA‑384.
On a typical x86‑64 machine, the default build hashes tens of megabytes per second. Enabling opt_size trades approximately 16% of throughput for a roughly 75% reduction in code size, making it ideal for embedded targets with tight flash budgets.
Versioning & Stability
This project adheres to Semantic Versioning 2.0.0.
- The public API is considered stable. Any breaking change (removing an item, altering a method signature, changing constant values, or modifying the behaviour of a function in a non‑backward‑compatible way) will result in a major version bump.
- New methods, new trait implementations, or additions to the
sha384module (while keeping existing APIs unchanged) do not constitute breaking changes. - Feature flags (
sha384,opt_size) are additive; removing a feature flag or changing its default status would be a breaking change and will be treated accordingly.
Consult the repository’s changelog for version‑specific notes before upgrading.
Contributing
Contributions are welcome. Please open an issue or a pull request on the GitHub repository. By contributing, you agree that your work will be released under the same ISC license.
For substantial changes, it is recommended to discuss the proposal via an issue first to ensure alignment with the project’s goals.
License
This crate is distributed under the ISC License.
Copyright (c) 2019-2026 Frank Denis
Copyright (c) 2026 mroczect
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Acknowledgements
This library is a fork of Frank Denis’s rust-hmac-sha512. The core cryptographic logic remains unchanged; this version adds SHA‑384 support, HKDF, FIPS‑compliant full‑length padding, comprehensive documentation, benchmarks, and a modular macro‑based structure.