Skip to content

hashing

xero edited this page May 30, 2026 · 1 revision
logo

Hashing

The landing page for every hashing primitive in leviathan-crypto. It frames the three hash families the library ships, helps you pick the right one, and links the API docs, WASM implementation docs, and correctness audits for each.

Table of Contents


Overview

A cryptographic hash function takes an input of any size and produces a fixed-size output called a digest. Even the smallest change to the input produces a completely different digest, which makes hash functions useful for verifying that data has not been tampered with. A hash is one-way: you cannot recover the input from the digest.

leviathan-crypto ships three hash families. Each runs entirely in WebAssembly; the TypeScript layer handles input validation and the JS/WASM boundary and never implements the algorithm.

SHA-2. The default workhorse, standardized in FIPS 180-4 (Secure Hash Standard). SHA-256 is the right choice unless a protocol or threat model tells you otherwise. Six variants ship, plus HMAC and HKDF built on top.

SHA-3. Standardized in FIPS 202 (SHA-3 Standard) and built on the Keccak sponge, a different mathematical foundation from SHA-2. It exists for defense in depth and for the SHAKE extendable-output functions. SP 800-185 (SHA-3 Derived Functions) adds cSHAKE and KMAC on the same sponge.

BLAKE3. A performance-tier tree-mode hash with keyed-hash and key-derivation modes. BLAKE3 is not a NIST-approved primitive. Reach for it for transcripts, content-addressed storage, and KDF-style work where the BLAKE2/BLAKE3 cryptanalytic posture is acceptable. Use SHA-2 or SHA-3 when an approved primitive is mandated.


Choosing a hash

I want to...
Hash data with a sensible default SHA256
Hash with a NIST-approved primitive SHA256, SHA512, or SHA3_256
Hash as fast as possible BLAKE3 (not NIST-approved)
Get length-extension immunity any SHA-3 variant or BLAKE3; SHA-2 is vulnerable, so wrap it in HMAC
Produce variable-length output SHAKE128, SHAKE256, KMACXOF256, or a BLAKE3OutputReader
Authenticate a message with a key HMAC_SHA256 or KMAC256
Derive keys from a shared secret HKDF_SHA256, BLAKE3DeriveKey, or CSHAKE256
Hash a password or passphrase not these. Use Argon2id, see argon2id.md
Hash into a Merkle tree Sha256Tree or Blake3Tree
Seed a CSPRNG accumulator SHA256Hash, SHA3_256Hash, or BLAKE3Hash

SHA-2

The SHA-2 family standardized in FIPS 180-4. Six fixed-output variants ship: SHA-256 and SHA-512 are the primary choices, SHA-384 and SHA-224 are truncated variants for protocol interop, and SHA-512/224 and SHA-512/256 use SHA-512 round logic with truncating IVs. HMAC and HKDF build keyed authentication and key derivation on the same compression functions.

Module Description
sha2.md TypeScript API: SHA256, SHA512, SHA384, HMAC_SHA256, HMAC_SHA384, HMAC_SHA512, HKDF_SHA256, HKDF_SHA512
asm_sha2.md WASM implementation: compression functions, HMAC inner/outer padding

SHA-3 and SP 800-185

The SHA-3 family standardized in FIPS 202: four fixed-output hashes (SHA3-224 through SHA3-512) and two extendable-output functions (SHAKE128, SHAKE256), all built on the Keccak sponge. SP 800-185 adds cSHAKE and KMAC on the same primitive. SHA-3 is not a replacement for SHA-2; both are secure and NIST-standardized. SHA-3 gives you a hash on a different mathematical foundation, so a future weakness in one family does not touch the other.

Module Description
sha3.md TypeScript API: SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256, plus streaming variants (SHA3_256Stream, SHA3_512Stream, SHAKE128Stream, SHAKE256Stream)
kmac.md TypeScript API: CSHAKE128, CSHAKE256, KMAC128, KMAC256, KMACXOF128, KMACXOF256 (SP 800-185)
asm_sha3.md WASM implementation: Keccak permutation (1600-bit state), sponge construction

New streaming classes. The SHA-3 family ships incremental absorb/squeeze classes: SHA3_256Stream, SHA3_512Stream, SHAKE128Stream, and SHAKE256Stream. Feed data in chunks and finalize or squeeze when you are done, so you never hold the whole input in memory.

keccak alias. 'keccak' is an alias for 'sha3'. Same WASM binary, same instance slot; keccakInit() and sha3Init() are interchangeable. The keccak subpath exists for contexts where the Keccak name reads clearer, such as ML-KEM. See init.md §keccak alias.


BLAKE3

