Skip to content

signatures: cross-check leanXMSS against EthLib's test vectors - #648

Merged
TomWambsgans merged 1 commit into
mainfrom
test/ethlib-xmss-vectors
Oct 28, 2026
Merged

TomWambsgans merged 1 commit into
mainfrom
test/ethlib-xmss-vectors

Conversation

@tcoratger

Copy link
Copy Markdown
Collaborator

EthLib specifies leanXMSS in Lean, with machine-checked proofs that its key generation, signing and verification fit together.
Its test vectors (ethereum/EthLib#50) pin all three byte for byte, rejections included.

This runs every one of them against lean_xmss:

key_gen   4 cases   2 public keys, 2 rejected seeds
sign      6 cases   4 signatures, 2 rejected inputs
verify   16 cases   4 accepted, 12 rejected

All 26 agree with this crate.
The signatures cover the first leaf, the first leaf of the second bottom tree, the last leaf, and 0xA5C37E19.
Each rejected verification changes one input: the message, the leaf index, one bit of a randomizer, a chain value or a sibling on either layer, the key's root or public parameter, another key, or a length.

How the vectors get here

crates/signatures/tests/signatures/ethlib/xmss/ is a verbatim copy of EthLib's tests/cryptography/xmss/, at the commit in ethlib/COMMIT (dd0b80a).

crates/signatures/tests/signatures/ethlib/sync.sh <ethlib-commit>

It fetches EthLib at that commit, checks every case against EthLib's SHA256SUMS, then replaces the copy and records the commit.
The test reads the copy offline, so CI never touches the network.

A strict reader parses the fixed shape of a case, so a change of format fails the test instead of skipping cases.
An EthLib output of null marks an input of the wrong length, which here cannot fill the API's fixed-size arrays.

Cost

Two full keys and four bottom trees: about 2 s in release.
Corrupting one byte of one vendored signature fails sign_matches_ethlib and names the case.

I am an AI agent (Claude); a human reviews before merge.

🤖 Generated with Claude Code

EthLib specifies leanXMSS in Lean and proves its keyGen, sign and verify
correct. Its test vectors pin key generation, signing and verification
byte for byte, rejections included.

`tests/signatures/ethlib/xmss/` vendors those vectors at EthLib dd0b80a
(ethereum/EthLib#50), and `ethlib_vectors.rs` runs every case against
lean_xmss: 4 key generations, 6 signings and 16 verifications, all equal.

`ethlib/sync.sh <commit>` refreshes the copy: it fetches EthLib at that
commit, checks every case against EthLib's SHA256SUMS, and records the
commit in `ethlib/COMMIT`. The cases are read by a strict reader of their
fixed shape, so a change of format fails instead of skipping cases.

The three tests take about 2 s in release: two full keys and four bottom
trees.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TomWambsgans
TomWambsgans merged commit 7de9ff5 into main Oct 28, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants