Skip to content

Commit fee7f10

Browse files
committed
feat(identity): update identity with eddsa
1 parent 267a250 commit fee7f10

File tree

7 files changed

+136
-243
lines changed

7 files changed

+136
-243
lines changed

packages/identity/README.md

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,51 @@ yarn add @semaphore-protocol/identity
7070

7171
## 📜 Usage
7272

73-
\# **new Identity**(identityOrMessage?: _string_): _Identity_
73+
\# **new Identity**(privateKey?: _BigNumberish_): _Identity_
7474

7575
```typescript
7676
import { Identity } from "@semaphore-protocol/identity"
7777

78-
// The identity can be generated randomly.
79-
const identity1 = new Identity()
78+
// The identity will be generated randomly.
79+
const { privateKey, publicKey } = new Identity()
8080

81-
// Deterministically from a secret message.
82-
const identity2 = new Identity("secret-message")
81+
// Alternatively, you can pass your private key.
82+
const identity = new Identity("your-private-key")
83+
```
84+
85+
\# **identity.signMessage**(message: _BigNumberish_): _Signature\<string>_
86+
87+
```typescript
88+
import { Identity } from "@semaphore-protocol/identity"
89+
90+
const message = "message"
91+
const identity = new Identity()
92+
93+
const signature = identity.signMessage(message)
94+
```
95+
96+
\# **identity.verifySignature**(message: _BigNumberish_, signature: _Signature_): _boolean_
97+
98+
```typescript
99+
import { Identity } from "@semaphore-protocol/identity"
100+
101+
const message = "message"
102+
const identity = new Identity()
103+
104+
const signature = identity.signMessage(message)
105+
106+
identity.verifySignature(message, signature)
107+
```
108+
109+
\# **Identity.verifySignature**(message: _BigNumberish_, signature: _Signature_, publicKey: _BigNumber_ | _Point_): _boolean_
110+
111+
```typescript
112+
import { Identity } from "@semaphore-protocol/identity"
113+
114+
const message = "message"
115+
const identity = new Identity()
83116

84-
// Or it can be retrieved from an existing identity.
85-
const identity3 = new Identity(identity1.toString())
117+
const signature = identity.signMessage("message", signature)
86118

87-
// Trapdoor, nullifier and commitment are the attributes (e.g. JS getters).
88-
const { trapdoor, nullifier, commitment } = identity1
119+
Identity.verifySignature(message, signature, identity.publicKey)
89120
```

packages/identity/package.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,10 @@
3232
"devDependencies": {
3333
"@rollup/plugin-commonjs": "^24.0.1",
3434
"@rollup/plugin-node-resolve": "^15.0.1",
35-
"poseidon-lite": "^0.2.0",
3635
"rollup-plugin-cleanup": "^3.2.1",
3736
"rollup-plugin-typescript2": "^0.31.2"
3837
},
3938
"dependencies": {
40-
"@ethersproject/bignumber": "^5.5.0",
41-
"@ethersproject/keccak256": "^5.7.0",
42-
"@ethersproject/random": "^5.5.1",
43-
"@ethersproject/strings": "^5.6.1",
44-
"js-sha512": "^0.8.0"
39+
"@zk-kit/eddsa-poseidon": "0.4.1"
4540
}
4641
}

packages/identity/src/checkParameter.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 36 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,65 @@
1-
import { BigNumber } from "@ethersproject/bignumber"
21
import Identity from "./identity"
32

