diff --git a/whitepaper.md b/whitepaper.md
index e88fc159ec719831a78385d69df0d4aa832bc674..d9bd53da48a417e55dbccd28673625bb100736aa 100644
--- a/whitepaper.md
+++ b/whitepaper.md
@@ -32,4 +32,59 @@ possible by default to create a token with a *subtree Merkle root* **without** p
verifying its children. Most tokens will forbid this, but it can be used to import a large amount of
somehow trusted tokens into the tree. The main usage is cross-tree communication with trust coming
from an user-based oracle (detailed later in this document), allowing bandswitch and computation
-sharding between multiple independent trees.
\ No newline at end of file
+sharding between multiple independent trees.
+
+## Merkle trees and proofs
+
+Merkle trees allow to store large sets of data. Each element hash is a leaf of a binary tree, and
+each node is the hash of the concatenation of its children. Finally, we only store the root of the
+tree called a **Merkle root**.
+
+```mermaid
+graph TD
+ root(root) --> abcd(abcd)
+ root --> efgh(efgh)
+
+ abcd --> ab(ab)
+ abcd --> cd(cd)
+
+ efgh --> ef(ef)
+ efgh --> gh(gh)
+
+ ab --> a(a)
+ ab --> b(b)
+ cd --> c(c)
+ cd --> d(d)
+ ef --> e(e)
+ ef --> f(f)
+ gh --> g(g)
+ gh --> h(h)
+
+ a --> A
+ b --> B
+ c --> C
+ d --> D
+ e --> E
+ f --> F
+ g --> G
+ h --> H
+```
+
+Data is provided with a proof of its presence in the tree called a **Merkle proof**. The proof is
+composed of all hashes necessary to recompute the branch from the data leaf and the root.
+
+```mermaid
+graph TD
+ root(root) --> abcd(abcd)
+ root --> efgh(efgh)
+
+ abcd --> ab(ab)
+ abcd --> cd(cd)
+
+ cd --> c(c)
+ cd --> d(d)
+
+ c --> C
+```
+
+If data is updated, we can compute its new hash and with the previous proof compute the new one.
\ No newline at end of file