diff --git a/docs/SMT.md b/docs/SMT.md index 106b4fa..06ad9e2 100644 --- a/docs/SMT.md +++ b/docs/SMT.md @@ -4,26 +4,26 @@ - [Overview](#overview) - [Implementation](#implementation) - - [Inner Nodes](#inner-nodes) - - [Extension Nodes](#extension-nodes) - - [Leaf Nodes](#leaf-nodes) - - [Lazy Nodes](#lazy-nodes) - - [Lazy Loading](#lazy-loading) - - [Visualisations](#visualisations) - - [General Trie Structure](#general-trie-structure) - - [Lazy Nodes](#lazy-nodes-1) + * [Inner Nodes](#inner-nodes) + * [Extension Nodes](#extension-nodes) + * [Leaf Nodes](#leaf-nodes) + * [Lazy Nodes](#lazy-nodes) + * [Lazy Loading](#lazy-loading) + * [Visualisations](#visualisations) + + [General Trie Structure](#general-trie-structure) + + [Lazy Nodes](#lazy-nodes-1) - [Paths](#paths) - - [Visualisation](#visualisation) + * [Visualisation](#visualisation) - [Values](#values) - - [Nil values](#nil-values) + * [Nil values](#nil-values) - [Hashers & Digests](#hashers--digests) - [Proofs](#proofs) - - [Verification](#verification) - - [Closest Proof](#closest-proof) - - [Compression](#compression) - - [Serialisation](#serialisation) + * [Verification](#verification) + * [Closest Proof](#closest-proof) + * [Compression](#compression) + * [Serialisation](#serialisation) - [Database](#database) - - [Data Loss](#data-loss) + * [Data Loss](#data-loss) - [Sparse Merkle Sum Trie](#sparse-merkle-sum-trie) - [Example](#example) @@ -378,10 +378,28 @@ This backstepping process allows the traversal to continue until it reaches a sentinel leaf that has the longest common prefix and most bits in common with the provided hash, up to the depth of the leaf found. -This method guarentees a proof of inclusion in all cases and can be verified by +This method guarantees a proof of inclusion in all cases and can be verified by using the `VerifyClosestProof` function which requires the proof and root hash of the trie. +Since the `ClosestProof` method takes a hash as input, it is possible to place a +leaf in the trie according to the hash's path, if it is known. Depending on +the use case of this function this may expose a vulnerability. _It is not +intendend to be used as a general purpose proof mechanism_. Given two parties: +the prover and the verifier, the verifier should supply the prover with a hash +after the trie has been "closed" and is no longer being updated. The prover +will then generate a `ClosestProof` for a leaf using the corresponding method. +The verifier can subsequently verify that proof for its validity. If however, +the prover were to know the hash prior to "closing" the trie, they could place +a leaf where the method would always guarantee it existence. This form of attack +can only happen due to the method's deterministic behaviour and the prover +knowing the hash before they have "closed" the trie. The intended use of this +method is that the verifier gives the hash only after the prover has closed their +trie and submitted the closed trie's root hash. This enables the verifier to +verify the integrity of the proof (if the trie was changed the root hash would +be different) and also guarantees the pseudo-random proof of inclusion was not +a maliciously placed leaf. + ### Compression Both proof types have compression and decompression functions available to