@semaphore-protocol/proof 0.1.0 → 0.2.2
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 +61 -11
- package/dist/index.mjs +118 -148
- package/dist/index.node.js +124 -151
- package/dist/types/createMerkleProof.d.ts +11 -0
- package/dist/types/createMerkleTree.d.ts +10 -0
- package/dist/types/generateNullifierHash.d.ts +8 -0
- package/dist/types/generateProof.d.ts +4 -0
- package/dist/types/generateSignalHash.d.ts +6 -0
- package/dist/types/index.d.ts +8 -3
- package/dist/types/{semaphore.test.d.ts → index.test.d.ts} +0 -0
- package/dist/types/packToSolidityProof.d.ts +7 -0
- package/dist/types/types/index.d.ts +24 -28
- package/dist/types/verifyProof.d.ts +8 -0
- package/package.json +5 -4
- package/src/createMerkleProof.ts +32 -0
- package/src/createMerkleTree.ts +28 -0
- package/src/generateNullifierHash.ts +15 -0
- package/src/generateProof.ts +36 -0
- package/src/generateSignalHash.ts +11 -0
- package/src/index.test.ts +123 -0
- package/src/index.ts +17 -3
- package/src/packToSolidityProof.ts +19 -0
- package/src/types/index.ts +25 -29
- package/src/verifyProof.ts +21 -0
- package/dist/types/semaphore.d.ts +0 -48
- package/dist/types/utils.d.ts +0 -21
- package/src/semaphore.test.ts +0 -72
- package/src/semaphore.ts +0 -118
- package/src/utils.ts +0 -65
package/dist/index.node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/proof
|
|
3
|
-
* @version 0.
|
|
3
|
+
* @version 0.2.2
|
|
4
4
|
* @file A library for generating and verifying Semaphore proofs.
|
|
5
5
|
* @copyright Ethereum Foundation 2022
|
|
6
6
|
* @license MIT
|
|
@@ -10,13 +10,61 @@
|
|
|
10
10
|
|
|
11
11
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
12
12
|
|
|
13
|
-
var
|
|
14
|
-
var strings = require('@ethersproject/strings');
|
|
13
|
+
var incrementalMerkleTree = require('@zk-kit/incremental-merkle-tree');
|
|
15
14
|
var circomlibjs = require('circomlibjs');
|
|
16
15
|
var snarkjs = require('snarkjs');
|
|
17
|
-
var
|
|
16
|
+
var solidity = require('@ethersproject/solidity');
|
|
17
|
+
var strings = require('@ethersproject/strings');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a Merkle tree.
|
|
21
|
+
* @param depth The depth of the tree.
|
|
22
|
+
* @param zeroValue The zero value of the tree.
|
|
23
|
+
* @param leaves The list of the leaves of the tree.
|
|
24
|
+
* @returns The Merkle tree.
|
|
25
|
+
*/
|
|
26
|
+
function createMerkleTree(depth, zeroValue, leaves) {
|
|
27
|
+
var tree = new incrementalMerkleTree.IncrementalMerkleTree(circomlibjs.poseidon, depth, zeroValue, 2);
|
|
28
|
+
for (var _i = 0, leaves_1 = leaves; _i < leaves_1.length; _i++) {
|
|
29
|
+
var leaf = leaves_1[_i];
|
|
30
|
+
if (leaf === zeroValue) {
|
|
31
|
+
throw new Error("Leaves cannot have zero values");
|
|
32
|
+
}
|
|
33
|
+
tree.insert(BigInt(leaf));
|
|
34
|
+
}
|
|
35
|
+
return tree;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Creates a Merkle proof.
|
|
40
|
+
* @param depth The depth of the tree.
|
|
41
|
+
* @param zeroValue The zero value of the tree.
|
|
42
|
+
* @param leaves The list of the leaves of the tree.
|
|
43
|
+
* @param leaf The leaf for which Merkle proof should be created.
|
|
44
|
+
* @returns The Merkle proof.
|
|
45
|
+
*/
|
|
46
|
+
function createMerkleProof(depth, zeroValue, leaves, leaf) {
|
|
47
|
+
var tree = createMerkleTree(depth, zeroValue, leaves);
|
|
48
|
+
var leafIndex = tree.leaves.indexOf(BigInt(leaf));
|
|
49
|
+
if (leafIndex === -1) {
|
|
50
|
+
throw new Error("The leaf does not exist");
|
|
51
|
+
}
|
|
52
|
+
var merkleProof = tree.createProof(leafIndex);
|
|
53
|
+
merkleProof.siblings = merkleProof.siblings.map(function (s) { return s[0]; });
|
|
54
|
+
return merkleProof;
|
|
55
|
+
}
|
|
18
56
|
|
|
19
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Generates a nullifier by hashing the external and the identity nullifiers.
|
|
59
|
+
* @param externalNullifier The external nullifier.
|
|
60
|
+
* @param identityNullifier The identity nullifier.
|
|
61
|
+
* @returns The nullifier hash.
|
|
62
|
+
*/
|
|
63
|
+
function generateNullifierHash(externalNullifier, identityNullifier) {
|
|
64
|
+
return circomlibjs.poseidon([BigInt(externalNullifier), BigInt(identityNullifier)]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/******************************************************************************
|
|
20
68
|
Copyright (c) Microsoft Corporation.
|
|
21
69
|
|
|
22
70
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -69,157 +117,82 @@ function __generator(thisArg, body) {
|
|
|
69
117
|
}
|
|
70
118
|
}
|
|
71
119
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Hashes a signal string with Keccak256.
|
|
122
|
+
* @param signal The Semaphore signal.
|
|
123
|
+
* @returns The signal hash.
|
|
124
|
+
*/
|
|
125
|
+
function genSignalHash(signal) {
|
|
126
|
+
return BigInt(solidity.keccak256(["bytes32"], [strings.formatBytes32String(signal)])) >> BigInt(8);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function generateProof(identity, merkleProof, externalNullifier, signal, snarkArtifacts) {
|
|
130
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
131
|
+
var _a, proof, publicSignals;
|
|
132
|
+
return __generator(this, function (_b) {
|
|
133
|
+
switch (_b.label) {
|
|
134
|
+
case 0: return [4 /*yield*/, snarkjs.groth16.fullProve({
|
|
135
|
+
identityTrapdoor: identity.getTrapdoor(),
|
|
136
|
+
identityNullifier: identity.getNullifier(),
|
|
137
|
+
treePathIndices: merkleProof.pathIndices,
|
|
138
|
+
treeSiblings: merkleProof.siblings,
|
|
139
|
+
externalNullifier: externalNullifier,
|
|
140
|
+
signalHash: genSignalHash(signal)
|
|
141
|
+
}, snarkArtifacts.wasmFilePath, snarkArtifacts.zkeyFilePath)];
|
|
142
|
+
case 1:
|
|
143
|
+
_a = _b.sent(), proof = _a.proof, publicSignals = _a.publicSignals;
|
|
144
|
+
return [2 /*return*/, {
|
|
145
|
+
proof: proof,
|
|
146
|
+
publicSignals: {
|
|
147
|
+
merkleRoot: publicSignals[0],
|
|
148
|
+
nullifierHash: publicSignals[1],
|
|
149
|
+
signalHash: publicSignals[2],
|
|
150
|
+
externalNullifier: publicSignals[3]
|
|
151
|
+
}
|
|
152
|
+
}];
|
|
153
|
+
}
|
|
102
154
|
});
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
* Verifies a zero-knowledge SnarkJS proof.
|
|
106
|
-
* @param verificationKey The zero-knowledge verification key.
|
|
107
|
-
* @param fullProof The SnarkJS full proof.
|
|
108
|
-
* @returns True if the proof is valid, false otherwise.
|
|
109
|
-
*/
|
|
110
|
-
/* istanbul ignore next */
|
|
111
|
-
Semaphore.verifyProof = function (verificationKey, _a) {
|
|
112
|
-
var proof = _a.proof, publicSignals = _a.publicSignals;
|
|
113
|
-
return snarkjs.groth16.verify(verificationKey, [
|
|
114
|
-
publicSignals.merkleRoot,
|
|
115
|
-
publicSignals.nullifierHash,
|
|
116
|
-
publicSignals.signalHash,
|
|
117
|
-
publicSignals.externalNullifier
|
|
118
|
-
], proof);
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Creates a Semaphore witness for the Semaphore ZK proof.
|
|
122
|
-
* @param identityTrapdoor The identity trapdoor.
|
|
123
|
-
* @param identityNullifier The identity nullifier.
|
|
124
|
-
* @param merkleProof The Merkle proof that identity exists in Semaphore tree.
|
|
125
|
-
* @param externalNullifier The topic on which vote should be broadcasted.
|
|
126
|
-
* @param signal The signal that should be broadcasted.
|
|
127
|
-
* @returns The Semaphore witness.
|
|
128
|
-
*/
|
|
129
|
-
Semaphore.genWitness = function (identityTrapdoor, identityNullifier, merkleProof, externalNullifier, signal) {
|
|
130
|
-
return {
|
|
131
|
-
identityNullifier: identityNullifier,
|
|
132
|
-
identityTrapdoor: identityTrapdoor,
|
|
133
|
-
treePathIndices: merkleProof.pathIndices,
|
|
134
|
-
treeSiblings: merkleProof.siblings,
|
|
135
|
-
externalNullifier: externalNullifier,
|
|
136
|
-
signalHash: Semaphore.genSignalHash(signal)
|
|
137
|
-
};
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
* Generates a nullifier by hashing the external and the identity nullifiers.
|
|
141
|
-
* @param externalNullifier The external nullifier.
|
|
142
|
-
* @param identityNullifier The identity nullifier.
|
|
143
|
-
* @returns The nullifier hash.
|
|
144
|
-
*/
|
|
145
|
-
Semaphore.genNullifierHash = function (externalNullifier, identityNullifier) {
|
|
146
|
-
return circomlibjs.poseidon([BigInt(externalNullifier), BigInt(identityNullifier)]);
|
|
147
|
-
};
|
|
148
|
-
/**
|
|
149
|
-
* Hashes a signal string with Keccak256.
|
|
150
|
-
* @param signal The Semaphore signal.
|
|
151
|
-
* @returns The signal hash.
|
|
152
|
-
*/
|
|
153
|
-
Semaphore.genSignalHash = function (signal) {
|
|
154
|
-
return BigInt(solidity.keccak256(["bytes32"], [strings.formatBytes32String(signal)])) >> BigInt(8);
|
|
155
|
-
};
|
|
156
|
-
/**
|
|
157
|
-
* Converts a full proof in a proof compatible with the Verifier.sol method inputs.
|
|
158
|
-
* @param proof The proof generated with SnarkJS.
|
|
159
|
-
* @returns The Solidity compatible proof.
|
|
160
|
-
*/
|
|
161
|
-
/* istanbul ignore next */
|
|
162
|
-
Semaphore.packToSolidityProof = function (proof) {
|
|
163
|
-
return [
|
|
164
|
-
proof.pi_a[0],
|
|
165
|
-
proof.pi_a[1],
|
|
166
|
-
proof.pi_b[0][1],
|
|
167
|
-
proof.pi_b[0][0],
|
|
168
|
-
proof.pi_b[1][1],
|
|
169
|
-
proof.pi_b[1][0],
|
|
170
|
-
proof.pi_c[0],
|
|
171
|
-
proof.pi_c[1]
|
|
172
|
-
];
|
|
173
|
-
};
|
|
174
|
-
return Semaphore;
|
|
175
|
-
}());
|
|
155
|
+
});
|
|
156
|
+
}
|
|
176
157
|
|
|
177
|
-
BigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
178
|
-
function genExternalNullifier(plaintext) {
|
|
179
|
-
var hashed = solidity.keccak256(["string"], [plaintext]);
|
|
180
|
-
var hexStr = "0x".concat(hashed.slice(8));
|
|
181
|
-
var len = 32 * 2;
|
|
182
|
-
var h = hexStr.slice(2, len + 2);
|
|
183
|
-
return "0x".concat(h.padStart(len, "0"));
|
|
184
|
-
}
|
|
185
158
|
/**
|
|
186
|
-
*
|
|
187
|
-
* @param
|
|
188
|
-
* @param
|
|
189
|
-
* @
|
|
190
|
-
* @returns The Merkle tree.
|
|
159
|
+
* Verifies a SnarkJS proof.
|
|
160
|
+
* @param verificationKey The zero-knowledge verification key.
|
|
161
|
+
* @param fullProof The SnarkJS full proof.
|
|
162
|
+
* @returns True if the proof is valid, false otherwise.
|
|
191
163
|
*/
|
|
192
|
-
function
|
|
193
|
-
var
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
164
|
+
function verifyProof(verificationKey, _a) {
|
|
165
|
+
var proof = _a.proof, publicSignals = _a.publicSignals;
|
|
166
|
+
return snarkjs.groth16.verify(verificationKey, [
|
|
167
|
+
publicSignals.merkleRoot,
|
|
168
|
+
publicSignals.nullifierHash,
|
|
169
|
+
publicSignals.signalHash,
|
|
170
|
+
publicSignals.externalNullifier
|
|
171
|
+
], proof);
|
|
172
|
+
}
|
|
173
|
+
|
|
200
174
|
/**
|
|
201
|
-
*
|
|
202
|
-
* @param
|
|
203
|
-
* @
|
|
204
|
-
* @param leaves The list of the leaves of the tree.
|
|
205
|
-
* @param leaf The leaf for which Merkle proof should be created.
|
|
206
|
-
* @returns The Merkle proof.
|
|
175
|
+
* Makes a proof compatible with the Verifier.sol method inputs.
|
|
176
|
+
* @param proof The proof generated with SnarkJS.
|
|
177
|
+
* @returns The Solidity compatible proof.
|
|
207
178
|
*/
|
|
208
|
-
function
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return merkleProof;
|
|
179
|
+
function packToSolidityProof(proof) {
|
|
180
|
+
return [
|
|
181
|
+
proof.pi_a[0],
|
|
182
|
+
proof.pi_a[1],
|
|
183
|
+
proof.pi_b[0][1],
|
|
184
|
+
proof.pi_b[0][0],
|
|
185
|
+
proof.pi_b[1][1],
|
|
186
|
+
proof.pi_b[1][0],
|
|
187
|
+
proof.pi_c[0],
|
|
188
|
+
proof.pi_c[1]
|
|
189
|
+
];
|
|
220
190
|
}
|
|
221
191
|
|
|
222
|
-
exports.
|
|
223
|
-
exports.
|
|
224
|
-
exports.
|
|
225
|
-
exports.
|
|
192
|
+
exports.createMerkleProof = createMerkleProof;
|
|
193
|
+
exports.createMerkleTree = createMerkleTree;
|
|
194
|
+
exports.generateNullifierHash = generateNullifierHash;
|
|
195
|
+
exports.generateProof = generateProof;
|
|
196
|
+
exports.generateSignalHash = genSignalHash;
|
|
197
|
+
exports.packToSolidityProof = packToSolidityProof;
|
|
198
|
+
exports.verifyProof = verifyProof;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MerkleProof } from "@zk-kit/incremental-merkle-tree";
|
|
2
|
+
import { BigNumberish } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a Merkle proof.
|
|
5
|
+
* @param depth The depth of the tree.
|
|
6
|
+
* @param zeroValue The zero value of the tree.
|
|
7
|
+
* @param leaves The list of the leaves of the tree.
|
|
8
|
+
* @param leaf The leaf for which Merkle proof should be created.
|
|
9
|
+
* @returns The Merkle proof.
|
|
10
|
+
*/
|
|
11
|
+
export default function createMerkleProof(depth: number, zeroValue: BigNumberish, leaves: BigNumberish[], leaf: BigNumberish): MerkleProof;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree";
|
|
2
|
+
import { BigNumberish } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a Merkle tree.
|
|
5
|
+
* @param depth The depth of the tree.
|
|
6
|
+
* @param zeroValue The zero value of the tree.
|
|
7
|
+
* @param leaves The list of the leaves of the tree.
|
|
8
|
+
* @returns The Merkle tree.
|
|
9
|
+
*/
|
|
10
|
+
export default function createMerkleTree(depth: number, zeroValue: BigNumberish, leaves: BigNumberish[]): IncrementalMerkleTree;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BigNumberish } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Generates a nullifier by hashing the external and the identity nullifiers.
|
|
4
|
+
* @param externalNullifier The external nullifier.
|
|
5
|
+
* @param identityNullifier The identity nullifier.
|
|
6
|
+
* @returns The nullifier hash.
|
|
7
|
+
*/
|
|
8
|
+
export default function generateNullifierHash(externalNullifier: BigNumberish, identityNullifier: BigNumberish): bigint;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Identity } from "@semaphore-protocol/identity";
|
|
2
|
+
import { MerkleProof } from "@zk-kit/incremental-merkle-tree";
|
|
3
|
+
import { BigNumberish, FullProof, SnarkArtifacts } from "./types";
|
|
4
|
+
export default function generateProof(identity: Identity, merkleProof: MerkleProof, externalNullifier: BigNumberish, signal: string, snarkArtifacts: SnarkArtifacts): Promise<FullProof>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { MerkleProof } from "@zk-kit/incremental-merkle-tree";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
2
|
+
import createMerkleTree from "./createMerkleTree";
|
|
3
|
+
import createMerkleProof from "./createMerkleProof";
|
|
4
|
+
import generateNullifierHash from "./generateNullifierHash";
|
|
5
|
+
import generateProof from "./generateProof";
|
|
6
|
+
import verifyProof from "./verifyProof";
|
|
7
|
+
import generateSignalHash from "./generateSignalHash";
|
|
8
|
+
import packToSolidityProof from "./packToSolidityProof";
|
|
9
|
+
export { MerkleProof, createMerkleTree, createMerkleProof, generateNullifierHash, generateProof, verifyProof, generateSignalHash, packToSolidityProof };
|
|
5
10
|
export * from "./types";
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Proof, SolidityProof } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Makes a proof compatible with the Verifier.sol method inputs.
|
|
4
|
+
* @param proof The proof generated with SnarkJS.
|
|
5
|
+
* @returns The Solidity compatible proof.
|
|
6
|
+
*/
|
|
7
|
+
export default function packToSolidityProof(proof: Proof): SolidityProof;
|
|
@@ -1,36 +1,32 @@
|
|
|
1
|
-
export declare type
|
|
1
|
+
export declare type BigNumberish = string | bigint;
|
|
2
|
+
export declare type SnarkArtifacts = {
|
|
3
|
+
wasmFilePath: string;
|
|
4
|
+
zkeyFilePath: string;
|
|
5
|
+
};
|
|
2
6
|
export declare type Proof = {
|
|
3
|
-
pi_a:
|
|
4
|
-
pi_b:
|
|
5
|
-
pi_c:
|
|
7
|
+
pi_a: BigNumberish[];
|
|
8
|
+
pi_b: BigNumberish[][];
|
|
9
|
+
pi_c: BigNumberish[];
|
|
6
10
|
protocol: string;
|
|
7
11
|
curve: string;
|
|
8
12
|
};
|
|
9
|
-
export declare type
|
|
13
|
+
export declare type FullProof = {
|
|
10
14
|
proof: Proof;
|
|
11
|
-
publicSignals:
|
|
15
|
+
publicSignals: PublicSignals;
|
|
12
16
|
};
|
|
13
|
-
export declare type
|
|
14
|
-
merkleRoot:
|
|
15
|
-
nullifierHash:
|
|
16
|
-
signalHash:
|
|
17
|
-
externalNullifier:
|
|
17
|
+
export declare type PublicSignals = {
|
|
18
|
+
merkleRoot: BigNumberish;
|
|
19
|
+
nullifierHash: BigNumberish;
|
|
20
|
+
signalHash: BigNumberish;
|
|
21
|
+
externalNullifier: BigNumberish;
|
|
18
22
|
};
|
|
19
|
-
export declare type
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
export declare type SolidityProof = [
|
|
24
|
+
BigNumberish,
|
|
25
|
+
BigNumberish,
|
|
26
|
+
BigNumberish,
|
|
27
|
+
BigNumberish,
|
|
28
|
+
BigNumberish,
|
|
29
|
+
BigNumberish,
|
|
30
|
+
BigNumberish,
|
|
31
|
+
BigNumberish
|
|
28
32
|
];
|
|
29
|
-
export declare type SemaphoreWitness = {
|
|
30
|
-
identityNullifier: StrBigInt;
|
|
31
|
-
identityTrapdoor: StrBigInt;
|
|
32
|
-
treeSiblings: StrBigInt[];
|
|
33
|
-
treePathIndices: number[];
|
|
34
|
-
externalNullifier: StrBigInt;
|
|
35
|
-
signalHash: StrBigInt;
|
|
36
|
-
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FullProof } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Verifies a SnarkJS proof.
|
|
4
|
+
* @param verificationKey The zero-knowledge verification key.
|
|
5
|
+
* @param fullProof The SnarkJS full proof.
|
|
6
|
+
* @returns True if the proof is valid, false otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export default function verifyProof(verificationKey: any, { proof, publicSignals }: FullProof): Promise<boolean>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semaphore-protocol/proof",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "A library for generating and verifying Semaphore proofs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.node.js",
|
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
"build:watch": "rollup -c rollup.config.ts -w --configPlugin typescript",
|
|
22
22
|
"build": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript",
|
|
23
23
|
"prepublishOnly": "yarn build",
|
|
24
|
-
"docs": "typedoc src/index.ts --out ../../docs/
|
|
24
|
+
"docs": "typedoc src/index.ts --out ../../docs/proof"
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
+
"download": "^8.0.0",
|
|
30
31
|
"ffjavascript": "^0.2.54",
|
|
31
32
|
"rollup-plugin-cleanup": "^3.2.1",
|
|
32
33
|
"rollup-plugin-typescript2": "^0.31.2",
|
|
@@ -36,9 +37,9 @@
|
|
|
36
37
|
"@ethersproject/bytes": "^5.5.0",
|
|
37
38
|
"@ethersproject/solidity": "^5.5.0",
|
|
38
39
|
"@ethersproject/strings": "^5.5.0",
|
|
40
|
+
"@semaphore-protocol/identity": "0.2.2",
|
|
39
41
|
"@zk-kit/incremental-merkle-tree": "^0.4.3",
|
|
40
42
|
"circomlibjs": "0.0.8",
|
|
41
43
|
"snarkjs": "^0.4.13"
|
|
42
|
-
}
|
|
43
|
-
"gitHead": "6c1b469a4b5ffaac562f478fc2bbc78731734e81"
|
|
44
|
+
}
|
|
44
45
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
|
|
2
|
+
import createMerkleTree from "./createMerkleTree"
|
|
3
|
+
import { BigNumberish } from "./types"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a Merkle proof.
|
|
7
|
+
* @param depth The depth of the tree.
|
|
8
|
+
* @param zeroValue The zero value of the tree.
|
|
9
|
+
* @param leaves The list of the leaves of the tree.
|
|
10
|
+
* @param leaf The leaf for which Merkle proof should be created.
|
|
11
|
+
* @returns The Merkle proof.
|
|
12
|
+
*/
|
|
13
|
+
export default function createMerkleProof(
|
|
14
|
+
depth: number,
|
|
15
|
+
zeroValue: BigNumberish,
|
|
16
|
+
leaves: BigNumberish[],
|
|
17
|
+
leaf: BigNumberish
|
|
18
|
+
): MerkleProof {
|
|
19
|
+
const tree = createMerkleTree(depth, zeroValue, leaves)
|
|
20
|
+
|
|
21
|
+
const leafIndex = tree.leaves.indexOf(BigInt(leaf))
|
|
22
|
+
|
|
23
|
+
if (leafIndex === -1) {
|
|
24
|
+
throw new Error("The leaf does not exist")
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const merkleProof = tree.createProof(leafIndex)
|
|
28
|
+
|
|
29
|
+
merkleProof.siblings = merkleProof.siblings.map((s) => s[0])
|
|
30
|
+
|
|
31
|
+
return merkleProof
|
|
32
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree"
|
|
2
|
+
import { poseidon } from "circomlibjs"
|
|
3
|
+
import { BigNumberish } from "./types"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a Merkle tree.
|
|
7
|
+
* @param depth The depth of the tree.
|
|
8
|
+
* @param zeroValue The zero value of the tree.
|
|
9
|
+
* @param leaves The list of the leaves of the tree.
|
|
10
|
+
* @returns The Merkle tree.
|
|
11
|
+
*/
|
|
12
|
+
export default function createMerkleTree(
|
|
13
|
+
depth: number,
|
|
14
|
+
zeroValue: BigNumberish,
|
|
15
|
+
leaves: BigNumberish[]
|
|
16
|
+
): IncrementalMerkleTree {
|
|
17
|
+
const tree = new IncrementalMerkleTree(poseidon, depth, zeroValue, 2)
|
|
18
|
+
|
|
19
|
+
for (const leaf of leaves) {
|
|
20
|
+
if (leaf === zeroValue) {
|
|
21
|
+
throw new Error("Leaves cannot have zero values")
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
tree.insert(BigInt(leaf))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return tree
|
|
28
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { poseidon } from "circomlibjs"
|
|
2
|
+
import { BigNumberish } from "./types"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates a nullifier by hashing the external and the identity nullifiers.
|
|
6
|
+
* @param externalNullifier The external nullifier.
|
|
7
|
+
* @param identityNullifier The identity nullifier.
|
|
8
|
+
* @returns The nullifier hash.
|
|
9
|
+
*/
|
|
10
|
+
export default function generateNullifierHash(
|
|
11
|
+
externalNullifier: BigNumberish,
|
|
12
|
+
identityNullifier: BigNumberish
|
|
13
|
+
): bigint {
|
|
14
|
+
return poseidon([BigInt(externalNullifier), BigInt(identityNullifier)])
|
|
15
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Identity } from "@semaphore-protocol/identity"
|
|
2
|
+
import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
|
|
3
|
+
import { groth16 } from "snarkjs"
|
|
4
|
+
import generateSignalHash from "./generateSignalHash"
|
|
5
|
+
import { BigNumberish, FullProof, SnarkArtifacts } from "./types"
|
|
6
|
+
|
|
7
|
+
export default async function generateProof(
|
|
8
|
+
identity: Identity,
|
|
9
|
+
merkleProof: MerkleProof,
|
|
10
|
+
externalNullifier: BigNumberish,
|
|
11
|
+
signal: string,
|
|
12
|
+
snarkArtifacts: SnarkArtifacts
|
|
13
|
+
): Promise<FullProof> {
|
|
14
|
+
const { proof, publicSignals } = await groth16.fullProve(
|
|
15
|
+
{
|
|
16
|
+
identityTrapdoor: identity.getTrapdoor(),
|
|
17
|
+
identityNullifier: identity.getNullifier(),
|
|
18
|
+
treePathIndices: merkleProof.pathIndices,
|
|
19
|
+
treeSiblings: merkleProof.siblings,
|
|
20
|
+
externalNullifier,
|
|
21
|
+
signalHash: generateSignalHash(signal)
|
|
22
|
+
},
|
|
23
|
+
snarkArtifacts.wasmFilePath,
|
|
24
|
+
snarkArtifacts.zkeyFilePath
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
proof,
|
|
29
|
+
publicSignals: {
|
|
30
|
+
merkleRoot: publicSignals[0],
|
|
31
|
+
nullifierHash: publicSignals[1],
|
|
32
|
+
signalHash: publicSignals[2],
|
|
33
|
+
externalNullifier: publicSignals[3]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { keccak256 } from "@ethersproject/solidity"
|
|
2
|
+
import { formatBytes32String } from "@ethersproject/strings"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hashes a signal string with Keccak256.
|
|
6
|
+
* @param signal The Semaphore signal.
|
|
7
|
+
* @returns The signal hash.
|
|
8
|
+
*/
|
|
9
|
+
export default function genSignalHash(signal: string): bigint {
|
|
10
|
+
return BigInt(keccak256(["bytes32"], [formatBytes32String(signal)])) >> BigInt(8)
|
|
11
|
+
}
|