@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.
@@ -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
@@ -0,0 +1,3 @@
1
+ export * from './pair.js';
2
+ export * from './secret.js';
3
+ export * from './public.js';
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
+ }