askill
zk-circuits

zk-circuitsSafety 85Repository

Zero-knowledge circuit development using Circom and Noir languages. Supports constraint optimization, ZK-friendly cryptographic primitives, proof generation (Groth16, PLONK), and Merkle tree implementations.

29 stars
1.2k downloads
Updated 2/5/2026

Package Files

Loading files...
SKILL.md

ZK Circuit Development Skill

Zero-knowledge circuit development using Circom and Noir for privacy-preserving applications and zkRollups.

Capabilities

  • Circom Circuits: Write Circom templates and components
  • Noir Programs: Develop Noir ZK applications
  • Constraint Optimization: Minimize circuit constraints
  • ZK Primitives: Use Poseidon, MiMC, and Pedersen hashes
  • Proof Systems: Generate Groth16 and PLONK proofs
  • Signal Design: Design efficient circuit inputs/outputs
  • Merkle Trees: Implement membership and non-membership proofs
  • Witness Generation: Create efficient witness calculators

Circom Development

Installation

# Install Circom
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
git clone https://github.com/iden3/circom.git
cd circom
cargo build --release
cargo install --path circom

# Install snarkjs
npm install -g snarkjs

# Verify
circom --version
snarkjs --version

Basic Circuit

pragma circom 2.1.6;

// Simple addition circuit
template Addition() {
    // Public inputs
    signal input a;
    signal input b;

    // Output (public by default)
    signal output c;

    // Constraint
    c <== a + b;
}

component main = Addition();

Multiplier Circuit

pragma circom 2.1.6;

template Multiplier(n) {
    signal input in[n];
    signal output out;

    signal intermediate[n];

    intermediate[0] <== in[0];
    for (var i = 1; i < n; i++) {
        intermediate[i] <== intermediate[i-1] * in[i];
    }

    out <== intermediate[n-1];
}

component main {public [in]} = Multiplier(3);

Hash Circuit (Poseidon)

pragma circom 2.1.6;

include "circomlib/circuits/poseidon.circom";

template HashPreimage() {
    signal input preimage;
    signal input hash;

    component hasher = Poseidon(1);
    hasher.inputs[0] <== preimage;

    // Verify hash
    hash === hasher.out;
}

component main {public [hash]} = HashPreimage();

Merkle Tree Membership

pragma circom 2.1.6;

include "circomlib/circuits/poseidon.circom";
include "circomlib/circuits/mux1.circom";

template MerkleProof(levels) {
    signal input leaf;
    signal input root;
    signal input pathElements[levels];
    signal input pathIndices[levels];

    component hashers[levels];
    component mux[levels];

    signal levelHashes[levels + 1];
    levelHashes[0] <== leaf;

    for (var i = 0; i < levels; i++) {
        hashers[i] = Poseidon(2);
        mux[i] = Mux1();

        mux[i].c[0] <== levelHashes[i];
        mux[i].c[1] <== pathElements[i];
        mux[i].s <== pathIndices[i];

        hashers[i].inputs[0] <== mux[i].out;
        hashers[i].inputs[1] <== levelHashes[i] + pathElements[i] - mux[i].out;

        levelHashes[i + 1] <== hashers[i].out;
    }

    root === levelHashes[levels];
}

component main {public [root]} = MerkleProof(20);

Circom Build Process

# Compile circuit
circom circuit.circom --r1cs --wasm --sym -o build

# Generate witness
node build/circuit_js/generate_witness.js build/circuit_js/circuit.wasm input.json witness.wtns

# Powers of Tau ceremony (one-time)
snarkjs powersoftau new bn128 14 pot14_0000.ptau
snarkjs powersoftau contribute pot14_0000.ptau pot14_0001.ptau
snarkjs powersoftau prepare phase2 pot14_0001.ptau pot14_final.ptau

# Generate proving key (Groth16)
snarkjs groth16 setup build/circuit.r1cs pot14_final.ptau circuit_0000.zkey
snarkjs zkey contribute circuit_0000.zkey circuit_final.zkey

# Export verification key
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json

# Generate proof
snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json

# Verify proof
snarkjs groth16 verify verification_key.json public.json proof.json

# Generate Solidity verifier
snarkjs zkey export solidityverifier circuit_final.zkey Verifier.sol

Noir Development

Installation

# Install Noir (Nargo)
curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
noirup

# Verify
nargo --version

Basic Noir Program

// src/main.nr
fn main(x: Field, y: pub Field) {
    assert(x != y);
}

Hash Verification

use dep::std::hash::pedersen_hash;

fn main(preimage: Field, hash: pub Field) {
    let computed_hash = pedersen_hash([preimage]);
    assert(computed_hash == hash);
}

Merkle Proof in Noir

use dep::std::hash::poseidon;
use dep::std::merkle::compute_merkle_root;

fn main(
    leaf: Field,
    index: Field,
    hash_path: [Field; 20],
    root: pub Field
) {
    let computed_root = compute_merkle_root(leaf, index, hash_path);
    assert(computed_root == root);
}

Noir Build Process

# Create project
nargo new my_circuit
cd my_circuit

# Edit src/main.nr
# Edit Prover.toml with inputs

# Compile
nargo compile

# Generate witness
nargo execute

# Generate proof
nargo prove

# Verify proof
nargo verify

Optimization Techniques

Constraint Reduction

// BAD: Creates extra constraints
template Bad() {
    signal input a;
    signal output b;
    b <== a * a * a * a; // Multiple intermediate constraints
}

// GOOD: Single constraint
template Good() {
    signal input a;
    signal output b;
    signal a2;
    a2 <== a * a;
    b <== a2 * a2; // Fewer constraints
}

Field Arithmetic

// Use field arithmetic efficiently
template FieldOps() {
    signal input a;
    signal input b;
    signal output c;

    // Addition is free (no constraint)
    signal sum;
    sum <== a + b;

    // Multiplication adds constraint
    c <== a * b;
}

Lookup Tables

// Use lookup tables for range checks
template RangeCheck(n) {
    signal input in;

    component bits = Num2Bits(n);
    bits.in <== in;
    // Implicitly constrains in < 2^n
}

ZK-Friendly Primitives

PrimitiveConstraintsUse Case
Poseidon~300/hashGeneral hashing
MiMC~700/hashMerkle trees
Pedersen~1000/hashCommitments
ECDSA~10000/sigSignatures
EdDSA~3000/sigSignatures

Process Integration

ProcessPurpose
zk-circuit-development.jsCircuit development
zk-snark-application.jsZK application building
zk-rollup-development.jsRollup circuits
privacy-token-implementation.jsPrivacy protocols

Best Practices

  1. Minimize constraints for efficient proofs
  2. Use ZK-friendly hash functions
  3. Audit circuits for completeness
  4. Test with edge cases
  5. Use formal verification when possible
  6. Document signal flows clearly

See Also

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

94/100Analyzed 2/10/2026

An exceptional technical reference for ZK circuit development, providing comprehensive setup instructions, code examples for both Circom and Noir, and advanced optimization techniques.

85
95
90
98
98

Metadata

Licenseunknown
Version-
Updated2/5/2026
Publishera5c-ai

Tags

ci-cdgithubtesting