@semaphore-protocol/proof 3.12.3 → 3.13.0

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.
@@ -0,0 +1,4 @@
1
+ export default function groth16Prove(_input: any, wasmFile: any, zkeyFileName: any): Promise<{
2
+ proof: any;
3
+ publicSignals: any;
4
+ }>;
@@ -0,0 +1 @@
1
+ export declare function log2(V: any): number;
@@ -0,0 +1 @@
1
+ export default function groth16Verify(_vk_verifier: any, _publicSignals: any, _proof: any): Promise<any>;
@@ -0,0 +1 @@
1
+ export default function wtnsCalculate(_input: any, wasmFileName: any, wtnsFileName: any): Promise<void>;
@@ -0,0 +1,6 @@
1
+ export declare function writeBin(fd: any, witnessBin: any, prime: any): Promise<void>;
2
+ export declare function readHeader(fd: any, sections: any): Promise<{
3
+ n8: any;
4
+ q: any;
5
+ nWitness: any;
6
+ }>;
@@ -0,0 +1 @@
1
+ export declare function readHeader(fd: any, sections: any, toObject: any): Promise<any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semaphore-protocol/proof",
3
- "version": "3.12.3",
3
+ "version": "3.13.0",
4
4
  "description": "A library to generate and verify Semaphore proofs.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.node.js",
@@ -35,28 +35,29 @@
35
35
  "access": "public"
36
36
  },
37
37
  "devDependencies": {
38
+ "@iden3/binfileutils": "0.0.11",
38
39
  "@rollup/plugin-commonjs": "^24.1.0",
39
40
  "@rollup/plugin-json": "^5.0.1",
40
41
  "@rollup/plugin-node-resolve": "^15.0.2",
41
- "@rollup/plugin-replace": "^5.0.3",
42
42
  "@rollup/plugin-virtual": "^3.0.2",
43
- "ffjavascript": "^0.2.54",
43
+ "fastfile": "0.0.20",
44
44
  "poseidon-lite": "^0.2.0",
45
45
  "rimraf": "^5.0.5",
46
46
  "rollup": "^4.0.2",
47
47
  "rollup-plugin-cleanup": "^3.2.1",
48
- "rollup-plugin-typescript2": "^0.31.2",
49
- "snarkjs": "0.7.1"
48
+ "rollup-plugin-typescript2": "^0.31.2"
50
49
  },
51
50
  "peerDependencies": {
52
- "@semaphore-protocol/group": "3.12.3",
53
- "@semaphore-protocol/identity": "3.12.3"
51
+ "@semaphore-protocol/group": "3.13.0",
52
+ "@semaphore-protocol/identity": "3.13.0"
54
53
  },
55
54
  "dependencies": {
56
55
  "@ethersproject/bignumber": "^5.5.0",
57
56
  "@ethersproject/bytes": "^5.7.0",
58
57
  "@ethersproject/keccak256": "^5.7.0",
59
58
  "@ethersproject/strings": "^5.5.0",
60
- "@zk-kit/incremental-merkle-tree": "0.4.3"
59
+ "@zk-kit/incremental-merkle-tree": "0.4.3",
60
+ "circom_runtime": "0.1.24",
61
+ "ffjavascript": "0.2.60"
61
62
  }
62
63
  }
@@ -1,5 +1,5 @@
1
1
  import { BytesLike, Hexable } from "@ethersproject/bytes"
2
- import { poseidon2 } from "poseidon-lite/poseidon2"
2
+ import { poseidon2 } from "poseidon-lite"
3
3
  import hash from "./hash"
4
4
 
