@did-btcr2/kms 0.2.0 → 0.4.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/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/kms.js +161 -202
- package/dist/cjs/kms.js.map +1 -1
- package/dist/cjs/store.js +13 -77
- package/dist/cjs/store.js.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/kms.js +161 -202
- package/dist/esm/kms.js.map +1 -1
- package/dist/esm/store.js +13 -77
- package/dist/esm/store.js.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/interface.d.ts +77 -47
- package/dist/types/interface.d.ts.map +1 -1
- package/dist/types/kms.d.ts +82 -70
- package/dist/types/kms.d.ts.map +1 -1
- package/dist/types/store.d.ts +15 -105
- package/dist/types/store.d.ts.map +1 -1
- package/package.json +3 -5
- package/src/index.ts +0 -1
- package/src/interface.ts +84 -46
- package/src/kms.ts +185 -237
- package/src/store.ts +24 -113
- package/dist/cjs/signer.js +0 -53
- package/dist/cjs/signer.js.map +0 -1
- package/dist/esm/signer.js +0 -53
- package/dist/esm/signer.js.map +0 -1
- package/dist/types/signer.d.ts +0 -48
- package/dist/types/signer.d.ts.map +0 -1
- package/src/signer.ts +0 -60
package/src/kms.ts
CHANGED
|
@@ -1,324 +1,272 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Bytes,
|
|
3
|
+
HashBytes,
|
|
4
|
+
KeyBytes,
|
|
5
|
+
KeyManagerError,
|
|
6
|
+
SignatureBytes
|
|
7
|
+
} from '@did-btcr2/common';
|
|
2
8
|
import { SchnorrKeyPair } from '@did-btcr2/keypair';
|
|
3
9
|
import { sha256 } from '@noble/hashes/sha2.js';
|
|
4
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
GenerateKeyOptions,
|
|
12
|
+
ImportKeyOptions,
|
|
13
|
+
KeyEntry,
|
|
14
|
+
KeyIdentifier,
|
|
15
|
+
KeyManager,
|
|
16
|
+
SignOptions,
|
|
17
|
+
} from './interface.js';
|
|
5
18
|
import { KeyValueStore, MemoryStore } from './store.js';
|
|
6
19
|
|
|
7
20
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @
|
|
21
|
+
* Key Management System for the did:btcr2 DID method.
|
|
22
|
+
*
|
|
23
|
+
* Implements the {@link KeyManager} interface with a pluggable
|
|
24
|
+
* {@link KeyValueStore} (defaults to {@link MemoryStore}).
|
|
25
|
+
*
|
|
26
|
+
* Supports both signing (secret key present) and watch-only
|
|
27
|
+
* (public-key-only) key entries, and both Schnorr and ECDSA
|
|
28
|
+
* signature schemes.
|
|
29
|
+
*
|
|
11
30
|
*/
|
|
12
31
|
export class Kms implements KeyManager {
|
|
13
|
-
|
|
14
|
-
* Singleton instance of the Kms.
|
|
15
|
-
* @private
|
|
16
|
-
* @type {KeyManager}
|
|
17
|
-
*/
|
|
18
|
-
static #instance?: Kms;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The `store` is a private variable in `KeyManager`. It is a `KeyValueStore` instance used for
|
|
22
|
-
* storing and managing cryptographic keys. It allows the `KeyManager` class to save,
|
|
23
|
-
* retrieve, and handle keys efficiently within the local Key Management System (KMS) context.
|
|
24
|
-
* This variable can be configured to use different storage backends, like in-memory storage or
|
|
25
|
-
* persistent storage, providing flexibility in key management according to the application's
|
|
26
|
-
* requirements.
|
|
27
|
-
* @private
|
|
28
|
-
* @type {KeyValueStore<KeyIdentifier, KeyBytes>} The key store for managing cryptographic keys.
|
|
29
|
-
*/
|
|
30
|
-
#store: KeyValueStore<KeyIdentifier, KeyBytes>;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The `#activeKeyId` property is a string that points to the currently active key.
|
|
35
|
-
* It is used to identify the key that will be used for signing and verifying operations.
|
|
36
|
-
* This property is optional and can be set to a specific key ID when initializing the
|
|
37
|
-
* `KeyManager` instance. If not set, the key manager will use the default key id.
|
|
38
|
-
* @private
|
|
39
|
-
* @type {KeyIdentifier}
|
|
40
|
-
*/
|
|
32
|
+
#store: KeyValueStore<KeyIdentifier, KeyEntry>;
|
|
41
33
|
#activeKeyId?: KeyIdentifier;
|
|
42
34
|
|
|
43
35
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* managed during cryptographic operations.
|
|
36
|
+
* Create a new KMS instance.
|
|
37
|
+
*
|
|
38
|
+
* @param {KeyValueStore<KeyIdentifier, KeyEntry>} [store] Optional key-value store.
|
|
39
|
+
* Defaults to in-memory store if not provided.
|
|
49
40
|
*/
|
|
50
|
-
constructor(store?: KeyValueStore<KeyIdentifier,
|
|
51
|
-
|
|
52
|
-
this.#store = store ?? new MemoryStore<KeyIdentifier, KeyBytes>();
|
|
41
|
+
constructor(store?: KeyValueStore<KeyIdentifier, KeyEntry>) {
|
|
42
|
+
this.#store = store ?? new MemoryStore<KeyIdentifier, KeyEntry>();
|
|
53
43
|
}
|
|
54
44
|
|
|
55
45
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
46
|
+
* Get the active key identifier.
|
|
47
|
+
*
|
|
48
|
+
* @returns {KeyIdentifier | undefined} The active key identifier, or undefined if none is set.
|
|
58
49
|
*/
|
|
59
50
|
get activeKeyId(): KeyIdentifier | undefined {
|
|
60
51
|
return this.#activeKeyId;
|
|
61
52
|
}
|
|
62
53
|
|
|
63
54
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Get the key id
|
|
71
|
-
const keyId = id ?? this.#activeKeyId;
|
|
72
|
-
// Throw an error if no active key is set
|
|
73
|
-
if (!keyId) {
|
|
74
|
-
throw new KeyManagerError('No active key set', 'ACTIVE_KEY_URI_NOT_SET');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Get the secret key from the store, throw an error if not found
|
|
78
|
-
const _secretKey = this.#store.get(keyId);
|
|
79
|
-
if (!_secretKey) {
|
|
80
|
-
throw new KeyManagerError(`Key not found: ${keyId}`, 'KEY_NOT_FOUND');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Create a key pair from the secret key
|
|
84
|
-
const kp = new SchnorrKeyPair({ secretKey: _secretKey });
|
|
85
|
-
|
|
86
|
-
// Return the secret key
|
|
87
|
-
return kp;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Checks if a key with the given ID exists in the key store.
|
|
92
|
-
* @param {KeyIdentifier} id The ID of the key to check.
|
|
93
|
-
* @returns {boolean} A promise resolving to a boolean indicating if the key exists.
|
|
55
|
+
* Generate a URN-style key identifier from compressed public key bytes.
|
|
56
|
+
* Format: `urn:kms:secp256k1:<fingerprint>` where fingerprint is the
|
|
57
|
+
* first 8 bytes of SHA-256(publicKey), hex-encoded.
|
|
58
|
+
*
|
|
59
|
+
* @param {KeyBytes} publicKeyBytes Compressed secp256k1 public key bytes.
|
|
60
|
+
* @returns {KeyIdentifier} The generated key identifier.
|
|
94
61
|
*/
|
|
95
|
-
#
|
|
96
|
-
const
|
|
97
|
-
|
|
62
|
+
#generateUrn(publicKeyBytes: KeyBytes): KeyIdentifier {
|
|
63
|
+
const hash = sha256(publicKeyBytes);
|
|
64
|
+
const fingerprint = Array.from(hash.slice(0, 8))
|
|
65
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
66
|
+
.join('');
|
|
67
|
+
return `urn:kms:secp256k1:${fingerprint}`;
|
|
98
68
|
}
|
|
99
69
|
|
|
100
70
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* @param {
|
|
104
|
-
* @
|
|
105
|
-
* @
|
|
106
|
-
* @throws {KeyManagerError} If attempting to remove the active key without force.
|
|
71
|
+
* Retrieve a key entry or throw if not found / no active key set.
|
|
72
|
+
*
|
|
73
|
+
* @param {KeyIdentifier} [id] Key identifier. Uses active key if omitted.
|
|
74
|
+
* @returns {KeyEntry} The retrieved key entry.
|
|
75
|
+
* @throws {KeyManagerError} If key not found or no active key set.
|
|
107
76
|
*/
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (
|
|
111
|
-
throw new KeyManagerError('
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Check if the key exists, if not throw an error
|
|
115
|
-
if (!this.#exists(id)) {
|
|
116
|
-
throw new KeyManagerError(`Key not found: ${id}`, 'KEY_NOT_FOUND');
|
|
77
|
+
#getEntryOrThrow(id?: KeyIdentifier): KeyEntry {
|
|
78
|
+
const keyId = id ?? this.#activeKeyId;
|
|
79
|
+
if (!keyId) {
|
|
80
|
+
throw new KeyManagerError('No active key set', 'ACTIVE_KEY_NOT_SET');
|
|
117
81
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// Clear the active key if it was the one removed
|
|
123
|
-
if (this.#activeKeyId === id) {
|
|
124
|
-
this.#activeKeyId = undefined;
|
|
82
|
+
const entry = this.#store.get(keyId);
|
|
83
|
+
if (!entry) {
|
|
84
|
+
throw new KeyManagerError(`Key not found: ${keyId}`, 'KEY_NOT_FOUND');
|
|
125
85
|
}
|
|
86
|
+
return entry;
|
|
126
87
|
}
|
|
127
88
|
|
|
128
89
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
|
|
132
|
-
listKeys(): KeyIdentifier[] {
|
|
133
|
-
return this.#store.entries().flatMap(([k, _]) => [k as KeyIdentifier]);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Sets the active key to the key associated with the given ID.
|
|
138
|
-
* @param {KeyIdentifier} id The ID of the key to set as active.
|
|
139
|
-
* @returns {Promise<void>} A promise that resolves when the active key is set.
|
|
90
|
+
* Set the active key.
|
|
91
|
+
*
|
|
92
|
+
* @param id The key identifier to set as active.
|
|
140
93
|
* @throws {KeyManagerError} If the key is not found.
|
|
141
94
|
*/
|
|
142
95
|
setActiveKey(id: KeyIdentifier): void {
|
|
143
|
-
|
|
144
|
-
this.#getKeyOrThrow(id);
|
|
145
|
-
|
|
146
|
-
// Set the active key ID
|
|
96
|
+
this.#getEntryOrThrow(id);
|
|
147
97
|
this.#activeKeyId = id;
|
|
148
98
|
}
|
|
149
99
|
|
|
150
100
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* @
|
|
101
|
+
* Get the compressed public key bytes for a key.
|
|
102
|
+
*
|
|
103
|
+
* @param id Key identifier. Uses active key if omitted.
|
|
104
|
+
* @returns Compressed secp256k1 public key bytes.
|
|
105
|
+
* @throws {KeyManagerError} If key not found or no active key set.
|
|
154
106
|
*/
|
|
155
107
|
getPublicKey(id?: KeyIdentifier): KeyBytes {
|
|
156
|
-
|
|
157
|
-
const { publicKey } = this.#getKeyOrThrow(id);
|
|
158
|
-
|
|
159
|
-
// Return the public key bytes
|
|
160
|
-
return publicKey.compressed;
|
|
108
|
+
return this.#getEntryOrThrow(id).publicKey;
|
|
161
109
|
}
|
|
162
110
|
|
|
163
111
|
/**
|
|
164
|
-
*
|
|
112
|
+
* Sign data using the specified key.
|
|
113
|
+
*
|
|
165
114
|
* @param {Bytes} data The data to sign.
|
|
166
|
-
* @param {KeyIdentifier} [id]
|
|
167
|
-
* @
|
|
115
|
+
* @param {KeyIdentifier} [id] Key identifier. Uses active key if omitted.
|
|
116
|
+
* @param {SignOptions} [options] Signing options (scheme defaults to 'schnorr').
|
|
117
|
+
* @returns {SignatureBytes} The signature bytes.
|
|
118
|
+
* @throws {KeyManagerError} If key not found, no active key, or key cannot sign.
|
|
168
119
|
*/
|
|
169
|
-
sign(data: Bytes, id?: KeyIdentifier): SignatureBytes {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if(!secretKey) {
|
|
175
|
-
throw new KeyManagerError(`Key ID ${id} is not a signer`, 'KEY_NOT_SIGNER');
|
|
120
|
+
sign(data: Bytes, id?: KeyIdentifier, options: SignOptions = {}): SignatureBytes {
|
|
121
|
+
const entry = this.#getEntryOrThrow(id);
|
|
122
|
+
if (!entry.secretKey) {
|
|
123
|
+
const keyId = id ?? this.#activeKeyId;
|
|
124
|
+
throw new KeyManagerError(`Key is not a signing key: ${keyId}`, 'KEY_NOT_SIGNER');
|
|
176
125
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return secretKey.sign(data);
|
|
126
|
+
const kp = new SchnorrKeyPair({ secretKey: entry.secretKey });
|
|
127
|
+
return kp.secretKey.sign(data, { scheme: options.scheme ?? 'schnorr' });
|
|
180
128
|
}
|
|
181
129
|
|
|
182
130
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* @param {SignatureBytes} signature The signature to verify.
|
|
186
|
-
* @param {
|
|
187
|
-
* @
|
|
131
|
+
* Verify a signature using the specified key.
|
|
132
|
+
*
|
|
133
|
+
* @param {SignatureBytes} signature The signature bytes to verify.
|
|
134
|
+
* @param {Bytes} data The data that was signed.
|
|
135
|
+
* @param {KeyIdentifier} [id] Key identifier. Uses active key if omitted.
|
|
136
|
+
* @param {SignOptions} [options] Verification options (scheme defaults to 'schnorr').
|
|
137
|
+
* @returns {boolean} True if the signature is valid, false otherwise.
|
|
138
|
+
* @throws {KeyManagerError} If key not found or no active key set.
|
|
188
139
|
*/
|
|
189
|
-
verify(signature: SignatureBytes, data: Bytes, id?: KeyIdentifier): boolean {
|
|
190
|
-
|
|
191
|
-
const { publicKey }
|
|
192
|
-
|
|
193
|
-
// Verify the signature using the multikey
|
|
194
|
-
return publicKey.verify(signature, data);
|
|
140
|
+
verify(signature: SignatureBytes, data: Bytes, id?: KeyIdentifier, options: SignOptions = {}): boolean {
|
|
141
|
+
const entry = this.#getEntryOrThrow(id);
|
|
142
|
+
const kp = new SchnorrKeyPair({ publicKey: entry.publicKey });
|
|
143
|
+
return kp.publicKey.verify(signature, data, { scheme: options.scheme ?? 'schnorr' });
|
|
195
144
|
}
|
|
196
145
|
|
|
197
146
|
/**
|
|
198
|
-
*
|
|
147
|
+
* Import a key pair into the KMS.
|
|
148
|
+
*
|
|
199
149
|
* @param {SchnorrKeyPair} keyPair The key pair to import.
|
|
200
|
-
* @param {
|
|
201
|
-
* @
|
|
202
|
-
* @
|
|
203
|
-
* @returns {Promise<KeyIdentifier>} A promise resolving to the ID of the imported key.
|
|
150
|
+
* @param {ImportKeyOptions} [options] Import options (id, tags, setActive).
|
|
151
|
+
* @returns {KeyIdentifier} The identifier of the imported key.
|
|
152
|
+
* @throws {KeyManagerError} If a key with the same identifier already exists.
|
|
204
153
|
*/
|
|
205
|
-
importKey(
|
|
206
|
-
keyPair
|
|
207
|
-
options: {
|
|
208
|
-
id?: KeyIdentifier;
|
|
209
|
-
setActive?: boolean
|
|
210
|
-
} = {}
|
|
211
|
-
): KeyIdentifier {
|
|
212
|
-
// Ensure the key pair has a public key
|
|
213
|
-
if(!keyPair.publicKey) {
|
|
214
|
-
keyPair.publicKey = keyPair.secretKey.computePublicKey();
|
|
215
|
-
}
|
|
154
|
+
importKey(keyPair: SchnorrKeyPair, options: ImportKeyOptions = {}): KeyIdentifier {
|
|
155
|
+
const id = options.id ?? this.#generateUrn(keyPair.publicKey.compressed);
|
|
216
156
|
|
|
217
|
-
|
|
218
|
-
const id = options.id ?? (keyPair.publicKey.hex as string);
|
|
219
|
-
|
|
220
|
-
// Check if the key already exists
|
|
221
|
-
if (this.#exists(id)) {
|
|
157
|
+
if (this.#store.has(id)) {
|
|
222
158
|
throw new KeyManagerError(`Key already exists: ${id}`, 'KEY_FOUND');
|
|
223
159
|
}
|
|
224
160
|
|
|
225
|
-
//
|
|
226
|
-
|
|
161
|
+
// Build key entry — secret key may not be available for watch-only pairs
|
|
162
|
+
const entry: KeyEntry = {
|
|
163
|
+
publicKey : keyPair.publicKey.compressed,
|
|
164
|
+
...(options.tags && { tags: options.tags }),
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
if (keyPair.secretKey) {
|
|
169
|
+
entry.secretKey = keyPair.secretKey.bytes;
|
|
170
|
+
}
|
|
171
|
+
} catch {
|
|
172
|
+
// Public-key-only key pair — secretKey getter throws
|
|
173
|
+
}
|
|
227
174
|
|
|
228
|
-
|
|
229
|
-
const setActive = options.setActive ?? true;
|
|
175
|
+
this.#store.set(id, entry);
|
|
230
176
|
|
|
231
|
-
|
|
232
|
-
if (setActive) {
|
|
177
|
+
if (options.setActive) {
|
|
233
178
|
this.#activeKeyId = id;
|
|
234
179
|
}
|
|
235
180
|
|
|
236
|
-
// Return the key ID
|
|
237
181
|
return id;
|
|
238
182
|
}
|
|
239
183
|
|
|
240
184
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* @
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Generates a new key pair and stores it in the key store.
|
|
251
|
-
* @returns {KeyIdentifier} The key identifier of the generated key.
|
|
185
|
+
* Remove a key from the KMS.
|
|
186
|
+
*
|
|
187
|
+
* @param {KeyIdentifier} id The key identifier to remove.
|
|
188
|
+
* @param {Object} [options] Removal options.
|
|
189
|
+
* @param {boolean} [options.force=false] Force removal of active key.
|
|
190
|
+
* @throws {KeyManagerError} If key not found or attempting to remove active key without force.
|
|
252
191
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
192
|
+
removeKey(id: KeyIdentifier, options: { force?: boolean } = {}): void {
|
|
193
|
+
if (this.#activeKeyId === id && !options.force) {
|
|
194
|
+
throw new KeyManagerError(
|
|
195
|
+
'Cannot remove active key (use "force": true or switch active key)',
|
|
196
|
+
'ACTIVE_KEY_DELETE'
|
|
197
|
+
);
|
|
198
|
+
}
|
|
256
199
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
200
|
+
if (!this.#store.has(id)) {
|
|
201
|
+
throw new KeyManagerError(`Key not found: ${id}`, 'KEY_NOT_FOUND');
|
|
202
|
+
}
|
|
260
203
|
|
|
261
|
-
|
|
262
|
-
this.#activeKeyId = id;
|
|
204
|
+
this.#store.delete(id);
|
|
263
205
|
|
|
264
|
-
|
|
265
|
-
|
|
206
|
+
if (this.#activeKeyId === id) {
|
|
207
|
+
this.#activeKeyId = undefined;
|
|
208
|
+
}
|
|
266
209
|
}
|
|
267
210
|
|
|
268
211
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
* @
|
|
272
|
-
* @returns {void}
|
|
212
|
+
* List all key identifiers in the KMS.
|
|
213
|
+
*
|
|
214
|
+
* @returns {KeyIdentifier[]} Array of key identifiers.
|
|
273
215
|
*/
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
console.warn('WARNING: Kms global instance is already initialized.');
|
|
278
|
-
return Kms.#instance;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Check if the keypair is provided
|
|
282
|
-
if(!keyPair) {
|
|
283
|
-
// Log a warning message if not provided
|
|
284
|
-
console.warn('WARNING: secretKey not provided, generating new SchnorrKeyPair ...');
|
|
285
|
-
}
|
|
216
|
+
listKeys(): KeyIdentifier[] {
|
|
217
|
+
return this.#store.entries().map(([k]) => k);
|
|
218
|
+
}
|
|
286
219
|
|
|
287
|
-
|
|
288
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Compute the SHA-256 digest of the given data.
|
|
222
|
+
*
|
|
223
|
+
* @param {Uint8Array} data The data to digest.
|
|
224
|
+
* @returns {HashBytes} The SHA-256 hash of the data.
|
|
225
|
+
*/
|
|
226
|
+
digest(data: Uint8Array): HashBytes {
|
|
227
|
+
return sha256(data);
|
|
228
|
+
}
|
|
289
229
|
|
|
290
|
-
|
|
291
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Generate a new secp256k1 key pair and store it in the KMS.
|
|
232
|
+
*
|
|
233
|
+
* @param {GenerateKeyOptions} [options] Generation options (tags, setActive).
|
|
234
|
+
* @returns {KeyIdentifier} The identifier of the generated key.
|
|
235
|
+
*/
|
|
236
|
+
generateKey(options: GenerateKeyOptions = {}): KeyIdentifier {
|
|
237
|
+
const kp = SchnorrKeyPair.generate();
|
|
238
|
+
const id = this.#generateUrn(kp.publicKey.compressed);
|
|
292
239
|
|
|
293
|
-
|
|
294
|
-
|
|
240
|
+
const entry: KeyEntry = {
|
|
241
|
+
secretKey : kp.secretKey.bytes,
|
|
242
|
+
publicKey : kp.publicKey.compressed,
|
|
243
|
+
...(options.tags && { tags: options.tags }),
|
|
244
|
+
};
|
|
295
245
|
|
|
296
|
-
|
|
297
|
-
Kms.#instance.#activeKeyId = id;
|
|
246
|
+
this.#store.set(id, entry);
|
|
298
247
|
|
|
299
|
-
|
|
300
|
-
|
|
248
|
+
if (options.setActive) {
|
|
249
|
+
this.#activeKeyId = id;
|
|
250
|
+
}
|
|
301
251
|
|
|
302
|
-
|
|
303
|
-
return Kms.#instance;
|
|
252
|
+
return id;
|
|
304
253
|
}
|
|
305
254
|
|
|
306
255
|
/**
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
* @
|
|
256
|
+
* Export the key pair for a stored key.
|
|
257
|
+
*
|
|
258
|
+
* Only available on the concrete {@link Kms} class, not on the
|
|
259
|
+
* {@link KeyManager} interface. HSM or hardware-backed implementations
|
|
260
|
+
* may not support key export.
|
|
261
|
+
*
|
|
262
|
+
* @param {KeyIdentifier} id The key identifier to export.
|
|
263
|
+
* @returns {SchnorrKeyPair} The reconstructed SchnorrKeyPair.
|
|
311
264
|
*/
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if(
|
|
315
|
-
|
|
265
|
+
exportKey(id: KeyIdentifier): SchnorrKeyPair {
|
|
266
|
+
const entry = this.#getEntryOrThrow(id);
|
|
267
|
+
if (entry.secretKey) {
|
|
268
|
+
return new SchnorrKeyPair({ secretKey: entry.secretKey });
|
|
316
269
|
}
|
|
317
|
-
|
|
318
|
-
// Use the active key ID if not provided
|
|
319
|
-
id ??= Kms.#instance.activeKeyId;
|
|
320
|
-
|
|
321
|
-
// Instantiate a new Kms with the default key store
|
|
322
|
-
return Kms.#instance.#getKeyOrThrow(id);
|
|
270
|
+
return new SchnorrKeyPair({ publicKey: entry.publicKey });
|
|
323
271
|
}
|
|
324
|
-
}
|
|
272
|
+
}
|