AgentSkillsCN

crypto-zkp

零知识证明工程——电路设计、证明系统选择与形式化验证。

SKILL.md
--- frontmatter
name: crypto-zkp
description: Zero-knowledge proof engineering — circuit design, proof system selection, and formal verification

What I do

  • Guide proof system selection with a multi-dimensional decision framework
  • Document circuit engineering discipline (R1CS, PLONKish arithmetization)
  • Enforce adversarial constraint testing through the constraint fuzzer directive
  • Cover formal verification tools and the ZKP tooling ecosystem

When to use me

Use this skill when designing ZK circuits, selecting proof systems, or implementing ZKP-based protocols. Pair with crypto-core for shared foundations, security invariants, and code review checklists.

Proof System Decision Framework

Decision Tree

code
Need post-quantum security?
  YES --> zk-STARKs (hash-based, no pairings)
  NO  |
      v
Need minimal proof size? (on-chain verification)
  YES --> Groth16 (~200 bytes, trusted setup per circuit)
  NO  |
      v
Need universal/updatable setup?
  YES --> PLONK variants (KZG setup, reusable across circuits)
  NO  |
      v
Need no trusted setup at all?
  YES --> Bulletproofs (no setup, O(n) verification)
          or STARKs (no setup, large proofs, fast verification)
  NO  |
      v
Need recursive proof composition?
  YES --> Nova/SuperNova (folding schemes)
          Halo2 (IPA-based recursion)
          Plonky2/3 (STARK-inside-SNARK)
  NO  |
      v
Need general computation (not custom circuits)?
  YES --> zkVM: SP1, RISC Zero, Jolt, Valida
  NO  --> Custom circuit: circom, halo2, noir

Comparison Matrix

SystemSetupProof SizeProverVerifierPost-QuantumRecursion
Groth16Per-circuit~200 BSlowVery fastNoDifficult
PLONK (KZG)Universal~400 BMediumFastNoYes
PLONK (IPA)None~1.5 KBMediumSlowerNoYes
STARKsNone~50-200 KBFastFastYesYes
BulletproofsNone~700 BSlowSlow (O(n))NoNo
NovaNone~10 KBFast (IVC)FastDependsNative

Circuit Engineering

Arithmetization

AspectR1CSPLONKish
Gate typea * b = c (multiplication gates)Custom gates, lookup tables
FlexibilityFixed structureHighly configurable
Best forSimple circuits (Groth16)Complex circuits (halo2, PLONK)
OptimizationMinimize multiplication gatesMinimize rows, use lookups

The Critical Distinction

In circom, <-- is witness assignment (prover-side computation, not enforced by the verifier). === is a constraint (enforced by the verifier). A circuit with assignments but no constraints accepts ANY witness.

Always verify: constraint count matches expected count. Use the --inspect flag to audit constraints.

Optimization Patterns

  • Lookup tables for range checks and non-arithmetic operations
  • Custom gates for repeated sub-circuits (PLONKish only)
  • Batch inversions -- one inversion + n multiplications instead of n inversions
  • Algebraic tricks -- x^3 costs 1 constraint (xx=x2, x2x=x3), not 2
  • Constant propagation -- replace known-at-compile-time values to eliminate constraints

Constraint Fuzzer Directive

Before any circuit is considered tested, generate and verify rejection of these adversarial witnesses. Do not skip this step.

  1. All-zeros -- set every private input to 0
  2. All-max -- set every private input to (field_prime - 1)
  3. Perturbed valid -- take a valid witness, randomly change one value
  4. Swapped inputs -- swap two private input values
  5. Replayed witness -- use a valid witness from a different public input

All five must be REJECTED by the constraint system. If any passes, the circuit is under-constrained.

Under-constrained circuits compile, generate proofs with valid witnesses, and appear to work correctly. They silently break security. This is the most dangerous class of ZK bug.

Workflow: Designing a ZK Circuit

  1. Specify -- Define the statement: "I know w such that f(x, w) = true" where x is public. List all security properties needed.
  2. Arithmetize -- Decompose the computation into field operations (+, *, =). Choose R1CS or PLONKish. Estimate constraint count.
  3. Implement -- Choose tooling: circom for simple circuits, halo2 for complex circuits with custom gates, noir for portability. Separate witness generation from constraint logic.
  4. Test -- Valid witness passes. Run constraint fuzzer directive. Test edge cases: zero values, max field elements, boundary conditions.
  5. Optimize -- Profile constraint count per operation. Apply lookup tables, custom gates, batch inversions. Re-test after every change.
  6. Audit -- Run crypto-core code review checklist. Check for under-constrained values. Run formal verification tools.
  7. Deploy -- Generate or use trusted setup (if applicable). Deploy verifier contract (if on-chain). Monitor proof generation times.

Formal Verification

ToolTargetWhat It Checks
ecnecircom circuitsConstraint equivalence to specification
Picuscircom circuitsUnder-constraint detection (finds missing constraints)
CertoraSolidity verifiersSmart contract correctness of on-chain verifiers

Use formal verification when: (1) the circuit handles financial value, (2) constraint count exceeds 10,000, or (3) the circuit will be deployed without further audit. Formal verification does not replace adversarial testing -- it complements it.

Tooling Ecosystem

ToolLanguageProof SystemMaturityBest For
circomDSL (JS/Wasm)Groth16, PLONKProductionSimple-to-medium circuits, rapid prototyping
snarkjsJavaScriptGroth16, PLONKProductionProof generation and verification for circom
halo2RustPLONKish (IPA/KZG)ProductionComplex circuits, custom gates, lookups
arkworksRustMultipleProductionResearch, custom proof systems, flexibility
noirDSL (Rust)Backend-agnosticMaturingPortable ZK apps, developer experience
gnarkGoGroth16, PLONKProductionGo ecosystem, fast prover
SP1Rust (zkVM)STARK-basedMaturingGeneral computation proofs, RISC-V
RISC ZeroRust (zkVM)STARK-basedProductionGeneral computation, developer-friendly
JoltRust (zkVM)Sum-checkResearchLookup-based zkVM
Plonky2/3RustSTARK + recursionProductionRecursive proofs, Ethereum L2s
rapidsnarkC++Groth16ProductionFast server-side Groth16 proving
CircomlibcircomN/AProductionStandard circuit library (hashes, sigs, etc.)

Anti-Patterns

Anti-PatternWhy It Fails
Confusing <-- with === in circomCreates under-constrained circuit; prover can forge proofs
Testing only with valid witnessesMisses under-constrained circuits that accept invalid proofs
Optimizing before constraint count is baselinedCannot measure improvement without a baseline
Using Groth16 when circuit changes frequentlyEvery circuit change requires a new trusted setup ceremony
Ignoring proof malleabilityThird parties can modify proofs without invalidating them
Skipping formal verification on high-value circuitsUnder-constraints are invisible to standard testing