Merkle Proof Format
TrackForge uses a deterministic binary Merkle tree to commit a set of evidence packet hashes to one root. The root is then tied to certificate and OpenTimestamps proof state.
Proof JSON
{
"leaf_hash": "64-character sha256 hex",
"proof_hashes": ["64-character sha256 hex"],
"proof_directions": ["right"],
"root_hash": "64-character sha256 hex",
"leaf_index": 0,
"total_leaves": 1095
}
| Field | Meaning |
|---|---|
leaf_hash | Evidence packet hash or other methodology-defined leaf hash. |
proof_hashes | Sibling hashes from leaf to root. |
proof_directions | Direction of each sibling: left or right. |
root_hash | Merkle root committed by the rating/certification event. |
leaf_index | Position in the sorted leaf list. |
total_leaves | Total leaves in the tree. |
Construction Rules
- Sort leaf hashes lexicographically.
- Pair adjacent hashes.
- If a layer has an odd number of nodes, duplicate the last node.
- Combine siblings by concatenating their hex strings and hashing the UTF-8 bytes:
hashlib.sha256((left + right).encode("utf-8")).hexdigest()
This mirrors the backend implementation. The combination input is the concatenated hex text, not decoded raw bytes.
Verification Algorithm
def verify_merkle_proof(proof: dict) -> bool:
current = proof["leaf_hash"]
for sibling, direction in zip(proof["proof_hashes"], proof["proof_directions"]):
if direction == "right":
current = sha256_hex(current + sibling)
else:
current = sha256_hex(sibling + current)
return current == proof["root_hash"]
The proof only establishes inclusion in the committed root. To verify a certificate, also check that the root belongs to the same rating event, methodology hash, snapshot run, and proof state shown on the certificate.