ERC: Quantum Bridge Shield

Quantova Inc proposes the Quantum Bridge Shield, an ERC that lets any bridge on Ethereum accept a cross chain message only when a committee has signed its batch with hash based signatures that a quantum computer cannot forge.

Why this matters now

Bridges on Ethereum are secured by committees that sign with secp256k1 ECDSA or BLS12 381. Shor’s algorithm recovers those private keys in polynomial time, and every committee public key and signature is already public, so the material can be harvested today and broken later. NIST IR 8547 proposes deprecating quantum vulnerable signatures from 2030 and disallowing them after 2035, and CNSA 2.0 sets the same transition window for signing. Bridges hold some of the largest pools of value on Ethereum and are the first place a recovered key becomes theft.

The construction

Each committee member holds an LMS key as specified in RFC 8554, approved in NIST SP 800 208 and listed in CNSA 2.0, over SHA 256 with 32 byte outputs, tree heights 5 to 25 and Winternitz parameters 1, 2, 4 and 8. A public key is 56 bytes and a W4 signature at height 10 is 2,508 bytes. Security rests only on SHA 256 and Keccak 256, about 128 bits against Grover search.

The committee signs the Merkle root of each message batch. The guard approves a root only on a strict majority of distinct unfrozen keys, records every used leaf as a hash of the digest and the signature, freezes any key that signs one leaf twice, and binds every digest to a domain tag, the chain identifier, the guard address and the epoch. Every root waits a minimum of 60 seconds before use, every action takes full effect or reverts, and hybrid mode pairs each LMS signature with ECDSA during migration.

Measured cost

  • LMS W4 verification at height 10 costs 185,093 to 223,979 gas, mean 204,807, over 16 signatures
  • Approval by 2 of 3 hybrid members costs 549,015 gas, and by 6 of 10 costs 1,686,595 gas
  • Accepting one message from an approved batch of 256 costs 7,078 gas
  • A LayerZero packet through the shield costs 128,683 gas
  • The worst committee rotation the guard accepts costs 12.44 million gas, 26 percent under the EIP 7825 cap of 16,777,216

Assurance

A NioLabs security assessment found no critical and no high severity issues. The reference implementation ships 55 contract tests with 512 run fuzzing, 24 rounds of byte level parity between the contracts and the signer kit, the RFC 8554 Appendix F vectors, 48 signer kit safety checks and a 12 step live run on a local Ethereum node, all in continuous integration.

Why Quantova

Quantova Inc built a post quantum stack from first principles. Every account on the Quantova network signs with ML DSA 65 under FIPS 204 or SLH DSA under FIPS 205, validators sign every block and finality certificate with ML DSA 65, nodes establish channels with ML KEM 768 under FIPS 203, and hashing is SHA3 256, with no elliptic curve cryptography in the settlement path. Smart contracts are written in Quanta, our own language, compiled by an attested compiler and executed in the QVM, our post quantum virtual machine. Running post quantum signatures in production taught us where key state, leaf reuse and rollback fail in practice, and the signer kit in this ERC carries that experience with durable leaf reservation, a monotonic high water mark and refusal of network file systems.

Feedback welcome on

  • the default parameter set, W4 at height 15 or 20
  • whether the committee size bounds fit real bridge operators
  • leaf bindings for bridge designs beyond the packet verifier binding in the draft

Draft pull request Add ERC: Quantum Bridge Shield by quantova-inc · Pull Request #2071 · ethereum/ERCs · GitHub

Reference implementation with security assessment, tests and benchmarks GitHub - quantova-inc/Quantova-bridge-guard: The first open source post quantum shield for bridges on Ethereum. Messages pass only with RFC 8554 LMS hash based signatures that quantum computers cannot forge. Proposed to Ethereum as the Quantum Bridge Shield ERC. Owned by Quantova Inc, MIT or Apache 2.0. www.quantova.org qstamp.org · GitHub

Nice to see the signer kit treat leaf state as the main risk. A few thoughts on the questions you asked, plus one on the guard.

On height 15 vs 20: I’d size it from the batch rate rather than pick one default. 2^15 is 32,768 leaves. At one batch per block (about 7,200 a day) a key lasts about 4.5 days, at one per minute about 22 days, before you count reserve leaves. 2^20 gives roughly 145 days and 2 years at those same rates. With the worst case rotation at 12.44M gas, I’d lean towards 20 as the default and let low volume bridges opt down.

