This standard defines a keystore format for stateful hash-based signing keys, specifically eXtended Merkle Signature Scheme (XMSS) as used by the Lean Ethereum consensus layer (hereafter leanxmss). It extends ERC-2335 so that the encrypted secret may be an XMSS seed and adds the machinery a consumable key requires: an explicit scheme-parameter block, a non-authoritative capacity snapshot, normative rules for where the authoritative signing state lives, a commit-before-sign durability requirement, reserved leaf ranges for concurrent signers, and import/export semantics that forbid silently resetting a key’s signing position.
The encryption upgrades (Advanced Encryption Standard with 256-bit keys (AES-256) and Authenticated Encryption with Associated Data (AEAD)) are minor. The substance of this EIP is state management, because an XMSS key is destroyed by leaf reuse and the existing keystore model assumes keys are immutable, freely copyable, and restore-safe, three assumptions that are unsafe for consumable keys.
Motivation
ERC-2335 stores a 32-byte BLS scalar. Lean Ethereum replaces BLS validator keys with XMSS for post-quantum security. An XMSS secret can also be reduced to a small seed, so the container needs only modest change. The danger is elsewhere.
Each XMSS signature consumes a one-time Winternitz One-Time Signature Plus (WOTS+) leaf identified by an index that must not ever be reused. Reuse of a leaf across two distinct messages enables forgery and is therefore key-destroying. This single property breaks three behaviors that are safe today and that operators, wallets, and clients currently take for granted:
Immutability. A 2335 keystore never changes after creation. An XMSS key advances state on every signature.
Free copying. A BLS keystore may run on two machines harmlessly. Two copies of an XMSS key signing independently will reuse leaves.
Restore-safety. Restoring a BLS keystore from any backup is safe. Restoring a stale XMSS state rolls back the high-water mark and invites reuse.
Validators already solve an isomorphic problem for BLS: EIP-3076 slashing protection enforces “never sign two different messages for the same slot.” For the synchronized XMSS variant, where one leaf is bound to one epoch/slot, “never reuse a leaf” and “never double-sign a slot” are the same invariant. This EIP makes that coupling normative rather than coincidental, and specifies the remaining cases (off-protocol signers such as builder-bid signing) that fall outside the slashing-protection database.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHOULD”, “SHOULD NOT”, and “MAY” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
1. Terminology
Consumable key: a signing key whose security depends on never reusing an index (e.g. XMSS, Leighton-Micali Signatures (LMS)). Contrast with reusable keys (ECDSA, BLS).
Leaf index: the position of the one-time key consumed by a signature.
High-water mark: the highest leaf index that has been (or is reserved as) consumed. Signing is permitted only strictly above it.
Authoritative state: the single source of truth for the high-water mark that a signer consults and advances. It is NOT the keystore file.
Synchronized mode: leaf index is a deterministic function of consensus position (leaf = f(epoch) or f(slot)); state authority is the slashing-protection database.
Counter mode: leaf index is a free-running counter not bound to consensus position (e.g. off-protocol signing); state authority is a dedicated atomically-updated store.
2. File format
This EIP defines keystore version5. A v5 keystore is a v4 keystore with the changes below.
2.1 Cipher and Key Derivation Function (KDF)
crypto.cipher.function MUST be an AEAD or 256-bit construction. aes-256-gcm is RECOMMENDED. aes-128-ctr MUST NOT be used in v5.
crypto.kdf.function MAY be argon2id in addition to the scrypt and pbkdf2 of v4. Parameters MUST target current memory-hardness guidance.
These are precautionary against Grover and do not affect the consumable-key semantics below.
2.2 Encrypted secret
crypto.cipher.message is the encrypted XMSS seed, not an expanded private key. The seed length is defined by the scheme parameters. The keystore stores only material required to recover the key (see §6); it does not store live signing state.
scheme.name MUST identify the signature scheme. A reader that does not recognize scheme.name MUST refuse to use the keystore.
scheme.params MUST contain every parameter required to deterministically regenerate the public key and to verify a signature. These fields are immutable; a writer MUST NOT alter them after creation.
hash identifies the tweakable hash function and its underlying field. This specification is hash-agnostic: any hash meeting the security requirements of the signature scheme MAY be used, and hash records the concrete choice so that a verifier can reproduce it. The Poseidon1 hash (for example over the KoalaBear field) is still being evaluated for consideration as the recommended instantiation.
tree_height is the height of the (single) Merkle tree; with hypertree_layers it determines lifetime_leaves = 2^(tree_height × hypertree_layers).
hypertree_layers is the number of stacked Merkle trees. leanxmss is a single-tree Generalized XMSS, so this MUST be 1.
encoding identifies the incomparable encoding. leanxmss uses target_sum.
winternitz_w is the base of each hash chain (BASE in leanSig).
dimension is the number of hash chains (the hypercube dimension). Together with winternitz_w and target_sum it fully specifies the target-sum encoding and is REQUIRED to regenerate the public key and verify a signature.
target_sum is the target sum of the target-sum encoding.
index_mode MUST be synchronized or counter per §1.
The non-hash values above are the recommended production parameter set for a 2^32 key lifetime, matching leanSig’s SIGAbortingTargetSumLifetime32Dim46Base8 instantiation (LOG_LIFETIME = 32, DIMENSION = 46, BASE = 8, TARGET_SUM = 200). The format is hash-agnostic; the concrete hash function (for example Poseidon1 over KoalaBear) is still being evaluated for consideration and is recorded in the hash field.
state.authoritative MUST be false in any keystore file. The file is a snapshot for operator visibility only and MUST NOT be consulted as the high-water mark at signing time.
state.authority MUST be one of slashing-protection, external, or embedded and MUST be consistent with scheme.params.index_mode:
synchronized ⇒ slashing-protection.
counter ⇒ external (a dedicated state store).
embedded is RESERVED and SHOULD NOT be used for production validator keys; it exists only for self-contained single-signer tooling and, if used, the file ceases to be immutable.
capacity and high_water are informational. A consumer MUST treat the authoritative store, not these fields, as binding.
3. State authority
A signer MUST consult and advance a single authoritative state when producing a signature.
In synchronized mode, the authoritative state is the EIP-3076 slashing-protection database. The leaf consumed by a signature is f(epoch) (or f(slot)); refusing to double-sign a slot is exactly refusing to reuse a leaf. Implementations MUST bind the XMSS key and its slashing-protection history as an inseparable unit: any operation that moves, imports, or exports the key MUST move, import, or export the corresponding history atomically with it.
In counter mode, the authoritative state is a dedicated store keyed by the keystore uuid, holding the current counter. It MUST provide the same durability and atomicity guarantees as §4.
4. Commit-before-sign ordering
For every signature, an implementation MUST, in order:
Determine the candidate leaf index.
Verify the index is strictly greater than the authoritative high-water mark (or, in synchronized mode, that the slot/epoch has not been signed).
Durably persist the advanced high-water mark, written, flushed (fsync or platform equivalent), and committed via atomic rename or an equivalently atomic transaction, before step 5.
Compute the signature.
Release the signature to the caller.
Releasing a signature before the state advance is durable is a violation: a crash between release and persistence causes index reuse on restart. Step 3 MUST complete before step 5; steps 3 and 4 MAY be reordered relative to each other, but neither may precede step 2.
5. Reserved leaf ranges
To support concurrent or high-throughput signers (e.g. builder-bid signing) without serializing every signature on one lock, a keystore MAY partition its leaf space into disjoint reserved ranges:
Ranges MUST be disjoint. A signer assigned a range MUST consume only indices within [start, end] and MUST maintain its own authoritative high-water mark for that range under the §4 ordering.
A range MUST NOT be assigned to more than one signer instance simultaneously.
Exhaustion of a range MUST cause the signer to refuse rather than wrap or borrow from another range.
This is the recommended mechanism for the builder-bid exhaustion case, where a single global counter is too contended.
6. Import, export, recover, resume
This EIP distinguishes two operations that legacy tooling conflates:
Recover: reconstruct the key (regenerate the hypertree, derive the public key) from the encrypted seed. This is always safe and uses only the keystore file.
Resume signing: begin producing signatures. This requires the latest authoritative state and is unsafe from the keystore file alone.
Therefore:
An implementation MUST NOT begin signing from a keystore that lacks authoritative state. “Import with empty/fresh state” MUST be a hard error for a consumable key, not a warning.
Export of a consumable key MUST include or reference its authoritative state. A bare keystore file MAY be exported for recovery and verification only and, if so, MUST be flagged such that no consumer will sign from it.
Restoring a keystore together with a stale state snapshot is the catastrophic case. Implementations MUST detect a regression of the high-water mark and refuse to sign until reconciled with the latest authoritative state.
Rationale
Why extend 2335 rather than define a new format. The encryption envelope, KDF abstraction, and modular design of 2335 are sound and widely implemented; only the cipher strength and the assumption of a fixed-size reusable secret needed changing. Reusing the envelope preserves tooling and review surface.
Why couple to 3076 instead of a bespoke state mechanism. In synchronized mode the slashing-protection invariant and the leaf-uniqueness invariant are identical. Defining a second, parallel state mechanism would create two sources of truth that can disagree, the worst outcome for a consumable key. Making the slashing DB authoritative gives the key a single, already-battle-tested guardrail.
Why a non-authoritative snapshot in the file. Operators need to see capacity and remaining leaves without a separate tool, but a mutable field in a portable file is a reuse trap. Marking it authoritative: false keeps visibility while denying it any role at signing time.
Why commit-before-sign is normative, not advisory. It is the single ordering rule that prevents crash-induced reuse. Everything else in the spec is bookkeeping around it.
Synchronized vs counter. Synchronized keys map cleanly onto consensus duties and the slashing DB. Off-protocol duties (builder-bid signing being the motivating example) have no slot to key on and need a free counter and its own durable store. Both are specified so a single deployment can hold keys of each kind. Open issue for discussion: whether the lean profile mandates synchronized-only for protocol keys and confines counter mode to clearly-separated signing services.
Backwards Compatibility
v5 is not backwards compatible with v4 consumers, which assume a reusable 32-byte secret and have no notion of state authority. v4 and v5 keystores are distinguished by the version field and the presence of the scheme object. A v5-aware client must refuse to operate on a consumable key as if it were a v4 reusable key. v4 BLS keystores remain valid under their own standard and are out of scope.
Test Cases
To be added. At minimum: (1) round-trip encrypt/decrypt of a leanxmss seed; (2) refusal to sign on high-water regression; (3) crash-injection between signature computation and state persistence demonstrating no reuse on restart; (4) disjointness and exclusive-assignment checks for reserved ranges.
Reference Implementation
To be added.
Security Considerations
Leaf reuse is catastrophic and silent. Unlike a slashing event, reuse may produce no immediate on-chain penalty while fully compromising the key. The §4 ordering and §6 import rules are the primary defenses and must not be relaxed for performance.
Stale-restore is the dominant operational risk. Backups protect the seed but not the state. Operators must be guided toward recover-then-reconcile, never restore-and-sign. Detection of high-water regression (§6) is required.
Cloning across hosts. Running the same key on two hosts without disjoint reserved ranges guarantees reuse. Range assignment (§5) must be exclusive.
State store integrity. An attacker able to roll back the authoritative state can induce reuse. The state store should have integrity protection commensurate with the keystore itself.
Encryption strength. AES-256 and a memory-hard KDF mitigate Grover-accelerated password search; they do not and need not protect the signing scheme, which is post-quantum by construction.
Capacity exhaustion as availability risk. A key that exhausts its leaves can no longer sign. Capacity monitoring (§2.4) and conservative lifetime_leaves selection are operational requirements, not optional.