Skip to content
Choosing LMS/HSS Parameters

Choosing LMS/HSS Parameters

LMS and HSS have more knobs than most signature schemes: tree height, number of hierarchy levels, and the LM-OTS Winternitz width, each choosable per level. This guide is about picking them. It assumes you have read the Stateful Signing guide; nothing here changes the state rules, and SP 800-208-conformant deployments carry additional operational requirements regardless of parameter choice.

Since: cryptopp-modern 2026.8.0 for mixed hierarchies and the W1/W2/W4 sets. The uniform typedefs date from 2026.6.0.

Start from signing capacity

A key has a fixed maximum number of signatures determined by its parameter set. Capacity is the product of the per-level tree sizes: an H10 tree has 1,024 leaves, an H5 tree 32, so H10-over-H5 gives 32,768 signatures.

Count the signatures your deployment will ever make with one key, then add generous margin; a firmware line that expects 200 signed artefacts should not run on a 1,024-signature key just because 200 fits. Exhaustion is not a soft failure. The signer refuses to continue and you must roll out a new public key.

ConfigurationTotal signaturesSignature size
HSS_SHA256_H5_W8_L21,0242,644 bytes
HSS_SHA256_H10W4_H5W8_L232,7683,860 bytes
HSS_SHA256_H5_W8_L332,7683,992 bytes
HSS_SHA256_H10_W8_L21,048,5762,964 bytes
HSS_SHA256_H5_W8_L41,048,5765,340 bytes

Two trade-offs matter. Adding a level multiplies capacity but adds another LMS signature and embedded public key, roughly 1.3 to 1.5 KB for the shipped W=8 trees, to every signature you emit. Raising a tree height multiplies capacity and costs only 32 bytes per height step in the affected level’s signature. When both routes reach your target capacity, the taller tree usually wins on size; the extra level wins when key generation time matters, as below.

What tree height costs

Key generation computes every leaf of the root tree, and each bottom-tree rotation computes every leaf of a new bottom tree. An H5 tree is 32 one-time keys; an H10 tree is 1,024. So HSS_SHA256_H10_W8_L2 pays a 1,024-leaf computation at key generation and again every 1,024 signatures, while HSS_SHA256_H5_W8_L4 pays 32-leaf computations throughout, at the price of a 5,340-byte signature.

If your signer is a small device or an HSM where a long key generation pause hurts, prefer short trees and more levels. If signatures travel over constrained links, prefer tall trees and fewer levels.

What W costs

The Winternitz width trades signature size against hashing work in both signing and verification. Chain length is 2^W - 1 hash steps:

WChainsChain lengthLMS signature (H5)
126518,684 bytes
213334,460 bytes
467152,348 bytes
8342551,292 bytes

W=8 is the default in the shipped typedefs because signature size is usually the binding constraint. W=4 uses 67 chains of at most 15 steps, compared with 34 chains of at most 255 steps for W=8, so it reduces LM-OTS chain hashing substantially, at the cost of 1,056 additional bytes per LMS signature. Signing and verification divide the chain work between them according to the message coefficients and checksum. All four widths are RFC 8554 parameter sets approved by SP 800-208. W=1 and W=2 are mainly useful when reducing chain hashing matters more than signature size, or when interoperating with those parameter sets.

When to mix parameters per level

The levels perform different jobs, so they do not need identical parameters. Each non-bottom level signs a child LMS public key when that child tree is created; the bottom level signs every message. In a two-level hierarchy the root therefore signs once per bottom-tree rotation, and in deeper hierarchies intermediate levels absorb most rotations, so the root signs much less often still. Meanwhile the authentication chain from the root is included in, and verified with, every emitted HSS signature.

That asymmetry is the reason to mix. A verifier-heavy deployment can spend bytes at the root to save hashing on every verification: HSS_SHA256_H10W4_H5W8_L2 does exactly this, pairing an H10/W4 root with chains of at most 15 steps, rather than 255 for W=8, and a compact H5/W8 bottom. It is also the configuration of RFC 8554 Appendix F Test Case 2, so it is the set to reach for when testing interoperability against another implementation.

Height can be mixed for the same reason: tall upper trees add capacity while being generated infrequently, and short lower trees keep rotations cheap.

The mixed set ships as a normal typedef and is used exactly like the uniform ones:

#include <cryptopp/hss.h>

using namespace CryptoPP;

typedef HSS_SHA256_H10W4_H5W8_L2 Scheme;
typedef HSS_SHA256_H10W4_H5W8_L2_Params Params;

Scheme::PrivateKey privKey;
// ... key generation, signing and verification are identical to the
// uniform typedefs; see the LMS/HSS API reference.

Hierarchies beyond the five shipped parameter sets are a source-level extension: the HSS class templates are explicitly instantiated in the library, so a new HSS_Params combination in application code compiles but does not link until matching instantiations are added to src/pqc/lms.cpp and the library is rebuilt. cryptopp-modern’s structural rules (two to four levels, one LM-OTS N across the hierarchy, each LMS M matching its LM-OTS N) are enforced by the compiler either way, so an invalid hierarchy fails to build rather than misbehaving at runtime. RFC 8554 itself is more permissive; these limits are this implementation’s. The API reference shows the instantiation mechanics.

Mixing changes sizes, not obligations. Every configuration on this page is stateful. For the full scheme capacity, initialise the state store with Params::TotalSignatures(); a backend may enforce a lower limit, but must never issue an index beyond the selected parameter set’s capacity.

Three worked choices

Firmware signing, a few signed artefacts a year. Count test signatures, product variants and failed signing attempts, not just releases. If 32 signatures with adequate margin are enough, single-tree LMS_SHA256_M32_H5 is the simplest option at 1,292 bytes per signature. Otherwise take the simplest shipped HSS configuration: HSS_SHA256_H5_W8_L2, 1,024 signatures at 2,644 bytes. If the product might outlive 1,024 signed artefacts, HSS_SHA256_H5_W8_L3 buys 32x the capacity for an extra 1,348 bytes per signature.

Manufacturing line provisioning hundreds of thousands of devices. Capacity drives everything. HSS_SHA256_H10_W8_L2 provides 1,048,576 signatures at 2,964 bytes and suits deployments comfortably below that limit, provided retries, rejected units, testing and future growth are in the capacity calculation; a planned one million signatures leaves less than 5% headroom and should use a larger hierarchy or a deliberate public-key rollover strategy. If the 1,024-leaf key generation and rotation pauses are unacceptable on the signing hardware, HSS_SHA256_H5_W8_L4 replaces those long pauses with shorter, more frequent H5 tree generations, at the cost of 5,340-byte signatures.

Signatures verified constantly on cheap hardware. Spend root bytes to save verify hashing: HSS_SHA256_H10W4_H5W8_L2 at 3,860 bytes. A different mix requires adding matching explicit instantiations and rebuilding the library (see above), not an application-side typedef.

See also