From hl-design-systems
Create Circom circuits for zkVerify Groth16 proofs with snarkjs. Use when the user wants to create a ZK circuit, write circom code, or start a new zero-knowledge proof project.
npx claudepluginhub horizenlabs/hl-claude-marketplace --plugin hl-design-systemsThis skill uses the workspace's default tool permissions.
Help the user create a Circom circuit that will be used with zkVerify for proof verification.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Performs token-optimized structural code search using tree-sitter AST parsing to discover symbols, outline files, and unfold code without reading full files.
Help the user create a Circom circuit that will be used with zkVerify for proof verification.
If invoked with an argument (e.g., /groth16-circuit hash-preimage), use it as the circuit type and skip asking what to prove.
| Argument | Circuit Type |
|---|---|
hash-preimage | Prove knowledge of hash preimage |
range-proof | Prove value is within range |
merkle-proof | Prove membership in Merkle tree |
age-check | Prove age meets minimum |
| (custom) | Use as circuit description |
If no argument provided, ask the user what they want to prove.
Before creating the circuit, verify Node.js is available:
node --version
| Check | If Missing |
|---|---|
| node | Direct user to install Node.js |
If Node.js is missing, stop and help user install it first.
Note: Circom is NOT required for this skill. You can create .circom files without having circom installed. Circom will be automatically installed when the user runs /groth16-compile.
This skill is specifically for:
This skill is NOT for:
If the user asks for a different proof system or language, inform them this skill only covers Circom/Groth16 and suggest they check zkVerify documentation for other proof systems.
Ask about the circuit purpose if not specified:
Create the circuit file in circuits/ directory
Analyze input dependencies to determine if a helper script is needed
Create valid inputs - either directly or via helper script
Before creating the input file, analyze the circuit's inputs:
Question: Are any inputs computed from other inputs?
| Answer | Action |
|---|---|
| YES | Create a helper script in scripts/ to compute dependent values |
| NO | Create inputs/*.json directly with valid example values |
hash = Poseidon(preimage) - hash depends on preimageroot = hash(hash(...leaves)) - root depends on leavescommitment = hash(secret, nullifier) - commitment depends on secretsvalue=50, min=0, max=100 - just numbersa=10, b=20, expectedSum=30 - just ensure math is correctage=25, minAge=18 - independent valuescircuits/
├── <circuit_name>.circom # The circuit
scripts/
├── compute_<name>_input.ts # Helper script (only if inputs are dependent)
inputs/
└── <circuit_name>_input.json # Valid input file
<== for assignment + constraint - Combines <-- and ===<-- only when necessary - Must add separate constraint with ===component main {public [input1, input2]} = Template();zkVerify has a limit of 64 total public signals (inputs + outputs) for Groth16 proofs submitted via the Kurier API.
| Total Public Signals | Result |
|---|---|
| ≤ 64 | Works |
| > 64 | FAILS (optimisticVerify: failed) |
This limit is NOT documented by zkVerify. Proofs with >64 public signals will verify locally with snarkjs but fail on zkVerify with no useful error message.
Total Public Signals = Public Inputs + Public Outputs
Example:
component main {public [a, b, c]} = MyCircuit(); with 1 output = 4 total signalsUse hash commitments to reduce public inputs:
Instead of:
// BAD: 81 public inputs (puzzle grid)
signal input puzzle[9][9]; // All public
Do this:
// GOOD: 1 public input (hash of puzzle)
signal input puzzleHash; // Public: just the hash
signal input puzzle[9][9]; // Private: actual puzzle
// Prove: Poseidon(puzzle) === puzzleHash
| Use Case | Naive Approach | Problem | Solution |
|---|---|---|---|
| Sudoku | 81 public inputs (puzzle) | 81 > 64 | Hash the puzzle |
| Voting | N public voter IDs | N could be large | Merkle tree of voters |
| Batch proofs | Many public values | Sum exceeds 64 | Aggregate with hashes |
If helper script was created: Run it to generate valid inputs
npm install circomlibjs ts-node typescript @types/node
npx ts-node scripts/compute_<name>_input.ts <args>
Install circomlib if circuit uses library components:
npm install circomlib
Next step: Run /groth16-compile to compile the circuit
circuits/For detailed examples and reference material, see: