hsh-digest 0.0.10

General-purpose cryptographic hashing primitives (SHA-2, SHA-3, BLAKE3) — NOT for password storage. Use `hsh::api` for passwords.
Documentation

⚠️ This crate is NOT for password storage. Hashing passwords requires a memory-hard / iteration-hard KDF (Argon2id, scrypt, bcrypt, PBKDF2). For that, use hsh::api::hash — not the primitives here.


Contents

Install · When to use · Quick Start · Algorithm matrix · Streaming vs one-shot · Constant-time compare · Test vectors · Examples · License


Install

[dependencies]
hsh-digest = "0.0.9"

MSRV 1.75 stable.

Feature flags

Feature Status Pulls in Notes
default sha2 sha3 blake3 The sensible defaults
sha2 sha2 0.10 SHA-256, SHA-384, SHA-512 (FIPS 180-4)
sha3 sha3 0.10 SHA3-256, SHA3-384, SHA3-512 (FIPS 202)
blake3 blake3 1.5 BLAKE3-256
k12 🚧 reserved (future) k12 KangarooTwelve / TurboSHAKE128/256 (RFC 9861, Oct 2025)
ascon 🚧 reserved (future) ascon-hash Ascon-Hash256 / Ascon-XOF128 (NIST SP 800-232 Aug 2025)

Disable a default feature to shrink the dependency surface:

hsh-digest = { version = "0.0.9", default-features = false, features = ["sha2"] }

When to use

Yes, use hsh-digest for:

  • Content addressing (Git-style, IPFS-style content hashes).
  • Building blocks for higher-level protocols (Merkle trees, commitment schemes).
  • Pre-processing input for an HMAC or signature scheme.
  • PHC string parsing for non-hsh hashes.

No, don't use hsh-digest for:

  • Password storage. Use hsh::api::hash — it picks a memory-hard KDF and applies constant-time verification.
  • HMAC / KDF / signatures / KEMs. Use the RustCrypto siblings (hmac, hkdf, digest, signatures/*).

ADR-0005 documents the scope boundary: doc/adr/0005-general-hashing-scope.md.


Quick Start

One-shot

use hsh_digest::{Algorithm, hash};

let digest = hash(Algorithm::Sha256, b"hello, world").unwrap();
assert_eq!(digest.len(), 32);

Streaming

use hsh_digest::{Algorithm, Hasher};

let mut hasher = Hasher::new(Algorithm::Blake3).unwrap();
hasher.update(b"hello, ");
hasher.update(b"world");
let digest = hasher.finalize();
assert_eq!(digest.len(), 32);

Algorithm matrix

Variant Output Spec Cargo feature
Algorithm::Sha256 32 B FIPS 180-4 sha2
Algorithm::Sha384 48 B FIPS 180-4 sha2
Algorithm::Sha512 64 B FIPS 180-4 sha2
Algorithm::Sha3_256 32 B FIPS 202 sha3
Algorithm::Sha3_384 48 B FIPS 202 sha3
Algorithm::Sha3_512 64 B FIPS 202 sha3
Algorithm::Blake3 32 B BLAKE3 spec (Aumasson et al., 2020) blake3

All variants implement constant-output-length digests. For variable-length output (SHAKE / TurboSHAKE), see the k12 follow-up feature.

Algorithm::id() returns the standard identifier ("sha256", "sha3-256", "blake3", etc.) for use in PHC strings or protocol headers.


Streaming vs one-shot

Both are equivalent — choose based on whether the input is already in memory:

use hsh_digest::{Algorithm, hash, Hasher};

let oneshot = hash(Algorithm::Sha256, b"hello").unwrap();

let mut streaming = Hasher::new(Algorithm::Sha256).unwrap();
streaming.update(b"hello");
let streamed = streaming.finalize();

assert_eq!(oneshot, streamed);

The streaming API exposes Update semantics for incremental hashing (file-content addressing, network-stream MACing, etc.).


Constant-time compare

use hsh_digest::constant_time_eq;

let a = b"sha256-tag-32-bytes...";
let b = b"sha256-tag-32-bytes...";
assert!(constant_time_eq(a, b));

Wraps [subtle::ConstantTimeEq] so comparing two digest tags doesn't leak the prefix-match length via timing. Use this whenever you compare a computed digest against an expected one (MAC verification, content-hash equality checks).


Test vectors

The crate ships KAT tests (crates/hsh-digest/tests/kat.rs) against:

  • SHA-2 — NIST CAVP byte-test vectors (SHAVS).
  • SHA-3 — NIST CAVP byte-test vectors (SHA3VS).
  • BLAKE3 — project test vectors at blake3-team/BLAKE3/test_vectors.

Run with:

cargo test -p hsh-digest

Examples

See crates/hsh-digest/examples/ for runnable demos:

  • oneshot.rs — minimal hash + hex print.
  • streaming.rs — incremental hashing of a large input.
  • content_addressing.rs — Git-style content-hash workflow.

Run with cargo run -p hsh-digest --example oneshot.


Documentation

Doc What's in it
adr/0005-general-hashing-scope.md Scope decision: re-export only, no KDF / MAC / signature drift

License

Dual-licensed under Apache 2.0 or MIT, at your option.