Skip to main content
Zero-Knowledge Threat Modeling

Playing with Shadows: Threat Modeling Zero-Knowledge Proofs in Production

Zero-knowledge proofs (ZKPs) are no longer a research curiosity—they are being deployed in production systems handling real assets, identities, and governance decisions. But the same properties that make ZKPs powerful (non-interactivity, succinctness, zero-knowledge) also create unfamiliar attack surfaces. A proof is not just a cryptographic object; it is a message that must be generated, transmitted, verified, and stored. Each step introduces assumptions that can fail in ways traditional security reviews miss. This guide is for teams that have already built a prototype and now need to decide how to harden it for production. We will walk through threat modeling from the perspective of a deployer, not a cryptographer, and focus on the decisions that determine whether your system survives contact with adversaries. Who Must Choose and by When The decision to adopt ZKPs in production is rarely made in isolation.

Zero-knowledge proofs (ZKPs) are no longer a research curiosity—they are being deployed in production systems handling real assets, identities, and governance decisions. But the same properties that make ZKPs powerful (non-interactivity, succinctness, zero-knowledge) also create unfamiliar attack surfaces. A proof is not just a cryptographic object; it is a message that must be generated, transmitted, verified, and stored. Each step introduces assumptions that can fail in ways traditional security reviews miss. This guide is for teams that have already built a prototype and now need to decide how to harden it for production. We will walk through threat modeling from the perspective of a deployer, not a cryptographer, and focus on the decisions that determine whether your system survives contact with adversaries.

Who Must Choose and by When

The decision to adopt ZKPs in production is rarely made in isolation. It usually comes down to a team lead, a security architect, or a protocol designer who must evaluate whether ZKP integration is feasible before a launch deadline. The timeline matters: if you are already in the final month before mainnet deployment, your options are constrained. You might have to accept higher gas costs or weaker privacy guarantees because the circuit is already frozen. If you are still in the design phase, you have room to choose between proving systems, setup ceremonies, and verification strategies.

The core question is: what trust assumptions are your users accepting? Every ZKP system has a setup phase, a proof generation phase, and a verification phase. Each phase can be attacked. The setup might be compromised by a malicious participant in a multi-party ceremony. The prover might leak the witness through side channels. The verifier might accept a forged proof if the circuit has a soundness bug. These are not theoretical—they have happened in practice. The question is not whether these risks exist, but which ones you can mitigate given your timeline and resources.

For teams building on existing platforms (e.g., Ethereum with Groth16 verifiers), the choice is often between using a trusted setup that already exists or running your own ceremony. For teams building a new L1 or L2, you might decide to use a transparent setup (like STARKs) to avoid ceremony risks entirely. The deadline pressure often pushes teams toward the path of least resistance, which is not always the safest. This guide will help you map your constraints to a concrete decision before you lock in your architecture.

Option Landscape: Three Approaches to Production ZKP

We compare three architectural patterns that cover most current production deployments. Each represents a different trade-off between privacy, cost, and trust. We will not name specific vendors or libraries, but the patterns correspond to real choices teams face.

Approach A: Off-Chain Proof Generation with On-Chain Verification

This is the most common pattern today. The prover generates a proof locally (on a user device or a backend server), submits it to a smart contract, and the contract verifies it. The witness (private inputs) never leaves the prover's machine. The verifier only sees the proof and public inputs. This pattern works well for applications like private transfers, anonymous voting, and identity attestation.

Pros: Strong privacy (witness stays local), mature tooling (many libraries support Groth16 and PLONK), and relatively low on-chain verification gas costs (around 200k–500k gas for a Groth16 proof).

Cons: Proof generation can be slow (minutes on a mobile device for complex circuits), the prover must be trusted to generate a valid proof (malicious prover can create a valid proof for a false statement if the circuit has a soundness hole), and the setup ceremony is a single point of trust unless you use a transparent setup.

Approach B: Trusted Execution Environments for Private Witness Handling

In this pattern, the witness is processed inside a TEE (like Intel SGX or AMD SEV), and a ZKP is generated from within the enclave. The enclave attests that the proof was generated correctly without leaking the witness. This can reduce the trust required in the prover's hardware, but introduces a new trust assumption: the TEE manufacturer.

Pros: Reduces the risk of witness leakage from the prover's machine (the witness never leaves the enclave in plaintext), and can enable use cases where the prover is not fully trusted (e.g., a centralized service proving correct computation on user data).

Cons: TEEs have their own attack surface (side-channel attacks, rollback attacks, and attestation failures), the proof generation inside the enclave is slower due to hardware constraints, and the TEE vendor becomes a critical trust anchor. Many teams find that adding a TEE introduces more complexity than it solves.

Approach C: Hybrid Recursive Proofs with Fallback Circuits

This is an advanced pattern where multiple proofs are composed recursively, and a fallback circuit exists in case the primary circuit is compromised. For example, you might have a fast circuit for common cases and a slower, more audited circuit for edge cases. Recursive proofs allow you to verify many statements with a single on-chain check, reducing gas costs. The fallback circuit acts as a safety net: if a bug is found in the primary circuit, you can switch to the fallback without redeploying the entire system.

