@semaphore-protocol/proof 3.0.0-beta.6 → 3.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 CHANGED
@@ -73,12 +73,12 @@ yarn add @semaphore-protocol/identity @semaphore-protocol/group @semaphore-proto
73
73
  import { Identity } from "@semaphore-protocol/identity"
74
74
  import { Group } from "@semaphore-protocol/group"
75
75
  import { generateProof } from "@semaphore-protocol/proof"
76
- import { formatBytes32String } from "ethers/lib/utils"
76
+ import { utils } from "ethers"
77
77
 
78
78
  const identity = new Identity()
79
79
  const group = new Group()
80
- const externalNullifier = 1
81
- const signal = formatBytes32String("Hello world")
80
+ const externalNullifier = utils.formatBytes32String("Topic")
81
+ const signal = utils.formatBytes32String("Hello world")
82
82
 
83
83
  group.addMembers([...identityCommitments, identity.generateCommitment()])
84
84
 
@@ -98,27 +98,3 @@ import { verifyProof } from "@semaphore-protocol/proof"
98
98
 
99
99
  await verifyProof(fullProof, 20)
100
100
  ```
101
-
102
- \# **packToSolidityProof**(proof: _Proof_): _SolidityProof_
103
-
104
- ```typescript
105
- import { packToSolidityProof } from "@semaphore-protocol/proof"
106
-
107
- const solidityProof = packToSolidityProof(fullProof.proof)
108
- ```
109
-
110
- \# **generateNullifierHash**(externalNullifier: _BigNumberish_, identityNullifier: _BigNumberish_): _bigint_
111
-
112
- ```typescript
113
- import { generateNullifierHash } from "@semaphore-protocol/proof"
114
-
115
- const nullifierHash = generateNullifierHash(externalNullifier, identity.getNullifier())
116
- ```
117
-
118
- \# **generateSignalHash**(signal: _string_): _bigint_
119
-
120
- ```typescript
121
- import { generateSignalHash } from "@semaphore-protocol/proof"
122
-
123
- const signalHash = generateSignalHash(signal)
124
- ```
package/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * @module @semaphore-protocol/proof
3
- * @version 3.0.0-beta.6
3
+ * @version 3.0.0-beta.8
4
4
  * @file A library to generate and verify Semaphore proofs.
5
5
  * @copyright Ethereum Foundation 2022
6
6
  * @license MIT
7
7
  * @see [Github]{@link https://github.com/semaphore-protocol/semaphore/tree/main/packages/proof}
8
8
  */
9
- import { groth16 } from 'snarkjs';
10
9
  import { BigNumber } from '@ethersproject/bignumber';
10
+ import { groth16 } from 'snarkjs';
11
11
  import { zeroPad } from '@ethersproject/bytes';
12
12
  import { keccak256 } from '@ethersproject/keccak256';
13
13
 
@@ -86,6 +86,33 @@ function hash(message) {
86
86
  return BigInt(keccak256(message)) >> BigInt(8);
87
87
  }
88
88
 
89
+ /**
90
+ * Packs a proof into a format compatible with Semaphore.
91
+ * @param originalProof The proof generated with SnarkJS.
92
+ * @returns The proof compatible with Semaphore.
93
+ */
94
+ function packProof(originalProof) {
95
+ return [
96
+ originalProof.pi_a[0],
97
+ originalProof.pi_a[1],
98
+ originalProof.pi_b[0][1],
99
+ originalProof.pi_b[0][0],
100
+ originalProof.pi_b[1][1],
101
+ originalProof.pi_b[1][0],
102
+ originalProof.pi_c[0],
103
+ originalProof.pi_c[1]
104
+ ];
105
+ }
106
+
107
+ /**
108
+ * Generates a Semaphore proof.
109
+ * @param identity The Semaphore identity.
110
+ * @param groupOrMerkleProof The Semaphore group or its Merkle proof.
111
+ * @param externalNullifier The external nullifier.
112
+ * @param signal The Semaphore signal.
113
+ * @param snarkArtifacts The SNARK artifacts.
114
+ * @returns The Semaphore proof ready to be verified.
115
+ */
89
116
  function generateProof(_a, groupOrMerkleProof, externalNullifier, signal, snarkArtifacts) {
90
117
  var trapdoor = _a.trapdoor, nullifier = _a.nullifier, commitment = _a.commitment;
91
118
  return __awaiter(this, void 0, void 0, function () {
@@ -120,19 +147,35 @@ function generateProof(_a, groupOrMerkleProof, externalNullifier, signal, snarkA
120
147
  case 1:
121
148
  _b = _c.sent(), proof = _b.proof, publicSignals = _b.publicSignals;
122
149
  return [2 /*return*/, {
123
- proof: proof,
124
- publicSignals: {
125
- merkleTreeRoot: publicSignals[0],
126
- nullifierHash: publicSignals[1],
127
- signalHash: publicSignals[2],
128
- externalNullifier: publicSignals[3]
129
- }
150
+ merkleTreeRoot: publicSignals[0],
151
+ nullifierHash: publicSignals[1],
152
+ signal: BigNumber.from(signal).toString(),
153
+ externalNullifier: BigNumber.from(externalNullifier).toString(),
154
+ proof: packProof(proof)
130
155
  }];
131
156
  }
132
157
  });
133
158
  });
134
159
  }
135
160
 
161
+ /**
162
+ * Unpacks a proof into its original form.
163
+ * @param proof The proof compatible with Semaphore.
164
+ * @returns The proof compatible with SnarkJS.
165
+ */
166
+ function unpackProof(proof) {
167
+ return {
168
+ pi_a: [proof[0], proof[1]],
169
+ pi_b: [
170
+ [proof[3], proof[2]],
171
+ [proof[5], proof[4]]
172
+ ],
173
+ pi_c: [proof[6], proof[7]],
174
+ protocol: "groth16",
175
+ curve: "bn128"
176
+ };
177
+ }
178
+
136
179
  var protocol = "groth16";
137
180
  var curve = "bn128";
138
181
  var nPublic = 4;
@@ -913,41 +956,18 @@ var verificationKeys = {
913
956
  };
914
957
 
915
958
  /**
916
- * Verifies a SnarkJS proof.
917
- * @param fullProof The SnarkJS full proof.
959
+ * Verifies a Semaphore proof.
960
+ * @param fullProof The SnarkJS Semaphore proof.
918
961
  * @param treeDepth The Merkle tree depth.
919
962
  * @returns True if the proof is valid, false otherwise.
920
963
  */
921
964
  function verifyProof(_a, treeDepth) {
922
- var proof = _a.proof, publicSignals = _a.publicSignals;
965
+ var merkleTreeRoot = _a.merkleTreeRoot, nullifierHash = _a.nullifierHash, externalNullifier = _a.externalNullifier, signal = _a.signal, proof = _a.proof;
923
966
  if (treeDepth < 16 || treeDepth > 32) {
924
967
  throw new TypeError("The tree depth must be a number between 16 and 32");
925
968
  }
926
969
  var verificationKey = __assign(__assign({}, verificationKeys), { vk_delta_2: verificationKeys.vk_delta_2[treeDepth - 16], IC: verificationKeys.IC[treeDepth - 16] });
927
- return groth16.verify(verificationKey, [
928
- publicSignals.merkleTreeRoot,
929
- publicSignals.nullifierHash,
930
- publicSignals.signalHash,
931
- publicSignals.externalNullifier
932
- ], proof);
933
- }
934
-
935
- /**
936
- * Makes a proof compatible with the Verifier.sol method inputs.
937
- * @param proof The proof generated with SnarkJS.
938
- * @returns The Solidity compatible proof.
939
- */
940
- function packToSolidityProof(proof) {
941
- return [
942
- proof.pi_a[0],
943
- proof.pi_a[1],
944
- proof.pi_b[0][1],
945
- proof.pi_b[0][0],
946
- proof.pi_b[1][1],
947
- proof.pi_b[1][0],
948
- proof.pi_c[0],
949
- proof.pi_c[1]
950
- ];
970
+ return groth16.verify(verificationKey, [merkleTreeRoot, nullifierHash, hash(signal), hash(externalNullifier)], unpackProof(proof));
951
971
  }
952
972
 
953
- export { generateProof, packToSolidityProof, verifyProof };
973
+ export { generateProof, verifyProof };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @module @semaphore-protocol/proof
3
- * @version 3.0.0-beta.6
3
+ * @version 3.0.0-beta.8
4
4
  * @file A library to generate and verify Semaphore proofs.
5
5
  * @copyright Ethereum Foundation 2022
6
6
  * @license MIT
@@ -10,8 +10,8 @@
10
10
 
11
11
  Object.defineProperty(exports, '__esModule', { value: true });
12
12
 
13
- var snarkjs = require('snarkjs');
14
13
  var bignumber = require('@ethersproject/bignumber');
14
+ var snarkjs = require('snarkjs');
15
15
  var bytes = require('@ethersproject/bytes');
16
16
  var keccak256 = require('@ethersproject/keccak256');
17
17
 
@@ -90,6 +90,33 @@ function hash(message) {
90
90
  return BigInt(keccak256.keccak256(message)) >> BigInt(8);
91
91
  }
92
92
 
93
+ /**
94
+ * Packs a proof into a format compatible with Semaphore.
95
+ * @param originalProof The proof generated with SnarkJS.
96
+ * @returns The proof compatible with Semaphore.
97
+ */
98
+ function packProof(originalProof) {
99
+ return [
100
+ originalProof.pi_a[0],
101
+ originalProof.pi_a[1],
102
+ originalProof.pi_b[0][1],
103
+ originalProof.pi_b[0][0],
104
+ originalProof.pi_b[1][1],
105
+ originalProof.pi_b[1][0],
106
+ originalProof.pi_c[0],
107
+ originalProof.pi_c[1]
108
+ ];
109
+ }
110
+
111
+ /**
112
+ * Generates a Semaphore proof.
113
+ * @param identity The Semaphore identity.
114
+ * @param groupOrMerkleProof The Semaphore group or its Merkle proof.
115
+ * @param externalNullifier The external nullifier.
116
+ * @param signal The Semaphore signal.
117
+ * @param snarkArtifacts The SNARK artifacts.
118
+ * @returns The Semaphore proof ready to be verified.
119
+ */
93
120
  function generateProof(_a, groupOrMerkleProof, externalNullifier, signal, snarkArtifacts) {
94
121
  var trapdoor = _a.trapdoor, nullifier = _a.nullifier, commitment = _a.commitment;
95
122
  return __awaiter(this, void 0, void 0, function () {
@@ -124,19 +151,35 @@ function generateProof(_a, groupOrMerkleProof, externalNullifier, signal, snarkA
124
151
  case 1:
125
152
  _b = _c.sent(), proof = _b.proof, publicSignals = _b.publicSignals;
126
153
  return [2 /*return*/, {
127
- proof: proof,
128
- publicSignals: {
129
- merkleTreeRoot: publicSignals[0],
130
- nullifierHash: publicSignals[1],
131
- signalHash: publicSignals[2],
132
- externalNullifier: publicSignals[3]
133
- }
154
+ merkleTreeRoot: publicSignals[0],
155
+ nullifierHash: publicSignals[1],
156
+ signal: bignumber.BigNumber.from(signal).toString(),
157
+ externalNullifier: bignumber.BigNumber.from(externalNullifier).toString(),
158
+ proof: packProof(proof)
134
159
  }];
135
160
  }
136
161
  });
137
162
  });
138
163
  }
139
164
 
165
+ /**
166
+ * Unpacks a proof into its original form.
167
+ * @param proof The proof compatible with Semaphore.
168
+ * @returns The proof compatible with SnarkJS.
169
+ */
170
+ function unpackProof(proof) {
171
+ return {
172
+ pi_a: [proof[0], proof[1]],
173
+ pi_b: [
174
+ [proof[3], proof[2]],
175
+ [proof[5], proof[4]]
176
+ ],
177
+ pi_c: [proof[6], proof[7]],
178
+ protocol: "groth16",
179
+ curve: "bn128"
180
+ };
181
+ }
182
+
140
183
  var protocol = "groth16";
141
184
  var curve = "bn128";
142
185
  var nPublic = 4;
@@ -917,43 +960,19 @@ var verificationKeys = {
917
960
  };
918
961
 
919
962
  /**
920
- * Verifies a SnarkJS proof.
921
- * @param fullProof The SnarkJS full proof.
963
+ * Verifies a Semaphore proof.
964
+ * @param fullProof The SnarkJS Semaphore proof.
922
965
  * @param treeDepth The Merkle tree depth.
923
966
  * @returns True if the proof is valid, false otherwise.
924
967
  */
925
968
  function verifyProof(_a, treeDepth) {
926
- var proof = _a.proof, publicSignals = _a.publicSignals;
969
+ var merkleTreeRoot = _a.merkleTreeRoot, nullifierHash = _a.nullifierHash, externalNullifier = _a.externalNullifier, signal = _a.signal, proof = _a.proof;
927
970
  if (treeDepth < 16 || treeDepth > 32) {
928
971
  throw new TypeError("The tree depth must be a number between 16 and 32");
929
972
  }
930
973
  var verificationKey = __assign(__assign({}, verificationKeys), { vk_delta_2: verificationKeys.vk_delta_2[treeDepth - 16], IC: verificationKeys.IC[treeDepth - 16] });
931
- return snarkjs.groth16.verify(verificationKey, [
932
- publicSignals.merkleTreeRoot,
933
- publicSignals.nullifierHash,
934
- publicSignals.signalHash,
935
- publicSignals.externalNullifier
936
- ], proof);
937
- }
938
-
939
- /**
940
- * Makes a proof compatible with the Verifier.sol method inputs.
941
- * @param proof The proof generated with SnarkJS.
942
- * @returns The Solidity compatible proof.
943
- */
944
- function packToSolidityProof(proof) {
945
- return [
946
- proof.pi_a[0],
947
- proof.pi_a[1],
948
- proof.pi_b[0][1],
949
- proof.pi_b[0][0],
950
- proof.pi_b[1][1],
951
- proof.pi_b[1][0],
952
- proof.pi_c[0],
953
- proof.pi_c[1]
954
- ];
974
+ return snarkjs.groth16.verify(verificationKey, [merkleTreeRoot, nullifierHash, hash(signal), hash(externalNullifier)], unpackProof(proof));
955
975
  }
956
976
 
957
977
  exports.generateProof = generateProof;
958
- exports.packToSolidityProof = packToSolidityProof;
959
978
  exports.verifyProof = verifyProof;
@@ -3,4 +3,13 @@ import { Group } from "@semaphore-protocol/group";
3
3
  import type { Identity } from "@semaphore-protocol/identity";
4
4
  import { MerkleProof } from "@zk-kit/incremental-merkle-tree";
5
5
  import { FullProof, SnarkArtifacts } from "./types";
6
+ /**
7
+ * Generates a Semaphore proof.
8
+ * @param identity The Semaphore identity.
9
+ * @param groupOrMerkleProof The Semaphore group or its Merkle proof.
10
+ * @param externalNullifier The external nullifier.
11
+ * @param signal The Semaphore signal.
12
+ * @param snarkArtifacts The SNARK artifacts.
13
+ * @returns The Semaphore proof ready to be verified.
14
+ */
6
15
  export default function generateProof({ trapdoor, nullifier, commitment }: Identity, groupOrMerkleProof: Group | MerkleProof, externalNullifier: BytesLike | Hexable | number | bigint, signal: BytesLike | Hexable | number | bigint, snarkArtifacts?: SnarkArtifacts): Promise<FullProof>;
@@ -1,5 +1,4 @@
1
1
  import generateProof from "./generateProof";
2
2
  import verifyProof from "./verifyProof";
3
- import packToSolidityProof from "./packToSolidityProof";
4
- export { generateProof, verifyProof, packToSolidityProof };
3
+ export { generateProof, verifyProof };
5
4
  export * from "./types";
@@ -0,0 +1,7 @@
1
+ import { SnarkJSProof, Proof } from "./types";
2
+ /**
3
+ * Packs a proof into a format compatible with Semaphore.
4
+ * @param originalProof The proof generated with SnarkJS.
5
+ * @returns The proof compatible with Semaphore.
6
+ */
7
+ export default function packProof(originalProof: SnarkJSProof): Proof;
@@ -3,7 +3,7 @@ export type SnarkArtifacts = {
3
3
  wasmFilePath: string;
4
4
  zkeyFilePath: string;
5
5
  };
6
- export type Proof = {
6
+ export type SnarkJSProof = {
7
7
  pi_a: BigNumberish[];
8
8
  pi_b: BigNumberish[][];
9
9
  pi_c: BigNumberish[];
@@ -11,16 +11,13 @@ export type Proof = {
11
11
  curve: string;
12
12
  };
13
13
  export type FullProof = {
14
- proof: Proof;
15
- publicSignals: PublicSignals;
16
- };
17
- export type PublicSignals = {
18
14
  merkleTreeRoot: BigNumberish;
15
+ signal: BigNumberish;
19
16
  nullifierHash: BigNumberish;
20
- signalHash: BigNumberish;
21
17
  externalNullifier: BigNumberish;
18
+ proof: Proof;
22
19
  };
23
- export type SolidityProof = [
20
+ export type Proof = [
24
21
  BigNumberish,
25
22
  BigNumberish,
26
23
  BigNumberish,
@@ -0,0 +1,7 @@
1
+ import { SnarkJSProof, Proof } from "./types";
2
+ /**
3
+ * Unpacks a proof into its original form.
4
+ * @param proof The proof compatible with Semaphore.
5
+ * @returns The proof compatible with SnarkJS.
6
+ */
7
+ export default function unpackProof(proof: Proof): SnarkJSProof;
@@ -1,8 +1,8 @@
1
1
  import { FullProof } from "./types";
2
2
  /**
3
- * Verifies a SnarkJS proof.
4
- * @param fullProof The SnarkJS full proof.
3
+ * Verifies a Semaphore proof.
4
+ * @param fullProof The SnarkJS Semaphore proof.
5
5
  * @param treeDepth The Merkle tree depth.
6
6
  * @returns True if the proof is valid, false otherwise.
7
7
  */
8
- export default function verifyProof({ proof, publicSignals }: FullProof, treeDepth: number): Promise<boolean>;
8
+ export default function verifyProof({ merkleTreeRoot, nullifierHash, externalNullifier, signal, proof }: FullProof, treeDepth: number): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semaphore-protocol/proof",
3
- "version": "3.0.0-beta.6",
3
+ "version": "3.0.0-beta.8",
4
4
  "description": "A library to generate and verify Semaphore proofs.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.node.js",
@@ -37,8 +37,8 @@
37
37
  "typedoc": "^0.22.11"
38
38
  },
39
39
  "peerDependencies": {
40
- "@semaphore-protocol/group": "3.0.0-beta.6",
41
- "@semaphore-protocol/identity": "3.0.0-beta.6"
40
+ "@semaphore-protocol/group": "3.0.0-beta.8",
41
+ "@semaphore-protocol/identity": "3.0.0-beta.8"
42
42
  },
43
43
  "dependencies": {
44
44
  "@ethersproject/bignumber": "^5.5.0",
@@ -46,6 +46,6 @@
46
46
  "@ethersproject/keccak256": "^5.7.0",
47
47
  "@ethersproject/strings": "^5.5.0",
48
48
  "@zk-kit/incremental-merkle-tree": "0.4.3",
49
- "snarkjs": "^0.4.13"
49
+ "snarkjs": "0.4.13"
50
50
  }
51
51
  }
@@ -1,11 +1,22 @@
1
+ import { BigNumber } from "@ethersproject/bignumber"
1
2
  import { BytesLike, Hexable } from "@ethersproject/bytes"
2
3
  import { Group } from "@semaphore-protocol/group"
3
4
  import type { Identity } from "@semaphore-protocol/identity"
4
5
  import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
5
6
  import { groth16 } from "snarkjs"
6
7
  import hash from "./hash"
8
+ import packProof from "./packProof"
7
9
  import { FullProof, SnarkArtifacts } from "./types"
8
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 externalNullifier The external nullifier.
16
+ * @param signal The Semaphore signal.
17
+ * @param snarkArtifacts The SNARK artifacts.
18
+ * @returns The Semaphore proof ready to be verified.
19
+ */
9
20
  export default async function generateProof(
10
21
  { trapdoor, nullifier, commitment }: Identity,
11
22
  groupOrMerkleProof: Group | MerkleProof,
@@ -48,12 +59,10 @@ export default async function generateProof(
48
59
  )
49
60
 
50
61
  return {
51
- proof,
52
- publicSignals: {
53
- merkleTreeRoot: publicSignals[0],
54
- nullifierHash: publicSignals[1],
55
- signalHash: publicSignals[2],
56
- externalNullifier: publicSignals[3]
57
- }
62
+ merkleTreeRoot: publicSignals[0],
63
+ nullifierHash: publicSignals[1],
64
+ signal: BigNumber.from(signal).toString(),
65
+ externalNullifier: BigNumber.from(externalNullifier).toString(),
66
+ proof: packProof(proof)
58
67
  }
59
68
  }
package/src/index.test.ts CHANGED
@@ -1,17 +1,19 @@
1
+ import { formatBytes32String } from "@ethersproject/strings"
1
2
  import { Group } from "@semaphore-protocol/group"
2
3
  import { Identity } from "@semaphore-protocol/identity"
3
4
  import { getCurveFromName } from "ffjavascript"
4
5
  import generateProof from "./generateProof"
5
6
  import hash from "./hash"
6
- import packToSolidityProof from "./packToSolidityProof"
7
+ import packProof from "./packProof"
7
8
  import { FullProof } from "./types"
9
+ import unpackProof from "./unpackProof"
8
10
  import verifyProof from "./verifyProof"
9
11
 
10
12
  describe("Proof", () => {
11
13
  const treeDepth = Number(process.env.TREE_DEPTH) || 20
12
14
 
13
- const externalNullifier = 1
14
- const signal = 2
15
+ const externalNullifier = formatBytes32String("Topic")
16
+ const signal = formatBytes32String("Hello world")
15
17
 
16
18
  const wasmFilePath = `./snark-artifacts/${treeDepth}/semaphore.wasm`
17
19
  const zkeyFilePath = `./snark-artifacts/${treeDepth}/semaphore.zkey`
@@ -65,7 +67,7 @@ describe("Proof", () => {
65
67
  })
66
68
 
67
69
  expect(typeof fullProof).toBe("object")
68
- expect(fullProof.publicSignals.merkleTreeRoot).toBe(group.root.toString())
70
+ expect(fullProof.merkleTreeRoot).toBe(group.root.toString())
69
71
  }, 20000)
70
72
 
71
73
  it("Should generate a Semaphore proof passing a Merkle proof as parameter", async () => {
@@ -79,7 +81,7 @@ describe("Proof", () => {
79
81
  })
80
82
 
81
83
  expect(typeof fullProof).toBe("object")
82
- expect(fullProof.publicSignals.merkleTreeRoot).toBe(group.root.toString())
84
+ expect(fullProof.merkleTreeRoot).toBe(group.root.toString())
83
85
  }, 20000)
84
86
  })
85
87
 
@@ -101,13 +103,17 @@ describe("Proof", () => {
101
103
  it("Should hash the signal value correctly", async () => {
102
104
  const signalHash = hash(signal)
103
105
 
104
- expect(signalHash.toString()).toBe(fullProof.publicSignals.signalHash)
106
+ expect(signalHash.toString()).toBe(
107
+ "8665846418922331996225934941481656421248110469944536651334918563951783029"
108
+ )
105
109
  })
106
110
 
107
111
  it("Should hash the external nullifier value correctly", async () => {
108
112
  const externalNullifierHash = hash(externalNullifier)
109
113
 
110
- expect(externalNullifierHash.toString()).toBe(fullProof.publicSignals.externalNullifier)
114
+ expect(externalNullifierHash.toString()).toBe(
115
+ "244178201824278269437519042830883072613014992408751798420801126401127326826"
116
+ )
111
117
  })
112
118
 
113
119
  it("Should hash a number", async () => {
@@ -141,11 +147,12 @@ describe("Proof", () => {
141
147
  })
142
148
  })
143
149
 
144
- describe("# packToSolidityProof", () => {
145
- it("Should return a Solidity proof", async () => {
146
- const solidityProof = packToSolidityProof(fullProof.proof)
150
+ describe("# packProof/unpackProof", () => {
151
+ it("Should return a packed proof", async () => {
152
+ const originalProof = unpackProof(fullProof.proof)
153
+ const proof = packProof(originalProof)
147
154
 
148
- expect(solidityProof).toHaveLength(8)
155
+ expect(proof).toStrictEqual(fullProof.proof)
149
156
  })
150
157
  })
151
158
  })
package/src/index.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import generateProof from "./generateProof"
2
2
  import verifyProof from "./verifyProof"
3
- import packToSolidityProof from "./packToSolidityProof"
4
3
 
5
- export { generateProof, verifyProof, packToSolidityProof }
4
+ export { generateProof, verifyProof }
6
5
  export * from "./types"
@@ -0,0 +1,19 @@
1
+ import { SnarkJSProof, Proof } from "./types"
2
+
3
+ /**
4
+ * Packs a proof into a format compatible with Semaphore.
5
+ * @param originalProof The proof generated with SnarkJS.
6
+ * @returns The proof compatible with Semaphore.
7
+ */
8
+ export default function packProof(originalProof: SnarkJSProof): Proof {
9
+ return [
10
+ originalProof.pi_a[0],
11
+ originalProof.pi_a[1],
12
+ originalProof.pi_b[0][1],
13
+ originalProof.pi_b[0][0],
14
+ originalProof.pi_b[1][1],
15
+ originalProof.pi_b[1][0],
16
+ originalProof.pi_c[0],
17
+ originalProof.pi_c[1]
18
+ ]
19
+ }
@@ -5,7 +5,7 @@ export type SnarkArtifacts = {
5
5
  zkeyFilePath: string
6
6
  }
7
7
 
8
- export type Proof = {
8
+ export type SnarkJSProof = {
9
9
  pi_a: BigNumberish[]
10
10
  pi_b: BigNumberish[][]
11
11
  pi_c: BigNumberish[]
@@ -14,18 +14,14 @@ export type Proof = {
14
14
  }
15
15
 
16
16
  export type FullProof = {
17
- proof: Proof
18
- publicSignals: PublicSignals
19
- }
20
-
21
- export type PublicSignals = {
22
17
  merkleTreeRoot: BigNumberish
18
+ signal: BigNumberish
23
19
  nullifierHash: BigNumberish
24
- signalHash: BigNumberish
25
20
  externalNullifier: BigNumberish
21
+ proof: Proof
26
22
  }
27
23
 
28
- export type SolidityProof = [
24
+ export type Proof = [
29
25
  BigNumberish,
30
26
  BigNumberish,
31
27
  BigNumberish,
@@ -0,0 +1,19 @@
1
+ import { SnarkJSProof, Proof } from "./types"
2
+
3
+ /**
4
+ * Unpacks a proof into its original form.
5
+ * @param proof The proof compatible with Semaphore.
6
+ * @returns The proof compatible with SnarkJS.
7
+ */
8
+ export default function unpackProof(proof: Proof): SnarkJSProof {
9
+ return {
10
+ pi_a: [proof[0], proof[1]],
11
+ pi_b: [
12
+ [proof[3], proof[2]],
13
+ [proof[5], proof[4]]
14
+ ],
15
+ pi_c: [proof[6], proof[7]],
16
+ protocol: "groth16",
17
+ curve: "bn128"
18
+ }
19
+ }
@@ -1,14 +1,19 @@
1
1
  import { groth16 } from "snarkjs"
2
+ import hash from "./hash"
2
3
  import { FullProof } from "./types"
4
+ import unpackProof from "./unpackProof"
3
5
  import verificationKeys from "./verificationKeys.json"
4
6
 
5
7
  /**
6
- * Verifies a SnarkJS proof.
7
- * @param fullProof The SnarkJS full proof.
8
+ * Verifies a Semaphore proof.
9
+ * @param fullProof The SnarkJS Semaphore proof.
8
10
  * @param treeDepth The Merkle tree depth.
9
11
  * @returns True if the proof is valid, false otherwise.
10
12
  */
11
- export default function verifyProof({ proof, publicSignals }: FullProof, treeDepth: number): Promise<boolean> {
13
+ export default function verifyProof(
14
+ { merkleTreeRoot, nullifierHash, externalNullifier, signal, proof }: FullProof,
15
+ treeDepth: number
16
+ ): Promise<boolean> {
12
17
  if (treeDepth < 16 || treeDepth > 32) {
13
18
  throw new TypeError("The tree depth must be a number between 16 and 32")
14
19
  }
@@ -21,12 +26,7 @@ export default function verifyProof({ proof, publicSignals }: FullProof, treeDep
21
26
 
22
27
  return groth16.verify(
23
28
  verificationKey,
24
- [
25
- publicSignals.merkleTreeRoot,
26
- publicSignals.nullifierHash,
27
- publicSignals.signalHash,
28
- publicSignals.externalNullifier
29
- ],
30
- proof
29
+ [merkleTreeRoot, nullifierHash, hash(signal), hash(externalNullifier)],
30
+ unpackProof(proof)
31
31
  )
32
32
  }
@@ -1,7 +0,0 @@
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,19 +0,0 @@
1
- import { Proof, SolidityProof } from "./types"
2
-
3
- /**
4
- * Makes a proof compatible with the Verifier.sol method inputs.
5
- * @param proof The proof generated with SnarkJS.
6
- * @returns The Solidity compatible proof.
7
- */
8
- export default function packToSolidityProof(proof: Proof): SolidityProof {
9
- return [
10
- proof.pi_a[0],
11
- proof.pi_a[1],
12
- proof.pi_b[0][1],
13
- proof.pi_b[0][0],
14
- proof.pi_b[1][1],
15
- proof.pi_b[1][0],
16
- proof.pi_c[0],
17
- proof.pi_c[1]
18
- ]
19
- }