From 3805b29b7767145b55f5a50556f27dfcd5516f43 Mon Sep 17 00:00:00 2001 From: Aali Charania Date: Mon, 6 Apr 2026 21:40:53 +0000 Subject: [PATCH] docs(sdk-lib-mpc): document that reducedEncryptedPrv contains private key material Add JSDoc/inline comments to ReducedKeyShareType, getReducedKeyShare(), reducedEncryptedPrv field, and the encryption block in ecdsaMPCv2.ts clarifying that prv is the party's private scalar s_i and that the resulting reducedEncryptedPrv on the key card QR code is a second copy of private key material. Ticket: WP-8474 --- modules/sdk-core/src/bitgo/keychain/iKeychains.ts | 4 +++- .../sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts | 4 ++++ modules/sdk-lib-mpc/src/tss/ecdsa-dkls/dkg.ts | 5 +++++ modules/sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts | 10 ++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/modules/sdk-core/src/bitgo/keychain/iKeychains.ts b/modules/sdk-core/src/bitgo/keychain/iKeychains.ts index 0242b7361a..eb978dbfba 100644 --- a/modules/sdk-core/src/bitgo/keychain/iKeychains.ts +++ b/modules/sdk-core/src/bitgo/keychain/iKeychains.ts @@ -32,7 +32,9 @@ export interface Keychain { provider?: string; encryptedPrv?: string; // Required for MPCV2 keys where we reduce the amount of data needed for the keycard. - // This is only generated client side and is not sent to WP + // Contains the party's private scalar (s_i) as private key material, CBOR-encoded + // and encrypted with the wallet passphrase. This is only generated client side and + // is not sent to WP. reducedEncryptedPrv?: string; derivationPath?: string; derivedFromParentWithSeed?: string; diff --git a/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts b/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts index 49980335e3..be1dff5b51 100644 --- a/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts +++ b/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts @@ -365,6 +365,10 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils { input: privateMaterial.toString('base64'), password: passphrase, }); + // Encrypts the CBOR-encoded ReducedKeyShare (which contains the party's private + // scalar s_i) with the wallet passphrase. The result is stored as reducedEncryptedPrv + // on the key card QR code and represents a second copy of private key material + // beyond the server-stored encryptedPrv. reducedEncryptedPrv = this.bitgo.encrypt({ // Buffer.toString('base64') can not be used here as it does not work on the browser. // The browser deals with a Buffer as Uint8Array, therefore in the browser .toString('base64') just creates a comma seperated string of the array values. diff --git a/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/dkg.ts b/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/dkg.ts index a3a07c39b5..11ee916648 100644 --- a/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/dkg.ts +++ b/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/dkg.ts @@ -184,6 +184,11 @@ export class Dkg { return this.keyShareBuff; } + /** + * Returns a CBOR-encoded ReducedKeyShare buffer containing the party's private + * scalar (s_i) in the `prv` field. This buffer is private key material. + * The caller encrypts it and stores it as `reducedEncryptedPrv` on the key card QR code. + */ getReducedKeyShare(): Buffer { if (!this.keyShareBuff) { throw Error('Can not get key share, DKG is not complete yet.'); 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 672e1531c0..f142ffe8ca 100644 --- a/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts +++ b/modules/sdk-lib-mpc/src/tss/ecdsa-dkls/types.ts @@ -60,6 +60,16 @@ export type RetrofitData = { xiList?: number[][]; }; +/** + * A CBOR-encoded subset of an MPCv2 (DKLS) key share stored on the key card. + * + * @property bigSList - Public commitments S_i = s_i * G for each party. + * @property xList - Evaluation points (x-coordinates for Lagrange interpolation). + * @property rootChainCode - Root chain code for HD derivation. + * @property prv - The party's private scalar s_i. This is private key material; + * possession of this value allows the holder to act as this party in signing. + * @property pub - The party's public key. + */ export const ReducedKeyShareType = t.type({ bigSList: t.array(t.array(t.number)), xList: t.array(t.array(t.number)),