QNSP

Blog · 2026-06-01 · 10 min read

SLH-DSA Explained: Hash-Based Signatures (SPHINCS+) for Your Most Long-Lived Roots of Trust

A plain-English guide to SLH-DSA (FIPS 205, formerly SPHINCS+): why a stateless hash-based signature whose security rests only on hash functions is the most conservative post-quantum hedge, the 12 parameter sets and their large/slow signatures, when to choose it over ML-DSA for code-signing roots, firmware, and CA hierarchies you can't re-key, and how QNSP supports it across all crypto-policy tiers.

SLH-DSASPHINCS+hash-based signaturesFIPS 205post-quantum cryptographyQNSP
By Christopher Frost, Founder, CUI LABS PTE. LTD.

The signature you reach for when you can never re-key

If you have read our explainers on ML-KEM (key exchange) and ML-DSA (the general-purpose post-quantum signature), this post completes the trio. ML-DSA is the default you will use for almost everything you sign. SLH-DSA is the one you reach for when the artifact you are signing has to stay trustworthy for a very long time and the signing root is something you genuinely cannot afford to rotate — a code-signing root, a firmware-update key burned into a fleet of devices, a CA hierarchy, or an archival audit log that must still verify decades from now.

SLH-DSA — the Stateless Hash-based Digital Signature Algorithm — was finalized by NIST as FIPS 205 in August 2024, the same day as FIPS 203 (ML-KEM) and FIPS 204 (ML-DSA). It was previously known as SPHINCS+. What makes it special is not speed or compactness — it is neither fast nor compact. What makes it special is the foundation its security rests on, and why that foundation is the most conservative bet you can place in post-quantum cryptography.

This post is about that bet: what hash-based signing actually is, why "stateless" is the word that matters, what the signatures cost you in size and speed, and exactly when the trade is worth it. QNSP, the flagship post-quantum cryptography platform from CUI Labs, supports SLH-DSA across every crypto-policy tier — we will show where at the end.

What "hash-based" means — and why it is the conservative choice

Most of the post-quantum signature world is lattice-based. ML-DSA's security reduces to the hardness of Module-LWE and Module-SIS — lattice problems that, as far as anyone knows today, no efficient quantum algorithm solves. That is a well-studied assumption, but it is still a specific mathematical assumption about lattices.

SLH-DSA makes a different and narrower bet. Its security reduces solely to the security of the underlying hash function — concretely, the difficulty of finding preimages and collisions in SHA-2 or SHAKE. There is no lattice assumption, no number-theoretic assumption, nothing exotic underneath. If the hash function is secure, the signature scheme is secure; that is essentially the entire argument.

That is what makes SLH-DSA the most conservative option NIST standardized. Hash functions are among the oldest, most scrutinized, and best-understood primitives in cryptography, and Grover's algorithm only gives a quadratic speedup against them — which a sufficiently large output size absorbs comfortably. So when you sign something with SLH-DSA, you are betting on hash-function security and nothing else. For a root of trust that has to survive a future where some lattice assumption might one day weaken, that is a deliberate belt-and-suspenders posture.

Rule of thumb: ML-DSA bets on lattice hardness; SLH-DSA bets only on hash-function security. For the signing roots you most need to outlive any single mathematical surprise, the narrower bet is the safer one.

How it works, in plain terms

You do not need the full construction to use SLH-DSA well, but the shape explains its trade-offs. SLH-DSA stacks three classic ideas. At the bottom is WOTS+, a one-time signature built purely from hash chains — secure, but each key can safely sign only once. To sign more than once, you build a Merkle tree of many one-time keys and publish only the root as your public key; a signature then includes the authentication path proving a given leaf belongs under that root.

A single Merkle tree large enough to sign realistic volumes would be impractical to generate, so SLH-DSA uses a hypertree — a tree of trees — where upper layers certify the roots of lower layers. Finally, the actual message is signed not by a one-time key directly but by FORS (Forest Of Random Subsets), a few-time signature that tolerates the way leaves get selected. The whole assembly is glued together with hashes, which is why the security argument collapses neatly down to "is the hash function secure?"

The practical consequence of all that structure: a signature has to carry one-time signature material plus authentication paths through the hypertree. That is why SLH-DSA signatures are large — kilobytes to tens of kilobytes — and why signing takes milliseconds rather than the microseconds a lattice scheme manages.

"Stateless" is the word that matters

There is an older family of hash-based signatures — LMS and XMSS (RFC 8554 and RFC 8391) — that is also hash-based and also quantum-resistant. The crucial difference is that those schemes are stateful: each private key contains a counter of which one-time keys have already been used, and the signer must reliably persist and advance that counter on every single signature.

