Skip to content

Commit 95e9ed3

Browse files
slavik0329Amxxfrangio
authored
Enable proof verification without full tree (#15)
Co-authored-by: Hadrien Croubois <[email protected]> Co-authored-by: Francisco Giordano <[email protected]>
1 parent 2ce6a45 commit 95e9ed3

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 1.0.3
4+
5+
- Added `StandardMerkleTree.verify` static method for verification of a proof for given root, leaf, and leaf encoding.
6+
37
## 1.0.2
48

59
- Added `StandardMerkleTree` methods `verify` and `verifyMultiProof`.

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ Creates a standard merkle tree out of an array of the elements in the tree, alon
149149
> **Note**
150150
> Consider reading the array of elements from a CSV file for easy interoperability with spreadsheets or other data processing pipelines.
151151
152+
### `StandardMerkleTree.verify`
153+
154+
```typescript
155+
const verified = StandardMerkleTree.verify(root, ['address', 'uint'], [alice, '100'], proof);
156+
```
157+
158+
Returns a boolean that is `true` when the proof verifies that the value is contained in the tree given only the proof, merkle root, and encoding.
159+
152160
### `tree.root`
153161

154162
```typescript

src/standard.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,26 @@ describe('standard merkle tree', () => {
3232
}
3333
});
3434

35+
it('generates valid single proofs for all leaves from root and encoding', () => {
36+
const { t } = characters('abcdef');
37+
38+
for (const [, leaf] of t.entries()) {
39+
const proof = t.getProof(leaf);
40+
41+
assert(StandardMerkleTree.verify(t.root, ['string'], leaf, proof));
42+
}
43+
});
44+
45+
it('rejects invalid proof using static verify method', () => {
46+
const { t } = characters('abcdef');
47+
const { t: fakeTree } = characters('xyz');
48+
49+
const testLeaf = ['x'];
50+
const proof = fakeTree.getProof(testLeaf);
51+
52+
assert(!StandardMerkleTree.verify(t.root, ['string'], testLeaf, proof));
53+
});
54+
3555
it('generates valid multiproofs', () => {
3656
const { t, l } = characters('abcdef');
3757

src/standard.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class StandardMerkleTree<T extends any[]> {
2828
private readonly values: { value: T, treeIndex: number }[],
2929
private readonly leafEncoding: string[],
3030
) {
31-
this.hashLookup =
31+
this.hashLookup =
3232
Object.fromEntries(values.map(({ value }, valueIndex) => [
3333
hex(standardLeafHash(value, leafEncoding)),
3434
valueIndex,
@@ -61,6 +61,11 @@ export class StandardMerkleTree<T extends any[]> {
6161
);
6262
}
6363

64+
static verify<T extends any[]>(root: string, leafEncoding: string[], leaf: T, proof: string[]): boolean {
65+
const impliedRoot = processProof(standardLeafHash(leaf, leafEncoding), proof.map(hexToBytes));
66+
return equalsBytes(impliedRoot, hexToBytes(root));
67+
}
68+
6469
dump(): StandardMerkleTreeData<T> {
6570
return {
6671
format: 'standard-v1',

0 commit comments

Comments
 (0)