From 3a198d453c46bc9a7217c34111fae85add6f13a1 Mon Sep 17 00:00:00 2001 From: Alejandro Busse Date: Fri, 12 Apr 2024 11:53:51 -0300 Subject: [PATCH] feat(sdk-lib-mpc): add dkls utils added a few dkls related utils, to deserialized single messages and get the commonkeyChain from the keyShare WP-0000 TICKET: WP-0000 --- .../sdk-lib-mpc/src/tss/ecdsa-dkls/index.ts | 1 + .../sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts | 99 +++++++++++++------ .../test/unit/tss/ecdsa/dklsDkg.ts | 22 ++++- 3 files changed, 89 insertions(+), 33 deletions(-) diff --git a/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/index.ts b/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/index.ts index c2aba66c67..8fc767a23d 100644 --- a/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/index.ts +++ b/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/index.ts @@ -1,3 +1,4 @@ export * as DklsDkg from './dkg'; export * as DklsDsg from './dsg'; export * as DklsTypes from './types'; +export * as DklsComms from './commsLayer'; diff --git a/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts b/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts index 88d23dccd8..3b5e3cd011 100644 --- a/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts +++ b/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts @@ -1,3 +1,6 @@ +import assert from 'assert'; +import { decode } from 'cbor'; + // Broadcast message meant to be sent to multiple parties interface BroadcastMessage { payload: T; @@ -73,42 +76,80 @@ export type DeserializedMessages = { */ export function serializeMessages(messages: DeserializedMessages): SerializedMessages { return { - p2pMessages: messages.p2pMessages.map((m) => { - return { - to: m.to, - from: m.from, - payload: Buffer.from(m.payload).toString('base64'), - commitment: m.commitment ? Buffer.from(m.commitment).toString('base64') : m.commitment, - }; - }), - broadcastMessages: messages.broadcastMessages.map((m) => { - return { - from: m.from, - payload: Buffer.from(m.payload).toString('base64'), - }; - }), + p2pMessages: messages.p2pMessages.map(serializeP2PMessage), + broadcastMessages: messages.broadcastMessages.map(serializeBroadcastMessage), }; } /** - * Desrializes messages payloads to Uint8Array. + * Deserialize messages payloads to Uint8Array. * @param messages */ export function deserializeMessages(messages: SerializedMessages): DeserializedMessages { return { - p2pMessages: messages.p2pMessages.map((m) => { - return { - to: m.to, - from: m.from, - payload: new Uint8Array(Buffer.from(m.payload, 'base64')), - commitment: m.commitment ? new Uint8Array(Buffer.from(m.commitment, 'base64')) : undefined, - }; - }), - broadcastMessages: messages.broadcastMessages.map((m) => { - return { - from: m.from, - payload: new Uint8Array(Buffer.from(m.payload, 'base64')), - }; - }), + p2pMessages: messages.p2pMessages.map(deserializeP2PMessage), + broadcastMessages: messages.broadcastMessages.map(deserializeBroadcastMessage), + }; +} + +/** + * Deserializes a P2P message. + * @param message + */ +export function deserializeP2PMessage(message: SerializedP2PMessage): DeserializedP2PMessage { + return { + to: message.to, + from: message.from, + payload: new Uint8Array(Buffer.from(message.payload, 'base64')), + commitment: message.commitment ? new Uint8Array(Buffer.from(message.commitment, 'base64')) : undefined, }; } + +/** + * Deserializes a Broadcast message. + * @param message + */ +export function deserializeBroadcastMessage(message: SerializedBroadcastMessage): DeserializedBroadcastMessage { + return { + from: message.from, + payload: new Uint8Array(Buffer.from(message.payload, 'base64')), + }; +} + +/** + * Serializes a P2P message. + * @param message + */ +export function serializeP2PMessage(message: DeserializedP2PMessage): SerializedP2PMessage { + return { + to: message.to, + from: message.from, + payload: Buffer.from(message.payload).toString('base64'), + commitment: message.commitment ? Buffer.from(message.commitment).toString('base64') : undefined, + }; +} + +/** + * Serializes a Broadcast message. + * @param message + */ +export function serializeBroadcastMessage(message: DeserializedBroadcastMessage): SerializedBroadcastMessage { + return { + from: message.from, + payload: Buffer.from(message.payload).toString('base64'), + }; +} + +/** + * Gets commonkeyChain from DKLS keyShare + * @param {Buffer} keyShare - DKLS keyShare + * @returns {string} commonKeychain + */ +export function getCommonKeychain(keyShare: Buffer): string { + const parsedKeyShare = decode(keyShare); + assert(parsedKeyShare.public_key, 'public_key not found in keyShare'); + assert(parsedKeyShare.root_chain_code, 'root_chain_code not found in public_key'); + const publicKey = Buffer.from(parsedKeyShare.public_key).toString('hex'); + const rootChainCode = Buffer.from(parsedKeyShare.root_chain_code).toString('hex'); + return publicKey + rootChainCode; +} diff --git a/modules/sdk-lib-mpc/test/unit/tss/ecdsa/dklsDkg.ts b/modules/sdk-lib-mpc/test/unit/tss/ecdsa/dklsDkg.ts index 1ab7946fd9..65814672f6 100644 --- a/modules/sdk-lib-mpc/test/unit/tss/ecdsa/dklsDkg.ts +++ b/modules/sdk-lib-mpc/test/unit/tss/ecdsa/dklsDkg.ts @@ -1,4 +1,5 @@ -import { DklsDkg } from '../../../../src/tss/ecdsa-dkls'; +import assert from 'assert'; +import { DklsDkg, DklsTypes } from '../../../../src/tss/ecdsa-dkls'; import { decryptAndVerifyIncomingMessages, encryptAndAuthOutgoingMessages, @@ -75,9 +76,14 @@ describe('DKLS Dkg 2x3', function () { p2pMessages: [], broadcastMessages: bitgoRound4Messages.broadcastMessages.concat(userRound4Messages.broadcastMessages), }); - const backupKeyShare = decode(backup.getKeyShare()); - decode(user.getKeyShare()).public_key.should.deepEqual(backupKeyShare.public_key); - decode(bitgo.getKeyShare()).public_key.should.deepEqual(backupKeyShare.public_key); + + const userKeyShare = user.getKeyShare(); + const backupKeyShare = backup.getKeyShare(); + const bitgoKeyShare = bitgo.getKeyShare(); + assert.deepEqual(decode(userKeyShare).public_key, decode(bitgoKeyShare).public_key); + assert.deepEqual(decode(backupKeyShare).public_key, decode(bitgoKeyShare).public_key); + assert.deepEqual(DklsTypes.getCommonKeychain(userKeyShare), DklsTypes.getCommonKeychain(bitgoKeyShare)); + assert.deepEqual(DklsTypes.getCommonKeychain(backupKeyShare), DklsTypes.getCommonKeychain(bitgoKeyShare)); }); it(`should create key shares with authenticated encryption`, async function () { @@ -241,5 +247,13 @@ describe('DKLS Dkg 2x3', function () { p2pMessages: [], broadcastMessages: bitgoRound4Messages.broadcastMessages.concat(userRound4Messages.broadcastMessages), }); + + const userKeyShare = user.getKeyShare(); + const backupKeyShare = backup.getKeyShare(); + const bitgoKeyShare = bitgo.getKeyShare(); + assert.deepEqual(decode(userKeyShare).public_key, decode(bitgoKeyShare).public_key); + assert.deepEqual(decode(backupKeyShare).public_key, decode(bitgoKeyShare).public_key); + assert.deepEqual(DklsTypes.getCommonKeychain(userKeyShare), DklsTypes.getCommonKeychain(bitgoKeyShare)); + assert.deepEqual(DklsTypes.getCommonKeychain(backupKeyShare), DklsTypes.getCommonKeychain(bitgoKeyShare)); }); });