Stateful signing is operationally dangerous. If you ever reuse a one-time key — because a backup was restored, a key was cloned to two hosts, a VM was rolled back, or the counter was not flushed before a crash — the security guarantee can collapse and signatures can become forgeable. Getting that state management exactly right across redundancy, failover, and disaster recovery is genuinely hard, which is why NIST's separate guidance on stateful hash-based signatures (SP 800-208) is cautious about their use.

SLH-DSA removes that hazard entirely. It is stateless: there is no counter to maintain, no "have I used this leaf before?" bookkeeping, no way for a restore or a clone to silently break the scheme. You hold a key, you sign, and correctness does not depend on durable mutable state. For a root of trust replicated across regions and recovery sites, that property alone is often the deciding factor.

Stateful hash-based signatures (LMS / XMSS) can be catastrophically broken by one-time-key reuse — a restored backup or a cloned key is enough. SLH-DSA is stateless, so there is no counter to lose and no reuse hazard to manage.

The parameter sets: 12 ways to trade size for speed

FIPS 205 defines twelve parameter sets, covering every combination of two hash families, three security categories, and two optimization targets: {SHA-2, SHAKE} × {128, 192, 256 bits} × {fast, small}. The hash choice (SHA-2 vs SHAKE) is about your platform — SHAKE gives a constant-time extendable-output function for environments where hardware SHA-2 acceleration is not available, at otherwise identical security.

The category (128 / 192 / 256) sets the security level, and the f/s suffix is the central trade-off. The "s" (small) variants minimize signature size at the cost of slower signing; the "f" (fast) variants speed up signing in exchange for noticeably larger signatures. There is no free lunch — you are choosing where to spend.

Concrete numbers from the standard make the cost vivid. SLH-DSA-SHA2-128s produces roughly 7,856-byte signatures; the fast variant SLH-DSA-SHA2-128f roughly 17,088 bytes. At the top end, the level-5 SLH-DSA-SHA2-256s is around 29,792 bytes and SLH-DSA-SHA2-256f around 49,856 bytes. Compare that to ML-DSA, whose signatures run roughly 2,400 to 4,600 bytes: SLH-DSA signatures are an order of magnitude larger or more.

Signature sizes from FIPS 205: SLH-DSA-SHA2-128s ~7,856 B; 128f ~17,088 B; 256s ~29,792 B; 256f ~49,856 B. These are the per-parameter-set sizes published on the QNSP /algorithms/slh-dsa page. Public keys are tiny by comparison — 32 bytes at level 1, 64 bytes at level 5.

The real cost: large signatures and slow signing

It is worth being honest about why you would not just use SLH-DSA everywhere. The signatures are the largest of any FIPS-finalized post-quantum scheme — between roughly 8 KB and 50 KB depending on the parameter set — and signing is the slowest, measured in milliseconds rather than microseconds.

For a high-volume signing path — say JWTs minted on every authenticated API call — that is a poor fit: the per-request size and latency overhead would dominate. That is exactly why ML-DSA, and specifically the compact ML-DSA-44, is the right default for token signing, while SLH-DSA is not.

But for the use cases SLH-DSA is meant for, the cost barely registers. You sign a firmware image or a release artifact rarely — once per build, not once per request — so signing latency is irrelevant. The signature ships alongside a multi-megabyte payload, so an extra 30 KB is noise. And verification, which happens far more often than signing, is comparatively cheap. The economics flip entirely depending on how often you sign and how long the result must be trusted.

When to choose SLH-DSA over ML-DSA

The decision comes down to two questions: how long must this signature stay trustworthy, and how often will you sign with this key? SLH-DSA wins precisely when the answer is "a very long time" and "rarely." Here are the cases where it earns its size:

  • Code-signing roots and software-update keys — the key that signs your firmware or release packages is long-lived, hard to rotate across a deployed fleet, and a forged signature ships malware that passes verification. The conservative hash-only assumption is worth the bytes.
  • CA hierarchies and root certificates you cannot easily re-key — a root that anchors a trust chain for years to decades benefits from the narrowest possible security assumption.
  • Decades-long archival signatures — legal, medical, and government records that must remain verifiable far into the future, long after today's lattice analysis has had time to evolve.
  • Government and highest-assurance policy — where a mandate calls for FIPS-finalized, conservative-assumption algorithms, SLH-DSA is the hash-based answer.
  • Independent cross-verification of ML-DSA — because SLH-DSA rests on a completely different assumption than lattice signatures, pairing the two gives genuine algorithm diversity: a weakness in one family does not touch the other.

ML-DSA, SLH-DSA, Falcon: how the three fit together

NIST standardized more than one signature scheme on purpose — algorithm diversity is a hedge against a future weakness in any single mathematical family. The clean way to think about the finalized and forthcoming signatures:

