From ab8b8ef1357c7a8dc338eaea16b20d93a0c92d4f Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Tue, 19 Jul 2022 10:30:48 +0200 Subject: [PATCH] feat: add dynamic suite and signing provider (#949) Signed-off-by: Timo Glastra --- packages/core/src/crypto/BbsService.ts | 151 ------------------ .../src/crypto/__tests__/JwsService.test.ts | 3 +- .../Bls12381g2SigningProvider.ts | 111 +++++++++++++ .../signing-provider/SigningProvider.ts | 32 ++++ .../signing-provider/SigningProviderError.ts | 3 + .../SigningProviderRegistry.ts | 32 ++++ .../__tests__/SigningProviderRegistry.test.ts | 46 ++++++ .../core/src/crypto/signing-provider/index.ts | 4 + .../signature/SignatureDecoratorUtils.test.ts | 3 +- .../__tests__/ConnectionService.test.ts | 3 +- .../modules/dids/__tests__/peer-did.test.ts | 3 +- .../__tests__/IndyLedgerService.test.ts | 3 +- .../ledger/__tests__/IndyPoolService.test.ts | 3 +- .../ledger/__tests__/LedgerModule.test.ts | 3 +- .../oob/__tests__/OutOfBandService.test.ts | 3 +- .../__tests__/QuestionAnswerService.test.ts | 3 +- .../MediationRecipientService.test.ts | 3 +- .../src/modules/vc/SignatureSuiteRegistry.ts | 33 ++-- .../src/modules/vc/W3cCredentialService.ts | 8 +- .../vc/__tests__/W3cCredentialService.test.ts | 31 +++- packages/core/src/modules/vc/module.ts | 28 ++++ packages/core/src/plugins/index.ts | 2 +- .../__tests__/IndyStorageService.test.ts | 3 +- packages/core/src/wallet/IndyWallet.test.ts | 24 +-- packages/core/src/wallet/IndyWallet.ts | 69 +++++--- packages/core/src/wallet/WalletModule.ts | 4 + 26 files changed, 381 insertions(+), 230 deletions(-) delete mode 100644 packages/core/src/crypto/BbsService.ts create mode 100644 packages/core/src/crypto/signing-provider/Bls12381g2SigningProvider.ts create mode 100644 packages/core/src/crypto/signing-provider/SigningProvider.ts create mode 100644 packages/core/src/crypto/signing-provider/SigningProviderError.ts create mode 100644 packages/core/src/crypto/signing-provider/SigningProviderRegistry.ts create mode 100644 packages/core/src/crypto/signing-provider/__tests__/SigningProviderRegistry.test.ts create mode 100644 packages/core/src/crypto/signing-provider/index.ts diff --git a/packages/core/src/crypto/BbsService.ts b/packages/core/src/crypto/BbsService.ts deleted file mode 100644 index c00e814249..0000000000 --- a/packages/core/src/crypto/BbsService.ts +++ /dev/null @@ -1,151 +0,0 @@ -import type { CreateKeyOptions } from '../wallet' -import type { BlsKeyPair as _BlsKeyPair } from '@mattrglobal/bbs-signatures' - -import { - bls12381toBbs, - generateBls12381G2KeyPair, - generateBls12381G1KeyPair, - sign, - verify, -} from '@mattrglobal/bbs-signatures' - -import { TypedArrayEncoder } from '../utils/TypedArrayEncoder' -import { Buffer } from '../utils/buffer' -import { WalletError } from '../wallet/error' - -import { KeyType } from './KeyType' - -export interface BlsKeyPair { - publicKeyBase58: string - privateKeyBase58: string - keyType: Extract -} - -interface BbsCreateKeyOptions extends CreateKeyOptions { - keyType: Extract -} - -interface BbsSignOptions { - messages: Buffer | Buffer[] - publicKey: Buffer - privateKey: Buffer -} - -interface BbsVerifyOptions { - publicKey: Buffer - signature: Buffer - messages: Buffer | Buffer[] -} - -export class BbsService { - /** - * Create an instance of a Key class for the following key types: - * - Bls12381g1 - * - Bls12381g2 - * - * @param keyType KeyType The type of key to be created (see above for the accepted types) - * - * @returns A Key class with the public key and key type - * - * @throws {WalletError} When a key could not be created - * @throws {WalletError} When the method is called with an invalid keytype - */ - public static async createKey({ keyType, seed }: BbsCreateKeyOptions): Promise { - // Generate bytes from the seed as required by the bbs-signatures libraries - const seedBytes = seed ? TypedArrayEncoder.fromString(seed) : undefined - - // Temporary keypair holder - let blsKeyPair: Required<_BlsKeyPair> - - switch (keyType) { - case KeyType.Bls12381g1: - // Generate a bls12-381G1 keypair - blsKeyPair = await generateBls12381G1KeyPair(seedBytes) - break - case KeyType.Bls12381g2: - // Generate a bls12-381G2 keypair - blsKeyPair = await generateBls12381G2KeyPair(seedBytes) - break - default: - // additional check. Should never be hit as this function will only be called from a place where - // a key type check already happened. - throw new WalletError(`Cannot create key with the BbsService for key type: ${keyType}`) - } - - return { - keyType, - publicKeyBase58: TypedArrayEncoder.toBase58(blsKeyPair.publicKey), - privateKeyBase58: TypedArrayEncoder.toBase58(blsKeyPair.secretKey), - } - } - - /** - * Sign an arbitrary amount of messages, in byte form, with a keypair - * - * @param messages Buffer[] List of messages in Buffer form - * @param publicKey Buffer Publickey required for the signing process - * @param privateKey Buffer PrivateKey required for the signing process - * - * @returns A Buffer containing the signature of the messages - * - * @throws {WalletError} When there are no supplied messages - */ - public static async sign({ messages, publicKey, privateKey }: BbsSignOptions): Promise { - if (messages.length === 0) throw new WalletError('Unable to create a signature without any messages') - // Check if it is a single message or list and if it is a single message convert it to a list - const normalizedMessages = (TypedArrayEncoder.isTypedArray(messages) ? [messages as Buffer] : messages) as Buffer[] - - // Get the Uint8Array variant of all the messages - const messageBuffers = normalizedMessages.map((m) => Uint8Array.from(m)) - - const bbsKeyPair = await bls12381toBbs({ - keyPair: { publicKey: Uint8Array.from(publicKey), secretKey: Uint8Array.from(privateKey) }, - messageCount: normalizedMessages.length, - }) - - // Sign the messages via the keyPair - const signature = await sign({ - keyPair: bbsKeyPair, - messages: messageBuffers, - }) - - // Convert the Uint8Array signature to a Buffer type - return Buffer.from(signature) - } - - /** - * Verify an arbitrary amount of messages with their signature created with their key pair - * - * @param publicKey Buffer The public key used to sign the messages - * @param messages Buffer[] The messages that have to be verified if they are signed - * @param signature Buffer The signature that has to be verified if it was created with the messages and public key - * - * @returns A boolean whether the signature is create with the public key over the messages - * - * @throws {WalletError} When the message list is empty - * @throws {WalletError} When the verification process failed - */ - public static async verify({ signature, messages, publicKey }: BbsVerifyOptions): Promise { - if (messages.length === 0) throw new WalletError('Unable to create a signature without any messages') - // Check if it is a single message or list and if it is a single message convert it to a list - const normalizedMessages = (TypedArrayEncoder.isTypedArray(messages) ? [messages as Buffer] : messages) as Buffer[] - - // Get the Uint8Array variant of all the messages - const messageBuffers = normalizedMessages.map((m) => Uint8Array.from(m)) - - const bbsKeyPair = await bls12381toBbs({ - keyPair: { publicKey: Uint8Array.from(publicKey) }, - messageCount: normalizedMessages.length, - }) - - // Verify the signature against the messages with their public key - const { verified, error } = await verify({ signature, messages: messageBuffers, publicKey: bbsKeyPair.publicKey }) - - // If the messages could not be verified and an error occured - if (!verified && error) { - throw new WalletError(`Could not verify the signature against the messages: ${error}`) - } - - return verified - } -} diff --git a/packages/core/src/crypto/__tests__/JwsService.test.ts b/packages/core/src/crypto/__tests__/JwsService.test.ts index d3371200ff..41b777e3cd 100644 --- a/packages/core/src/crypto/__tests__/JwsService.test.ts +++ b/packages/core/src/crypto/__tests__/JwsService.test.ts @@ -8,6 +8,7 @@ import { IndyWallet } from '../../wallet/IndyWallet' import { JwsService } from '../JwsService' import { Key } from '../Key' import { KeyType } from '../KeyType' +import { SigningProviderRegistry } from '../signing-provider' import * as didJwsz6Mkf from './__fixtures__/didJwsz6Mkf' import * as didJwsz6Mkv from './__fixtures__/didJwsz6Mkv' @@ -19,7 +20,7 @@ describe('JwsService', () => { beforeAll(async () => { const config = getAgentConfig('JwsService') - wallet = new IndyWallet(config.agentDependencies, config.logger) + wallet = new IndyWallet(config.agentDependencies, config.logger, new SigningProviderRegistry([])) agentContext = getAgentContext({ wallet, }) diff --git a/packages/core/src/crypto/signing-provider/Bls12381g2SigningProvider.ts b/packages/core/src/crypto/signing-provider/Bls12381g2SigningProvider.ts new file mode 100644 index 0000000000..02998c007f --- /dev/null +++ b/packages/core/src/crypto/signing-provider/Bls12381g2SigningProvider.ts @@ -0,0 +1,111 @@ +import type { SigningProvider, CreateKeyPairOptions, SignOptions, VerifyOptions, KeyPair } from './SigningProvider' + +import { bls12381toBbs, verify, sign, generateBls12381G2KeyPair } from '@mattrglobal/bbs-signatures' + +import { injectable } from '../../plugins' +import { TypedArrayEncoder } from '../../utils' +import { Buffer } from '../../utils/buffer' +import { KeyType } from '../KeyType' + +import { SigningProviderError } from './SigningProviderError' + +/** + * This will be extracted to the bbs package. + */ +@injectable() +export class Bls12381g2SigningProvider implements SigningProvider { + public readonly keyType = KeyType.Bls12381g2 + + /** + * Create a KeyPair with type Bls12381g2 + * + * @throws {SigningProviderError} When a key could not be created + */ + public async createKeyPair({ seed }: CreateKeyPairOptions): Promise { + // Generate bytes from the seed as required by the bbs-signatures libraries + const seedBytes = seed ? TypedArrayEncoder.fromString(seed) : undefined + + const blsKeyPair = await generateBls12381G2KeyPair(seedBytes) + + return { + keyType: KeyType.Bls12381g2, + publicKeyBase58: TypedArrayEncoder.toBase58(blsKeyPair.publicKey), + privateKeyBase58: TypedArrayEncoder.toBase58(blsKeyPair.secretKey), + } + } + + /** + * Sign an arbitrary amount of messages, in byte form, with a keypair + * + * @param messages Buffer[] List of messages in Buffer form + * @param publicKey Buffer Publickey required for the signing process + * @param privateKey Buffer PrivateKey required for the signing process + * + * @returns A Buffer containing the signature of the messages + * + * @throws {SigningProviderError} When there are no supplied messages + */ + public async sign({ data, publicKeyBase58, privateKeyBase58 }: SignOptions): Promise { + if (data.length === 0) throw new SigningProviderError('Unable to create a signature without any messages') + // Check if it is a single message or list and if it is a single message convert it to a list + const normalizedMessages = (TypedArrayEncoder.isTypedArray(data) ? [data as Buffer] : data) as Buffer[] + + // Get the Uint8Array variant of all the messages + const messageBuffers = normalizedMessages.map((m) => Uint8Array.from(m)) + + const publicKey = TypedArrayEncoder.fromBase58(publicKeyBase58) + const privateKey = TypedArrayEncoder.fromBase58(privateKeyBase58) + + const bbsKeyPair = await bls12381toBbs({ + keyPair: { publicKey: Uint8Array.from(publicKey), secretKey: Uint8Array.from(privateKey) }, + messageCount: normalizedMessages.length, + }) + + // Sign the messages via the keyPair + const signature = await sign({ + keyPair: bbsKeyPair, + messages: messageBuffers, + }) + + // Convert the Uint8Array signature to a Buffer type + return Buffer.from(signature) + } + + /** + * Verify an arbitrary amount of messages with their signature created with their key pair + * + * @param publicKey Buffer The public key used to sign the messages + * @param messages Buffer[] The messages that have to be verified if they are signed + * @param signature Buffer The signature that has to be verified if it was created with the messages and public key + * + * @returns A boolean whether the signature is create with the public key over the messages + * + * @throws {SigningProviderError} When the message list is empty + * @throws {SigningProviderError} When the verification process failed + */ + public async verify({ data, publicKeyBase58, signature }: VerifyOptions): Promise { + if (data.length === 0) throw new SigningProviderError('Unable to create a signature without any messages') + // Check if it is a single message or list and if it is a single message convert it to a list + const normalizedMessages = (TypedArrayEncoder.isTypedArray(data) ? [data as Buffer] : data) as Buffer[] + + const publicKey = TypedArrayEncoder.fromBase58(publicKeyBase58) + + // Get the Uint8Array variant of all the messages + const messageBuffers = normalizedMessages.map((m) => Uint8Array.from(m)) + + const bbsKeyPair = await bls12381toBbs({ + keyPair: { publicKey: Uint8Array.from(publicKey) }, + messageCount: normalizedMessages.length, + }) + + // Verify the signature against the messages with their public key + const { verified, error } = await verify({ signature, messages: messageBuffers, publicKey: bbsKeyPair.publicKey }) + + // If the messages could not be verified and an error occurred + if (!verified && error) { + throw new SigningProviderError(`Could not verify the signature against the messages: ${error}`) + } + + return verified + } +} diff --git a/packages/core/src/crypto/signing-provider/SigningProvider.ts b/packages/core/src/crypto/signing-provider/SigningProvider.ts new file mode 100644 index 0000000000..2f2c31e701 --- /dev/null +++ b/packages/core/src/crypto/signing-provider/SigningProvider.ts @@ -0,0 +1,32 @@ +import type { Buffer } from '../../utils/buffer' +import type { KeyType } from '../KeyType' + +export interface KeyPair { + publicKeyBase58: string + privateKeyBase58: string + keyType: KeyType +} + +export interface SignOptions { + data: Buffer | Buffer[] + publicKeyBase58: string + privateKeyBase58: string +} + +export interface VerifyOptions { + data: Buffer | Buffer[] + publicKeyBase58: string + signature: Buffer +} + +export interface CreateKeyPairOptions { + seed?: string +} + +export interface SigningProvider { + readonly keyType: KeyType + + createKeyPair(options: CreateKeyPairOptions): Promise + sign(options: SignOptions): Promise + verify(options: VerifyOptions): Promise +} diff --git a/packages/core/src/crypto/signing-provider/SigningProviderError.ts b/packages/core/src/crypto/signing-provider/SigningProviderError.ts new file mode 100644 index 0000000000..21bcf0650b --- /dev/null +++ b/packages/core/src/crypto/signing-provider/SigningProviderError.ts @@ -0,0 +1,3 @@ +import { AriesFrameworkError } from '../../error' + +export class SigningProviderError extends AriesFrameworkError {} diff --git a/packages/core/src/crypto/signing-provider/SigningProviderRegistry.ts b/packages/core/src/crypto/signing-provider/SigningProviderRegistry.ts new file mode 100644 index 0000000000..993ae09547 --- /dev/null +++ b/packages/core/src/crypto/signing-provider/SigningProviderRegistry.ts @@ -0,0 +1,32 @@ +import type { KeyType } from '..' +import type { SigningProvider } from './SigningProvider' + +import { AriesFrameworkError } from '../../error' +import { injectable, injectAll } from '../../plugins' + +export const SigningProviderToken = Symbol('SigningProviderToken') + +@injectable() +export class SigningProviderRegistry { + private signingKeyProviders: SigningProvider[] + + public constructor(@injectAll(SigningProviderToken) signingKeyProviders: SigningProvider[]) { + this.signingKeyProviders = signingKeyProviders + } + + public hasProviderForKeyType(keyType: KeyType): boolean { + const signingKeyProvider = this.signingKeyProviders.find((x) => x.keyType === keyType) + + return signingKeyProvider !== undefined + } + + public getProviderForKeyType(keyType: KeyType): SigningProvider { + const signingKeyProvider = this.signingKeyProviders.find((x) => x.keyType === keyType) + + if (!signingKeyProvider) { + throw new AriesFrameworkError(`No signing key provider for key type: ${keyType}`) + } + + return signingKeyProvider + } +} diff --git a/packages/core/src/crypto/signing-provider/__tests__/SigningProviderRegistry.test.ts b/packages/core/src/crypto/signing-provider/__tests__/SigningProviderRegistry.test.ts new file mode 100644 index 0000000000..315b76f80a --- /dev/null +++ b/packages/core/src/crypto/signing-provider/__tests__/SigningProviderRegistry.test.ts @@ -0,0 +1,46 @@ +import type { Buffer } from '../../../utils/buffer' +import type { SigningProvider, KeyPair } from '../SigningProvider' + +import { KeyType } from '../../KeyType' +import { SigningProviderRegistry } from '../SigningProviderRegistry' + +class SigningProviderMock implements SigningProvider { + public readonly keyType = KeyType.Bls12381g2 + + public async createKeyPair(): Promise { + throw new Error('Method not implemented.') + } + public async sign(): Promise { + throw new Error('Method not implemented.') + } + public async verify(): Promise { + throw new Error('Method not implemented.') + } +} + +const signingProvider = new SigningProviderMock() +const signingProviderRegistry = new SigningProviderRegistry([signingProvider]) + +describe('SigningProviderRegistry', () => { + describe('hasProviderForKeyType', () => { + test('returns true if the key type is registered', () => { + expect(signingProviderRegistry.hasProviderForKeyType(KeyType.Bls12381g2)).toBe(true) + }) + + test('returns false if the key type is not registered', () => { + expect(signingProviderRegistry.hasProviderForKeyType(KeyType.Ed25519)).toBe(false) + }) + }) + + describe('getProviderForKeyType', () => { + test('returns the correct provider true if the key type is registered', () => { + expect(signingProviderRegistry.getProviderForKeyType(KeyType.Bls12381g2)).toBe(signingProvider) + }) + + test('throws error if the key type is not registered', () => { + expect(() => signingProviderRegistry.getProviderForKeyType(KeyType.Ed25519)).toThrowError( + 'No signing key provider for key type: ed25519' + ) + }) + }) +}) diff --git a/packages/core/src/crypto/signing-provider/index.ts b/packages/core/src/crypto/signing-provider/index.ts new file mode 100644 index 0000000000..165ca2ba92 --- /dev/null +++ b/packages/core/src/crypto/signing-provider/index.ts @@ -0,0 +1,4 @@ +export * from './Bls12381g2SigningProvider' +export * from './SigningProvider' +export * from './SigningProviderRegistry' +export * from './SigningProviderError' diff --git a/packages/core/src/decorators/signature/SignatureDecoratorUtils.test.ts b/packages/core/src/decorators/signature/SignatureDecoratorUtils.test.ts index 0f216a372b..ec6c906818 100644 --- a/packages/core/src/decorators/signature/SignatureDecoratorUtils.test.ts +++ b/packages/core/src/decorators/signature/SignatureDecoratorUtils.test.ts @@ -1,4 +1,5 @@ import { getAgentConfig } from '../../../tests/helpers' +import { SigningProviderRegistry } from '../../crypto/signing-provider' import { IndyWallet } from '../../wallet/IndyWallet' import { SignatureDecorator } from './SignatureDecorator' @@ -41,7 +42,7 @@ describe('Decorators | Signature | SignatureDecoratorUtils', () => { beforeAll(async () => { const config = getAgentConfig('SignatureDecoratorUtilsTest') - wallet = new IndyWallet(config.agentDependencies, config.logger) + wallet = new IndyWallet(config.agentDependencies, config.logger, new SigningProviderRegistry([])) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(config.walletConfig!) }) diff --git a/packages/core/src/modules/connections/__tests__/ConnectionService.test.ts b/packages/core/src/modules/connections/__tests__/ConnectionService.test.ts index 9f16191403..25ade9e32d 100644 --- a/packages/core/src/modules/connections/__tests__/ConnectionService.test.ts +++ b/packages/core/src/modules/connections/__tests__/ConnectionService.test.ts @@ -15,6 +15,7 @@ import { AgentMessage } from '../../../agent/AgentMessage' import { EventEmitter } from '../../../agent/EventEmitter' import { InboundMessageContext } from '../../../agent/models/InboundMessageContext' import { Key, KeyType } from '../../../crypto' +import { SigningProviderRegistry } from '../../../crypto/signing-provider' import { signData, unpackAndVerifySignatureDecorator } from '../../../decorators/signature/SignatureDecoratorUtils' import { JsonTransformer } from '../../../utils/JsonTransformer' import { uuid } from '../../../utils/uuid' @@ -63,7 +64,7 @@ describe('ConnectionService', () => { let agentContext: AgentContext beforeAll(async () => { - wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger) + wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger, new SigningProviderRegistry([])) agentContext = getAgentContext({ wallet, agentConfig }) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(agentConfig.walletConfig!) diff --git a/packages/core/src/modules/dids/__tests__/peer-did.test.ts b/packages/core/src/modules/dids/__tests__/peer-did.test.ts index 98a772fb07..38f5747b17 100644 --- a/packages/core/src/modules/dids/__tests__/peer-did.test.ts +++ b/packages/core/src/modules/dids/__tests__/peer-did.test.ts @@ -6,6 +6,7 @@ import { Subject } from 'rxjs' import { getAgentConfig, getAgentContext } from '../../../../tests/helpers' import { EventEmitter } from '../../../agent/EventEmitter' import { Key, KeyType } from '../../../crypto' +import { SigningProviderRegistry } from '../../../crypto/signing-provider' import { IndyStorageService } from '../../../storage/IndyStorageService' import { JsonTransformer } from '../../../utils' import { IndyWallet } from '../../../wallet/IndyWallet' @@ -31,7 +32,7 @@ describe('peer dids', () => { let eventEmitter: EventEmitter beforeEach(async () => { - wallet = new IndyWallet(config.agentDependencies, config.logger) + wallet = new IndyWallet(config.agentDependencies, config.logger, new SigningProviderRegistry([])) agentContext = getAgentContext({ wallet }) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(config.walletConfig!) diff --git a/packages/core/src/modules/ledger/__tests__/IndyLedgerService.test.ts b/packages/core/src/modules/ledger/__tests__/IndyLedgerService.test.ts index 85d29438a3..74636089b3 100644 --- a/packages/core/src/modules/ledger/__tests__/IndyLedgerService.test.ts +++ b/packages/core/src/modules/ledger/__tests__/IndyLedgerService.test.ts @@ -7,6 +7,7 @@ import { Subject } from 'rxjs' import { NodeFileSystem } from '../../../../../node/src/NodeFileSystem' import { getAgentConfig, getAgentContext, mockFunction } from '../../../../tests/helpers' import { CacheRepository } from '../../../cache/CacheRepository' +import { SigningProviderRegistry } from '../../../crypto/signing-provider' import { IndyWallet } from '../../../wallet/IndyWallet' import { IndyIssuerService } from '../../indy/services/IndyIssuerService' import { IndyPool } from '../IndyPool' @@ -41,7 +42,7 @@ describe('IndyLedgerService', () => { let ledgerService: IndyLedgerService beforeAll(async () => { - wallet = new IndyWallet(config.agentDependencies, config.logger) + wallet = new IndyWallet(config.agentDependencies, config.logger, new SigningProviderRegistry([])) agentContext = getAgentContext() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(config.walletConfig!) diff --git a/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts b/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts index eebbe4332c..3e6a65b96b 100644 --- a/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts +++ b/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts @@ -8,6 +8,7 @@ import { NodeFileSystem } from '../../../../../node/src/NodeFileSystem' import { agentDependencies, getAgentConfig, getAgentContext, mockFunction } from '../../../../tests/helpers' import { CacheRecord } from '../../../cache' import { CacheRepository } from '../../../cache/CacheRepository' +import { SigningProviderRegistry } from '../../../crypto/signing-provider' import { AriesFrameworkError } from '../../../error/AriesFrameworkError' import { IndyWallet } from '../../../wallet/IndyWallet' import { LedgerError } from '../error/LedgerError' @@ -63,7 +64,7 @@ describe('IndyPoolService', () => { let cacheRepository: CacheRepository beforeAll(async () => { - wallet = new IndyWallet(config.agentDependencies, config.logger) + wallet = new IndyWallet(config.agentDependencies, config.logger, new SigningProviderRegistry([])) agentContext = getAgentContext() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(config.walletConfig!) diff --git a/packages/core/src/modules/ledger/__tests__/LedgerModule.test.ts b/packages/core/src/modules/ledger/__tests__/LedgerModule.test.ts index e33c6e3c41..9be7b6167a 100644 --- a/packages/core/src/modules/ledger/__tests__/LedgerModule.test.ts +++ b/packages/core/src/modules/ledger/__tests__/LedgerModule.test.ts @@ -4,6 +4,7 @@ import type { CredentialDefinitionTemplate } from '../services/IndyLedgerService import type * as Indy from 'indy-sdk' import { getAgentConfig, getAgentContext, mockFunction, mockProperty } from '../../../../tests/helpers' +import { SigningProviderRegistry } from '../../../crypto/signing-provider' import { AriesFrameworkError } from '../../../error/AriesFrameworkError' import { IndyWallet } from '../../../wallet/IndyWallet' import { AnonCredsCredentialDefinitionRecord } from '../../indy/repository/AnonCredsCredentialDefinitionRecord' @@ -107,7 +108,7 @@ describe('LedgerModule', () => { }) beforeEach(async () => { - wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger) + wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger, new SigningProviderRegistry([])) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(agentConfig.walletConfig!) }) diff --git a/packages/core/src/modules/oob/__tests__/OutOfBandService.test.ts b/packages/core/src/modules/oob/__tests__/OutOfBandService.test.ts index d5c1e358ad..553ed826b9 100644 --- a/packages/core/src/modules/oob/__tests__/OutOfBandService.test.ts +++ b/packages/core/src/modules/oob/__tests__/OutOfBandService.test.ts @@ -14,6 +14,7 @@ import { import { EventEmitter } from '../../../agent/EventEmitter' import { InboundMessageContext } from '../../../agent/models/InboundMessageContext' import { KeyType, Key } from '../../../crypto' +import { SigningProviderRegistry } from '../../../crypto/signing-provider' import { AriesFrameworkError } from '../../../error' import { IndyWallet } from '../../../wallet/IndyWallet' import { DidExchangeState } from '../../connections/models' @@ -39,7 +40,7 @@ describe('OutOfBandService', () => { let agentContext: AgentContext beforeAll(async () => { - wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger) + wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger, new SigningProviderRegistry([])) agentContext = getAgentContext() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(agentConfig.walletConfig!) diff --git a/packages/core/src/modules/question-answer/__tests__/QuestionAnswerService.test.ts b/packages/core/src/modules/question-answer/__tests__/QuestionAnswerService.test.ts index 1820debc06..fa5f57f86e 100644 --- a/packages/core/src/modules/question-answer/__tests__/QuestionAnswerService.test.ts +++ b/packages/core/src/modules/question-answer/__tests__/QuestionAnswerService.test.ts @@ -14,6 +14,7 @@ import { mockFunction, } from '../../../../tests/helpers' import { EventEmitter } from '../../../agent/EventEmitter' +import { SigningProviderRegistry } from '../../../crypto/signing-provider' import { IndyWallet } from '../../../wallet/IndyWallet' import { QuestionAnswerEventTypes } from '../QuestionAnswerEvents' import { QuestionAnswerRole } from '../QuestionAnswerRole' @@ -62,7 +63,7 @@ describe('QuestionAnswerService', () => { beforeAll(async () => { agentConfig = getAgentConfig('QuestionAnswerServiceTest') - wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger) + wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger, new SigningProviderRegistry([])) agentContext = getAgentContext() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(agentConfig.walletConfig!) diff --git a/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts b/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts index 92f1cd2141..76c51345f1 100644 --- a/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts +++ b/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts @@ -8,6 +8,7 @@ import { AgentEventTypes } from '../../../../agent/Events' import { MessageSender } from '../../../../agent/MessageSender' import { InboundMessageContext } from '../../../../agent/models/InboundMessageContext' import { Key } from '../../../../crypto' +import { SigningProviderRegistry } from '../../../../crypto/signing-provider' import { Attachment } from '../../../../decorators/attachment/Attachment' import { AriesFrameworkError } from '../../../../error' import { uuid } from '../../../../utils/uuid' @@ -62,7 +63,7 @@ describe('MediationRecipientService', () => { let agentContext: AgentContext beforeAll(async () => { - wallet = new IndyWallet(config.agentDependencies, config.logger) + wallet = new IndyWallet(config.agentDependencies, config.logger, new SigningProviderRegistry([])) agentContext = getAgentContext({ agentConfig: config, }) diff --git a/packages/core/src/modules/vc/SignatureSuiteRegistry.ts b/packages/core/src/modules/vc/SignatureSuiteRegistry.ts index 0d5404aa44..925fa3f334 100644 --- a/packages/core/src/modules/vc/SignatureSuiteRegistry.ts +++ b/packages/core/src/modules/vc/SignatureSuiteRegistry.ts @@ -1,12 +1,13 @@ -import { KeyType } from '../../crypto' +import type { KeyType } from '../../crypto' + import { AriesFrameworkError } from '../../error' +import { injectable, injectAll } from '../../plugins' import { suites } from './libraries/jsonld-signatures' -import { Ed25519Signature2018 } from './signature-suites' -import { BbsBlsSignature2020, BbsBlsSignatureProof2020 } from './signature-suites/bbs' const LinkedDataSignature = suites.LinkedDataSignature +export const SignatureSuiteToken = Symbol('SignatureSuiteToken') export interface SuiteInfo { suiteClass: typeof LinkedDataSignature proofType: string @@ -14,27 +15,13 @@ export interface SuiteInfo { keyType: string } +@injectable() export class SignatureSuiteRegistry { - private suiteMapping: SuiteInfo[] = [ - { - suiteClass: Ed25519Signature2018, - proofType: 'Ed25519Signature2018', - requiredKeyType: 'Ed25519VerificationKey2018', - keyType: KeyType.Ed25519, - }, - { - suiteClass: BbsBlsSignature2020, - proofType: 'BbsBlsSignature2020', - requiredKeyType: 'BbsBlsSignatureProof2020', - keyType: KeyType.Bls12381g2, - }, - { - suiteClass: BbsBlsSignatureProof2020, - proofType: 'BbsBlsSignatureProof2020', - requiredKeyType: 'BbsBlsSignatureProof2020', - keyType: KeyType.Bls12381g2, - }, - ] + private suiteMapping: SuiteInfo[] + + public constructor(@injectAll(SignatureSuiteToken) suites: SuiteInfo[]) { + this.suiteMapping = suites + } public get supportedProofTypes(): string[] { return this.suiteMapping.map((x) => x.proofType) diff --git a/packages/core/src/modules/vc/W3cCredentialService.ts b/packages/core/src/modules/vc/W3cCredentialService.ts index e46260224f..a8ba4e704d 100644 --- a/packages/core/src/modules/vc/W3cCredentialService.ts +++ b/packages/core/src/modules/vc/W3cCredentialService.ts @@ -37,10 +37,14 @@ export class W3cCredentialService { private didResolver: DidResolverService private suiteRegistry: SignatureSuiteRegistry - public constructor(w3cCredentialRepository: W3cCredentialRepository, didResolver: DidResolverService) { + public constructor( + w3cCredentialRepository: W3cCredentialRepository, + didResolver: DidResolverService, + suiteRegistry: SignatureSuiteRegistry + ) { this.w3cCredentialRepository = w3cCredentialRepository this.didResolver = didResolver - this.suiteRegistry = new SignatureSuiteRegistry() + this.suiteRegistry = suiteRegistry } /** diff --git a/packages/core/src/modules/vc/__tests__/W3cCredentialService.test.ts b/packages/core/src/modules/vc/__tests__/W3cCredentialService.test.ts index b9a8e9d2a8..0d133a18f5 100644 --- a/packages/core/src/modules/vc/__tests__/W3cCredentialService.test.ts +++ b/packages/core/src/modules/vc/__tests__/W3cCredentialService.test.ts @@ -3,12 +3,14 @@ import type { AgentContext } from '../../../agent' import { getAgentConfig, getAgentContext } from '../../../../tests/helpers' import { KeyType } from '../../../crypto' import { Key } from '../../../crypto/Key' +import { Bls12381g2SigningProvider, SigningProviderRegistry } from '../../../crypto/signing-provider' import { JsonTransformer } from '../../../utils/JsonTransformer' import { IndyWallet } from '../../../wallet/IndyWallet' import { WalletError } from '../../../wallet/error' import { DidKey, DidResolverService } from '../../dids' import { DidRepository } from '../../dids/repository' import { IndyLedgerService } from '../../ledger/services/IndyLedgerService' +import { SignatureSuiteRegistry } from '../SignatureSuiteRegistry' import { W3cCredentialService } from '../W3cCredentialService' import { orArrayToArray } from '../jsonldUtil' import { purposes } from '../libraries/jsonld-signatures' @@ -18,10 +20,35 @@ import { W3cPresentation } from '../models/presentation/W3Presentation' import { W3cVerifiablePresentation } from '../models/presentation/W3cVerifiablePresentation' import { CredentialIssuancePurpose } from '../proof-purposes/CredentialIssuancePurpose' import { W3cCredentialRepository } from '../repository/W3cCredentialRepository' +import { Ed25519Signature2018 } from '../signature-suites' +import { BbsBlsSignature2020, BbsBlsSignatureProof2020 } from '../signature-suites/bbs' import { customDocumentLoader } from './documentLoader' import { BbsBlsSignature2020Fixtures, Ed25519Signature2018Fixtures } from './fixtures' +const signatureSuiteRegistry = new SignatureSuiteRegistry([ + { + suiteClass: Ed25519Signature2018, + proofType: 'Ed25519Signature2018', + requiredKeyType: 'Ed25519VerificationKey2018', + keyType: KeyType.Ed25519, + }, + { + suiteClass: BbsBlsSignature2020, + proofType: 'BbsBlsSignature2020', + requiredKeyType: 'BbsBlsSignatureProof2020', + keyType: KeyType.Bls12381g2, + }, + { + suiteClass: BbsBlsSignatureProof2020, + proofType: 'BbsBlsSignatureProof2020', + requiredKeyType: 'BbsBlsSignatureProof2020', + keyType: KeyType.Bls12381g2, + }, +]) + +const signingProviderRegistry = new SigningProviderRegistry([new Bls12381g2SigningProvider()]) + jest.mock('../../ledger/services/IndyLedgerService') const IndyLedgerServiceMock = IndyLedgerService as jest.Mock @@ -41,7 +68,7 @@ describe('W3cCredentialService', () => { const seed = 'testseed000000000000000000000001' beforeAll(async () => { - wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger) + wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger, signingProviderRegistry) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await wallet.createAndOpen(agentConfig.walletConfig!) agentContext = getAgentContext({ @@ -54,7 +81,7 @@ describe('W3cCredentialService', () => { agentConfig.logger ) w3cCredentialRepository = new W3cCredentialRepositoryMock() - w3cCredentialService = new W3cCredentialService(w3cCredentialRepository, didResolverService) + w3cCredentialService = new W3cCredentialService(w3cCredentialRepository, didResolverService, signatureSuiteRegistry) w3cCredentialService.documentLoaderWithContext = () => customDocumentLoader }) diff --git a/packages/core/src/modules/vc/module.ts b/packages/core/src/modules/vc/module.ts index 11e4983e05..f9102217e3 100644 --- a/packages/core/src/modules/vc/module.ts +++ b/packages/core/src/modules/vc/module.ts @@ -1,14 +1,42 @@ import type { DependencyManager } from '../../plugins' +import { KeyType } from '../../crypto' import { module } from '../../plugins' +import { SignatureSuiteRegistry, SignatureSuiteToken } from './SignatureSuiteRegistry' import { W3cCredentialService } from './W3cCredentialService' import { W3cCredentialRepository } from './repository/W3cCredentialRepository' +import { Ed25519Signature2018 } from './signature-suites' +import { BbsBlsSignature2020, BbsBlsSignatureProof2020 } from './signature-suites/bbs' @module() export class W3cVcModule { public static register(dependencyManager: DependencyManager) { dependencyManager.registerSingleton(W3cCredentialService) dependencyManager.registerSingleton(W3cCredentialRepository) + + dependencyManager.registerSingleton(SignatureSuiteRegistry) + + // Always register ed25519 signature suite + dependencyManager.registerInstance(SignatureSuiteToken, { + suiteClass: Ed25519Signature2018, + proofType: 'Ed25519Signature2018', + requiredKeyType: 'Ed25519VerificationKey2018', + keyType: 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, + }) + dependencyManager.registerInstance(SignatureSuiteToken, { + suiteClass: BbsBlsSignatureProof2020, + proofType: 'BbsBlsSignatureProof2020', + requiredKeyType: 'BbsBlsSignatureProof2020', + keyType: KeyType.Bls12381g2, + }) } } diff --git a/packages/core/src/plugins/index.ts b/packages/core/src/plugins/index.ts index 27b41e4d10..faee88c0f1 100644 --- a/packages/core/src/plugins/index.ts +++ b/packages/core/src/plugins/index.ts @@ -1,3 +1,3 @@ export * from './DependencyManager' export * from './Module' -export { inject, injectable, Disposable } from 'tsyringe' +export { inject, injectable, Disposable, injectAll } from 'tsyringe' diff --git a/packages/core/src/storage/__tests__/IndyStorageService.test.ts b/packages/core/src/storage/__tests__/IndyStorageService.test.ts index 08f2df3fa7..bd61553b08 100644 --- a/packages/core/src/storage/__tests__/IndyStorageService.test.ts +++ b/packages/core/src/storage/__tests__/IndyStorageService.test.ts @@ -3,6 +3,7 @@ import type { TagsBase } from '../BaseRecord' import type * as Indy from 'indy-sdk' import { agentDependencies, getAgentConfig, getAgentContext } from '../../../tests/helpers' +import { SigningProviderRegistry } from '../../crypto/signing-provider' import { RecordDuplicateError, RecordNotFoundError } from '../../error' import { IndyWallet } from '../../wallet/IndyWallet' import { IndyStorageService } from '../IndyStorageService' @@ -18,7 +19,7 @@ describe('IndyStorageService', () => { beforeEach(async () => { const agentConfig = getAgentConfig('IndyStorageServiceTest') indy = agentConfig.agentDependencies.indy - wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger) + wallet = new IndyWallet(agentConfig.agentDependencies, agentConfig.logger, new SigningProviderRegistry([])) agentContext = getAgentContext({ wallet, agentConfig, diff --git a/packages/core/src/wallet/IndyWallet.test.ts b/packages/core/src/wallet/IndyWallet.test.ts index a59cd82f60..c2ab276035 100644 --- a/packages/core/src/wallet/IndyWallet.test.ts +++ b/packages/core/src/wallet/IndyWallet.test.ts @@ -6,6 +6,7 @@ import { SIGNATURE_LENGTH as ED25519_SIGNATURE_LENGTH } from '@stablelib/ed25519 import { agentDependencies } from '../../tests/helpers' import testLogger from '../../tests/logger' import { KeyType } from '../crypto' +import { Bls12381g2SigningProvider, SigningProviderRegistry } from '../crypto/signing-provider' import { KeyDerivationMethod } from '../types' import { TypedArrayEncoder } from '../utils' @@ -26,7 +27,11 @@ describe('IndyWallet', () => { const message = TypedArrayEncoder.fromString('sample-message') beforeEach(async () => { - indyWallet = new IndyWallet(agentDependencies, testLogger) + indyWallet = new IndyWallet( + agentDependencies, + testLogger, + new SigningProviderRegistry([new Bls12381g2SigningProvider()]) + ) await indyWallet.createAndOpen(walletConfig) }) @@ -79,13 +84,6 @@ describe('IndyWallet', () => { }) }) - test('Create blsg12381g1 keypair', async () => { - await expect(indyWallet.createKey({ seed, keyType: KeyType.Bls12381g1 })).resolves.toMatchObject({ - publicKeyBase58: '6RhvX1RK5rA9uXdTtV6WvHWNQqcCW86BQxz1aBPr6ebBcppCYMD3LLy7QLg4cGcWaq', - keyType: KeyType.Bls12381g1, - }) - }) - test('Create bls12381g2 keypair', async () => { await expect(indyWallet.createKey({ seed, keyType: KeyType.Bls12381g2 })).resolves.toMatchObject({ publicKeyBase58: @@ -120,16 +118,6 @@ describe('IndyWallet', () => { expect(signature.length).toStrictEqual(BBS_SIGNATURE_LENGTH) }) - test('Fail to create a signature with a bls12381g1 keypair', async () => { - const bls12381g1Key = await indyWallet.createKey({ seed, keyType: KeyType.Bls12381g1 }) - await expect( - indyWallet.sign({ - data: message, - key: bls12381g1Key, - }) - ).rejects.toThrowError(WalletError) - }) - test('Verify a signed message with a ed25519 publicKey', async () => { const ed25519Key = await indyWallet.createKey({ keyType: KeyType.Ed25519 }) const signature = await indyWallet.sign({ diff --git a/packages/core/src/wallet/IndyWallet.ts b/packages/core/src/wallet/IndyWallet.ts index 493cfd4707..0e1462cb3e 100644 --- a/packages/core/src/wallet/IndyWallet.ts +++ b/packages/core/src/wallet/IndyWallet.ts @@ -1,4 +1,4 @@ -import type { BlsKeyPair } from '../crypto/BbsService' +import type { KeyPair } from '../crypto/signing-provider/SigningProvider' import type { EncryptedMessage, KeyDerivationMethod, @@ -20,9 +20,9 @@ import type { default as Indy, WalletStorageConfig } from 'indy-sdk' import { AgentDependencies } from '../agent/AgentDependencies' import { InjectionSymbols } from '../constants' -import { BbsService } from '../crypto/BbsService' import { Key } from '../crypto/Key' import { KeyType } from '../crypto/KeyType' +import { SigningProviderRegistry } from '../crypto/signing-provider/SigningProviderRegistry' import { AriesFrameworkError, IndySdkError, RecordDuplicateError, RecordNotFoundError } from '../error' import { Logger } from '../logger' import { inject, injectable } from '../plugins' @@ -39,14 +39,17 @@ export class IndyWallet implements Wallet { private walletHandle?: number private logger: Logger + private signingKeyProviderRegistry: SigningProviderRegistry private publicDidInfo: DidInfo | undefined private indy: typeof Indy public constructor( @inject(InjectionSymbols.AgentDependencies) agentDependencies: AgentDependencies, - @inject(InjectionSymbols.Logger) logger: Logger + @inject(InjectionSymbols.Logger) logger: Logger, + signingKeyProviderRegistry: SigningProviderRegistry ) { this.logger = logger + this.signingKeyProviderRegistry = signingKeyProviderRegistry this.indy = agentDependencies.indy } @@ -467,6 +470,7 @@ export class IndyWallet implements Wallet { */ public async createKey({ seed, keyType }: CreateKeyOptions): Promise { try { + // Ed25519 is supported natively in Indy wallet if (keyType === KeyType.Ed25519) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore @@ -474,10 +478,13 @@ export class IndyWallet implements Wallet { return Key.fromPublicKeyBase58(verkey, keyType) } - if (keyType === KeyType.Bls12381g1 || keyType === KeyType.Bls12381g2) { - const blsKeyPair = await BbsService.createKey({ keyType, seed }) - await this.storeKeyPair(blsKeyPair) - return Key.fromPublicKeyBase58(blsKeyPair.publicKeyBase58, keyType) + // Check if there is a signing key provider for the specified key type. + if (this.signingKeyProviderRegistry.hasProviderForKeyType(keyType)) { + const signingKeyProvider = this.signingKeyProviderRegistry.getProviderForKeyType(keyType) + + const keyPair = await signingKeyProvider.createKeyPair({ seed }) + await this.storeKeyPair(keyPair) + return Key.fromPublicKeyBase58(keyPair.publicKeyBase58, keyType) } } catch (error) { if (!isError(error)) { @@ -501,6 +508,7 @@ export class IndyWallet implements Wallet { */ public async sign({ data, key }: SignOptions): Promise { try { + // Ed25519 is supported natively in Indy wallet if (key.keyType === KeyType.Ed25519) { // Checks to see if it is an not an Array of messages, but just a single one if (!TypedArrayEncoder.isTypedArray(data)) { @@ -509,13 +517,18 @@ export class IndyWallet implements Wallet { return await this.indy.cryptoSign(this.handle, key.publicKeyBase58, data as Buffer) } - if (key.keyType === KeyType.Bls12381g2) { - const blsKeyPair = await this.retrieveKeyPair(key.publicKeyBase58) - return BbsService.sign({ - messages: data, - publicKey: key.publicKey, - privateKey: TypedArrayEncoder.fromBase58(blsKeyPair.privateKeyBase58), + // Check if there is a signing key provider for the specified key type. + if (this.signingKeyProviderRegistry.hasProviderForKeyType(key.keyType)) { + const signingKeyProvider = this.signingKeyProviderRegistry.getProviderForKeyType(key.keyType) + + const keyPair = await this.retrieveKeyPair(key.publicKeyBase58) + const signed = await signingKeyProvider.sign({ + data, + privateKeyBase58: keyPair.privateKeyBase58, + publicKeyBase58: key.publicKeyBase58, }) + + return signed } } catch (error) { if (!isError(error)) { @@ -542,6 +555,7 @@ export class IndyWallet implements Wallet { */ public async verify({ data, key, signature }: VerifyOptions): Promise { try { + // Ed25519 is supported natively in Indy wallet if (key.keyType === KeyType.Ed25519) { // Checks to see if it is an not an Array of messages, but just a single one if (!TypedArrayEncoder.isTypedArray(data)) { @@ -550,8 +564,17 @@ export class IndyWallet implements Wallet { return await this.indy.cryptoVerify(key.publicKeyBase58, data as Buffer, signature) } - if (key.keyType === KeyType.Bls12381g2) { - return await BbsService.verify({ signature, publicKey: key.publicKey, messages: data }) + // Check if there is a signing key provider for the specified key type. + if (this.signingKeyProviderRegistry.hasProviderForKeyType(key.keyType)) { + const signingKeyProvider = this.signingKeyProviderRegistry.getProviderForKeyType(key.keyType) + + const signed = await signingKeyProvider.verify({ + data, + signature, + publicKeyBase58: key.publicKeyBase58, + }) + + return signed } } catch (error) { if (!isError(error)) { @@ -609,11 +632,11 @@ export class IndyWallet implements Wallet { } } - private async retrieveKeyPair(publicKeyBase58: string): Promise { + private async retrieveKeyPair(publicKeyBase58: string): Promise { try { - const { value } = await this.indy.getWalletRecord(this.handle, 'KeyPairRecord', `keypair-${publicKeyBase58}`, {}) + const { value } = await this.indy.getWalletRecord(this.handle, 'KeyPairRecord', `key-${publicKeyBase58}`, {}) if (value) { - return JsonEncoder.fromString(value) as BlsKeyPair + return JsonEncoder.fromString(value) as KeyPair } else { throw new WalletError(`No content found for record with public key: ${publicKeyBase58}`) } @@ -628,14 +651,16 @@ export class IndyWallet implements Wallet { } } - private async storeKeyPair(blsKeyPair: BlsKeyPair): Promise { + private async storeKeyPair(keyPair: KeyPair): Promise { try { await this.indy.addWalletRecord( this.handle, 'KeyPairRecord', - `keypair-${blsKeyPair.publicKeyBase58}`, - JSON.stringify(blsKeyPair), - {} + `key-${keyPair.publicKeyBase58}`, + JSON.stringify(keyPair), + { + keyType: keyPair.keyType, + } ) } catch (error) { if (isIndyError(error, 'WalletItemAlreadyExists')) { diff --git a/packages/core/src/wallet/WalletModule.ts b/packages/core/src/wallet/WalletModule.ts index 7d4bd0f739..2c318a23c8 100644 --- a/packages/core/src/wallet/WalletModule.ts +++ b/packages/core/src/wallet/WalletModule.ts @@ -4,6 +4,7 @@ import type { Wallet } from './Wallet' import { AgentContext } from '../agent' import { InjectionSymbols } from '../constants' +import { Bls12381g2SigningProvider, SigningProviderToken } from '../crypto/signing-provider' import { Logger } from '../logger' import { inject, injectable, module } from '../plugins' import { StorageUpdateService } from '../storage' @@ -114,5 +115,8 @@ export class WalletModule { public static register(dependencyManager: DependencyManager) { // Api dependencyManager.registerContextScoped(WalletModule) + + // Signing providers. + dependencyManager.registerSingleton(SigningProviderToken, Bls12381g2SigningProvider) } }