lib-q-sha3 0.0.2

lib-Q: SHA-3 (FIPS 202), SHAKE, cSHAKE (SP 800-185), TurboSHAKE; no_std-friendly. Raw Keccak digests: lib-q-keccak-digest
Documentation

lib-q-sha3

NIST-aligned SHA-3 (FIPS 202), SHAKE, cSHAKE (SP 800-185), and TurboSHAKE (12-round Keccak as in RFC 9861 KangarooTwelve) for lib-Q. Pre–FIPS raw Keccak fixed digests (Keccak224Keccak512, Keccak256Full) are in the separate crate lib-q-keccak-digest (see ADR 001).

Algorithms

Family Types (crate root) Normative reference
SHA-3 (224–512) Sha3_224Sha3_512 FIPS 202
SHAKE XOF Shake128, Shake256 + readers FIPS 202
cSHAKE XOF CShake128, CShake256 + readers SP 800-185
TurboSHAKE XOF TurboShake128<DS>, TurboShake256<DS> (domain byte DS) IRTF / RFC 9861 (K12); collision strength in type impls
Raw Keccak (not this crate) Keccak224 … / Keccak256Full See lib-q-keccak-digest (pre-FIPS padding; not interoperable with SHA-3)

Which traits to use

  • Fixed-length digest (SHA3-*): implement Digestupdate, finalize into a fixed Output.
  • XOFs (SHAKE, cSHAKE, TurboSHAKE): do not use Digest. Use Update, ExtendableOutput (or ExtendableOutputReset where implemented), and XofReader. These traits are re-exported at the crate root (use lib_q_sha3::{Update, ExtendableOutput, XofReader}). If you also import Digest in the same module, qualify Digest::update or Update::update to avoid method-name ambiguity.
  • cSHAKE customization only (NIST “S” string, empty function name): CustomizedInit::new_customized or the CShake* constructors.

Digest is not implemented for XOFs by design (the digest crate splits fixed vs extendable output APIs).

Prelude

This crate does not provide a prelude module. Imports are kept explicit so security reviews can see exactly which algorithms and traits are in scope. Use the re-exports documented below or use lib_q_sha3::digest::{...} for additional digest traits.

Feature flags

Feature Effect
alloc (default) Enables digest/alloc (e.g. finalize_boxed on XOFs where applicable).
oid (default) OID support for fixed-output types where defined.
zeroize Zeroizes dropped sponge state for supported types (see digest + this crate’s ZeroizeOnDrop impls).
asm ARMv8 Keccak acceleration via lib-q-keccak (not all targets).

no_std: supported with default-features = false; you may need to disable alloc for the leanest build.

Security

  • Output length (XOF): security depends on how many bytes you read; use enough bytes for your collision and preimage profile (see FIPS 202 / SP 800-185 and CollisionResistance on each type in rustdoc).
  • cSHAKE: use distinct function-name and/or customization strings for distinct protocols: both empty degrades to SHAKE (SP 800-185).
  • TurboSHAKE: the const generic DS (domain separator, 0x010x7F) must differ across independent uses to avoid cross-protocol output collisions (see RFC 9861 / Turbot documentation).
  • SHA3-256 vs SHA-256: Sha3_256 and sha3_256 are FIPS 202 SHA3-256 (Keccak sponge with SHA-3 padding). They are not FIPS 180-4 SHA-256 (Merkle–Damgård); outputs and wire formats differ.
  • Keccak vs SHA-3: use lib-q-keccak-digest for pre-FIPS Keccak256 types; they are different from Sha3_256 (different padding).
  • Implementation status: the code targets correct sponge semantics per the referenced standards. Constant-time or side-channel guarantees are not claimed here unless supported by your platform and analysis.
  • Architecture: whether to split non–FIPS-202 Keccak surfaces is recorded in docs/adr/001-keccak-nonfips-surface.md.

Examples

SHA3-256 (Digest)

use hex_literal::hex;
use lib_q_sha3::{Digest, Sha3_256};

let mut hasher = Sha3_256::new();
hasher.update(b"abc");
let hash = hasher.finalize();
assert_eq!(hash, hex!("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"));

One-shot SHA3-256

For a single input slice, sha3_256 hashes in one call. This is SHA3-256 (FIPS 202); it is not SHA-256 (FIPS 180). Prefer Sha3_256 with Digest when you need incremental updates or state serialization.

use hex_literal::hex;
use lib_q_sha3::sha3_256;

let digest = sha3_256(b"abc");
assert_eq!(digest, hex!("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"));

SHAKE128 (XOF)

use hex_literal::hex;
use lib_q_sha3::{ExtendableOutput, Shake128, Update, XofReader};

let mut hasher = Shake128::default();
hasher.update(b"abc");
let mut reader = hasher.finalize_xof();
let mut buf = [0u8; 10];
reader.read(&mut buf);
assert_eq!(buf, hex!("5881092dd818bf5cf8a3"));

cSHAKE256 with customization

use lib_q_sha3::{CShake256, CustomizedInit, ExtendableOutput, Update, XofReader};

let mut h = CShake256::new_customized(b"my application");
h.update(b"message");
let mut out = [0u8; 64];
h.finalize_xof().read(&mut out);

TurboSHAKE128 with domain byte (RFC 9861 style)

use lib_q_sha3::{ExtendableOutput, TurboShake128, Update, XofReader};

const D: u8 = 0x07; // distinct per protocol; see RFC 9861
let mut h = TurboShake128::<D>::default();
h.update(b"data");
let mut out = [0u8; 32];
h.finalize_xof().read(&mut out);

License

Licensed under Apache License, Version 2.0; see the workspace LICENSE file.