Pros: Very low on-chain verification cost (one verification for many proofs), flexibility to upgrade circuits without changing the verifier, and the ability to handle complex logic that would be too expensive in a single circuit.

Cons: Recursive proof generation is computationally heavy (often requires a server-grade GPU), the fallback circuit must be maintained and tested alongside the primary, and the recursive composition introduces additional soundness assumptions (the recursive verifier itself must be bug-free).

Each approach has a place. Approach A is the default for most teams. Approach B is used when the prover is a centralized service that cannot be fully trusted. Approach C is for teams that need to scale proof verification across many users or transactions, and are willing to invest in the infrastructure.

Comparison Criteria Readers Should Use

When evaluating these approaches, teams often focus on gas costs and proof size, but those are only part of the picture. We recommend a five-criterion framework:

  1. Trust assumptions: Who or what must be honest for the system to be secure? This includes the setup ceremony, the prover, the verifier, and any hardware or software dependencies. List every entity and ask: what happens if they are compromised?
  2. Proof size and verification cost: For on-chain verification, this is gas. For off-chain verification, it is bandwidth and latency. But also consider that smaller proofs often come with larger setup assumptions (e.g., Groth16 requires a trusted setup, while STARKs do not but have larger proofs).
  3. Latency: How long does it take to generate a proof? On a mobile device? On a server? If your application requires sub-second proof generation, you may need to use a simpler circuit or a more powerful prover.
  4. Auditability: Can the circuit and the verification logic be audited by third parties? Is the setup transcript public? Are there multiple implementations of the verifier? A system that relies on a single closed-source library is riskier than one with multiple independent implementations.
  5. Upgradeability: Can you change the circuit after deployment? If you find a bug, can you patch it without forcing all users to update? This is especially important for smart contract-based systems where the verifier is immutable.

Weigh these criteria according to your specific threat model. For a financial application handling large sums, trust assumptions and auditability may outweigh gas costs. For a high-frequency trading application, latency and verification cost may be paramount. There is no universal ranking.

Trade-offs Table: A Structured Comparison

The table below summarizes the key trade-offs across the three approaches. Use it as a starting point for your own evaluation, but always validate against your specific circuit and deployment environment.

CriterionOff-Chain + On-ChainTEE-BasedRecursive + Fallback
Trust SetupDepends on proving system (Groth16 requires trusted setup; PLONK can be transparent)Trusted setup + TEE vendorDepends on proving system; fallback adds another setup
Proof SizeSmall (Groth16: ~128 bytes; PLONK: ~500 bytes)Similar to off-chain + on-chainCan be larger due to recursive composition
Verification Gas~200k–500k gas (Groth16)Similar, plus attestation verification costVery low per proof (one verification for many)
Proof Gen LatencySeconds to minutes (depends on circuit)Slower due to TEE overheadMinutes to hours (requires GPU)
AuditabilityHigh (open-source libraries, public ceremonies)Medium (TEE code may be proprietary)High (if both circuits are open)
UpgradeabilityLow (requires redeploying verifier contract)Low (requires TEE update)High (fallback circuit can be swapped)

One pattern that emerges: the more you try to reduce on-chain costs, the more complexity you push into the proving infrastructure. Recursive proofs are elegant but demand significant engineering investment. TEEs add a hardware dependency that many teams underestimate. The off-chain + on-chain pattern remains the most battle-tested, but it is not a silver bullet—especially if your circuit is large or your users are on mobile devices.

Implementation Path After the Choice

Once you have selected an approach, the real work begins. The following steps are common across all patterns, but the specifics vary.

Step 1: Circuit Hardening and Auditing

Your circuit is the most critical piece. Every constraint must be correct, and there must be no missing constraints that allow a malicious prover to create a valid proof for an invalid statement. This is not just about soundness—it is also about completeness: can honest provers always produce a proof? Common pitfalls include under-constrained variables, incorrect range checks, and misuse of hash functions. Hire an external auditor who specializes in ZK circuits, and run fuzzing tools that generate random witnesses and check that proof generation and verification succeed consistently.

Step 2: Secure Proof Generation and Transmission

If the prover is a user device, ensure that the proof generation library is memory-safe and does not leak the witness through timing or power side channels. For server-side proving, isolate the proving environment from other processes. Use TLS for proof transmission, but also consider that the proof itself is public—it does not need encryption, but the proof submission endpoint must be protected against replay attacks. Use a nonce or a sequence number in the public inputs to ensure each proof is unique.

Step 3: Verification Infrastructure Monitoring

On-chain verifiers should be monitored for reverts and unexpected failures. A sudden spike in verification failures could indicate an attempted attack or a circuit bug. Log all verification attempts (public inputs, proof hashes) for forensic analysis. For off-chain verification, ensure that the verifier is running on a trusted machine and that its software is updated.

Step 4: Plan for Circuit Upgrades