A SIMD-only BLAKE3 binding covering all three modes from the BLAKE3 specification (BLAKE3 §2.3, Modes): hash, keyed_hash, and derive_key. Each mode ships a one-shot class and a streaming class. The module is SIMD-only and fails loudly at init() on runtimes without WebAssembly SIMD.

Module Description
blake3.md TypeScript API: BLAKE3, BLAKE3Stream, BLAKE3KeyedHash, BLAKE3KeyedHashStream, BLAKE3DeriveKey, BLAKE3DeriveKeyStream, BLAKE3OutputReader, plus the BLAKE3Hash Fortuna HashFn const
asm_blake3.md WASM implementation: v128-internal compress and lane-parallel compress4 (BLAKE3 §5.3, SIMD), §2.4 chunk machine, §2.5 tree assembly + root finalize, §2.6 XOF squeeze, all three §2.3 modes

Streaming and incremental hashing

When data arrives in chunks or is too large to buffer, use a streaming class instead of a one-shot call. The streaming surface differs by family.

SHA-3. Explicit incremental classes ship for the common variants: SHA3_256Stream, SHA3_512Stream, SHAKE128Stream, and SHAKE256Stream. See sha3.md §Streaming Classes.

BLAKE3. Every mode has a streaming class: BLAKE3Stream, BLAKE3KeyedHashStream, and BLAKE3DeriveKeyStream, plus BLAKE3OutputReader for unbounded XOF reads. See blake3.md.

SHA-2. There is no separate Stream class. The one-shot hash() already streams large inputs through WASM in fixed-size chunks internally, so memory usage stays constant regardless of input size. Do not go looking for a SHA256Stream; call hash() and it handles large inputs for you.


Message authentication

A Message Authentication Code (MAC) combines a secret key with a hash to produce a tag that proves both integrity and authenticity. The library ships two keyed constructions.

HMAC. RFC 2104 HMAC over SHA-2: HMAC_SHA256, HMAC_SHA384, and HMAC_SHA512. HMAC has a formally proven security reduction and is the correct MAC even where length extension is not a concern. It is the default choice.

KMAC. The Keccak-based MAC from SP 800-185: KMAC128 and KMAC256, with built-in customization-string domain separation and a constant-time verify path. Use KMAC when you want a MAC on the SHA-3 family or defense in depth against a future weakness in SHA-2.

For the full decision between cSHAKE, KMAC, and HMAC, see kmac.md §When to Use cSHAKE vs KMAC vs HMAC.


Key derivation

Deriving keys from a shared secret needs a Key Derivation Function (KDF), not a raw hash. Three options ship.

HKDF. RFC 5869 extract-then-expand over SHA-2: HKDF_SHA256 and HKDF_SHA512. This is the workhorse KDF used internally by the stream and ratchet layers.

BLAKE3 derive_key. BLAKE3DeriveKey is a two-pass KDF with a domain-separating context string, suitable for application key derivation.

cSHAKE. CSHAKE128 and CSHAKE256 give a customized XOF without keying, for domain-separated output expansion under a context tag.


Extendable-output functions

An extendable-output function (XOF) produces output of any length you ask for rather than a fixed-size digest. Useful for key stretching, nonce generation, and deriving several values from one stream.

SHAKE. SHAKE128 and SHAKE256 are the FIPS 202 XOFs. The only constraint is outputLength >= 1.

KMACXOF. KMACXOF128 and KMACXOF256 are KMAC in XOF mode, for variable-length keyed output.

BLAKE3 XOF. A BLAKE3OutputReader squeezes unbounded output from any BLAKE3 mode.


Security notes

Important

Read these before using any hash. Misusing hash functions is one of the most common sources of security vulnerabilities.

  • Hashing is not encryption. A hash is one-way. You cannot recover the input from a digest. To protect data so it can be read later, use encryption, see serpent.md or XChaCha20Poly1305.

  • Never hash passwords with a plain hash. SHA-2, SHA-3, and BLAKE3 are all fast by design, which is exactly wrong for password storage. Use a memory-hardened function like Argon2id, see argon2id.md.

  • SHA-2 is vulnerable to length extension. Never build a MAC as hash(secret || message). An attacker who sees SHA256(secret || message) can extend it without knowing the secret. SHA-3 and BLAKE3 are immune by construction, but HMAC is still the proven way to build a MAC. Use HMAC_SHA256 or KMAC256.

  • Always compare tags in constant time. Verifying a MAC tag with === leaks timing information that lets an attacker forge a tag one byte at a time. Use constantTimeEqual, which always compares every byte.


Related uses

Hashes feed several higher-level constructions in the library.

Merkle trees. The transparency-log substrate hashes leaves and nodes with Sha256Tree or Blake3Tree. See merkle.md.

