Understanding SPHINCS+
A visual walkthrough of how hash-based post-quantum signatures work and why Quantroot uses them to protect Bitcoin.
What is SPHINCS+?
SPHINCS+ (standardized as SLH-DSA in NIST FIPS 205) is a post-quantum
digital signature scheme. It replaces the elliptic-curve math behind
ECDSA and Schnorr with nothing but hash
functions — the same primitives you already know from
SHA-256 and block explorers.
That substitution is what makes it safe against quantum computers.
At the highest level, SPHINCS+ is built from a handful of cryptographic pieces stacked on top of each other. You will see these names repeatedly:
| WOTS+ | One-time signature made from hash chains. Signs a single message. |
| Merkle tree | Binary tree of hashes that commits to many values under one root. |
| XMSS | A Merkle tree of WOTS+ keys — multi-time signing, but stateful. |
| FORS | A "few-time" signature over a forest of small Merkle trees. Signs the message hash. |
| Hypertree | A tree of XMSS trees that lets one small public key authenticate billions of signatures. |
Prerequisites
This guide assumes passing familiarity with a few cryptographic primitives. If you'd like a refresher, the links below go to general-purpose introductions:
A piece of math that proves "I, holder of this private key, authorized this exact message."
Wikipedia →Binary hash trees that commit to many values under a single root. We'll revisit these below.
Wikipedia →Two things worth keeping in mind as you read on:
-
Hash functions are one-way.
Computing
H(x)fromxis trivial; going backwards is infeasible. That asymmetry is the only hard problem SPHINCS+ depends on. - In Bitcoin, a broken signature scheme means an attacker can spend coins from any address whose public key has been revealed on-chain — i.e., any address that has been spent from. Post-quantum signatures exist to keep that window closed.
Why Hash-Based Signatures?
Bitcoin's current signatures — ECDSA and Schnorr — rest
on the Elliptic Curve Discrete
Logarithm Problem (ECDLP). A private key is a random
256-bit integer d. The public
key is a point P = d·G on the
secp256k1 curve. Computing
P from
d is fast; recovering
d from
P takes roughly
2128 operations classically — effectively
infinite.
Forward is easy; reverse (ECDLP) is hard classically but broken on a sufficiently large quantum computer via Shor's algorithm.
Forward is easy; reverse is infeasible both classically and on a quantum computer.
In 1994 Peter Shor published a quantum algorithm that solves
discrete-log (and integer factoring) in polynomial time. A large,
fault-tolerant quantum computer running Shor's could recover
d from
P in hours. This would break
ECDSA, Schnorr, RSA, and every other scheme whose security reduces
to discrete-log or factoring. Nobody has built such a machine yet,
but cryptographic standards move slowly, and coins safe today need
to stay safe in a decade.
Hash functions don't have the algebraic structure Shor's exploits. The best known quantum attack against a hash function is Grover's algorithm, which provides only a quadratic speedup (2n → 2n/2). Easy to absorb by using a larger hash output — a 256-bit hash still provides 128-bit security against a quantum attacker, the same level Bitcoin's Schnorr already targets.
Build a signature scheme whose only hard problem is "invert a hash function," and you get post-quantum security for free.
Building Block 1: WOTS+ (Hash Chains)
The Winternitz One-Time Signature (WOTS+) is the first primitive
we'll build from scratch. The core idea is a
hash chain: pick a random
secret s and hash it
w times in a row. The end of
the chain is the public key. To sign a digit
d, reveal the intermediate
hash Hd(s); the
verifier applies H an
additional w − d times
and checks that the result matches the public key.
Security comes from hash-function asymmetry. The verifier can
trivially hash forward; a forger trying to sign a lower
digit would need to run H
backwards, which is exactly what hash functions are built to
prevent. But an attacker who sees the signature can hash
forward and claim a higher digit. WOTS+ closes this hole
with a separate checksum chain
whose digits move in the opposite direction — any forward
move on a message chain forces a backward move on the checksum
chain, and forging in both directions at once is infeasible.
One chain signs a single
log2(w)-bit digit;
a full message hash needs several chains in parallel plus the
checksum chain. The Winternitz
parameter w trades
signature size against hashing work: higher
w gives shorter signatures
but more hashing. Quantroot uses
w = 256, the maximum FIPS 205
allows.
The catch: one WOTS+ key signs exactly one message. Signing a second message exposes two intermediate hashes in the same chain, letting an attacker hash either forward to forge signatures on many other messages. WOTS+ is one-time by construction, which is why we need the next building block.
Building Block 2: Merkle Trees
XMSS is just "put WOTS+ keys at the leaves of a Merkle tree," so
it's worth spelling out exactly which property we'll use. A Merkle
tree is a binary tree where each internal node is the hash of its
two children concatenated. The single root
hash commits to every value at the leaves, and any individual leaf
can be proven in the tree with
log₂(n) sibling hashes
— the authentication path.
To prove that a specific leaf is in the tree, you provide the authentication path: the sibling hashes at each level on the way from the leaf to the root. The verifier walks up the path, recomputes the root, and checks it matches the published one. A million leaves costs twenty hashes — that logarithmic scaling is why Merkle trees show up in Bitcoin blocks, Git objects, and certificate transparency logs.
Building Block 3: XMSS
XMSS — the eXtended Merkle Signature Scheme — is exactly
what the name suggests: a Merkle tree whose leaves are WOTS+ public
keys. The XMSS public key is the Merkle root. To sign message
i, use
WOTS+ keypair i and attach
the authentication path from leaf
i to the root. A tree of
height h gives
2h one-time
keypairs — one-time signatures turned into many-time
signatures.
Every leaf is still a WOTS+ key, and WOTS+ is still one-time. Which brings us to the problem the next section is about.
The State Problem
XMSS requires the signer to remember which leaves have already been used. In practice, that means maintaining a counter: "I've signed k messages, the next signature uses leaf k, then increment to k+1." That counter is called state, and keeping it correct is suddenly part of the signer's job.
State is poison for Bitcoin wallets. Consider how a Bitcoin private key actually gets used:
Worst of all, none of these failures are visible. A signature made with a reused leaf is structurally valid and every wallet will accept it. The compromise only becomes apparent once an attacker publishes a forgery — and by then it's too late. This is why "just use XMSS" was never acceptable for Bitcoin.
SPHINCS+: Stateless via PRF
The insight that makes SPHINCS+ work: instead of remembering which leaf you've used, derive the leaf from the message itself. SPHINCS+ uses a pseudorandom function (PRF) keyed by a secret — a function whose output looks random without the key but is perfectly deterministic with it. Same inputs always produce the same output.
If the counter is lost, corrupted, or reused across devices, security is silently broken.
The message deterministically selects the leaf. Same message = same leaf = same signature (safe). Different message = different leaf (safe).
Every failure mode from the previous section evaporates. Same seed reproduces the same PRF and picks the same leaves. Two devices with the same key land on the same leaf for the same message. Restored backups don't affect leaf selection. There is simply nothing for the signer to track.
Deterministic leaf selection has one cost: if two messages collide on the same leaf, you get WOTS+-style reuse. To keep that collision probability astronomically small, SPHINCS+ needs a huge number of possible leaves — Quantroot targets 232, roughly four billion. A single XMSS tree that large is impractical to build: generating the root alone requires hashing every one of its four billion leaves. The fix is to compose the tree out of smaller trees.
The Hypertree
SPHINCS+ stacks d smaller
XMSS trees into a hypertree
— a tree of trees — with a dedicated few-time signer
at the very bottom. Each XMSS tree has small height
h/d, so its root is cheap to
compute. The "signature" at each layer above 0 is really a WOTS+
signature on the root of the tree directly below. At the very
bottom, each leaf of the lowest XMSS tree points to a fresh
instance of a special few-time scheme that actually signs the
message hash — the next section covers that scheme.
(top)
(bottom)
Signing walks the full chain — PRF picks a bottom-layer
instance, the few-time scheme signs the message hash, and each
layer's auth path threads up to the SPHINCS+ root. Verification
runs the chain in reverse. The 232 leaf capacity is
spread across d=4 layers, so
no single tree is ever bigger than 28 = 256 leaves.
Signing and verification each touch one small tree per layer, not
one giant tree.
Building Block 4: FORS
FORS — Forest Of Random Subsets — is the few-time
scheme at the bottom of the hypertree. Unlike WOTS+, it signs the
full message hash directly, and it tolerates a small number of
reuses before collapsing. A FORS key is
k small Merkle trees, each of
height a. Each leaf is a
secret value. The FORS public key is the hash of all
k tree roots concatenated.
To sign a message hash, split it into
k indices, one per tree, and
reveal one leaf per tree
plus the authentication path from that leaf up to its tree's root.
Why few-time?
If two messages overlap in some but not all trees, an attacker can mix revealed leaves from both signatures and forge a third message. The probability of overlap grows quickly with the number of messages signed under one FORS key, so a single FORS instance is only safe for a handful of signatures.
SPHINCS+ sidesteps this by using a fresh FORS key per signature. The PRF picks a different bottom-XMSS leaf for almost every message, and each leaf points to its own FORS instance. The few-time safety budget resets every time.
Bitcoin's SPHINCS+ Parameters
Quantroot tunes SPHINCS+ for Bitcoin's constraints. Bigger isn't always better — we care about signature size, verification speed, and how many signatures a single key can safely make.
| Param | Value | Meaning |
|---|---|---|
| n | 16 | Hash output size in bytes — security parameter |
| h | 32 | Total hypertree height (232 possible signatures) |
| d | 4 | Number of XMSS layers (8 levels per layer) |
| w | 256 | Winternitz parameter — maximum, shortest WOTS+ sig |
| k | 10 | Number of FORS trees |
| a | 14 | FORS tree height (214 = 16,384 leaves per tree) |
Inside a 4,080-Byte Signature
That 64× size increase is the price of building a signature out of nothing but hashing.
How Quantroot Uses SPHINCS+
SPHINCS+ is not used alone in Bitcoin. Quantroot's soft fork pairs it with Schnorr in a hybrid Tapscript leaf:
The 4,080-byte SPHINCS+ signature is carried in the Taproot annex — a dedicated witness field — rather than on the script stack, which has a 520-byte element limit.
Before the soft fork activates,
OP_CHECKSPHINCSVERIFY is a
no-op: the script still passes or fails on the Schnorr check. That
keeps quantum-insured outputs spendable on today's mainnet and lets
wallets opt in now. After activation, the SPHINCS+ check becomes
mandatory and the output is protected against both classical
and quantum key recovery.