03 — One-Time Signatures (WOTS+)
The Core Idea
A one-time signature (OTS) key can sign exactly one message. Reuse it, and an attacker can forge signatures. This seems like a terrible limitation — but with Merkle trees (next article), we can manage millions of OTS keys efficiently.
Winternitz OTS: The Basic Version
Setup
Generate random secret values:
Compute public values by hashing each secret many times:
Where means "apply hash times" and is the Winternitz parameter (e.g., ).
Signing
- Hash the message to get an -byte digest:
- Split into chunks of bits each
- For each chunk with value :
- Compute signature element:
- Output signature:
Verification
- Hash the message to get , split into chunks
- For each signature element:
- Compute
- Check: does match the public key?
Why It Works
If the signer is honest, , so:
If the signer is cheating, they don't know , so they can't compute for arbitrary .
WOTS+ (The Improved Version)
The original WOTS has a weakness: different messages produce related signatures. WOTS+ fixes this with two improvements:
1. Bitmask XOR
Before each hash, XOR with a random bitmask:
Where is a public random value. This prevents multi-target attacks.
2. Checksum
A checksum is added to prevent signature forgery by increasing chunk values:
Message chunks: b_1, b_2, ..., b_n
Checksum: C = sum(w - 1 - b_i) for all i
Split C into additional checksum chunks
Signature includes both message chunks AND checksum chunks
Why it helps: If an attacker tries to decrease some (to create a "shorter" hash chain), the checksum increases, requiring them to increase other values. The total sum is fixed, so any change is detectable.
WOTS+ Parameters and Sizes
| Parameter | Symbol | Typical Value | Effect |
|---|---|---|---|
| Security parameter | n | 32 bytes | Matches SHA-256 output |
| Winternitz width | w | 16 | Trade-off: smaller sigs but more hashing |
| Number of chains | len | 67 (for n=32, w=16) | Covers message + checksum |
| Signature size | len × n = 2,144 B | ||
| Public key size | len × n = 2,144 B |
The One-Time Property
Why can you only sign once?
After signing message with chunks , the signature reveals:
If you sign a second message with chunks , you reveal:
An attacker now has two points on the same hash chain:
- at position
- at position
If , the attacker can compute:
But more importantly, if the attacker wants to forge a message with chunks where , they can compute:
from either starting point! By combining information from multiple signatures, the attacker can sign any message whose chunks are less than or equal to the minimum values seen across all signatures.
One signature = limited leakage. Many signatures = complete compromise.
From OTS to Many Signatures: Merkle Trees
WOTS+ alone signs one message. To sign many messages, we use Merkle trees to manage many WOTS+ keys.
See: 02 — Merkle Trees and 05 — The Hypertree.
Resources
- Buchmann et al., "XMSS — A practical forward secure signature scheme based on minimal security assumptions" (2011)
- Hülsing, "W-OTS+ — Shorter signatures for hash-based signature schemes" (2013), AFRICACRYPT
- NIST FIPS 205, Section 5: WOTS+ Algorithm