Skip to content

Commit

Permalink
feat: fetch verification method types by proof type (#913)
Browse files Browse the repository at this point in the history
Signed-off-by: Karim <karim@animo.id>
  • Loading branch information
karimStekelenburg authored Aug 11, 2022
1 parent d2fe29e commit a457773
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ describe('ed25519', () => {
})

it('supports Ed25519VerificationKey2018 verification method type', () => {
expect(keyDidEd25519.supportedVerificationMethodTypes).toMatchObject(['Ed25519VerificationKey2018'])
expect(keyDidEd25519.supportedVerificationMethodTypes).toMatchObject([
'Ed25519VerificationKey2018',
'Ed25519VerificationKey2020',
])
})

it('returns key for Ed25519VerificationKey2018 verification method', () => {
Expand All @@ -63,6 +66,22 @@ describe('ed25519', () => {
expect(key.fingerprint).toBe(TEST_ED25519_FINGERPRINT)
})

it('returns key for Ed25519VerificationKey2020 verification method', () => {
const verificationMethod = JsonTransformer.fromJSON(
{
id: 'did:example:123',
type: 'Ed25519VerificationKey2020',
controller: 'did:example:123',
publicKeyMultibase: 'z6MkkBWg1AnNxxWiq77gJDeHsLhGN6JV9Y3d6WiTifUs1sZi',
},
VerificationMethod
)

const key = keyDidEd25519.getKeyFromVerificationMethod(verificationMethod)

expect(key.publicKeyBase58).toBe('6jFdQvXwdR2FicGycegT2F9GYX2djeoGQVoXtPWr6enL')
})

it('throws an error if an invalid verification method is passed', () => {
const verificationMethod = JsonTransformer.fromJSON(didKeyEd25519Fixture.verificationMethod[0], VerificationMethod)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { KeyDidMapping } from './keyDidMapping'
import { KeyType } from '../../../../crypto'
import { Key } from '../../../../crypto/Key'

const VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020 = 'Bls12381G2Key2020'
export const VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020 = 'Bls12381G2Key2020'

export function getBls12381g2VerificationMethod(did: string, key: Key) {
return {
Expand Down
22 changes: 16 additions & 6 deletions packages/core/src/modules/dids/domain/key-type/ed25519.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { convertPublicKeyToX25519 } from '@stablelib/ed25519'
import { KeyType } from '../../../../crypto'
import { Key } from '../../../../crypto/Key'

const VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018 = 'Ed25519VerificationKey2018'
export const VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018 = 'Ed25519VerificationKey2018'
export const VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020 = 'Ed25519VerificationKey2020'

export function getEd25519VerificationMethod({ key, id, controller }: { id: string; key: Key; controller: string }) {
return {
Expand All @@ -18,19 +19,28 @@ export function getEd25519VerificationMethod({ key, id, controller }: { id: stri
}

export const keyDidEd25519: KeyDidMapping = {
supportedVerificationMethodTypes: [VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018],
supportedVerificationMethodTypes: [
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018,
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020,
],
getVerificationMethods: (did, key) => [
getEd25519VerificationMethod({ id: `${did}#${key.fingerprint}`, key, controller: did }),
],
getKeyFromVerificationMethod: (verificationMethod: VerificationMethod) => {
if (
verificationMethod.type !== VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018 ||
!verificationMethod.publicKeyBase58
verificationMethod.type === VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018 &&
verificationMethod.publicKeyBase58
) {
return Key.fromPublicKeyBase58(verificationMethod.publicKeyBase58, KeyType.Ed25519)
}
if (
verificationMethod.type === VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020 &&
verificationMethod.publicKeyMultibase
) {
throw new Error('Invalid verification method passed')
return Key.fromFingerprint(verificationMethod.publicKeyMultibase)
}

return Key.fromPublicKeyBase58(verificationMethod.publicKeyBase58, KeyType.Ed25519)
throw new Error('Invalid verification method passed')
},
}

Expand Down
20 changes: 17 additions & 3 deletions packages/core/src/modules/vc/SignatureSuiteRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export const SignatureSuiteToken = Symbol('SignatureSuiteToken')
export interface SuiteInfo {
suiteClass: typeof LinkedDataSignature
proofType: string
requiredKeyType: string
keyType: string
verificationMethodTypes: string[]
keyTypes: KeyType[]
}

@injectable()
Expand All @@ -27,8 +27,12 @@ export class SignatureSuiteRegistry {
return this.suiteMapping.map((x) => x.proofType)
}

public getByVerificationMethodType(verificationMethodType: string) {
return this.suiteMapping.find((x) => x.verificationMethodTypes.includes(verificationMethodType))
}

public getByKeyType(keyType: KeyType) {
return this.suiteMapping.find((x) => x.keyType === keyType)
return this.suiteMapping.find((x) => x.keyTypes.includes(keyType))
}

public getByProofType(proofType: string) {
Expand All @@ -40,4 +44,14 @@ export class SignatureSuiteRegistry {

return suiteInfo
}

public getVerificationMethodTypesByProofType(proofType: string): string[] {
const suiteInfo = this.suiteMapping.find((suiteInfo) => suiteInfo.proofType === proofType)

if (!suiteInfo) {
throw new AriesFrameworkError(`No verification method type found for proof type: ${proofType}`)
}

return suiteInfo.verificationMethodTypes
}
}
12 changes: 10 additions & 2 deletions packages/core/src/modules/vc/W3cCredentialService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class W3cCredentialService {
const signingKey = await this.getPublicKeyFromVerificationMethod(agentContext, options.verificationMethod)
const suiteInfo = this.suiteRegistry.getByProofType(options.proofType)

if (signingKey.keyType !== suiteInfo.keyType) {
if (!suiteInfo.keyTypes.includes(signingKey.keyType)) {
throw new AriesFrameworkError('The key type of the verification method does not match the suite')
}

Expand Down Expand Up @@ -169,7 +169,7 @@ export class W3cCredentialService {

const signingKey = await this.getPublicKeyFromVerificationMethod(agentContext, options.verificationMethod)

if (signingKey.keyType !== suiteInfo.keyType) {
if (!suiteInfo.keyTypes.includes(signingKey.keyType)) {
throw new AriesFrameworkError('The key type of the verification method does not match the suite')
}

Expand Down Expand Up @@ -379,6 +379,14 @@ export class W3cCredentialService {
return result.map((record) => record.credential)
}

public getVerificationMethodTypesByProofType(proofType: string): string[] {
return this.suiteRegistry.getByProofType(proofType).verificationMethodTypes
}

public getKeyTypesByProofType(proofType: string): string[] {
return this.suiteRegistry.getByProofType(proofType).keyTypes
}

public async findCredentialRecordByQuery(
agentContext: AgentContext,
query: Query<W3cCredentialRecord>
Expand Down
20 changes: 14 additions & 6 deletions packages/core/src/modules/vc/W3cVcModule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { DependencyManager, Module } from '../../plugins'

import { KeyType } from '../../crypto'
import { VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020 } from '../dids/domain/key-type/bls12381g2'
import {
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018,
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020,
} from '../dids/domain/key-type/ed25519'

import { SignatureSuiteRegistry, SignatureSuiteToken } from './SignatureSuiteRegistry'
import { W3cCredentialService } from './W3cCredentialService'
Expand All @@ -19,22 +24,25 @@ export class W3cVcModule implements Module {
dependencyManager.registerInstance(SignatureSuiteToken, {
suiteClass: Ed25519Signature2018,
proofType: 'Ed25519Signature2018',
requiredKeyType: 'Ed25519VerificationKey2018',
keyType: KeyType.Ed25519,
verificationMethodTypes: [
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018,
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020,
],
keyTypes: [KeyType.Ed25519],
})

// This will be moved out of core into the bbs module
dependencyManager.registerInstance(SignatureSuiteToken, {
suiteClass: BbsBlsSignature2020,
proofType: 'BbsBlsSignature2020',
requiredKeyType: 'BbsBlsSignatureProof2020',
keyType: KeyType.Bls12381g2,
verificationMethodTypes: [VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020],
keyTypes: [KeyType.Bls12381g2],
})
dependencyManager.registerInstance(SignatureSuiteToken, {
suiteClass: BbsBlsSignatureProof2020,
proofType: 'BbsBlsSignatureProof2020',
requiredKeyType: 'BbsBlsSignatureProof2020',
keyType: KeyType.Bls12381g2,
verificationMethodTypes: [VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020],
keyTypes: [KeyType.Bls12381g2],
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { JsonTransformer } from '../../../utils/JsonTransformer'
import { IndyWallet } from '../../../wallet/IndyWallet'
import { WalletError } from '../../../wallet/error'
import { DidKey, DidResolverService } from '../../dids'
import { VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020 } from '../../dids/domain/key-type/bls12381g2'
import {
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018,
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020,
} from '../../dids/domain/key-type/ed25519'
import { SignatureSuiteRegistry } from '../SignatureSuiteRegistry'
import { W3cCredentialService } from '../W3cCredentialService'
import { orArrayToArray } from '../jsonldUtil'
Expand All @@ -29,20 +34,24 @@ const signatureSuiteRegistry = new SignatureSuiteRegistry([
{
suiteClass: Ed25519Signature2018,
proofType: 'Ed25519Signature2018',
requiredKeyType: 'Ed25519VerificationKey2018',
keyType: KeyType.Ed25519,

verificationMethodTypes: [
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018,
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020,
],
keyTypes: [KeyType.Ed25519],
},
{
suiteClass: BbsBlsSignature2020,
proofType: 'BbsBlsSignature2020',
requiredKeyType: 'BbsBlsSignatureProof2020',
keyType: KeyType.Bls12381g2,
verificationMethodTypes: [VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020],
keyTypes: [KeyType.Bls12381g2],
},
{
suiteClass: BbsBlsSignatureProof2020,
proofType: 'BbsBlsSignatureProof2020',
requiredKeyType: 'BbsBlsSignatureProof2020',
keyType: KeyType.Bls12381g2,
verificationMethodTypes: [VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020],
keyTypes: [KeyType.Bls12381g2],
},
])

Expand Down Expand Up @@ -94,6 +103,44 @@ describe('W3cCredentialService', () => {
await wallet.delete()
})

describe('Utility methods', () => {
describe('getKeyTypesByProofType', () => {
it('should return the correct key types for Ed25519Signature2018 proof type', async () => {
const keyTypes = w3cCredentialService.getKeyTypesByProofType('Ed25519Signature2018')
expect(keyTypes).toEqual([KeyType.Ed25519])
})
it('should return the correct key types for BbsBlsSignature2020 proof type', async () => {
const keyTypes = w3cCredentialService.getKeyTypesByProofType('BbsBlsSignature2020')
expect(keyTypes).toEqual([KeyType.Bls12381g2])
})
it('should return the correct key types for BbsBlsSignatureProof2020 proof type', async () => {
const keyTypes = w3cCredentialService.getKeyTypesByProofType('BbsBlsSignatureProof2020')
expect(keyTypes).toEqual([KeyType.Bls12381g2])
})
})

describe('getVerificationMethodTypesByProofType', () => {
it('should return the correct key types for Ed25519Signature2018 proof type', async () => {
const verificationMethodTypes =
w3cCredentialService.getVerificationMethodTypesByProofType('Ed25519Signature2018')
expect(verificationMethodTypes).toEqual([
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018,
VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020,
])
})
it('should return the correct key types for BbsBlsSignature2020 proof type', async () => {
const verificationMethodTypes =
w3cCredentialService.getVerificationMethodTypesByProofType('BbsBlsSignature2020')
expect(verificationMethodTypes).toEqual([VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020])
})
it('should return the correct key types for BbsBlsSignatureProof2020 proof type', async () => {
const verificationMethodTypes =
w3cCredentialService.getVerificationMethodTypesByProofType('BbsBlsSignatureProof2020')
expect(verificationMethodTypes).toEqual([VERIFICATION_METHOD_TYPE_BLS12381G2_KEY_2020])
})
})
})

describe('Ed25519Signature2018', () => {
let issuerDidKey: DidKey
let verificationMethod: string
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/modules/vc/__tests__/W3cVcModule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ describe('W3cVcModule', () => {
expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(3)
expect(dependencyManager.registerInstance).toHaveBeenCalledWith(SignatureSuiteToken, {
suiteClass: Ed25519Signature2018,
verificationMethodTypes: ['Ed25519VerificationKey2018', 'Ed25519VerificationKey2020'],
proofType: 'Ed25519Signature2018',
requiredKeyType: 'Ed25519VerificationKey2018',
keyType: KeyType.Ed25519,
keyTypes: [KeyType.Ed25519],
})

expect(dependencyManager.registerInstance).toHaveBeenCalledWith(SignatureSuiteToken, {
suiteClass: BbsBlsSignature2020,
verificationMethodTypes: ['Bls12381G2Key2020'],
proofType: 'BbsBlsSignature2020',
requiredKeyType: 'BbsBlsSignatureProof2020',
keyType: KeyType.Bls12381g2,
keyTypes: [KeyType.Bls12381g2],
})

expect(dependencyManager.registerInstance).toHaveBeenCalledWith(SignatureSuiteToken, {
suiteClass: BbsBlsSignatureProof2020,
proofType: 'BbsBlsSignatureProof2020',
requiredKeyType: 'BbsBlsSignatureProof2020',
keyType: KeyType.Bls12381g2,
verificationMethodTypes: ['Bls12381G2Key2020'],
keyTypes: [KeyType.Bls12381g2],
})
})
})

0 comments on commit a457773

Please sign in to comment.