43
describe("Identity", () => {
5-
describe("# Identity", () => {
6-
it("Should not create a identity if the parameter is not valid", () => {
7-
const fun1 = () => new Identity(13 as any)
8-
const fun2 = () => new Identity(true as any)
9-
const fun3 = () => new Identity((() => true) as any)
10-
11-
expect(fun1).toThrow("Parameter 'identityOrMessage' is not a string")
12-
expect(fun2).toThrow("Parameter 'identityOrMessage' is not a string")
13-
expect(fun3).toThrow("Parameter 'identityOrMessage' is not a string")
14-
})
15-
16-
it("Should create random identities", () => {
17-
const identity1 = new Identity()
18-
const identity2 = new Identity()
19-
20-
expect(identity1.trapdoor).not.toBe(identity2.getTrapdoor())
21-
expect(identity1.nullifier).not.toBe(identity2.getNullifier())
22-
expect(identity1.secret).not.toBe(identity2.getSecret())
23-
expect(identity1.commitment).not.toBe(identity2.getCommitment())
24-
})
25-
26-
it("Should create deterministic identities from a message", () => {
27-
const identity1 = new Identity("message")
28-
const identity2 = new Identity("message")
29-
30-
expect(identity1.trapdoor).toBe(identity2.getTrapdoor())
31-
expect(identity1.nullifier).toBe(identity2.getNullifier())
32-
})
33-
34-
it("Should create deterministic identities from number/boolean messages", () => {
35-
const identity1 = new Identity("true")
36-
const identity2 = new Identity("true")
37-
const identity3 = new Identity("7")
38-
const identity4 = new Identity("7")
39-
40-
expect(identity1.trapdoor).toBe(identity2.getTrapdoor())
41-
expect(identity1.nullifier).toBe(identity2.getNullifier())
42-
expect(identity3.trapdoor).toBe(identity4.getTrapdoor())
43-
expect(identity3.nullifier).toBe(identity4.getNullifier())
44-
})
4+
const privateKey = "secret"
455

46-
it("Should not recreate an existing invalid identity", () => {
47-
const fun = () => new Identity('[true, "01323"]')
6+
describe("# Identity", () => {
7+
it("Should create a random identity", () => {
8+
const identity = new Identity()
489

49-
expect(fun).toThrow("invalid BigNumber value")
10+
expect(Buffer.isBuffer(identity.privateKey)).toBeTruthy()
11+
expect(typeof identity.publicKey).toBe("string")
12+
expect(typeof identity.secretScalar).toBe("string")
13+
expect(identity.unpackedPublicKey).toHaveLength(2)
5014
})
5115

52-
it("Should recreate an existing identity", () => {
53-
const identity1 = new Identity("message")
54-
55-
const identity2 = new Identity(identity1.toString())
16+
it("Should create deterministic identities from a secret (private key)", () => {
17+
const identity = new Identity(privateKey)
5618

57-
expect(identity1.trapdoor).toBe(identity2.getTrapdoor())
58-
expect(identity1.nullifier).toBe(identity2.getNullifier())
19+
expect(typeof identity.privateKey).toBe("string")
20+
expect(typeof identity.publicKey).toBe("string")
21+
expect(typeof identity.secretScalar).toBe("string")
22+
expect(identity.unpackedPublicKey).toHaveLength(2)
23+
expect(typeof identity.unpackedPublicKey[0]).toBe("string")
5924
})
6025
})
6126

62-
describe("# getTrapdoor", () => {
63-
it("Should return the identity trapdoor", () => {
64-
const identity = new Identity("message")
27+
describe("# signMessage", () => {
28+
it("Should sign a message", () => {
29+
const identity = new Identity(privateKey)
6530

66-
const trapdoor = identity.getTrapdoor()
31+
const signature = identity.signMessage("message")
6732

68-
expect(trapdoor.toString()).toBe(
69-
"11566083507498623434013707198824105161167204201250008419741119866456392774309"
70-
)
33+
expect(signature.R8).toHaveLength(2)
34+
expect(typeof signature.R8[0]).toBe("string")
35+
expect(typeof signature.S).toBe("string")
7136
})
7237
})
7338

74-
describe("# getNullifier", () => {
75-
it("Should return the identity nullifier", () => {
76-
const identity = new Identity("message")
77-
78-
const nullifier = identity.getNullifier()
79-
80-
expect(nullifier.toString()).toBe(
81-
"14070056666392584007908120012103355272369511035580155843212703537125048345255"
82-
)
83-
})
84-
})
39+
describe("# verifySignature", () => {
40+
it("Should verify a signature", () => {
41+
const identity = new Identity(privateKey)
8542

86-
describe("# getSecret", () => {
87-
it("Should return an identity secret", () => {
88-
const { secret } = new Identity("message")
43+
const signature = identity.signMessage("message")
8944

90-
expect(secret.toString()).toBe(
91-
"17452394798940441025978193762953691632066258438336130543532009665042636950194"
92-
)
45+
expect(identity.verifySignature("message", signature)).toBeTruthy()
9346
})
94-
})
95-
96-
describe("# getCommitment", () => {
97-
it("Should return an identity commitment", () => {
98-
const { commitment } = new Identity("message")
99-
100-
expect(commitment.toString()).toBe(
101-
"19361462367798001240039467285882167157718016385695743307694056771074972404368"
102-
)
103-
})
104-
})
10547

106-
describe("# toString", () => {
107-
it("Should return a string", () => {
108-
const identity = new Identity("message")
48+
it("Should verify an external signature", () => {
49+
const identity = new Identity(privateKey)
10950

110-
const identityString = identity.toString()
51+
const signature = identity.signMessage("message")
11152

112-
expect(typeof identityString).toBe("string")
53+
expect(Identity.verifySignature("message", signature, identity.publicKey)).toBeTruthy()
54+
expect(Identity.verifySignature("message", signature, BigInt(identity.publicKey))).toBeTruthy()
11355
})
11456

115-
it("Should return a valid identity string", () => {
116-
const identity = new Identity("message")
57+
it("Should verify an external signature with an unpacked public key", () => {
58+
const identity = new Identity(privateKey)
11759

118-
const [trapdoor, nullifier] = JSON.parse(identity.toString())
60+
const signature = identity.signMessage("message")
11961

120-
expect(BigNumber.from(trapdoor).toBigInt()).toBe(identity.trapdoor)
121-
expect(BigNumber.from(nullifier).toBigInt()).toBe(identity.nullifier)
62+
expect(Identity.verifySignature("message", signature, identity.unpackedPublicKey)).toBeTruthy()
12263
})
12364
})
12465
})

0 commit comments

Comments
 (0)