Repository navigation
feat: add the Groth16 terminal verifier, its export tooling, and cost measurements - #5
Merged
Merged
Conversation
Measure a complete 206,726-byte raw packet on a local Osaka Anvil node with the enforced 16,777,216-gas cap: verification 13,751,027 gas (calldata 3,173,300), deployment of all modules 144,547,906 gas. The same build forked from Sepolia at block 12066266 gives identical figures. The previous row was measured on a 182 KB packet from Ethereum block 26240087 and is replaced, since it no longer describes the current proof.
Measure the same complete shrink proof with the lossless field zero-run and full-hash dictionary transport: verification 13,628,720 gas, calldata 2,845,696 gas, packet 182,190 bytes, against 13,751,027 gas for the raw packet. Deployment is unchanged at 144,547,906 gas because it depends on bytecode size, not on the packet transport.
Move the Groth16 verifier and its adapter into contracts/ziren-groth16-verifier as a standalone Foundry project pinned to solc 0.8.30. The adapter is renamed ZirenGroth16ProofVerifier and implements IZirenProofVerifier, which is renamed from IZirenShrinkVerifier and shared with the metis output oracle. Add crates/ziren-groth16-export, which exports a Groth16 terminal proof as JSON, and scripts/groth16_args.py and scripts/groth16_verify.py, which convert the proof, deploy the verifier and adapter to a local node, and check the accept and reject cases. The output digest is computed from public_values.bin and must match the proof's committed value. Document the flow in docs/groth16-verification.md and link it from docs/development.md.
Move IZirenProofVerifier to contracts/shared and import it from both Foundry projects through the @ziren-shared remapping, replacing the two copies. Reword the interface doc to describe the contract rather than the shrink entry. Factor the repeated cast calls in groth16_verify.py into a helper, keep the adapter transaction check with the others, and wrap long lines. groth16_args.py returns a dataclass and reads the proof with Path.read_text. Reflow the adapter's contract comment.
Add Groth16VerifierTest, which runs the real Groth16Verifier on the fibonacci fixture proof: the proof and a public input are accepted or rejected as expected, and the adapter accepts the fixture packet through the real verifier. Update the measured figures in docs/groth16-verification.md and the shrink verifier README to the optimizer-enabled build. The verification transaction is 233,450 gas, the calldata share is 5,092 gas, the verifier deployment is 1,135,523 gas and the adapter deployment is 326,771 gas. Describe the proof as a Groth16 proof of the fibonacci guest and drop the earlier optimizer-off figures.
Split export_groth16 into three modes. prove runs setup, core proving, compression and native shrink, and saves shrink.bin and public_values.bin. replay wraps a saved shrink.bin with wrap_bn254 and wrap_groth16_bn254 without proving again. groth16 runs both steps in one process and writes only the proof JSON. Add zkm-primitives and bincode to the crate for the saved proof files, and update the Groth16 verification doc and the crate README to describe the modes.
replay now reads groth16_proof.json from a prove output directory and checks its layout. It runs no shrink, wrap or proving, and does not verify the proof cryptographically. Its argument check is fixed: replay takes two arguments, so the top-level check now requires two and each mode checks its own count. Restructure the export example around three modes. prove runs the whole chain through a prove helper. groth16 takes a saved compressed proof, and both groth16 and prove share groth16_from_compressed, which was previously named wrap_to_json. read_compressed rejects files shorter than the SDK tag. Name the encoded proof length as a constant. Update the crate README and the verification doc to describe the new modes and outputs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Measurements
Groth16 terminal, fibonacci guest (input 10), local Osaka Anvil with --gas-limit 60000000, optimizer enabled:
Shrink proof (206,726-byte packet): verification 13,751,027 gas, deployment of all modules 144,547,906 gas. With zero-run transport: verification 13,628,720 gas.
Testing
Not covered / open questions