UPA Gas Costs
Delve into the end-to-end gas costs and savings that NEBRA UPA brings to zero-knowledge applications.
The high cost of verification is one of the biggest obstacles preventing applications from taking full advantage of zero-knowledge proof technology. Despite the hefty price tag, enough use-cases already exist to justify current spending of nearly $100 million/yr to verify proofs on Ethereum. Our thesis at NEBRA is simple: by slashing verification costs, we not only enable existing zk-apps to scale to new heights, but also pave the way for entirely new use-cases and applications for zero-knowlege proofs.
In this blog post, we delve into the gas savings that NEBRA UPA brings to zero-knowledge applications. Our current UPA release (v1.1) offers end-to-end gas savings of more than 70%. UPA is fully deployed on Sepolia testnet, ready for developers to integrate their applications. Improvements coming in the near future are slated to push these savings even further, to over 90%.
Verification cost without UPA
The cost of verifying an individual Groth16 proof and using the result can be broken down into two parts:
- Submitting and verifying the proof (~250k gas)
- Retrieving the verification result
- from an external contract (~10-20k gas)
- from within the app contract (0 gas)
Gas savings with UPA
Let's take a look at the end-to-end gas cost for a ZK app using NEBRA UPA. These are the three steps that can consume gas, along with their current per-proof costs. (The exact costs may vary a bit based on the details of the application):
- Submitting proofs
- on-chain (~23-100k gas per proof- depends on submission size)
- off-chain (0 gas per proof)
- Verifying the aggregated proof (~18k gas per proof)
- Querying the verification result (~25k gas per proof)
Summing up these costs, we find that in total:
- Applications submitting their proofs on-chain can save as much as 184k gas (~75%) per proof.
- Applications submitting their proofs off-chain can save upwards of 207k gas (~85%) per proof.
The cost of each step can be further reduced with greater amortization. For example, we can increase the aggregation batch size, which is currently set to just 32 proofs. And, as we discuss in the gas cost breakdown, we also expect to see lower submission and query costs coming from continued development of the UPA contracts and additional features.
As always, the set of factors that go into an apples-to-apples comparison depend on the use case. For instance, the third query step is an "extra" cost for applications that would normally verify the proof inside the app contract. But for applications that use ZK co-processors (such as Brevis or Bonsai), this external query cost is already "built-in" to the app's protocol. With the breakdown of costs to follow, developers can take the right factors into account to determine where NEBRA UPA can offer them gas savings.
See our Gas Estimator to calculate the gas savings for your particular apps.
Breakdown and scaling of UPA gas costs
Step 1: Proof submissions
NEBRA UPA collects submissions of one or more proofs and places them in a queue to be aggregated. Note that UPA does not aggregate submission-by-submission. Instead, aggregated batches are chosen independently of the way the proofs were submitted.
Applications will have two options for sending submissions to UPA: on-chain and off-chain. On-chain submissions cost gas in exchange for censorship-resistance. Off-chain submissions have no gas cost, but offer weaker censorship resistance.
Our current UPA release (v1.1) supports on-chain submission. Off-chain submission will be available soon.
Cost of on-chain submission
Due to per-transaction storage costs, using a whole Ethereum transaction to submit a single proof is relatively expensive. Instead, we recommend that apps take advantage of multi-proof submissions.
The contracts currently deployed to the Sepolia testnet are initial implementations with large scope for gas optimization, but they serve to illustrate the approximate cost model. Currently, the fixed cost per submission is ~100k gas. The marginal cost of each additional proof in a submission is ~20k gas (for processing the additional proof and public input data).
Therefore the per-proof gas cost for an on-chain submission of $M$ proofs is approximately:
$$100000/M + 20000$$
The table below shows the measured cost of submissions of different sizes.
On-chain submission size | Total gas cost | Per proof gas cost |
---|---|---|
4 (Etherscan) | 191,829 | 47,957 |
8 (Etherscan) | 269,867 | 33,733 |
16 (Etherscan) | 424,891 | 26,559 |
32 (Etherscan) | 734,388 | 22,963 |
As we iterate the contracts and introduce more optimizations, we expect to significantly reduce the costs shown here.
Step 2: Aggregated proof verification
The current version of NEBRA UPA aggregates proofs into a Halo2-KZG proof. The cost of verifying such a proof in isolation is about 350k gas, and is roughly independent of batch size. In addition, the UPA contract emits an event and updates its storage to mark each application proof in the batch as verified. This incurs a marginal per-proof cost of about 7k gas.
Therefore the per-proof gas cost for verifying one batch of $N$ proofs and storing the result is approximately:
$$350000/N + 7000$$
The current configuration of NEBRA UPA sets the batch size to $N=32$. With this batch size the aggregated verification cost comes out to ~18k gas per-proof (Etherscan).
Step 3: Querying the verification result
Once a proof has been verified by the UPA contract, the app contract may query the UPA contract to confirm that the associated public inputs are valid. This typically looks like:
require(upaVerifier.isVerified(circuitId, publicInputs, "Not verified");
The gas cost of this external contract call is about 25k gas per proof.
In the near future, apps will be able to amortize this cost by checking that a whole multi-proof submission has been verified instead of checking each of its proofs individually.
End-to-end gas savings
Using on-chain submission
With UPA, assuming submissions of size $M$ and proof aggregations of size $N$, the total end-to-end per-proof gas cost with on-chain submissions comes out to about:
$$100000/M + 350000/N + 52000$$
Concretely, with submissions of $M=32$ proofs and aggregations of $N=32$ proofs, this per-proof gas cost comes out to
$$100000/32 + 350000/32 + 52000 \approx 66000$$
which represents a savings of about 184k gas (~75%).
Using off-chain submission
The end-to-end gas cost with off-chain submissions will be approximately:
$$350000/N + 32000$$
With the current UPA configuration of $N=32$, the per-proof cost comes out to
$$350000/32 + 32000 \approx 43000$$
which represents a savings of about 207k gas (~85%).