zero-knowledge proof verification on ethereum sepolia testnet
groth16 Β· circom Β· snarkjs Β· solidity Β· foundry
a minimal zk-snark verifier dapp that demonstrates groth16 proof verification on-chain. the circuit proves knowledge of two factors a and b such that a Γ b = c, verified trustlessly on ethereum.
live contract β sepolia testnet
| component | address |
|---|---|
| groth16 verifier | 0x29DD4CC005bEa9969a3120fb930F2a59fAEDB15D |
1.circuit β multiplier.circom (a Γ b = c)
2.setup β groth16 trusted setup (pot12 ptau)
3.witness β snarkjs witness generation
4.proof β groth16.fullProve()
5.verify β on-chain via solidity verifier
the public signal 0x21 (decimal 33 = 3 Γ 11) is committed on-chain.
the verifier checks the groth16 pairing equations using the bn128 elliptic curve.
| layer | tool |
|---|---|
| zk circuit | circom 2.0 |
| proof system | groth16 (snarkjs) |
| smart contract | solidity 0.8.x |
| deployment | foundry forge |
| frontend | react + vite + ethers.js v6 |
| network | ethereum sepolia |
zkphase2/ βββ multiplier.circom # zk circuit βββ multiplier_final.zkey # groth16 proving key βββ verification_key.json # verification key βββ Verifier.sol # on-chain groth16 verifier βββ proof.json # sample proof βββ public.json # public signals βββ zk-deploy/ # foundry deployment β βββ src/Verifier.sol β βββ .env.example βββ zk-frontend/ # react dapp βββ src/App.jsx
git clone https://github.com/ar1as1/zk-verifier-egold
cd zkphase2/zk-frontend
npm install
npm run devopen http://localhost:5173 β click verify zk proof
# install deps
npm install -g snarkjs circom
# compile circuit
circom multiplier.circom --r1cs --wasm --sym
# generate witness
node multiplier_js/generate_witness.js multiplier_js/multiplier.wasm input.json witness.wtns
# generate proof
snarkjs groth16 prove multiplier_final.zkey witness.wtns proof.json public.json
# verify locally
snarkjs groth16 verify verification_key.json public.json proof.jsoncd zk-deploy
cp .env.example .env
# add PRIVATE_KEY and SEPOLIA_RPC to .env
forge create src/Verifier.sol:Groth16Verifier \
--rpc-url $SEPOLIA_RPC \
--private-key $PRIVATE_KEY \
--broadcastpragma circom 2.0.0;
template Multiplier2() {
signal input a;
signal input b;
signal output c;
c <== a * b;
}
component main = Multiplier2();constraint: c === a Γ b β proven without revealing a or b
tested on:
- circom 2.2.3
- snarkjs 0.7.6
- node v25.9.0
- forge 1.5.1
- blackarch linux / kernel 6.12
mit β built by egold