refactor(xmss): restructure subspec into focused modules and clean APIs#783
Merged
tcoratger merged 9 commits intoMay 27, 2026
Merged
Conversation
Reorganize the XMSS subspec around single-responsibility files and tighten the public APIs while preserving all cryptographic behavior. Structure: - Split low-level primitives into field.py (base-P decomposition + secure sampling), poseidon.py (Poseidon1 engine + tweakable hash), and prf.py (SHAKE128 PRF); hashing.py is removed. - tweak_hash and hash_chain become methods on PoseidonXmss; the tweak NamedTuples move to types.py. - Merge message_hash.py + target_sum.py into encoding.py, subtree.py into merkle.py, and delete the rand.py/utils.py grab-bags. APIs: - TypeOneMultiSignature.aggregate becomes a classmethod taking (validator_index, pubkey, signature) tuples, dropping the optional participant bitfield and its runtime guards. - Move the greedy set-cover selection out of the multisig type into forks/lstar/aggregation_select.py. - Replace inline noqa for uppercase config properties with a file-scoped ruff ignore. Docs: - Tighten docstrings to the project /doc rules: one sentence per line, no backticks, WHY-focused comments, worked examples for the encoding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a LEAVES_PER_BOTTOM_TREE property to XmssConfig and route the four recomputations of 2^(LOG_LIFETIME / 2) through it. Sign now reuses get_prepared_interval for its prepared-window bound check, removing the duplicated window arithmetic, and drops a redundant int() cast on slot. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rework the docstrings and inline comments of the interface module to follow the project documentation rules: one sentence per line, no backticks, and WHY-focused comments rather than restatements of the code. - _expand_activation_time: conceptual overview of the bottom-tree model plus phase-labeled comments explaining the round-down/round-up bit tricks. - key_gen: lead with the memory-bound rationale; fix the phase numbering so the inline labels match execution order. - sign: explain each phase from the scheme's perspective (synchronized one-time keys, the target-sum layer giving incomparability, Winternitz chain release, and the Merkle opening). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Give the subtree builder an optional highest_layer bound so a bottom tree stops at depth/2 instead of building the full tree to the global root and discarding the upper half. The single-node root is then taken from the top built layer, keeping the absolute-index selection that handles odd bottom tree indices. The constructed layers are byte-identical to before. Also simplify the authentication-path index math to plain int arithmetic, matching the verifier, and drop the redundant Uint64 wraps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A parallel worktree under .claude/worktrees was accidentally staged and committed as a gitlink. Remove it from tracking and ignore the directory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite the merkle documentation to the project doc standard: a module header explaining the top-bottom split and sliding-window memory bound, overview-only docstrings backed by phase-labeled bodies, and concrete layout and climb traces. Move the signer's internal tree representation next to its only user: the layer container, its list, and the padding logic now live in the merkle module as a named constructor, while the signature-facing opening type stays among the base types. Inline the single-use layer cap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the master key type next to the pseudorandom function and expose its derivations as methods: a fresh-key constructor, a chain-start derivation, and a signing-randomness derivation. Update all call sites accordingly. Tighten the base types: type the PRF domain separator as a fixed-length byte string, inline the single-use digest-length alias, and express the layer node cap in terms of the leaves-per-bottom-tree property. Clarify the docs across the PRF and base-type modules per the project doc rules. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reorganize the XMSS unit tests so each source module has one matching test file, redistributing the orphan files into the module they exercise. Drive every module to full line and branch coverage apart from three intentionally unreachable arcs, deduplicate overlapping cases, split bundled assertions into single-behavior tests, parametrize scenario families across sizes and edges, and match the complete text of every error message the spec itself raises. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The new xmss test module mirroring the field source shares a basename with the koalabear field test. Without a package marker, pytest's prepend import mode maps both to the same module name and aborts collection. Adding an empty package init namespaces the xmss test modules and resolves the clash, matching how other test directories in the tree are already packaged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reorganizes the XMSS subspec around single-responsibility modules and tightens the public APIs, with no change to cryptographic behavior. Net: 35 files changed, +1693 / −2628.
Structure
field.py(base-P decomposition + secure sampling),poseidon.py(Poseidon1 engine + tweakable hash),prf.py(SHAKE128 PRF).hashing.pyis removed.tweak_hashandhash_chainare now methods onPoseidonXmss(every call already threadedposeidonas the first arg); theTreeTweak/ChainTweakNamedTuples move totypes.py.message_hash.py+target_sum.py→encoding.py,subtree.py→merkle.py; delete therand.py/utils.pygrab-bags.field/prfat the bottom,poseidonabovefield,merkle/encoding/interfaceon top.APIs
TypeOneMultiSignature.aggregateis now a@classmethodtaking(validator_index, pubkey, signature)tuples — the optional participant bitfield and its runtime guards are gone (the index travels with each fresh signer, so the mismatch is unrepresentable).forks/lstar/aggregation_select.py.# noqa: N802on uppercase config properties with one file-scoped ruff ignore.Docs
/docrules: one sentence per line, no backticks, WHY-focused comments, and a worked example for the encoding pipeline.Test plan
just checkpasses (ruff lint + format, ty typecheck, codespell, mdformat)uv run pytest tests/lean_spec/subspecs/xmss/— 104 passed🤖 Generated with Claude Code