Incremental Merkle Tree (IMT) is a specialized form of a Merkle tree designed to allow for efficient appending of new elements, making it useful in applications where the dataset is expected to grow over time and updates need to be processed efficiently.
zk-IMT is a zero-knowledge proof system for Incremental Merkle Trees. It allows a prover to prove tree membership and non-membership of a leaf in an IMT without revealing the leaf itself. The prover can also prove the consistency of two IMTs without revealing the entire tree.
MiMC5 is a family of hash functions that are based on the MiMC construction. It is a sponge-based hash function that is used to hash the inputs in zk-IMT.
MiMC is more suitable than SHA256 or Keccak for zk-SNARKs because it has low multiplicative complexity and is more efficient to implement in zk-SNARKs.
- Generate a random
nullifier
($n_i$ ) andsecret
($s_i$ ). - Calculate the hash of them (
commitment
,$c_i = hash(n_i, s_i)$ ).
- Insert the
commitment
($c_i$ ) to the tree as leaf (onchain). - After every the path from leaf to root is updated.
For a commitment (
- Generate
$h_2 = H(H(p_{2,1},H(c_2, p_{2,0})),p_{2,2})$ - Check if
$h_2 = root$ . If equal then$c_i$ is in the tree.
Now to prove that
- Nullifier (
$n_2$ ) and Secret ($s_2$ ) will be used to generate Groth16 proof. - Nullifier (
$n_2$ ) is used as public parameter to prevent reusing the same commitment in the future. - Secret (
$s_2$ ) is kept secret (private input) for anonymity.
Generate a proof such that that
- leaf
$\rightarrow n_2$ - path
$\rightarrow [s_2, p_{2,0}, p_{2,1}, p_{2,2}]$ $h_2 = H(H(p_{2,1},H(H(n_2, s_2), p_{2,0})),p_{2,2})$
This project was developed and tested with the following software versions:
- Python: 3.11.7
- Node.js: 20.10.0
- Circom Compiler: 2.1.8
python3 -m venv env
source env/bin/activate
pip install -r requirements.txt
npm install -g snarkjs@latest
We will use ZK Incremental Merkle Tree using app.py
script to perform local and onchain operations.
It will generate random nullifier
and secret
and insert the hash of the both (commitment
) to the tree (onchain).
python app.py --task insert
It will fetch the path of a leaf given it's index and generate a proof for the leaf's membership in the tree. The proof will be verified onchain for tree membership without revealing for which leaf the proof was generated.
python app.py --task zk-verify