@semaphore-protocol/identity 3.0.0 → 3.2.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.
package/README.md CHANGED
@@ -40,7 +40,7 @@
40
40
  🔎 Issues
41
41
  </a>
42
42
  <span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>
43
- <a href="https://discord.gg/6mSdGHnstH">
43
+ <a href="https://semaphore.appliedzkp.org/discord">
44
44
  🗣️ Chat &amp; Support
45
45
  </a>
46
46
  </h4>
package/dist/index.mjs CHANGED
@@ -1,16 +1,16 @@
1
1
  /**
2
2
  * @module @semaphore-protocol/identity
3
- * @version 3.0.0
3
+ * @version 3.2.0
4
4
  * @file A library to create Semaphore identities.
5
5
  * @copyright Ethereum Foundation 2022
6
6
  * @license MIT
7
7
  * @see [Github]{@link https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity}
8
8
  */
9
9
  import { BigNumber } from '@ethersproject/bignumber';
10
- import { keccak256 } from '@ethersproject/keccak256';
11
- import { toUtf8Bytes } from '@ethersproject/strings';
10
+ import hash from 'js-sha512';
12
11
  import { randomBytes } from '@ethersproject/random';
13
- import poseidon from 'poseidon-lite';
12
+ import { poseidon1 } from 'poseidon-lite/poseidon1';
13
+ import { poseidon2 } from 'poseidon-lite/poseidon2';
14
14
 
15
15
  function checkParameter(value, name, type) {
16
16
  if (typeof value !== type) {
@@ -18,15 +18,6 @@ function checkParameter(value, name, type) {
18
18
  }
19
19
  }
20
20
 
21
- /**
22
- * Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
23
- * @param message The message to be hashed.
24
- * @returns The message digest.
25
- */
26
- function hash(message) {
27
- return BigInt(keccak256(toUtf8Bytes(message))) >> BigInt(8);
28
- }
29
-
30
21
  /**
31
22
  * Generates a random big number.
32
23
  * @param numberOfBytes The number of bytes of the number.
@@ -43,7 +34,7 @@ function genRandomNumber(numberOfBytes) {
43
34
  * @returns identity commitment
44
35
  */
45
36
  function generateCommitment(nullifier, trapdoor) {
46
- return poseidon([poseidon([nullifier, trapdoor])]);
37
+ return poseidon1([poseidon2([nullifier, trapdoor])]);
47
38
  }
48
39
  /**
49
40
  * Checks if a string is a JSON.
@@ -73,15 +64,16 @@ var Identity = /** @class */ (function () {
73
64
  }
74
65
  checkParameter(identityOrMessage, "identityOrMessage", "string");
75
66
  if (!isJsonArray(identityOrMessage)) {
76
- var messageHash = hash(identityOrMessage);
77
- this._trapdoor = hash("".concat(messageHash, "identity_trapdoor"));
78
- this._nullifier = hash("".concat(messageHash, "identity_nullifier"));
67
+ var h = hash.sha512(identityOrMessage).padStart(128, "0");
68
+ // alt_bn128 is 253.6 bits, so we can safely use 253 bits
69
+ this._trapdoor = BigInt("0x".concat(h.slice(64))) >> BigInt(3);
70
+ this._nullifier = BigInt("0x".concat(h.slice(0, 64))) >> BigInt(3);
79
71
  this._commitment = generateCommitment(this._nullifier, this._trapdoor);
80
72
  return;
81
73
  }
82
74
  var _a = JSON.parse(identityOrMessage), trapdoor = _a[0], nullifier = _a[1];
83
- this._trapdoor = BigNumber.from("0x".concat(trapdoor)).toBigInt();
84
- this._nullifier = BigNumber.from("0x".concat(nullifier)).toBigInt();
75
+ this._trapdoor = BigNumber.from(trapdoor).toBigInt();
76
+ this._nullifier = BigNumber.from(nullifier).toBigInt();
85
77
  this._commitment = generateCommitment(this._nullifier, this._trapdoor);
86
78
  }
87
79
  Object.defineProperty(Identity.prototype, "trapdoor", {
@@ -144,7 +136,7 @@ var Identity = /** @class */ (function () {
144
136
  * @returns The string representation of the identity.
145
137
  */
146
138
  Identity.prototype.toString = function () {
147
- return JSON.stringify([this._trapdoor.toString(16), this._nullifier.toString(16)]);
139
+ return JSON.stringify(["0x".concat(this._trapdoor.toString(16)), "0x".concat(this._nullifier.toString(16))]);
148
140
  };
149
141
  return Identity;
150
142
  }());
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @module @semaphore-protocol/identity
3
- * @version 3.0.0
3
+ * @version 3.2.0
4
4
  * @file A library to create Semaphore identities.
5
5
  * @copyright Ethereum Foundation 2022
6
6
  * @license MIT
@@ -11,14 +11,14 @@
11
11
  Object.defineProperty(exports, '__esModule', { value: true });
12
12
 
13
13
  var bignumber = require('@ethersproject/bignumber');
14
- var keccak256 = require('@ethersproject/keccak256');
15
- var strings = require('@ethersproject/strings');
14
+ var hash = require('js-sha512');
16
15
  var random = require('@ethersproject/random');
17
- var poseidon = require('poseidon-lite');
16
+ var poseidon1 = require('poseidon-lite/poseidon1');
17
+ var poseidon2 = require('poseidon-lite/poseidon2');
18
18
 
19
19
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
20
20
 
21
- var poseidon__default = /*#__PURE__*/_interopDefaultLegacy(poseidon);
21
+ var hash__default = /*#__PURE__*/_interopDefaultLegacy(hash);
22
22
 
23
23
  function checkParameter(value, name, type) {
24
24
  if (typeof value !== type) {
@@ -26,15 +26,6 @@ function checkParameter(value, name, type) {
26
26
  }
27
27
  }
28
28
 
29
- /**
30
- * Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
31
- * @param message The message to be hashed.
32
- * @returns The message digest.
33
- */
34
- function hash(message) {
35
- return BigInt(keccak256.keccak256(strings.toUtf8Bytes(message))) >> BigInt(8);
36
- }
37
-
38
29
  /**
39
30
  * Generates a random big number.
40
31
  * @param numberOfBytes The number of bytes of the number.
@@ -51,7 +42,7 @@ function genRandomNumber(numberOfBytes) {
51
42
  * @returns identity commitment
52
43
  */
53
44
  function generateCommitment(nullifier, trapdoor) {
54
- return poseidon__default["default"]([poseidon__default["default"]([nullifier, trapdoor])]);
45
+ return poseidon1.poseidon1([poseidon2.poseidon2([nullifier, trapdoor])]);
55
46
  }
56
47
  /**
57
48
  * Checks if a string is a JSON.
@@ -81,15 +72,16 @@ var Identity = /** @class */ (function () {
81
72
  }
82
73
  checkParameter(identityOrMessage, "identityOrMessage", "string");
83
74
  if (!isJsonArray(identityOrMessage)) {
84
- var messageHash = hash(identityOrMessage);
85
- this._trapdoor = hash("".concat(messageHash, "identity_trapdoor"));
86
- this._nullifier = hash("".concat(messageHash, "identity_nullifier"));
75
+ var h = hash__default["default"].sha512(identityOrMessage).padStart(128, "0");
76
+ // alt_bn128 is 253.6 bits, so we can safely use 253 bits
77
+ this._trapdoor = BigInt("0x".concat(h.slice(64))) >> BigInt(3);
78
+ this._nullifier = BigInt("0x".concat(h.slice(0, 64))) >> BigInt(3);
87
79
  this._commitment = generateCommitment(this._nullifier, this._trapdoor);
88
80
  return;
89
81
  }
90
82
  var _a = JSON.parse(identityOrMessage), trapdoor = _a[0], nullifier = _a[1];
91
- this._trapdoor = bignumber.BigNumber.from("0x".concat(trapdoor)).toBigInt();
92
- this._nullifier = bignumber.BigNumber.from("0x".concat(nullifier)).toBigInt();
83
+ this._trapdoor = bignumber.BigNumber.from(trapdoor).toBigInt();
84
+ this._nullifier = bignumber.BigNumber.from(nullifier).toBigInt();
93
85
  this._commitment = generateCommitment(this._nullifier, this._trapdoor);
94
86
  }
95
87
  Object.defineProperty(Identity.prototype, "trapdoor", {
@@ -152,7 +144,7 @@ var Identity = /** @class */ (function () {
152
144
  * @returns The string representation of the identity.
153
145
  */
154
146
  Identity.prototype.toString = function () {
155
- return JSON.stringify([this._trapdoor.toString(16), this._nullifier.toString(16)]);
147
+ return JSON.stringify(["0x".concat(this._trapdoor.toString(16)), "0x".concat(this._nullifier.toString(16))]);
156
148
  };
157
149
  return Identity;
158
150
  }());
package/package.json CHANGED
@@ -1,44 +1,45 @@
1
1
  {
2
- "name": "@semaphore-protocol/identity",
3
- "version": "3.0.0",
4
- "description": "A library to create Semaphore identities.",
5
- "license": "MIT",
6
- "main": "dist/index.node.js",
7
- "exports": {
8
- "import": "./dist/index.mjs",
9
- "require": "./dist/index.node.js"
10
- },
11
- "types": "dist/types/index.d.ts",
12
- "files": [
13
- "dist/",
14
- "src/",
15
- "LICENSE",
16
- "README.md"
17
- ],
18
- "repository": "https://github.com/semaphore-protocol/semaphore",
19
- "homepage": "https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity",
20
- "bugs": {
21
- "url": "https://github.com/semaphore-protocol/semaphore.git/issues"
22
- },
23
- "scripts": {
24
- "build:watch": "rollup -c rollup.config.ts -w --configPlugin typescript",
25
- "build": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript",
26
- "prepublishOnly": "yarn build",
27
- "docs": "typedoc src/index.ts --out ../../docs/identity"
28
- },
29
- "publishConfig": {
30
- "access": "public"
31
- },
32
- "devDependencies": {
33
- "rollup-plugin-cleanup": "^3.2.1",
34
- "rollup-plugin-typescript2": "^0.31.2",
35
- "typedoc": "^0.22.11"
36
- },
37
- "dependencies": {
38
- "@ethersproject/bignumber": "^5.5.0",
39
- "@ethersproject/keccak256": "^5.7.0",
40
- "@ethersproject/random": "^5.5.1",
41
- "@ethersproject/strings": "^5.6.1",
42
- "poseidon-lite": "0.0.2"
43
- }
44
- }
2
+ "name": "@semaphore-protocol/identity",
3
+ "version": "3.2.0",
4
+ "description": "A library to create Semaphore identities.",
5
+ "license": "MIT",
6
+ "main": "dist/index.node.js",
7
+ "exports": {
8
+ "import": "./dist/index.mjs",
9
+ "require": "./dist/index.node.js"
10
+ },
11
+ "types": "dist/types/index.d.ts",
12
+ "files": [
13
+ "dist/",
14
+ "src/",
15
+ "LICENSE",
16
+ "README.md"
17
+ ],
18
+ "repository": "https://github.com/semaphore-protocol/semaphore",
19
+ "homepage": "https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity",
20
+ "bugs": {
21
+ "url": "https://github.com/semaphore-protocol/semaphore.git/issues"
22
+ },
23
+ "scripts": {
24
+ "build:watch": "rollup -c rollup.config.ts -w --configPlugin typescript",
25
+ "build": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript",
26
+ "prepublishOnly": "yarn build",
27
+ "docs": "typedoc src/index.ts --out ../../docs/identity"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "devDependencies": {
33
+ "rollup-plugin-cleanup": "^3.2.1",
34
+ "rollup-plugin-typescript2": "^0.31.2",
35
+ "typedoc": "^0.22.11"
36
+ },
37
+ "dependencies": {
38
+ "@ethersproject/bignumber": "^5.5.0",
39
+ "@ethersproject/keccak256": "^5.7.0",
40
+ "@ethersproject/random": "^5.5.1",
41
+ "@ethersproject/strings": "^5.6.1",
42
+ "js-sha512": "^0.8.0",
43
+ "poseidon-lite": "^0.1.0"
44
+ }
45
+ }
@@ -45,7 +45,7 @@ describe("Identity", () => {
45
45
  it("Should not recreate an existing invalid identity", () => {
46
46
  const fun = () => new Identity('[true, "01323"]')
47
47
 
48
- expect(fun).toThrow("invalid BigNumber string")
48
+ expect(fun).toThrow("invalid BigNumber value")
49
49
  })
50
50
 
51
51
  it("Should recreate an existing identity", () => {
@@ -64,7 +64,9 @@ describe("Identity", () => {
64
64
 
65
65
  const trapdoor = identity.getTrapdoor()
66
66
 
67
- expect(trapdoor).toBe(BigInt("211007102311354422986775462856672883657031335757695461477990303178796954863"))
67
+ expect(trapdoor.toString()).toBe(
68
+ "11566083507498623434013707198824105161167204201250008419741119866456392774309"
69
+ )
68
70
  })
69
71
  })
70
72
 
@@ -74,7 +76,9 @@ describe("Identity", () => {
74
76
 
75
77
  const nullifier = identity.getNullifier()
76
78
 
77
- expect(nullifier).toBe(BigInt("10282208199720122340759039255952223220417076359839127631923809108800013776"))
79
+ expect(nullifier.toString()).toBe(
80
+ "14070056666392584007908120012103355272369511035580155843212703537125048345255"
81
+ )
78
82
  })
79
83
  })
80
84
 
@@ -82,8 +86,8 @@ describe("Identity", () => {
82
86
  it("Should generate an identity commitment", () => {
83
87
  const { commitment } = new Identity("message")
84
88
 
85
- expect(commitment).toBe(
86
- BigInt("13192222509545780880434144549342414064490325100975031303723930089730328393905")
89
+ expect(commitment.toString()).toBe(
90
+ "19361462367798001240039467285882167157718016385695743307694056771074972404368"
87
91
  )
88
92
  })
89
93
  })
@@ -102,8 +106,8 @@ describe("Identity", () => {
102
106
 
103
107
  const [trapdoor, nullifier] = JSON.parse(identity.toString())
104
108
 
105
- expect(BigNumber.from(`0x${trapdoor}`).toBigInt()).toBe(identity.trapdoor)
106
- expect(BigNumber.from(`0x${nullifier}`).toBigInt()).toBe(identity.nullifier)
109
+ expect(BigNumber.from(trapdoor).toBigInt()).toBe(identity.trapdoor)
110
+ expect(BigNumber.from(nullifier).toBigInt()).toBe(identity.nullifier)
107
111
  })
108
112
  })
109
113
  })
package/src/identity.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BigNumber } from "@ethersproject/bignumber"
2
+ import hash from "js-sha512"
2
3
  import checkParameter from "./checkParameter"
3
- import hash from "./hash"
4
4
  import { generateCommitment, genRandomNumber, isJsonArray } from "./utils"
5
5
 
6
6
  export default class Identity {
@@ -24,10 +24,10 @@ export default class Identity {
24
24
  checkParameter(identityOrMessage, "identityOrMessage", "string")
25
25
 
26
26
  if (!isJsonArray(identityOrMessage)) {
27
- const messageHash = hash(identityOrMessage)
28
-
29
- this._trapdoor = hash(`${messageHash}identity_trapdoor`)
30
- this._nullifier = hash(`${messageHash}identity_nullifier`)
27
+ const h = hash.sha512(identityOrMessage).padStart(128, "0")
28
+ // alt_bn128 is 253.6 bits, so we can safely use 253 bits
29
+ this._trapdoor = BigInt(`0x${h.slice(64)}`) >> BigInt(3)
30
+ this._nullifier = BigInt(`0x${h.slice(0, 64)}`) >> BigInt(3)
31
31
  this._commitment = generateCommitment(this._nullifier, this._trapdoor)
32
32
 
33
33
  return
@@ -35,8 +35,8 @@ export default class Identity {
35
35
 
36
36
  const [trapdoor, nullifier] = JSON.parse(identityOrMessage)
37
37
 
38
- this._trapdoor = BigNumber.from(`0x${trapdoor}`).toBigInt()
39
- this._nullifier = BigNumber.from(`0x${nullifier}`).toBigInt()
38
+ this._trapdoor = BigNumber.from(trapdoor).toBigInt()
39
+ this._nullifier = BigNumber.from(nullifier).toBigInt()
40
40
  this._commitment = generateCommitment(this._nullifier, this._trapdoor)
41
41
  }
42
42
 
@@ -94,6 +94,6 @@ export default class Identity {
94
94
  * @returns The string representation of the identity.
95
95
  */
96
96
  public toString(): string {
97
- return JSON.stringify([this._trapdoor.toString(16), this._nullifier.toString(16)])
97
+ return JSON.stringify([`0x${this._trapdoor.toString(16)}`, `0x${this._nullifier.toString(16)}`])
98
98
  }
99
99
  }
package/src/utils.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { BigNumber } from "@ethersproject/bignumber"
2
2
  import { randomBytes } from "@ethersproject/random"
3
- import poseidon from "poseidon-lite"
3
+ import { poseidon1 } from "poseidon-lite/poseidon1"
4
+ import { poseidon2 } from "poseidon-lite/poseidon2"
4
5
 
5
6
  /**
6
7
  * Generates a random big number.
@@ -18,7 +19,7 @@ export function genRandomNumber(numberOfBytes = 31): bigint {
18
19
  * @returns identity commitment
19
20
  */
20
21
  export function generateCommitment(nullifier: bigint, trapdoor: bigint): bigint {
21
- return poseidon([poseidon([nullifier, trapdoor])])
22
+ return poseidon1([poseidon2([nullifier, trapdoor])])
22
23
  }
23
24
 
24
25
  /**
@@ -1,6 +0,0 @@
1
- /**
2
- * Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
3
- * @param message The message to be hashed.
4
- * @returns The message digest.
5
- */
6
- export default function hash(message: string): bigint;
package/src/hash.ts DELETED
@@ -1,11 +0,0 @@
1
- import { keccak256 } from "@ethersproject/keccak256"
2
- import { toUtf8Bytes } from "@ethersproject/strings"
3
-
4
- /**
5
- * Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
6
- * @param message The message to be hashed.
7
- * @returns The message digest.
8
- */
9
- export default function hash(message: string): bigint {
10
- return BigInt(keccak256(toUtf8Bytes(message))) >> BigInt(8)
11
- }