@semaphore-protocol/group 4.0.0-beta.6 → 4.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/index.cjs +22 -14
- package/dist/index.js +22 -14
- package/dist/types/index.d.ts +91 -3
- package/package.json +3 -2
- package/src/index.ts +155 -3
- package/dist/types/group.d.ts +0 -90
- package/dist/types/types/index.d.ts +0 -3
- package/src/group.ts +0 -143
- package/src/types/index.ts +0 -4
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ const { commitment } = new Identity()
|
|
|
98
98
|
|
|
99
99
|
group.addMember(commitment)
|
|
100
100
|
|
|
101
|
-
//
|
|
101
|
+
// 12989101133047504182892154686643420754368236204022364847543591045056549053997n
|
|
102
102
|
console.log(group.members[0])
|
|
103
103
|
```
|
|
104
104
|
|
|
@@ -121,11 +121,11 @@ group.addMembers([identity1.commitment, identity2.commitment])
|
|
|
121
121
|
```typescript
|
|
122
122
|
import { Group } from "@semaphore-protocol/group"
|
|
123
123
|
|
|
124
|
-
const group = new Group([
|
|
124
|
+
const group = new Group([1n, 3n])
|
|
125
125
|
|
|
126
126
|
group.updateMember(0, 2)
|
|
127
127
|
|
|
128
|
-
console.log(group.members[0]) // "
|
|
128
|
+
console.log(group.members[0]) // "2n"
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
\# **removeMember**(index: _number_)
|
|
@@ -133,11 +133,11 @@ console.log(group.members[0]) // "2"
|
|
|
133
133
|
```typescript
|
|
134
134
|
import { Group } from "@semaphore-protocol/group"
|
|
135
135
|
|
|
136
|
-
const group = new Group([
|
|
136
|
+
const group = new Group([1n, 3n])
|
|
137
137
|
|
|
138
138
|
group.removeMember(0)
|
|
139
139
|
|
|
140
|
-
console.log(group.members[0]) //
|
|
140
|
+
console.log(group.members[0]) // 0n
|
|
141
141
|
```
|
|
142
142
|
|
|
143
143
|
\# **indexOf**(member: _BigNumberish_): _number_
|
|
@@ -145,7 +145,7 @@ console.log(group.members[0]) // "0"
|
|
|
145
145
|
```typescript
|
|
146
146
|
import { Group } from "@semaphore-protocol/group"
|
|
147
147
|
|
|
148
|
-
const group = new Group([
|
|
148
|
+
const group = new Group([1n])
|
|
149
149
|
|
|
150
150
|
const index = group.indexOf(1)
|
|
151
151
|
|
|
@@ -157,7 +157,7 @@ console.log(index) // 0
|
|
|
157
157
|
```typescript
|
|
158
158
|
import { Group } from "@semaphore-protocol/group"
|
|
159
159
|
|
|
160
|
-
const group = new Group([
|
|
160
|
+
const group = new Group([1n, 3n])
|
|
161
161
|
|
|
162
162
|
const proof = group.generateMerkleProof(0)
|
|
163
163
|
|
|
@@ -177,7 +177,7 @@ console.log(proof)
|
|
|
177
177
|
```typescript
|
|
178
178
|
import { Group } from "@semaphore-protocol/group"
|
|
179
179
|
|
|
180
|
-
const group = new Group([
|
|
180
|
+
const group = new Group([1n, 2n, 3n])
|
|
181
181
|
|
|
182
182
|
const exportedGroup = group.export()
|
|
183
183
|
|
|
@@ -192,7 +192,7 @@ console.log(exportedGroup)
|
|
|
192
192
|
```typescript
|
|
193
193
|
import { Group } from "@semaphore-protocol/group"
|
|
194
194
|
|
|
195
|
-
const group1 = new Group([
|
|
195
|
+
const group1 = new Group([1n, 2n, 3n])
|
|
196
196
|
|
|
197
197
|
const exportedGroup = group.export()
|
|
198
198
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/group
|
|
3
|
-
* @version 4.0.0-beta.
|
|
3
|
+
* @version 4.0.0-beta.8
|
|
4
4
|
* @file A library to create and manage Semaphore groups.
|
|
5
5
|
* @copyright Ethereum Foundation 2024
|
|
6
6
|
* @license MIT
|
|
@@ -136,7 +136,7 @@ class Group {
|
|
|
136
136
|
* @returns The root hash as a string.
|
|
137
137
|
*/
|
|
138
138
|
get root() {
|
|
139
|
-
return this.leanIMT.root ? this.leanIMT.root
|
|
139
|
+
return this.leanIMT.root ? this.leanIMT.root : 0n;
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* Returns the depth of the tree.
|
|
@@ -157,7 +157,7 @@ class Group {
|
|
|
157
157
|
* @returns The list of members of the group.
|
|
158
158
|
*/
|
|
159
159
|
get members() {
|
|
160
|
-
return this.leanIMT.leaves
|
|
160
|
+
return this.leanIMT.leaves;
|
|
161
161
|
}
|
|
162
162
|
/**
|
|
163
163
|
* Returns the index of a member. If the member does not exist it returns -1.
|
|
@@ -172,6 +172,9 @@ class Group {
|
|
|
172
172
|
* @param member The new member to be added.
|
|
173
173
|
*/
|
|
174
174
|
addMember(member) {
|
|
175
|
+
if (member === 0n || member === "0") {
|
|
176
|
+
throw new Error("Failed to add member: value cannot be 0");
|
|
177
|
+
}
|
|
175
178
|
this.leanIMT.insert(BigInt(member));
|
|
176
179
|
}
|
|
177
180
|
/**
|
|
@@ -179,6 +182,11 @@ class Group {
|
|
|
179
182
|
* @param members New members.
|
|
180
183
|
*/
|
|
181
184
|
addMembers(members) {
|
|
185
|
+
for (const member of members) {
|
|
186
|
+
if (member === 0n || member === "0") {
|
|
187
|
+
throw new Error("Failed to add member: value cannot be 0");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
182
190
|
this.leanIMT.insertMany(members.map(BigInt));
|
|
183
191
|
}
|
|
184
192
|
/**
|
|
@@ -187,6 +195,9 @@ class Group {
|
|
|
187
195
|
* @param member New member value.
|
|
188
196
|
*/
|
|
189
197
|
updateMember(index, member) {
|
|
198
|
+
if (this.members[index] === 0n) {
|
|
199
|
+
throw new Error("Failed to update member: it has been removed");
|
|
200
|
+
}
|
|
190
201
|
this.leanIMT.update(index, BigInt(member));
|
|
191
202
|
}
|
|
192
203
|
/**
|
|
@@ -194,21 +205,18 @@ class Group {
|
|
|
194
205
|
* @param index The index of the member to be removed.
|
|
195
206
|
*/
|
|
196
207
|
removeMember(index) {
|
|
197
|
-
this.
|
|
208
|
+
if (this.members[index] === 0n) {
|
|
209
|
+
throw new Error("Failed to remove member: it has already been removed");
|
|
210
|
+
}
|
|
211
|
+
this.leanIMT.update(index, 0n);
|
|
198
212
|
}
|
|
199
213
|
/**
|
|
200
214
|
* Creates a proof of membership for a member of the group.
|
|
201
215
|
* @param index The index of the member.
|
|
202
216
|
* @returns The {@link MerkleProof} object.
|
|
203
217
|
*/
|
|
204
|
-
generateMerkleProof(
|
|
205
|
-
|
|
206
|
-
return {
|
|
207
|
-
index,
|
|
208
|
-
leaf: leaf.toString(),
|
|
209
|
-
root: root.toString(),
|
|
210
|
-
siblings: siblings.map(String)
|
|
211
|
-
};
|
|
218
|
+
generateMerkleProof(index) {
|
|
219
|
+
return this.leanIMT.generateProof(index);
|
|
212
220
|
}
|
|
213
221
|
/**
|
|
214
222
|
* Enables the conversion of the group into a JSON string that
|
|
@@ -226,9 +234,9 @@ class Group {
|
|
|
226
234
|
* @param nodes The stringified JSON of the group.
|
|
227
235
|
* @returns The {@link Group} instance.
|
|
228
236
|
*/
|
|
229
|
-
static import(
|
|
237
|
+
static import(nodes) {
|
|
230
238
|
const group = new Group();
|
|
231
|
-
group.leanIMT.import(
|
|
239
|
+
group.leanIMT.import(nodes);
|
|
232
240
|
return group;
|
|
233
241
|
}
|
|
234
242
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/group
|
|
3
|
-
* @version 4.0.0-beta.
|
|
3
|
+
* @version 4.0.0-beta.8
|
|
4
4
|
* @file A library to create and manage Semaphore groups.
|
|
5
5
|
* @copyright Ethereum Foundation 2024
|
|
6
6
|
* @license MIT
|
|
@@ -134,7 +134,7 @@ class Group {
|
|
|
134
134
|
* @returns The root hash as a string.
|
|
135
135
|
*/
|
|
136
136
|
get root() {
|
|
137
|
-
return this.leanIMT.root ? this.leanIMT.root
|
|
137
|
+
return this.leanIMT.root ? this.leanIMT.root : 0n;
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
140
|
* Returns the depth of the tree.
|
|
@@ -155,7 +155,7 @@ class Group {
|
|
|
155
155
|
* @returns The list of members of the group.
|
|
156
156
|
*/
|
|
157
157
|
get members() {
|
|
158
|
-
return this.leanIMT.leaves
|
|
158
|
+
return this.leanIMT.leaves;
|
|
159
159
|
}
|
|
160
160
|
/**
|
|
161
161
|
* Returns the index of a member. If the member does not exist it returns -1.
|
|
@@ -170,6 +170,9 @@ class Group {
|
|
|
170
170
|
* @param member The new member to be added.
|
|
171
171
|
*/
|
|
172
172
|
addMember(member) {
|
|
173
|
+
if (member === 0n || member === "0") {
|
|
174
|
+
throw new Error("Failed to add member: value cannot be 0");
|
|
175
|
+
}
|
|
173
176
|
this.leanIMT.insert(BigInt(member));
|
|
174
177
|
}
|
|
175
178
|
/**
|
|
@@ -177,6 +180,11 @@ class Group {
|
|
|
177
180
|
* @param members New members.
|
|
178
181
|
*/
|
|
179
182
|
addMembers(members) {
|
|
183
|
+
for (const member of members) {
|
|
184
|
+
if (member === 0n || member === "0") {
|
|
185
|
+
throw new Error("Failed to add member: value cannot be 0");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
180
188
|
this.leanIMT.insertMany(members.map(BigInt));
|
|
181
189
|
}
|
|
182
190
|
/**
|
|
@@ -185,6 +193,9 @@ class Group {
|
|
|
185
193
|
* @param member New member value.
|
|
186
194
|
*/
|
|
187
195
|
updateMember(index, member) {
|
|
196
|
+
if (this.members[index] === 0n) {
|
|
197
|
+
throw new Error("Failed to update member: it has been removed");
|
|
198
|
+
}
|
|
188
199
|
this.leanIMT.update(index, BigInt(member));
|
|
189
200
|
}
|
|
190
201
|
/**
|
|
@@ -192,21 +203,18 @@ class Group {
|
|
|
192
203
|
* @param index The index of the member to be removed.
|
|
193
204
|
*/
|
|
194
205
|
removeMember(index) {
|
|
195
|
-
this.
|
|
206
|
+
if (this.members[index] === 0n) {
|
|
207
|
+
throw new Error("Failed to remove member: it has already been removed");
|
|
208
|
+
}
|
|
209
|
+
this.leanIMT.update(index, 0n);
|
|
196
210
|
}
|
|
197
211
|
/**
|
|
198
212
|
* Creates a proof of membership for a member of the group.
|
|
199
213
|
* @param index The index of the member.
|
|
200
214
|
* @returns The {@link MerkleProof} object.
|
|
201
215
|
*/
|
|
202
|
-
generateMerkleProof(
|
|
203
|
-
|
|
204
|
-
return {
|
|
205
|
-
index,
|
|
206
|
-
leaf: leaf.toString(),
|
|
207
|
-
root: root.toString(),
|
|
208
|
-
siblings: siblings.map(String)
|
|
209
|
-
};
|
|
216
|
+
generateMerkleProof(index) {
|
|
217
|
+
return this.leanIMT.generateProof(index);
|
|
210
218
|
}
|
|
211
219
|
/**
|
|
212
220
|
* Enables the conversion of the group into a JSON string that
|
|
@@ -224,9 +232,9 @@ class Group {
|
|
|
224
232
|
* @param nodes The stringified JSON of the group.
|
|
225
233
|
* @returns The {@link Group} instance.
|
|
226
234
|
*/
|
|
227
|
-
static import(
|
|
235
|
+
static import(nodes) {
|
|
228
236
|
const group = new Group();
|
|
229
|
-
group.leanIMT.import(
|
|
237
|
+
group.leanIMT.import(nodes);
|
|
230
238
|
return group;
|
|
231
239
|
}
|
|
232
240
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,91 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { LeanIMT, LeanIMTMerkleProof } from "@zk-kit/imt";
|
|
2
|
+
import type { BigNumber } from "@zk-kit/utils";
|
|
3
|
+
/**
|
|
4
|
+
* The Semaphore group is a {@link https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html | LeanIMT}
|
|
5
|
+
* (Lean Incremental Merkle Tree), i.e. an optimized version of the incremental binary Merkle tree
|
|
6
|
+
* used by Semaphore V3. The new tree does not use zero hashes, and its depth is dynamic.
|
|
7
|
+
* The members of a Semaphore group, or the leaves of a tree, are the identity commitments.
|
|
8
|
+
* Thanks to the properties of Merkle trees, it can be efficiently demonstrated that a group
|
|
9
|
+
* member belongs to the group.
|
|
10
|
+
* This class supports operations such as member addition, update, removal and Merkle proof
|
|
11
|
+
* generation and verification. Groups can also be exported or imported.
|
|
12
|
+
*/
|
|
13
|
+
export declare class Group {
|
|
14
|
+
leanIMT: LeanIMT;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new instance of the Group. Optionally, a list of identity commitments can
|
|
17
|
+
* be passed as a parameter. Adding members in chunks is more efficient than adding
|
|
18
|
+
* them one by one with the `addMember` function.
|
|
19
|
+
* @param members A list of identity commitments.
|
|
20
|
+
*/
|
|
21
|
+
constructor(members?: BigNumber[]);
|
|
22
|
+
/**
|
|
23
|
+
* Returns the root hash of the tree.
|
|
24
|
+
* @returns The root hash as a string.
|
|
25
|
+
*/
|
|
26
|
+
get root(): bigint;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the depth of the tree.
|
|
29
|
+
* @returns The tree depth as a number.
|
|
30
|
+
*/
|
|
31
|
+
get depth(): number;
|
|
32
|
+
/**
|
|
33
|
+
* Returns the size of the tree (i.e. number of leaves).
|
|
34
|
+
* @returns The tree size as a number.
|
|
35
|
+
*/
|
|
36
|
+
get size(): number;
|
|
37
|
+
/**
|
|
38
|
+
* Returns the members (i.e. identity commitments) of the group.
|
|
39
|
+
* @returns The list of members of the group.
|
|
40
|
+
*/
|
|
41
|
+
get members(): bigint[];
|
|
42
|
+
/**
|
|
43
|
+
* Returns the index of a member. If the member does not exist it returns -1.
|
|
44
|
+
* @param member A member of the group.
|
|
45
|
+
* @returns The index of the member, or -1 if it does not exist.
|
|
46
|
+
*/
|
|
47
|
+
indexOf(member: BigNumber): number;
|
|
48
|
+
/**
|
|
49
|
+
* Adds a new member to the group.
|
|
50
|
+
* @param member The new member to be added.
|
|
51
|
+
*/
|
|
52
|
+
addMember(member: BigNumber): void;
|
|
53
|
+
/**
|
|
54
|
+
* Adds new members to the group.
|
|
55
|
+
* @param members New members.
|
|
56
|
+
*/
|
|
57
|
+
addMembers(members: BigNumber[]): void;
|
|
58
|
+
/**
|
|
59
|
+
* Updates a member in the group.
|
|
60
|
+
* @param index Index of the member to be updated.
|
|
61
|
+
* @param member New member value.
|
|
62
|
+
*/
|
|
63
|
+
updateMember(index: number, member: BigNumber): void;
|
|
64
|
+
/**
|
|
65
|
+
* Removes a member from the group.
|
|
66
|
+
* @param index The index of the member to be removed.
|
|
67
|
+
*/
|
|
68
|
+
removeMember(index: number): void;
|
|
69
|
+
/**
|
|
70
|
+
* Creates a proof of membership for a member of the group.
|
|
71
|
+
* @param index The index of the member.
|
|
72
|
+
* @returns The {@link MerkleProof} object.
|
|
73
|
+
*/
|
|
74
|
+
generateMerkleProof(index: number): LeanIMTMerkleProof;
|
|
75
|
+
/**
|
|
76
|
+
* Enables the conversion of the group into a JSON string that
|
|
77
|
+
* can be re-used for future imports. This approach is beneficial for
|
|
78
|
+
* large groups, as it avoids re-calculating the tree hashes.
|
|
79
|
+
* @returns The stringified JSON of the group.
|
|
80
|
+
*/
|
|
81
|
+
export(): string;
|
|
82
|
+
/**
|
|
83
|
+
* Imports an entire group by initializing the tree without calculating
|
|
84
|
+
* any hashes. Note that it is crucial to ensure the integrity of the
|
|
85
|
+
* exported group.
|
|
86
|
+
* @param nodes The stringified JSON of the group.
|
|
87
|
+
* @returns The {@link Group} instance.
|
|
88
|
+
*/
|
|
89
|
+
static import(nodes: string): Group;
|
|
90
|
+
}
|
|
91
|
+
export { LeanIMTMerkleProof as MerkleProof };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semaphore-protocol/group",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.8",
|
|
4
4
|
"description": "A library to create and manage Semaphore groups.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"rollup-plugin-cleanup": "^3.2.1"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@zk-kit/imt": "2.0.0-beta.2"
|
|
42
|
+
"@zk-kit/imt": "2.0.0-beta.2",
|
|
43
|
+
"@zk-kit/utils": "1.0.0-beta"
|
|
43
44
|
}
|
|
44
45
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,156 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { LeanIMT, LeanIMTMerkleProof } from "@zk-kit/imt"
|
|
2
|
+
import type { BigNumber } from "@zk-kit/utils"
|
|
3
|
+
import { poseidon2 } from "poseidon-lite/poseidon2"
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The Semaphore group is a {@link https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html | LeanIMT}
|
|
7
|
+
* (Lean Incremental Merkle Tree), i.e. an optimized version of the incremental binary Merkle tree
|
|
8
|
+
* used by Semaphore V3. The new tree does not use zero hashes, and its depth is dynamic.
|
|
9
|
+
* The members of a Semaphore group, or the leaves of a tree, are the identity commitments.
|
|
10
|
+
* Thanks to the properties of Merkle trees, it can be efficiently demonstrated that a group
|
|
11
|
+
* member belongs to the group.
|
|
12
|
+
* This class supports operations such as member addition, update, removal and Merkle proof
|
|
13
|
+
* generation and verification. Groups can also be exported or imported.
|
|
14
|
+
*/
|
|
15
|
+
export class Group {
|
|
16
|
+
// The {@link https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html | LeanIMT} instance.
|
|
17
|
+
public leanIMT: LeanIMT
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a new instance of the Group. Optionally, a list of identity commitments can
|
|
21
|
+
* be passed as a parameter. Adding members in chunks is more efficient than adding
|
|
22
|
+
* them one by one with the `addMember` function.
|
|
23
|
+
* @param members A list of identity commitments.
|
|
24
|
+
*/
|
|
25
|
+
constructor(members: BigNumber[] = []) {
|
|
26
|
+
this.leanIMT = new LeanIMT((a, b) => poseidon2([a, b]), members.map(BigInt))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the root hash of the tree.
|
|
31
|
+
* @returns The root hash as a string.
|
|
32
|
+
*/
|
|
33
|
+
public get root(): bigint {
|
|
34
|
+
return this.leanIMT.root ? this.leanIMT.root : 0n
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Returns the depth of the tree.
|
|
39
|
+
* @returns The tree depth as a number.
|
|
40
|
+
*/
|
|
41
|
+
public get depth(): number {
|
|
42
|
+
return this.leanIMT.depth
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns the size of the tree (i.e. number of leaves).
|
|
47
|
+
* @returns The tree size as a number.
|
|
48
|
+
*/
|
|
49
|
+
public get size(): number {
|
|
50
|
+
return this.leanIMT.size
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Returns the members (i.e. identity commitments) of the group.
|
|
55
|
+
* @returns The list of members of the group.
|
|
56
|
+
*/
|
|
57
|
+
public get members(): bigint[] {
|
|
58
|
+
return this.leanIMT.leaves
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns the index of a member. If the member does not exist it returns -1.
|
|
63
|
+
* @param member A member of the group.
|
|
64
|
+
* @returns The index of the member, or -1 if it does not exist.
|
|
65
|
+
*/
|
|
66
|
+
public indexOf(member: BigNumber): number {
|
|
67
|
+
return this.leanIMT.indexOf(BigInt(member))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Adds a new member to the group.
|
|
72
|
+
* @param member The new member to be added.
|
|
73
|
+
*/
|
|
74
|
+
public addMember(member: BigNumber) {
|
|
75
|
+
if (member === 0n || member === "0") {
|
|
76
|
+
throw new Error("Failed to add member: value cannot be 0")
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.leanIMT.insert(BigInt(member))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Adds new members to the group.
|
|
84
|
+
* @param members New members.
|
|
85
|
+
*/
|
|
86
|
+
public addMembers(members: BigNumber[]) {
|
|
87
|
+
for (const member of members) {
|
|
88
|
+
if (member === 0n || member === "0") {
|
|
89
|
+
throw new Error("Failed to add member: value cannot be 0")
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.leanIMT.insertMany(members.map(BigInt))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Updates a member in the group.
|
|
98
|
+
* @param index Index of the member to be updated.
|
|
99
|
+
* @param member New member value.
|
|
100
|
+
*/
|
|
101
|
+
public updateMember(index: number, member: BigNumber) {
|
|
102
|
+
if (this.members[index] === 0n) {
|
|
103
|
+
throw new Error("Failed to update member: it has been removed")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this.leanIMT.update(index, BigInt(member))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Removes a member from the group.
|
|
111
|
+
* @param index The index of the member to be removed.
|
|
112
|
+
*/
|
|
113
|
+
public removeMember(index: number) {
|
|
114
|
+
if (this.members[index] === 0n) {
|
|
115
|
+
throw new Error("Failed to remove member: it has already been removed")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.leanIMT.update(index, 0n)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Creates a proof of membership for a member of the group.
|
|
123
|
+
* @param index The index of the member.
|
|
124
|
+
* @returns The {@link MerkleProof} object.
|
|
125
|
+
*/
|
|
126
|
+
public generateMerkleProof(index: number): LeanIMTMerkleProof {
|
|
127
|
+
return this.leanIMT.generateProof(index)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Enables the conversion of the group into a JSON string that
|
|
132
|
+
* can be re-used for future imports. This approach is beneficial for
|
|
133
|
+
* large groups, as it avoids re-calculating the tree hashes.
|
|
134
|
+
* @returns The stringified JSON of the group.
|
|
135
|
+
*/
|
|
136
|
+
public export(): string {
|
|
137
|
+
return this.leanIMT.export()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Imports an entire group by initializing the tree without calculating
|
|
142
|
+
* any hashes. Note that it is crucial to ensure the integrity of the
|
|
143
|
+
* exported group.
|
|
144
|
+
* @param nodes The stringified JSON of the group.
|
|
145
|
+
* @returns The {@link Group} instance.
|
|
146
|
+
*/
|
|
147
|
+
static import(nodes: string): Group {
|
|
148
|
+
const group = new Group()
|
|
149
|
+
|
|
150
|
+
group.leanIMT.import(nodes)
|
|
151
|
+
|
|
152
|
+
return group
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export { LeanIMTMerkleProof as MerkleProof }
|
package/dist/types/group.d.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { LeanIMT } from "@zk-kit/imt";
|
|
2
|
-
import { BigNumberish, MerkleProof } from "./types";
|
|
3
|
-
/**
|
|
4
|
-
* The Semaphore group is a {@link https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html | LeanIMT}
|
|
5
|
-
* (Lean Incremental Merkle Tree), i.e. an optimized version of the incremental binary Merkle tree
|
|
6
|
-
* used by Semaphore V3. The new tree does not use zero hashes, and its depth is dynamic.
|
|
7
|
-
* The members of a Semaphore group, or the leaves of a tree, are the identity commitments.
|
|
8
|
-
* Thanks to the properties of Merkle trees, it can be efficiently demonstrated that a group
|
|
9
|
-
* member belongs to the group.
|
|
10
|
-
* This class supports operations such as member addition, update, removal and Merkle proof
|
|
11
|
-
* generation and verification. Groups can also be exported or imported.
|
|
12
|
-
*/
|
|
13
|
-
export default class Group {
|
|
14
|
-
leanIMT: LeanIMT;
|
|
15
|
-
/**
|
|
16
|
-
* Creates a new instance of the Group. Optionally, a list of identity commitments can
|
|
17
|
-
* be passed as a parameter. Adding members in chunks is more efficient than adding
|
|
18
|
-
* them one by one with the `addMember` function.
|
|
19
|
-
* @param members A list of identity commitments.
|
|
20
|
-
*/
|
|
21
|
-
constructor(members?: BigNumberish[]);
|
|
22
|
-
/**
|
|
23
|
-
* Returns the root hash of the tree.
|
|
24
|
-
* @returns The root hash as a string.
|
|
25
|
-
*/
|
|
26
|
-
get root(): string;
|
|
27
|
-
/**
|
|
28
|
-
* Returns the depth of the tree.
|
|
29
|
-
* @returns The tree depth as a number.
|
|
30
|
-
*/
|
|
31
|
-
get depth(): number;
|
|
32
|
-
/**
|
|
33
|
-
* Returns the size of the tree (i.e. number of leaves).
|
|
34
|
-
* @returns The tree size as a number.
|
|
35
|
-
*/
|
|
36
|
-
get size(): number;
|
|
37
|
-
/**
|
|
38
|
-
* Returns the members (i.e. identity commitments) of the group.
|
|
39
|
-
* @returns The list of members of the group.
|
|
40
|
-
*/
|
|
41
|
-
get members(): string[];
|
|
42
|
-
/**
|
|
43
|
-
* Returns the index of a member. If the member does not exist it returns -1.
|
|
44
|
-
* @param member A member of the group.
|
|
45
|
-
* @returns The index of the member, or -1 if it does not exist.
|
|
46
|
-
*/
|
|
47
|
-
indexOf(member: BigNumberish): number;
|
|
48
|
-
/**
|
|
49
|
-
* Adds a new member to the group.
|
|
50
|
-
* @param member The new member to be added.
|
|
51
|
-
*/
|
|
52
|
-
addMember(member: BigNumberish): void;
|
|
53
|
-
/**
|
|
54
|
-
* Adds new members to the group.
|
|
55
|
-
* @param members New members.
|
|
56
|
-
*/
|
|
57
|
-
addMembers(members: BigNumberish[]): void;
|
|
58
|
-
/**
|
|
59
|
-
* Updates a member in the group.
|
|
60
|
-
* @param index Index of the member to be updated.
|
|
61
|
-
* @param member New member value.
|
|
62
|
-
*/
|
|
63
|
-
updateMember(index: number, member: BigNumberish): void;
|
|
64
|
-
/**
|
|
65
|
-
* Removes a member from the group.
|
|
66
|
-
* @param index The index of the member to be removed.
|
|
67
|
-
*/
|
|
68
|
-
removeMember(index: number): void;
|
|
69
|
-
/**
|
|
70
|
-
* Creates a proof of membership for a member of the group.
|
|
71
|
-
* @param index The index of the member.
|
|
72
|
-
* @returns The {@link MerkleProof} object.
|
|
73
|
-
*/
|
|
74
|
-
generateMerkleProof(_index: number): MerkleProof;
|
|
75
|
-
/**
|
|
76
|
-
* Enables the conversion of the group into a JSON string that
|
|
77
|
-
* can be re-used for future imports. This approach is beneficial for
|
|
78
|
-
* large groups, as it avoids re-calculating the tree hashes.
|
|
79
|
-
* @returns The stringified JSON of the group.
|
|
80
|
-
*/
|
|
81
|
-
export(): string;
|
|
82
|
-
/**
|
|
83
|
-
* Imports an entire group by initializing the tree without calculating
|
|
84
|
-
* any hashes. Note that it is crucial to ensure the integrity of the
|
|
85
|
-
* exported group.
|
|
86
|
-
* @param nodes The stringified JSON of the group.
|
|
87
|
-
* @returns The {@link Group} instance.
|
|
88
|
-
*/
|
|
89
|
-
static import(exportedGroup: string): Group;
|
|
90
|
-
}
|
package/src/group.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { LeanIMT } from "@zk-kit/imt"
|
|
2
|
-
import { poseidon2 } from "poseidon-lite/poseidon2"
|
|
3
|
-
import { BigNumberish, MerkleProof } from "./types"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The Semaphore group is a {@link https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html | LeanIMT}
|
|
7
|
-
* (Lean Incremental Merkle Tree), i.e. an optimized version of the incremental binary Merkle tree
|
|
8
|
-
* used by Semaphore V3. The new tree does not use zero hashes, and its depth is dynamic.
|
|
9
|
-
* The members of a Semaphore group, or the leaves of a tree, are the identity commitments.
|
|
10
|
-
* Thanks to the properties of Merkle trees, it can be efficiently demonstrated that a group
|
|
11
|
-
* member belongs to the group.
|
|
12
|
-
* This class supports operations such as member addition, update, removal and Merkle proof
|
|
13
|
-
* generation and verification. Groups can also be exported or imported.
|
|
14
|
-
*/
|
|
15
|
-
export default class Group {
|
|
16
|
-
// The {@link https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html | LeanIMT} instance.
|
|
17
|
-
public leanIMT: LeanIMT
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Creates a new instance of the Group. Optionally, a list of identity commitments can
|
|
21
|
-
* be passed as a parameter. Adding members in chunks is more efficient than adding
|
|
22
|
-
* them one by one with the `addMember` function.
|
|
23
|
-
* @param members A list of identity commitments.
|
|
24
|
-
*/
|
|
25
|
-
constructor(members: BigNumberish[] = []) {
|
|
26
|
-
this.leanIMT = new LeanIMT((a, b) => poseidon2([a, b]), members.map(BigInt))
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Returns the root hash of the tree.
|
|
31
|
-
* @returns The root hash as a string.
|
|
32
|
-
*/
|
|
33
|
-
public get root(): string {
|
|
34
|
-
return this.leanIMT.root ? this.leanIMT.root.toString() : "0"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Returns the depth of the tree.
|
|
39
|
-
* @returns The tree depth as a number.
|
|
40
|
-
*/
|
|
41
|
-
public get depth(): number {
|
|
42
|
-
return this.leanIMT.depth
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Returns the size of the tree (i.e. number of leaves).
|
|
47
|
-
* @returns The tree size as a number.
|
|
48
|
-
*/
|
|
49
|
-
public get size(): number {
|
|
50
|
-
return this.leanIMT.size
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Returns the members (i.e. identity commitments) of the group.
|
|
55
|
-
* @returns The list of members of the group.
|
|
56
|
-
*/
|
|
57
|
-
public get members(): string[] {
|
|
58
|
-
return this.leanIMT.leaves.map(String)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Returns the index of a member. If the member does not exist it returns -1.
|
|
63
|
-
* @param member A member of the group.
|
|
64
|
-
* @returns The index of the member, or -1 if it does not exist.
|
|
65
|
-
*/
|
|
66
|
-
public indexOf(member: BigNumberish): number {
|
|
67
|
-
return this.leanIMT.indexOf(BigInt(member))
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Adds a new member to the group.
|
|
72
|
-
* @param member The new member to be added.
|
|
73
|
-
*/
|
|
74
|
-
public addMember(member: BigNumberish) {
|
|
75
|
-
this.leanIMT.insert(BigInt(member))
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Adds new members to the group.
|
|
80
|
-
* @param members New members.
|
|
81
|
-
*/
|
|
82
|
-
public addMembers(members: BigNumberish[]) {
|
|
83
|
-
this.leanIMT.insertMany(members.map(BigInt))
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Updates a member in the group.
|
|
88
|
-
* @param index Index of the member to be updated.
|
|
89
|
-
* @param member New member value.
|
|
90
|
-
*/
|
|
91
|
-
public updateMember(index: number, member: BigNumberish) {
|
|
92
|
-
this.leanIMT.update(index, BigInt(member))
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Removes a member from the group.
|
|
97
|
-
* @param index The index of the member to be removed.
|
|
98
|
-
*/
|
|
99
|
-
public removeMember(index: number) {
|
|
100
|
-
this.leanIMT.update(index, BigInt(0))
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Creates a proof of membership for a member of the group.
|
|
105
|
-
* @param index The index of the member.
|
|
106
|
-
* @returns The {@link MerkleProof} object.
|
|
107
|
-
*/
|
|
108
|
-
public generateMerkleProof(_index: number): MerkleProof {
|
|
109
|
-
const { index, leaf, root, siblings } = this.leanIMT.generateProof(_index)
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
index,
|
|
113
|
-
leaf: leaf.toString(),
|
|
114
|
-
root: root.toString(),
|
|
115
|
-
siblings: siblings.map(String)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Enables the conversion of the group into a JSON string that
|
|
121
|
-
* can be re-used for future imports. This approach is beneficial for
|
|
122
|
-
* large groups, as it avoids re-calculating the tree hashes.
|
|
123
|
-
* @returns The stringified JSON of the group.
|
|
124
|
-
*/
|
|
125
|
-
public export(): string {
|
|
126
|
-
return this.leanIMT.export()
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Imports an entire group by initializing the tree without calculating
|
|
131
|
-
* any hashes. Note that it is crucial to ensure the integrity of the
|
|
132
|
-
* exported group.
|
|
133
|
-
* @param nodes The stringified JSON of the group.
|
|
134
|
-
* @returns The {@link Group} instance.
|
|
135
|
-
*/
|
|
136
|
-
static import(exportedGroup: string): Group {
|
|
137
|
-
const group = new Group()
|
|
138
|
-
|
|
139
|
-
group.leanIMT.import(exportedGroup)
|
|
140
|
-
|
|
141
|
-
return group
|
|
142
|
-
}
|
|
143
|
-
}
|
package/src/types/index.ts
DELETED