# Merkle Trees, Commitments & Chaining

This section explains how individual data points are fingerprinted, hidden, organized into a tamper-evident structure, and linked across time to create an immutable historical record.

### **Starting with Commitments**

Before we get to Merkle trees, we need to understand **commitments** as they're the building blocks.

#### **What Is a Commitment?**

A commitment is a way of locking in a value without revealing it. Think of it as putting a number in a sealed, tamper-evident envelope:

* **You can't see inside** — the commitment reveals nothing about the value
* **You can't swap it out** — once committed, the value is fixed
* **You can prove it later** — when you reveal the value, anyone can verify it matches the commitment

In this system, a commitment is created by combining a value with a **salt** (a unique secret) and running them through a hash function:

```
commitment = hash(value + salt)
```

The hash function is a one-way process. Given a value and salt, anyone can compute the commitment. But given only the commitment, it's impossible to figure out what value and salt produced it.

#### **Why Salts Are Essential**

Without a salt, commitments would be vulnerable to guessing. If someone knows the possible range of values (say, dollar amounts between $1 million and $100 million), they could hash each possibility until they find one that matches the commitment.

The salt eliminates this attack. Even if you know the value, you can't verify it without the salt. And salts in this system are derived from a private master secret. They never leave the secure enclave.

**Analogy:** Imagine a sealed envelope containing a number. Without a salt, it's like the envelope is slightly translucent. If there are only a few possible numbers, you might be able to tell which one is inside. With a salt, the envelope is completely opaque. The salt is like a unique, unpredictable padding that makes every envelope look identical from the outside.

#### **Dual Commitments**

The system creates **two commitments** for each value:

| Type              | Technology | Purpose                                                                 |
| ----------------- | ---------- | ----------------------------------------------------------------------- |
| Public commitment | keccak256  | Compatible with Ethereum smart contracts and widely used auditing tools |
| ZK commitment     | Poseidon   | Optimized for zero-knowledge proof systems                              |

Both commitments lock in the same value. They just use different mathematical methods suited for different verification contexts. The public commitment is the one external auditors and smart contracts would check. The ZK commitment is the one used inside the zero-knowledge proof system.

### **Now: Merkle Trees**

#### **What Is a Merkle Tree?**

A Merkle tree is a way of combining many fingerprints into one. It's named after Ralph Merkle, who invented it in 1979. The concept is used everywhere today — in Git (version control), in Bitcoin and Ethereum, in certificate transparency, and in file verification systems.

The idea is simple:

1. Start with all your commitments as **leaves** at the bottom
2. Pair them up and hash each pair together to create a **parent**
3. Keep pairing and hashing until you have a single hash at the top — the **root**

<figure><img src="https://3912034821-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEPdvkoJHpBF3QkBeBWkM%2Fuploads%2F9Cz5WTmkr84LFq1wMXFB%2Fdoc41.png?alt=media&#x26;token=90bc30bf-3fd6-4e49-8cb5-22524d733a64" alt=""><figcaption></figcaption></figure>

* `A, B, C, D` are the individual value commitments
* `H(A+B)` means "hash of A combined with B"
* The root is a single hash that represents all four values

#### **Why Not Just Hash Everything Together?**

You could just concatenate all values and hash them once. But a Merkle tree gives you additional capabilities:

**Tamper evidence at the individual level.** If someone changes just one value (say, B), the root changes completely. But more importantly, you can trace exactly which branch was affected.

**Efficient selective verification.** If you want to prove that a specific value (say, C) is part of the tree, you only need to provide a few sibling hashes along the path to the root — not the entire dataset. This is called a **Merkle proof**.

**Consistent structure.** No matter how many values are committed, the root is always the same size (32 bytes). The tree scales without the root growing.

#### **A Real-World Analogy**

Imagine a company with four divisions. Each division seals its financial report in an envelope (commitment). Then:

* Divisions are paired: envelopes from Division A and B are sealed together in a larger envelope
* The same for C and D
* Finally, the two larger envelopes are sealed into one master envelope (the root)

If someone tampers with Division B's report, the seal on the A+B envelope breaks, which breaks the master seal. And you can check Division B's report without opening Division C or D's envelopes.

### **How the System Builds the Tree**

#### **Leaf Ordering**

Commitments are placed in the tree in a specific, deterministic order based on their field identifiers. This ensures that the same data always produces the same tree, regardless of the order it was submitted.

#### **Padding**

The tree always has a fixed number of leaf positions (16 in the current system). If fewer values are committed, the remaining positions are filled with placeholder values (zeros). This ensures the tree structure is always the same, which is required for the zero-knowledge proofs.

The orange nodes are real commitments; the gray nodes are zero-padded slots.

#### **Two Parallel Trees**

Just as there are two types of commitments (public and ZK), there are two parallel Merkle trees:

<figure><img src="https://3912034821-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEPdvkoJHpBF3QkBeBWkM%2Fuploads%2FdmMhlpsFxjXpP8kW5znb%2Fdoc42.png?alt=media&#x26;token=a1a5759e-728f-47ba-b499-062abd3e7b42" alt=""><figcaption></figcaption></figure>

Both trees have identical structure and leaf ordering. The only difference is the hash function used. The public root goes into the TEE attestation and is verifiable by anyone. The ZK root is used inside the zero-knowledge proof circuit.

### **What the Merkle Root Represents**

The Merkle root is the cornerstone of the proof payload. It's a single, compact fingerprint that represents:

