EIP-196/197: putting zero-knowledge proofs on-chain
Verifying a zk-SNARK means doing elliptic-curve pairing math — thousands of field operations that, written as EVM bytecode, would cost more gas than an entire block holds. EIP-196 and 197 add that math as native precompiles, so a contract can check a proof in a few cheap calls. It's the quiet enabler of on-chain privacy and every validity rollup.
- contracts & the EVM
- precompiles (the idea)
Byzantium, October 2017. The REVERT chapter is the change from that fork you feel every day; this is the one that reshaped Ethereum’s future. It sounds narrow — two opcodes’ worth of elliptic-curve arithmetic — but it’s what first made verifying a zero-knowledge proof on-chain affordable, and from that one capability came private transactions and every validity (zk) rollup. The problem it solves is a brutal cost wall, and the tool it uses — the precompile — is one of Ethereum’s most important escape hatches. Let’s derive it.
The problem: pairings don’t fit in a block
A zk-SNARK A zero-knowledge proof that a statement is true (e.g. 'this batch of transactions is valid') which is tiny and fast to check, revealing nothing else. Verifying one requires elliptic-curve operations — in particular a pairing check. is wonderful because it’s small and fast to verify — but “fast” is relative to the operation it needs: an elliptic-curve pairing, plus curve additions and scalar multiplications. Those are heavy number-theory computations over large fields. Written as ordinary EVM bytecode — looping over field arithmetic opcode by opcode — a single verification would run to hundreds of millions of gas, far more than an entire block’s gas limit. On-chain proof verification simply doesn’t fit.
→ Step 2: let the protocol run the hard part.
Precompiles: native crypto at reserved addresses
The escape hatch is a precompile A built-in operation exposed at a reserved low address (0x01, 0x02, …). It's called exactly like a contract, but instead of running EVM bytecode the client executes an optimized native implementation, priced at a fixed gas cost reflecting its real work. . Instead of forcing the pairing through the EVM, the protocol provides an optimized native (C/Go) implementation at a reserved address, callable like any contract. EIP-196 adds addition and scalar multiplication on the alt_bn128 curve The elliptic curve (also called BN254) whose operations Byzantium made available: ecAdd at 0x06, ecMul at 0x07, and the ecPairing check at 0x08. Chosen because efficient SNARK systems target it. (ecAdd at 0x06, ecMul at 0x07), and EIP-197 adds the crucial pairing check (ecPairing at 0x08). Each is billed a fixed, modest gas cost matching what the operation actually takes a node — not what it would cost as bytecode.
→ Step 3: verify anything, reveal nothing.
The payoff: privacy and validity rollups
With the pairing check affordable, a contract can verify a SNARK in a handful of calls — and a SNARK can attest to almost anything while revealing nothing beyond “it’s true.” Two enormous applications grew directly from this. Privacy: a mixer contract can accept a proof that “I own a deposit in this set and haven’t withdrawn it” without revealing which deposit, enabling private transfers (the design behind Tornado Cash and Zcash-style schemes). And scaling: a validity rollup A layer-2 that executes transactions off-chain and posts a single succinct proof to L1 that the whole batch was valid. The L1 contract verifies the proof — cheaply, thanks to the pairing precompile — instead of re-executing every transaction. (zk-rollup) can prove that an entire batch of thousands of L2 transactions was executed correctly, and the L1 contract verifies that one proof instead of re-running the batch.