verifier.cash
← back

How could we solve this?

The ~1.4× chunking overhead is not a property of Groth16 or of zero-knowledge proofs. It is an artifact of today's Bitcoin Cash per-input limits: the 10 KB contract-size cap, the op-cost budget that is derived from it, and the fact that every step has to re-ship the shared verifier bytecode. Each of those is something the protocol could change, and each change would shrink the overhead without any new cryptography.

Raise the contract-size cap

This is the biggest lever. Today a P2SH contract's bytecode is capped at 10 KB per input, and the op-cost budget is derived directly from that length ((41 + len) × 800), so the size cap and the compute budget are really one wall. Raising the cap does two things at once: each input could hold a far larger chunk of the verifier, and its op-cost budget would rise by the same order of magnitude.

This is not hypothetical. The draft CHIP-2025-01 TXv5 proposes raising the maximum bytecode length from 10 KB to 100,000 bytes (and the stack-element limit with it), explicitly motivated by zero-knowledge and post-quantum proofs that don't fit in 10,000 bytes. Even optimized for op-cost, the BN254 verifier needs roughly 9 inputs' worth of budget as a single input; lifting the cap an order of magnitude shrinks that to a handful of steps, with the standard transaction-size ceiling (100,000 bytes) as the natural upper bound.

Lower the base instruction cost

Another lever targets the op-cost formula itself. Lowering the base instruction cost (the flat per-opcode component) from 100 to 10 has been discussed before but was set aside. It would be a large lever, not a minor one: roughly 40% off a BN254 verifier's op-cost and 25% off a BLS one. The budget is dominated not by the few expensive field multiplies but by the tens of thousands of cheap glue ops (stack plumbing, serialization) that are almost entirely base cost, which is exactly what the change targets. Because it leaves the larger operand-length arithmetic untouched, the smaller-field BN254 gains about twice what BLS does.

Buy compute without the padding

The single largest slice of the overhead, 0% of the smallest fitting BN254 chain, is something even stranger: zero-padding. A step's op-cost budget scales with its script length ((41 + len) × 800), so the only way to afford more compute is to make the script physically longer. A verifier's field arithmetic is extremely compute-dense, far more op-cost per byte than ordinary contract code, so each chunk would blow its budget at its natural size. To fit, it appends thousands of zero bytes (one big push that is immediately dropped) purely to dilute the compute and lift the ceiling, which is why the padding ends up larger than the real code. Those bytes are never read, yet they are real on-chain data that gets relayed, stored, and paid for.

A dedicated way to buy compute would delete that waste. A step could simply declare the extra budget it needs; the transaction would still be billed for it as if the bytes were present, so the network's anti-denial-of-service accounting is unchanged (compute is still paid for at the same rate), but the padding itself would not have to be transmitted or stored. The cost is measured against virtual bytes while real bandwidth and storage drop to what the contract actually uses, removing the biggest single component of the chunking tax without weakening the limit it stands in for.

Read-only inputs

The other large slice of the overhead is the shared verifier code itself: the per-chunk function prologues are re-shipped in every input of the chain. Read-only inputs, also proposed in TXv5, fix that directly. They let a transaction reference and evaluate a UTXO without spending it, so commonly-used bytecode can live in one UTXO that every step points at by outpoint instead of re-including it. This is a well-established UTXO pattern, not a novel one: it has shipped for years elsewhere as Cardano's reference inputs, Ergo's data inputs, and similar constructs.

TXv5's own worked example is a ZKP covenant: the proof-verifying bytecode, possibly many hundreds or thousands of bytes, is held in a read-only input and omitted from each spending transaction (deduplicated in the blockchain), so the chain pays for the shared program once rather than once per step. That turns a per-step tax into a one-time setup cost.

Store and fetch off-stack constants

A narrower lever targets the glue itself. A verifier leans on large tables of baked constants, and today those ride on the stack, deep-picked up and down inside the hot inner loops. A future upgrade could give the VM dedicated storage opcodes (a mutable OP_STORE/OP_FETCH pair, or an immutable/mutable split such as OP_STORECONST/OP_FETCHCONST alongside OP_STOREVAR/OP_FETCHVAR) that keep those tables off-stack and read them back by index, removing much of the stack plumbing that the base-cost lever above flagged as the dominant op-cost. Because a step buys op-cost budget with zero-padding, trimming that glue lets a chunk stay under budget on fewer bytes, so the win lands as smaller on-chain size. These are smaller, incremental ideas than the levers above; they shave the edges rather than move the wall, but they point at where a future upgrade could keep chipping away. A few are sketched in the CHIP-2025-08 Functions discussion.

Benchmark the proposed bch-spec VM

Several of these levers are already bundled into a concrete proposal, so the leaderboard benchmarks them directly. Alongside today's rules it grades a bch-spec VM (libauth) that models the CHIP-2025-01 TXv5 upgrade, and the entries built for it show up on the leaderboard with a bch-spec badge. It raises the per-input script cap from 10 KB to 100,000 bytes and the op-cost budget's base length from 41 to 10,000, so an input gets (10,000 + unlocking length) × 800, up to 88,000,000 per input versus roughly 8,000,000 today. The standard unlocking, stack-element, and big-integer limits all rise to 100,000 with it. It changes only these limits, not the op-cost formula, so any given script spends the same op-cost on either VM. Note the 100-to-10 base instruction cost cut discussed above is not part of this proposal.

That headroom alone collapses the BN254 verifier from 10 inputs to 5 (191 KB) in one non-standard transaction, without touching the cryptography. It needs the upgrade, so it does not run on today's BCH, but it measures exactly how much of the chunking tax the size and compute limits account for. The spec also adds two opcodes a verifier can lean on: OP_POW, native exponentiation for the field arithmetic, and OP_EVAL, which evaluates a bytecode blob from the stack as a subroutine so shared code runs once instead of being re-shipped per step.

Why not native curve opcodes?

A recurring alternative is to skip these general limit changes and instead add elliptic-curve opcodes so contracts can do curve arithmetic natively. The trade-off is worth being clear about. Every lever above is general-purpose: a larger size cap, a cheaper base cost, real compute, and read-only inputs lower the floor for every contract while committing the protocol to nothing in particular, leaving a verifier as ordinary script that any future curve or proof system can replace. Native curve opcodes do the opposite. They bake one specific curve and more pre-quantum cryptography directly into consensus, and steer application developers toward building on it. Any honest case for them also has to start from the current best implementation in script, since that is the baseline they claim to improve on. Establishing that baseline is the point of this project, and the numbers show the gap is dominated by glue, padding, and re-shipped code rather than by the curve math itself, which is exactly what the general levers above already address.

Where this leaves the competition

These are protocol-level levers, not contract tricks: they describe how much of the gap is the network's to close in a future upgrade. The leaderboard measures where things stand under today's limits, so the competition is about getting as small as possible within them, while these changes would lower the floor for everyone at once. How it works covers those limits and the chunking design in detail.