* Every reserve value
* Every liability value
* Every salt used
* The exact ordering and structure of the data

Change any single value, alter any salt, or reorder any element — the root changes completely.

This root is what the TEE hardware attests (see [Trusted Execution Environments](https://docs.afiprotocol.xyz/proof-of-reserve-network/trusted-execution-environments-tee)) and what the ZK proof verifies (see [Zero-Knowledge Proofs](https://docs.afiprotocol.xyz/proof-of-reserve-network/zero-knowledge-proofs)). It's the anchor point that connects every layer of the system's security.

### **Timeseries Chaining**

#### **The Problem with Standalone Proofs**

Imagine the system produces a proof every hour. Each proof confirms that at that moment, reserves and liabilities had certain values. That's useful — but what stops someone from going back and replacing last Tuesday's proof with a fabricated one?

If each proof stands alone, there's no way to tell. An attacker could:

* **Replace** an old proof with one showing different numbers
* **Delete** a proof from the history entirely
* **Reorder** proofs to misrepresent the timeline
* **Insert** fabricated proofs between legitimate ones

The individual proof would still verify correctly (it has valid attestation and ZK proofs). But the historical record would be a lie.

#### **The Solution: Chain the Roots**

Timeseries chaining solves this by making each proof **depend on the one before it**. When a new proof is generated, it includes the previous proof's Merkle root. The two roots are combined to create a **chained root**.

<figure><img src="https://3912034821-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEPdvkoJHpBF3QkBeBWkM%2Fuploads%2Fhfd3IGJQ1aqFfvjgXvdl%2Fdoc43.png?alt=media&#x26;token=8c7f6f23-72de-4608-99c8-c7b5df61d12a" alt=""><figcaption></figcaption></figure>

* **Proof #1** has no predecessor. It's the start of the chain, so its chained root is just its own root.
* **Proof #2** references Proof #1's root. Its chained root combines both.
* **Proof #3** references Proof #2's root. The chain continues.

Each link in the chain is like a knot in a rope — pull on any knot, and everything downstream shifts.

#### **What Chaining Prevents**

**Replacing a historical proof:** If an attacker replaces Proof #2 with fabricated data, the fabricated proof would have a different root. Proof #3 references Proof #2's original root — so the chain breaks. To get away with it, the attacker would need to re-forge every subsequent proof, each with valid hardware attestation and ZK proofs. That's effectively impossible.

**Deleting a proof:** If someone removes Proof #2, Proof #3 references a root that no longer exists. The gap is immediately obvious.

**Reordering proofs:** Each proof explicitly references its predecessor. Swapping them would mean a proof references a future proof — the ordering is self-evident.

**Inserting fabricated proofs:** Inserting between existing proofs would break the chain, because the subsequent proof already references the correct predecessor.

#### **Why This Is Like a Blockchain**

If this sounds familiar, it's because blockchains use the same principle. Each block contains the hash of the previous block, forming a chain that can't be modified without redoing all subsequent blocks.

|                 | Blockchain             | This System                      |
| --------------- | ---------------------- | -------------------------------- |
| **Chain links** | Blocks of transactions | Individual proof attestations    |
| **Secured by**  | Consensus (many nodes) | Hardware attestation + ZK proofs |
| **Purpose**     | Decentralized ledger   | Verifiable financial data        |
| **Frequency**   | Minutes (block time)   | On-demand (per attestation)      |

#### **Starting a New Chain**

Sometimes it's necessary to start a fresh chain — for example, when deploying a new version of the system or beginning a new data feed. In these cases, the system can generate a proof with no predecessor, creating a new chain from scratch.

This is an explicit action. The proof payload clearly indicates that there is no previous root, so verifiers know this is a chain start, not a broken link.

#### **Verifying the Chain**

To verify the chain between any two consecutive proofs:

1. Take the earlier proof's root
2. Take the later proof's root
3. Confirm the later proof's "previous root" field matches the earlier proof's root
4. Recompute the chained root and confirm it matches

To verify the full history, walk the chain from the first proof to the latest, checking each link.

### **Verification**

Verifiers can check the Merkle root by:

1. Taking all the commitments from the proof payload
2. Rebuilding the tree using the same algorithm
3. Confirming the recomputed root matches the root in the attestation

If the roots match, the commitments are the ones that were attested — nothing was added, removed, or changed after the hardware signed off.

### **Public Commitments Mode**

The system supports an optional **public commitments** mode for when transparency is more important than privacy:

| Mode              | What's Visible                            | Use Case                             |
| ----------------- | ----------------------------------------- | ------------------------------------ |
| Private (default) | Only commitments — values hidden          | Production use where privacy matters |
| Public            | Raw values included alongside commitments | Full transparency scenarios          |

In public mode, anyone can see the individual values. The Merkle tree and commitments still provide tamper evidence, but privacy is not the goal — auditability is.

### **Key Properties**

| Property                     | What It Means                                               |
| ---------------------------- | ----------------------------------------------------------- |
| **Tamper-evident**           | Changing any value changes the root                         |
| **Privacy-preserving**       | Commitments hide values; only the root is public            |
| **Deterministic**            | Same data always produces the same root                     |
| **Compact**                  | One 32-byte root represents all data                        |
| **Independently verifiable** | Anyone can rebuild the tree and check the root              |
| **Selectively provable**     | Individual values can be revealed without exposing others   |
| **Historically linked**      | Each proof chains to the previous one, preventing tampering |
