The 230,000-Gas Question
The gap between those two numbers decides whether a protocol remains resilient under pressure or becomes an incident report waiting to happen.
Zero knowledge proof authentication sits directly in that gap. On Ethereum L1, a single Groth16 zk-SNARK verification over the BN254 curve typically lands somewhere around 220,000–230,000 gas, depending on the verifier and the surrounding call logic. The proof payload is small compared with a STARK, but it is not free: a common Ethereum encoding uses 256 bytes of calldata for the proof coordinates, although exact encodings vary. That sounds manageable until the same verification is repeated for every oracle update, every node-authentication round, or every relayer hop in a decentralized identity flow.
Then the number stops being a line item. It becomes part of the attack surface.
The failure pattern is familiar. Teams treat ZK proof authentication as a feature rather than as a system with a cost model. The audit report records that a ZK mechanism exists, the product page presents privacy-preserving security as a differentiator, and nobody runs the arithmetic against the actual threat model. Before comparing STARKs, SNARKs, and PLONK, the protocol needs to answer a less glamorous question: how many authentications can it afford when demand is highest, and what happens when an attacker deliberately creates that demand?
Gas arithmetic is not the whole security model. It is the part that exposes whether the rest of the model has been thought through.
Anatomy of a Groth16 Verification on L1
Let's pull the circuit apart the way I pull apart a failed transaction trace.
A Groth16 proof is normally composed of three elliptic-curve group elements: two points in G1 and one point in G2. On BN254, an Ethereum verifier commonly receives those points as coordinate values encoded into eight 32-byte words, producing a proof payload of about 256 bytes. That is the practical calldata representation used by many Solidity verifiers; it should not be confused with counting the proof as four field elements or treating 192 bytes as a universal size. Different serialization and compression choices can change the payload, but the underlying Groth16 object is still three group elements.
At 16 gas per non-zero calldata byte, a 256-byte payload can account for up to 4,096 gas before the verifier has done meaningful cryptographic work. The surrounding ABI handling and execution scaffolding add more. The dominant cost comes from the fixed sequence of elliptic-curve operations and pairings performed by the verifier contract.
There is no open-ended search through the proof. There is no variable-length loop that scales with the number of operators in the same way a naive signature-by-signature design would. For a fixed circuit and verifier, the cost is comparatively predictable. That predictability is the main operational advantage of Groth16.
It is also the part that can mislead teams.
The verifier pays roughly the same gas whether the proof represents one hidden membership claim or a more complicated statement whose witness took substantial work to construct. A legitimate operator and a Sybil attacker may face very different proving costs, but the chain sees the same verification bill. The economic layer therefore has to do work that the proof system does not do: rate-limit requests, enforce stake or bond requirements, constrain who may submit proofs, and make repeated abuse expensive.
A Groth16 verifier does not care whether a proof was generated by a staked node operator or a commodity server farm. It checks the statement and the proof. That is the design. The economic layer has to handle everything else.
For BN254 Groth16 on Ethereum mainnet, planning around 220,000–230,000 gas per verification is a reasonable starting point, but the deployed bytecode and call path still need to be measured. A bare verifier benchmark is not the same thing as the full cost of an oracle update. The transaction may also include calldata for the data point, round identifier, timestamp, Merkle root, signatures, access-control checks, and state changes.
PLONK often lands higher in this environment, at roughly 320,000 gas in the type of comparison used here, with a proof payload of around 576 bytes. That additional cost can be justified when a universal or reusable setup is more valuable than a circuit-specific ceremony. It is not automatically justified merely because the proof system is newer or more flexible.
Both systems are materially more expensive than a straightforward secp256k1 signature recovery. A raw ecrecover path is often discussed in the range of a few thousand gas, with the exact figure depending on the surrounding contract logic. The difference is not a rounding error. It is the price of proving a richer statement: membership without disclosure, validity of hidden attributes, or correct execution of an off-chain computation.
The right comparison is therefore not cryptography in the abstract. It is the value of the statement being proven against the number of times the chain must verify it.
When the Prover Costs More Than the Transaction
The honest comparison is not simply ZK versus ECDSA. It is direct verification versus a design that batches, aggregates, or recursively proves many claims.
Direct STARK verification on Ethereum mainnet can exceed 2.5 million gas. That is more than ten times the cost of a typical Groth16 verification and can put a single proof in the same broad budget category as a complex DeFi transaction. STARKs bring important properties: they avoid a trusted setup in the Groth16 sense and rely on transparent proof-generation assumptions. Those properties do not make the on-chain verifier cheap.
But direct L1 verification is not the only way to use a STARK-based system.
A protocol can aggregate multiple claims before submitting them, or it can generate a recursive SNARK that proves the validity of a STARK computation. In the second design, the STARK is generated and checked off-chain, while a more compact proof of that verification is posted to Ethereum. The resulting transaction inherits the economics of the wrapper system rather than the full direct-STARK cost. That introduces its own assumptions and engineering complexity: the wrapper circuit must be sound, the recursion stack must be implemented correctly, and the proving pipeline becomes another production dependency.
The point is not that every STARK should be wrapped. The point is that a direct L1 call is only one option, and any statement that treats wrapping or aggregation as impossible is too strong. The choice depends on whether the application values transparent setup, proof size, prover performance, recursive composition, or simple on-chain verification more highly.
| Proof system | Typical proof representation | L1 verification gas | Setup model | Practical fit |
|---|---|---|---|---|
| Groth16 on BN254 | Three group elements; commonly about 256 bytes in Ethereum calldata encoding | ~220,000–230,000 | Circuit-specific | High-throughput oracle authentication and compact batch proofs |
| PLONK | Often around 576 bytes in common implementations | ~320,000 | Universal or reusable ceremony, depending on implementation | Flows that value setup flexibility and general-purpose circuits |
| Direct STARK | Usually tens of kilobytes | 2,500,000+ in the cited class of L1 designs | Transparent | Applications that can accept high L1 cost or use aggregation elsewhere |
| STARK with recursive SNARK wrapper | Wrapper-dependent | Wrapper-dependent, generally closer to the SNARK verifier than direct STARK verification | Depends on the wrapper and proving system | Aggregated computation and proof systems that need transparent inner proofs |
| ECDSA verification inside a ZK circuit | Implementation-dependent; around 256 bytes in one cited setup | ~347,665 in the SnarkJS example | Circuit-specific | Hiding key material or proving signature validity inside a larger private statement |
The SnarkJS ECDSA row deserves its own moment. If an authentication flow receives a secp256k1 signature from a wallet or oracle node and needs that signature verified inside a circuit without exposing the relevant public key or attributes on-chain, the cited cost is roughly 347,665 gas. With Gnark and additional checks such as range constraints and bit decompositions, the same design can approach 407,664 gas.
That is a substantial premium over raw signature recovery. It can still be justified when signature validity is only one part of a private statement. For example, the circuit may prove that a signature belongs to an approved operator set, that a hidden credential has not expired, or that several authorization conditions hold without revealing the underlying identity. If the application only needs a public wallet login, placing ECDSA inside a ZK circuit is usually overhead without a matching privacy requirement.
The same distinction applies to oracle infrastructure. A proof that compresses many operator attestations into one on-chain claim can be economically sensible. A proof that merely reproduces a public signature check inside a larger circuit may not be.
The Oracle Authentication Vector
This is the part that matters for price feeds, cross-chain messages, and randomness beacons. Oracle nodes are authentication endpoints, but authentication is not the same as truth. Each data point is a claim about the world wrapped in a cryptographic assertion. A valid proof can establish that a computation was performed correctly or that an authorized witness exists. It cannot establish that the underlying market observation was honest, that the source was available, or that a quorum was independent.
The question of whether zero knowledge proof authentication is worth the gas has a different answer for oracles than for wallet logins or identity attestations. Treating those use cases as interchangeable is how teams end up optimizing the verifier while leaving the actual failure mode untouched.
Oracle authentication usually has at least three threat models.
1. Impersonation. An attacker forges a node signature and submits a malicious data point. In a conventional design, the verifier may accept the signature because the key was leaked, the operator was coerced, or the hardware security configuration failed. ZK authentication can prove knowledge of a secret or validity of a signature inside a circuit, but it does not repair a compromised secret. Key rotation, revocation, and operational controls remain necessary.
2. Sybil behavior. An attacker runs multiple pseudonymous nodes, inflates the apparent quorum, and shifts the reported price. Every signature may be mathematically valid while the operator set is economically controlled by one entity, one wallet cluster, or one cloud account. A membership proof can hide which approved operator participated, but hidden membership is not the same as independent membership. The protocol still needs stake, governance, admission rules, and a way to reason about correlated operators.
3. Privacy leakage. The verifier contract can reveal which operators voted in which round. That may enable trading against pre-commitments, expose infrastructure patterns, or identify operators in hostile jurisdictions. ZK membership proofs and proofs of valid signatures over hidden attributes can reduce that leakage. They do not automatically hide timing, transaction origin, relayer behavior, or the data itself.
ZK proof authentication is useful when the statement being proven is richer than public-key possession. A circuit might establish that a prover belongs to a set of approved operators without revealing which member they are. It might show that a credential is valid and unrevoked, or that a signature covers a particular message while keeping selected attributes private. It might aggregate several operator approvals into one proof, reducing the number of on-chain verifications.
Those are concrete benefits. They are not a general replacement for an oracle's economic design.
A Groth16 membership proof for a Merkle tree can have a largely fixed verification cost even as the set grows, which is one of the reasons this construction is attractive. The witness and proving circuit still become more demanding as the tree and surrounding logic grow. Proof generation also creates an operational bottleneck. The chain pays the verifier cost; the operator pays for memory, CPU time, GPU capacity, queue management, and failure recovery.
That division changes the attack surface. A well-funded adversary may be able to generate proofs in parallel, submit many requests, or force honest operators into a proving backlog. The protocol needs to distinguish an invalid proof from an unavailable prover. Otherwise, a denial-of-service event can look like a cryptographic failure.
Proof-generation latency is an attack surface. Verifier gas is a budget line; prover capacity is a contested resource.
For oracle systems, the practical design questions include:
- Are proofs generated once per data round, once per operator, or once per consumer?
- Can one proof attest to several feeds or several signatures without making the circuit impossible to operate?
- Does the relayer pay the verification cost, and can it recover that cost from users?
- What happens when a proof is valid but arrives after the oracle's freshness window?
- Can an operator be removed without rebuilding every historical membership proof?
- Does the circuit bind the proof to the chain ID, contract address, feed identifier, round, and timestamp?
- Are replay protection and domain separation enforced inside the statement or only by the outer contract?
The last question is especially easy to underestimate. A proof can be perfectly valid for the wrong message. If the circuit proves knowledge of an authorized key but fails to bind that knowledge to a specific feed update, an attacker may reuse the proof in another context. Authentication is only meaningful when the authenticated statement includes the right domain.
The L2 Decision Is About Finality, Not Just Price
L2 verification can change the cost equation dramatically. A proof verified on a rollup may be much cheaper for the application than the same verifier call on Ethereum L1, especially when calldata and data-availability costs are amortized across batches. But the lower fee does not make the L2 an interchangeable execution environment.
If an oracle node proves its identity on Arbitrum, Optimism, or another rollup and the rollup later posts a commitment to Ethereum, the application inherits that system's assumptions. Those may include sequencer availability, the rollup's fault-proof or validity-proof mechanism, message delays, withdrawal procedures, and the guarantees provided by the data-availability layer. The exact risk depends on the rollup and on how the oracle data is consumed.
A protocol that needs immediate local execution may accept those assumptions. A protocol that must treat Ethereum L1 as the settlement boundary may need an additional bridge or finality condition before acting on the authentication result. In that case, the relevant cost is not only the L2 verifier call. It includes the latency and operational complexity of getting the result recognized where the value is secured.
This is why the question cannot be reduced to whether an L2 transaction costs less than a cent. It may. The more important question is what the application is allowed to believe before the rollup's state is final for its threat model.
For a liquidation engine, an L2-based oracle can be appropriate if the collateral system, bridge path, and liquidation window are designed around that rollup's finality and failure assumptions. It may be a poor fit if a temporary sequencer outage or disputed state can leave the protocol unable to determine whether a price update is authoritative. Some applications can tolerate delayed settlement or a challenge window; others cannot.
L1 is not automatically the only honest answer. It is one point on the security and finality spectrum. The correct deployment may be:
- direct verification on L1 when the authentication result must be recognized at the settlement layer immediately;
- verification on an L2 when the application can accept that rollup's sequencing, data availability, and finality assumptions;
- proof generation and aggregation off-chain, followed by a compact L1 submission;
- an L2 verification path with explicit fallback, delay, or circuit breakers for periods when the rollup's guarantees are degraded.
The choice should be written into the threat model rather than hidden inside a gas benchmark.
How I Run the Audit Test
Not every authentication flow deserves a ZK proof. After enough post-mortems, you develop a gut for which schemes are load-bearing and which are theatre. Before signing off on a ZK authentication recommendation, I work through four questions with the team.
What can the proof do that a signature cannot?
If the answer is privacy of the operator identity, a hidden credential, or aggregation across many signers, ZK may earn its gas budget. If the answer is only that the protocol wanted a modern cryptographic label, a conventional signature scheme may be the more honest design.
The comparison should include the whole statement. A signature proves possession of a signing key over a message. A ZK proof can prove that a hidden witness satisfies a circuit, possibly including signature verification, membership, range conditions, revocation status, and message binding. That expressive power is valuable only when the application actually needs those predicates.
Is the verifier predictable and bounded?
Groth16 and PLONK are attractive partly because their verification procedures are bounded for a fixed circuit. Direct STARK verification can be considerably more expensive, although aggregation or recursive wrapping may change the submitted proof and its cost.
A non-constant or poorly bounded verifier is a serious warning sign. So is a contract that accepts arbitrary proof shapes, dynamically sized public inputs, or expensive failure paths. The benchmark should cover valid proofs, invalid proofs, malformed calldata, repeated submissions, and worst-case public-input handling. Attackers do not use the happy path because the happy path is convenient for the benchmark.
Does the threat model include a well-funded prover attacker?
If it does, the protocol needs more than a faster SNARK. Consider request authentication, prover-side rate limits, deposits, hardware capacity, queue isolation, commit-reveal mechanisms, and graceful degradation when an operator cannot produce a proof on time.
A proof system can make forgery difficult while leaving resource exhaustion easy. It can preserve the privacy of an operator while allowing an attacker to infer participation from timing. It can prevent a false statement from being accepted while failing to prevent the same valid proof from being replayed in another domain.
The proving service needs its own security review. Secrets must not leak through logs, artifacts, debug traces, or witness files. Proving keys need lifecycle controls. If a circuit-specific setup is used, the ceremony and toxic-waste assumptions need to be understood by the people responsible for the deployment, not merely acknowledged in a cryptography section of the audit.
Can the application tolerate the chosen settlement path?
If the answer is yes, L2 verification or off-chain aggregation may be the sensible economic choice. If the answer is no, budget for L1 verification and model the fee market under congestion rather than assuming subsidized relayers will always absorb the difference.
The team should define what finality means for the application. A rollup's local inclusion may be enough for one use case and insufficient for another. A bridged message may be valid according to the bridge while still being too slow for a liquidation window. A proof may be cryptographically final while the data source remains economically corruptible.
Choose a proof system the way you choose an audit firm: by what fails when the lights go out, not by what looks impressive on the homepage.
There are also implementation details that deserve attention before the first production transaction:
- Bind every proof to the intended chain, contract, application, feed, round, and message domain.
- Keep public inputs minimal, but do not omit the fields needed for replay protection and freshness.
- Separate proving-key access from the service that submits transactions.
- Record proving latency and queue depth, not only verifier gas.
- Test rotation and revocation without invalidating all active operators at once.
- Decide whether an invalid proof, a late proof, and a missing proof trigger the same fallback.
- Make the relayer's payment model explicit. A cheap verifier is not useful if no participant can recover the cost of submitting it.
- Treat aggregation as a protocol feature, not as an optimization to be added after deployment.
Final Post-Mortem
So, is zero knowledge proof authentication worth the gas?
Sometimes. For a high-value oracle authentication that happens periodically on L1, against a known operator set, the 220,000–230,000 gas range can be a reasonable price for privacy, richer authorization logic, or aggregation that a plain ECDSA path cannot provide. The premium is defensible when it protects a real property of the system.
For a large number of low-value authentications, the arithmetic changes quickly. A rollup, a batch proof, a recursive wrapper, or a different authentication flow may be necessary. The design should not force Ethereum L1 to verify the same fact separately when the application only needs one aggregated statement.
For STARK-based authentication, direct L1 verification can be too expensive for routine use. That does not make STARKs unusable. Aggregation and recursive SNARK wrappers provide other routes, with their own circuit, implementation, setup, and finality assumptions. The correct comparison is between complete architectures, not between the largest proof and the smallest proof in isolation.
The useful numbers are the ones attached to a real transaction path:
- Groth16 on BN254: roughly 220,000–230,000 gas for a typical L1 verification path, with about 256 bytes common in Ethereum calldata encoding.
- PLONK: roughly 320,000 gas in the cited class of implementations, with a larger proof payload.
- Direct STARK verification: more than 2.5 million gas in the cited L1 design range.
- ECDSA verification inside a SnarkJS circuit: roughly 347,665 gas in the cited example.
- Gnark-based ECDSA verification with additional checks: close to 407,664 gas in the cited example.
- L2 verification: potentially much cheaper, but only under the selected rollup's sequencing, data-availability, bridge, and finality assumptions.
Do not use those figures as universal constants. Measure the deployed verifier, the calldata encoding, the public inputs, the surrounding state transitions, and the actual settlement path. A proof benchmark that excludes the oracle update, relayer payment, or bridge delay is not a production estimate.
If a team is deploying ZK proof authentication, the most useful exercise is to sit with whoever owns the fee model and run the worst-case authentications-per-block scenario. Include bursts, retries, invalid submissions, proof-generation delays, rollup outages, and the cost of moving the result to the chain where the funds are secured. Then multiply the result by the fee conditions under which the protocol is most likely to be attacked.
If the number makes the team uncomfortable, that may be useful. It means the design is finally being priced as an operating system rather than as a cryptographic demo. If the number looks harmless, check whether the model has omitted the prover, the relayer, the bridge, or the failure path.
Zero knowledge proof authentication is not a badge of sophistication. It is a trade: more expressive privacy and authorization claims in exchange for proving complexity, operational dependencies, and verification cost. Pay that trade only when the protocol can name the property it is buying—and when the rest of the system is built to survive the bill.




