@dwn-protocol/id-sdk 0.2.5 → 0.2.6

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.
Files changed (99) hide show
  1. package/package.json +2 -3
  2. package/src/agent/app-data-store.ts +0 -365
  3. package/src/agent/did-manager.ts +0 -393
  4. package/src/agent/dwn-manager.ts +0 -548
  5. package/src/agent/identity-manager.ts +0 -165
  6. package/src/agent/index.ts +0 -19
  7. package/src/agent/json-rpc.ts +0 -107
  8. package/src/agent/key-manager.ts +0 -302
  9. package/src/agent/kms-local.ts +0 -412
  10. package/src/agent/outbox.ts +0 -128
  11. package/src/agent/rpc-client.ts +0 -223
  12. package/src/agent/store-managed-did.ts +0 -295
  13. package/src/agent/store-managed-identity.ts +0 -243
  14. package/src/agent/store-managed-key.ts +0 -754
  15. package/src/agent/sync-manager.ts +0 -631
  16. package/src/agent/test-managed-agent.ts +0 -299
  17. package/src/agent/types/agent.ts +0 -145
  18. package/src/agent/types/managed-key.ts +0 -442
  19. package/src/agent/utils.ts +0 -190
  20. package/src/common/convert.ts +0 -424
  21. package/src/common/index.ts +0 -9
  22. package/src/common/multicodec.ts +0 -176
  23. package/src/common/object.ts +0 -43
  24. package/src/common/stores.ts +0 -125
  25. package/src/common/stream-node.ts +0 -381
  26. package/src/common/stream.ts +0 -406
  27. package/src/common/type-utils.ts +0 -117
  28. package/src/common/types.ts +0 -48
  29. package/src/credentials/credential-bbs.ts +0 -419
  30. package/src/credentials/credential.ts +0 -324
  31. package/src/credentials/index.ts +0 -5
  32. package/src/credentials/presentation.ts +0 -182
  33. package/src/credentials/status-list.ts +0 -365
  34. package/src/credentials/utils.ts +0 -58
  35. package/src/credentials/validators.ts +0 -52
  36. package/src/crypto/algorithms-api/aes/base.ts +0 -49
  37. package/src/crypto/algorithms-api/aes/ctr.ts +0 -51
  38. package/src/crypto/algorithms-api/aes/index.ts +0 -2
  39. package/src/crypto/algorithms-api/crypto-algorithm.ts +0 -127
  40. package/src/crypto/algorithms-api/crypto-key.ts +0 -56
  41. package/src/crypto/algorithms-api/ec/base.ts +0 -39
  42. package/src/crypto/algorithms-api/ec/ecdh.ts +0 -53
  43. package/src/crypto/algorithms-api/ec/ecdsa.ts +0 -37
  44. package/src/crypto/algorithms-api/ec/eddsa.ts +0 -30
  45. package/src/crypto/algorithms-api/ec/index.ts +0 -4
  46. package/src/crypto/algorithms-api/errors.ts +0 -29
  47. package/src/crypto/algorithms-api/index.ts +0 -6
  48. package/src/crypto/algorithms-api/pbkdf/index.ts +0 -1
  49. package/src/crypto/algorithms-api/pbkdf/pbkdf2.ts +0 -91
  50. package/src/crypto/crypto-algorithms/aes-ctr.ts +0 -70
  51. package/src/crypto/crypto-algorithms/bbs.ts +0 -110
  52. package/src/crypto/crypto-algorithms/ecdh.ts +0 -115
  53. package/src/crypto/crypto-algorithms/ecdsa.ts +0 -111
  54. package/src/crypto/crypto-algorithms/eddsa.ts +0 -110
  55. package/src/crypto/crypto-algorithms/index.ts +0 -6
  56. package/src/crypto/crypto-algorithms/pbkdf2.ts +0 -54
  57. package/src/crypto/crypto-primitives/aes-ctr.ts +0 -131
  58. package/src/crypto/crypto-primitives/aes-gcm.ts +0 -138
  59. package/src/crypto/crypto-primitives/bbs.ts +0 -183
  60. package/src/crypto/crypto-primitives/concat-kdf.ts +0 -207
  61. package/src/crypto/crypto-primitives/ed25519.ts +0 -201
  62. package/src/crypto/crypto-primitives/index.ts +0 -10
  63. package/src/crypto/crypto-primitives/pbkdf2.ts +0 -78
  64. package/src/crypto/crypto-primitives/secp256k1.ts +0 -322
  65. package/src/crypto/crypto-primitives/x25519.ts +0 -101
  66. package/src/crypto/crypto-primitives/xchacha20-poly1305.ts +0 -46
  67. package/src/crypto/crypto-primitives/xchacha20.ts +0 -34
  68. package/src/crypto/index.ts +0 -8
  69. package/src/crypto/jose.ts +0 -948
  70. package/src/crypto/types/crypto-key.ts +0 -4
  71. package/src/crypto/types/iddwn-crypto.ts +0 -119
  72. package/src/crypto/utils.ts +0 -200
  73. package/src/did-api.ts +0 -72
  74. package/src/dids/dht.ts +0 -412
  75. package/src/dids/did-dht.ts +0 -436
  76. package/src/dids/did-ion.ts +0 -613
  77. package/src/dids/did-key.ts +0 -791
  78. package/src/dids/did-resolver.ts +0 -107
  79. package/src/dids/index.ts +0 -9
  80. package/src/dids/resolver-cache-level.ts +0 -82
  81. package/src/dids/resolver-cache-noop.ts +0 -25
  82. package/src/dids/types.ts +0 -278
  83. package/src/dids/utils.ts +0 -129
  84. package/src/dwn-api.ts +0 -584
  85. package/src/iddwn.ts +0 -241
  86. package/src/identity-agent/index.ts +0 -270
  87. package/src/index.ts +0 -26
  88. package/src/interfaces/metadata.ts +0 -163
  89. package/src/interfaces/queue.ts +0 -108
  90. package/src/interfaces/services.ts +0 -122
  91. package/src/interfaces/transactions.ts +0 -220
  92. package/src/protocol.ts +0 -68
  93. package/src/proxy-agent/index.ts +0 -255
  94. package/src/record.ts +0 -521
  95. package/src/service-options.ts +0 -62
  96. package/src/typings/decentralized-identity__ion-pow-sdk.d.ts +0 -7
  97. package/src/user-agent/index.ts +0 -295
  98. package/src/utils.ts +0 -29
  99. package/src/vc-api.ts +0 -505
