Merkle tree membership proof circuit in ZoKrates. Proves that a value exists in a Poseidon-based Merkle tree (depth 3, 8 leaves) without revealing the value or its position.
Equivalent to the circom and Noir versions, using ZoKrates' stdlib Poseidon hash and the Groth16 proving system with the bellman backend (faster and more memory-efficient than the default arkworks backend).
- ZoKrates ≥ 0.8.8 —
curl -LSfs get.zokrat.es | shthenexport PATH=$PATH:$HOME/.zokrates/bin - Node.js ≥ 18 (for input generation and visualization scripts)
npm installzokrates compile -i circuits/merkle.zok -o build/merkleOutputs build/merkle (compiled circuit). 1072 constraints.
node scripts/generate_input.js [leafIndex]Computes the Poseidon Merkle tree and prints the witness arguments needed for compute-witness. Default leaf index is 3 (value 42).
zokrates compute-witness -i build/merkle -o build/witness -a <args from step 2>For the default (leaf 42 at index 3):
zokrates compute-witness -i build/merkle -o build/witness -a 42 3 30 18520321019059006606511285595387750999043784958310087972051959520693448686063 3420474571345144317592756791686222517137740774669488698617074013334764505433 14137441823196867098576785772577409116077936272054299522801628487819529363847zokrates setup -i build/merkle -b bellman -s g16 -p build/proving.key -v build/verification.keyzokrates generate-proof -i build/merkle -b bellman -s g16 -p build/proving.key -w build/witness -j build/proof.jsonzokrates verify -v build/verification.key -j build/proof.jsonExpected output: PASSED
node scripts/visualize_tree.js [leafIndex]Prints an ASCII tree with color-coded proof path (green), sibling witnesses (yellow), and other nodes (dim). Default leaf index is 3 (value 42).
zokrates export-verifier -i build/verification.key -o build/Verifier.sol| Signal | Visibility | Description |
|---|---|---|
leaf |
private | The leaf value to prove membership of |
index |
private | Leaf position (u32, bit-decomposed for path selection) |
siblings[3] |
private | Sibling hashes along the authentication path |
root |
public | Expected Merkle root |
The circuit decomposes index into bits, then walks up the tree hashing with poseidon([left, right]) at each level, selecting left/right based on the index bits. It asserts the computed root equals the provided root.
| Circom | Noir | ZoKrates | |
|---|---|---|---|
| Hash function | Poseidon | Poseidon2 | Poseidon |
| Proving system | Groth16 (snarkjs) | UltraHonk (Barretenberg) | Groth16 (built-in) |
| Leaf handling | Hashes value before insertion | Raw values as leaves | Raw values as leaves |
| Setup | Separate ceremony steps | No trusted setup | Single setup command |
| Constraints | 951 | N/A (gates) | 1072 |