ML-DSA (FIPS 204) is the general-purpose default: lattice-based, fast, compact enough for high-volume signing, and the scheme you will use for the overwhelming majority of signatures. SLH-DSA (FIPS 205) is the conservative hedge: hash-based, large and slow, but resting on the narrowest assumption — reserved for the long-lived roots you most need to protect. Falcon, being standardized as FN-DSA in the draft FIPS 206, is also lattice-based and produces notably more compact signatures than ML-DSA, but it carries delicate floating-point implementation requirements and — as of this writing — is still a draft, not a finalized standard, so it should be treated as forthcoming rather than ready for unconditional reliance.

In practice the rule is simple: ML-DSA by default; SLH-DSA where you want hash-only conservatism for a long-lived root; Falcon/FN-DSA only where signature size is the binding constraint and you are comfortable tracking draft status. The two finalized schemes are deliberately complementary, and a serious migration uses both.

How QNSP supports SLH-DSA

QNSP — the flagship post-quantum cryptography platform from CUI Labs — supports SLH-DSA across all twelve parameter sets, available from the default crypto-policy tier upward, so you are not paying for an enterprise plan just to sign a firmware root with hash-based cryptography. SLH-DSA is one of the 63 signature algorithms in QNSP's 90-algorithm catalog (27 KEMs + 63 signatures across 14 families), so it sits alongside ML-DSA and the rest rather than as a bolt-on.

Where SLH-DSA becomes mandatory is in the hardened policy tiers. The strict tier admits the level-5 SLH-DSA-256 variants (both SHA-2 and SHAKE, fast and small) into its allowed signature set; the maximum and government tiers narrow to the level-5 fast variants (SLH-DSA-SHA2-256f and SLH-DSA-SHAKE-256f). The government tier in particular admits only FIPS-finalized signatures — ML-DSA-87 and SLH-DSA-256f — and explicitly excludes the draft FIPS 206 Falcon, because a government deployment should not depend on a standard that has not been finalized.

This is wired behavior enforced by the platform, not a documentation claim: crypto-policy tier is enforced by tenant-service and KMS, and the CBOM crypto-inventory service surfaces where each signature algorithm — including SLH-DSA roots — is actually used, emitted as CycloneDX 1.5 with the cryptographic-properties extension.

Verifiable implementation, not just claims

Consistent with CUI Labs' evidence-first posture, QNSP's SLH-DSA support runs through dual-provider cross-verification: the native-C liboqs library (primary) and the pure-JavaScript @noble/post-quantum implementation (secondary). On the maximum and government tiers, cross-verification is mandatory — operations are exercised against two independent implementations so a deviation in one provider is caught rather than silently trusted, which is exactly the kind of independent check a long-lived root deserves.

Conformance is published rather than asserted. QNSP's public NIST ACVP conformance evidence lives at /verify/conformance, bound to a SHA-3-256 tamper digest that is regenerated each release. For SLH-DSA specifically, the noble provider passes all 120 keyGen ACVP test vectors across all twelve parameter sets; the liboqs keyGen vectors are deferred pending the same upstream derandomized-keypair binding gap that affects ML-DSA, and that status is reported plainly on the page rather than glossed over.

A note on what this evidence is and is not: QNSP runs and publishes the official NIST ACVP test vectors. That is verification against published NIST standards — but it is not a NIST endorsement, certification, or CAVP/CMVP validation, and we do not claim otherwise. The point of /verify/conformance is that you can check the vectors yourself rather than take any vendor's word for it.

Public conformance at /verify/conformance (bound to a SHA-3-256 digest, regenerated each release): the noble provider passes all 120 SLH-DSA keyGen ACVP test vectors across all 12 parameter sets; liboqs keyGen is deferred and reported as such. SLH-DSA runs through dual-provider cross-verification (liboqs + @noble/post-quantum).

Where to start

Begin with an inventory, not an algorithm. Find every place you rely on a long-lived classical signing root — code-signing keys, firmware-update keys, internal CA roots, archival audit signers — and rank them by how long the signed artifact has to stay trustworthy and how painful the key is to rotate. The hard-to-re-key, long-lived ones are where hash-based signing pays off.

For those roots, SLH-DSA is the conservative answer: hash-only security, stateless operation, no reuse hazard. For everything higher-volume or shorter-lived, ML-DSA stays the right default — the two are complementary, not competing. QNSP can carry both the inventory and the signing: the free-forever tier (10 GB storage, 50,000 API calls, 20 KMS keys, 25 vault secrets) and SDKs in five languages let you wire up SLH-DSA signing without committing budget first, while the CBOM crypto inventory shows you where your classical signature roots still live.

For the lattice signature you will use for nearly everything else, read the companion post on ML-DSA. For the full per-parameter-set detail on SLH-DSA — every size, every variant, and the live conformance status — see /algorithms/slh-dsa.

Related
← Back to blog