Even with the best auditing, bugs can be discovered after deployment. Design your system to support circuit upgrades from day one. This might mean using a proxy contract that points to a new verifier, or implementing a fallback circuit as described in Approach C. Without an upgrade path, a critical bug could force a hard fork or a migration that loses user data.

Risks If You Choose Wrong or Skip Steps

The consequences of a poor threat model are not abstract. Here are concrete failure modes that have occurred in real deployments.

Setup Ceremony Compromise

If your proving system uses a trusted setup and the ceremony is compromised (e.g., a participant leaks toxic waste), an attacker can forge proofs for arbitrary statements. This is catastrophic: the attacker could drain a private pool, forge identity credentials, or manipulate governance votes. The only mitigation is to use a transparent setup (like STARKs or PLONK with a random oracle) or to run a ceremony with multiple independent participants and verify the transcript publicly.

Circuit Soundness Bug

A missing constraint in the circuit can allow a prover to produce a valid proof for a false statement. For example, if a range check is omitted, a prover could claim a value is within bounds when it is not. This can lead to theft of funds or unauthorized access. The fix is rigorous auditing and fuzzing, but if the bug is discovered after deployment, the system may be irrecoverable without an upgrade path.

Proof Malleability

Some proving systems (notably Groth16) produce proofs that can be modified without invalidating them. An attacker can take a valid proof, modify it slightly, and submit it as a new proof. If the public inputs do not include a unique identifier (like a nonce), the attacker can replay the proof multiple times. This has been exploited in practice to drain privacy pools. Mitigations include binding the proof to a unique public input and using a nullifier scheme.

Side-Channel Leakage from Prover

If the prover runs on a shared machine, an attacker with access to the same hardware (e.g., a cloud VM) might be able to extract the witness through cache timing or power analysis. This breaks the zero-knowledge property. Use constant-time implementations and isolate the proving process.

Verifier Implementation Bug

The verifier itself can have bugs. For example, a Solidity verifier might incorrectly parse the proof, accepting a malformed proof as valid. Use multiple independent implementations of the verifier and test them against the same test vectors.

Mini-FAQ

Q: Should I use Groth16 or PLONK?
Groth16 has smaller proofs and lower verification gas, but requires a trusted setup. PLONK has larger proofs but can use a transparent setup (if using the random oracle variant). If you can afford the gas and want to avoid ceremony risk, PLONK is a safer choice. If gas is critical and you trust the setup, Groth16 is fine. Many teams start with PLONK for flexibility and switch to Groth16 later if gas becomes a bottleneck.

Q: How do I handle proof replay attacks?
Include a unique identifier in the public inputs—such as a sequence number, a nonce, or a hash of the previous transaction. For on-chain systems, use a nullifier: a public value that can only be used once. The verifier should check that the nullifier has not been seen before. This is standard in privacy-focused protocols.

Q: What if a circuit bug is found after deployment?
If you have an upgrade path (proxy contract or fallback circuit), you can deploy a fixed circuit and migrate users. If not, you may need to freeze the system and ask users to withdraw funds or migrate manually. This is why upgradeability should be part of your initial design.

Q: Can I trust a third-party setup ceremony?
Only if you can verify the transcript and ensure that at least one participant was honest. For Groth16, the setup is a multi-party computation where each participant contributes randomness. If even one participant is honest and destroys their secret, the setup is secure. You should always verify the transcript against the final parameters.

Q: How much does proof generation cost in compute resources?
It depends heavily on the circuit size. A simple circuit (e.g., proving knowledge of a hash preimage) can generate a proof in under a second on a modern CPU. A complex circuit (e.g., proving correct execution of a virtual machine) may take hours on a GPU. Estimate by profiling your circuit early, and consider using a proving service if latency is critical.

Q: Should I use recursive proofs for my use case?
Recursive proofs are beneficial when you need to verify many statements on-chain with minimal gas, or when you want to compose proofs from different parties. However, they add significant complexity. Only use them if the gas savings justify the engineering cost.

Closing: Three Specific Next Moves

Threat modeling is not a one-time activity. As your circuit evolves and your deployment scales, new risks emerge. Here are three concrete actions to take this week:

  1. Run a threat modeling workshop focused on your ZK system. Gather your team, list all trust assumptions, and walk through each attack scenario we discussed. Document the results and assign owners for each mitigation.
  2. Instrument proof generation and verification with monitoring. Add logging for proof submission times, failure rates, and verification gas costs. Set up alerts for anomalies. This data will help you detect attacks and performance regressions.
  3. Design your circuit upgrade mechanism now, before you need it. Even if you do not use recursive proofs, plan how you will replace a compromised circuit. This might mean a proxy contract, a migration tool, or a fallback circuit. Test the upgrade process on a testnet.

Zero-knowledge proofs are a powerful tool, but they are not magic. The shadow they cast is the set of assumptions you make about who and what you trust. Shine a light on those shadows, and you will deploy with confidence.

Share this article:

Comments (0)

No comments yet. Be the first to comment!