@@ -1,791 +0,0 @@
1
- import type { PrivateKeyJwk, PublicKeyJwk, IDCrypto } from '../crypto/index.js';
2
-
3
- import { universalTypeOf } from '../common/index.js';
4
- // import { keyToMultibaseId, multibaseIdToKey } from '../crypto/utils.js';
5
- import {
6
- Jose,
7
- Ed25519,
8
- Secp256k1,
9
- EcdsaAlgorithm,
10
- EdDsaAlgorithm,
11
- utils as cryptoUtils,
12
- } from '../crypto/index.js';
13
-
14
- import type {
15
- DidMethod,
16
- DidDocument,
17
- PortableDid,
18
- VerificationMethod,
19
- DidResolutionResult,
20
- DidResolutionOptions,
21
- DidKeySetVerificationMethodKey
22
- } from './types.js';
23
-
24
- import { getVerificationMethodTypes, parseDid } from './utils.js';
25
-
26
- const SupportedCryptoAlgorithms = [
27
- 'Ed25519',
28
- 'secp256k1'
29
- ] as const;
30
-
31
- const SupportedPublicKeyFormats = [
32
- 'Ed25519VerificationKey2020',
33
- 'JsonWebKey2020',
34
- 'X25519KeyAgreementKey2020'
35
- ];
36
-
37
- const VERIFICATION_METHOD_TYPES: Record<string, string> = {
38
- 'Ed25519VerificationKey2020' : 'https://w3id.org/security/suites/ed25519-2020/v1',
39
- 'JsonWebKey2020' : 'https://w3id.org/security/suites/jws-2020/v1',
40
- 'X25519KeyAgreementKey2020' : 'https://w3id.org/security/suites/x25519-2020/v1',
41
- } as const;
42
-
43
- export type DidVerificationMethodType = keyof typeof VERIFICATION_METHOD_TYPES;
44
-
45
- const MULTICODEC_PUBLIC_KEY_LENGTH: Record<number, number> = {
46
- // secp256k1-pub - Secp256k1 public key (compressed) - 33 bytes
47
- 0xe7: 33,
48
-
49
- // x25519-pub - Curve25519 public key - 32 bytes
50
- 0xec: 32,
51
-
52
- // ed25519-pub - Ed25519 public key - 32 bytes
53
- 0xed: 32
54
- };
55
-
56
- export type DidKeyCreateOptions = {
57
- enableEncryptionKeyDerivation?: boolean;
58
- keyAlgorithm?: typeof SupportedCryptoAlgorithms[number];
59
- keySet?: DidKeyKeySet;
60
- publicKeyFormat?: DidVerificationMethodType;
61
- }
62
-
63
- export type DidKeyCreateDocumentOptions = {
64
- defaultContext?: string;
65
- did: string;
66
- enableEncryptionKeyDerivation?: boolean;
67
- enableExperimentalPublicKeyTypes?: boolean;
68
- publicKeyFormat?: DidVerificationMethodType;
69
- }
70
-
71
- export type DidKeyDeriveEncryptionKeyResult = {
72
- key: Uint8Array;
73
- multicodecCode: number;
74
- }
75
-
76
- export type DidKeyIdentifier = {
77
- fragment: string;
78
- method: string;
79
- multibaseValue: string;
80
- scheme: string;
81
- version: string;
82
- }
83
-
84
- export type DidKeyKeySet = {
85
- verificationMethodKeys?: DidKeySetVerificationMethodKey[];
86
- }
87
-
88
- export class DidKeyMethod implements DidMethod {
89
- /**
90
- * Name of the DID method
91
- */
92
- public static methodName = 'key';
93
-
94
- public static async create(options?: DidKeyCreateOptions): Promise<PortableDid> {
95
- let {
96
- enableEncryptionKeyDerivation = false,
97
- keyAlgorithm,
98
- keySet,
99
- publicKeyFormat = 'JsonWebKey2020'
100
- } = options ?? { };
101
-
102
- // If keySet not given, generate a default key set.
103
- if (keySet === undefined) {
104
- keySet = await DidKeyMethod.generateKeySet({ keyAlgorithm });
105
- }
106
-
107
- const portableDid: Partial<PortableDid> = {};
108
- let multibaseId = '';
109
-
110
- if (keySet.verificationMethodKeys?.[0]?.publicKeyJwk) {
111
- // Compute the multibase identifier based on the JSON Web Key.
112
- const publicKeyJwk = keySet.verificationMethodKeys[0].publicKeyJwk;
113
- multibaseId = await Jose.jwkToMultibaseId({ key: publicKeyJwk });
114
- }
115
-
116
- if (!multibaseId) {
117
- throw new Error('DidKeyMethod: Failed to create DID with given input.');
118
- }
119
-
120
- // Concatenate the DID identifier.
121
- portableDid.did = `did:key:${multibaseId}`;
122
-
123
- // Expand the DID identifier to a DID document.
124
- portableDid.document = await DidKeyMethod.createDocument({
125
- did: portableDid.did,
126
- publicKeyFormat,
127
- enableEncryptionKeyDerivation
128
- });
129
-
130
- // Return the given or generated key set.
131
- portableDid.keySet = keySet;
132
-
133
- return portableDid as PortableDid;
134
- }
135
-
136
- /**
137
- * Expands a did:key identifier to a DID Document.
138
- *
139
- * Reference: https://w3c-ccg.github.io/did-method-key/#document-creation-algorithm
140
- *
141
- * @param options
142
- * @returns - A DID dodcument.
143
- */
144
- public static async createDocument(options: DidKeyCreateDocumentOptions): Promise<DidDocument> {
145
- const {
146
- defaultContext = 'https://www.w3.org/ns/did/v1',
147
- did,
148
- enableEncryptionKeyDerivation = false,
149
- enableExperimentalPublicKeyTypes = false,
150
- publicKeyFormat = 'JsonWebKey2020'
151
- } = options;
152
-
153
- /**
154
- * 1. Initialize document to an empty object.
155
- */
156
- const document: Partial<DidDocument> = {};
157
-
158
- /**
159
- * 2. Using a colon (:) as the delimiter, split the identifier into its
160
- * components: a scheme, a method, a version, and a multibaseValue.
161
- * If there are only three components set the version to the string
162
- * value 1 and use the last value as the multibaseValue.
163
- *
164
- * Note: The W3C DID specification makes no mention of a version value
165
- * being part of the DID syntax. Additionally, there does not
166
- * appear to be any real-world usage of the version number.
167
- * Consequently, this implementation will ignore the version
168
- * related guidance in the did:key specification.
169
- */
170
- let multibaseValue: string;
171
- try {
172
- ({ id: multibaseValue } = parseDid({ didUrl: did }));
173
- } catch (error: any) {
174
- throw new Error(`invalidDid: Unknown format: ${did}`);
175
- }
176
-
177
- /**
178
- * 3. Check the validity of the input identifier.
179
- * The scheme MUST be the value did. The method MUST be the value key.
180
- * The version MUST be convertible to a positive integer value. The
181
- * multibaseValue MUST be a string and begin with the letter z. If any
182
- * of these requirements fail, an invalidDid error MUST be raised.
183
- */
184
- if (!DidKeyMethod.validateIdentifier({ did })) {
185
- throw new Error(`invalidDid: Invalid identifier format: ${did}`);
186
- }
187
-
188
- /**
189
- * 4. Initialize the signatureVerificationMethod to the result of passing
190
- * identifier, multibaseValue, and options to a
191
- * {@link https://w3c-ccg.github.io/did-method-key/#signature-method-creation-algorithm | Signature Method Creation Algorithm}.
192
- */
193
- const signatureVerificationMethod = await DidKeyMethod.createSignatureMethod({
194
- did,
195
- enableExperimentalPublicKeyTypes,
196
- multibaseValue,
197
- publicKeyFormat
198
- });
199
-
200
- /**
201
- * 5. Set document.id to identifier. If document.id is not a valid DID,
202
- * an invalidDid error MUST be raised.
203
- *
204
- * Note: Identifier was already confirmed to be valid in Step 3, so
205
- * skipping the redundant validation.
206
- */
207
- document.id = did;
208
-
209
- /**
210
- * 6. Initialize the verificationMethod property in document to an array
211
- * where the first value is the signatureVerificationMethod.
212
- */
213
- document.verificationMethod = [signatureVerificationMethod];
214
-
215
- /**
216
- * 7. Initialize the authentication, assertionMethod, capabilityInvocation,
217
- * and the capabilityDelegation properties in document to an array where
218
- * the first item is the value of the id property in
219
- * signatureVerificationMethod.
220
- */
221
- document.authentication = [signatureVerificationMethod.id];
222
- document.assertionMethod = [signatureVerificationMethod.id];
223
- document.capabilityInvocation = [signatureVerificationMethod.id];
224
- document.capabilityDelegation = [signatureVerificationMethod.id];
225
-
226
- /**
227
- * 8. If options.enableEncryptionKeyDerivation is set to true:
228
- * Add the encryptionVerificationMethod value to the verificationMethod
229
- * array. Initialize the keyAgreement property in document to an array
230
- * where the first item is the value of the id property in
231
- * encryptionVerificationMethod.
232
- */
233
- if (enableEncryptionKeyDerivation === true) {
234
- /**
235
- * Although not covered by the did:key method specification, a sensible
236
- * default will be taken to use the 'X25519KeyAgreementKey2020'
237
- * verification method type if the given publicKeyFormat is
238
- * 'Ed25519VerificationKey2020' and 'JsonWebKey2020' otherwise.
239
- */
240
- const encryptionPublicKeyFormat =
241
- (publicKeyFormat === 'Ed25519VerificationKey2020')
242
- ? 'X25519KeyAgreementKey2020'
243
- : 'JsonWebKey2020';
244
-
245
- /**
246
- * 8.1 Initialize the encryptionVerificationMethod to the result of
247
- * passing identifier, multibaseValue, and options to an
248
- * {@link https://w3c-ccg.github.io/did-method-key/#encryption-method-creation-algorithm | Encryption Method Creation Algorithm}.
249
- */
250
- const encryptionVerificationMethod = await this.createEncryptionMethod({
251
- did,
252
- enableExperimentalPublicKeyTypes,
253
- multibaseValue,
254
- publicKeyFormat: encryptionPublicKeyFormat
255
- });
256
-
257
- /**
258
- * 8.2 Add the encryptionVerificationMethod value to the
259
- * verificationMethod array.
260
- */
261
- document.verificationMethod.push(encryptionVerificationMethod);
262
-
263
- /**
264
- * 8.3. Initialize the keyAgreement property in document to an array
265
- * where the first item is the value of the id property in
266
- * encryptionVerificationMethod.
267
- */
268
- document.keyAgreement = [encryptionVerificationMethod.id];
269
- }
270
-
271
- /**
272
- * 9. Initialize the @context property in document to the result of passing
273
- * document and options to the Context Creation algorithm.
274
- */
275
- // Set contextArray to an array that is initialized to
276
- // options.defaultContext.
277
- const contextArray = [defaultContext];
278
-
279
- // For every object in every verification relationship listed in document,
280
- // add a string value to the contextArray based on the object type value,
281
- // if it doesn't already exist, according to the following table:
282
- // {@link https://w3c-ccg.github.io/did-method-key/#context-creation-algorithm | Context Type URL}
283
- const verificationMethodTypes = getVerificationMethodTypes({ didDocument: document });
284
- verificationMethodTypes.forEach((typeName: string) => {
285
- const typeUrl = VERIFICATION_METHOD_TYPES[typeName];
286
- contextArray.push(typeUrl);
287
- });
288
- document['@context'] = contextArray;
289
-
290
- /**
291
- * 10. Return document.
292
- */
293
- return document as DidDocument;
294
- }
295
-
296
- /**
297
- * Decoding a multibase-encoded multicodec value into a verification method
298
- * that is suitable for verifying that encrypted information will be
299
- * received by the intended recipient.
300
- */
301
- public static async createEncryptionMethod(options: {
302
- did: string,
303
- enableExperimentalPublicKeyTypes: boolean,
304
- multibaseValue: string,
305
- publicKeyFormat: DidVerificationMethodType
306
- }): Promise<VerificationMethod> {
307
- const { did, enableExperimentalPublicKeyTypes, multibaseValue, publicKeyFormat } = options;
308
-
309
- /**
310
- * 1. Initialize verificationMethod to an empty object.
311
- */
312
- const verificationMethod: Partial<VerificationMethod> = {};
313
-
314
- /**
315
- * 2. Set multicodecValue and rawPublicKeyBytes to the result of passing
316
- * multibaseValue and options to a Derive Encryption Key algorithm.
317
- */
318
- const {
319
- key: rawPublicKeyBytes,
320
- multicodecCode: multicodecValue,
321
- } = await DidKeyMethod.deriveEncryptionKey({ multibaseValue });
322
-
323
- /**
324
- * 3. Ensure the proper key length of rawPublicKeyBytes based on the
325
- * multicodecValue table provided below:
326
- *
327
- * Multicodec hexadecimal value: 0xec
328
- *
329
- * If the byte length of rawPublicKeyBytes
330
- * does not match the expected public key length for the associated
331
- * multicodecValue, an invalidPublicKeyLength error MUST be raised.
332
- */
333
- const actualLength = rawPublicKeyBytes.byteLength;
334
- const expectedLength = MULTICODEC_PUBLIC_KEY_LENGTH[multicodecValue];
335
- if (actualLength !== expectedLength) {
336
- throw new Error(`invalidPublicKeyLength: Expected ${actualLength} bytes. Actual ${expectedLength} bytes.`);
337
- }
338
-
339
- /**
340
- * 4. Create the multibaseValue by concatenating the letter 'z' and the
341
- * base58-btc encoding of the concatenation of the multicodecValue and
342
- * the rawPublicKeyBytes.
343
- */
344
- const kemMultibaseValue = cryptoUtils.keyToMultibaseId({
345
- key : rawPublicKeyBytes,
346
- multicodecCode : multicodecValue
347
- });
348
-
349
- /**
350
- * 5. Set the verificationMethod.id value by concatenating identifier,
351
- * a hash character (#), and the multibaseValue. If verificationMethod.id
352
- * is not a valid DID URL, an invalidDidUrl error MUST be raised.
353
- */
354
- verificationMethod.id = `${did}#${kemMultibaseValue}`;
355
- try {
356
- new URL(verificationMethod.id);
357
- } catch (error: any) {
358
- throw new Error('invalidDidUrl: Verification Method ID is not a valid DID URL.');
359
- }
360
-
361
- /**
362
- * 6. Set the publicKeyFormat value to the options.publicKeyFormat value.
363
- * 7. If publicKeyFormat is not known to the implementation, an
364
- * unsupportedPublicKeyType error MUST be raised.
365
- */
366
- if (!(SupportedPublicKeyFormats.includes(publicKeyFormat))) {
367
- throw new Error(`unsupportedPublicKeyType: Unsupported format: ${publicKeyFormat}`);
368
- }
369
-
370
- /**
371
- * 8. If options.enableExperimentalPublicKeyTypes is set to false and
372
- * publicKeyFormat is not Multikey, JsonWebKey2020, or
373
- * X25519KeyAgreementKey2020, an invalidPublicKeyType error MUST be
374
- * raised.
375
- */
376
- const StandardPublicKeyTypes = ['Multikey', 'JsonWebKey2020', 'X25519KeyAgreementKey2020'];
377
- if (enableExperimentalPublicKeyTypes === false
378
- && !(StandardPublicKeyTypes.includes(publicKeyFormat))) {
379
- throw new Error(`invalidPublicKeyType: Specified '${publicKeyFormat}' without setting enableExperimentalPublicKeyTypes to true.`);
380
- }
381
-
382
- /**
383
- * 9. Set verificationMethod.type to the publicKeyFormat value.
384
- */
385
- verificationMethod.type = publicKeyFormat;
386
-
387
- /**
388
- * 10. Set verificationMethod.controller to the identifier value.
389
- * If verificationMethod.controller is not a valid DID, an invalidDid
390
- * error MUST be raised.
391
- */
392
- verificationMethod.controller = did;
393
- if (!DidKeyMethod.validateIdentifier({ did })) {
394
- throw new Error(`invalidDid: Invalid identifier format: ${did}`);
395
- }
396
-
397
- /**
398
- * 11. If publicKeyFormat is Multikey or X25519KeyAgreementKey2020,
399
- * set the verificationMethod.publicKeyMultibase value to multibaseValue.
400
- *
401
- * Note: This implementation does not currently support the Multikey
402
- * format.
403
- */
404
- if (publicKeyFormat === 'X25519KeyAgreementKey2020') {
405
- verificationMethod.publicKeyMultibase = kemMultibaseValue;
406
- }
407
-
408
- /**
409
- * 12. If publicKeyFormat is JsonWebKey2020, set the
410
- * verificationMethod.publicKeyJwk value to the result of passing
411
- * multicodecValue and rawPublicKeyBytes to a JWK encoding algorithm.
412
- */
413
- if (publicKeyFormat === 'JsonWebKey2020') {
414
- const jwkParams = await Jose.multicodecToJose({ code: multicodecValue });
415
- const jsonWebKey = await Jose.keyToJwk({
416
- keyMaterial : rawPublicKeyBytes,
417
- keyType : 'public',
418
- ...jwkParams
419
- });
420
- // Ensure that "d" is NOT present.
421
- if ('x' in jsonWebKey && !('d' in jsonWebKey)) {
422
- verificationMethod.publicKeyJwk = jsonWebKey;
423
- }
424
- }
425
-
426
- /**
427
- * 13. Return verificationMethod.
428
- */
429
- return verificationMethod as VerificationMethod;
430
- }
431
-
432
- /**
433
- * Transform a multibase-encoded multicodec value to public encryption key
434
- * components that are suitable for encrypting messages to a receiver. A
435
- * mathematical proof elaborating on the safety of performing this operation
436
- * is available in:
437
- * {@link https://eprint.iacr.org/2021/509.pdf | On using the same key pair for Ed25519 and an X25519 based KEM}
438
- */
439
- public static async deriveEncryptionKey(options: {
440
- multibaseValue: string
441
- }): Promise<DidKeyDeriveEncryptionKeyResult> {
442
- const { multibaseValue } = options;
443
-
444
- /**
445
- * 1. Set publicEncryptionKey to an empty object.
446
- */
447
- let publicEncryptionKey: Partial<DidKeyDeriveEncryptionKeyResult> = {};
448
-
449
- /**
450
- * 2. Decode multibaseValue using the base58-btc multibase alphabet and
451
- * set multicodecValue to the multicodec header for the decoded value.
452
- * Implementers are cautioned to ensure that the multicodecValue is set
453
- * to the result after performing varint decoding.
454
- *
455
- * 3. Set the rawPublicKeyBytes to the bytes remaining after the multicodec
456
- * header.
457
- */
458
- const {
459
- key: rawPublicKeyBytes,
460
- multicodecCode: multicodecValue
461
- } = cryptoUtils.multibaseIdToKey({ multibaseKeyId: multibaseValue });
462
-
463
- /**
464
- * 4. If the multicodecValue is 0xed, derive a public X25519 encryption key
465
- * by using the rawPublicKeyBytes and the algorithm defined in
466
- * {@link https://datatracker.ietf.org/doc/html/draft-ietf-core-oscore-groupcomm | Group OSCORE - Secure Group Communication for CoAP}
467
- * for Curve25519 in Section 2.4.2: ECDH with Montgomery Coordinates and
468
- * set generatedPublicEncryptionKeyBytes to the result.
469
- */
470
- if (multicodecValue === 0xed) {
471
- const generatedPublicEncryptionKeyBytes = await Ed25519.convertPublicKeyToX25519({
472
- publicKey: rawPublicKeyBytes
473
- });
474
-
475
- /**
476
- * 5. Set multicodecValue in publicEncryptionKey to 0xec.
477
- *
478
- * 6. Set rawPublicKeyBytes in publicEncryptionKey to
479
- * generatedPublicEncryptionKeyBytes.
480
- */
481
- publicEncryptionKey = {
482
- key : generatedPublicEncryptionKeyBytes,
483
- multicodecCode : 0xec
484
- };
485
- }
486
-
487
- /**
488
- * 7. Return publicEncryptionKey.
489
- */
490
- return publicEncryptionKey as DidKeyDeriveEncryptionKeyResult;
491
- }
492
-
493
- /**
494
- * Decodes a multibase-encoded multicodec value into a verification method
495
- * that is suitable for verifying digital signatures.
496
- * @param options - Signature method creation algorithm inputs.
497
- * @returns - A verification method.
498
- */
499
- public static async createSignatureMethod(options: {
500
- did: string,
501
- enableExperimentalPublicKeyTypes: boolean,
502
- multibaseValue: string,
503
- publicKeyFormat: DidVerificationMethodType
504
- }): Promise<VerificationMethod> {
505
- const { did, enableExperimentalPublicKeyTypes, multibaseValue, publicKeyFormat } = options;
506
-
507
- /**
508
- * 1. Initialize verificationMethod to an empty object.
509
- */
510
- const verificationMethod: Partial<VerificationMethod> = {};
511
-
512
- /**
513
- * 2. Set multicodecValue and rawPublicKeyBytes to the result of passing
514
- * multibaseValue and options to a Decode Public Key algorithm.
515
- */
516
- const {
517
- key: rawPublicKeyBytes,
518
- multicodecCode: multicodecValue,
519
- multicodecName
520
- } = cryptoUtils.multibaseIdToKey({ multibaseKeyId: multibaseValue });
521
-
522
- /**
523
- * 3. Ensure the proper key length of rawPublicKeyBytes based on the
524
- * multicodecValue {@link https://w3c-ccg.github.io/did-method-key/#signature-method-creation-algorithm | table provided}.
525
- * If the byte length of rawPublicKeyBytes does not match the expected
526
- * public key length for the associated multicodecValue, an
527
- * invalidPublicKeyLength error MUST be raised.
528
- */
529
- const actualLength = rawPublicKeyBytes.byteLength;
530
- const expectedLength = MULTICODEC_PUBLIC_KEY_LENGTH[multicodecValue];
531
- if (actualLength !== expectedLength) {
532
- throw new Error(`invalidPublicKeyLength: Expected ${actualLength} bytes. Actual ${expectedLength} bytes.`);
533
- }
534
-
535
- /**
536
- * 4. Ensure the rawPublicKeyBytes are a proper encoding of the public
537
- * key type as specified by the multicodecValue. This validation is often
538
- * done by a cryptographic library when importing the public key by,
539
- * for example, ensuring that an Elliptic Curve public key is a specific
540
- * coordinate that exists on the elliptic curve. If an invalid public key
541
- * value is detected, an invalidPublicKey error MUST be raised.
542
- */
543
- let isValid = false;
544
- switch (multicodecName) {
545
- case 'secp256k1-pub':
546
- isValid = await Secp256k1.validatePublicKey({ key: rawPublicKeyBytes });
547
- break;
548
- case 'ed25519-pub':
549
- isValid = await Ed25519.validatePublicKey({ key: rawPublicKeyBytes });
550
- break;
551
- case 'x25519-pub':
552
- // TODO: validate key once/if X25519.validatePublicKey() is implemented.
553
- // isValid = X25519.validatePublicKey({ key: rawPublicKeyBytes})
554
- isValid = true;
555
- break;
556
- }
557
- if (!isValid) {
558
- throw new Error('invalidPublicKey: Invalid public key detected.');
559
- }
560
-
561
- /**
562
- * 5. Set the verificationMethod.id value by concatenating identifier,
563
- * a hash character (#), and the multibaseValue. If verificationMethod.id
564
- * is not a valid DID URL, an invalidDidUrl error MUST be raised.
565
- */
566
- verificationMethod.id = `${did}#${multibaseValue}`;
567
- try {
568
- new URL(verificationMethod.id);
569
- } catch (error: any) {
570
- throw new Error('invalidDidUrl: Verification Method ID is not a valid DID URL.');
571
- }
572
-
573
- /**
574
- * 6. Set the publicKeyFormat value to the options.publicKeyFormat value.
575
- * 7. If publicKeyFormat is not known to the implementation, an
576
- * unsupportedPublicKeyType error MUST be raised.
577
- */
578
- if (!(SupportedPublicKeyFormats.includes(publicKeyFormat))) {
579
- throw new Error(`unsupportedPublicKeyType: Unsupported format: ${publicKeyFormat}`);
580
- }
581
-
582
- /**
583
- * 8. If options.enableExperimentalPublicKeyTypes is set to false and
584
- * publicKeyFormat is not Multikey, JsonWebKey2020, or
585
- * Ed25519VerificationKey2020, an invalidPublicKeyType error MUST be
586
- * raised.
587
- */
588
- const StandardPublicKeyTypes = ['Multikey', 'JsonWebKey2020', 'Ed25519VerificationKey2020'];
589
- if (enableExperimentalPublicKeyTypes === false
590
- && !(StandardPublicKeyTypes.includes(publicKeyFormat))) {
591
- throw new Error(`invalidPublicKeyType: Specified '${publicKeyFormat}' without setting enableExperimentalPublicKeyTypes to true.`);
592
- }
593
-
594
- /**
595
- * 9. Set verificationMethod.type to the publicKeyFormat value.
596
- */
597
- verificationMethod.type = publicKeyFormat;
598
-
599
- /**
600
- * 10. Set verificationMethod.controller to the identifier value.
601
- * If verificationMethod.controller is not a valid DID, an invalidDid
602
- * error MUST be raised.
603
- */
604
- verificationMethod.controller = did;
605
- if (!DidKeyMethod.validateIdentifier({ did })) {
606
- throw new Error(`invalidDid: Invalid identifier format: ${did}`);
607
- }
608
-
609
- /**
610
- * 11. If publicKeyFormat is Multikey or Ed25519VerificationKey2020,
611
- * set the verificationMethod.publicKeyMultibase value to multibaseValue.
612
- *
613
- * Note: This implementation does not currently support the Multikey
614
- * format.
615
- */
616
- if (publicKeyFormat === 'Ed25519VerificationKey2020') {
617
- verificationMethod.publicKeyMultibase = multibaseValue;
618
- }
619
-
620
- /**
621
- * 12. If publicKeyFormat is JsonWebKey2020, set the
622
- * verificationMethod.publicKeyJwk value to the result of passing
623
- * multicodecValue and rawPublicKeyBytes to a JWK encoding algorithm.
624
- */
625
- if (publicKeyFormat === 'JsonWebKey2020') {
626
- const jwkParams = await Jose.multicodecToJose({ code: multicodecValue });
627
- const jsonWebKey = await Jose.keyToJwk({
628
- keyMaterial : rawPublicKeyBytes,
629
- keyType : 'public',
630
- ...jwkParams
631
- });
632
- // Ensure that "d" is NOT present.
633
- if ('x' in jsonWebKey && !('d' in jsonWebKey)) {
634
- verificationMethod.publicKeyJwk = jsonWebKey;
635
- }
636
- }
637
-
638
- /**
639
- * 13. Return verificationMethod.
640
- */
641
- return verificationMethod as VerificationMethod;
642
- }
643
-
644
- public static async generateKeySet(options?: {
645
- keyAlgorithm?: typeof SupportedCryptoAlgorithms[number]
646
- }): Promise<DidKeyKeySet> {
647
- // Generate Ed25519 keys, by default.
648
- const { keyAlgorithm = 'Ed25519' } = options ?? {};
649
-
650
- let keyPair: IDCrypto.CryptoKeyPair;
651
-
652
- switch (keyAlgorithm) {
653
- case 'Ed25519': {
654
- keyPair = await new EdDsaAlgorithm().generateKey({
655
- algorithm : { name: 'EdDSA', namedCurve: 'Ed25519' },
656
- extractable : true,
657
- keyUsages : ['sign', 'verify']
658
- });
659
- break;
660
- }
661
-
662
- case 'secp256k1': {
663
- keyPair = await new EcdsaAlgorithm().generateKey({
664
- algorithm : { name: 'ECDSA', namedCurve: 'secp256k1' },
665
- extractable : true,
666
- keyUsages : ['sign', 'verify']
667
- });
668
- break;
669
- }
670
-
671
- default: {
672
- throw new Error(`Unsupported crypto algorithm: '${keyAlgorithm}'`);
673
- }
674
- }
675
-
676
- const publicKeyJwk = await Jose.cryptoKeyToJwk({ key: keyPair.publicKey }) as PublicKeyJwk;
677
- const privateKeyJwk = await Jose.cryptoKeyToJwk({ key: keyPair.privateKey }) as PrivateKeyJwk;
678
-
679
- const keySet: DidKeyKeySet = {
680
- verificationMethodKeys: [{
681
- publicKeyJwk,
682
- privateKeyJwk,
683
- relationships: ['authentication']
684
- }]
685
- };
686
-
687
- return keySet;
688
- }
689
-
690
- /**
691
- * Given the W3C DID Document of a `did:key` DID, return the identifier of
692
- * the verification method key that will be used for signing messages and
693
- * credentials, by default.
694
- *
695
- * @param document = DID Document to get the default signing key from.
696
- * @returns Verification method identifier for the default signing key.
697
- */
698
- public static async getDefaultSigningKey(options: {
699
- didDocument: DidDocument
700
- }): Promise<string | undefined> {
701
- const { didDocument } = options;
702
-
703
- if (didDocument.authentication
704
- && Array.isArray(didDocument.authentication)
705
- && didDocument.authentication.length > 0
706
- && typeof didDocument.authentication[0] === 'string') {
707
-
708
- const [verificationMethodId] = didDocument.authentication;
709
- const signingKeyId = verificationMethodId;
710
-
711
- return signingKeyId;
712
- }
713
- }
714
-
715
- public static async resolve(options: {
716
- didUrl: string,
717
- resolutionOptions?: DidResolutionOptions
718
- }): Promise<DidResolutionResult> {
719
- const { didUrl, resolutionOptions: _ } = options;
720
- // TODO: add resolutionOptions as defined in https://www.w3.org/TR/did-core/#did-resolution
721
-
722
- const parsedDid = parseDid({ didUrl });
723
- if (!parsedDid) {
724
- return {
725
- '@context' : 'https://w3id.org/did-resolution/v1',
726
- didDocument : undefined,
727
- didDocumentMetadata : {},
728
- didResolutionMetadata : {
729
- contentType : 'application/did+json',
730
- error : 'invalidDid',
731
- errorMessage : `Cannot parse DID: ${didUrl}`
732
- }
733
- };
734
- }
735
-
736
- if (parsedDid.method !== 'key') {
737
- return {
738
- '@context' : 'https://w3id.org/did-resolution/v1',
739
- didDocument : undefined,
740
- didDocumentMetadata : {},
741
- didResolutionMetadata : {
742
- contentType : 'application/did+json',
743
- error : 'methodNotSupported',
744
- errorMessage : `Method not supported: ${parsedDid.method}`
745
- }
746
- };
747
- }
748
-
749
- const didDocument = await DidKeyMethod.createDocument({ did: parsedDid.did });
750
-
751
- return {
752
- '@context' : 'https://w3id.org/did-resolution/v1',
753
- didDocument,
754
- didDocumentMetadata : {},
755
- didResolutionMetadata : {
756
- contentType : 'application/did+json',
757
- did : {
758
- didString : parsedDid.did,
759
- methodSpecificId : parsedDid.id,
760
- method : parsedDid.method
761
- }
762
- }
763
- };
764
- }
765
-
766
- public static validateIdentifier(options: {
767
- did: string
768
- }): boolean {
769
- const { did } = options;
770
-
771
- const { method, id: multibaseValue } = parseDid({ didUrl: did });
772
- const [scheme] = did.split(':', 1);
773
-
774
- /**
775
- * Note: The W3C DID specification makes no mention of a version value
776
- * being part of the DID syntax. Additionally, there does not
777
- * appear to be any real-world usage of the version number.
778
- * Consequently, this implementation will ignore the version
779
- * related guidance in the did:key specification.
780
- */
781
- const version = '1';
782
-
783
- return (
784
- scheme !== 'did' ||
785
- method !== 'key' ||
786
- parseInt(version) > 0 ||
787
- universalTypeOf(multibaseValue) !== 'String' ||
788
- !multibaseValue.startsWith('z')
789
- );
790
- }
791
- }