Skip to content

Commit fd53460

Browse files
slavik0329frangio
andauthored
Added static method for verifying multiproof as well (#16)
Co-authored-by: Francisco Giordano <[email protected]>
1 parent 2134dc8 commit fd53460

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
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.4
4+
5+
- Added `StandardMerkleTree.verifyMultiProof` static method.
6+
37
## 1.0.3
48

59
- Added `StandardMerkleTree.verify` static method for verification of a proof for given root, leaf, and leaf encoding.

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ const verified = StandardMerkleTree.verify(root, ['address', 'uint'], [alice, '1
157157

158158
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.
159159

160+
### `StandardMerkleTree.verifyMultiProof`
161+
162+
```typescript
163+
const isValid = StandardMerkleTree.verifyMultiProof(root, leafEncoding, multiproof);
164+
```
165+
166+
Returns a boolean that is `true` when the multiproof verifies that all the values are contained in the tree given only the multiproof, merkle root, and leaf encoding.
167+
160168
### `StandardMerkleTree.load`
161169

162170
```typescript

src/standard.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,37 @@ describe('standard merkle tree', () => {
6565
}
6666
});
6767

68+
it('generates valid multi-proofs for all leaves from root and encoding', () => {
69+
const { t } = characters('abcdef');
70+
const leaves = Array.from(t.entries()).map(([_, leaf]) => leaf);
71+
72+
const multiproof = t.getMultiProof(leaves);
73+
74+
assert(StandardMerkleTree.verifyMultiProof(t.root, ['string'], multiproof));
75+
});
76+
77+
it('rejects invalid multi-proof using static verifyMultiProof method', () => {
78+
const { t } = characters('abcdef');
79+
const { t: fakeTree } = characters('xyz');
80+
81+
const fakeLeaves = Array.from(fakeTree.entries()).map(([_, leaf]) => leaf);
82+
const fakeMultiProof = fakeTree.getMultiProof(fakeLeaves);
83+
84+
assert(!StandardMerkleTree.verifyMultiProof(t.root, ['string'], fakeMultiProof));
85+
});
86+
87+
it('verifies partial multi-proof using static verifyMultiProof method', () => {
88+
const { t } = characters('abcdef');
89+
90+
const leaves = Array.from(t.entries())
91+
.filter(([index]) => index % 2 === 0)
92+
.map(([_, leaf]) => leaf);
93+
94+
const multiproof = t.getMultiProof(leaves);
95+
96+
assert(StandardMerkleTree.verifyMultiProof(t.root, ['string'], multiproof));
97+
});
98+
6899
it('renders tree representation', () => {
69100
const { t } = characters('abc');
70101

src/standard.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@ export class StandardMerkleTree<T extends any[]> {
6666
return equalsBytes(impliedRoot, hexToBytes(root));
6767
}
6868

69+
static verifyMultiProof<T extends any[]>(root: string, leafEncoding: string[], multiproof: MultiProof<string, T>): boolean {
70+
const leafHashes = multiproof.leaves.map(leaf => standardLeafHash(leaf, leafEncoding));
71+
const proofBytes = multiproof.proof.map(hexToBytes);
72+
73+
const impliedRoot = processMultiProof({
74+
leaves: leafHashes,
75+
proof: proofBytes,
76+
proofFlags: multiproof.proofFlags,
77+
});
78+
79+
return equalsBytes(impliedRoot, hexToBytes(root));
80+
}
81+
6982
dump(): StandardMerkleTreeData<T> {
7083
return {
7184
format: 'standard-v1',

0 commit comments

Comments
 (0)