On committee bounds: a frozen key can push the guard below threshold, and recovery means a new guard and shield. With 2 of 3, one frozen key leaves zero margin. Maybe the ERC should recommend n of at least threshold plus the number of keys you expect could be frozen or lost at the same time.

On the guard: is the used leaf record per guard? If the same key can be listed on several guards, a compromised or cloned signer could sign leaf N for guard A and leaf N again for guard B, and each guard only ever sees one signature. Can reportEquivocation on A accept a signature whose digest is bound to B, so the key freezes everywhere? Two one time signatures at the same leaf also reveal more of the hash chains, which matters on any guard where that leaf is still unused.

Thanks for the close read. All three points line up with how the shield is built.

On tree height, 2^20 is the right default for active bridges. It gives 1,048,576 leaves, roughly 145 days at one batch per block and about two years at one per minute. The cost of moving from height 15 to 20 is about 1,500 gas and 160 bytes per signature, and the reference signer kit builds a height 20 W4 key in roughly ten minutes on one core. Because one leaf signs a whole batch, operators extend key life further simply by batching more messages per root. The ERC will state height 20 as the recommended default, sized from the batch rate as you describe.

On committee bounds, the guard is designed to halt rather than accept a weakened quorum, and liveSignerCount exposes the remaining margin on chain for monitoring. With a strict majority threshold the margin is n minus t, so operators should size n so that n minus t covers the number of keys they could lose or see frozen at the same time. The ERC will carry that sizing rule explicitly.

On the guard, the used leaf records are per guard, and cross guard reuse is handled by design. reportEquivocation accepts any two valid LMS signatures from the same leaf of the same key, whichever guard their digests are bound to. A signer that signs leaf N for guard A and again for guard B can therefore be frozen on A, on B and on every guard listing that key, by anyone holding the two signatures. The signer kit keeps a single durable leaf counter and high water mark per key across all guards, so an honest signer never produces that pair in the first place. The ERC will make two rules explicit. A guard should not share a key with another guard, and where keys are shared, watchers must report on every guard listing the key. We are also evaluating binding the LMS identifier I to the guard at configuration, which would enforce one key per guard at the protocol level at no verification cost, and I would welcome views on it.

Thanks, that clears it up. Good to know reportEquivocation works across guards.

On binding I to the guard: I like it. It turns an ops rule into something the contract enforces, and since I is already hashed into every LMS computation it costs nothing at verify time. A few things I’d pin down in the ERC.

Derive I from the chain ID and the guard address, not the address alone. With CREATE2 the same guard address can exist on several chains, and one key would then still be valid on all of them.

Leave the epoch out of I. The digest already binds the epoch, and putting it in I would force new keys on every reconfiguration.

The guard address has to be known before key generation, so deployments need a fixed address (CREATE2 or a precomputed nonce). It also means the recovery path after a halt needs fresh keys for every member, not only the frozen ones. At ten minutes per key that’s fine, but worth stating.

And have the signer kit check I against the guard it’s signing for, so a misconfigured key fails locally instead of on chain.

Once this is in, would you keep the shared key mode at all, or make one key per guard mandatory?

The identifier binding i proposed is now final, and it is worth stating precisely, because the derivation you describe would weaken it.

Deriving all sixteen bytes of I from the chain identifier and the guard address gives every member of a committee the same I. RFC 8554 requires I to be unique per key pair. I is the domain separator that keeps hash targets distinct across keys, and a shared I lets an adversary attack every key on the guard at once, costing log2 of n bits of multi target margin for a committee of n.

my construction avoids this. The first eight bytes of I equal the first eight bytes of keccak256 over the chain identifier and the guard address, and the last eight bytes are drawn uniformly at random per key. The guard rejects any key whose prefix does not match and any committee containing a duplicate I. Each key is bound to exactly one guard on exactly one chain, with a 2^-64 chance of accidental validity elsewhere, and every key keeps a distinct identifier.

The rest follows directly from the design. The epoch is excluded from I because every digest already binds it. Guards deploy to precomputed addresses. Recovery after a halt is a new guard with fresh keys for every member, generated in parallel. The signer kit verifies the prefix against the chain and guard of every request before it touches leaf state.

One key per guard is mandatory, and shared keys are impossible by construction. The ERC specifies this, and the reference implementation enforces it.

Fair correction, thanks. I meant binding I to the guard, but as I wrote it every member would end up with the same I, and you’re right about the multi target cost. A guard prefix plus a random per key suffix gets you both properties.

Making one key per guard mandatory also removes the need for watchers to report on every guard, so the ERC gets simpler too. Looking forward to the next draft.