Skip to content

mbo/digest: BLAKE3 (all modes), SHAKE128/256 XOFs, native BLAKE2b keying - #230

Merged
helly25 merged 6 commits into
mainfrom
digest/xof-blake3
Jul 4, 2026
Merged

mbo/digest: BLAKE3 (all modes), SHAKE128/256 XOFs, native BLAKE2b keying#230
helly25 merged 6 commits into
mainfrom
digest/xof-blake3

Conversation

@helly25

@helly25 helly25 commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Closes out the remaining mbo/digest charter items (everything except the mh hash work), plus the digest CLI binary.

BLAKE3 (digest_blake3.h)

Constexpr scalar transcription with the full Merkle-tree structure - the incremental chunk-stack algorithm (54 levels, any 64-bit length), single code path for compile time and run time. All three modes:

  • Digest / DigestXof<N> - plain hashing, any output length (root-counter squeeze)
  • DigestKeyed / Algorithm::StreamInitKeyed - native keyed mode (32-byte key)
  • DeriveKey<N> - the KDF mode (two-stage context/material domain separation)

Verification: pinned against the official BLAKE3-team/BLAKE3 test-vector suite - all 35 lengths (every block/chunk/tree-shape boundary through 102400 bytes) x all 3 modes, plus the full 131-byte XOF outputs (proves multi-block squeeze). static_assert compile-time proofs for each mode. NOTICE attribution added (CC0-1.0 OR Apache-2.0 upstream; original transcription from the public spec).

SHAKE128 / SHAKE256 (digest_shake.h)

The FIPS 202 XOFs on the existing Keccak sponge: sha3_internal::Finalize generalized to FinalizeXof (domain byte parameter + squeeze loop permuting between rate-sized blocks; SHA-3 digests are the 0x06 single-block special case - values unchanged). shake128::Digest<N> plus fixed-size Algorithm<N> satisfying the digest concepts (works with Streamer/Hmac). Documented XOF property: different lengths share their prefix. Vectors from hashlib incl. 200-byte outputs crossing both rates.

Native BLAKE2b keying (digest_blake2b.h)

RFC 7693 key block (keys up to 64 bytes) via KeyedInit/DigestKeyed/StreamInitKeyed - BLAKE2 was designed as its own MAC, no HMAC construction needed. Vectors from hashlib: keys of 3/32/64 bytes, empty + block-boundary messages, both digest sizes; chunked streaming == one-shot.

The digest binary (//mbo/digest:digest)

Checksum-style CLI: digest [-a <algorithm>] <file>... prints <hash> <file> lines byte-compatible with sha256sum/shasum (verified against both). -a is the shasum-style short alias for --algorithm (17 algorithms, default sha256), --reverse swaps the columns, - reads stdin, directories are errors (for now). Files are digested in streaming 64-KiB chunks (no whole-file buffering). A bashtest suite covers known answers, -a precedence, --reverse, stdin, multi-file continuation, and all error paths.

Testing

Typed suite extended to 17 algorithms (blake3, shake128<32>, shake256<32> added) x 6 tests each; dedicated BLAKE3 official-vector, SHAKE long-output/prefix, and BLAKE2b-keyed tests; the CLI bashtest. All pass. clang-tidy sweep (repo baseline checks) over mbo/hash + mbo/digest: clean.

Charter status after this: mbo/digest complete. Remaining ideas (not scheduled): cSHAKE/KMAC, HKDF, a --check mode for the CLI.

helly25 added 5 commits July 4, 2026 22:19
…KE2b keying

BLAKE3: constexpr scalar transcription with the full Merkle-tree
structure (chunk stack), all three modes, pinned against the official
test-vector suite (35 lengths x 3 modes + 131-byte XOF outputs) with
compile-time proofs per mode; NOTICE attribution added. SHAKE: generic
FinalizeXof squeeze on the shared Keccak sponge, Digest<N> /
Algorithm<N>. BLAKE2b: RFC 7693 key block via DigestKeyed /
StreamInitKeyed - BLAKE2 is its own MAC.
Checksum-style '<hash>  <file>' lines (sha256sum/shasum format,
byte-compatible), -a/--algorithm selects any of the 17 library
algorithms, --reverse swaps columns, '-' reads stdin, directories are
errors (for now); streaming chunked reads. bashtest covers known
answers, -a precedence, reverse, stdin, multi-file, and all error
paths.
…generated expected files

Same three input files (fox line, multi-block text, empty) hashed under
every algorithm and diffed against testdata/<algorithm>.out generated
with python hashlib / the official blake3 module (never this binary).
A missing expected file fails the matrix, so a new algorithm without
coverage is spotted immediately (same pattern as the diff CLI matrix).
@helly25
helly25 requested a review from Fab-Cat July 4, 2026 22:03
@helly25
helly25 merged commit d6dd2e2 into main Jul 4, 2026
40 checks passed
@helly25
helly25 deleted the digest/xof-blake3 branch July 4, 2026 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants