Indexed Merkle Tree (Nullifier Tree)
Prerequisites
This page assumes familiarity with:
- Merkle trees and membership proofs
- The UTXO model for private state
- Zero-knowledge proof concepts (circuits, constraints)
Overview
This page covers indexed merkle trees and how they improve nullifier tree performance in circuits, including:
- Why nullifier trees are necessary
- How indexed merkle trees work
- Membership exclusion proofs
- Batch insertions
- Tradeoffs
This content was presented to the Privacy + Scaling Explorations team at the Ethereum Foundation.
Primer on Nullifier Trees
Privacy in public blockchains requires a UTXO model. State is stored in encrypted UTXOs in merkle trees. Since updating state directly leaks information, we simulate updates by "destroying" old UTXOs and creating new ones, resulting in an append-only merkle tree.
A classic merkle tree:
To destroy state, a "nullifier" tree stores deterministic values linked to notes in the append-only tree. This is typically implemented as a sparse Merkle Tree.
A sparse merkle tree (not every leaf stores a value):
To spend or modify a note in the private state tree, you must create a nullifier and prove it does not already exist in the nullifier tree. Since nullifier trees are modeled as sparse merkle trees, non-membership checks are conceptually trivial.
Data is stored at the leaf index corresponding to its value. For example, in a sparse tree containing values, to prove non-membership of value :
- Prove via a merkle membership proof (value does not exist)
- Conversely, prove to show the item exists
Problems introduced by using Sparse Merkle Trees for Nullifier Trees
While sparse Merkle Trees offer a simple solution, they have significant drawbacks. A sparse nullifier tree must have an index for , which for the bn254 curve requires a depth of 254.
A tree of depth 254 means 254 hashes per membership proof. Each nullifier insertion requires a non-membership check followed by an insertion—two trips from leaf to root. This results in hashes per insertion. Since the tree is sparse, insertions are random and must be sequential, so hash count scales linearly with nullifier count. This causes constraint counts in rollup circuits to grow rapidly, leading to long proving times.
Indexed Merkle Tree Constructions
This paper (page 6) introduces indexed merkle trees, which enable efficient non-membership proofs. Each node stores a value