5
5
  /**
@@ -3,10 +3,11 @@ import { BytesLike, Hexable } from "@ethersproject/bytes"
3
3
  import { Group } from "@semaphore-protocol/group"
4
4
  import type { Identity } from "@semaphore-protocol/identity"
5
5
  import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
6
- import { groth16, NumericString } from "snarkjs"
6
+ import type { NumericString } from "snarkjs"
7
7
  import hash from "./hash"
8
8
  import packProof from "./packProof"
9
9
  import { SemaphoreProof, SnarkArtifacts } from "./types"
10
+ import groth16Prove from "./groth16/prove"
10
11
 
11
12
  /**
12
13
  * Generates a Semaphore proof.
@@ -45,7 +46,7 @@ export default async function generateProof(
45
46
  }
46
47
  }
47
48
 
48
- const { proof, publicSignals } = await groth16.fullProve(
49
+ const { proof, publicSignals } = await groth16Prove(
49
50
  {
50
51
  identityTrapdoor: trapdoor,
51
52
  identityNullifier: nullifier,
@@ -0,0 +1,226 @@
1
+ /* eslint-disable no-plusplus */
2
+ /* eslint-disable eqeqeq */
3
+ /* eslint-disable @typescript-eslint/naming-convention */
4
+ /* istanbul ignore file */
5
+
6
+ // @ts-ignore
7
+ import * as binFileUtils from "@iden3/binfileutils"
8
+ import { BigBuffer, Scalar, utils } from "ffjavascript"
9
+ import { log2 } from "./utils"
10
+ import * as zkeyUtils from "./zkey-utils"
11
+ import * as wtnsUtils from "./wtns-utils"
12
+ import wtnsCalculate from "./wtns-calculate"
13
+
14
+ const { stringifyBigInts, unstringifyBigInts } = utils
15
+
16
+ async function buildABC1(curve: any, zkey: any, witness: any, coeffs: any) {
17
+ const { n8 } = curve.Fr
18
+ const sCoef = 4 * 3 + zkey.n8r
19
+ const nCoef = (coeffs.byteLength - 4) / sCoef
20
+
21
+ const outBuffA = new BigBuffer(zkey.domainSize * n8)
22
+ const outBuffB = new BigBuffer(zkey.domainSize * n8)
23
+ const outBuffC = new BigBuffer(zkey.domainSize * n8)
24
+
25
+ const outBuf = [outBuffA, outBuffB]
26
+ for (let i = 0; i < nCoef; i++) {
27
+ const buffCoef = coeffs.slice(4 + i * sCoef, 4 + i * sCoef + sCoef)
28
+ const buffCoefV = new DataView(buffCoef.buffer)
29
+ const m = buffCoefV.getUint32(0, true)
30
+ const c = buffCoefV.getUint32(4, true)
31
+ const s = buffCoefV.getUint32(8, true)
32
+ const coef = buffCoef.slice(12, 12 + n8)
33
+ outBuf[m].set(
34
+ curve.Fr.add(outBuf[m].slice(c * n8, c * n8 + n8), curve.Fr.mul(coef, witness.slice(s * n8, s * n8 + n8))),
35
+ c * n8
36
+ )
37
+ }
38
+
39
+ for (let i = 0; i < zkey.domainSize; i++) {
40
+ outBuffC.set(curve.Fr.mul(outBuffA.slice(i * n8, i * n8 + n8), outBuffB.slice(i * n8, i * n8 + n8)), i * n8)
41
+ }
42
+
43
+ return [outBuffA, outBuffB, outBuffC]
44
+ }
45
+
46
+ async function joinABC(curve: any, _zkey: any, a: any, b: any, c: any) {
47
+ const MAX_CHUNK_SIZE = 1 << 22
48
+
49
+ const { n8 } = curve.Fr
50
+ const nElements = Math.floor(a.byteLength / curve.Fr.n8)
51
+
52
+ const promises = []
53
+
54
+ for (let i = 0; i < nElements; i += MAX_CHUNK_SIZE) {
55
+ const n = Math.min(nElements - i, MAX_CHUNK_SIZE)
56
+
57
+ const task = []
58
+
59
+ const aChunk = a.slice(i * n8, (i + n) * n8)
60
+ const bChunk = b.slice(i * n8, (i + n) * n8)
61
+ const cChunk = c.slice(i * n8, (i + n) * n8)
62
+
63
+ task.push({ cmd: "ALLOCSET", var: 0, buff: aChunk })
64
+ task.push({ cmd: "ALLOCSET", var: 1, buff: bChunk })
65
+ task.push({ cmd: "ALLOCSET", var: 2, buff: cChunk })
66
+ task.push({ cmd: "ALLOC", var: 3, len: n * n8 })
67
+ task.push({
68
+ cmd: "CALL",
69
+ fnName: "qap_joinABC",
70
+ params: [{ var: 0 }, { var: 1 }, { var: 2 }, { val: n }, { var: 3 }]
71
+ })
72
+ task.push({ cmd: "CALL", fnName: "frm_batchFromMontgomery", params: [{ var: 3 }, { val: n }, { var: 3 }] })
73
+ task.push({ cmd: "GET", out: 0, var: 3, len: n * n8 })
74
+ promises.push(curve.tm.queueAction(task))
75
+ }
76
+
77
+ const result = await Promise.all(promises)
78
+
79
+ let outBuff
80
+ if (a instanceof BigBuffer) {
81
+ // @ts-ignore
82
+ outBuff = new BigBuffer(a.byteLength)
83
+ } else {
84
+ outBuff = new Uint8Array(a.byteLength)
85
+ }
86
+
87
+ let p = 0
88
+ for (let i = 0; i < result.length; i++) {
89
+ outBuff.set(result[i][0], p)
90
+ p += result[i][0].byteLength
91
+ }
92
+
93
+ return outBuff
94
+ }
95
+
96
+ export default async function groth16Prove(_input: any, wasmFile: any, zkeyFileName: any) {
97
+ const input = unstringifyBigInts(_input)
98
+
99
+ const witnessFileName = {
100
+ type: "mem"
101
+ }
102
+
103
+ await wtnsCalculate(input, wasmFile, witnessFileName)
104
+
105
+ const { fd: fdWtns, sections: sectionsWtns } = await binFileUtils.readBinFile(
106
+ witnessFileName,
107
+ "wtns",
108
+ 2,
109
+ 1 << 25,
110
+ 1 << 23
111
+ )
112
+
113
+ const wtns = await wtnsUtils.readHeader(fdWtns, sectionsWtns)
114
+
115
+ const { fd: fdZKey, sections: sectionsZKey } = await binFileUtils.readBinFile(
116
+ zkeyFileName,
117
+ "zkey",
118
+ 2,
119
+ 1 << 25,
120
+ 1 << 23
121
+ )
122
+
123
+ const zkey = await zkeyUtils.readHeader(fdZKey, sectionsZKey, undefined)
124
+
125
+ if (zkey.protocol !== "groth16") {
126
+ throw new Error("zkey file is not groth16")
127
+ }
128
+
129
+ if (!Scalar.eq(zkey.r, wtns.q)) {
130
+ throw new Error("Curve of the witness does not match the curve of the proving key")
131
+ }
132
+
133
+ if (wtns.nWitness !== zkey.nVars) {
134
+ throw new Error(`Invalid witness length. Circuit: ${zkey.nVars}, witness: ${wtns.nWitness}`)
135
+ }
136
+
137
+ const { curve } = zkey
138
+ const { Fr } = curve
139
+ const { G1 } = curve
140
+ const { G2 } = curve
141
+
142
+ const power = log2(zkey.domainSize)
143
+
144
+ const buffWitness = await binFileUtils.readSection(fdWtns, sectionsWtns, 2)
145
+ const buffCoeffs = await binFileUtils.readSection(fdZKey, sectionsZKey, 4)
146
+
147
+ const [buffA_T, buffB_T, buffC_T] = await buildABC1(curve, zkey, buffWitness, buffCoeffs)
148
+
149
+ const inc = power == Fr.s ? curve.Fr.shift : curve.Fr.w[power + 1]
150
+
151
+ const buffA = await Fr.ifft(buffA_T, "", "", undefined, "IFFT_A")
152
+ const buffAodd = await Fr.batchApplyKey(buffA, Fr.e(1), inc)
153
+ const buffAodd_T = await Fr.fft(buffAodd, "", "", undefined, "FFT_A")
154
+
155
+ const buffB = await Fr.ifft(buffB_T, "", "", undefined, "IFFT_B")
156
+ const buffBodd = await Fr.batchApplyKey(buffB, Fr.e(1), inc)
157
+ const buffBodd_T = await Fr.fft(buffBodd, "", "", undefined, "FFT_B")
158
+
159
+ const buffC = await Fr.ifft(buffC_T, "", "", undefined, "IFFT_C")
160
+ const buffCodd = await Fr.batchApplyKey(buffC, Fr.e(1), inc)
161
+ const buffCodd_T = await Fr.fft(buffCodd, "", "", undefined, "FFT_C")
162
+
163
+ const buffPodd_T = await joinABC(curve, zkey, buffAodd_T, buffBodd_T, buffCodd_T)
164
+
165
+ let proof: any = {}
166
+
167
+ const buffBasesA = await binFileUtils.readSection(fdZKey, sectionsZKey, 5)
168
+ proof.pi_a = await curve.G1.multiExpAffine(buffBasesA, buffWitness, undefined, "multiexp A")
169
+
170
+ const buffBasesB1 = await binFileUtils.readSection(fdZKey, sectionsZKey, 6)
171
+ let pib1 = await curve.G1.multiExpAffine(buffBasesB1, buffWitness, undefined, "multiexp B1")
172
+
173
+ const buffBasesB2 = await binFileUtils.readSection(fdZKey, sectionsZKey, 7)
174
+ proof.pi_b = await curve.G2.multiExpAffine(buffBasesB2, buffWitness, undefined, "multiexp B2")
175
+
176
+ const buffBasesC = await binFileUtils.readSection(fdZKey, sectionsZKey, 8)
177
+ proof.pi_c = await curve.G1.multiExpAffine(
178
+ buffBasesC,
179
+ buffWitness.slice((zkey.nPublic + 1) * curve.Fr.n8),
180
+ undefined,
181
+ "multiexp C"
182
+ )
183
+
184
+ const buffBasesH = await binFileUtils.readSection(fdZKey, sectionsZKey, 9)
185
+ const resH = await curve.G1.multiExpAffine(buffBasesH, buffPodd_T, undefined, "multiexp H")
186
+
187
+ const r = curve.Fr.random()
188
+ const s = curve.Fr.random()
189
+
190
+ proof.pi_a = G1.add(proof.pi_a, zkey.vk_alpha_1)
191
+ proof.pi_a = G1.add(proof.pi_a, G1.timesFr(zkey.vk_delta_1, r))
192
+
193
+ proof.pi_b = G2.add(proof.pi_b, zkey.vk_beta_2)
194
+ proof.pi_b = G2.add(proof.pi_b, G2.timesFr(zkey.vk_delta_2, s))
195
+
196
+ pib1 = G1.add(pib1, zkey.vk_beta_1)
197
+ pib1 = G1.add(pib1, G1.timesFr(zkey.vk_delta_1, s))
198
+
199
+ proof.pi_c = G1.add(proof.pi_c, resH)
200
+
201
+ proof.pi_c = G1.add(proof.pi_c, G1.timesFr(proof.pi_a, s))
202
+ proof.pi_c = G1.add(proof.pi_c, G1.timesFr(pib1, r))
203
+ proof.pi_c = G1.add(proof.pi_c, G1.timesFr(zkey.vk_delta_1, Fr.neg(Fr.mul(r, s))))
204
+
205
+ let publicSignals = []
206
+
207
+ for (let i = 1; i <= zkey.nPublic; i++) {
208
+ const b = buffWitness.slice(i * Fr.n8, i * Fr.n8 + Fr.n8)
209
+ publicSignals.push(Scalar.fromRprLE(b, undefined, undefined))
210
+ }
211
+
212
+ proof.pi_a = G1.toObject(G1.toAffine(proof.pi_a))
213
+ proof.pi_b = G2.toObject(G2.toAffine(proof.pi_b))
214
+ proof.pi_c = G1.toObject(G1.toAffine(proof.pi_c))
215
+
216
+ proof.protocol = "groth16"
217
+ proof.curve = curve.name
218
+
219
+ await fdZKey.close()
220
+ await fdWtns.close()
221
+
222
+ proof = stringifyBigInts(proof)
223
+ publicSignals = stringifyBigInts(publicSignals)
224
+
225
+ return { proof, publicSignals }
226
+ }
@@ -0,0 +1,14 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ /* eslint-disable no-return-assign */
3
+ /* istanbul ignore file */
4
+
5
+ export function log2(V: any) {
6
+ return (
7
+ ((V & 0xffff0000) !== 0 ? ((V &= 0xffff0000), 16) : 0) |
8
+ ((V & 0xff00ff00) !== 0 ? ((V &= 0xff00ff00), 8) : 0) |
9
+ ((V & 0xf0f0f0f0) !== 0 ? ((V &= 0xf0f0f0f0), 4) : 0) |
10
+ ((V & 0xcccccccc) !== 0 ? ((V &= 0xcccccccc), 2) : 0) |
11
+ // @ts-ignore
12
+ ((V & 0xaaaaaaaa) !== 0)
13
+ )
14
+ }
@@ -0,0 +1,73 @@
1
+ /* eslint-disable no-plusplus */
2
+ /* eslint-disable @typescript-eslint/naming-convention */
3
+ /* istanbul ignore file */
4
+
5
+ import { Scalar, utils, buildBn128 } from "ffjavascript"
6
+
7
+ const { unstringifyBigInts } = utils
8
+
9
+ function isWellConstructed(curve: any, proof: any) {
10
+ const { G1 } = curve
11
+ const { G2 } = curve
12
+
13
+ return G1.isValid(proof.pi_a) && G2.isValid(proof.pi_b) && G1.isValid(proof.pi_c)
14
+ }
15
+
16
+ function publicInputsAreValid(curve: any, publicInputs: any) {
17
+ for (let i = 0; i < publicInputs.length; i++) {
18
+ if (!Scalar.lt(publicInputs[i], curve.r)) {
19
+ return false
20
+ }
21
+ }
22
+ return true
23
+ }
24
+
25
+ export default async function groth16Verify(_vk_verifier: any, _publicSignals: any, _proof: any) {
26
+ const vk_verifier = unstringifyBigInts(_vk_verifier)
27
+ const proof = unstringifyBigInts(_proof)
28
+ const publicSignals = unstringifyBigInts(_publicSignals)
29
+
30
+ const curve = await buildBn128(undefined, undefined)
31
+
32
+ const IC0 = curve.G1.fromObject(vk_verifier.IC[0])
33
+ const IC = new Uint8Array(curve.G1.F.n8 * 2 * publicSignals.length)
34
+ const w = new Uint8Array(curve.Fr.n8 * publicSignals.length)
35
+
36
+ if (!publicInputsAreValid(curve, publicSignals)) {
37
+ return false
38
+ }
39
+
40
+ for (let i = 0; i < publicSignals.length; i++) {
41
+ const buffP = curve.G1.fromObject(vk_verifier.IC[i + 1])
42
+ IC.set(buffP, i * curve.G1.F.n8 * 2)
43
+ Scalar.toRprLE(w, curve.Fr.n8 * i, publicSignals[i], curve.Fr.n8)
44
+ }
45
+
46
+ let cpub = await curve.G1.multiExpAffine(IC, w)
47
+ cpub = curve.G1.add(cpub, IC0)
48
+
49
+ const pi_a = curve.G1.fromObject(proof.pi_a)
50
+ const pi_b = curve.G2.fromObject(proof.pi_b)
51
+ const pi_c = curve.G1.fromObject(proof.pi_c)
52
+
53
+ if (!isWellConstructed(curve, { pi_a, pi_b, pi_c })) {
54
+ return false
55
+ }
56
+
57
+ const vk_gamma_2 = curve.G2.fromObject(vk_verifier.vk_gamma_2)
58
+ const vk_delta_2 = curve.G2.fromObject(vk_verifier.vk_delta_2)
59
+ const vk_alpha_1 = curve.G1.fromObject(vk_verifier.vk_alpha_1)
60
+ const vk_beta_2 = curve.G2.fromObject(vk_verifier.vk_beta_2)
61
+
62
+ return curve.pairingEq(
63
+ curve.G1.neg(pi_a),
64
+ pi_b,
65
+ cpub,
66
+ vk_gamma_2,
67
+ pi_c,
68
+ vk_delta_2,
69
+
70
+ vk_alpha_1,
71
+ vk_beta_2
72
+ )
73
+ }
@@ -0,0 +1,39 @@
1
+ /* eslint-disable eqeqeq */
2
+ /* istanbul ignore file */
3
+
4
+ // @ts-ignore
5
+ import * as binFileUtils from "@iden3/binfileutils"
6
+ // @ts-ignore
7
+ import { WitnessCalculatorBuilder } from "circom_runtime"
8
+ // @ts-ignore
9
+ import * as fastFile from "fastfile"
10
+ import { utils } from "ffjavascript"
11
+ import * as wtnsUtils from "./wtns-utils"
12
+
13
+ const { unstringifyBigInts } = utils
14
+
15
+ export default async function wtnsCalculate(_input: any, wasmFileName: any, wtnsFileName: any) {
16
+ const input = unstringifyBigInts(_input)
17
+
18
+ const fdWasm = await fastFile.readExisting(wasmFileName)
19
+ const wasm = await fdWasm.read(fdWasm.totalSize)
20
+ await fdWasm.close()
21
+
22
+ const wc = await WitnessCalculatorBuilder(wasm)
23
+
24
+ if (wc.circom_version() == 1) {
25
+ const w = await wc.calculateBinWitness(input)
26
+
27
+ const fdWtns = await binFileUtils.createBinFile(wtnsFileName, "wtns", 2, 2)
28
+
29
+ await wtnsUtils.writeBin(fdWtns, w, wc.prime)
30
+ await fdWtns.close()
31
+ } else {
32
+ const fdWtns = await fastFile.createOverride(wtnsFileName)
33
+
34
+ const w = await wc.calculateWTNSBin(input)
35
+
36
+ await fdWtns.write(w)
37
+ await fdWtns.close()
38
+ }
39
+ }
@@ -0,0 +1,32 @@
1
+ /* eslint-disable eqeqeq */
2
+ /* istanbul ignore file */
3
+
4
+ // @ts-ignore
5
+ import * as binFileUtils from "@iden3/binfileutils"
6
+ import { Scalar } from "ffjavascript"
7
+
8
+ export async function writeBin(fd: any, witnessBin: any, prime: any) {
9
+ await binFileUtils.startWriteSection(fd, 1)
10
+ const n8 = (Math.floor((Scalar.bitLength(prime) - 1) / 64) + 1) * 8
11
+ await fd.writeULE32(n8)
12
+ await binFileUtils.writeBigInt(fd, prime, n8)
13
+ if (witnessBin.byteLength % n8 != 0) {
14
+ throw new Error("Invalid witness length")
15
+ }
16
+ await fd.writeULE32(witnessBin.byteLength / n8)
17
+ await binFileUtils.endWriteSection(fd)
18
+
19
+ await binFileUtils.startWriteSection(fd, 2)
20
+ await fd.write(witnessBin)
21
+ await binFileUtils.endWriteSection(fd)
22
+ }
23
+
24
+ export async function readHeader(fd: any, sections: any) {
25
+ await binFileUtils.startReadUniqueSection(fd, sections, 1)
26
+ const n8 = await fd.readULE32()
27
+ const q = await binFileUtils.readBigInt(fd, n8)
28
+ const nWitness = await fd.readULE32()
29
+ await binFileUtils.endReadSection(fd)
30
+
31
+ return { n8, q, nWitness }
32
+ }
@@ -0,0 +1,60 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ /* istanbul ignore file */
3
+
4
+ // @ts-ignore
5
+ import * as binFileUtils from "@iden3/binfileutils"
6
+ import { buildBn128 } from "ffjavascript"
7
+ import { log2 } from "./utils"
8
+
9
+ async function readG1(fd: any, curve: any, toObject: any) {
10
+ const buff = await fd.read(curve.G1.F.n8 * 2)
11
+ const res = curve.G1.fromRprLEM(buff, 0)
12
+ return toObject ? curve.G1.toObject(res) : res
13
+ }
14
+
15
+ async function readG2(fd: any, curve: any, toObject: any) {
16
+ const buff = await fd.read(curve.G2.F.n8 * 2)
17
+ const res = curve.G2.fromRprLEM(buff, 0)
18
+ return toObject ? curve.G2.toObject(res) : res
19
+ }
20
+
21
+ async function readHeaderGroth16(fd: any, sections: any, toObject: any) {
22
+ const zkey: any = {}
23
+
24
+ zkey.protocol = "groth16"
25
+
26
+ await binFileUtils.startReadUniqueSection(fd, sections, 2)
27
+ const n8q = await fd.readULE32()
28
+ zkey.n8q = n8q
29
+ zkey.q = await binFileUtils.readBigInt(fd, n8q)
30
+
31
+ const n8r = await fd.readULE32()
32
+ zkey.n8r = n8r
33
+ zkey.r = await binFileUtils.readBigInt(fd, n8r)
34
+ zkey.curve = await buildBn128(undefined, undefined)
35
+ zkey.nVars = await fd.readULE32()
36
+ zkey.nPublic = await fd.readULE32()
37
+ zkey.domainSize = await fd.readULE32()
38
+ zkey.power = log2(zkey.domainSize)
39
+ zkey.vk_alpha_1 = await readG1(fd, zkey.curve, toObject)
40
+ zkey.vk_beta_1 = await readG1(fd, zkey.curve, toObject)
41
+ zkey.vk_beta_2 = await readG2(fd, zkey.curve, toObject)
42
+ zkey.vk_gamma_2 = await readG2(fd, zkey.curve, toObject)
43
+ zkey.vk_delta_1 = await readG1(fd, zkey.curve, toObject)
44
+ zkey.vk_delta_2 = await readG2(fd, zkey.curve, toObject)
45
+ await binFileUtils.endReadSection(fd)
46
+
47
+ return zkey
48
+ }
49
+
50
+ export async function readHeader(fd: any, sections: any, toObject: any) {
51
+ await binFileUtils.startReadUniqueSection(fd, sections, 1)
52
+ const protocolId = await fd.readULE32()
53
+ await binFileUtils.endReadSection(fd)
54
+
55
+ if (protocolId === 1) {
56
+ return readHeaderGroth16(fd, sections, toObject)
57
+ }
58
+
59
+ throw new Error("Protocol not supported: ")
60
+ }
@@ -1,8 +1,8 @@
1
- import { groth16 } from "snarkjs"
2
1
  import hash from "./hash"
3
2
  import { SemaphoreProof } from "./types"
4
3
  import unpackProof from "./unpackProof"
5
4
  import verificationKeys from "./verificationKeys.json"
5
+ import groth16Verify from "./groth16/verify"
6
6
 
7
7
  /**
8
8
  * Verifies a Semaphore proof.
@@ -24,7 +24,7 @@ export default function verifyProof(
24
24
  IC: verificationKeys.IC[treeDepth - 16]
25
25
  }
26
26
 
27
- return groth16.verify(
27
+ return groth16Verify(
28
28
  verificationKey,
29
29
  [merkleTreeRoot, nullifierHash, hash(signal), hash(externalNullifier)],
30
30
  unpackProof(proof)