SLH-DSA Introduction
The StateLess Hash-based Digital Signature Algorithm (SLH-DSA) is described in FIPS.205, published by NIST, 13 August 2024. It is based on SPHINCS+, submitted as part of the NIST PQC Standardization process.
As a summary of the SLH-DSA algorithm, we take the excellent description of SLH-DSA from RFC 9814 Use of the SLH-DSA Signature Algorithm in the Cryptographic Message Syntax (CMS) by R. Housley, et al, July 2025
SLH-DSA is a stateless hash-based signature algorithm. SLH-DSA makes use of a few time signature construction (Forest of Random Subsets (FORS)) and a hypertree [a tree of trees]. FORS signs a message with a private key. The corresponding FORS public keys are the leaves in k binary trees. The roots of these trees are hashed together to form a FORS root. SLH-DSA uses a one-time signature scheme called Winternitz One-Time Signature Plus (WOTS+). The FORS tree roots are signed by a WOTS+ private key. The corresponding WOTS+ public keys form the leaves in d-layers of Merkle subtrees in the SLH-DSA hypertree. The bottom layer of that hypertree signs the FORS roots with WOTS+. The roots of the bottom Merkle subtrees are then signed with WOTS+ and the corresponding WOTS+ public keys form the leaves of the next-level-up subtree. Subtree roots are consequently signed by their corresponding subtree layers until the top subtree is reached. The top-layer subtree forms the hypertree root, which is trusted at the verifier.
An SLH-DSA signature consists of the randomization string, the FORS signature, the WOTS+ signature in each layer, and the path to the root of each subtree until the root of the hypertree is reached.
An SLH-DSA signature is verified using the FORS signature, the WOTS+ signatures, and the path to the root of each subtree. When reaching the root of the hypertree, the signature verifies only if it hashes to the pre-trusted root of the SLH-DSA hypertree.
SLH-DSA is a stateless hash-based signature algorithm. Stateful hash-based signature schemes require that the WOTS+ private key (generated by using a state index) never be reused or the scheme loses its security. FORS is used at the bottom of the SLH-DSA hypertree. Security decreases if the same private key is used to sign two or more different messages, but security does not collapse, as is the case in stateful hash-based signature algorithms. Without the need for state kept by the signer to ensure it is not reused, SLH-DSA is much less fragile.
SLH-DSA was designed to sign up to $2^{64}$ messages and offers three security levels. The parameters of the SLH-DSA hypertree include the security parameter $n$, the hash function, the tree height, the number of layers of subtrees, the Winternitz parameter of WOTS+, and the number of FORS trees and leaves in each. The parameters for each of the security levels were chosen to be at least as secure as a generic block cipher of 128, 192, or 256 bits.
The SLH-DSA key pair
The public key consists of two $n$-byte values:
the root node of the top tree in the hypertree PK.root,
and a random $n$-byte public seed PK.seed.
The private key consists of the public key plus two more $n$-byte random seeds:
SK.seed to generate the WOTS+ and FORS secret keys
and SK.prf used for the randomized message digest.
External and Internal Signatures
SIG = slh_sign(M, ctx, SK)where
M is the content-to-be-signed, ctx is an optional context string of up to 255 bytes which by default is empty,
and SK is the SLH-DSA private key.
The SLH-DSA algorithm specified in FIPS.205 provides for two signature versions: "pure" and "prehash".
"Pure" signing accepts the entire message to be signed as input and "prehash" accepts a hash digest of the message.
Both versions use the slh_sign_internal function but they differ
in how the message input to slh_sign_internal is created from the content to be signed by adding domain separation information
There are also "hedged" and "deterministic" variants. "Hedged" adds additional randomness to the process, so each signature of the same data with the same key will be different, while the "deterministic" variant always produces the same output.
FIPS.205 Algorithm 19 Pure SigningSIG = slh_sign_internal(M', SK, addrnd)where
M' is the modified message, SK the private key, and addrnd is optional additional randomness.
M' = toByte(0, 1) || toByte(|ctx|, 1) || ctx || M
In the default case in which the context string is empty, pure signing simply involves prepending two zero bytes to the content to be signed
and passing the result to slh_sign_internal along with the private key and, in the case of hedged signing, an $n$-byte random value.
In our example, we are carrying out "pure" signing with an empty context string using the deterministic variant. So we have
M' = 0x00 || 0x00 || Mand our result is given by
SIG = slh_sign_internal(M', SK, null)
How many private keys are there?
Each time we create a signature we expose a few FORS private keys. This obviously reduces the security of subsequent signatures, but by how much?
Well, consider how many FORS private keys there are to choose from, see: How many FORS private keys are there?
Answer: about the number of stars in the Universe.
Remember that SHL-DSA is designed to sign up to $2^{64}$ messages using the one key pair, which is in practical terms limitless. There are moves afoot to introduce new, smaller SLH-DSA parameter sets for lower message limits.
| << previous: Few Time Signature (FTS) | Contents | next: SLH-DSA: how many FORS private keys are there? >> |
Rate this page
Contact us
To comment on this page or to contact us, please send us a message.
This page first published 17 March 2023. Last updated 16 February 2026.

