@did-btcr2/keypair 0.5.1
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/LICENSE +373 -0
- package/README.md +4 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/pair.js +203 -0
- package/dist/cjs/pair.js.map +1 -0
- package/dist/cjs/public.js +283 -0
- package/dist/cjs/public.js.map +1 -0
- package/dist/cjs/secret.js +271 -0
- package/dist/cjs/secret.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/pair.js +203 -0
- package/dist/esm/pair.js.map +1 -0
- package/dist/esm/public.js +283 -0
- package/dist/esm/public.js.map +1 -0
- package/dist/esm/secret.js +271 -0
- package/dist/esm/secret.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/pair.d.ts +126 -0
- package/dist/types/pair.d.ts.map +1 -0
- package/dist/types/public.d.ts +197 -0
- package/dist/types/public.d.ts.map +1 -0
- package/dist/types/secret.d.ts +174 -0
- package/dist/types/secret.d.ts.map +1 -0
- package/package.json +120 -0
- package/src/index.ts +3 -0
- package/src/pair.ts +274 -0
- package/src/public.ts +424 -0
- package/src/secret.ts +410 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Bytes, Entropy, Hex, KeyBytes, SecretKeyObject } from '@did-btcr2/common';
|
|
2
|
+
import { SchnorrKeyPair } from './pair.js';
|
|
3
|
+
import { PublicKey } from './public.js';
|
|
4
|
+
/**
|
|
5
|
+
* Interface for the SecretKey class.
|
|
6
|
+
* @interface ISecretKey
|
|
7
|
+
* @type {ISecretKey}
|
|
8
|
+
*/
|
|
9
|
+
export interface ISecretKey {
|
|
10
|
+
/**
|
|
11
|
+
* Get the secret key bytes.
|
|
12
|
+
* @readonly @type {KeyBytes} The secret key bytes.
|
|
13
|
+
*/
|
|
14
|
+
bytes: KeyBytes;
|
|
15
|
+
/**
|
|
16
|
+
* Getter returns the secret key bytes in bigint format.
|
|
17
|
+
* Setter allows alternative method of using a bigint seed for the entropy.
|
|
18
|
+
* @type {bigint} The secret key seed.
|
|
19
|
+
*/
|
|
20
|
+
seed: bigint;
|
|
21
|
+
/**
|
|
22
|
+
* Get the secret key as a hex string.
|
|
23
|
+
* @readonly @type {Hex} The secret key as a hex string.
|
|
24
|
+
*/
|
|
25
|
+
hex: Hex;
|
|
26
|
+
/**
|
|
27
|
+
* Checks if this secret key is equal to another secret key.
|
|
28
|
+
*
|
|
29
|
+
* @returns {boolean} True if the private keys are equal.
|
|
30
|
+
*/
|
|
31
|
+
equals(other: SecretKey): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Uses the secret key to compute the corresponding public key.
|
|
34
|
+
* @returns {KeyBytes} A new PublicKey object.
|
|
35
|
+
*/
|
|
36
|
+
computePublicKey(): KeyBytes;
|
|
37
|
+
/**
|
|
38
|
+
* Checks if the secret key is valid.
|
|
39
|
+
* @returns {boolean} Whether the secret key is valid.
|
|
40
|
+
*/
|
|
41
|
+
isValid(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* JSON representation of a SecretKey object.
|
|
44
|
+
* @returns {SecretKeyObject} The SecretKey as a JSON object.
|
|
45
|
+
*/
|
|
46
|
+
json(): SecretKeyObject;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Encapsulates a secp256k1 secret key
|
|
50
|
+
* Provides get methods for different formats (raw, secret, point).
|
|
51
|
+
* Provides helpers methods for comparison, serialization and publicKey generation.
|
|
52
|
+
* @class SecretKey
|
|
53
|
+
* @type {SecretKey}
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
export declare class SecretKey implements ISecretKey {
|
|
57
|
+
/** @type {KeyBytes} The entropy for the secret key as a byte array */
|
|
58
|
+
private _bytes?;
|
|
59
|
+
/** @type {bigint} The entropy for the secret key as a bigint */
|
|
60
|
+
private _seed?;
|
|
61
|
+
/** @type {string} The secret key as a secretKeyMultibase */
|
|
62
|
+
private _multibase;
|
|
63
|
+
/**
|
|
64
|
+
* Instantiates an instance of SecretKey.
|
|
65
|
+
* @param {Entropy} entropy bytes (Uint8Array) or secret (bigint)
|
|
66
|
+
* @throws {SecretKeyError} If entropy is not provided, not a valid 32-byte secret key or not a valid bigint seed
|
|
67
|
+
*/
|
|
68
|
+
constructor(entropy: Entropy);
|
|
69
|
+
/**
|
|
70
|
+
* Get the secret key entropy as a byte array.
|
|
71
|
+
* @returns {KeyBytes} The secret key bytes as a Uint8Array
|
|
72
|
+
*/
|
|
73
|
+
get bytes(): Uint8Array;
|
|
74
|
+
/**
|
|
75
|
+
* Get the secret key entropy as a bigint.
|
|
76
|
+
* @returns {bigint} The secret key as a bigint
|
|
77
|
+
*/
|
|
78
|
+
get seed(): bigint;
|
|
79
|
+
/**
|
|
80
|
+
* Returns the raw secret key as a hex string.
|
|
81
|
+
* @returns {Hex} The secret key as a hex string
|
|
82
|
+
*/
|
|
83
|
+
get hex(): Hex;
|
|
84
|
+
/**
|
|
85
|
+
* Encode the secret key bytes as a secretKeyMultibase string.
|
|
86
|
+
* @returns {string} The secret key in base58btc multibase format
|
|
87
|
+
*/
|
|
88
|
+
get multibase(): string;
|
|
89
|
+
/**
|
|
90
|
+
* Encodes the secret key bytes to BIP340 multibase format.
|
|
91
|
+
* @returns {string} The secret key in BIP340 multibase format.
|
|
92
|
+
*/
|
|
93
|
+
encode(): string;
|
|
94
|
+
/**
|
|
95
|
+
* Checks if this secret key is equal to another.
|
|
96
|
+
* @param {SecretKey} other The other secret key
|
|
97
|
+
* @returns {boolean} True if the private keys are equal, false otherwise
|
|
98
|
+
*/
|
|
99
|
+
equals(other: SecretKey): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Computes the public key from the secret key bytes.
|
|
102
|
+
* @returns {KeyBytes} The computed public key
|
|
103
|
+
*/
|
|
104
|
+
computePublicKey(): KeyBytes;
|
|
105
|
+
/**
|
|
106
|
+
* Converts the secret key to a JSON object.
|
|
107
|
+
* @returns {SecretKeyObject} The secret key as a JSON object
|
|
108
|
+
*/
|
|
109
|
+
json(): SecretKeyObject;
|
|
110
|
+
/**
|
|
111
|
+
* Checks if the secret key is valid.
|
|
112
|
+
* @returns {boolean} True if the secret key is valid, false otherwise
|
|
113
|
+
*/
|
|
114
|
+
isValid(): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Checks if the public key is a valid secp256k1 point.
|
|
117
|
+
* @param {PublicKey} pk The public key to validate
|
|
118
|
+
* @returns {boolean} True if the public key is valid, false otherwise
|
|
119
|
+
*/
|
|
120
|
+
isValidPair(pk: PublicKey): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Decodes the multibase string to the 34-byte secret key (2 byte prefix + 32 byte key).
|
|
123
|
+
* @param {string} multibase The multibase string to decode
|
|
124
|
+
* @returns {Bytes} The decoded secret key.
|
|
125
|
+
*/
|
|
126
|
+
static decode(multibase: string): Bytes;
|
|
127
|
+
/**
|
|
128
|
+
* Creates a SecretKey object from a JSON object.
|
|
129
|
+
* @param {SecretKeyObject} json The JSON object containing the secret key bytes
|
|
130
|
+
* @returns {SecretKey} A new SecretKey object
|
|
131
|
+
*/
|
|
132
|
+
static fromJSON(json: SecretKeyObject): SecretKey;
|
|
133
|
+
/**
|
|
134
|
+
* Converts a SecretKey or KeyBytes to a Pair.
|
|
135
|
+
* @param {KeyBytes} bytes
|
|
136
|
+
* @returns {SchnorrKeyPair} The SchnorrKeyPair object containing the public and private keys
|
|
137
|
+
* @throws {SecretKeyError} If the secret key is not valid
|
|
138
|
+
*/
|
|
139
|
+
static toKeyPair(bytes: KeyBytes): SchnorrKeyPair;
|
|
140
|
+
/**
|
|
141
|
+
* Convert a bigint secret to secret key bytes.
|
|
142
|
+
* @param {KeyBytes} bytes The secret key bytes
|
|
143
|
+
* @returns {bigint} The secret key bytes as a bigint secret
|
|
144
|
+
*/
|
|
145
|
+
static toSecret(bytes: KeyBytes): bigint;
|
|
146
|
+
/**
|
|
147
|
+
* Convert a secret key bytes to a bigint secret.
|
|
148
|
+
* @param {bigint} secret The secret key secret.
|
|
149
|
+
* @returns {KeyBytes} The secret key secret as secret key bytes.
|
|
150
|
+
*/
|
|
151
|
+
static toBytes(secret: bigint): KeyBytes;
|
|
152
|
+
/**
|
|
153
|
+
* Creates a new SecretKey object from a bigint secret.
|
|
154
|
+
* @param {bigint} secret The secret bigint
|
|
155
|
+
* @returns {SecretKey} A new SecretKey object
|
|
156
|
+
*/
|
|
157
|
+
static fromSecret(secret: bigint): SecretKey;
|
|
158
|
+
/**
|
|
159
|
+
* Generates random secret key bytes.
|
|
160
|
+
* @returns {KeyBytes} Uint8Array of 32 random bytes.
|
|
161
|
+
*/
|
|
162
|
+
static random(): KeyBytes;
|
|
163
|
+
/**
|
|
164
|
+
* Creates a new SecretKey from random secret key bytes.
|
|
165
|
+
* @returns {SecretKey} A new SecretKey object
|
|
166
|
+
*/
|
|
167
|
+
static generate(): SecretKey;
|
|
168
|
+
/**
|
|
169
|
+
* Generates a public key from the given secret key bytes.
|
|
170
|
+
* @param {KeyBytes} bytes The secret key bytes
|
|
171
|
+
* @returns {KeyBytes} The computed public key bytes
|
|
172
|
+
*/
|
|
173
|
+
static getPublicKey(bytes: KeyBytes): KeyBytes;
|
|
174
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret.d.ts","sourceRoot":"","sources":["../../src/secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,EAEL,OAAO,EACP,GAAG,EACH,QAAQ,EAER,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,EAAE,QAAQ,CAAC;IAEhB;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,GAAG,EAAE,GAAG,CAAC;IAET;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;IAElC;;;OAGG;IACH,gBAAgB,IAAI,QAAQ,CAAC;IAE7B;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC;IAGnB;;;OAGG;IACH,IAAI,IAAI,eAAe,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,qBAAa,SAAU,YAAW,UAAU;IAC1C,sEAAsE;IACtE,OAAO,CAAC,MAAM,CAAC,CAAW;IAE1B,gEAAgE;IAChE,OAAO,CAAC,KAAK,CAAC,CAAS;IAEvB,4DAA4D;IAC5D,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;OAIG;gBACS,OAAO,EAAE,OAAO;IAyC5B;;;OAGG;IACH,IAAI,KAAK,IAAI,UAAU,CAItB;IAED;;;OAGG;IACH,IAAI,IAAI,IAAI,MAAM,CAIjB;IAED;;;OAGG;IACH,IAAI,GAAG,IAAI,GAAG,CAGb;IAGD;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAGtB;IAED;;;OAGG;IACI,MAAM,IAAI,MAAM;IAoBvB;;;;OAIG;IACI,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAKxC;;;OAGG;IACI,gBAAgB,IAAI,QAAQ;IAuBnC;;;OAGG;IACI,IAAI,IAAI,eAAe;IAQ9B;;;OAGG;IACI,OAAO,IAAI,OAAO;IAIzB;;;;OAIG;IACI,WAAW,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO;IAU1C;;;;OAIG;WACW,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK;IA8B9C;;;;OAIG;WACW,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS;IAIxD;;;;;OAKG;WACW,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,cAAc;IAWxD;;;;OAIG;WACW,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAI/C;;;;OAIG;WACW,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAiB/C;;;;OAIG;WACW,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IASnD;;;OAGG;WACW,MAAM,IAAI,QAAQ;IAShC;;;OAGG;WACW,QAAQ,IAAI,SAAS;IAQnC;;;;OAIG;WACW,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ;CAItD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@did-btcr2/keypair",
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "JavaScript/TypeScript implementation of secp256k1 public/private key pairs with BIP340 schnorr signatures. Used by various parts of the did-btcr2-js monorepo.",
|
|
6
|
+
"main": "./dist/cjs/index.js",
|
|
7
|
+
"module": "./dist/esm/index.js",
|
|
8
|
+
"types": "./dist/types/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
12
|
+
"import": "./dist/esm/index.js",
|
|
13
|
+
"require": "./dist/cjs/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"license": "MPL-2.0",
|
|
21
|
+
"contributors": [
|
|
22
|
+
{
|
|
23
|
+
"name": "dcdpr",
|
|
24
|
+
"url": "https://github.com/dcdpr"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "jintekc",
|
|
28
|
+
"url": "https://github.com/jintekc",
|
|
29
|
+
"email": "github@jintek.consulting"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"homepage": "https://github.com/dcdpr/did-btcr2-js/tree/main/packages/keypair",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+ssh://git@github.com:dcdpr/did-btcr2-js.git",
|
|
36
|
+
"directory": "packages/keypair"
|
|
37
|
+
},
|
|
38
|
+
"bugs": "https://github.com/dcdpr/did-btcr2-js/issues",
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.0.0"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"did",
|
|
47
|
+
"dids",
|
|
48
|
+
"decentralized identity",
|
|
49
|
+
"decentralized identifiers",
|
|
50
|
+
"did method",
|
|
51
|
+
"did:btcr2",
|
|
52
|
+
"bitcoin",
|
|
53
|
+
"schnorr",
|
|
54
|
+
"schnorr signatures",
|
|
55
|
+
"secp256k1",
|
|
56
|
+
"secp256k1 key pair",
|
|
57
|
+
"cryptosuite",
|
|
58
|
+
"bip340",
|
|
59
|
+
"bip340 key pair"
|
|
60
|
+
],
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@noble/hashes": "^1.7.1",
|
|
63
|
+
"multiformats": "^13.3.2",
|
|
64
|
+
"tiny-secp256k1": "^2.2.3",
|
|
65
|
+
"@did-btcr2/common": "2.0.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@eslint/js": "^9.20.0",
|
|
69
|
+
"@types/chai": "^5.0.1",
|
|
70
|
+
"@types/chai-as-promised": "^8.0.1",
|
|
71
|
+
"@types/eslint": "^9.6.1",
|
|
72
|
+
"@types/mocha": "^10.0.10",
|
|
73
|
+
"@types/node": "^22.13.4",
|
|
74
|
+
"@typescript-eslint/eslint-plugin": "^8.24.1",
|
|
75
|
+
"@typescript-eslint/parser": "^8.24.1",
|
|
76
|
+
"c8": "^10.1.3",
|
|
77
|
+
"chai": "^5.2.0",
|
|
78
|
+
"chai-as-promised": "^8.0.1",
|
|
79
|
+
"esbuild": "^0.25.0",
|
|
80
|
+
"eslint": "^9.20.1",
|
|
81
|
+
"eslint-plugin-mocha": "^10.5.0",
|
|
82
|
+
"globals": "^15.15.0",
|
|
83
|
+
"mocha": "^11.1.0",
|
|
84
|
+
"mocha-junit-reporter": "^2.2.1",
|
|
85
|
+
"node-stdlib-browser": "^1.3.1",
|
|
86
|
+
"rimraf": "^6.0.1",
|
|
87
|
+
"typedoc-plugin-markdown": "^4.7.0",
|
|
88
|
+
"typescript": "^5.7.3",
|
|
89
|
+
"typescript-eslint": "^8.24.1"
|
|
90
|
+
},
|
|
91
|
+
"scripts": {
|
|
92
|
+
"clean": "rimraf dist coverage tests/compiled",
|
|
93
|
+
"clean:build": "rimraf dist",
|
|
94
|
+
"clean:coverage": "rimraf coverage",
|
|
95
|
+
"clean:tests": "rimraf tests/compiled",
|
|
96
|
+
"clean:test-coverage": "pnpm clean:tests && pnpm clean:coverage",
|
|
97
|
+
"wipe": "rimraf node_modules pnpm-lock.json",
|
|
98
|
+
"wipe:clean": "pnpm wipe && pnpm clean",
|
|
99
|
+
"wipe:install": "pnpm wipe && pnpm install",
|
|
100
|
+
"clean:install": "pnpm clean && pnpm install",
|
|
101
|
+
"wipe:clean:install": "pnpm wipe:clean && pnpm install",
|
|
102
|
+
"reinstall": "pnpm install --force",
|
|
103
|
+
"build": "pnpm clean && pnpm build:esm && pnpm build:cjs",
|
|
104
|
+
"build:esm": "rimraf dist/esm dist/types && pnpm tsc -p tsconfig.json",
|
|
105
|
+
"build:cjs": "rimraf dist/cjs && tsc -p tsconfig.cjs.json && echo '{\"type\": \"commonjs\"}' > ./dist/cjs/package.json",
|
|
106
|
+
"build:tests": "pnpm tsc -p tests/tsconfig.json",
|
|
107
|
+
"build:docs": "typedoc --options typedoc.json",
|
|
108
|
+
"build:all": "pnpm build && pnpm build:tests && pnpm build:docs",
|
|
109
|
+
"release": "pnpm build && pnpm pack && mv *.tgz ../../release/key-pair",
|
|
110
|
+
"lint": "eslint . --max-warnings 0",
|
|
111
|
+
"lint:fix": "eslint . --fix",
|
|
112
|
+
"test": "pnpm c8 mocha",
|
|
113
|
+
"build:test": "pnpm build && pnpm build:tests && pnpm c8 mocha",
|
|
114
|
+
"build:lint:test": "pnpm build && pnpm build:tests && pnpm lint:fix",
|
|
115
|
+
"prepublish": "pnpm build",
|
|
116
|
+
"version": "pnpm version",
|
|
117
|
+
"version:no-git": "pnpm version --no-commit-hooks --no-git-tag-version",
|
|
118
|
+
"version:new": "[ -z \"$NEW_VERSION\" ] && echo 'ERROR: NEW_VERSION is not set' && exit 1 || (git checkout -b $NEW_VERSION && git tag $NEW_VERSION && pnpm version:no-git $NEW_VERSION)"
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/index.ts
ADDED
package/src/pair.ts
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Hex,
|
|
3
|
+
KeyBytes,
|
|
4
|
+
KeyPairError,
|
|
5
|
+
SchnorrKeyPairObject
|
|
6
|
+
} from '@did-btcr2/common';
|
|
7
|
+
import { PublicKey } from './public.js';
|
|
8
|
+
import { SecretKey } from './secret.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Interface for KeyPair class.
|
|
12
|
+
* @interface KeyPair
|
|
13
|
+
* @type {KeyPair}
|
|
14
|
+
*/
|
|
15
|
+
export interface KeyPair {
|
|
16
|
+
/**
|
|
17
|
+
* @type {PublicKey} The PublicKey associated with the SchnorrKeyPair (required).
|
|
18
|
+
*/
|
|
19
|
+
readonly publicKey: PublicKey;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @type {SecretKey} The SecretKey associated with the SchnorrKeyPair (optional).
|
|
23
|
+
* @throws {KeyPairError} If the secret key is not available.
|
|
24
|
+
*/
|
|
25
|
+
readonly secretKey?: SecretKey;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* JSON representation of the SchnorrKeyPair object.
|
|
29
|
+
* @returns {SchnorrKeyPairObject} The SchnorrKeyPair as a JSON object.
|
|
30
|
+
*/
|
|
31
|
+
json(): SchnorrKeyPairObject;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type RawKeyPair = {
|
|
35
|
+
public: KeyBytes;
|
|
36
|
+
secret?: KeyBytes
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Params for the {@link SchnorrKeyPair} constructor */
|
|
40
|
+
interface KeyParams {
|
|
41
|
+
secretKey?: SecretKey | KeyBytes;
|
|
42
|
+
publicKey?: PublicKey | KeyBytes;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface MultibaseKeys {
|
|
46
|
+
publicKeyMultibase: string;
|
|
47
|
+
secretKeyMultibase: string
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Encapsulates a PublicKey and a SecretKey object as a single Keys object.
|
|
51
|
+
* @class SchnorrKeyPair
|
|
52
|
+
* @type {SchnorrKeyPair}
|
|
53
|
+
*/
|
|
54
|
+
export class SchnorrKeyPair implements KeyPair {
|
|
55
|
+
/** @type {SecretKey} The secret key object */
|
|
56
|
+
private _secretKey?: SecretKey;
|
|
57
|
+
|
|
58
|
+
/** @type {PublicKey} The public key object */;
|
|
59
|
+
private _publicKey: PublicKey;
|
|
60
|
+
|
|
61
|
+
/** @type {string} The public key in multibase format */
|
|
62
|
+
private _publicKeyMultibase: string;
|
|
63
|
+
|
|
64
|
+
/** @type {string} The secret key in multibase format */
|
|
65
|
+
private _secretKeyMultibase: string;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Creates an instance of Keys. Must provide a at least a secret key.
|
|
69
|
+
* Can optionally provide both a private and public key, but must be a valid pair.
|
|
70
|
+
* @param {SecretKey} secretKey The secret key object
|
|
71
|
+
*/
|
|
72
|
+
constructor({ secretKey, publicKey }: KeyParams = {}) {
|
|
73
|
+
// If no secret key or public key, throw an error
|
|
74
|
+
if (!publicKey && !secretKey) {
|
|
75
|
+
throw new KeyPairError('Argument missing: must at least provide a publicKey', 'CONSTRUCTOR_ERROR');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Set the secret key
|
|
79
|
+
if(secretKey instanceof Uint8Array) {
|
|
80
|
+
this._secretKey = new SecretKey(secretKey);
|
|
81
|
+
} else if (secretKey instanceof SecretKey) {
|
|
82
|
+
this._secretKey = secretKey;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Set the public key
|
|
86
|
+
if(publicKey instanceof PublicKey) {
|
|
87
|
+
this._publicKey = publicKey;
|
|
88
|
+
} else if (publicKey instanceof Uint8Array) {
|
|
89
|
+
this._publicKey = new PublicKey(publicKey);
|
|
90
|
+
} else {
|
|
91
|
+
this._publicKey = new PublicKey(this._secretKey!.computePublicKey());
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this._publicKeyMultibase = this._publicKey.multibase.address;
|
|
95
|
+
this._secretKeyMultibase = this._secretKey ? this._secretKey.multibase : '';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the SecretKey.
|
|
100
|
+
* @returns {SecretKey} The SecretKey object
|
|
101
|
+
* @throws {KeyPairError} If the secret key is not available
|
|
102
|
+
*/
|
|
103
|
+
get secretKey(): SecretKey {
|
|
104
|
+
// If the secret key is not available, throw an error
|
|
105
|
+
if(!this._secretKey) {
|
|
106
|
+
throw new KeyPairError('Secret key not available', 'SECRET_KEY_ERROR');
|
|
107
|
+
}
|
|
108
|
+
// If the secret key is not valid, throw an error
|
|
109
|
+
if(!this._secretKey.isValid()) {
|
|
110
|
+
throw new KeyPairError('Secret key is not valid', 'SECRET_KEY_ERROR');
|
|
111
|
+
}
|
|
112
|
+
// Return a copy of the secret key
|
|
113
|
+
const secretKey = this._secretKey;
|
|
114
|
+
return secretKey;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Set the PublicKey.
|
|
119
|
+
* @param {PublicKey} publicKey The PublicKey object
|
|
120
|
+
* @throws {KeyPairError} If the public key is not a valid pair with the secret key.
|
|
121
|
+
*/
|
|
122
|
+
set publicKey(publicKey: PublicKey) {
|
|
123
|
+
// If the public key is not a valid pair with the secret key, throw an error
|
|
124
|
+
if(this.secretKey && !this.secretKey.isValidPair(publicKey)) {
|
|
125
|
+
throw new KeyPairError('Public key is not a valid pair with the secret key', 'PUBLIC_KEY_ERROR');
|
|
126
|
+
}
|
|
127
|
+
this._publicKey = publicKey;
|
|
128
|
+
this._publicKeyMultibase = publicKey.multibase.address;
|
|
129
|
+
this._secretKeyMultibase = this._secretKey ? this._secretKey.multibase : '';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get the PublicKey.
|
|
134
|
+
* @returns {PublicKey} The PublicKey object
|
|
135
|
+
*/
|
|
136
|
+
get publicKey(): PublicKey {
|
|
137
|
+
const publicKey = this._publicKey;
|
|
138
|
+
return publicKey;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get the Keys as a raw key pair.
|
|
143
|
+
* @returns {RawKeyPair} The Keys as a raw key pair
|
|
144
|
+
*/
|
|
145
|
+
get raw(): RawKeyPair {
|
|
146
|
+
return {
|
|
147
|
+
public : this.publicKey.x,
|
|
148
|
+
secret : this.secretKey ? this.secretKey.bytes : undefined
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Get the Keys in multibase format.
|
|
154
|
+
* @returns {MultibaseKeys} The SecretKey in multibase format
|
|
155
|
+
*/
|
|
156
|
+
get multibase(): MultibaseKeys {
|
|
157
|
+
return {
|
|
158
|
+
publicKeyMultibase : this._publicKeyMultibase,
|
|
159
|
+
secretKeyMultibase : this._secretKeyMultibase,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* JSON representation of a Keys.
|
|
165
|
+
* @returns {SchnorrKeyPairObject} The Keys as a JSON object
|
|
166
|
+
*/
|
|
167
|
+
public json(): SchnorrKeyPairObject {
|
|
168
|
+
return {
|
|
169
|
+
secretKey : this.secretKey.json(),
|
|
170
|
+
publicKey : this.publicKey.json()
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Static method creates a new Keys from a JSON object.
|
|
176
|
+
* @param {SchnorrKeyPairObject} keys The JSON object to initialize the Keys.
|
|
177
|
+
* @returns {SchnorrKeyPair} The initialized Keys object.
|
|
178
|
+
*/
|
|
179
|
+
public static fromJSON(keys: SchnorrKeyPairObject): SchnorrKeyPair {
|
|
180
|
+
const secretKey = SecretKey.fromJSON(keys.secretKey);
|
|
181
|
+
const publicKey = PublicKey.fromJSON(keys.publicKey);
|
|
182
|
+
return new SchnorrKeyPair({ secretKey, publicKey });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Static method creates a new SchnorrKeyPair from a SecretKey object or secret key bytes.
|
|
187
|
+
* @param {SecretKey | KeyBytes} data The secret key bytes
|
|
188
|
+
* @returns {SchnorrKeyPair} A new SchnorrKeyPair object
|
|
189
|
+
*/
|
|
190
|
+
public static fromPrivateKey(data: SecretKey | KeyBytes): SchnorrKeyPair {
|
|
191
|
+
|
|
192
|
+
// If the secret key is a SecretKey object, get the raw bytes else use the bytes
|
|
193
|
+
const bytes = data instanceof SecretKey ? data.bytes : data;
|
|
194
|
+
|
|
195
|
+
// Throw error if the secret key is not 32 bytes
|
|
196
|
+
if(bytes.length !== 32) {
|
|
197
|
+
throw new KeyPairError('Invalid arg: must be 32 byte secret key', 'FROM_PRIVATE_KEY_ERROR');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// If pk Uint8Array, construct SecretKey object else use the object
|
|
201
|
+
const secretKey = data instanceof Uint8Array ? new SecretKey(data) : data;
|
|
202
|
+
|
|
203
|
+
// Compute the public key from the secret key
|
|
204
|
+
const publicKey = secretKey.computePublicKey();
|
|
205
|
+
|
|
206
|
+
// Return a new Keys object
|
|
207
|
+
return new SchnorrKeyPair({ secretKey, publicKey });
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Static method creates a new Keys (SecretKey/PublicKey) bigint secret.
|
|
212
|
+
* @param {bigint} secret The secret key secret
|
|
213
|
+
* @returns {Keys} A new Keys object
|
|
214
|
+
*/
|
|
215
|
+
public static fromSecret(secret: bigint): SchnorrKeyPair {
|
|
216
|
+
const secretKey = SecretKey.fromSecret(secret);
|
|
217
|
+
const publicKey = secretKey.computePublicKey();
|
|
218
|
+
return new SchnorrKeyPair({ secretKey, publicKey });
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Converts key bytes to a hex string.
|
|
223
|
+
* @param {KeyBytes} keyBytes The key bytes (private or public).
|
|
224
|
+
* @returns {Hex} The key bytes as a hex string.
|
|
225
|
+
*/
|
|
226
|
+
public static toHex(keyBytes: KeyBytes): Hex {
|
|
227
|
+
return Buffer.from(keyBytes).toString('hex');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Compares two Keys objects for equality.
|
|
232
|
+
* @param {SchnorrKeyPair} keys The main keys.
|
|
233
|
+
* @param {SchnorrKeyPair} otherKeys The other keys to compare.
|
|
234
|
+
* @returns {boolean} True if the public key and secret key are equal, false otherwise.
|
|
235
|
+
*/
|
|
236
|
+
public static equals(keys: SchnorrKeyPair, otherKeys: SchnorrKeyPair): boolean {
|
|
237
|
+
// Deconstruct the public keys from the key pairs
|
|
238
|
+
const pk = keys.publicKey;
|
|
239
|
+
const otherPk = otherKeys.publicKey;
|
|
240
|
+
|
|
241
|
+
// If publicKeys present, use to compare as hex strings.
|
|
242
|
+
if(pk && otherPk) {
|
|
243
|
+
return pk.hex === otherPk.hex;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Deconstruct the private keys from the key pairs
|
|
247
|
+
const sk = keys.secretKey;
|
|
248
|
+
const otherSk = otherKeys.secretKey;
|
|
249
|
+
if(sk && otherSk) {
|
|
250
|
+
// Get the public key hex strings for both key pair publicKeys
|
|
251
|
+
return sk.hex === otherSk.hex;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
throw new KeyPairError('Cannot compare invalid key pair(s)', 'KEYPAIR_EQUALS_ERROR');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Static method to generate a new random SchnorrKeyPair instance.
|
|
259
|
+
* @returns {SchnorrKeyPair} A new SecretKey object.
|
|
260
|
+
*/
|
|
261
|
+
public static generate(): SchnorrKeyPair {
|
|
262
|
+
// Generate random secret key bytes
|
|
263
|
+
const skBytes = SecretKey.random();
|
|
264
|
+
|
|
265
|
+
// Construct a new SecretKey object
|
|
266
|
+
const secretKey = new SecretKey(skBytes);
|
|
267
|
+
|
|
268
|
+
// Compute the public key from the secret key
|
|
269
|
+
const publicKey = secretKey.computePublicKey();
|
|
270
|
+
|
|
271
|
+
// Return a new Keys object
|
|
272
|
+
return new SchnorrKeyPair({ secretKey, publicKey });
|
|
273
|
+
}
|
|
274
|
+
}
|