365 Architect

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

  1. Generate nn random secret values: sk1,sk2,...,sknsk_1, sk_2, ..., sk_n

  2. Compute public values by hashing each secret many times:

    pki=Hw1(ski)\displaystyle pk_i = H^{w-1}(sk_i)

    Where HkH^k means "apply hash kk times" and ww is the Winternitz parameter (e.g., w=16w=16).

Signing

  1. Hash the message to get an nn-byte digest: d=Hash(message)d = Hash(message)
  2. Split dd into nn chunks of extlog2(w)ext{log}_2(w) bits each
  3. For each chunk ii with value bi[0,w1]b_i \in [0, w-1]:
    • Compute signature element: σi=Hbi(ski)\sigma_i = H^{b_i}(sk_i)
  4. Output signature: σ=(σ1,σ2,...,σn)\sigma = (\sigma_1, \sigma_2, ..., \sigma_n)

Verification

  1. Hash the message to get dd, split into chunks bib_i
  2. For each signature element:
    • Compute pki=Hw1bi(σi)pk_i' = H^{w-1-b_i}(\sigma_i)
  3. Check: does (pk1,pk2,...,pkn)(pk_1', pk_2', ..., pk_n') match the public key?

Why It Works

If the signer is honest, σi=Hbi(ski)\sigma_i = H^{b_i}(sk_i), so:

Hw1bi(σi)=Hw1bi(Hbi(ski))=Hw1(ski)=pki\displaystyle H^{w-1-b_i}(\sigma_i) = H^{w-1-b_i}(H^{b_i}(sk_i)) = H^{w-1}(sk_i) = pk_i

If the signer is cheating, they don't know skisk_i, so they can't compute Hbi(ski)H^{b_i}(sk_i) for arbitrary bib_i.

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:

H(x)=H(xr)\displaystyle H'(x) = H(x \oplus r)

Where rr 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 bib_i (to create a "shorter" hash chain), the checksum CC 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 MM with chunks bib_i, the signature reveals:

σi=Hbi(ski)\displaystyle \sigma_i = H^{b_i}(sk_i)

If you sign a second message MM' with chunks bib_i', you reveal:

σi=Hbi(ski)\displaystyle \sigma_i' = H^{b_i'}(sk_i)

An attacker now has two points on the same hash chain:

  • σi=Hbi(ski)\sigma_i = H^{b_i}(sk_i) at position bib_i
  • σi=Hbi(ski)\sigma_i' = H^{b_i'}(sk_i) at position bib_i'

If bi<bib_i < b_i', the attacker can compute:

Hbibi(σi)=Hbi(ski)=σi\displaystyle H^{b_i' - b_i}(\sigma_i) = H^{b_i'}(sk_i) = \sigma_i'

But more importantly, if the attacker wants to forge a message with chunks bib_i'' where bi<min(bi,bi)b_i'' < \min(b_i, b_i'), they can compute:

Hbi(ski)\displaystyle H^{b_i''}(sk_i)

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
Share on LinkedIn