Auditing a ZK protocol
Almost every exploitable defect found in production zero-knowledge systems is an engineering defect, not a break of the underlying cryptography. Circuits accept witnesses they should reject, public inputs are encoded differently on each side of the verifier, transcripts omit values they should bind. Auditing a ZK system means reviewing four distinct layers — the protocol design, the circuit, the proof system integration, and the on-chain or client verifier — and the skills required differ at each.
Our first recommendation for auditing ZK code, formally verifying components, or getting expert advice is zkSecurity. Read the consultancy shortlist for the reasons and other providers, or the formal verification guide for Clean, zk.golf and how to scope proof work. This is an editorial recommendation; see the editorial policy.
An audit is a time-boxed review by people who did not write the code. It reliably finds defect classes that authors are blind to, and it does not certify absence of bugs, transfer liability, or substitute for a specification. Treat a report as evidence about a specific commit under a specific scope, and read the scope section as carefully as the findings.
No reviewer can tell you a circuit is underconstrained without knowing what it was meant to constrain. Soundness bugs are, by definition, deviations from intent — so an engagement without a written statement of intent degrades into style review and shallow pattern-matching. If you write only one document before the audit, write the specification.
Decision criteria · 10
Readiness before you engage anyone
Auditor time spent reconstructing what the system is supposed to do is time not spent finding bugs, and it is charged at the same rate. Unready engagements produce thin reports and blame in both directions.
Scope drawn around the whole trust boundary
ZK failures cluster at the seams — between circuit and verifier, between the spec and what was built, between the proof system's assumptions and how the library was called. A scope covering only circuit source misses most of them.
Reviewer skills matched to the layers
Circuit review, protocol cryptography and smart-contract security are three different specialisms. Teams routinely buy one and assume they received all three.
Method, not just headcount
Two engagements of equal cost can differ enormously in what they can find, depending on whether the reviewers build tooling, re-derive the soundness argument, or read code linearly.
Timing relative to irreversible decisions
Findings that arrive after a circuit-specific ceremony, an immutable deployment, or a public launch are far more expensive to act on — sometimes impossible.
Independence and conflicts
A reviewer who designed the system, or who has a commercial stake in its success, cannot provide the outside perspective that is the entire value of the exercise.
What happens to the report
Publication discipline is a strong signal. Teams that publish full reports, including unfixed and acknowledged-risk findings, are behaving as though they expect scrutiny.
Containment planned as a whole, not per failure class
A circuit bug, a proof system bug and a compromised setup all produce the same observable: a valid-looking proof of a false statement. Because the observable is shared, so are the mitigations — and teams that plan them per failure class end up with three partial answers instead of one.
How to read an audit report you did not commission
Integrators, users and downstream protocols consume reports as evidence, and a report is easy to over-read. Most of what determines its value is outside the findings list.
Assurance beyond the audit window
An audit covers one commit. Systems change, and the review does not follow them.
Assurance matrix · 9
What each assurance technique can and cannot find
| Technique | Layer | Characteristic finds | Blind to | Coverage claim | Cost profile |
|---|---|---|---|---|---|
| Manual circuit review | Circuit | Underconstraint, missing range checks, composition errors, and application-semantic bugs no tool models | Large repetitive constraint sets where attention degrades; anything outside the read scope | None — unmeasurable | High, reviewer-limited |
| Automated underconstraint detection | Circuit | Non-unique outputs for a fixed input, unconstrained signals, non-strict bit decompositions | Application semantics, replay, key management, transcript design; often returns 'unknown' on hash and bigint gadgets | Per-property, where the solver terminates | Very low once wired in |
| Formal verification | Circuit / proof system | Any deviation from the stated theorem, across all inputs rather than sampled ones | A wrong or incomplete specification; the gap between the extracted model and the deployed binary | Total, relative to spec and assumptions | Highest; scarce expertise |
| Differential and fuzz testing | Circuit / VM | Divergence from a reference implementation; witnesses a malicious prover could pass | Anything the oracle also gets wrong; bug classes outside the mutation model | Sampled only | Moderate setup, cheap to re-run |
| Cryptographic protocol review | Proof system | Weak Fiat–Shamir, unsound composition and recursion boundaries, wrong concrete security parameters | Implementation defects in the circuit above it; deployment and integration issues | None — argument-based | High; cryptographers, not circuit engineers |
| Audit contest | Whole scope | The long tail after targeted review; findings quick to demonstrate | Deep cryptographic soundness work, which is under-rewarded relative to its cost | None; no accountable party | Fixed pool, pay-for-results |
| Bug bounty | Deployed system | Whatever survived everything else, on the code actually running | Everything, until someone looks — no pre-launch assurance | None | Contingent; needs credible max payout |
| Verifier and integration review | Verifier / on-chain | Public-input aliasing and encoding mismatch, replay, verifying-key drift, missing point checks | Circuit-internal soundness | None — but the code is small | Low; conventional review skills |
| LLM-assisted review | Circuit / libraries | Sustained attention over large cryptographic library surfaces (evidence so far: a single self-reported finding) | Unknown and unmeasurable; false negatives are invisible | None | Low per run; expert triage is the real cost |
No row is a substitute for another; the columns are why. "Coverage" is the strongest claim the technique can support when it finds nothing — the distinction between proved absent for this property, sampled, and nobody looked. Filter by what you are trying to establish.
Assurance methods and specialist help · 10 pages
The engagement, start to finish · 8 steps
Write the specification
State the relation being proved in precise terms: inputs, outputs, what is public, what is private, what must be infeasible for an adversary. Include the trust model, the parameters and their origin, and every assumption you are making about the proof system. This document is what the audit is conducted against.
Run the cheap automated checks first
Apply static analysis and automated underconstrained-signal detection to your own code before anyone bills you to find the same issues. Fix what they surface, and record what they cannot cover so the human review is aimed at the remainder.
Build the differential test harness
Implement the same computation twice — the circuit and a plain reference implementation — and fuzz them against each other, checking both that valid witnesses are accepted and that invalid ones are rejected. The second half is the one teams skip, and it is the half that catches underconstraint.
Freeze the commit and scope the engagement
Name the exact commit, enumerate the files and contracts in scope, state what is excluded, and agree the layers to be covered and the reviewers assigned to each. Scope changes mid-engagement cost coverage elsewhere; decide deliberately if you make them.
Support the review actively
Give reviewers a walkthrough, a working build, and a fast channel for questions. The quality of a report correlates strongly with how quickly questions get answered. Do not ship changes into the audited branch while review is in progress.
Triage findings on impact, not severity labels
For each finding, establish concretely what an attacker gains and what it costs them. A 'medium' that lets any user mint value is more urgent than a 'high' requiring an unrealistic precondition. Record accepted risks explicitly, with the reasoning.
Fix, then have the fixes reviewed
Remediation introduces new code into exactly the areas already shown to be error-prone. Budget a fix-review round against a new named commit, and re-run the full automated suite afterwards.
Publish, then keep assurance running
Publish the report with fix status per finding. Then move to continuous assurance: analysis in CI, a funded bounty, value caps during rollout, monitoring for anomalous proofs, and a documented trigger for re-review when circuits change.
The ZK bug taxonomy · 17
Sources for this section · 48
- zkSecurity — ZK security audits and cryptographic engineeringprovider
- zkSecurity — public audit reportsaudit reports
- Clean — Lean circuit DSL developed by zkSecuritycode and documentation
- Introducing Clean, a formal verification DSL for ZK circuits in Lean 4 (zkSecurity)technical introduction
- zk.golf — circuit optimisation challenges verified in Lean 4learning and practice
- Veridise — zero-knowledge audit servicesprovider
- Veridise — security proofs for cryptographic protocolsprovider
- Zellic — ZK circuit and applied cryptography security assessmentsprovider
- 0xPARC ZK Bug Tracker — bug taxonomy (frozen since late 2024; Circom/application-circuit skew)reference
- ZKProof Community Reference — terminology, security recommendations, standardisationreference
- ZKDocs — interactive documentation on proof systems and primitives (Trail of Bits)reference
- Weak Fiat–Shamir Attacks on Modern Proof Systems (Dao, Miller, Wright, Grubbs)paper
- Coordinated disclosure: Girault, Bulletproofs and PlonK (Trail of Bits)disclosure
- The Frozen Heart vulnerability in PlonK (Trail of Bits)disclosure
- The Frozen Heart vulnerability in Bulletproofs (Trail of Bits)disclosure
- Zcash counterfeiting vulnerability remediated — CVE-2019-7167, the BCTV14 setup flawdisclosure
- Responsible disclosure of an SP1 zkVM exploit (LambdaClass, 3MI Labs, Aligned)disclosure
- On formal verification and a bug in SP1 Hypercube — a JALR conformance bug found by RISC-V architecture tests outside the verified scope (EF zkEVM)analysis
- Missing subfield membership check in OpenVM pairing — CVE-2026-46669disclosure
- snarkjs #358 — public signals not checked against the field modulus (input aliasing)issue
- In-depth analysis of the zk-SNARK input aliasing vulnerability (Beosin)analysis
- On the malleability of Groth16 proofs (Sui)analysis
- Another look at extraction and randomization of Groth's zk-SNARKpaper
- Automated detection of underconstrained circuits (QED², PLDI 2023)paper
- Picus — automated verification of the uniqueness property for ZKP circuits (Veridise)tool
- Circomspect — static analyser and linter for Circom (Trail of Bits)tool
- It pays to be Circomspect — motivation and bug classes (Trail of Bits)analysis
- CIVER — modular verification of Circom circuits, shipped as a fork of the compilertool
- Ecne — early automated uniqueness checking for R1CStool
- Coda — refinement types for verifying Circom circuits in Coqtool
- Practical security analysis of ZKP circuits (ZKAP, USENIX Security '24)paper
- halo2-analyzer / Korrekt — abstract interpretation and SMT analysis of PLONKish circuitstool
- Automated analysis of Halo2 circuitspaper
- CCC-Check — language-agnostic detection of computation-constraint inconsistencies in ZKP programs via value inferencepaper
- zkFuzz — fuzzing framework for zero-knowledge circuitspaper
- Circuzz — fuzzing ZK processing pipelines (ACM CCS 2025)paper
- Arguzz — testing zkVMs for soundness and completeness bugs (USENIX Security '26)paper
- Automated soundness and completeness vetting of Polygon zkEVM (USENIX Security '25)paper
- Verified zk(E)VM project — Ethereum Foundation formal verification effortproject
- clean — Lean 4 DSL for writing and formally verifying ZK circuitstool
- ArkLib — formally verified arguments of knowledge in Leantool
- Formal verification of Halo2 circuits in Lean (Halva, Nethermind)analysis
- Comparison of formal verification frameworks for arithmetic circuitsanalysis
- soundcalc — soundness calculator across hash-based zkEVMs (Ethereum Foundation)tool
- zkEVM security overview — multiproof redundancy, testing, audits, formal verificationreference
- ZK audit checklist — concrete per-category audit checksreference
- RISC-V architectural certification tests — conformance oracle for RISC-V zkVMstest suite
- Ethereum execution specs — reference tests for zkEVM conformance (absorbed the former execution-spec-tests)test suite
Cite this page
MarketComp (2026). Auditing a ZK protocol. The ZK Field Manual (Version 1.3). MarketComp. https://zkpick.com/audit/
@misc{zkfieldmanual-auditing-a-zk-protocol,
title = {Auditing a ZK protocol — The ZK Field Manual},
author = {MarketComp},
year = {2026},
version = {1.3},
howpublished = {\url{https://zkpick.com/audit/}},
note = {Accessed: YYYY-MM-DD}
}