3.12.5 Zero-Knowledge Proof System Security

Zero-knowledge proofs have moved from cryptographic exotica to load-bearing infrastructure. By 2026, ZK rollups secure tens of billions of dollars across zkSync Era, StarkNet, Polygon zkEVM, Scroll, Linea, and dozens of others. ZK-based privacy systems handle confidential transactions in Aztec, Tornado-style protocols, and emerging compliance-tooling. ZK identity systems (Polygon ID, Worldcoin's iris-based verification, several emerging KYC-with-privacy designs) authenticate users without revealing personal data. Application-layer ZK proofs verify off-chain computation, replay arbitrary state transitions, and increasingly compress L1 operations into single verification calls.

The security of every one of these systems depends on the correctness of the proof system itself. The math may be perfect — modern ZK constructions have decades of academic scrutiny. But the implementation gap is wide. A ZK system in production is a complex stack: a constraint system describing the computation, a compiler translating it to a low-level representation, a prover generating proofs, a verifier checking them, and on-chain contracts integrating the verification. Each layer can fail. The track record shows that bugs at each layer have produced losses ranging from individual transactions to nine-figure near-misses.

This subsection covers what protocol developers should understand about ZK system security. The topic is technical, and a full treatment requires substantial background in cryptography and constraint systems — beyond Book 3's scope. The goal here is to communicate the threat model, the failure modes that have actually happened, and the practical posture developers should take when building on or with ZK systems. Section 3.11.5 covered bridges including ZK bridges; this section is the deeper companion specifically focused on the proof-system layer.

The Three Properties at Stake

Every ZK proof system aims to provide three properties. Security analysis is largely the question of whether each holds.

Soundness. A dishonest prover cannot convince the verifier of a false statement, except with negligible probability. This is the most security-critical property — its failure means an attacker can prove false claims and extract value.

Completeness. An honest prover can always convince the verifier of true statements. Its failure is mostly a liveness issue (legitimate proofs are rejected), not a value-extraction issue.

Zero-knowledge. The proof reveals nothing about the private witness beyond what's implied by the statement. Its failure is a privacy issue — the witness leaks — but not directly a value-extraction issue.

For most protocol-level security concerns, soundness is the property that matters. When soundness fails, the verifier accepts proofs that should have been rejected. In a ZK rollup, this means an attacker can prove a state transition that didn't actually happen — for example, withdrawing tokens they don't own. In an identity system, it means proving facts about identity that aren't true. In a privacy system, it means double-spending or counterfeit-minting.

How Soundness Actually Breaks

The textbook description of ZK proof systems makes soundness sound like a property of the underlying math. In practice, the math is fine; the soundness breaks at the implementation layer.

A 2024 academic analysis found that approximately 96% of documented bugs in SNARK-based ZK systems were under-constrained circuits. The constraint system that defines what a "valid" proof must demonstrate is incomplete — there are valid-looking proofs of false statements that pass verification because the constraints don't catch them.

Under-Constrained Circuits

The dominant failure mode. A circuit defines computations as a system of polynomial constraints; the prover must show they have witness values satisfying all constraints. If the constraints don't fully specify the computation, multiple witnesses can satisfy them — including some that correspond to false statements.

Concrete example: a circuit meant to verify "I know a secret $x$ such that $hash(x) = h$" must constrain that the prover's claimed $x$ actually hashes to $h$. If the circuit accidentally allows any value to pass as a "preimage" without checking the hash relation, an attacker can claim knowledge of any preimage without actually knowing one.

These bugs are not always obvious in circuit code. The typical pattern: the developer writes constraints they think capture the computation; some constraints are missing or weakened by the compiler; the circuit passes integration tests (which test honest behavior) but accepts adversarial witnesses.

Over-Constrained Circuits

The opposite failure: the circuit has too many constraints, rejecting some valid witnesses. This is a completeness failure rather than a soundness failure. Less critical from a value-extraction standpoint, but can cause legitimate users to have proofs rejected.

Weak Fiat-Shamir Challenges

Many ZK proof systems use the Fiat-Shamir heuristic to make interactive proofs non-interactive: the prover derives the verifier's "challenge" from a hash of the partial proof. If the hash function or the challenge derivation is wrong — predictable, low-entropy, or missing inputs — the prover can choose favorable challenges and forge proofs.

Several documented incidents involve weak Fiat-Shamir implementations. The bug class persists because subtle issues in challenge derivation (missing context binding, predictable randomness, malleable inputs) are easy to introduce.

Trusted Setup Compromise

Some SNARK constructions (Groth16, original PLONK) require a "trusted setup" — a one-time ceremony that produces public parameters needed for proving and verification. If the secret values used in the setup are recovered (the so-called "toxic waste"), an attacker can forge proofs.

The mitigation: multi-party computation ceremonies where many participants contribute, and as long as one participant honestly destroys their share, the toxic waste is unrecoverable. Powers of Tau ceremonies for Ethereum and various rollups have involved hundreds of participants.

The risk persists for systems that use small setup ceremonies, or where coordination is centralized enough that an adversary could compromise the ceremony. Newer SNARK constructions (PLONK with universal setup, Halo2's recursive composition without setup) reduce this risk; STARKs eliminate it entirely.

Verifier Implementation Bugs

Even given a correct proof system, the on-chain verifier contract is itself a Solidity contract subject to all the usual bugs. Off-by-one errors in field arithmetic, incorrect group element checks, missing pairing checks — any of these can cause the verifier to accept invalid proofs.

This bug class has produced multiple production incidents. The ChainLight discovery of a zkSync Era soundness bug in 2023 was a verifier-implementation issue, not a circuit issue. The fix was straightforward; the damage if exploited would have been substantial.

Historical Incidents

A few cases inform the threat model:

Zcash Counterfeiting Bug (2018)

The earliest major ZK soundness bug. A flaw in the Sapling protocol's parameters allowed an attacker to mint unlimited Zcash (the "infinite shielded counterfeiting" bug). The bug was discovered by Zcash's own engineers in early 2018, kept secret while a fix was developed, and patched without public exploitation. The attacker who could have exploited it would have minted unlimited ZEC, undetectable because the shielded transaction structure hid the source of funds.

The Zcash team's handling of the discovery — secret patch, then full disclosure — became a model for similar later incidents. The bug existed in production for approximately two years before being discovered.

zkSync Era Soundness Bug (2023)

ChainLight discovered a soundness bug in zkSync Era's verifier in 2023. If exploited, it would have allowed forged withdrawals draining substantial funds — public estimates suggest up to $1.9 billion was at risk. The bug was responsibly disclosed and patched before exploitation. This near-miss was one of the largest avoided losses in DeFi history.

The technical detail: the verifier contract was missing certain validation checks on the structure of submitted proofs, allowing crafted proofs that didn't correspond to valid state transitions to pass verification.

Aztec Discovery (2023)

A similar verifier-implementation bug was discovered in the Aztec privacy protocol's verifier in 2023. Like zkSync Era, the bug was found by researchers and patched without exploitation.

FOOMCASH (2024)

A smaller but actually-exploited case. A privacy protocol's circuit had under-constraints that allowed limited counterfeiting; an attacker exploited the bug for several million dollars before the protocol was paused. The exact loss figure varies across reports; the case stands as one of the few documented production exploits of a ZK soundness bug.

Patterns from the Track Record

A few observations:

  • Near-misses outnumber actual exploits. Most ZK soundness bugs have been found by security researchers before attackers. This is not luck — the ZK community has been unusually proactive about security review.
  • The largest potential losses have been at L2 verifiers. Bugs in rollup verifiers expose the entire bridged value. zkSync Era's near-miss demonstrated the scale.
  • The exploitable bugs are usually subtle. Almost every documented bug requires non-trivial understanding of the proof system to exploit. The bar for attackers is high; the bar for defenders is high; the resulting security is genuinely hard to evaluate.

What Protocol Developers Should Know

For developers building applications that use ZK proofs (whether on a ZK rollup, with ZK identity proofs, or with custom circuits), the relevant security considerations:

Choosing a Proof System

Three major categories of production proof systems, each with different security profiles:

Groth16 (and similar SNARK constructions). Requires per-circuit trusted setup. Smallest proofs (~200 bytes), fast verification, but the setup ceremony is a permanent security dependency.

PLONK and variants (PLONK, UltraPLONK, Halo2). Universal trusted setup (one setup serves all circuits) or no setup at all (Halo2). Larger proofs than Groth16 but more flexibility. Becoming the default for new SNARK-based systems.

STARKs (StarkNet, Plonky3 in many configurations). No trusted setup. Quantum-resistant (Section 3.12.4). Larger proofs and verification cost, but stronger long-term security assumptions.

The choice depends on the protocol's priorities. STARKs have lower long-term cryptographic risk but higher on-chain verification cost. SNARKs are cheaper to verify but have setup and quantum-resistance considerations.

Choosing a Circuit Language

Several DSLs and frameworks exist for writing ZK circuits:

  • Circom — the most established; produces R1CS systems; Circom 3.0 brought improved security features. The largest ecosystem of audit tools and known patterns.
  • Cairo — StarkNet's native language; designed specifically for STARK provers.
  • Noir — Aztec's higher-level language with growing ecosystem.
  • o1js — Mina's TypeScript-based ZK framework.
  • ZoKrates — earlier framework, less actively maintained.
  • Leo — Aleo's domain-specific language.

Each has its own security maturity. Circom and Cairo are the most production-tested. Noir is rapidly maturing. The choice often follows the ecosystem (StarkNet protocols use Cairo; Aztec uses Noir; many cross-ecosystem ZK applications use Circom).

Threat Model

A realistic threat model for ZK-using protocols:

  1. The proof system's cryptographic assumptions hold. Modern proof systems based on well-studied assumptions (discrete log, hash function security) are unlikely to be broken in production timeframes.

  2. The circuit may have bugs. Under-constraints are the dominant failure mode; assume any custom circuit has not been fully secured until audited.

  3. The verifier contract may have bugs. Independent from circuit correctness, the on-chain verifier is Solidity code with all its typical concerns.

  4. The trusted setup ceremony was conducted correctly (if applicable). A failure here is catastrophic but rare; verify the ceremony's structure if relying on a custom setup.

  5. Composition with other protocols introduces additional surface. A ZK proof that verifies one fact may be misused in a context that depends on additional unverified facts.

Practical Patterns

Use well-established systems where possible. For most applications, a custom circuit is unnecessary. Existing systems (Aztec for privacy, Sismo for attestations, established rollups for scaling) provide audited circuits and verifiers. Building custom circuits adds risk without necessarily adding value.

Audit circuits with ZK specialists. Generic smart contract auditors typically lack ZK-specific expertise. Firms with established ZK practices (Nethermind, OpenZeppelin's ZKP practice, ChainLight, Veridise) have specialists. Section 3.12.3 covers the broader audit landscape.

Use formal verification for high-stakes circuits. Several tools support formal verification of ZK circuits — Veridise's tools, picus, ZK-Refinement — providing stronger guarantees than testing alone. Section 3.12.1 covers formal verification broadly.

Implement defense in depth at the application layer. Don't assume the ZK system is the only security boundary. Rate limits, withdrawal caps, monitoring for anomalous proof patterns — these provide additional protection even if the underlying proof system has a bug.

Monitor for proof-system updates and disclosed bugs. The ZK ecosystem moves fast; new bugs are discovered and patched regularly. Protocol teams should track major ZK system advisories.

Application-Layer Considerations

For applications that integrate with existing ZK systems (rather than building their own circuits):

Verifying Proofs in Smart Contracts

Most ZK proof verification happens in a dedicated verifier contract provided by the proof system. Application contracts call this verifier:

interface IVerifier {
    function verifyProof(
        bytes32[] calldata proof,
        bytes32[] calldata publicInputs
    ) external view returns (bool);
}

contract ZKApplication {
    IVerifier public immutable verifier;

    function executeWithProof(
        bytes32[] calldata proof,
        bytes32[] calldata publicInputs
    ) external {
        require(verifier.verifyProof(proof, publicInputs), "invalid proof");
        // ... execute based on what the proof attested
    }
}

Key considerations:

  • The verifier contract is the trust boundary. A bug in the verifier compromises everything downstream. Use audited verifiers; do not implement custom verification logic.
  • Public inputs must be validated independently. The proof attests that the statement is true given the public inputs. The application must ensure the public inputs are what the application expected — otherwise an attacker could submit a valid proof for a different statement than the one the application thinks it's checking.
  • Proof submissions can be front-run. A valid proof is essentially a "ticket" that can be replayed if not bound to a specific transaction. Include nonces, deadlines, and binding to specific application state in the public inputs.

Composing with ZK Privacy

When integrating with privacy-preserving ZK systems (Aztec, Tornado-style protocols), additional concerns:

  • The integration boundary may leak information. If your application reveals which deposits flow to which withdrawals through timing or amount correlation, the privacy guarantee may be partial.
  • Compliance and regulatory considerations. Section 3.12.7 covers standards; integrations with privacy systems have specific regulatory considerations that depend on jurisdiction.

What's Changing in 2026

Several trends in ZK security:

Formal verification of circuits becoming standard. Tools like Veridise's Picus and Nethermind's formal verification offerings are increasingly used for high-stakes circuits. The "circuit is formally verified" claim is starting to appear in audit reports.

Universal setup and setup-free systems. New SNARK constructions (Halo2, Nova) and STARK-based systems reduce or eliminate trusted setup, simplifying the trust model.

Increased focus on verifier audits. Following the zkSync Era and Aztec near-misses, verifier contracts are receiving more attention than circuits in some audits.

Standardization of ZK-related APIs. EIPs covering ZK-specific concerns (e.g., precompiles for common operations) are stabilizing, reducing duplication of verifier implementations.

zkVMs reaching production. General-purpose ZK virtual machines (RISC Zero, SP1, Cairo) are enabling protocols to use familiar languages while still leveraging ZK proofs. The security implications are an active area; the trust boundary moves from "this circuit" to "this VM implementation."

Cross-chain ZK proofs. ZK proofs verified across chains (e.g., proofs about Ethereum state verified on other chains) are an active development area. The security model spans multiple chains and their respective trust assumptions.

Practical Checklist

For a protocol using existing ZK systems:

  • The chosen ZK system has been production-tested at meaningful scale
  • The verifier contract has been audited by ZK specialists
  • Public inputs are validated against expected values, not just trusted because the proof verified
  • Proof submissions include nonces / deadlines to prevent replay
  • The application has fallback behavior for verifier-unavailable scenarios
  • The team monitors for security advisories on the chosen ZK system

For a protocol implementing custom circuits:

  • Circuit code is reviewed for under-constraints (the dominant failure mode)
  • Fiat-Shamir challenges are correctly derived with full context binding
  • Trusted setup (if applicable) used a multi-party ceremony with appropriate participant diversity
  • Circuits and verifiers are audited by ZK specialists (not generic auditors)
  • Formal verification is applied to the most critical circuit components
  • Tests cover adversarial witness generation, not just honest cases
  • Defense-in-depth at the application layer (rate limits, withdrawal caps) supplements proof-system security

For a protocol selecting a ZK rollup or proof system:

  • Quantum-resistance is considered (STARK vs SNARK; Section 3.12.4)
  • Trusted setup history is evaluated (if applicable)
  • The ecosystem's track record of bug discoveries and disclosures is reviewed
  • Cross-chain implications (proof verification across chains) are understood
  • L2-specific considerations (Section 3.11.8) are evaluated alongside ZK-specific ones

Cross-References

  • L2 considerations — Section 3.11.8 covers L2 architecture including ZK rollups
  • Cross-chain and bridge security — Section 3.11.5 covers ZK bridges and their unique considerations
  • Formal verification — Section 3.12.1 covers formal methods, increasingly applied to ZK circuits
  • Post-quantum considerations — Section 3.12.4 covers the quantum-resistance differences between STARKs and SNARKs
  • Audit practices — Section 3.9 covers the general audit discipline; ZK requires specialists
  • Decentralized auditing — Section 3.12.3 covers the broader audit landscape
  • Privacy — Book 5 (Advanced Web3 Security) covers privacy-specific considerations beyond this section's scope
  • Vitalik Buterin's "How do Zero-Knowledge Proofs Work?" — accessible technical introduction
  • Nethermind ZK Security Guidehttps://www.nethermind.io/blog/zk-circuit-security-a-guide-for-engineers-and-architects
  • Veridise / Picus — formal verification tooling for ZK circuits
  • ZK Bug Tracker — community-maintained catalog of disclosed ZK vulnerabilities