@semaphore-protocol/proof 3.15.2 → 4.0.0-alpha.1
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/LICENSE +1 -1
- package/README.md +18 -28
- package/dist/index.browser.mjs +802 -0
- package/dist/index.node.js +280 -1074
- package/dist/index.node.mjs +278 -1074
- package/dist/types/generate-proof.d.ts +15 -0
- package/dist/types/get-snark-artifacts.browser.d.ts +2 -0
- package/dist/types/get-snark-artifacts.node.d.ts +2 -0
- package/dist/types/index.d.ts +6 -5
- package/dist/types/pack-points.d.ts +8 -0
- package/dist/types/types/index.d.ts +7 -5
- package/dist/types/unpack-points.d.ts +8 -0
- package/dist/types/verify-proof.d.ts +8 -0
- package/package.json +23 -15
- package/src/generate-proof.ts +88 -0
- package/src/get-snark-artifacts.browser.ts +9 -0
- package/src/get-snark-artifacts.node.ts +20 -0
- package/src/index.ts +6 -5
- package/src/pack-points.ts +20 -0
- package/src/types/index.ts +8 -5
- package/src/unpack-points.ts +20 -0
- package/src/verification-keys.json +522 -0
- package/src/verify-proof.ts +37 -0
- package/dist/types/calculateNullifierHash.d.ts +0 -8
- package/dist/types/generateProof.d.ts +0 -15
- package/dist/types/index.test.d.ts +0 -1
- package/dist/types/packProof.d.ts +0 -8
- package/dist/types/unpackProof.d.ts +0 -8
- package/dist/types/verifyProof.d.ts +0 -8
- package/src/calculateNullifierHash.ts +0 -16
- package/src/generateProof.ts +0 -69
- package/src/index.test.ts +0 -147
- package/src/packProof.ts +0 -20
- package/src/unpackProof.ts +0 -20
- package/src/verificationKeys.json +0 -712
- package/src/verifyProof.ts +0 -31
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BytesLike, Hexable } from "@ethersproject/bytes";
|
|
2
|
+
import type { Group, MerkleProof } from "@semaphore-protocol/group";
|
|
3
|
+
import type { Identity } from "@semaphore-protocol/identity";
|
|
4
|
+
import { SemaphoreProof, SnarkArtifacts } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* Generates a Semaphore proof.
|
|
7
|
+
* @param identity The Semaphore identity.
|
|
8
|
+
* @param groupOrMerkleProof The Semaphore group or its Merkle proof.
|
|
9
|
+
* @param scope The external nullifier.
|
|
10
|
+
* @param message The Semaphore signal.
|
|
11
|
+
* @param merkleTreeDepth The depth of the tree with which the circuit was compiled.
|
|
12
|
+
* @param snarkArtifacts The SNARK artifacts.
|
|
13
|
+
* @returns The Semaphore proof ready to be verified.
|
|
14
|
+
*/
|
|
15
|
+
export default function generateProof(identity: Identity, groupOrMerkleProof: Group | MerkleProof, message: BytesLike | Hexable | number | bigint, scope: BytesLike | Hexable | number | bigint, merkleTreeDepth?: number, snarkArtifacts?: SnarkArtifacts): Promise<SemaphoreProof>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
1
|
+
import generateProof from "./generate-proof";
|
|
2
|
+
import getSnarkArtifacts from "./get-snark-artifacts.node";
|
|
3
|
+
import packPoints from "./pack-points";
|
|
4
|
+
import unpackPoints from "./unpack-points";
|
|
5
|
+
import verifyProof from "./verify-proof";
|
|
5
6
|
export * from "./types";
|
|
6
|
-
export { generateProof,
|
|
7
|
+
export { generateProof, getSnarkArtifacts, packPoints, unpackPoints, verifyProof };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Groth16Proof } from "snarkjs";
|
|
2
|
+
import { PackedPoints } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Packs the Groth16 proof points into a format compatible with Semaphore.
|
|
5
|
+
* @param proof The proof points generated with SnarkJS.
|
|
6
|
+
* @returns The proof points compatible with Semaphore.
|
|
7
|
+
*/
|
|
8
|
+
export default function packPoints(proof: Groth16Proof): PackedPoints;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import type { NumericString } from "snarkjs";
|
|
2
|
+
export type BigNumberish = string | number | bigint;
|
|
2
3
|
export type SnarkArtifacts = {
|
|
3
4
|
wasmFilePath: string;
|
|
4
5
|
zkeyFilePath: string;
|
|
5
6
|
};
|
|
6
7
|
export type SemaphoreProof = {
|
|
8
|
+
merkleTreeDepth: number;
|
|
7
9
|
merkleTreeRoot: NumericString;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
message: NumericString;
|
|
11
|
+
nullifier: NumericString;
|
|
12
|
+
scope: NumericString;
|
|
13
|
+
points: PackedPoints;
|
|
12
14
|
};
|
|
13
|
-
export type
|
|
15
|
+
export type PackedPoints = [
|
|
14
16
|
NumericString,
|
|
15
17
|
NumericString,
|
|
16
18
|
NumericString,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Groth16Proof } from "snarkjs";
|
|
2
|
+
import { PackedPoints } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Unpacks the Groth16 proof points into their original form.
|
|
5
|
+
* @param proof The proof points compatible with Semaphore.
|
|
6
|
+
* @returns The proof points compatible with SnarkJS.
|
|
7
|
+
*/
|
|
8
|
+
export default function unpackPoints(proof: PackedPoints): Groth16Proof;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SemaphoreProof } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Verifies a Semaphore proof.
|
|
4
|
+
* @param fullProof The SnarkJS Semaphore proof.
|
|
5
|
+
* @param treeDepth The depth of the tree.
|
|
6
|
+
* @returns True if the proof is valid, false otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export default function verifyProof({ merkleTreeDepth, merkleTreeRoot, nullifier, message, scope, points }: SemaphoreProof): Promise<boolean>;
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semaphore-protocol/proof",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha.1",
|
|
4
4
|
"description": "A library to generate and verify Semaphore proofs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.node.js",
|
|
7
7
|
"exports": {
|
|
8
|
-
"
|
|
9
|
-
|
|
8
|
+
"node": {
|
|
9
|
+
"import": "./dist/index.node.mjs",
|
|
10
|
+
"require": "./dist/index.node.js"
|
|
11
|
+
},
|
|
12
|
+
"browser": "./dist/index.browser.mjs",
|
|
13
|
+
"default": "./dist/index.browser.mjs",
|
|
10
14
|
"types": "./dist/types/index.d.ts"
|
|
11
15
|
},
|
|
12
16
|
"types": "dist/types/index.d.ts",
|
|
@@ -22,17 +26,20 @@
|
|
|
22
26
|
"url": "https://github.com/semaphore-protocol/semaphore.git/issues"
|
|
23
27
|
},
|
|
24
28
|
"scripts": {
|
|
25
|
-
"build
|
|
26
|
-
"build": "
|
|
29
|
+
"build": "rimraf dist && yarn build:browser && yarn build:node",
|
|
30
|
+
"build:browser": "rollup -c rollup.browser.config.ts --configPlugin typescript",
|
|
31
|
+
"build:node": "rollup -c rollup.node.config.ts --configPlugin typescript",
|
|
27
32
|
"prepublishOnly": "yarn build"
|
|
28
33
|
},
|
|
29
34
|
"publishConfig": {
|
|
30
35
|
"access": "public"
|
|
31
36
|
},
|
|
32
37
|
"devDependencies": {
|
|
33
|
-
"@
|
|
38
|
+
"@ethersproject/strings": "^5.7.0",
|
|
39
|
+
"@rollup/plugin-alias": "^5.1.0",
|
|
34
40
|
"@rollup/plugin-json": "^5.0.1",
|
|
35
|
-
"@
|
|
41
|
+
"@types/download": "^8.0.5",
|
|
42
|
+
"@types/tmp": "^0.2.6",
|
|
36
43
|
"poseidon-lite": "^0.2.0",
|
|
37
44
|
"rimraf": "^5.0.5",
|
|
38
45
|
"rollup": "^4.0.2",
|
|
@@ -40,15 +47,16 @@
|
|
|
40
47
|
"rollup-plugin-typescript2": "^0.31.2"
|
|
41
48
|
},
|
|
42
49
|
"peerDependencies": {
|
|
43
|
-
"@semaphore-protocol/group": "
|
|
44
|
-
"@semaphore-protocol/identity": "
|
|
50
|
+
"@semaphore-protocol/group": "4.0.0-alpha.1",
|
|
51
|
+
"@semaphore-protocol/identity": "4.0.0-alpha.1"
|
|
45
52
|
},
|
|
46
53
|
"dependencies": {
|
|
47
|
-
"@ethersproject/bignumber": "
|
|
48
|
-
"@ethersproject/bytes": "
|
|
49
|
-
"@ethersproject/keccak256": "
|
|
50
|
-
"@
|
|
51
|
-
"
|
|
52
|
-
"
|
|
54
|
+
"@ethersproject/bignumber": "5.7.0",
|
|
55
|
+
"@ethersproject/bytes": "5.7.0",
|
|
56
|
+
"@ethersproject/keccak256": "5.7.0",
|
|
57
|
+
"@types/snarkjs": "0.7.8",
|
|
58
|
+
"download": "8.0.0",
|
|
59
|
+
"snarkjs": "0.7.3",
|
|
60
|
+
"tmp": "0.2.1"
|
|
53
61
|
}
|
|
54
62
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { BigNumber } from "@ethersproject/bignumber"
|
|
2
|
+
import { BytesLike, Hexable } from "@ethersproject/bytes"
|
|
3
|
+
import type { Group, MerkleProof } from "@semaphore-protocol/group"
|
|
4
|
+
import type { Identity } from "@semaphore-protocol/identity"
|
|
5
|
+
import { NumericString, groth16 } from "snarkjs"
|
|
6
|
+
import getSnarkArtifacts from "./get-snark-artifacts.node"
|
|
7
|
+
import hash from "./hash"
|
|
8
|
+
import packPoints from "./pack-points"
|
|
9
|
+
import { SemaphoreProof, SnarkArtifacts } from "./types"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Generates a Semaphore proof.
|
|
13
|
+
* @param identity The Semaphore identity.
|
|
14
|
+
* @param groupOrMerkleProof The Semaphore group or its Merkle proof.
|
|
15
|
+
* @param scope The external nullifier.
|
|
16
|
+
* @param message The Semaphore signal.
|
|
17
|
+
* @param merkleTreeDepth The depth of the tree with which the circuit was compiled.
|
|
18
|
+
* @param snarkArtifacts The SNARK artifacts.
|
|
19
|
+
* @returns The Semaphore proof ready to be verified.
|
|
20
|
+
*/
|
|
21
|
+
export default async function generateProof(
|
|
22
|
+
identity: Identity,
|
|
23
|
+
groupOrMerkleProof: Group | MerkleProof,
|
|
24
|
+
message: BytesLike | Hexable | number | bigint,
|
|
25
|
+
scope: BytesLike | Hexable | number | bigint,
|
|
26
|
+
merkleTreeDepth?: number,
|
|
27
|
+
snarkArtifacts?: SnarkArtifacts
|
|
28
|
+
): Promise<SemaphoreProof> {
|
|
29
|
+
let merkleProof
|
|
30
|
+
|
|
31
|
+
if ("siblings" in groupOrMerkleProof) {
|
|
32
|
+
merkleProof = groupOrMerkleProof
|
|
33
|
+
} else {
|
|
34
|
+
const leafIndex = groupOrMerkleProof.indexOf(identity.commitment)
|
|
35
|
+
merkleProof = groupOrMerkleProof.generateMerkleProof(leafIndex)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const merkleProofLength = merkleProof.siblings.length
|
|
39
|
+
|
|
40
|
+
if (merkleTreeDepth !== undefined) {
|
|
41
|
+
if (merkleTreeDepth < 1 || merkleTreeDepth > 12) {
|
|
42
|
+
throw new TypeError("The tree depth must be a number between 1 and 12")
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
merkleTreeDepth = merkleProofLength
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// If the Snark artifacts are not defined they will be automatically downloaded.
|
|
49
|
+
/* istanbul ignore next */
|
|
50
|
+
if (!snarkArtifacts) {
|
|
51
|
+
snarkArtifacts = await getSnarkArtifacts(merkleTreeDepth)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The index must be converted to a list of indices, 1 for each tree level.
|
|
55
|
+
// The missing siblings can be set to 0, as they won't be used in the circuit.
|
|
56
|
+
const merkleProofIndices = []
|
|
57
|
+
const merkleProofSiblings = merkleProof.siblings
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < merkleTreeDepth; i += 1) {
|
|
60
|
+
merkleProofIndices.push((merkleProof.index >> i) & 1)
|
|
61
|
+
|
|
62
|
+
if (merkleProofSiblings[i] === undefined) {
|
|
63
|
+
merkleProofSiblings[i] = "0"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const { proof, publicSignals } = await groth16.fullProve(
|
|
68
|
+
{
|
|
69
|
+
secret: identity.secretScalar,
|
|
70
|
+
merkleProofLength,
|
|
71
|
+
merkleProofIndices,
|
|
72
|
+
merkleProofSiblings,
|
|
73
|
+
scope: hash(scope),
|
|
74
|
+
message: hash(message)
|
|
75
|
+
},
|
|
76
|
+
snarkArtifacts.wasmFilePath,
|
|
77
|
+
snarkArtifacts.zkeyFilePath
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
merkleTreeDepth,
|
|
82
|
+
merkleTreeRoot: publicSignals[0],
|
|
83
|
+
nullifier: publicSignals[1],
|
|
84
|
+
message: BigNumber.from(message).toString() as NumericString,
|
|
85
|
+
scope: BigNumber.from(scope).toString() as NumericString,
|
|
86
|
+
points: packPoints(proof)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* istanbul ignore file */
|
|
2
|
+
import { SnarkArtifacts } from "./types"
|
|
3
|
+
|
|
4
|
+
export default async function getSnarkArtifacts(treeDepth: number): Promise<SnarkArtifacts> {
|
|
5
|
+
return {
|
|
6
|
+
wasmFilePath: `https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.wasm`,
|
|
7
|
+
zkeyFilePath: `https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.zkey`
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* istanbul ignore file */
|
|
2
|
+
import download from "download"
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
import tmp from "tmp"
|
|
5
|
+
import { SnarkArtifacts } from "./types"
|
|
6
|
+
|
|
7
|
+
export default async function getSnarkArtifacts(treeDepth: number): Promise<SnarkArtifacts> {
|
|
8
|
+
const tmpDir = "semaphore-proof"
|
|
9
|
+
const tmpPath = `${tmp.tmpdir}/${tmpDir}-${treeDepth}`
|
|
10
|
+
|
|
11
|
+
if (!fs.existsSync(tmpPath) || fs.readdirSync(tmpPath).length !== 2) {
|
|
12
|
+
await download(`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.wasm`, tmpPath)
|
|
13
|
+
await download(`https://semaphore.cedoor.dev/artifacts/${treeDepth}/semaphore.zkey`, tmpPath)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
wasmFilePath: `${tmpPath}/semaphore.wasm`,
|
|
18
|
+
zkeyFilePath: `${tmpPath}/semaphore.zkey`
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import generateProof from "./generate-proof"
|
|
2
|
+
import getSnarkArtifacts from "./get-snark-artifacts.node"
|
|
3
|
+
import packPoints from "./pack-points"
|
|
4
|
+
import unpackPoints from "./unpack-points"
|
|
5
|
+
import verifyProof from "./verify-proof"
|
|
4
6
|
|
|
5
|
-
export { MerkleProof } from "@zk-kit/incremental-merkle-tree"
|
|
6
7
|
export * from "./types"
|
|
7
|
-
export { generateProof,
|
|
8
|
+
export { generateProof, getSnarkArtifacts, packPoints, unpackPoints, verifyProof }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Groth16Proof } from "snarkjs"
|
|
2
|
+
import { PackedPoints } from "./types"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Packs the Groth16 proof points into a format compatible with Semaphore.
|
|
6
|
+
* @param proof The proof points generated with SnarkJS.
|
|
7
|
+
* @returns The proof points compatible with Semaphore.
|
|
8
|
+
*/
|
|
9
|
+
export default function packPoints(proof: Groth16Proof): PackedPoints {
|
|
10
|
+
return [
|
|
11
|
+
proof.pi_a[0],
|
|
12
|
+
proof.pi_a[1],
|
|
13
|
+
proof.pi_b[0][1],
|
|
14
|
+
proof.pi_b[0][0],
|
|
15
|
+
proof.pi_b[1][1],
|
|
16
|
+
proof.pi_b[1][0],
|
|
17
|
+
proof.pi_c[0],
|
|
18
|
+
proof.pi_c[1]
|
|
19
|
+
]
|
|
20
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import type { NumericString } from "snarkjs"
|
|
2
2
|
|
|
3
|
+
export type BigNumberish = string | number | bigint
|
|
4
|
+
|
|
3
5
|
export type SnarkArtifacts = {
|
|
4
6
|
wasmFilePath: string
|
|
5
7
|
zkeyFilePath: string
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export type SemaphoreProof = {
|
|
11
|
+
merkleTreeDepth: number
|
|
9
12
|
merkleTreeRoot: NumericString
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
message: NumericString
|
|
14
|
+
nullifier: NumericString
|
|
15
|
+
scope: NumericString
|
|
16
|
+
points: PackedPoints
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
export type
|
|
19
|
+
export type PackedPoints = [
|
|
17
20
|
NumericString,
|
|
18
21
|
NumericString,
|
|
19
22
|
NumericString,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Groth16Proof } from "snarkjs"
|
|
2
|
+
import { PackedPoints } from "./types"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Unpacks the Groth16 proof points into their original form.
|
|
6
|
+
* @param proof The proof points compatible with Semaphore.
|
|
7
|
+
* @returns The proof points compatible with SnarkJS.
|
|
8
|
+
*/
|
|
9
|
+
export default function unpackPoints(proof: PackedPoints): Groth16Proof {
|
|
10
|
+
return {
|
|
11
|
+
pi_a: [proof[0], proof[1]],
|
|
12
|
+
pi_b: [
|
|
13
|
+
[proof[3], proof[2]],
|
|
14
|
+
[proof[5], proof[4]]
|
|
15
|
+
],
|
|
16
|
+
pi_c: [proof[6], proof[7]],
|
|
17
|
+
protocol: "groth16",
|
|
18
|
+
curve: "bn128"
|
|
19
|
+
}
|
|
20
|
+
}
|