SLH-DSA (FIPS 205)
Stateless Hash-Based Digital Signature Algorithm
Overview
SLH-DSA is the NIST-standardized stateless hash-based digital signature algorithm defined in FIPS 205. Formerly known as SPHINCS+, SLH-DSA provides digital signatures whose security relies solely on the security of the underlying hash function — no lattice assumptions, no number-theoretic assumptions.
This makes SLH-DSA the most conservative post-quantum signature choice: even if lattice-based assumptions (used by ML-DSA and Falcon) were broken, SLH-DSA would remain secure as long as its hash function is secure. The tradeoff is larger signatures compared to lattice-based schemes.
SLH-DSA uses a hypertree of many-time XMSS trees, each containing one-time WOTS+ signatures. A FORS (Forest of Random Subsets) few-time signature scheme signs the message, and the hypertree authenticates the FORS public key.
Specifications
SLH-DSA defines parameter sets across two hash families (SHA-2 and SHAKE) and two speed profiles (“f” for fast signing, “s” for small signatures).
All twelve FIPS 205 parameter sets are in the release catalog (documents/public-release/catalog.json, profiles slh-dsa-sha2-* and slh-dsa-shake-*); the sizes below are the catalog’s, which match FIPS 205 Table 2.
SHA-2 based variants:
| Parameter Set | NIST Level | Public Key (bytes) | Secret Key (bytes) | Signature (bytes) |
|---|---|---|---|---|
| SLH-DSA-SHA2-128s | 1 | 32 | 64 | 7856 |
| SLH-DSA-SHA2-128f | 1 | 32 | 64 | 17088 |
| SLH-DSA-SHA2-192s | 3 | 48 | 96 | 16224 |
| SLH-DSA-SHA2-192f | 3 | 48 | 96 | 35664 |
| SLH-DSA-SHA2-256s | 5 | 64 | 128 | 29792 |
| SLH-DSA-SHA2-256f | 5 | 64 | 128 | 49856 |
SHAKE based variants:
| Parameter Set | NIST Level | Public Key (bytes) | Secret Key (bytes) | Signature (bytes) |
|---|---|---|---|---|
| SLH-DSA-SHAKE-128s | 1 | 32 | 64 | 7856 |
| SLH-DSA-SHAKE-128f | 1 | 32 | 64 | 17088 |
| SLH-DSA-SHAKE-192s | 3 | 48 | 96 | 16224 |
| SLH-DSA-SHAKE-192f | 3 | 48 | 96 | 35664 |
| SLH-DSA-SHAKE-256s | 5 | 64 | 128 | 29792 |
| SLH-DSA-SHAKE-256f | 5 | 64 | 128 | 49856 |
Core operations:
KeyGen()— Generate a signing key pairSign(sk, msg)— Produce a signature over a messageVerify(pk, msg, sig)— Verify a signature against a public key and message
The “f” variants prioritize fast signing at the cost of larger signatures. The “s” variants produce smaller signatures but take longer to sign.
Security
- Security notion: EUF-CMA (existential unforgeability under chosen-message attack)
- Hardness assumption: Security of the underlying hash function only (SHA-256 or SHAKE-256)
- No algebraic assumptions: Unlike lattice-based schemes, SLH-DSA does not rely on Module-LWE, NTRU, or any structured mathematical problem
- Conservative choice: If future cryptanalysis weakens lattice assumptions, SLH-DSA remains unaffected
- Stateless: Unlike XMSS (RFC 8391), SLH-DSA does not require signers to maintain state between signing operations, eliminating a class of implementation errors
Hardware Acceleration
None. MetaMUI has no AVX2, NEON or SHA-NI code for SLH-DSA: the Rust and C implementations,
including the SHA-2 and SHAKE code they call, are portable scalar code. A binding that takes its
hash from the platform (for example the JVM’s MessageDigest) runs whatever that platform runs.
No performance claim is made.
Platform Support
SLH-DSA is implemented across all 10 platforms in the MetaMUI suite:
| Platform | Language | Implementation Path |
|---|---|---|
| Native | C | metamui-crypto-c/ |
| Systems | Rust | metamui-crypto-rust/ |
| Backend | Go | metamui-crypto-go/ |
| Data Science | Python | metamui-crypto-python/ |
| JVM | Java | metamui-crypto-java/ |
| JVM/Android | Kotlin | metamui-crypto-kotlin/ |
| .NET | C# | metamui-crypto-csharp/ |
| Apple | Swift | metamui-crypto-swift/ |
| Web | TypeScript | metamui-crypto-typescript/ |
| Browser | — | Not claimed for this release: the SLH-DSA npm packages are Node-only (no --target web build). The browser claim covers Falcon and ML-KEM only. |
API Example
// Key generation
let (pk, sk) = slh_dsa_shake_128f::keygen(&mut rng);
// Signing
let message = b"Document to be signed";
let signature = slh_dsa_shake_128f::sign(&sk, message);
// Verification
let is_valid = slh_dsa_shake_128f::verify(&pk, message, &signature);
assert!(is_valid);
Test Vectors
- Coverage: KeyGen, Sign, Verify for SHA-2 and SHAKE variants
- Source: NIST ACVP test vector format
References
- FIPS 205 — Stateless Hash-Based Digital Signature Standard. National Institute of Standards and Technology (2024). https://csrc.nist.gov/pubs/fips/205/final
- SPHINCS+ — Aumasson, J.-P., Bernstein, D.J., Dobraunig, C., et al. SPHINCS+ Specification. https://sphincs.org/
- NIST PQC Standardization — Post-Quantum Cryptography project. https://csrc.nist.gov/projects/post-quantum-cryptography