From 5562cb1751643eee16b4bf3304a5178a394a7f15 Mon Sep 17 00:00:00 2001 From: Daniel Bluhm Date: Tue, 30 Jan 2024 23:17:16 -0500 Subject: [PATCH] feat: add Multikey as supported vm type (#1720) --- .../domain/key-type/__tests__/ed25519.test.ts | 1 + .../domain/key-type/__tests__/x25519.test.ts | 6 ++- .../modules/dids/domain/key-type/ed25519.ts | 8 +++ .../dids/domain/key-type/keyDidMapping.ts | 19 ++++++- .../modules/dids/domain/key-type/x25519.ts | 8 +++ .../domain/verificationMethod/Multikey.ts | 50 +++++++++++++++++++ .../dids/domain/verificationMethod/index.ts | 1 + 7 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 packages/core/src/modules/dids/domain/verificationMethod/Multikey.ts diff --git a/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts b/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts index f7b046f7d8..f57600a3c0 100644 --- a/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts +++ b/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts @@ -56,6 +56,7 @@ describe('ed25519', () => { 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020', 'JsonWebKey2020', + 'Multikey', ]) }) diff --git a/packages/core/src/modules/dids/domain/key-type/__tests__/x25519.test.ts b/packages/core/src/modules/dids/domain/key-type/__tests__/x25519.test.ts index a95a552ea4..5fb6490e43 100644 --- a/packages/core/src/modules/dids/domain/key-type/__tests__/x25519.test.ts +++ b/packages/core/src/modules/dids/domain/key-type/__tests__/x25519.test.ts @@ -52,7 +52,11 @@ describe('x25519', () => { }) it('supports X25519KeyAgreementKey2019 verification method type', () => { - expect(keyDidX25519.supportedVerificationMethodTypes).toMatchObject(['X25519KeyAgreementKey2019', 'JsonWebKey2020']) + expect(keyDidX25519.supportedVerificationMethodTypes).toMatchObject([ + 'X25519KeyAgreementKey2019', + 'JsonWebKey2020', + 'Multikey', + ]) }) it('returns key for X25519KeyAgreementKey2019 verification method', () => { diff --git a/packages/core/src/modules/dids/domain/key-type/ed25519.ts b/packages/core/src/modules/dids/domain/key-type/ed25519.ts index 7142997dbc..b1184242eb 100644 --- a/packages/core/src/modules/dids/domain/key-type/ed25519.ts +++ b/packages/core/src/modules/dids/domain/key-type/ed25519.ts @@ -11,9 +11,12 @@ import { isEd25519VerificationKey2020, isJsonWebKey2020, getEd25519VerificationKey2018, + getKeyFromMultikey, + isMultikey, VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018, VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020, VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020, + VERIFICATION_METHOD_TYPE_MULTIKEY, } from '../verificationMethod' export { convertPublicKeyToX25519 } from '@stablelib/ed25519' @@ -23,6 +26,7 @@ export const keyDidEd25519: KeyDidMapping = { VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018, VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020, VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020, + VERIFICATION_METHOD_TYPE_MULTIKEY, ], getVerificationMethods: (did, key) => [ getEd25519VerificationKey2018({ id: `${did}#${key.fingerprint}`, key, controller: did }), @@ -40,6 +44,10 @@ export const keyDidEd25519: KeyDidMapping = { return getKeyFromJsonWebKey2020(verificationMethod) } + if (isMultikey(verificationMethod)) { + return getKeyFromMultikey(verificationMethod) + } + throw new AriesFrameworkError( `Verification method with type '${verificationMethod.type}' not supported for key type '${KeyType.Ed25519}'` ) diff --git a/packages/core/src/modules/dids/domain/key-type/keyDidMapping.ts b/packages/core/src/modules/dids/domain/key-type/keyDidMapping.ts index 6d3b117bf5..dfd277e60c 100644 --- a/packages/core/src/modules/dids/domain/key-type/keyDidMapping.ts +++ b/packages/core/src/modules/dids/domain/key-type/keyDidMapping.ts @@ -1,9 +1,14 @@ import type { Key } from '../../../../crypto/Key' -import type { VerificationMethod } from '../verificationMethod' import { KeyType } from '../../../../crypto/KeyType' import { getJwkFromJson } from '../../../../crypto/jose/jwk' import { AriesFrameworkError } from '../../../../error' +import { + VERIFICATION_METHOD_TYPE_MULTIKEY, + isMultikey, + type VerificationMethod, + getKeyFromMultikey, +} from '../verificationMethod' import { isJsonWebKey2020, VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020 } from '../verificationMethod/JsonWebKey2020' import { keyDidBls12381g1 } from './bls12381g1' @@ -67,7 +72,7 @@ export function getKeyDidMappingByKeyType(keyType: KeyType) { return keyDid } -export function getKeyFromVerificationMethod(verificationMethod: VerificationMethod) { +export function getKeyFromVerificationMethod(verificationMethod: VerificationMethod): Key { // This is a special verification method, as it supports basically all key types. if (isJsonWebKey2020(verificationMethod)) { // TODO: move this validation to another place @@ -80,6 +85,16 @@ export function getKeyFromVerificationMethod(verificationMethod: VerificationMet return getJwkFromJson(verificationMethod.publicKeyJwk).key } + if (isMultikey(verificationMethod)) { + if (!verificationMethod.publicKeyMultibase) { + throw new AriesFrameworkError( + `Missing publicKeyMultibase on verification method with type ${VERIFICATION_METHOD_TYPE_MULTIKEY}` + ) + } + + return getKeyFromMultikey(verificationMethod) + } + const keyDid = verificationMethodKeyDidMapping[verificationMethod.type] if (!keyDid) { throw new AriesFrameworkError(`Unsupported key did from verification method type '${verificationMethod.type}'`) diff --git a/packages/core/src/modules/dids/domain/key-type/x25519.ts b/packages/core/src/modules/dids/domain/key-type/x25519.ts index 60f22cf4bb..d9683811bf 100644 --- a/packages/core/src/modules/dids/domain/key-type/x25519.ts +++ b/packages/core/src/modules/dids/domain/key-type/x25519.ts @@ -11,12 +11,16 @@ import { getKeyFromJsonWebKey2020, isJsonWebKey2020, VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020, + VERIFICATION_METHOD_TYPE_MULTIKEY, + isMultikey, + getKeyFromMultikey, } from '../verificationMethod' export const keyDidX25519: KeyDidMapping = { supportedVerificationMethodTypes: [ VERIFICATION_METHOD_TYPE_X25519_KEY_AGREEMENT_KEY_2019, VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020, + VERIFICATION_METHOD_TYPE_MULTIKEY, ], getVerificationMethods: (did, key) => [ getX25519KeyAgreementKey2019({ id: `${did}#${key.fingerprint}`, key, controller: did }), @@ -30,6 +34,10 @@ export const keyDidX25519: KeyDidMapping = { return getKeyFromX25519KeyAgreementKey2019(verificationMethod) } + if (isMultikey(verificationMethod)) { + return getKeyFromMultikey(verificationMethod) + } + throw new AriesFrameworkError( `Verification method with type '${verificationMethod.type}' not supported for key type '${KeyType.X25519}'` ) diff --git a/packages/core/src/modules/dids/domain/verificationMethod/Multikey.ts b/packages/core/src/modules/dids/domain/verificationMethod/Multikey.ts new file mode 100644 index 0000000000..4eb35ef715 --- /dev/null +++ b/packages/core/src/modules/dids/domain/verificationMethod/Multikey.ts @@ -0,0 +1,50 @@ +import type { VerificationMethod } from './VerificationMethod' + +import { Key } from '../../../../crypto/Key' +import { AriesFrameworkError } from '../../../../error' + +export const VERIFICATION_METHOD_TYPE_MULTIKEY = 'Multikey' + +type GetMultikeyOptions = { + did: string + key: Key + verificationMethodId?: string +} + +/** + * Get a Multikey verification method. + */ +export function getMultikey({ did, key, verificationMethodId }: GetMultikeyOptions) { + if (!verificationMethodId) { + verificationMethodId = `${did}#${key.fingerprint}` + } + + return { + id: verificationMethodId, + type: VERIFICATION_METHOD_TYPE_MULTIKEY, + controller: did, + publicKeyMultibase: key.fingerprint, + } +} + +/** + * Check whether a verification method is a Multikey verification method. + */ +export function isMultikey( + verificationMethod: VerificationMethod +): verificationMethod is VerificationMethod & { type: 'Multikey' } { + return verificationMethod.type === VERIFICATION_METHOD_TYPE_MULTIKEY +} + +/** + * Get a key from a Multikey verification method. + */ +export function getKeyFromMultikey(verificationMethod: VerificationMethod & { type: 'Multikey' }) { + if (!verificationMethod.publicKeyMultibase) { + throw new AriesFrameworkError( + `Missing publicKeyMultibase on verification method with type ${VERIFICATION_METHOD_TYPE_MULTIKEY}` + ) + } + + return Key.fromFingerprint(verificationMethod.publicKeyMultibase) +} diff --git a/packages/core/src/modules/dids/domain/verificationMethod/index.ts b/packages/core/src/modules/dids/domain/verificationMethod/index.ts index beac765a24..d696f0a2be 100644 --- a/packages/core/src/modules/dids/domain/verificationMethod/index.ts +++ b/packages/core/src/modules/dids/domain/verificationMethod/index.ts @@ -7,3 +7,4 @@ export * from './Ed25519VerificationKey2018' export * from './Ed25519VerificationKey2020' export * from './JsonWebKey2020' export * from './X25519KeyAgreementKey2019' +export * from './Multikey'