@semaphore-protocol/identity 3.1.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 +1 -1
- package/dist/index.mjs +12 -20
- package/dist/index.node.js +13 -21
- package/package.json +44 -43
- package/src/identity.test.ts +11 -7
- package/src/identity.ts +8 -8
- package/src/utils.ts +3 -2
- package/dist/types/hash.d.ts +0 -6
- package/src/hash.ts +0 -11
package/README.md
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/identity
|
|
3
|
-
* @version 3.
|
|
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
|
|
11
|
-
import { toUtf8Bytes } from '@ethersproject/strings';
|
|
10
|
+
import hash from 'js-sha512';
|
|
12
11
|
import { randomBytes } from '@ethersproject/random';
|
|
13
|
-
import
|
|
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
|
|
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
|
|
77
|
-
|
|
78
|
-
this.
|
|
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(
|
|
84
|
-
this._nullifier = BigNumber.from(
|
|
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
|
}());
|
package/dist/index.node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @semaphore-protocol/identity
|
|
3
|
-
* @version 3.
|
|
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
|
|
15
|
-
var strings = require('@ethersproject/strings');
|
|
14
|
+
var hash = require('js-sha512');
|
|
16
15
|
var random = require('@ethersproject/random');
|
|
17
|
-
var
|
|
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
|
|
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
|
|
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
|
|
85
|
-
|
|
86
|
-
this.
|
|
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(
|
|
92
|
-
this._nullifier = bignumber.BigNumber.from(
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
+
}
|
package/src/identity.test.ts
CHANGED
|
@@ -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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
106
|
-
expect(BigNumber.from(
|
|
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
|
|
28
|
-
|
|
29
|
-
this._trapdoor =
|
|
30
|
-
this._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(
|
|
39
|
-
this._nullifier = BigNumber.from(
|
|
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)
|
|
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
|
|
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
|
|
22
|
+
return poseidon1([poseidon2([nullifier, trapdoor])])
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
/**
|
package/dist/types/hash.d.ts
DELETED
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
|
-
}
|