@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
package/src/generateProof.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { BigNumber } from "@ethersproject/bignumber"
|
|
2
|
-
import { BytesLike, Hexable } from "@ethersproject/bytes"
|
|
3
|
-
import { Group } from "@semaphore-protocol/group"
|
|
4
|
-
import type { Identity } from "@semaphore-protocol/identity"
|
|
5
|
-
import { prove } from "@zk-kit/groth16"
|
|
6
|
-
import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
|
|
7
|
-
import type { NumericString } from "snarkjs"
|
|
8
|
-
import hash from "./hash"
|
|
9
|
-
import packProof from "./packProof"
|
|
10
|
-
import { SemaphoreProof, SnarkArtifacts } from "./types"
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Generates a Semaphore proof.
|
|
14
|
-
* @param identity The Semaphore identity.
|
|
15
|
-
* @param groupOrMerkleProof The Semaphore group or its Merkle proof.
|
|
16
|
-
* @param externalNullifier The external nullifier.
|
|
17
|
-
* @param signal The Semaphore signal.
|
|
18
|
-
* @param snarkArtifacts The SNARK artifacts.
|
|
19
|
-
* @returns The Semaphore proof ready to be verified.
|
|
20
|
-
*/
|
|
21
|
-
export default async function generateProof(
|
|
22
|
-
{ trapdoor, nullifier, commitment }: Identity,
|
|
23
|
-
groupOrMerkleProof: Group | MerkleProof,
|
|
24
|
-
externalNullifier: BytesLike | Hexable | number | bigint,
|
|
25
|
-
signal: BytesLike | Hexable | number | bigint,
|
|
26
|
-
snarkArtifacts?: SnarkArtifacts
|
|
27
|
-
): Promise<SemaphoreProof> {
|
|
28
|
-
let merkleProof: MerkleProof
|
|
29
|
-
|
|
30
|
-
if ("depth" in groupOrMerkleProof) {
|
|
31
|
-
const index = groupOrMerkleProof.indexOf(commitment)
|
|
32
|
-
|
|
33
|
-
if (index === -1) {
|
|
34
|
-
throw new Error("The identity is not part of the group")
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
merkleProof = groupOrMerkleProof.generateMerkleProof(index)
|
|
38
|
-
} else {
|
|
39
|
-
merkleProof = groupOrMerkleProof
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (!snarkArtifacts) {
|
|
43
|
-
snarkArtifacts = {
|
|
44
|
-
wasmFilePath: `https://www.trusted-setup-pse.org/semaphore/${merkleProof.siblings.length}/semaphore.wasm`,
|
|
45
|
-
zkeyFilePath: `https://www.trusted-setup-pse.org/semaphore/${merkleProof.siblings.length}/semaphore.zkey`
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const { proof, publicSignals } = await prove(
|
|
50
|
-
{
|
|
51
|
-
identityTrapdoor: trapdoor,
|
|
52
|
-
identityNullifier: nullifier,
|
|
53
|
-
treePathIndices: merkleProof.pathIndices,
|
|
54
|
-
treeSiblings: merkleProof.siblings,
|
|
55
|
-
externalNullifier: hash(externalNullifier),
|
|
56
|
-
signalHash: hash(signal)
|
|
57
|
-
},
|
|
58
|
-
snarkArtifacts.wasmFilePath,
|
|
59
|
-
snarkArtifacts.zkeyFilePath
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
merkleTreeRoot: publicSignals[0],
|
|
64
|
-
nullifierHash: publicSignals[1],
|
|
65
|
-
signal: BigNumber.from(signal).toString() as NumericString,
|
|
66
|
-
externalNullifier: BigNumber.from(externalNullifier).toString() as NumericString,
|
|
67
|
-
proof: packProof(proof)
|
|
68
|
-
}
|
|
69
|
-
}
|
package/src/index.test.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { formatBytes32String } from "@ethersproject/strings"
|
|
2
|
-
import { Group } from "@semaphore-protocol/group"
|
|
3
|
-
import { Identity } from "@semaphore-protocol/identity"
|
|
4
|
-
import { getCurveFromName } from "ffjavascript"
|
|
5
|
-
import calculateNullifierHash from "./calculateNullifierHash"
|
|
6
|
-
import generateProof from "./generateProof"
|
|
7
|
-
import hash from "./hash"
|
|
8
|
-
import packProof from "./packProof"
|
|
9
|
-
import { SemaphoreProof } from "./types"
|
|
10
|
-
import unpackProof from "./unpackProof"
|
|
11
|
-
import verifyProof from "./verifyProof"
|
|
12
|
-
|
|
13
|
-
describe("Proof", () => {
|
|
14
|
-
const treeDepth = Number(process.env.TREE_DEPTH) || 20
|
|
15
|
-
|
|
16
|
-
const externalNullifier = formatBytes32String("Topic")
|
|
17
|
-
const signal = formatBytes32String("Hello world")
|
|
18
|
-
|
|
19
|
-
const wasmFilePath = `./snark-artifacts/${treeDepth}/semaphore.wasm`
|
|
20
|
-
const zkeyFilePath = `./snark-artifacts/${treeDepth}/semaphore.zkey`
|
|
21
|
-
|
|
22
|
-
const identity = new Identity()
|
|
23
|
-
|
|
24
|
-
let fullProof: SemaphoreProof
|
|
25
|
-
let curve: any
|
|
26
|
-
|
|
27
|
-
beforeAll(async () => {
|
|
28
|
-
curve = await getCurveFromName("bn128")
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
afterAll(async () => {
|
|
32
|
-
await curve.terminate()
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
describe("# generateProof", () => {
|
|
36
|
-
it("Should not generate Semaphore proofs if the identity is not part of the group", async () => {
|
|
37
|
-
const group = new Group(treeDepth, 20, [BigInt(1), BigInt(2)])
|
|
38
|
-
|
|
39
|
-
const fun = () =>
|
|
40
|
-
generateProof(identity, group, externalNullifier, signal, {
|
|
41
|
-
wasmFilePath,
|
|
42
|
-
zkeyFilePath
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
await expect(fun).rejects.toThrow("The identity is not part of the group")
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it("Should not generate a Semaphore proof with default snark artifacts with Node.js", async () => {
|
|
49
|
-
const group = new Group(treeDepth, 20, [BigInt(1), BigInt(2), identity.commitment])
|
|
50
|
-
|
|
51
|
-
const fun = () => generateProof(identity, group, externalNullifier, signal)
|
|
52
|
-
|
|
53
|
-
await expect(fun).rejects.toThrow("ENOENT: no such file or directory")
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it("Should generate a Semaphore proof passing a group as parameter", async () => {
|
|
57
|
-
const group = new Group(treeDepth, 20, [BigInt(1), BigInt(2), identity.commitment])
|
|
58
|
-
|
|
59
|
-
fullProof = await generateProof(identity, group, externalNullifier, signal, {
|
|
60
|
-
wasmFilePath,
|
|
61
|
-
zkeyFilePath
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
expect(typeof fullProof).toBe("object")
|
|
65
|
-
expect(fullProof.merkleTreeRoot).toBe(group.root.toString())
|
|
66
|
-
}, 20000)
|
|
67
|
-
|
|
68
|
-
it("Should generate a Semaphore proof passing a Merkle proof as parameter", async () => {
|
|
69
|
-
const group = new Group(treeDepth, 20, [BigInt(1), BigInt(2), identity.commitment])
|
|
70
|
-
|
|
71
|
-
fullProof = await generateProof(identity, group.generateMerkleProof(2), externalNullifier, signal, {
|
|
72
|
-
wasmFilePath,
|
|
73
|
-
zkeyFilePath
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
expect(typeof fullProof).toBe("object")
|
|
77
|
-
expect(fullProof.merkleTreeRoot).toBe(group.root.toString())
|
|
78
|
-
}, 20000)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
describe("# verifyProof", () => {
|
|
82
|
-
it("Should not verify a proof if the tree depth is wrong", () => {
|
|
83
|
-
const fun = () => verifyProof(fullProof, 3)
|
|
84
|
-
|
|
85
|
-
expect(fun).toThrow("The tree depth must be a number between 16 and 32")
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it("Should verify a Semaphore proof", async () => {
|
|
89
|
-
const response = await verifyProof(fullProof, treeDepth)
|
|
90
|
-
|
|
91
|
-
expect(response).toBe(true)
|
|
92
|
-
})
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
describe("# hash", () => {
|
|
96
|
-
it("Should hash the signal value correctly", async () => {
|
|
97
|
-
const signalHash = hash(signal)
|
|
98
|
-
|
|
99
|
-
expect(signalHash).toBe("8665846418922331996225934941481656421248110469944536651334918563951783029")
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it("Should hash the external nullifier value correctly", async () => {
|
|
103
|
-
const externalNullifierHash = hash(externalNullifier)
|
|
104
|
-
|
|
105
|
-
expect(externalNullifierHash).toBe(
|
|
106
|
-
"244178201824278269437519042830883072613014992408751798420801126401127326826"
|
|
107
|
-
)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it("Should hash a number", async () => {
|
|
111
|
-
expect(hash(2)).toBe("113682330006535319932160121224458771213356533826860247409332700812532759386")
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it("Should hash a big number", async () => {
|
|
115
|
-
expect(hash(BigInt(2))).toBe("113682330006535319932160121224458771213356533826860247409332700812532759386")
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it("Should hash an hex number", async () => {
|
|
119
|
-
expect(hash("0x2")).toBe("113682330006535319932160121224458771213356533826860247409332700812532759386")
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
it("Should hash an string number", async () => {
|
|
123
|
-
expect(hash("2")).toBe("113682330006535319932160121224458771213356533826860247409332700812532759386")
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
it("Should hash an array", async () => {
|
|
127
|
-
expect(hash([2])).toBe("113682330006535319932160121224458771213356533826860247409332700812532759386")
|
|
128
|
-
})
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
describe("# calculateNullifierHash", () => {
|
|
132
|
-
it("Should calculate the nullifier hash correctly", async () => {
|
|
133
|
-
const nullifierHash = calculateNullifierHash(identity.nullifier, externalNullifier)
|
|
134
|
-
|
|
135
|
-
expect(fullProof.nullifierHash).toBe(nullifierHash.toString())
|
|
136
|
-
})
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
describe("# packProof/unpackProof", () => {
|
|
140
|
-
it("Should return a packed proof", async () => {
|
|
141
|
-
const originalProof = unpackProof(fullProof.proof)
|
|
142
|
-
const proof = packProof(originalProof)
|
|
143
|
-
|
|
144
|
-
expect(proof).toStrictEqual(fullProof.proof)
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
})
|
package/src/packProof.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Groth16Proof } from "snarkjs"
|
|
2
|
-
import { PackedProof } from "./types"
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Packs a proof into a format compatible with Semaphore.
|
|
6
|
-
* @param proof The Groth16 proof generated with SnarkJS.
|
|
7
|
-
* @returns The proof compatible with Semaphore.
|
|
8
|
-
*/
|
|
9
|
-
export default function packProof(proof: Groth16Proof): PackedProof {
|
|
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/unpackProof.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Groth16Proof } from "snarkjs"
|
|
2
|
-
import { PackedProof } from "./types"
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Unpacks a proof into its original form.
|
|
6
|
-
* @param proof The proof compatible with Semaphore.
|
|
7
|
-
* @returns The proof compatible with SnarkJS.
|
|
8
|
-
*/
|
|
9
|
-
export default function unpackProof(proof: PackedProof): 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
|
-
}
|