Merkle tree
Commitment leaves, depth-16 membership paths, generation-scoped roots and a 32-entry accepted-root ring.
Shield and Private Swap append note commitments as leaves in a Poseidon Merkle tree. A proof can establish that a note commitment belongs to an accepted root without disclosing the note's owner secret or leaf index.
leaf commitments · Poseidon2 parent hashes · 16 sibling values in a spend witness
Depth and capacity
The frozen tree depth is 16. A generation therefore has capacity:
A membership witness contains 16 sibling hashes and an index. At each level, the index bit determines whether the current node is the left or right input to Poseidon2.
Root history and sequence
TreeState stores a sequence counter and a ring of 32 root values with their sequence and generation. Core accepts a proof root only when the root, root sequence and generation identify a live entry in that ring. This permits a short window of roots while preventing a caller from pairing a root with a different sequence or tree generation.
The proof establishes:
note commitment ── 16 sibling hashes + index ──> stated Merkle rootOnly the root is public to the circuit statement; the path and index are witness data. The commitment itself is public as an appended leaf.
Reconstructing witnesses
The SDK default OnChainPagedMerkleWitnessProvider fetches the finalized TreeState, PageDirectory and 16 leaf pages in one 18-account request, verifies archive bindings and digests, finds the commitment, then checks the reconstructed 16-level path against the root. See Tree paging & archive and SDK recovery & witnesses.
Merkle membership proves that a commitment was appended. It does not prove that the corresponding note is unspent; the nullifier registry handles that separate property.