|
28 | 28 | <img alt="NPM bundle size" src="https://img.shields.io/bundlephobia/min/@cedoor/smt?style=flat-square">
|
29 | 29 | </p>
|
30 | 30 |
|
31 |
| - |
32 | 31 | A sparse Merkle tree (SMT) is a data structure useful for storing a key/value map where every leaf node of the tree contains the cryptographic hash of a key/value pair and every non leaf node contains the concatenated hashes of its child nodes. SMTs provides a secure and efficient verification of large data sets and they are often used in peer-to-peer technologies. This implementation is an optimized version of the traditional sparse Merkle tree and it is based on the concepts expressed in the papers and resources below.
|
33 | 32 |
|
34 | 33 | **Notice**: this library is still not stable and therefore it must be used with care.
|
35 | 34 |
|
36 | 35 | ## References
|
37 | 36 |
|
38 |
| -1. Rasmus Dahlberg, Tobias Pulls and Roel Peeters. *Efficient Sparse Merkle Trees: Caching Strategies and Secure (Non-)Membership Proofs*. Cryptology ePrint Archive: Report 2016/683, 2016. https://eprint.iacr.org/2016/683. |
39 |
| -2. Faraz Haider. *Compact sparse merkle trees*. Cryptology ePrint Archive: Report 2018/955, 2018. https://eprint.iacr.org/2018/955. |
40 |
| -3. Jordi Baylina and Marta Bellés. *Sparse Merkle Trees*. https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf. |
41 |
| -4. Vitalik Buterin Fichter. *Optimizing sparse Merkle trees*. https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751. |
| 37 | +1. Rasmus Dahlberg, Tobias Pulls and Roel Peeters. _Efficient Sparse Merkle Trees: Caching Strategies and Secure (Non-)Membership Proofs_. Cryptology ePrint Archive: Report 2016/683, 2016. https://eprint.iacr.org/2016/683. |
| 38 | +2. Faraz Haider. _Compact sparse merkle trees_. Cryptology ePrint Archive: Report 2018/955, 2018. https://eprint.iacr.org/2018/955. |
| 39 | +3. Jordi Baylina and Marta Bellés. _Sparse Merkle Trees_. https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf. |
| 40 | +4. Vitalik Buterin Fichter. _Optimizing sparse Merkle trees_. https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751. |
42 | 41 |
|
43 | 42 | ---
|
44 | 43 |
|
@@ -86,72 +85,78 @@ or [JSDelivr](https://www.jsdelivr.com/):
|
86 | 85 |
|
87 | 86 | ## API reference
|
88 | 87 |
|
89 |
| -* [Creating trees](#smt-new) |
90 |
| -* [Adding entries](#smt-add) |
91 |
| -* [Getting values](#smt-get) |
92 |
| -* [Updating values](#smt-update) |
93 |
| -* [Deleting entries](#smt-delete) |
94 |
| -* [Creating proofs](#smt-create-proof) |
95 |
| -* [Verifying proofs](#smt-verify-proof) |
| 88 | +- [Creating trees](#smt-new) |
| 89 | +- [Adding entries](#smt-add) |
| 90 | +- [Getting values](#smt-get) |
| 91 | +- [Updating values](#smt-update) |
| 92 | +- [Deleting entries](#smt-delete) |
| 93 | +- [Creating proofs](#smt-create-proof) |
| 94 | +- [Verifying proofs](#smt-verify-proof) |
96 | 95 |
|
97 |
| -<a name="smt-new" href="#smt-new">#</a> **new SMT**(hash: *HashFunction*): *SMT* |
| 96 | +<a name="smt-new" href="#smt-new">#</a> **new SMT**(hash: _HashFunction_, bigNumbers?: _boolean_): _SMT_ |
98 | 97 |
|
99 | 98 | ```typescript
|
100 | 99 | import { SMT, hexToDec } from "@cedoor/smt"
|
101 | 100 | import { sha256 } from "js-sha256"
|
| 101 | +import { poseidon } from "circomlib" |
102 | 102 |
|
| 103 | +// Hexadecimal hashes. |
103 | 104 | const hash = (childNodes: ChildNodes) => sha256(childNodes.join(""))
|
104 | 105 | const tree = new SMT(hash)
|
105 | 106 |
|
| 107 | +// Big number hashes. |
| 108 | +const hash2 = (childNodes: ChildNodes) => poseidon(childNodes) |
| 109 | +const tree2 = new SMT(hash, true) |
| 110 | + |
106 | 111 | console.log(tree.root) // 0
|
| 112 | +console.log(tree2.root) // 0n |
107 | 113 | ```
|
108 | 114 |
|
109 |
| -<a name="smt-add" href="#smt-add">#</a> **add**(key: *string* | *number*, value: *string* | *number*): *void* |
| 115 | +<a name="smt-add" href="#smt-add">#</a> **add**(key: _string_ | _number_, value: _string_ | _number_): _void_ |
110 | 116 |
|
111 | 117 | ```typescript
|
112 |
| -tree.add(22, 120) // Decimal key/value. |
113 | 118 | tree.add("2b", "44") // Hexadecimal key/value.
|
114 |
| -tree.add(13, 231) |
115 |
| -tree.add(16, 321) |
116 |
| -tree.add(32, 832) |
| 119 | +tree.add("16", "78") |
| 120 | +tree.add("d", "e7") |
| 121 | +tree.add("10", "141") |
| 122 | +tree.add("20", "340") |
117 | 123 |
|
118 |
| -console.log(tree.root) // 31ee2a59741c9c32a32d8c7fafe461cca1ccaf5986c2d592586e3e6482a48645 |
| 124 | +console.log(tree.root) // 31ee2a59741c9c32a32d8c7fafe461cca1ccaf5986c2d592586e3e6482a48645 |
119 | 125 | ```
|
120 | 126 |
|
121 |
| -<a name="smt-get" href="#smt-get">#</a> **get**(key: *string* | *number*): *undefined* | *string* |
| 127 | +<a name="smt-get" href="#smt-get">#</a> **get**(key: _string_ | _number_): _undefined_ | _string_ |
122 | 128 |
|
123 | 129 | ```typescript
|
124 |
| -const value = tree.get(22) |
| 130 | +const value = tree.get("16") |
125 | 131 |
|
126 | 132 | console.log(value) // 78
|
127 |
| -console.log(hexToDec(value)) // 120 |
128 | 133 | ```
|
129 | 134 |
|
130 |
| -<a name="smt-update" href="#smt-update">#</a> **update**(key: *string* | *number*, value: *string* | *number*): *void* |
| 135 | +<a name="smt-update" href="#smt-update">#</a> **update**(key: _string_ | _number_, value: _string_ | _number_): _void_ |
131 | 136 |
|
132 | 137 | ```typescript
|
133 |
| -tree.update(22, 121) |
| 138 | +tree.update("16", "79") |
134 | 139 |
|
135 |
| -const value = tree.get(22) |
| 140 | +const value = tree.get("16") |
136 | 141 |
|
137 |
| -console.log(hexToDec(value)) // 121 |
| 142 | +console.log(value) // 79 |
138 | 143 | ```
|
139 | 144 |
|
140 |
| -<a name="smt-delete" href="#smt-delete">#</a> **delete**(key: *string* | *number*): *void* |
| 145 | +<a name="smt-delete" href="#smt-delete">#</a> **delete**(key: _string_ | _number_): _void_ |
141 | 146 |
|
142 | 147 | ```typescript
|
143 |
| -tree.delete(22) |
| 148 | +tree.delete("16") |
144 | 149 |
|
145 |
| -const value = tree.get(22) |
| 150 | +const value = tree.get("16") |
146 | 151 |
|
147 | 152 | console.log(value) // undefined
|
148 | 153 | ```
|
149 | 154 |
|
150 |
| -<a name="smt-create-proof" href="#smt-create-proof">#</a> **createProof**(key: *string* | *number*): *Proof* |
| 155 | +<a name="smt-create-proof" href="#smt-create-proof">#</a> **createProof**(key: _string_ | _number_): _Proof_ |
151 | 156 |
|
152 | 157 | ```typescript
|
153 | 158 | const membershipProof = tree.createProof("2b")
|
154 |
| -const nonMembershipProof = tree.createProof(22) // This key has been deleted. |
| 159 | +const nonMembershipProof = tree.createProof("16") // This key has been deleted. |
155 | 160 |
|
156 | 161 | console.log(membershipProof)
|
157 | 162 | /*
|
@@ -182,8 +187,7 @@ console.log(nonMembershipProof)
|
182 | 187 | */
|
183 | 188 | ```
|
184 | 189 |
|
185 |
| -<a name="smt-verify-proof" href="#smt-verify-proof">#</a> **verifyProof**(proof: *Proof*): *boolean* |
186 |
| - |
| 190 | +<a name="smt-verify-proof" href="#smt-verify-proof">#</a> **verifyProof**(proof: _Proof_): _boolean_ |
187 | 191 |
|
188 | 192 | ```typescript
|
189 | 193 | console.log(tree.verifyProof(membershipProof)) // true
|
|
0 commit comments