Merkle Trees in Aztec
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0101\)
Merkle Tree Basics
\(A\)
\(F\)
\(N\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(\text{root}\)
\(\text{nodes}\)
\(\text{leaves}\)
\(\text{hash path}\)
\(\text{depth} = 4\)
Storage of Merkle Tree
- We store merkle trees using levelDB database
- Use of the dictionary data structureÂ
- For a depth \(d=3\) tree with all leaves non-empty:
\(i=0\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(i=1\)
\(i=2\)
\(\text{key}\)
\(\text{value}\)
\(r\)
\(h^2_0\)
\(h^2_1\)
\(h^2_1\)
\(h^1_2\)
\(h^1_3\)
\(h^1_0\)
\(h^0_0\)
\(h^0_1\)
\(h^1_1\)
\(h^0_2\)
\(h^0_3\)
\(h^1_2\)
\(h^0_4\)
\(h^0_5\)
\(h^1_3\)
\(h^0_6\)
\(h^0_7\)
\(h^2_0\)
\(h^1_0\)
\(h^1_1\)
Storage of Merkle Tree
- Suppose we have depth \(d=3\) tree with only 5 filled leaves
- Right subtree at \(i=2\) is called as a stump as only one leaf is filled in it!
- For a stump, we only store the filled leaf value and its subtree index
- Note that we use \(65\) bytes to store a stump, \(64\) bytes for a usual node
- Provides optimised storage for sparse merkle trees
\(i=0\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(i=1\)
\(i=2\)
\(\text{key}\)
\(\text{value}\)
\(r\)
\(h^2_0\)
\(h^2_1\)
\(h^2_0\)
\(h^1_0\)
\(h^1_1\)
\(h^2_1\)
\(h^0_6\)
\(2\)
\(\texttt{true}\)
\(h^1_0\)
\(h^0_0\)
\(h^0_1\)
\(h^1_1\)
\(h^0_2\)
\(h^0_3\)
\(1101\)
\(1010\)
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(\text{key}\)
\(\text{value}\)
\(r\)
\(h^3_0\)
\(h^3_1\)
\(h^2_0\)
\(h^3_0\)
\(h^2_1\)
\(5\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(0\)
\(A\)
\(\texttt{true}\)
\(h^2_0\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
\(\text{Common Height} = 2\)
\(z[2]\)
\(h^2_3\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
\(z[2]\)
\(h^2_3\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
\(z[2]\)
\(h^2_3\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
\(z[2]\)
\(h^2_3\)
\(z[1]\)
\(z[1]\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
\(z[2]\)
\(h^2_3\)
\(z[1]\)
\(z[1]\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
\(z[2]\)
\(h^2_3\)
\(z[1]\)
\(z[1]\)
Hash Path
\(A\)
\(F\)
\(N\)
\(i=0\)
\(i=1\)
\(i=2\)
\(i=3\)
\(0\)
\(1\)
\(2\)
\(3\)
\(4\)
\(5\)
\(6\)
\(7\)
\(8\)
\(9\)
\(10\)
\(11\)
\(12\)
\(13\)
\(14\)
\(15\)
\(1101\)
\(1010\)
\(r\)
\(h^3_0\)
\(5\)
\(h^2_0\)
\(\text{key}\)
\(\text{value}\)
\(h^3_1\)
\(h^3_0\)
\(N\)
\(h^3_1\)
\(\texttt{true}\)
\(h^2_1\)
\(0\)
\(A\)
\(\texttt{true}\)
\(1\)
\(F\)
\(\texttt{true}\)
\(h^2_0\)
\(h^2_1\)
\(\vec{h}(10)\)
\(0\)
\(1\)
\(2\)
\(3\)
\(h^3_0\)
\(h^3_1\)
\(z[2]\)
\(h^2_3\)
\(z[1]\)
\(z[1]\)
\(-1\)
\(-1\)