@semaphore-protocol/proof 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 +6 -4
- package/dist/index.browser.js +8 -23
- package/dist/index.node.cjs +7 -51
- package/dist/index.node.js +8 -52
- package/dist/types/generate-proof.d.ts +3 -2
- package/dist/types/types/index.d.ts +0 -4
- package/package.json +6 -6
- package/src/generate-proof.ts +9 -10
- package/src/types/index.ts +0 -5
- package/dist/types/get-snark-artifacts.browser.d.ts +0 -8
- package/dist/types/get-snark-artifacts.node.d.ts +0 -9
- package/src/get-snark-artifacts.browser.ts +0 -18
- package/src/get-snark-artifacts.node.ts +0 -59
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ group: _Group_,
|
|
|
78
78
|
message: _BigNumberish_ | _Uint8Array_ | string,
|
|
79
79
|
scope: _BigNumberish_ | _Uint8Array_ | string,
|
|
80
80
|
merkleTreeDepth: _number_,
|
|
81
|
-
snarkArtifacts?: _SnarkArtifacts_
|
|
81
|
+
snarkArtifacts?: [_SnarkArtifacts_](https://github.com/privacy-scaling-explorations/zk-kit/blob/88acdc6d8fa5f3f2a8ecd1e1a0140244b970c551/packages/utils/src/types/index.ts#L46)
|
|
82
82
|
): Promise\<_SemaphoreProof_>
|
|
83
83
|
|
|
84
84
|
```typescript
|
|
@@ -95,15 +95,17 @@ const group = new Group([identity1.commitment, identity2.commitment, identity3.c
|
|
|
95
95
|
const message = "Hello world"
|
|
96
96
|
const scope = "Semaphore"
|
|
97
97
|
|
|
98
|
+
// snarkArtifacts are not provided.
|
|
99
|
+
// So they will be automatically downloaded (see https://github.com/privacy-scaling-explorations/snark-artifacts).
|
|
98
100
|
const proof1 = await generateProof(identity1, group, message, scope)
|
|
99
101
|
|
|
100
102
|
// You can also specify the maximum tree depth supported by the proof.
|
|
101
103
|
const proof2 = await generateProof(identity2, group, message, scope, 20)
|
|
102
104
|
|
|
103
|
-
// You can also
|
|
105
|
+
// You can also override our default zkey/wasm files.
|
|
104
106
|
const proof3 = await generateProof(identity3, group, message, scope, 20, {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
wasm: "./semaphore.wasm",
|
|
108
|
+
zkey: "./semaphore.zkey"
|
|
107
109
|
})
|
|
108
110
|
```
|
|
109
111
|
|
package/dist/index.browser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/proof
|
|
3
|
-
* @version 4.0.0-beta.
|
|
3
|
+
* @version 4.0.0-beta.8
|
|
4
4
|
* @file A library to generate and verify Semaphore proofs.
|
|
5
5
|
* @copyright Ethereum Foundation 2024
|
|
6
6
|
* @license MIT
|
|
@@ -9,27 +9,13 @@
|
|
|
9
9
|
import { packGroth16Proof, unpackGroth16Proof } from '@zk-kit/utils/proof-packing';
|
|
10
10
|
export { packGroth16Proof, unpackGroth16Proof } from '@zk-kit/utils/proof-packing';
|
|
11
11
|
import { MIN_DEPTH, MAX_DEPTH } from '@semaphore-protocol/utils/constants';
|
|
12
|
-
import {
|
|
12
|
+
import { requireDefined, requireObject, requireTypes, requireNumber, requireString, requireArray } from '@zk-kit/utils/error-handlers';
|
|
13
|
+
import { maybeGetSemaphoreSnarkArtifacts } from '@zk-kit/utils';
|
|
13
14
|
import { groth16 } from 'snarkjs';
|
|
14
15
|
import { keccak256 } from 'ethers/crypto';
|
|
15
16
|
import { toBeHex, toBigInt as toBigInt$1 } from 'ethers/utils';
|
|
16
17
|
import { encodeBytes32String } from 'ethers/abi';
|
|
17
18
|
|
|
18
|
-
/* istanbul ignore file */
|
|
19
|
-
/**
|
|
20
|
-
* Returns the zero-knowledge artifact paths. Artifacts exist for each tree
|
|
21
|
-
* depth supported by Semaphore, and they were generated in a trusted-setup.
|
|
22
|
-
* @param treeDepth The depth of the tree.
|
|
23
|
-
* @returns The zero-knowledge artifacts paths.
|
|
24
|
-
*/
|
|
25
|
-
async function getSnarkArtifacts(treeDepth) {
|
|
26
|
-
requireNumber(treeDepth, "treeDepth");
|
|
27
|
-
return {
|
|
28
|
-
wasmFilePath: `https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.wasm`,
|
|
29
|
-
zkeyFilePath: `https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.zkey`
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
19
|
/**
|
|
34
20
|
* Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
|
|
35
21
|
* @param message The message to be hashed.
|
|
@@ -73,7 +59,7 @@ function toBigInt(value) {
|
|
|
73
59
|
* @param message The Semaphore message.
|
|
74
60
|
* @param scope The Semaphore scope.
|
|
75
61
|
* @param merkleTreeDepth The depth of the tree with which the circuit was compiled.
|
|
76
|
-
* @param snarkArtifacts
|
|
62
|
+
* @param snarkArtifacts See {@link https://zkkit.pse.dev/interfaces/_zk_kit_utils.SnarkArtifacts.html | SnarkArtifacts}.
|
|
77
63
|
* @returns The Semaphore proof ready to be verified.
|
|
78
64
|
*/
|
|
79
65
|
async function generateProof(identity, groupOrMerkleProof, message, scope, merkleTreeDepth, snarkArtifacts) {
|
|
@@ -115,9 +101,8 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
115
101
|
merkleTreeDepth = merkleProofLength;
|
|
116
102
|
}
|
|
117
103
|
// If the Snark artifacts are not defined they will be automatically downloaded.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
104
|
+
snarkArtifacts ?? (snarkArtifacts = await maybeGetSemaphoreSnarkArtifacts(merkleTreeDepth));
|
|
105
|
+
const { wasm, zkey } = snarkArtifacts;
|
|
121
106
|
// The index must be converted to a list of indices, 1 for each tree level.
|
|
122
107
|
// The missing siblings can be set to 0, as they won't be used in the circuit.
|
|
123
108
|
const merkleProofIndices = [];
|
|
@@ -125,7 +110,7 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
125
110
|
for (let i = 0; i < merkleTreeDepth; i += 1) {
|
|
126
111
|
merkleProofIndices.push((merkleProof.index >> i) & 1);
|
|
127
112
|
if (merkleProofSiblings[i] === undefined) {
|
|
128
|
-
merkleProofSiblings[i] =
|
|
113
|
+
merkleProofSiblings[i] = 0n;
|
|
129
114
|
}
|
|
130
115
|
}
|
|
131
116
|
const { proof, publicSignals } = await groth16.fullProve({
|
|
@@ -135,7 +120,7 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
135
120
|
merkleProofSiblings,
|
|
136
121
|
scope: hash(scope),
|
|
137
122
|
message: hash(message)
|
|
138
|
-
},
|
|
123
|
+
}, wasm, zkey);
|
|
139
124
|
return {
|
|
140
125
|
merkleTreeDepth,
|
|
141
126
|
merkleTreeRoot: publicSignals[0],
|
package/dist/index.node.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/proof
|
|
3
|
-
* @version 4.0.0-beta.
|
|
3
|
+
* @version 4.0.0-beta.8
|
|
4
4
|
* @file A library to generate and verify Semaphore proofs.
|
|
5
5
|
* @copyright Ethereum Foundation 2024
|
|
6
6
|
* @license MIT
|
|
@@ -11,55 +11,12 @@
|
|
|
11
11
|
var proofPacking = require('@zk-kit/utils/proof-packing');
|
|
12
12
|
var constants = require('@semaphore-protocol/utils/constants');
|
|
13
13
|
var errorHandlers = require('@zk-kit/utils/error-handlers');
|
|
14
|
+
var utils$1 = require('@zk-kit/utils');
|
|
14
15
|
var snarkjs = require('snarkjs');
|
|
15
|
-
var node_fs = require('node:fs');
|
|
16
|
-
var promises = require('node:fs/promises');
|
|
17
|
-
var os = require('node:os');
|
|
18
|
-
var node_path = require('node:path');
|
|
19
|
-
var node_stream = require('node:stream');
|
|
20
|
-
var promises$1 = require('node:stream/promises');
|
|
21
16
|
var crypto = require('ethers/crypto');
|
|
22
17
|
var utils = require('ethers/utils');
|
|
23
18
|
var abi = require('ethers/abi');
|
|
24
19
|
|
|
25
|
-
/* istanbul ignore file */
|
|
26
|
-
/**
|
|
27
|
-
* A utility function to download the zero-knowledge artifacts from an external server.
|
|
28
|
-
* @param url The URL from which to download the artifacts.
|
|
29
|
-
* @param outputPath The path in which to save the artifacts.
|
|
30
|
-
*/
|
|
31
|
-
async function download(url, outputPath) {
|
|
32
|
-
const response = await fetch(url);
|
|
33
|
-
if (!response.ok) {
|
|
34
|
-
throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
|
|
35
|
-
}
|
|
36
|
-
// Ensure the directory exists.
|
|
37
|
-
const dir = node_path.dirname(outputPath);
|
|
38
|
-
await promises.mkdir(dir, { recursive: true });
|
|
39
|
-
const fileStream = node_fs.createWriteStream(outputPath);
|
|
40
|
-
await promises$1.finished(node_stream.Readable.fromWeb(response.body).pipe(fileStream));
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Downloads the zero-knowledge artifacts and returns their paths.
|
|
44
|
-
* Artifacts exist for each tree depth supported by Semaphore, and
|
|
45
|
-
* they were generated in a trusted-setup.
|
|
46
|
-
* @param treeDepth The depth of the tree.
|
|
47
|
-
* @returns The zero-knowledge artifacts paths.
|
|
48
|
-
*/
|
|
49
|
-
async function getSnarkArtifacts(treeDepth) {
|
|
50
|
-
errorHandlers.requireNumber(treeDepth, "treeDepth");
|
|
51
|
-
const tmpDir = "semaphore-proof";
|
|
52
|
-
const tmpPath = `${os.tmpdir()}/${tmpDir}-${treeDepth}`;
|
|
53
|
-
if (!node_fs.existsSync(tmpPath) || node_fs.readdirSync(tmpPath).length !== 2) {
|
|
54
|
-
await download(`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.wasm`, `${tmpPath}/semaphore.wasm`);
|
|
55
|
-
await download(`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.zkey`, `${tmpPath}/semaphore.zkey`);
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
wasmFilePath: `${tmpPath}/semaphore.wasm`,
|
|
59
|
-
zkeyFilePath: `${tmpPath}/semaphore.zkey`
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
20
|
/**
|
|
64
21
|
* Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
|
|
65
22
|
* @param message The message to be hashed.
|
|
@@ -103,7 +60,7 @@ function toBigInt(value) {
|
|
|
103
60
|
* @param message The Semaphore message.
|
|
104
61
|
* @param scope The Semaphore scope.
|
|
105
62
|
* @param merkleTreeDepth The depth of the tree with which the circuit was compiled.
|
|
106
|
-
* @param snarkArtifacts
|
|
63
|
+
* @param snarkArtifacts See {@link https://zkkit.pse.dev/interfaces/_zk_kit_utils.SnarkArtifacts.html | SnarkArtifacts}.
|
|
107
64
|
* @returns The Semaphore proof ready to be verified.
|
|
108
65
|
*/
|
|
109
66
|
async function generateProof(identity, groupOrMerkleProof, message, scope, merkleTreeDepth, snarkArtifacts) {
|
|
@@ -145,9 +102,8 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
145
102
|
merkleTreeDepth = merkleProofLength;
|
|
146
103
|
}
|
|
147
104
|
// If the Snark artifacts are not defined they will be automatically downloaded.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
105
|
+
snarkArtifacts ?? (snarkArtifacts = await utils$1.maybeGetSemaphoreSnarkArtifacts(merkleTreeDepth));
|
|
106
|
+
const { wasm, zkey } = snarkArtifacts;
|
|
151
107
|
// The index must be converted to a list of indices, 1 for each tree level.
|
|
152
108
|
// The missing siblings can be set to 0, as they won't be used in the circuit.
|
|
153
109
|
const merkleProofIndices = [];
|
|
@@ -155,7 +111,7 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
155
111
|
for (let i = 0; i < merkleTreeDepth; i += 1) {
|
|
156
112
|
merkleProofIndices.push((merkleProof.index >> i) & 1);
|
|
157
113
|
if (merkleProofSiblings[i] === undefined) {
|
|
158
|
-
merkleProofSiblings[i] =
|
|
114
|
+
merkleProofSiblings[i] = 0n;
|
|
159
115
|
}
|
|
160
116
|
}
|
|
161
117
|
const { proof, publicSignals } = await snarkjs.groth16.fullProve({
|
|
@@ -165,7 +121,7 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
165
121
|
merkleProofSiblings,
|
|
166
122
|
scope: hash(scope),
|
|
167
123
|
message: hash(message)
|
|
168
|
-
},
|
|
124
|
+
}, wasm, zkey);
|
|
169
125
|
return {
|
|
170
126
|
merkleTreeDepth,
|
|
171
127
|
merkleTreeRoot: publicSignals[0],
|
package/dist/index.node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/proof
|
|
3
|
-
* @version 4.0.0-beta.
|
|
3
|
+
* @version 4.0.0-beta.8
|
|
4
4
|
* @file A library to generate and verify Semaphore proofs.
|
|
5
5
|
* @copyright Ethereum Foundation 2024
|
|
6
6
|
* @license MIT
|
|
@@ -9,56 +9,13 @@
|
|
|
9
9
|
import { packGroth16Proof, unpackGroth16Proof } from '@zk-kit/utils/proof-packing';
|
|
10
10
|
export { packGroth16Proof, unpackGroth16Proof } from '@zk-kit/utils/proof-packing';
|
|
11
11
|
import { MIN_DEPTH, MAX_DEPTH } from '@semaphore-protocol/utils/constants';
|
|
12
|
-
import {
|
|
12
|
+
import { requireDefined, requireObject, requireTypes, requireNumber, requireString, requireArray } from '@zk-kit/utils/error-handlers';
|
|
13
|
+
import { maybeGetSemaphoreSnarkArtifacts } from '@zk-kit/utils';
|
|
13
14
|
import { groth16 } from 'snarkjs';
|
|
14
|
-
import { existsSync, readdirSync, createWriteStream } from 'node:fs';
|
|
15
|
-
import { mkdir } from 'node:fs/promises';
|
|
16
|
-
import os from 'node:os';
|
|
17
|
-
import { dirname } from 'node:path';
|
|
18
|
-
import { Readable } from 'node:stream';
|
|
19
|
-
import { finished } from 'node:stream/promises';
|
|
20
15
|
import { keccak256 } from 'ethers/crypto';
|
|
21
16
|
import { toBeHex, toBigInt as toBigInt$1 } from 'ethers/utils';
|
|
22
17
|
import { encodeBytes32String } from 'ethers/abi';
|
|
23
18
|
|
|
24
|
-
/* istanbul ignore file */
|
|
25
|
-
/**
|
|
26
|
-
* A utility function to download the zero-knowledge artifacts from an external server.
|
|
27
|
-
* @param url The URL from which to download the artifacts.
|
|
28
|
-
* @param outputPath The path in which to save the artifacts.
|
|
29
|
-
*/
|
|
30
|
-
async function download(url, outputPath) {
|
|
31
|
-
const response = await fetch(url);
|
|
32
|
-
if (!response.ok) {
|
|
33
|
-
throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
|
|
34
|
-
}
|
|
35
|
-
// Ensure the directory exists.
|
|
36
|
-
const dir = dirname(outputPath);
|
|
37
|
-
await mkdir(dir, { recursive: true });
|
|
38
|
-
const fileStream = createWriteStream(outputPath);
|
|
39
|
-
await finished(Readable.fromWeb(response.body).pipe(fileStream));
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Downloads the zero-knowledge artifacts and returns their paths.
|
|
43
|
-
* Artifacts exist for each tree depth supported by Semaphore, and
|
|
44
|
-
* they were generated in a trusted-setup.
|
|
45
|
-
* @param treeDepth The depth of the tree.
|
|
46
|
-
* @returns The zero-knowledge artifacts paths.
|
|
47
|
-
*/
|
|
48
|
-
async function getSnarkArtifacts(treeDepth) {
|
|
49
|
-
requireNumber(treeDepth, "treeDepth");
|
|
50
|
-
const tmpDir = "semaphore-proof";
|
|
51
|
-
const tmpPath = `${os.tmpdir()}/${tmpDir}-${treeDepth}`;
|
|
52
|
-
if (!existsSync(tmpPath) || readdirSync(tmpPath).length !== 2) {
|
|
53
|
-
await download(`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.wasm`, `${tmpPath}/semaphore.wasm`);
|
|
54
|
-
await download(`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.zkey`, `${tmpPath}/semaphore.zkey`);
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
wasmFilePath: `${tmpPath}/semaphore.wasm`,
|
|
58
|
-
zkeyFilePath: `${tmpPath}/semaphore.zkey`
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
19
|
/**
|
|
63
20
|
* Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
|
|
64
21
|
* @param message The message to be hashed.
|
|
@@ -102,7 +59,7 @@ function toBigInt(value) {
|
|
|
102
59
|
* @param message The Semaphore message.
|
|
103
60
|
* @param scope The Semaphore scope.
|
|
104
61
|
* @param merkleTreeDepth The depth of the tree with which the circuit was compiled.
|
|
105
|
-
* @param snarkArtifacts
|
|
62
|
+
* @param snarkArtifacts See {@link https://zkkit.pse.dev/interfaces/_zk_kit_utils.SnarkArtifacts.html | SnarkArtifacts}.
|
|
106
63
|
* @returns The Semaphore proof ready to be verified.
|
|
107
64
|
*/
|
|
108
65
|
async function generateProof(identity, groupOrMerkleProof, message, scope, merkleTreeDepth, snarkArtifacts) {
|
|
@@ -144,9 +101,8 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
144
101
|
merkleTreeDepth = merkleProofLength;
|
|
145
102
|
}
|
|
146
103
|
// If the Snark artifacts are not defined they will be automatically downloaded.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
104
|
+
snarkArtifacts ?? (snarkArtifacts = await maybeGetSemaphoreSnarkArtifacts(merkleTreeDepth));
|
|
105
|
+
const { wasm, zkey } = snarkArtifacts;
|
|
150
106
|
// The index must be converted to a list of indices, 1 for each tree level.
|
|
151
107
|
// The missing siblings can be set to 0, as they won't be used in the circuit.
|
|
152
108
|
const merkleProofIndices = [];
|
|
@@ -154,7 +110,7 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
154
110
|
for (let i = 0; i < merkleTreeDepth; i += 1) {
|
|
155
111
|
merkleProofIndices.push((merkleProof.index >> i) & 1);
|
|
156
112
|
if (merkleProofSiblings[i] === undefined) {
|
|
157
|
-
merkleProofSiblings[i] =
|
|
113
|
+
merkleProofSiblings[i] = 0n;
|
|
158
114
|
}
|
|
159
115
|
}
|
|
160
116
|
const { proof, publicSignals } = await groth16.fullProve({
|
|
@@ -164,7 +120,7 @@ async function generateProof(identity, groupOrMerkleProof, message, scope, merkl
|
|
|
164
120
|
merkleProofSiblings,
|
|
165
121
|
scope: hash(scope),
|
|
166
122
|
message: hash(message)
|
|
167
|
-
},
|
|
123
|
+
}, wasm, zkey);
|
|
168
124
|
return {
|
|
169
125
|
merkleTreeDepth,
|
|
170
126
|
merkleTreeRoot: publicSignals[0],
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Group, MerkleProof } from "@semaphore-protocol/group";
|
|
2
2
|
import type { Identity } from "@semaphore-protocol/identity";
|
|
3
|
+
import { type SnarkArtifacts } from "@zk-kit/utils";
|
|
3
4
|
import type { BigNumberish } from "ethers";
|
|
4
|
-
import { SemaphoreProof
|
|
5
|
+
import type { SemaphoreProof } from "./types";
|
|
5
6
|
/**
|
|
6
7
|
* It generates a Semaphore proof, i.e. a zero-knowledge proof that an identity that
|
|
7
8
|
* is part of a group has shared an anonymous message.
|
|
@@ -19,7 +20,7 @@ import { SemaphoreProof, SnarkArtifacts } from "./types";
|
|
|
19
20
|
* @param message The Semaphore message.
|
|
20
21
|
* @param scope The Semaphore scope.
|
|
21
22
|
* @param merkleTreeDepth The depth of the tree with which the circuit was compiled.
|
|
22
|
-
* @param snarkArtifacts
|
|
23
|
+
* @param snarkArtifacts See {@link https://zkkit.pse.dev/interfaces/_zk_kit_utils.SnarkArtifacts.html | SnarkArtifacts}.
|
|
23
24
|
* @returns The Semaphore proof ready to be verified.
|
|
24
25
|
*/
|
|
25
26
|
export default function generateProof(identity: Identity, groupOrMerkleProof: Group | MerkleProof, message: BigNumberish | Uint8Array | string, scope: BigNumberish | Uint8Array | string, merkleTreeDepth?: number, snarkArtifacts?: SnarkArtifacts): Promise<SemaphoreProof>;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import type { NumericString } from "snarkjs";
|
|
2
2
|
import type { PackedGroth16Proof } from "@zk-kit/utils";
|
|
3
|
-
export type SnarkArtifacts = {
|
|
4
|
-
wasmFilePath: string;
|
|
5
|
-
zkeyFilePath: string;
|
|
6
|
-
};
|
|
7
3
|
export type SemaphoreProof = {
|
|
8
4
|
merkleTreeDepth: number;
|
|
9
5
|
merkleTreeRoot: NumericString;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semaphore-protocol/proof",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.8",
|
|
4
4
|
"description": "A library to generate and verify Semaphore proofs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,13 +48,13 @@
|
|
|
48
48
|
"rollup-plugin-cleanup": "^3.2.1"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@semaphore-protocol/group": "4.0.0-beta.
|
|
52
|
-
"@semaphore-protocol/identity": "4.0.0-beta.
|
|
51
|
+
"@semaphore-protocol/group": "4.0.0-beta.8",
|
|
52
|
+
"@semaphore-protocol/identity": "4.0.0-beta.8"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@semaphore-protocol/utils": "4.0.0-beta.
|
|
56
|
-
"@zk-kit/utils": "0.
|
|
55
|
+
"@semaphore-protocol/utils": "4.0.0-beta.8",
|
|
56
|
+
"@zk-kit/utils": "1.0.0-beta.4",
|
|
57
57
|
"ethers": "6.10.0",
|
|
58
|
-
"snarkjs": "0.7.
|
|
58
|
+
"snarkjs": "0.7.4"
|
|
59
59
|
}
|
|
60
60
|
}
|
package/src/generate-proof.ts
CHANGED
|
@@ -3,12 +3,12 @@ import type { Identity } from "@semaphore-protocol/identity"
|
|
|
3
3
|
import { MAX_DEPTH, MIN_DEPTH } from "@semaphore-protocol/utils/constants"
|
|
4
4
|
import { requireDefined, requireNumber, requireObject, requireTypes } from "@zk-kit/utils/error-handlers"
|
|
5
5
|
import { packGroth16Proof } from "@zk-kit/utils/proof-packing"
|
|
6
|
+
import { maybeGetSemaphoreSnarkArtifacts, type SnarkArtifacts } from "@zk-kit/utils"
|
|
6
7
|
import type { BigNumberish } from "ethers"
|
|
7
|
-
import { NumericString, groth16 } from "snarkjs"
|
|
8
|
-
import getSnarkArtifacts from "./get-snark-artifacts.node"
|
|
8
|
+
import { type NumericString, groth16 } from "snarkjs"
|
|
9
9
|
import hash from "./hash"
|
|
10
10
|
import toBigInt from "./to-bigint"
|
|
11
|
-
import { SemaphoreProof
|
|
11
|
+
import type { SemaphoreProof } from "./types"
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* It generates a Semaphore proof, i.e. a zero-knowledge proof that an identity that
|
|
@@ -27,7 +27,7 @@ import { SemaphoreProof, SnarkArtifacts } from "./types"
|
|
|
27
27
|
* @param message The Semaphore message.
|
|
28
28
|
* @param scope The Semaphore scope.
|
|
29
29
|
* @param merkleTreeDepth The depth of the tree with which the circuit was compiled.
|
|
30
|
-
* @param snarkArtifacts
|
|
30
|
+
* @param snarkArtifacts See {@link https://zkkit.pse.dev/interfaces/_zk_kit_utils.SnarkArtifacts.html | SnarkArtifacts}.
|
|
31
31
|
* @returns The Semaphore proof ready to be verified.
|
|
32
32
|
*/
|
|
33
33
|
export default async function generateProof(
|
|
@@ -83,9 +83,8 @@ export default async function generateProof(
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// If the Snark artifacts are not defined they will be automatically downloaded.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
86
|
+
snarkArtifacts ??= await maybeGetSemaphoreSnarkArtifacts(merkleTreeDepth)
|
|
87
|
+
const { wasm, zkey } = snarkArtifacts
|
|
89
88
|
|
|
90
89
|
// The index must be converted to a list of indices, 1 for each tree level.
|
|
91
90
|
// The missing siblings can be set to 0, as they won't be used in the circuit.
|
|
@@ -96,7 +95,7 @@ export default async function generateProof(
|
|
|
96
95
|
merkleProofIndices.push((merkleProof.index >> i) & 1)
|
|
97
96
|
|
|
98
97
|
if (merkleProofSiblings[i] === undefined) {
|
|
99
|
-
merkleProofSiblings[i] =
|
|
98
|
+
merkleProofSiblings[i] = 0n
|
|
100
99
|
}
|
|
101
100
|
}
|
|
102
101
|
|
|
@@ -109,8 +108,8 @@ export default async function generateProof(
|
|
|
109
108
|
scope: hash(scope),
|
|
110
109
|
message: hash(message)
|
|
111
110
|
},
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
wasm,
|
|
112
|
+
zkey
|
|
114
113
|
)
|
|
115
114
|
|
|
116
115
|
return {
|
package/src/types/index.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { NumericString } from "snarkjs"
|
|
2
2
|
import type { PackedGroth16Proof } from "@zk-kit/utils"
|
|
3
3
|
|
|
4
|
-
export type SnarkArtifacts = {
|
|
5
|
-
wasmFilePath: string
|
|
6
|
-
zkeyFilePath: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
4
|
export type SemaphoreProof = {
|
|
10
5
|
merkleTreeDepth: number
|
|
11
6
|
merkleTreeRoot: NumericString
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { SnarkArtifacts } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Returns the zero-knowledge artifact paths. Artifacts exist for each tree
|
|
4
|
-
* depth supported by Semaphore, and they were generated in a trusted-setup.
|
|
5
|
-
* @param treeDepth The depth of the tree.
|
|
6
|
-
* @returns The zero-knowledge artifacts paths.
|
|
7
|
-
*/
|
|
8
|
-
export default function getSnarkArtifacts(treeDepth: number): Promise<SnarkArtifacts>;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { SnarkArtifacts } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Downloads the zero-knowledge artifacts and returns their paths.
|
|
4
|
-
* Artifacts exist for each tree depth supported by Semaphore, and
|
|
5
|
-
* they were generated in a trusted-setup.
|
|
6
|
-
* @param treeDepth The depth of the tree.
|
|
7
|
-
* @returns The zero-knowledge artifacts paths.
|
|
8
|
-
*/
|
|
9
|
-
export default function getSnarkArtifacts(treeDepth: number): Promise<SnarkArtifacts>;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/* istanbul ignore file */
|
|
2
|
-
import { requireNumber } from "@zk-kit/utils/error-handlers"
|
|
3
|
-
import { SnarkArtifacts } from "./types"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns the zero-knowledge artifact paths. Artifacts exist for each tree
|
|
7
|
-
* depth supported by Semaphore, and they were generated in a trusted-setup.
|
|
8
|
-
* @param treeDepth The depth of the tree.
|
|
9
|
-
* @returns The zero-knowledge artifacts paths.
|
|
10
|
-
*/
|
|
11
|
-
export default async function getSnarkArtifacts(treeDepth: number): Promise<SnarkArtifacts> {
|
|
12
|
-
requireNumber(treeDepth, "treeDepth")
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
wasmFilePath: `https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.wasm`,
|
|
16
|
-
zkeyFilePath: `https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.zkey`
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/* istanbul ignore file */
|
|
2
|
-
import { requireNumber } from "@zk-kit/utils/error-handlers"
|
|
3
|
-
import { createWriteStream, existsSync, readdirSync } from "node:fs"
|
|
4
|
-
import { mkdir } from "node:fs/promises"
|
|
5
|
-
import os from "node:os"
|
|
6
|
-
import { dirname } from "node:path"
|
|
7
|
-
import { Readable } from "node:stream"
|
|
8
|
-
import { finished } from "node:stream/promises"
|
|
9
|
-
import { SnarkArtifacts } from "./types"
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* A utility function to download the zero-knowledge artifacts from an external server.
|
|
13
|
-
* @param url The URL from which to download the artifacts.
|
|
14
|
-
* @param outputPath The path in which to save the artifacts.
|
|
15
|
-
*/
|
|
16
|
-
async function download(url: string, outputPath: string) {
|
|
17
|
-
const response = await fetch(url)
|
|
18
|
-
|
|
19
|
-
if (!response.ok) {
|
|
20
|
-
throw new Error(`Failed to fetch ${url}: ${response.statusText}`)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Ensure the directory exists.
|
|
24
|
-
const dir = dirname(outputPath)
|
|
25
|
-
await mkdir(dir, { recursive: true })
|
|
26
|
-
|
|
27
|
-
const fileStream = createWriteStream(outputPath)
|
|
28
|
-
await finished(Readable.fromWeb(response.body as any).pipe(fileStream))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Downloads the zero-knowledge artifacts and returns their paths.
|
|
33
|
-
* Artifacts exist for each tree depth supported by Semaphore, and
|
|
34
|
-
* they were generated in a trusted-setup.
|
|
35
|
-
* @param treeDepth The depth of the tree.
|
|
36
|
-
* @returns The zero-knowledge artifacts paths.
|
|
37
|
-
*/
|
|
38
|
-
export default async function getSnarkArtifacts(treeDepth: number): Promise<SnarkArtifacts> {
|
|
39
|
-
requireNumber(treeDepth, "treeDepth")
|
|
40
|
-
|
|
41
|
-
const tmpDir = "semaphore-proof"
|
|
42
|
-
const tmpPath = `${os.tmpdir()}/${tmpDir}-${treeDepth}`
|
|
43
|
-
|
|
44
|
-
if (!existsSync(tmpPath) || readdirSync(tmpPath).length !== 2) {
|
|
45
|
-
await download(
|
|
46
|
-
`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.wasm`,
|
|
47
|
-
`${tmpPath}/semaphore.wasm`
|
|
48
|
-
)
|
|
49
|
-
await download(
|
|
50
|
-
`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.zkey`,
|
|
51
|
-
`${tmpPath}/semaphore.zkey`
|
|
52
|
-
)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
wasmFilePath: `${tmpPath}/semaphore.wasm`,
|
|
57
|
-
zkeyFilePath: `${tmpPath}/semaphore.zkey`
|
|
58
|
-
}
|
|
59
|
-
}
|