@libp2p/crypto 2.0.8-6b6ba9ab7 → 2.0.8-74e84bc29
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/dist/index.min.js +9 -9
- package/dist/src/aes/cipher-mode.js.map +1 -1
- package/dist/src/aes/index.d.ts +1 -1
- package/dist/src/aes/index.d.ts.map +1 -1
- package/dist/src/aes/index.js +1 -1
- package/dist/src/aes/index.js.map +1 -1
- package/dist/src/ciphers/aes-gcm.browser.js.map +1 -1
- package/dist/src/ciphers/aes-gcm.js +3 -3
- package/dist/src/ciphers/aes-gcm.js.map +1 -1
- package/dist/src/keys/ecdh-browser.js +1 -1
- package/dist/src/keys/ecdh-browser.js.map +1 -1
- package/dist/src/keys/ecdh.js.map +1 -1
- package/dist/src/keys/ed25519-browser.d.ts +5 -4
- package/dist/src/keys/ed25519-browser.d.ts.map +1 -1
- package/dist/src/keys/ed25519-browser.js +6 -6
- package/dist/src/keys/ed25519-browser.js.map +1 -1
- package/dist/src/keys/ed25519-class.d.ts +4 -3
- package/dist/src/keys/ed25519-class.d.ts.map +1 -1
- package/dist/src/keys/ed25519-class.js +19 -8
- package/dist/src/keys/ed25519-class.js.map +1 -1
- package/dist/src/keys/ed25519.d.ts +5 -4
- package/dist/src/keys/ed25519.d.ts.map +1 -1
- package/dist/src/keys/ed25519.js +11 -19
- package/dist/src/keys/ed25519.js.map +1 -1
- package/dist/src/keys/index.js.map +1 -1
- package/dist/src/keys/key-stretcher.js.map +1 -1
- package/dist/src/keys/keys.js.map +1 -1
- package/dist/src/keys/rsa-browser.d.ts +5 -4
- package/dist/src/keys/rsa-browser.d.ts.map +1 -1
- package/dist/src/keys/rsa-browser.js +3 -3
- package/dist/src/keys/rsa-browser.js.map +1 -1
- package/dist/src/keys/rsa-class.d.ts +8 -7
- package/dist/src/keys/rsa-class.d.ts.map +1 -1
- package/dist/src/keys/rsa-class.js +15 -8
- package/dist/src/keys/rsa-class.js.map +1 -1
- package/dist/src/keys/rsa-utils.js.map +1 -1
- package/dist/src/keys/rsa.d.ts +5 -4
- package/dist/src/keys/rsa.d.ts.map +1 -1
- package/dist/src/keys/rsa.js +38 -12
- package/dist/src/keys/rsa.js.map +1 -1
- package/dist/src/keys/secp256k1-browser.d.ts +18 -0
- package/dist/src/keys/secp256k1-browser.d.ts.map +1 -0
- package/dist/src/keys/secp256k1-browser.js +78 -0
- package/dist/src/keys/secp256k1-browser.js.map +1 -0
- package/dist/src/keys/secp256k1-class.d.ts +4 -3
- package/dist/src/keys/secp256k1-class.d.ts.map +1 -1
- package/dist/src/keys/secp256k1-class.js +17 -6
- package/dist/src/keys/secp256k1-class.js.map +1 -1
- package/dist/src/keys/secp256k1.d.ts +3 -2
- package/dist/src/keys/secp256k1.d.ts.map +1 -1
- package/dist/src/keys/secp256k1.js +23 -5
- package/dist/src/keys/secp256k1.js.map +1 -1
- package/dist/src/pbkdf2.js.map +1 -1
- package/dist/src/random-bytes.js.map +1 -1
- package/dist/src/util.d.ts +1 -0
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +8 -0
- package/dist/src/util.js.map +1 -1
- package/dist/src/webcrypto.js.map +1 -1
- package/package.json +8 -3
- package/src/aes/index.ts +1 -1
- package/src/ciphers/aes-gcm.ts +3 -3
- package/src/keys/ed25519-browser.ts +7 -6
- package/src/keys/ed25519-class.ts +21 -8
- package/src/keys/ed25519.ts +12 -20
- package/src/keys/rsa-browser.ts +9 -8
- package/src/keys/rsa-class.ts +21 -11
- package/src/keys/rsa.ts +43 -16
- package/src/keys/secp256k1-browser.ts +87 -0
- package/src/keys/secp256k1-class.ts +19 -6
- package/src/keys/secp256k1.ts +28 -5
- package/src/util.ts +10 -0
package/dist/src/util.js
CHANGED
|
@@ -34,4 +34,12 @@ export function base64urlToBuffer(str, len) {
|
|
|
34
34
|
}
|
|
35
35
|
return buf;
|
|
36
36
|
}
|
|
37
|
+
export function isPromise(thing) {
|
|
38
|
+
if (thing == null) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return typeof thing.then === 'function' &&
|
|
42
|
+
typeof thing.catch === 'function' &&
|
|
43
|
+
typeof thing.finally === 'function';
|
|
44
|
+
}
|
|
37
45
|
//# sourceMappingURL=util.js.map
|
package/dist/src/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAA;AAC/B,OAAO,wBAAwB,CAAA;AAC/B,qCAAqC;AACrC,OAAO,KAAK,MAAM,yBAAyB,CAAA;AAC3C,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEtE,MAAM,UAAU,yBAAyB,CAAE,GAAmB,EAAE,GAAY;IAC1E,uCAAuC;IACvC,IAAI,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA,CAAC,qCAAqC;IAExF,6EAA6E;IAC7E,uDAAuD;IACvD,6EAA6E;IAC7E,8EAA8E;IAC9E,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IAE1C,IAAI,GAAG,IAAI,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAA;AAC/B,OAAO,wBAAwB,CAAA;AAC/B,qCAAqC;AACrC,OAAO,KAAK,MAAM,yBAAyB,CAAA;AAC3C,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEtE,MAAM,UAAU,yBAAyB,CAAE,GAAmB,EAAE,GAAY;IAC1E,uCAAuC;IACvC,IAAI,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA,CAAC,qCAAqC;IAExF,6EAA6E;IAC7E,uDAAuD;IACvD,6EAA6E;IAC7E,8EAA8E;IAC9E,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IAE1C,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;QAC9E,GAAG,GAAG,gBAAgB,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IACjE,CAAC;IAED,OAAO,kBAAkB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;AAC7C,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,qBAAqB,CAAE,GAAW;IAChD,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;IAClC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;AACzE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAE,GAAW,EAAE,GAAY;IAC1D,IAAI,GAAG,GAAG,oBAAoB,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IAEnD,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;QAC9E,GAAG,GAAG,gBAAgB,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IACjE,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,SAAS,CAAgB,KAAU;IACjD,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU;QACrC,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU;QACjC,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CAAA;AACvC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webcrypto.js","sourceRoot":"","sources":["../../src/webcrypto.ts"],"names":[],"mappings":"AAAA,wBAAwB;AAExB,+EAA+E;AAC/E,6CAA6C;AAC7C,eAAe;IACb,GAAG,CAAE,GAAG,GAAG,UAAU;QACnB,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAA;QAE/B,IAAI,YAAY,IAAI,IAAI,IAAI,YAAY,CAAC,MAAM,IAAI,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"webcrypto.js","sourceRoot":"","sources":["../../src/webcrypto.ts"],"names":[],"mappings":"AAAA,wBAAwB;AAExB,+EAA+E;AAC/E,6CAA6C;AAC7C,eAAe;IACb,GAAG,CAAE,GAAG,GAAG,UAAU;QACnB,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAA;QAE/B,IAAI,YAAY,IAAI,IAAI,IAAI,YAAY,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YACxD,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CACP,0BAA0B;gBAC1B,0EAA0E;gBAC1E,sEAAsE;gBACtE,2BAA2B;gBAC3B,wFAAwF,CACzF,EACD,EAAE,IAAI,EAAE,wBAAwB,EAAE,CACnC,CAAA;QACH,CAAC;QAED,OAAO,YAAY,CAAA;IACrB,CAAC;CACF,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/crypto",
|
|
3
|
-
"version": "2.0.8-
|
|
3
|
+
"version": "2.0.8-74e84bc29",
|
|
4
4
|
"description": "Crypto primitives for libp2p",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/crypto#readme",
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/libp2p/js-libp2p/issues"
|
|
13
13
|
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public",
|
|
16
|
+
"provenance": true
|
|
17
|
+
},
|
|
14
18
|
"keywords": [
|
|
15
19
|
"IPFS",
|
|
16
20
|
"crypto",
|
|
@@ -86,7 +90,7 @@
|
|
|
86
90
|
"generate": "protons ./src/keys/keys.proto"
|
|
87
91
|
},
|
|
88
92
|
"dependencies": {
|
|
89
|
-
"@libp2p/interface": "0.1.6-
|
|
93
|
+
"@libp2p/interface": "0.1.6-74e84bc29",
|
|
90
94
|
"@noble/curves": "^1.1.0",
|
|
91
95
|
"@noble/hashes": "^1.3.1",
|
|
92
96
|
"multiformats": "^12.1.3",
|
|
@@ -107,6 +111,7 @@
|
|
|
107
111
|
"./dist/src/hmac/index.js": "./dist/src/hmac/index-browser.js",
|
|
108
112
|
"./dist/src/keys/ecdh.js": "./dist/src/keys/ecdh-browser.js",
|
|
109
113
|
"./dist/src/keys/ed25519.js": "./dist/src/keys/ed25519-browser.js",
|
|
110
|
-
"./dist/src/keys/rsa.js": "./dist/src/keys/rsa-browser.js"
|
|
114
|
+
"./dist/src/keys/rsa.js": "./dist/src/keys/rsa-browser.js",
|
|
115
|
+
"./dist/src/keys/secp256k1.js": "./dist/src/keys/secp256k1-browser.js"
|
|
111
116
|
}
|
|
112
117
|
}
|
package/src/aes/index.ts
CHANGED
|
@@ -51,7 +51,7 @@ export interface AESCipher {
|
|
|
51
51
|
* @param key - The key, if length `16` then `AES 128` is used. For length `32`, `AES 256` is used
|
|
52
52
|
* @param iv - Must have length `16`
|
|
53
53
|
*/
|
|
54
|
-
export
|
|
54
|
+
export function create (key: Uint8Array, iv: Uint8Array): AESCipher {
|
|
55
55
|
const mode = cipherMode(key)
|
|
56
56
|
const cipher = ciphers.createCipheriv(mode, key, iv)
|
|
57
57
|
const decipher = ciphers.createDecipheriv(mode, key, iv)
|
package/src/ciphers/aes-gcm.ts
CHANGED
|
@@ -14,7 +14,7 @@ export function create (opts?: CreateOptions): AESCipher {
|
|
|
14
14
|
const iterations = opts?.iterations ?? 32767
|
|
15
15
|
const algorithmTagLength = opts?.algorithmTagLength ?? 16
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
function encryptWithKey (data: Uint8Array, key: Uint8Array): Uint8Array {
|
|
18
18
|
const nonce = crypto.randomBytes(nonceLength)
|
|
19
19
|
|
|
20
20
|
// Create the cipher instance.
|
|
@@ -43,7 +43,7 @@ export function create (opts?: CreateOptions): AESCipher {
|
|
|
43
43
|
const key = crypto.pbkdf2Sync(password, salt, iterations, keyLength, digest)
|
|
44
44
|
|
|
45
45
|
// Encrypt and prepend salt.
|
|
46
|
-
return uint8ArrayConcat([salt,
|
|
46
|
+
return uint8ArrayConcat([salt, encryptWithKey(Uint8Array.from(data), key)])
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
@@ -53,7 +53,7 @@ export function create (opts?: CreateOptions): AESCipher {
|
|
|
53
53
|
* this decryption cipher must be the same as those used to create
|
|
54
54
|
* the encryption cipher.
|
|
55
55
|
*/
|
|
56
|
-
|
|
56
|
+
function decryptWithKey (ciphertextAndNonce: Uint8Array, key: Uint8Array): Uint8Array {
|
|
57
57
|
// Create Uint8Arrays of nonce, ciphertext and tag.
|
|
58
58
|
const nonce = ciphertextAndNonce.subarray(0, nonceLength)
|
|
59
59
|
const ciphertext = ciphertextAndNonce.subarray(nonceLength, ciphertextAndNonce.length - algorithmTagLength)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ed25519 as ed } from '@noble/curves/ed25519'
|
|
2
2
|
import type { Uint8ArrayKeyPair } from './interface'
|
|
3
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
3
4
|
|
|
4
5
|
const PUBLIC_KEY_BYTE_LENGTH = 32
|
|
5
6
|
const PRIVATE_KEY_BYTE_LENGTH = 64 // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
|
@@ -8,7 +9,7 @@ const KEYS_BYTE_LENGTH = 32
|
|
|
8
9
|
export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength }
|
|
9
10
|
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength }
|
|
10
11
|
|
|
11
|
-
export
|
|
12
|
+
export function generateKey (): Uint8ArrayKeyPair {
|
|
12
13
|
// the actual private key (32 bytes)
|
|
13
14
|
const privateKeyRaw = ed.utils.randomPrivateKey()
|
|
14
15
|
const publicKey = ed.getPublicKey(privateKeyRaw)
|
|
@@ -25,7 +26,7 @@ export async function generateKey (): Promise<Uint8ArrayKeyPair> {
|
|
|
25
26
|
/**
|
|
26
27
|
* Generate keypair from a 32 byte uint8array
|
|
27
28
|
*/
|
|
28
|
-
export
|
|
29
|
+
export function generateKeyFromSeed (seed: Uint8Array): Uint8ArrayKeyPair {
|
|
29
30
|
if (seed.length !== KEYS_BYTE_LENGTH) {
|
|
30
31
|
throw new TypeError('"seed" must be 32 bytes in length.')
|
|
31
32
|
} else if (!(seed instanceof Uint8Array)) {
|
|
@@ -44,14 +45,14 @@ export async function generateKeyFromSeed (seed: Uint8Array): Promise<Uint8Array
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
export
|
|
48
|
+
export function hashAndSign (privateKey: Uint8Array, msg: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
48
49
|
const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH)
|
|
49
50
|
|
|
50
|
-
return ed.sign(msg, privateKeyRaw)
|
|
51
|
+
return ed.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw)
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
export
|
|
54
|
-
return ed.verify(sig, msg, publicKey)
|
|
54
|
+
export function hashAndVerify (publicKey: Uint8Array, sig: Uint8Array, msg: Uint8Array | Uint8ArrayList): boolean {
|
|
55
|
+
return ed.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey)
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
function concatKeys (privateKeyRaw: Uint8Array, publicKey: Uint8Array): Uint8Array {
|
|
@@ -3,10 +3,12 @@ import { base58btc } from 'multiformats/bases/base58'
|
|
|
3
3
|
import { identity } from 'multiformats/hashes/identity'
|
|
4
4
|
import { sha256 } from 'multiformats/hashes/sha2'
|
|
5
5
|
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
|
|
6
|
+
import { isPromise } from '../util.js'
|
|
6
7
|
import * as crypto from './ed25519.js'
|
|
7
8
|
import { exporter } from './exporter.js'
|
|
8
9
|
import * as pbm from './keys.js'
|
|
9
10
|
import type { Multibase } from 'multiformats'
|
|
11
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
10
12
|
|
|
11
13
|
export class Ed25519PublicKey {
|
|
12
14
|
private readonly _key: Uint8Array
|
|
@@ -15,7 +17,7 @@ export class Ed25519PublicKey {
|
|
|
15
17
|
this._key = ensureKey(key, crypto.publicKeyLength)
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
verify (data: Uint8Array | Uint8ArrayList, sig: Uint8Array): boolean {
|
|
19
21
|
return crypto.hashAndVerify(this._key, sig, data)
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -34,10 +36,14 @@ export class Ed25519PublicKey {
|
|
|
34
36
|
return uint8ArrayEquals(this.bytes, key.bytes)
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
+
hash (): Uint8Array | Promise<Uint8Array> {
|
|
40
|
+
const p = sha256.digest(this.bytes)
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
if (isPromise(p)) {
|
|
43
|
+
return p.then(({ bytes }) => bytes)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return p.bytes
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
|
|
@@ -52,7 +58,7 @@ export class Ed25519PrivateKey {
|
|
|
52
58
|
this._publicKey = ensureKey(publicKey, crypto.publicKeyLength)
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
sign (message: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
56
62
|
return crypto.hashAndSign(this._key, message)
|
|
57
63
|
}
|
|
58
64
|
|
|
@@ -76,7 +82,14 @@ export class Ed25519PrivateKey {
|
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
async hash (): Promise<Uint8Array> {
|
|
79
|
-
const
|
|
85
|
+
const p = sha256.digest(this.bytes)
|
|
86
|
+
let bytes: Uint8Array
|
|
87
|
+
|
|
88
|
+
if (isPromise(p)) {
|
|
89
|
+
({ bytes } = await p)
|
|
90
|
+
} else {
|
|
91
|
+
bytes = p.bytes
|
|
92
|
+
}
|
|
80
93
|
|
|
81
94
|
return bytes
|
|
82
95
|
}
|
|
@@ -128,12 +141,12 @@ export function unmarshalEd25519PublicKey (bytes: Uint8Array): Ed25519PublicKey
|
|
|
128
141
|
}
|
|
129
142
|
|
|
130
143
|
export async function generateKeyPair (): Promise<Ed25519PrivateKey> {
|
|
131
|
-
const { privateKey, publicKey } =
|
|
144
|
+
const { privateKey, publicKey } = crypto.generateKey()
|
|
132
145
|
return new Ed25519PrivateKey(privateKey, publicKey)
|
|
133
146
|
}
|
|
134
147
|
|
|
135
148
|
export async function generateKeyPairFromSeed (seed: Uint8Array): Promise<Ed25519PrivateKey> {
|
|
136
|
-
const { privateKey, publicKey } =
|
|
149
|
+
const { privateKey, publicKey } = crypto.generateKeyFromSeed(seed)
|
|
137
150
|
return new Ed25519PrivateKey(privateKey, publicKey)
|
|
138
151
|
}
|
|
139
152
|
|
package/src/keys/ed25519.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import crypto from 'crypto'
|
|
2
|
-
import {
|
|
2
|
+
import { concat as uint8arrayConcat } from 'uint8arrays/concat'
|
|
3
3
|
import { fromString as uint8arrayFromString } from 'uint8arrays/from-string'
|
|
4
4
|
import { toString as uint8arrayToString } from 'uint8arrays/to-string'
|
|
5
5
|
import type { Uint8ArrayKeyPair } from './interface.js'
|
|
6
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
6
7
|
|
|
7
|
-
const keypair =
|
|
8
|
+
const keypair = crypto.generateKeyPairSync
|
|
8
9
|
|
|
9
10
|
const PUBLIC_KEY_BYTE_LENGTH = 32
|
|
10
11
|
const PRIVATE_KEY_BYTE_LENGTH = 64 // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
|
@@ -35,8 +36,8 @@ function derivePublicKey (privateKey: Uint8Array): Uint8Array {
|
|
|
35
36
|
return uint8arrayFromString(jwk.x, 'base64url')
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
export
|
|
39
|
-
const key =
|
|
39
|
+
export function generateKey (): Uint8ArrayKeyPair {
|
|
40
|
+
const key = keypair('ed25519', {
|
|
40
41
|
publicKeyEncoding: { type: 'spki', format: 'jwk' },
|
|
41
42
|
privateKeyEncoding: { type: 'pkcs8', format: 'jwk' }
|
|
42
43
|
})
|
|
@@ -47,7 +48,7 @@ export async function generateKey (): Promise<Uint8ArrayKeyPair> {
|
|
|
47
48
|
const publicKeyRaw = uint8arrayFromString(key.privateKey.x, 'base64url')
|
|
48
49
|
|
|
49
50
|
return {
|
|
50
|
-
privateKey:
|
|
51
|
+
privateKey: uint8arrayConcat([privateKeyRaw, publicKeyRaw], privateKeyRaw.byteLength + publicKeyRaw.byteLength),
|
|
51
52
|
publicKey: publicKeyRaw
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -55,7 +56,7 @@ export async function generateKey (): Promise<Uint8ArrayKeyPair> {
|
|
|
55
56
|
/**
|
|
56
57
|
* Generate keypair from a 32 byte uint8array
|
|
57
58
|
*/
|
|
58
|
-
export
|
|
59
|
+
export function generateKeyFromSeed (seed: Uint8Array): Uint8ArrayKeyPair {
|
|
59
60
|
if (seed.length !== KEYS_BYTE_LENGTH) {
|
|
60
61
|
throw new TypeError('"seed" must be 32 bytes in length.')
|
|
61
62
|
} else if (!(seed instanceof Uint8Array)) {
|
|
@@ -66,12 +67,12 @@ export async function generateKeyFromSeed (seed: Uint8Array): Promise<Uint8Array
|
|
|
66
67
|
const publicKeyRaw = derivePublicKey(seed)
|
|
67
68
|
|
|
68
69
|
return {
|
|
69
|
-
privateKey:
|
|
70
|
+
privateKey: uint8arrayConcat([seed, publicKeyRaw], seed.byteLength + publicKeyRaw.byteLength),
|
|
70
71
|
publicKey: publicKeyRaw
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
export
|
|
75
|
+
export function hashAndSign (key: Uint8Array, msg: Uint8Array | Uint8ArrayList): Buffer {
|
|
75
76
|
if (!(key instanceof Uint8Array)) {
|
|
76
77
|
throw new TypeError('"key" must be a node.js Buffer, or Uint8Array.')
|
|
77
78
|
}
|
|
@@ -99,10 +100,10 @@ export async function hashAndSign (key: Uint8Array, msg: Uint8Array): Promise<Bu
|
|
|
99
100
|
}
|
|
100
101
|
})
|
|
101
102
|
|
|
102
|
-
return crypto.sign(null, msg, obj)
|
|
103
|
+
return crypto.sign(null, msg instanceof Uint8Array ? msg : msg.subarray(), obj)
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
export
|
|
106
|
+
export function hashAndVerify (key: Uint8Array, sig: Uint8Array, msg: Uint8Array | Uint8ArrayList): boolean {
|
|
106
107
|
if (key.byteLength !== PUBLIC_KEY_BYTE_LENGTH) {
|
|
107
108
|
throw new TypeError('"key" must be 32 bytes in length.')
|
|
108
109
|
} else if (!(key instanceof Uint8Array)) {
|
|
@@ -124,14 +125,5 @@ export async function hashAndVerify (key: Uint8Array, sig: Uint8Array, msg: Uint
|
|
|
124
125
|
}
|
|
125
126
|
})
|
|
126
127
|
|
|
127
|
-
return crypto.verify(null, msg, obj, sig)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function concatKeys (privateKeyRaw: Uint8Array, publicKey: Uint8Array): Uint8Array {
|
|
131
|
-
const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH)
|
|
132
|
-
for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
|
|
133
|
-
privateKey[i] = privateKeyRaw[i]
|
|
134
|
-
privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i]
|
|
135
|
-
}
|
|
136
|
-
return privateKey
|
|
128
|
+
return crypto.verify(null, msg instanceof Uint8Array ? msg : msg.subarray(), obj, sig)
|
|
137
129
|
}
|
package/src/keys/rsa-browser.ts
CHANGED
|
@@ -6,6 +6,7 @@ import webcrypto from '../webcrypto.js'
|
|
|
6
6
|
import { jwk2pub, jwk2priv } from './jwk2pem.js'
|
|
7
7
|
import * as utils from './rsa-utils.js'
|
|
8
8
|
import type { JWKKeyPair } from './interface.js'
|
|
9
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
9
10
|
|
|
10
11
|
export { utils }
|
|
11
12
|
|
|
@@ -60,7 +61,7 @@ export async function unmarshalPrivateKey (key: JsonWebKey): Promise<JWKKeyPair>
|
|
|
60
61
|
|
|
61
62
|
export { randomBytes as getRandomValues }
|
|
62
63
|
|
|
63
|
-
export async function hashAndSign (key: JsonWebKey, msg: Uint8Array): Promise<Uint8Array> {
|
|
64
|
+
export async function hashAndSign (key: JsonWebKey, msg: Uint8Array | Uint8ArrayList): Promise<Uint8Array> {
|
|
64
65
|
const privateKey = await webcrypto.get().subtle.importKey(
|
|
65
66
|
'jwk',
|
|
66
67
|
key,
|
|
@@ -75,13 +76,13 @@ export async function hashAndSign (key: JsonWebKey, msg: Uint8Array): Promise<Ui
|
|
|
75
76
|
const sig = await webcrypto.get().subtle.sign(
|
|
76
77
|
{ name: 'RSASSA-PKCS1-v1_5' },
|
|
77
78
|
privateKey,
|
|
78
|
-
Uint8Array.
|
|
79
|
+
msg instanceof Uint8Array ? msg : msg.subarray()
|
|
79
80
|
)
|
|
80
81
|
|
|
81
82
|
return new Uint8Array(sig, 0, sig.byteLength)
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
export async function hashAndVerify (key: JsonWebKey, sig: Uint8Array, msg: Uint8Array): Promise<boolean> {
|
|
85
|
+
export async function hashAndVerify (key: JsonWebKey, sig: Uint8Array, msg: Uint8Array | Uint8ArrayList): Promise<boolean> {
|
|
85
86
|
const publicKey = await webcrypto.get().subtle.importKey(
|
|
86
87
|
'jwk',
|
|
87
88
|
key,
|
|
@@ -97,7 +98,7 @@ export async function hashAndVerify (key: JsonWebKey, sig: Uint8Array, msg: Uint
|
|
|
97
98
|
{ name: 'RSASSA-PKCS1-v1_5' },
|
|
98
99
|
publicKey,
|
|
99
100
|
sig,
|
|
100
|
-
msg
|
|
101
|
+
msg instanceof Uint8Array ? msg : msg.subarray()
|
|
101
102
|
)
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -141,18 +142,18 @@ Explanation:
|
|
|
141
142
|
|
|
142
143
|
*/
|
|
143
144
|
|
|
144
|
-
function convertKey (key: JsonWebKey, pub: boolean, msg: Uint8Array, handle: (msg: string, key: { encrypt(msg: string): string, decrypt(msg: string): string }) => string): Uint8Array {
|
|
145
|
+
function convertKey (key: JsonWebKey, pub: boolean, msg: Uint8Array | Uint8ArrayList, handle: (msg: string, key: { encrypt(msg: string): string, decrypt(msg: string): string }) => string): Uint8Array {
|
|
145
146
|
const fkey = pub ? jwk2pub(key) : jwk2priv(key)
|
|
146
|
-
const fmsg = uint8ArrayToString(Uint8Array.
|
|
147
|
+
const fmsg = uint8ArrayToString(msg instanceof Uint8Array ? msg : msg.subarray(), 'ascii')
|
|
147
148
|
const fomsg = handle(fmsg, fkey)
|
|
148
149
|
return uint8ArrayFromString(fomsg, 'ascii')
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
export function encrypt (key: JsonWebKey, msg: Uint8Array): Uint8Array {
|
|
152
|
+
export function encrypt (key: JsonWebKey, msg: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
152
153
|
return convertKey(key, true, msg, (msg, key) => key.encrypt(msg))
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
export function decrypt (key: JsonWebKey, msg: Uint8Array): Uint8Array {
|
|
156
|
+
export function decrypt (key: JsonWebKey, msg: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
156
157
|
return convertKey(key, false, msg, (msg, key) => key.decrypt(msg))
|
|
157
158
|
}
|
|
158
159
|
|
package/src/keys/rsa-class.ts
CHANGED
|
@@ -5,10 +5,12 @@ import forge from 'node-forge/lib/forge.js'
|
|
|
5
5
|
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
|
|
6
6
|
import 'node-forge/lib/sha512.js'
|
|
7
7
|
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
8
|
+
import { isPromise } from '../util.js'
|
|
8
9
|
import { exporter } from './exporter.js'
|
|
9
10
|
import * as pbm from './keys.js'
|
|
10
11
|
import * as crypto from './rsa.js'
|
|
11
12
|
import type { Multibase } from 'multiformats'
|
|
13
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
12
14
|
|
|
13
15
|
export const MAX_KEY_SIZE = 8192
|
|
14
16
|
|
|
@@ -19,7 +21,7 @@ export class RsaPublicKey {
|
|
|
19
21
|
this._key = key
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
verify (data: Uint8Array | Uint8ArrayList, sig: Uint8Array): boolean | Promise<boolean> {
|
|
23
25
|
return crypto.hashAndVerify(this._key, sig, data)
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -34,18 +36,22 @@ export class RsaPublicKey {
|
|
|
34
36
|
}).subarray()
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
encrypt (bytes: Uint8Array): Uint8Array {
|
|
39
|
+
encrypt (bytes: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
38
40
|
return crypto.encrypt(this._key, bytes)
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
equals (key: any): boolean {
|
|
43
|
+
equals (key: any): boolean | boolean {
|
|
42
44
|
return uint8ArrayEquals(this.bytes, key.bytes)
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
+
hash (): Uint8Array | Promise<Uint8Array> {
|
|
48
|
+
const p = sha256.digest(this.bytes)
|
|
49
|
+
|
|
50
|
+
if (isPromise(p)) {
|
|
51
|
+
return p.then(({ bytes }) => bytes)
|
|
52
|
+
}
|
|
47
53
|
|
|
48
|
-
return bytes
|
|
54
|
+
return p.bytes
|
|
49
55
|
}
|
|
50
56
|
}
|
|
51
57
|
|
|
@@ -62,7 +68,7 @@ export class RsaPrivateKey {
|
|
|
62
68
|
return crypto.getRandomValues(16)
|
|
63
69
|
}
|
|
64
70
|
|
|
65
|
-
|
|
71
|
+
sign (message: Uint8Array | Uint8ArrayList): Uint8Array | Promise<Uint8Array> {
|
|
66
72
|
return crypto.hashAndSign(this._key, message)
|
|
67
73
|
}
|
|
68
74
|
|
|
@@ -74,7 +80,7 @@ export class RsaPrivateKey {
|
|
|
74
80
|
return new RsaPublicKey(this._publicKey)
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
decrypt (bytes: Uint8Array): Uint8Array {
|
|
83
|
+
decrypt (bytes: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
78
84
|
return crypto.decrypt(this._key, bytes)
|
|
79
85
|
}
|
|
80
86
|
|
|
@@ -93,10 +99,14 @@ export class RsaPrivateKey {
|
|
|
93
99
|
return uint8ArrayEquals(this.bytes, key.bytes)
|
|
94
100
|
}
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
const
|
|
102
|
+
hash (): Uint8Array | Promise<Uint8Array> {
|
|
103
|
+
const p = sha256.digest(this.bytes)
|
|
104
|
+
|
|
105
|
+
if (isPromise(p)) {
|
|
106
|
+
return p.then(({ bytes }) => bytes)
|
|
107
|
+
}
|
|
98
108
|
|
|
99
|
-
return bytes
|
|
109
|
+
return p.bytes
|
|
100
110
|
}
|
|
101
111
|
|
|
102
112
|
/**
|
package/src/keys/rsa.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { CodeError } from '@libp2p/interface/errors'
|
|
|
4
4
|
import randomBytes from '../random-bytes.js'
|
|
5
5
|
import * as utils from './rsa-utils.js'
|
|
6
6
|
import type { JWKKeyPair } from './interface.js'
|
|
7
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
7
8
|
|
|
8
9
|
const keypair = promisify(crypto.generateKeyPair)
|
|
9
10
|
|
|
@@ -42,30 +43,56 @@ export async function unmarshalPrivateKey (key: JsonWebKey): Promise<JWKKeyPair>
|
|
|
42
43
|
|
|
43
44
|
export { randomBytes as getRandomValues }
|
|
44
45
|
|
|
45
|
-
export async function hashAndSign (key: JsonWebKey, msg: Uint8Array): Promise<Uint8Array> {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
.
|
|
46
|
+
export async function hashAndSign (key: JsonWebKey, msg: Uint8Array | Uint8ArrayList): Promise<Uint8Array> {
|
|
47
|
+
const hash = crypto.createSign('RSA-SHA256')
|
|
48
|
+
|
|
49
|
+
if (msg instanceof Uint8Array) {
|
|
50
|
+
hash.update(msg)
|
|
51
|
+
} else {
|
|
52
|
+
for (const buf of msg) {
|
|
53
|
+
hash.update(buf)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// @ts-expect-error node types are missing jwk as a format
|
|
58
|
+
return hash.sign({ format: 'jwk', key })
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
export async function hashAndVerify (key: JsonWebKey, sig: Uint8Array, msg: Uint8Array): Promise<boolean> {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.
|
|
61
|
+
export async function hashAndVerify (key: JsonWebKey, sig: Uint8Array, msg: Uint8Array | Uint8ArrayList): Promise<boolean> {
|
|
62
|
+
const hash = crypto.createVerify('RSA-SHA256')
|
|
63
|
+
|
|
64
|
+
if (msg instanceof Uint8Array) {
|
|
65
|
+
hash.update(msg)
|
|
66
|
+
} else {
|
|
67
|
+
for (const buf of msg) {
|
|
68
|
+
hash.update(buf)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// @ts-expect-error node types are missing jwk as a format
|
|
73
|
+
return hash.verify({ format: 'jwk', key }, sig)
|
|
57
74
|
}
|
|
58
75
|
|
|
59
76
|
const padding = crypto.constants.RSA_PKCS1_PADDING
|
|
60
77
|
|
|
61
|
-
export function encrypt (key: JsonWebKey, bytes: Uint8Array): Uint8Array {
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
export function encrypt (key: JsonWebKey, bytes: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
79
|
+
if (bytes instanceof Uint8Array) {
|
|
80
|
+
// @ts-expect-error node types are missing jwk as a format
|
|
81
|
+
return crypto.publicEncrypt({ format: 'jwk', key, padding }, bytes)
|
|
82
|
+
} else {
|
|
83
|
+
// @ts-expect-error node types are missing jwk as a format
|
|
84
|
+
return crypto.publicEncrypt({ format: 'jwk', key, padding }, bytes.subarray())
|
|
85
|
+
}
|
|
64
86
|
}
|
|
65
87
|
|
|
66
|
-
export function decrypt (key: JsonWebKey, bytes: Uint8Array): Uint8Array {
|
|
67
|
-
|
|
68
|
-
|
|
88
|
+
export function decrypt (key: JsonWebKey, bytes: Uint8Array | Uint8ArrayList): Uint8Array {
|
|
89
|
+
if (bytes instanceof Uint8Array) {
|
|
90
|
+
// @ts-expect-error node types are missing jwk as a format
|
|
91
|
+
return crypto.privateDecrypt({ format: 'jwk', key, padding }, bytes)
|
|
92
|
+
} else {
|
|
93
|
+
// @ts-expect-error node types are missing jwk as a format
|
|
94
|
+
return crypto.privateDecrypt({ format: 'jwk', key, padding }, bytes.subarray())
|
|
95
|
+
}
|
|
69
96
|
}
|
|
70
97
|
|
|
71
98
|
export function keySize (jwk: JsonWebKey): number {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { CodeError } from '@libp2p/interface/errors'
|
|
2
|
+
import { secp256k1 as secp } from '@noble/curves/secp256k1'
|
|
3
|
+
import { sha256 } from 'multiformats/hashes/sha2'
|
|
4
|
+
import { isPromise } from '../util.js'
|
|
5
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
6
|
+
|
|
7
|
+
const PRIVATE_KEY_BYTE_LENGTH = 32
|
|
8
|
+
|
|
9
|
+
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength }
|
|
10
|
+
|
|
11
|
+
export function generateKey (): Uint8Array {
|
|
12
|
+
return secp.utils.randomPrivateKey()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Hash and sign message with private key
|
|
17
|
+
*/
|
|
18
|
+
export function hashAndSign (key: Uint8Array, msg: Uint8Array | Uint8ArrayList): Uint8Array | Promise<Uint8Array> {
|
|
19
|
+
const p = sha256.digest(msg instanceof Uint8Array ? msg : msg.subarray())
|
|
20
|
+
|
|
21
|
+
if (isPromise(p)) {
|
|
22
|
+
return p.then(({ digest }) => secp.sign(digest, key).toDERRawBytes())
|
|
23
|
+
.catch(err => {
|
|
24
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT')
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
return secp.sign(p.digest, key).toDERRawBytes()
|
|
30
|
+
} catch (err) {
|
|
31
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT')
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Hash message and verify signature with public key
|
|
37
|
+
*/
|
|
38
|
+
export function hashAndVerify (key: Uint8Array, sig: Uint8Array, msg: Uint8Array | Uint8ArrayList): boolean | Promise<boolean> {
|
|
39
|
+
const p = sha256.digest(msg instanceof Uint8Array ? msg : msg.subarray())
|
|
40
|
+
|
|
41
|
+
if (isPromise(p)) {
|
|
42
|
+
return p.then(({ digest }) => secp.verify(sig, digest, key))
|
|
43
|
+
.catch(err => {
|
|
44
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT')
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
return secp.verify(sig, p.digest, key)
|
|
50
|
+
} catch (err) {
|
|
51
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT')
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function compressPublicKey (key: Uint8Array): Uint8Array {
|
|
56
|
+
const point = secp.ProjectivePoint.fromHex(key).toRawBytes(true)
|
|
57
|
+
return point
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function decompressPublicKey (key: Uint8Array): Uint8Array {
|
|
61
|
+
const point = secp.ProjectivePoint.fromHex(key).toRawBytes(false)
|
|
62
|
+
return point
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function validatePrivateKey (key: Uint8Array): void {
|
|
66
|
+
try {
|
|
67
|
+
secp.getPublicKey(key, true)
|
|
68
|
+
} catch (err) {
|
|
69
|
+
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY')
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function validatePublicKey (key: Uint8Array): void {
|
|
74
|
+
try {
|
|
75
|
+
secp.ProjectivePoint.fromHex(key)
|
|
76
|
+
} catch (err) {
|
|
77
|
+
throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY')
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function computePublicKey (privateKey: Uint8Array): Uint8Array {
|
|
82
|
+
try {
|
|
83
|
+
return secp.getPublicKey(privateKey, true)
|
|
84
|
+
} catch (err) {
|
|
85
|
+
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY')
|
|
86
|
+
}
|
|
87
|
+
}
|