@enbox/dids 0.0.3 → 0.0.5
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/browser.mjs +1 -1
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/methods/did-dht-dns.js +455 -0
- package/dist/esm/methods/did-dht-dns.js.map +1 -0
- package/dist/esm/methods/did-dht-pkarr.js +168 -0
- package/dist/esm/methods/did-dht-pkarr.js.map +1 -0
- package/dist/esm/methods/did-dht-types.js +116 -0
- package/dist/esm/methods/did-dht-types.js.map +1 -0
- package/dist/esm/methods/did-dht-utils.js +143 -0
- package/dist/esm/methods/did-dht-utils.js.map +1 -0
- package/dist/esm/methods/did-dht.js +65 -842
- package/dist/esm/methods/did-dht.js.map +1 -1
- package/dist/esm/methods/did-ion-utils.js +161 -0
- package/dist/esm/methods/did-ion-utils.js.map +1 -0
- package/dist/esm/methods/did-ion.js +4 -151
- package/dist/esm/methods/did-ion.js.map +1 -1
- package/dist/esm/methods/did-jwk.js.map +1 -1
- package/dist/esm/methods/did-key-utils.js +235 -0
- package/dist/esm/methods/did-key-utils.js.map +1 -0
- package/dist/esm/methods/did-key.js +6 -222
- package/dist/esm/methods/did-key.js.map +1 -1
- package/dist/esm/resolver/resolver-cache-memory.js +77 -0
- package/dist/esm/resolver/resolver-cache-memory.js.map +1 -0
- package/dist/esm/utils.js +25 -0
- package/dist/esm/utils.js.map +1 -1
- package/dist/types/bearer-did.d.ts +4 -4
- package/dist/types/bearer-did.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/methods/did-dht-dns.d.ts +114 -0
- package/dist/types/methods/did-dht-dns.d.ts.map +1 -0
- package/dist/types/methods/did-dht-pkarr.d.ts +56 -0
- package/dist/types/methods/did-dht-pkarr.d.ts.map +1 -0
- package/dist/types/methods/did-dht-types.d.ts +286 -0
- package/dist/types/methods/did-dht-types.d.ts.map +1 -0
- package/dist/types/methods/did-dht-utils.d.ts +54 -0
- package/dist/types/methods/did-dht-utils.d.ts.map +1 -0
- package/dist/types/methods/did-dht.d.ts +45 -460
- package/dist/types/methods/did-dht.d.ts.map +1 -1
- package/dist/types/methods/did-ion-utils.d.ts +86 -0
- package/dist/types/methods/did-ion-utils.d.ts.map +1 -0
- package/dist/types/methods/did-ion.d.ts +4 -84
- package/dist/types/methods/did-ion.d.ts.map +1 -1
- package/dist/types/methods/did-jwk.d.ts +4 -4
- package/dist/types/methods/did-jwk.d.ts.map +1 -1
- package/dist/types/methods/did-key-utils.d.ts +138 -0
- package/dist/types/methods/did-key-utils.d.ts.map +1 -0
- package/dist/types/methods/did-key.d.ts +6 -127
- package/dist/types/methods/did-key.d.ts.map +1 -1
- package/dist/types/methods/did-method.d.ts +3 -3
- package/dist/types/methods/did-method.d.ts.map +1 -1
- package/dist/types/resolver/resolver-cache-memory.d.ts +58 -0
- package/dist/types/resolver/resolver-cache-memory.d.ts.map +1 -0
- package/dist/types/utils.d.ts +19 -0
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +4 -4
- package/package.json +11 -13
- package/src/bearer-did.ts +4 -4
- package/src/index.ts +2 -0
- package/src/methods/did-dht-dns.ts +516 -0
- package/src/methods/did-dht-pkarr.ts +192 -0
- package/src/methods/did-dht-types.ts +316 -0
- package/src/methods/did-dht-utils.ts +157 -0
- package/src/methods/did-dht.ts +125 -1131
- package/src/methods/did-ion-utils.ts +186 -0
- package/src/methods/did-ion.ts +16 -185
- package/src/methods/did-jwk.ts +4 -4
- package/src/methods/did-key-utils.ts +258 -0
- package/src/methods/did-key.ts +20 -272
- package/src/methods/did-method.ts +3 -3
- package/src/resolver/resolver-cache-memory.ts +84 -0
- package/src/utils.ts +27 -0
- package/dist/browser.js +0 -73
- package/dist/browser.js.map +0 -7
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import type { AsymmetricKeyConverter, Jwk, KeyCompressor } from '@enbox/crypto';
|
|
2
|
+
import type { MulticodecCode, MulticodecDefinition } from '@enbox/common';
|
|
3
|
+
|
|
4
|
+
import { Multicodec } from '@enbox/common';
|
|
5
|
+
import { Ed25519, Secp256k1, Secp256r1 } from '@enbox/crypto';
|
|
6
|
+
|
|
7
|
+
import { keyBytesToMultibaseId } from '../utils.js';
|
|
8
|
+
import { DidError, DidErrorCode } from '../did-error.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Private helper that maps algorithm identifiers to their corresponding DID Key
|
|
12
|
+
* {@link DidKeyRegisteredKeyType | registered key type}.
|
|
13
|
+
*
|
|
14
|
+
* Note: This is also used by `DidKeyUtils.publicKeyToMultibaseId()` to validate key types.
|
|
15
|
+
*/
|
|
16
|
+
export const AlgorithmToKeyTypeMap = {
|
|
17
|
+
Ed25519 : 'Ed25519',
|
|
18
|
+
ES256K : 'secp256k1',
|
|
19
|
+
ES256 : 'secp256r1',
|
|
20
|
+
'P-256' : 'secp256r1',
|
|
21
|
+
secp256k1 : 'secp256k1',
|
|
22
|
+
secp256r1 : 'secp256r1',
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The `DidKeyUtils` class provides utility functions to support operations in the DID Key method.
|
|
27
|
+
*/
|
|
28
|
+
export class DidKeyUtils {
|
|
29
|
+
/**
|
|
30
|
+
* A mapping from JSON Web Key (JWK) property descriptors to multicodec names.
|
|
31
|
+
*
|
|
32
|
+
* This mapping is used to convert keys in JWK (JSON Web Key) format to multicodec format.
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* The keys of this object are strings that describe the JOSE key type and usage,
|
|
36
|
+
* such as 'Ed25519:public', 'Ed25519:private', etc. The values are the corresponding multicodec
|
|
37
|
+
* names used to represent these key types.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const multicodecName = JWK_TO_MULTICODEC['Ed25519:public'];
|
|
42
|
+
* // Returns 'ed25519-pub', the multicodec name for an Ed25519 public key
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
private static JWK_TO_MULTICODEC: { [key: string]: string } = {
|
|
46
|
+
'Ed25519:public' : 'ed25519-pub',
|
|
47
|
+
'Ed25519:private' : 'ed25519-priv',
|
|
48
|
+
'secp256k1:public' : 'secp256k1-pub',
|
|
49
|
+
'secp256k1:private' : 'secp256k1-priv',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Defines the expected byte lengths for public keys associated with different cryptographic
|
|
54
|
+
* algorithms, indexed by their multicodec code values.
|
|
55
|
+
*/
|
|
56
|
+
public static MULTICODEC_PUBLIC_KEY_LENGTH: Record<number, number> = {
|
|
57
|
+
// secp256k1-pub - Secp256k1 public key (compressed) - 33 bytes
|
|
58
|
+
0xe7: 33,
|
|
59
|
+
|
|
60
|
+
// ed25519-pub - Ed25519 public key - 32 bytes
|
|
61
|
+
0xed: 32
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A mapping from multicodec names to their corresponding JOSE (JSON Object Signing and Encryption)
|
|
66
|
+
* representations. This mapping facilitates the conversion of multicodec key formats to
|
|
67
|
+
* JWK (JSON Web Key) formats.
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* The keys of this object are multicodec names, such as 'ed25519-pub', 'ed25519-priv', etc.
|
|
71
|
+
* The values are objects representing the corresponding JWK properties for that key type.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const joseKey = MULTICODEC_TO_JWK['ed25519-pub'];
|
|
76
|
+
* // Returns a partial JWK for an Ed25519 public key
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
private static MULTICODEC_TO_JWK: { [key: string]: Jwk } = {
|
|
80
|
+
'ed25519-pub' : { crv: 'Ed25519', kty: 'OKP', x: '' },
|
|
81
|
+
'ed25519-priv' : { crv: 'Ed25519', kty: 'OKP', x: '', d: '' },
|
|
82
|
+
'secp256k1-pub' : { crv: 'secp256k1', kty: 'EC', x: '', y: '' },
|
|
83
|
+
'secp256k1-priv' : { crv: 'secp256k1', kty: 'EC', x: '', y: '', d: '' },
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Converts a JWK (JSON Web Key) to a Multicodec code and name.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const jwk: Jwk = { crv: 'Ed25519', kty: 'OKP', x: '...' };
|
|
92
|
+
* const { code, name } = await DidKeyUtils.jwkToMulticodec({ jwk });
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @param params - The parameters for the conversion.
|
|
96
|
+
* @param params.jwk - The JSON Web Key to be converted.
|
|
97
|
+
* @returns A promise that resolves to a Multicodec definition.
|
|
98
|
+
*/
|
|
99
|
+
public static async jwkToMulticodec({ jwk }: {
|
|
100
|
+
jwk: Jwk
|
|
101
|
+
}): Promise<MulticodecDefinition<MulticodecCode>> {
|
|
102
|
+
const params: string[] = [];
|
|
103
|
+
|
|
104
|
+
if (jwk.crv) {
|
|
105
|
+
params.push(jwk.crv);
|
|
106
|
+
if (jwk.d) {
|
|
107
|
+
params.push('private');
|
|
108
|
+
} else {
|
|
109
|
+
params.push('public');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const lookupKey = params.join(':');
|
|
114
|
+
const name = DidKeyUtils.JWK_TO_MULTICODEC[lookupKey];
|
|
115
|
+
|
|
116
|
+
if (name === undefined) {
|
|
117
|
+
throw new Error(`Unsupported JWK to Multicodec conversion: '${lookupKey}'`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const code = Multicodec.getCodeFromName({ name });
|
|
121
|
+
|
|
122
|
+
return { code, name };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Returns the appropriate public key compressor for the specified cryptographic curve.
|
|
127
|
+
*
|
|
128
|
+
* @param curve - The cryptographic curve to use for the key conversion.
|
|
129
|
+
* @returns A public key compressor for the specified curve.
|
|
130
|
+
*/
|
|
131
|
+
public static keyCompressor(
|
|
132
|
+
curve: string
|
|
133
|
+
): KeyCompressor['compressPublicKey'] {
|
|
134
|
+
// ): ({ publicKeyBytes }: { publicKeyBytes: Uint8Array }) => Promise<Uint8Array> {
|
|
135
|
+
const compressors = {
|
|
136
|
+
'P-256' : Secp256r1.compressPublicKey,
|
|
137
|
+
'secp256k1' : Secp256k1.compressPublicKey
|
|
138
|
+
} as Record<string, KeyCompressor['compressPublicKey']>;
|
|
139
|
+
|
|
140
|
+
const compressor = compressors[curve];
|
|
141
|
+
|
|
142
|
+
if (!compressor) {throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);}
|
|
143
|
+
|
|
144
|
+
return compressor;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Returns the appropriate key converter for the specified cryptographic curve.
|
|
149
|
+
*
|
|
150
|
+
* @param curve - The cryptographic curve to use for the key conversion.
|
|
151
|
+
* @returns An `AsymmetricKeyConverter` for the specified curve.
|
|
152
|
+
*/
|
|
153
|
+
public static keyConverter(curve: string): AsymmetricKeyConverter {
|
|
154
|
+
const converters: Record<string, AsymmetricKeyConverter> = {
|
|
155
|
+
'Ed25519' : Ed25519,
|
|
156
|
+
'P-256' : Secp256r1,
|
|
157
|
+
'secp256k1' : Secp256k1,
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const converter = converters[curve];
|
|
161
|
+
|
|
162
|
+
if (!converter) {throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);}
|
|
163
|
+
|
|
164
|
+
return converter;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Converts a Multicodec code or name to parial JWK (JSON Web Key).
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* const partialJwk = await DidKeyUtils.multicodecToJwk({ name: 'ed25519-pub' });
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* @param params - The parameters for the conversion.
|
|
176
|
+
* @param params.code - Optional Multicodec code to convert.
|
|
177
|
+
* @param params.name - Optional Multicodec name to convert.
|
|
178
|
+
* @returns A promise that resolves to a JOSE format key.
|
|
179
|
+
*/
|
|
180
|
+
public static async multicodecToJwk({ code, name }: {
|
|
181
|
+
code?: MulticodecCode,
|
|
182
|
+
name?: string
|
|
183
|
+
}): Promise<Jwk> {
|
|
184
|
+
// Either code or name must be specified, but not both.
|
|
185
|
+
if (!(name ? !code : code)) {
|
|
186
|
+
throw new Error(`Either 'name' or 'code' must be defined, but not both.`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// If name is undefined, lookup by code.
|
|
190
|
+
name = (name === undefined ) ? Multicodec.getNameFromCode({ code: code! }) : name;
|
|
191
|
+
|
|
192
|
+
const lookupKey = name;
|
|
193
|
+
const jose = DidKeyUtils.MULTICODEC_TO_JWK[lookupKey];
|
|
194
|
+
|
|
195
|
+
if (jose === undefined) {
|
|
196
|
+
throw new Error(`Unsupported Multicodec to JWK conversion`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return { ...jose };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Converts a public key in JWK (JSON Web Key) format to a multibase identifier.
|
|
204
|
+
*
|
|
205
|
+
* @remarks
|
|
206
|
+
* Note: All secp public keys are converted to compressed point encoding
|
|
207
|
+
* before the multibase identifier is computed.
|
|
208
|
+
*
|
|
209
|
+
* Per {@link https://github.com/multiformats/multicodec/blob/master/table.csv | Multicodec table}:
|
|
210
|
+
* Public keys for Elliptic Curve cryptography algorithms (e.g., secp256k1,
|
|
211
|
+
* secp256k1r1, secp384r1, etc.) are always represented with compressed point
|
|
212
|
+
* encoding (e.g., secp256k1-pub, p256-pub, p384-pub, etc.).
|
|
213
|
+
*
|
|
214
|
+
* Per {@link https://datatracker.ietf.org/doc/html/rfc8812#name-jose-and-cose-secp256k1-cur | RFC 8812}:
|
|
215
|
+
* "As a compressed point encoding representation is not defined for JWK
|
|
216
|
+
* elliptic curve points, the uncompressed point encoding defined there
|
|
217
|
+
* MUST be used. The x and y values represented MUST both be exactly
|
|
218
|
+
* 256 bits, with any leading zeros preserved."
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* const publicKey = { crv: 'Ed25519', kty: 'OKP', x: '...' };
|
|
223
|
+
* const multibaseId = await DidKeyUtils.publicKeyToMultibaseId({ publicKey });
|
|
224
|
+
* ```
|
|
225
|
+
*
|
|
226
|
+
* @param params - The parameters for the conversion.
|
|
227
|
+
* @param params.publicKey - The public key in JWK format.
|
|
228
|
+
* @returns A promise that resolves to the multibase identifier.
|
|
229
|
+
*/
|
|
230
|
+
public static async publicKeyToMultibaseId({ publicKey }: {
|
|
231
|
+
publicKey: Jwk
|
|
232
|
+
}): Promise<string> {
|
|
233
|
+
if (!(publicKey?.crv && publicKey.crv in AlgorithmToKeyTypeMap)) {
|
|
234
|
+
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Public key contains an unsupported key type: ${publicKey?.crv ?? 'undefined'}`);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Convert the public key from JWK format to a byte array.
|
|
238
|
+
let publicKeyBytes = await DidKeyUtils.keyConverter(publicKey.crv).publicKeyToBytes({ publicKey });
|
|
239
|
+
|
|
240
|
+
// Compress the public key if it is an elliptic curve key.
|
|
241
|
+
if (/^(secp256k1|P-256|P-384|P-521)$/.test(publicKey.crv)) {
|
|
242
|
+
publicKeyBytes = await DidKeyUtils.keyCompressor(publicKey.crv)({ publicKeyBytes });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Convert the JSON Web Key (JWK) parameters to a Multicodec name.
|
|
246
|
+
const { name: multicodecName } = await DidKeyUtils.jwkToMulticodec({ jwk: publicKey });
|
|
247
|
+
|
|
248
|
+
// Compute the multibase identifier based on the provided key.
|
|
249
|
+
const multibaseId = keyBytesToMultibaseId({
|
|
250
|
+
keyBytes: publicKeyBytes,
|
|
251
|
+
multicodecName
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
return multibaseId;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
|
package/src/methods/did-key.ts
CHANGED
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AsymmetricKeyConverter,
|
|
3
|
-
CryptoApi,
|
|
4
|
-
InferKeyGeneratorAlgorithm,
|
|
5
|
-
Jwk,
|
|
6
|
-
KeyCompressor,
|
|
7
|
-
KeyIdentifier,
|
|
8
|
-
KeyImporterExporter,
|
|
9
|
-
KmsExportKeyParams,
|
|
10
|
-
KmsImportKeyParams,
|
|
11
|
-
} from '@enbox/crypto';
|
|
12
|
-
import type { MulticodecCode, MulticodecDefinition } from '@enbox/common';
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
Ed25519,
|
|
16
|
-
LocalKeyManager,
|
|
17
|
-
Secp256k1,
|
|
18
|
-
Secp256r1,
|
|
19
|
-
} from '@enbox/crypto';
|
|
20
|
-
import { Multicodec, universalTypeOf } from '@enbox/common';
|
|
21
|
-
|
|
22
1
|
import type { PortableDid } from '../types/portable-did.js';
|
|
23
2
|
import type { DidCreateOptions, DidCreateVerificationMethod } from './did-method.js';
|
|
24
3
|
import type {
|
|
@@ -27,13 +6,25 @@ import type {
|
|
|
27
6
|
DidResolutionResult,
|
|
28
7
|
DidVerificationMethod,
|
|
29
8
|
} from '../types/did-core.js';
|
|
9
|
+
import type {
|
|
10
|
+
InferKeyGeneratorAlgorithm,
|
|
11
|
+
KeyIdentifier,
|
|
12
|
+
KeyImporterExporter,
|
|
13
|
+
KeyManager,
|
|
14
|
+
KmsExportKeyParams,
|
|
15
|
+
KmsImportKeyParams,
|
|
16
|
+
} from '@enbox/crypto';
|
|
17
|
+
|
|
18
|
+
import { universalTypeOf } from '@enbox/common';
|
|
19
|
+
import { Ed25519, LocalKeyManager, Secp256k1 } from '@enbox/crypto';
|
|
30
20
|
|
|
31
21
|
import { BearerDid } from '../bearer-did.js';
|
|
32
22
|
import { Did } from '../did.js';
|
|
23
|
+
import { DidKeyUtils } from './did-key-utils.js';
|
|
33
24
|
import { DidMethod } from './did-method.js';
|
|
34
25
|
import { EMPTY_DID_RESOLUTION_RESULT } from '../types/did-resolution.js';
|
|
35
26
|
import { DidError, DidErrorCode } from '../did-error.js';
|
|
36
|
-
import { getVerificationMethodTypes,
|
|
27
|
+
import { getVerificationMethodTypes, multibaseIdToKeyBytes } from '../utils.js';
|
|
37
28
|
|
|
38
29
|
/**
|
|
39
30
|
* Defines the set of options available when creating a new Decentralized Identifier (DID) with the
|
|
@@ -88,7 +79,7 @@ export interface DidKeyCreateOptions<TKms> extends DidCreateOptions<TKms> {
|
|
|
88
79
|
/**
|
|
89
80
|
* Optionally specify the algorithm to be used for key generation.
|
|
90
81
|
*/
|
|
91
|
-
algorithm?: TKms extends
|
|
82
|
+
algorithm?: TKms extends KeyManager
|
|
92
83
|
? InferKeyGeneratorAlgorithm<TKms>
|
|
93
84
|
: InferKeyGeneratorAlgorithm<LocalKeyManager>;
|
|
94
85
|
|
|
@@ -165,19 +156,6 @@ export const DidKeyVerificationMethodType = {
|
|
|
165
156
|
JsonWebKey2020: 'https://w3id.org/security/suites/jws-2020/v1',
|
|
166
157
|
} as const;
|
|
167
158
|
|
|
168
|
-
/**
|
|
169
|
-
* Private helper that maps algorithm identifiers to their corresponding DID Key
|
|
170
|
-
* {@link DidKeyRegisteredKeyType | registered key type}.
|
|
171
|
-
*/
|
|
172
|
-
const AlgorithmToKeyTypeMap = {
|
|
173
|
-
Ed25519 : DidKeyRegisteredKeyType.Ed25519,
|
|
174
|
-
ES256K : DidKeyRegisteredKeyType.secp256k1,
|
|
175
|
-
ES256 : DidKeyRegisteredKeyType.secp256r1,
|
|
176
|
-
'P-256' : DidKeyRegisteredKeyType.secp256r1,
|
|
177
|
-
secp256k1 : DidKeyRegisteredKeyType.secp256k1,
|
|
178
|
-
secp256r1 : DidKeyRegisteredKeyType.secp256r1,
|
|
179
|
-
} as const;
|
|
180
|
-
|
|
181
159
|
/**
|
|
182
160
|
* The `DidKey` class provides an implementation of the 'did:key' DID method.
|
|
183
161
|
*
|
|
@@ -295,7 +273,7 @@ export class DidKey extends DidMethod {
|
|
|
295
273
|
* @param params.options - Optional parameters that can be specified when creating a new DID.
|
|
296
274
|
* @returns A Promise resolving to a {@link BearerDid} object representing the new DID.
|
|
297
275
|
*/
|
|
298
|
-
public static async create<TKms extends
|
|
276
|
+
public static async create<TKms extends KeyManager | undefined = undefined>({
|
|
299
277
|
keyManager = new LocalKeyManager(),
|
|
300
278
|
options = {}
|
|
301
279
|
}: {
|
|
@@ -408,7 +386,7 @@ export class DidKey extends DidMethod {
|
|
|
408
386
|
* @throws An error if the DID document does not contain exactly one verification method.
|
|
409
387
|
*/
|
|
410
388
|
public static async import({ portableDid, keyManager = new LocalKeyManager() }: {
|
|
411
|
-
keyManager?:
|
|
389
|
+
keyManager?: KeyManager & KeyImporterExporter<KmsImportKeyParams, KeyIdentifier, KmsExportKeyParams>;
|
|
412
390
|
portableDid: PortableDid;
|
|
413
391
|
}): Promise<BearerDid> {
|
|
414
392
|
// Verify the DID method is supported.
|
|
@@ -473,7 +451,7 @@ export class DidKey extends DidMethod {
|
|
|
473
451
|
*/
|
|
474
452
|
private static async createDocument({ didUri, options = {} }: {
|
|
475
453
|
didUri: string;
|
|
476
|
-
options?: Exclude<DidKeyCreateOptions<
|
|
454
|
+
options?: Exclude<DidKeyCreateOptions<KeyManager>, 'algorithm' | 'verificationMethods'> | DidResolutionOptions;
|
|
477
455
|
}): Promise<DidDocument> {
|
|
478
456
|
const {
|
|
479
457
|
defaultContext = 'https://www.w3.org/ns/did/v1',
|
|
@@ -582,7 +560,7 @@ export class DidKey extends DidMethod {
|
|
|
582
560
|
private static async createSignatureMethod({ didUri, multibaseValue, options }: {
|
|
583
561
|
didUri: string;
|
|
584
562
|
multibaseValue: string;
|
|
585
|
-
options: Required<Pick<DidKeyCreateOptions<
|
|
563
|
+
options: Required<Pick<DidKeyCreateOptions<KeyManager>, 'enableExperimentalPublicKeyTypes' | 'publicKeyFormat'>>
|
|
586
564
|
}): Promise<DidVerificationMethod> {
|
|
587
565
|
const { enableExperimentalPublicKeyTypes, publicKeyFormat } = options;
|
|
588
566
|
|
|
@@ -733,235 +711,5 @@ export class DidKey extends DidMethod {
|
|
|
733
711
|
}
|
|
734
712
|
}
|
|
735
713
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
*/
|
|
739
|
-
export class DidKeyUtils {
|
|
740
|
-
/**
|
|
741
|
-
* A mapping from JSON Web Key (JWK) property descriptors to multicodec names.
|
|
742
|
-
*
|
|
743
|
-
* This mapping is used to convert keys in JWK (JSON Web Key) format to multicodec format.
|
|
744
|
-
*
|
|
745
|
-
* @remarks
|
|
746
|
-
* The keys of this object are strings that describe the JOSE key type and usage,
|
|
747
|
-
* such as 'Ed25519:public', 'Ed25519:private', etc. The values are the corresponding multicodec
|
|
748
|
-
* names used to represent these key types.
|
|
749
|
-
*
|
|
750
|
-
* @example
|
|
751
|
-
* ```ts
|
|
752
|
-
* const multicodecName = JWK_TO_MULTICODEC['Ed25519:public'];
|
|
753
|
-
* // Returns 'ed25519-pub', the multicodec name for an Ed25519 public key
|
|
754
|
-
* ```
|
|
755
|
-
*/
|
|
756
|
-
private static JWK_TO_MULTICODEC: { [key: string]: string } = {
|
|
757
|
-
'Ed25519:public' : 'ed25519-pub',
|
|
758
|
-
'Ed25519:private' : 'ed25519-priv',
|
|
759
|
-
'secp256k1:public' : 'secp256k1-pub',
|
|
760
|
-
'secp256k1:private' : 'secp256k1-priv',
|
|
761
|
-
};
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
* Defines the expected byte lengths for public keys associated with different cryptographic
|
|
765
|
-
* algorithms, indexed by their multicodec code values.
|
|
766
|
-
*/
|
|
767
|
-
public static MULTICODEC_PUBLIC_KEY_LENGTH: Record<number, number> = {
|
|
768
|
-
// secp256k1-pub - Secp256k1 public key (compressed) - 33 bytes
|
|
769
|
-
0xe7: 33,
|
|
770
|
-
|
|
771
|
-
// ed25519-pub - Ed25519 public key - 32 bytes
|
|
772
|
-
0xed: 32
|
|
773
|
-
};
|
|
774
|
-
|
|
775
|
-
/**
|
|
776
|
-
* A mapping from multicodec names to their corresponding JOSE (JSON Object Signing and Encryption)
|
|
777
|
-
* representations. This mapping facilitates the conversion of multicodec key formats to
|
|
778
|
-
* JWK (JSON Web Key) formats.
|
|
779
|
-
*
|
|
780
|
-
* @remarks
|
|
781
|
-
* The keys of this object are multicodec names, such as 'ed25519-pub', 'ed25519-priv', etc.
|
|
782
|
-
* The values are objects representing the corresponding JWK properties for that key type.
|
|
783
|
-
*
|
|
784
|
-
* @example
|
|
785
|
-
* ```ts
|
|
786
|
-
* const joseKey = MULTICODEC_TO_JWK['ed25519-pub'];
|
|
787
|
-
* // Returns a partial JWK for an Ed25519 public key
|
|
788
|
-
* ```
|
|
789
|
-
*/
|
|
790
|
-
private static MULTICODEC_TO_JWK: { [key: string]: Jwk } = {
|
|
791
|
-
'ed25519-pub' : { crv: 'Ed25519', kty: 'OKP', x: '' },
|
|
792
|
-
'ed25519-priv' : { crv: 'Ed25519', kty: 'OKP', x: '', d: '' },
|
|
793
|
-
'secp256k1-pub' : { crv: 'secp256k1', kty: 'EC', x: '', y: '' },
|
|
794
|
-
'secp256k1-priv' : { crv: 'secp256k1', kty: 'EC', x: '', y: '', d: '' },
|
|
795
|
-
};
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
* Converts a JWK (JSON Web Key) to a Multicodec code and name.
|
|
799
|
-
*
|
|
800
|
-
* @example
|
|
801
|
-
* ```ts
|
|
802
|
-
* const jwk: Jwk = { crv: 'Ed25519', kty: 'OKP', x: '...' };
|
|
803
|
-
* const { code, name } = await DidKeyUtils.jwkToMulticodec({ jwk });
|
|
804
|
-
* ```
|
|
805
|
-
*
|
|
806
|
-
* @param params - The parameters for the conversion.
|
|
807
|
-
* @param params.jwk - The JSON Web Key to be converted.
|
|
808
|
-
* @returns A promise that resolves to a Multicodec definition.
|
|
809
|
-
*/
|
|
810
|
-
public static async jwkToMulticodec({ jwk }: {
|
|
811
|
-
jwk: Jwk
|
|
812
|
-
}): Promise<MulticodecDefinition<MulticodecCode>> {
|
|
813
|
-
const params: string[] = [];
|
|
814
|
-
|
|
815
|
-
if (jwk.crv) {
|
|
816
|
-
params.push(jwk.crv);
|
|
817
|
-
if (jwk.d) {
|
|
818
|
-
params.push('private');
|
|
819
|
-
} else {
|
|
820
|
-
params.push('public');
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
const lookupKey = params.join(':');
|
|
825
|
-
const name = DidKeyUtils.JWK_TO_MULTICODEC[lookupKey];
|
|
826
|
-
|
|
827
|
-
if (name === undefined) {
|
|
828
|
-
throw new Error(`Unsupported JWK to Multicodec conversion: '${lookupKey}'`);
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
const code = Multicodec.getCodeFromName({ name });
|
|
832
|
-
|
|
833
|
-
return { code, name };
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
/**
|
|
837
|
-
* Returns the appropriate public key compressor for the specified cryptographic curve.
|
|
838
|
-
*
|
|
839
|
-
* @param curve - The cryptographic curve to use for the key conversion.
|
|
840
|
-
* @returns A public key compressor for the specified curve.
|
|
841
|
-
*/
|
|
842
|
-
public static keyCompressor(
|
|
843
|
-
curve: string
|
|
844
|
-
): KeyCompressor['compressPublicKey'] {
|
|
845
|
-
// ): ({ publicKeyBytes }: { publicKeyBytes: Uint8Array }) => Promise<Uint8Array> {
|
|
846
|
-
const compressors = {
|
|
847
|
-
'P-256' : Secp256r1.compressPublicKey,
|
|
848
|
-
'secp256k1' : Secp256k1.compressPublicKey
|
|
849
|
-
} as Record<string, KeyCompressor['compressPublicKey']>;
|
|
850
|
-
|
|
851
|
-
const compressor = compressors[curve];
|
|
852
|
-
|
|
853
|
-
if (!compressor) {throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);}
|
|
854
|
-
|
|
855
|
-
return compressor;
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
/**
|
|
859
|
-
* Returns the appropriate key converter for the specified cryptographic curve.
|
|
860
|
-
*
|
|
861
|
-
* @param curve - The cryptographic curve to use for the key conversion.
|
|
862
|
-
* @returns An `AsymmetricKeyConverter` for the specified curve.
|
|
863
|
-
*/
|
|
864
|
-
public static keyConverter(curve: string): AsymmetricKeyConverter {
|
|
865
|
-
const converters: Record<string, AsymmetricKeyConverter> = {
|
|
866
|
-
'Ed25519' : Ed25519,
|
|
867
|
-
'P-256' : Secp256r1,
|
|
868
|
-
'secp256k1' : Secp256k1,
|
|
869
|
-
};
|
|
870
|
-
|
|
871
|
-
const converter = converters[curve];
|
|
872
|
-
|
|
873
|
-
if (!converter) {throw new DidError(DidErrorCode.InvalidPublicKeyType, `Unsupported curve: ${curve}`);}
|
|
874
|
-
|
|
875
|
-
return converter;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
/**
|
|
879
|
-
* Converts a Multicodec code or name to parial JWK (JSON Web Key).
|
|
880
|
-
*
|
|
881
|
-
* @example
|
|
882
|
-
* ```ts
|
|
883
|
-
* const partialJwk = await DidKeyUtils.multicodecToJwk({ name: 'ed25519-pub' });
|
|
884
|
-
* ```
|
|
885
|
-
*
|
|
886
|
-
* @param params - The parameters for the conversion.
|
|
887
|
-
* @param params.code - Optional Multicodec code to convert.
|
|
888
|
-
* @param params.name - Optional Multicodec name to convert.
|
|
889
|
-
* @returns A promise that resolves to a JOSE format key.
|
|
890
|
-
*/
|
|
891
|
-
public static async multicodecToJwk({ code, name }: {
|
|
892
|
-
code?: MulticodecCode,
|
|
893
|
-
name?: string
|
|
894
|
-
}): Promise<Jwk> {
|
|
895
|
-
// Either code or name must be specified, but not both.
|
|
896
|
-
if (!(name ? !code : code)) {
|
|
897
|
-
throw new Error(`Either 'name' or 'code' must be defined, but not both.`);
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
// If name is undefined, lookup by code.
|
|
901
|
-
name = (name === undefined ) ? Multicodec.getNameFromCode({ code: code! }) : name;
|
|
902
|
-
|
|
903
|
-
const lookupKey = name;
|
|
904
|
-
const jose = DidKeyUtils.MULTICODEC_TO_JWK[lookupKey];
|
|
905
|
-
|
|
906
|
-
if (jose === undefined) {
|
|
907
|
-
throw new Error(`Unsupported Multicodec to JWK conversion`);
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
return { ...jose };
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
/**
|
|
914
|
-
* Converts a public key in JWK (JSON Web Key) format to a multibase identifier.
|
|
915
|
-
*
|
|
916
|
-
* @remarks
|
|
917
|
-
* Note: All secp public keys are converted to compressed point encoding
|
|
918
|
-
* before the multibase identifier is computed.
|
|
919
|
-
*
|
|
920
|
-
* Per {@link https://github.com/multiformats/multicodec/blob/master/table.csv | Multicodec table}:
|
|
921
|
-
* Public keys for Elliptic Curve cryptography algorithms (e.g., secp256k1,
|
|
922
|
-
* secp256k1r1, secp384r1, etc.) are always represented with compressed point
|
|
923
|
-
* encoding (e.g., secp256k1-pub, p256-pub, p384-pub, etc.).
|
|
924
|
-
*
|
|
925
|
-
* Per {@link https://datatracker.ietf.org/doc/html/rfc8812#name-jose-and-cose-secp256k1-cur | RFC 8812}:
|
|
926
|
-
* "As a compressed point encoding representation is not defined for JWK
|
|
927
|
-
* elliptic curve points, the uncompressed point encoding defined there
|
|
928
|
-
* MUST be used. The x and y values represented MUST both be exactly
|
|
929
|
-
* 256 bits, with any leading zeros preserved."
|
|
930
|
-
*
|
|
931
|
-
* @example
|
|
932
|
-
* ```ts
|
|
933
|
-
* const publicKey = { crv: 'Ed25519', kty: 'OKP', x: '...' };
|
|
934
|
-
* const multibaseId = await DidKeyUtils.publicKeyToMultibaseId({ publicKey });
|
|
935
|
-
* ```
|
|
936
|
-
*
|
|
937
|
-
* @param params - The parameters for the conversion.
|
|
938
|
-
* @param params.publicKey - The public key in JWK format.
|
|
939
|
-
* @returns A promise that resolves to the multibase identifier.
|
|
940
|
-
*/
|
|
941
|
-
public static async publicKeyToMultibaseId({ publicKey }: {
|
|
942
|
-
publicKey: Jwk
|
|
943
|
-
}): Promise<string> {
|
|
944
|
-
if (!(publicKey?.crv && publicKey.crv in AlgorithmToKeyTypeMap)) {
|
|
945
|
-
throw new DidError(DidErrorCode.InvalidPublicKeyType, `Public key contains an unsupported key type: ${publicKey?.crv ?? 'undefined'}`);
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
// Convert the public key from JWK format to a byte array.
|
|
949
|
-
let publicKeyBytes = await DidKeyUtils.keyConverter(publicKey.crv).publicKeyToBytes({ publicKey });
|
|
950
|
-
|
|
951
|
-
// Compress the public key if it is an elliptic curve key.
|
|
952
|
-
if (/^(secp256k1|P-256|P-384|P-521)$/.test(publicKey.crv)) {
|
|
953
|
-
publicKeyBytes = await DidKeyUtils.keyCompressor(publicKey.crv)({ publicKeyBytes });
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
// Convert the JSON Web Key (JWK) parameters to a Multicodec name.
|
|
957
|
-
const { name: multicodecName } = await DidKeyUtils.jwkToMulticodec({ jwk: publicKey });
|
|
958
|
-
|
|
959
|
-
// Compute the multibase identifier based on the provided key.
|
|
960
|
-
const multibaseId = keyBytesToMultibaseId({
|
|
961
|
-
keyBytes: publicKeyBytes,
|
|
962
|
-
multicodecName
|
|
963
|
-
});
|
|
964
|
-
|
|
965
|
-
return multibaseId;
|
|
966
|
-
}
|
|
967
|
-
}
|
|
714
|
+
// Re-export DidKeyUtils from its dedicated module for backward compatibility.
|
|
715
|
+
export { DidKeyUtils } from './did-key-utils.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
CryptoApi,
|
|
3
2
|
InferKeyGeneratorAlgorithm,
|
|
3
|
+
KeyManager,
|
|
4
4
|
LocalKeyManager,
|
|
5
5
|
} from '@enbox/crypto';
|
|
6
6
|
|
|
@@ -47,7 +47,7 @@ export interface DidCreateVerificationMethod<TKms> extends Pick<Partial<DidVerif
|
|
|
47
47
|
* };
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
|
-
algorithm: TKms extends
|
|
50
|
+
algorithm: TKms extends KeyManager
|
|
51
51
|
? InferKeyGeneratorAlgorithm<TKms>
|
|
52
52
|
: InferKeyGeneratorAlgorithm<LocalKeyManager>;
|
|
53
53
|
|
|
@@ -82,7 +82,7 @@ export interface DidCreateVerificationMethod<TKms> extends Pick<Partial<DidVerif
|
|
|
82
82
|
* @typeparam O - The type of the options used for creating the DID.
|
|
83
83
|
*/
|
|
84
84
|
export interface DidMethodApi<
|
|
85
|
-
TKms extends
|
|
85
|
+
TKms extends KeyManager | undefined = KeyManager,
|
|
86
86
|
TDid extends BearerDid = BearerDid,
|
|
87
87
|
TOptions extends DidCreateOptions<TKms> = DidCreateOptions<TKms>
|
|
88
88
|
> extends DidMethodResolver {
|