What would you like to Propose?
I propose adding a Winternitz One-Time Signature (WOTS) implementation to the ciphers package.
With the recently merged Lamport signature, the repository now has its first hash-based
post-quantum algorithm. WOTS (Merkle, 1989, based on Winternitz's idea) is the natural
next step: it is the size-optimized evolution of the Lamport scheme, trading additional
hash computations for significantly smaller signatures via a tunable parameter w. It is
also the actual building block used inside modern post-quantum signature standards such
as XMSS (RFC 8391) and SPHINCS+ (FIPS 205) — making it arguably the most practically
relevant one-time signature scheme to learn.
WOTS is a good fit for this repository because:
- It directly builds on and complements the existing Lamport signature, turning a single
algorithm into a coherent hash-based signatures learning path.
- It can be implemented entirely using standard Java (
java.security.MessageDigest and
java.security.SecureRandom) without any external dependencies, matching the
educational and dependency-free style of this repository.
- It demonstrates important cryptographic concepts not covered by Lamport: hash chains,
the signature-size vs. computation trade-off controlled by the Winternitz parameter w,
and the role of the checksum in preventing forgery.
- It remains simple enough to be a single self-contained class while being meaningfully
more advanced than Lamport.
Issue details
Algorithm / problem statement: Generate a key pair consisting of len random n-byte
secrets (private key) whose public key values are obtained by applying a hash chain w-1
times to each secret. To sign a message, hash it with SHA-256, split the digest into
base-w digits, append a checksum (also in base-w) that prevents forgery by advancing
hash chains, and for each digit m[i] output chain(sk[i], m[i]). To verify, recompute the
digits and check that chain(sig[i], w-1-m[i]) equals the corresponding public key entry.
-
src/main/java/com/thealgorithms/ciphers/WinternitzSignature.java
-
Key pair generation using SecureRandom (len secrets of 32 bytes; public key derived
via w-1 hash chain iterations per secret).
-
Support for Winternitz parameter w ∈ {4, 16, 256} (default 16), with chain counts
len1, len2, and len derived from w rather than hard-coded (e.g. w=16 → len1=64,
len2=3, len=67).
-
sign() method producing a signature for a given message, with the one-time property
enforced (signing a second message with the same key pair throws IllegalStateException).
-
Static verify() method validating a message/signature pair against a public key.
-
Defensive copies of all key and signature material (no internal array references leaked).
-
Input validation for null message/signature/keys, malformed signature dimensions, and
unsupported w values.
-
src/test/java/com/thealgorithms/ciphers/WinternitzSignatureTest.java
-
A valid signature verifies successfully for each supported w (parameterized tests).
-
Chain count derivation is correct (w=16 produces exactly 67 signature elements).
-
A tampered message and a tampered signature are rejected.
-
A signature does not verify under a different key pair or a mismatched w.
-
Signing a second message with the same key pair throws an exception.
-
Tests for null/invalid inputs, empty and multi-KB messages, and immutability of
returned key material.
-
The implementation will include Javadocs describing the algorithm, the role of the
Winternitz parameter and the checksum, why the scheme is quantum-resistant, the
one-time usage limitation, a note that the implementation is for educational purposes
only, a @see reference to the existing LamportSignature, and a reference to the
Wikipedia article on hash-based cryptography / the Lamport signature's Winternitz
improvement.
Additional Information
I searched the repository and existing pull requests and could not find a Winternitz OTS
implementation; the recently added Lamport signature is currently the only hash-based
signature in the repository.
I have already implemented this locally along with comprehensive JUnit 5 tests following
the repository's coding standards, and I can open a pull request as soon as this issue
is approved/assigned. If maintainers are interested, this could later be extended with
the Merkle Signature Scheme, which combines many one-time key pairs under a single
public key.
What would you like to Propose?
I propose adding a Winternitz One-Time Signature (WOTS) implementation to the ciphers package.
With the recently merged Lamport signature, the repository now has its first hash-based
post-quantum algorithm. WOTS (Merkle, 1989, based on Winternitz's idea) is the natural
next step: it is the size-optimized evolution of the Lamport scheme, trading additional
hash computations for significantly smaller signatures via a tunable parameter w. It is
also the actual building block used inside modern post-quantum signature standards such
as XMSS (RFC 8391) and SPHINCS+ (FIPS 205) — making it arguably the most practically
relevant one-time signature scheme to learn.
WOTS is a good fit for this repository because:
algorithm into a coherent hash-based signatures learning path.
java.security.MessageDigestandjava.security.SecureRandom) without any external dependencies, matching theeducational and dependency-free style of this repository.
the signature-size vs. computation trade-off controlled by the Winternitz parameter w,
and the role of the checksum in preventing forgery.
more advanced than Lamport.
Issue details
Algorithm / problem statement: Generate a key pair consisting of
lenrandom n-bytesecrets (private key) whose public key values are obtained by applying a hash chain w-1
times to each secret. To sign a message, hash it with SHA-256, split the digest into
base-w digits, append a checksum (also in base-w) that prevents forgery by advancing
hash chains, and for each digit m[i] output chain(sk[i], m[i]). To verify, recompute the
digits and check that chain(sig[i], w-1-m[i]) equals the corresponding public key entry.
src/main/java/com/thealgorithms/ciphers/WinternitzSignature.java
Key pair generation using SecureRandom (len secrets of 32 bytes; public key derived
via w-1 hash chain iterations per secret).
Support for Winternitz parameter w ∈ {4, 16, 256} (default 16), with chain counts
len1, len2, and len derived from w rather than hard-coded (e.g. w=16 → len1=64,
len2=3, len=67).
sign() method producing a signature for a given message, with the one-time property
enforced (signing a second message with the same key pair throws IllegalStateException).
Static verify() method validating a message/signature pair against a public key.
Defensive copies of all key and signature material (no internal array references leaked).
Input validation for null message/signature/keys, malformed signature dimensions, and
unsupported w values.
src/test/java/com/thealgorithms/ciphers/WinternitzSignatureTest.java
A valid signature verifies successfully for each supported w (parameterized tests).
Chain count derivation is correct (w=16 produces exactly 67 signature elements).
A tampered message and a tampered signature are rejected.
A signature does not verify under a different key pair or a mismatched w.
Signing a second message with the same key pair throws an exception.
Tests for null/invalid inputs, empty and multi-KB messages, and immutability of
returned key material.
The implementation will include Javadocs describing the algorithm, the role of the
Winternitz parameter and the checksum, why the scheme is quantum-resistant, the
one-time usage limitation, a note that the implementation is for educational purposes
only, a
@seereference to the existing LamportSignature, and a reference to theWikipedia article on hash-based cryptography / the Lamport signature's Winternitz
improvement.
Additional Information
I searched the repository and existing pull requests and could not find a Winternitz OTS
implementation; the recently added Lamport signature is currently the only hash-based
signature in the repository.
I have already implemented this locally along with comprehensive JUnit 5 tests following
the repository's coding standards, and I can open a pull request as soon as this issue
is approved/assigned. If maintainers are interested, this could later be extended with
the Merkle Signature Scheme, which combines many one-time key pairs under a single
public key.