Fortuna CSPRNG. The Fortuna accumulator takes a pluggable hash: SHA256Hash, SHA3_256Hash, or BLAKE3Hash. See fortuna.md.


Cross-references

Document Description
sha2_audit.md SHA-256/512/384 correctness, HMAC and HKDF composition, constant verification
sha3_audit.md Keccak permutation correctness, step verification, round constant derivation
blake3_audit.md BLAKE3 tree-mode correctness, compress / compress4 equivalence, chunk machine, XOF snapshot integrity
hmac_audit.md HMAC construction, key processing, RFC 4231 vector coverage
hkdf_audit.md HKDF extract-then-expand, info field domain separation, stream key derivation
lexicon.md Glossary of cryptographic terms: digest, sponge, XOF, MAC, KDF
architecture.md Repository structure, build and CI, WASM modules, public API, test suite, and security posture

Leviathan-Crypto Wiki

Leviathan logo

Getting Started

Authenticated Encryption

Digital Signatures

Ciphers

  • Serpent-256 TypeScript | WASM
    • Serpent, SerpentCtr, SerpentCbc, SerpentGenerator
  • ChaCha20 TypeScript | WASM
    • ChaCha20, Poly1305, ChaCha20Poly1305, XChaCha20Poly1305, ChaCha20Generator
  • AES TypeScript | WASM
    • AES, AESCbc, AESCtr, AESGCM, AESGCMSIV, AESGenerator

Signature Primitives

  • ML-DSA TypeScript | WASM
    • pure (FIPS 204): MlDsa44, MlDsa65, MlDsa87
    • pure-mode suites: MlDsa44Suite, MlDsa65Suite, MlDsa87Suite
    • prehash suites: MlDsa44PreHashSuite, MlDsa65PreHashSuite, MlDsa87PreHashSuite
  • SLH-DSA TypeScript | WASM
    • pure (FIPS 205): SlhDsa128f, SlhDsa192f, SlhDsa256f
    • pure-mode suites: SlhDsa128fSuite, SlhDsa192fSuite, SlhDsa256fSuite
    • prehash suites: SlhDsa128fPreHashSuite, SlhDsa192fPreHashSuite, SlhDsa256fPreHashSuite
  • Ed25519 TypeScript | WASM
    • Ed25519 (pure + Ed25519ph), Ed25519Suite, Ed25519PreHashSuite
  • ECDSA-P256 TypeScript | WASM
    • EcdsaP256 (hedged + RFC 6979), EcdsaP256Suite
    • DER codec: ecdsaSignatureToDer, ecdsaSignatureFromDer, encodeEcPrivateKey, decodeEcPrivateKey, pointDecompress
  • Hybrid composites PQ-only | Classical+PQ
    • PQ-only: MlDsa44SlhDsa128fSuite, MlDsa65SlhDsa192fSuite, MlDsa87SlhDsa256fSuite
    • Classical+PQ: MlDsa44Ed25519Suite, MlDsa65Ed25519Suite, MlDsa44EcdsaP256Suite, MlDsa65EcdsaP256Suite

Key Agreement

Post-Quantum

  • ML-KEM TypeScript | WASM
    • MlKem512, MlKem768, MlKem1024
  • Ratchet (SPQR)
    • KDFChain, ratchetInit, kemRatchetEncap, kemRatchetDecap, RatchetKeypair, SkippedKeyStore

Hashing

  • Hashing overview
  • SHA-2 TypeScript | WASM
    • SHA256, SHA384, SHA512, SHA224, SHA512_224, SHA512_256
    • HMAC_SHA256, HMAC_SHA384, HMAC_SHA512, HKDF_SHA256, HKDF_SHA512
  • SHA-3 TypeScript | WASM
    • SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256
  • BLAKE3 TypeScript | WASM
    • BLAKE3, BLAKE3Stream, BLAKE3KeyedHash, BLAKE3KeyedHashStream
    • BLAKE3DeriveKey, BLAKE3DeriveKeyStream, BLAKE3OutputReader, BLAKE3Hash
  • KMAC
    • CSHAKE128, CSHAKE256, KMAC128, KMAC256, KMACXOF128, KMACXOF256

Transparency Log

  • Merkle
    • MerkleVerifier, MerkleLog
    • SignedLog, Sha256Tree, Blake3Tree, MemoryStorage

Utilities

  • Fortuna CSPRNG
    • Fortuna, SerpentGenerator, ChaCha20Generator, AESGenerator, SHA256Hash, SHA3_256Hash, BLAKE3Hash
  • Utils TypeScript | WASM
    • constantTimeEqual, randomBytes, wipe, encoding helpers
  • TypeScript interfaces
    • Hash, KeyedHash, Blockcipher, Streamcipher, AEAD, Generator, HashFn

Project

Reference

Clone this wiki locally