From 6266f54d359201ba215685ac403da77c2a5533ae Mon Sep 17 00:00:00 2001 From: Marzooqa Kather Date: Tue, 30 Jun 2026 17:24:18 +0000 Subject: [PATCH] chore(sdk-lib-mpc): bump @bitgo/wasm-mps to 1.10.0 Upgrade @bitgo/wasm-mps from 1.8.1 to 1.10.0 in sdk-lib-mpc. Version 1.10.0 changes the key derivation algorithm used internally by ed25519_dsg_round0_process from the Silence Labs custom BIP32 formula to the standard Cardano BIP32-Ed25519 formula (the same one used by Eddsa.deriveUnhardened). This enables consistent use of deriveUnhardened across both the TSS protocol and address derivation, and supports the backwards-compatible BIP32 derivation in MPS sign required by HSM-384. Update the DSG cross-check tests in derive.ts to verify signatures against the BIP32-derived public key (via Ed25519Bip32HdTree) rather than the old Silence Labs formula in deriveUnhardenedMps, which no longer matches the WASM derivation after this bump. Ticket: WCI-880 Session-Id: bd2446e4-30fa-4159-b66d-6f3c9027f98f Task-Id: d9d634c8-6aea-446a-8c3b-c33dc8672961 --- modules/sdk-lib-mpc/package.json | 2 +- .../sdk-lib-mpc/test/unit/tss/eddsa/derive.ts | 32 +++++++++++++++---- yarn.lock | 8 ++--- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/modules/sdk-lib-mpc/package.json b/modules/sdk-lib-mpc/package.json index 4029b9a751..bd2b744f6d 100644 --- a/modules/sdk-lib-mpc/package.json +++ b/modules/sdk-lib-mpc/package.json @@ -36,7 +36,7 @@ ] }, "dependencies": { - "@bitgo/wasm-mps": "1.8.1", + "@bitgo/wasm-mps": "1.10.0", "@noble/curves": "1.8.1", "@silencelaboratories/dkls-wasm-ll-node": "1.2.0-pre.4", "@silencelaboratories/dkls-wasm-ll-web": "1.2.0-pre.4", diff --git a/modules/sdk-lib-mpc/test/unit/tss/eddsa/derive.ts b/modules/sdk-lib-mpc/test/unit/tss/eddsa/derive.ts index c948ddb5d3..08218ad971 100644 --- a/modules/sdk-lib-mpc/test/unit/tss/eddsa/derive.ts +++ b/modules/sdk-lib-mpc/test/unit/tss/eddsa/derive.ts @@ -1,9 +1,27 @@ import assert from 'assert'; import { ed25519 } from '@noble/curves/ed25519'; +import { Ed25519Bip32HdTree } from '../../../../src/curves/ed25519Bip32HdTree'; +import { bigIntFromBufferBE, bigIntFromBufferLE, bigIntToBufferBE, bigIntToBufferLE } from '../../../../src/util'; import { EddsaMPSDsg, MPSUtil } from '../../../../src/tss/eddsa-mps'; import { deriveUnhardenedMps } from '../../../../src/tss/eddsa-mps/derive'; import { generateEdDsaDKGKeyShares } from './util'; +/** + * Derives a child public key from a common keychain using the Cardano BIP32-Ed25519 + * formula (same as Eddsa.deriveUnhardened). Returns the 128-char hex common keychain + * (64-char pk + 64-char chaincode) that wasm-mps 1.10.0 now uses for key derivation. + */ +function deriveUnhardenedBip32(commonKeychainHex: string, path: string): string { + const buf = Buffer.from(commonKeychainHex, 'hex'); + const keychain = { + pk: bigIntFromBufferLE(buf.subarray(0, 32)), + chaincode: bigIntFromBufferBE(buf.subarray(32, 64)), + }; + const hdTree = new Ed25519Bip32HdTree(); + const derived = hdTree.publicDerive(keychain, path); + return bigIntToBufferLE(derived.pk, 32).toString('hex') + bigIntToBufferBE(derived.chaincode, 32).toString('hex'); +} + const MESSAGE = Buffer.from('The Times 03/Jan/2009 Chancellor on brink of second bailout for banks'); describe('deriveUnhardenedMps', function () { @@ -63,7 +81,7 @@ describe('deriveUnhardenedMps', function () { }); }); - describe('DSG signature cross-check against the public key derived by deriveUnhardenedMps', function () { + describe('DSG signature cross-check against the public key derived by BIP32 (deriveUnhardenedBip32)', function () { let sigAtRoot: Buffer; let sigAtM0: Buffer; let sigAtM01: Buffer; @@ -86,19 +104,19 @@ describe('deriveUnhardenedMps', function () { assert(ed25519.verify(sigAtRoot, MESSAGE, rootPubKey), 'DSG at "m" should verify against the raw DKG public key'); }); - it('signature from DSG at "m/0" verifies against deriveUnhardenedMps(commonKeychain, "m/0")', function () { - const derivedPk = Buffer.from(deriveUnhardenedMps(commonKeychain, 'm/0').slice(0, 64), 'hex'); + it('signature from DSG at "m/0" verifies against deriveUnhardenedBip32(commonKeychain, "m/0")', function () { + const derivedPk = Buffer.from(deriveUnhardenedBip32(commonKeychain, 'm/0').slice(0, 64), 'hex'); assert( ed25519.verify(sigAtM0, MESSAGE, derivedPk), - 'DSG at "m/0" should verify against deriveUnhardenedMps result at "m/0"' + 'DSG at "m/0" should verify against BIP32-derived public key at "m/0"' ); }); - it('signature from DSG at "m/0/1" verifies against deriveUnhardenedMps(commonKeychain, "m/0/1")', function () { - const derivedPk = Buffer.from(deriveUnhardenedMps(commonKeychain, 'm/0/1').slice(0, 64), 'hex'); + it('signature from DSG at "m/0/1" verifies against deriveUnhardenedBip32(commonKeychain, "m/0/1")', function () { + const derivedPk = Buffer.from(deriveUnhardenedBip32(commonKeychain, 'm/0/1').slice(0, 64), 'hex'); assert( ed25519.verify(sigAtM01, MESSAGE, derivedPk), - 'DSG at "m/0/1" should verify against deriveUnhardenedMps result at "m/0/1"' + 'DSG at "m/0/1" should verify against BIP32-derived public key at "m/0/1"' ); }); }); diff --git a/yarn.lock b/yarn.lock index 4c021ec4d1..cbfc4a7046 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1013,10 +1013,10 @@ resolved "https://registry.npmjs.org/@bitgo/wasm-dot/-/wasm-dot-1.7.0.tgz" integrity sha512-KoXavJvyDHlEN+sWcigbgxYJtdFaU7gS0EkYQbNH4npVjNlzo6rL6gwjyWbyOy7oEs65DhpJ9vY5kRbE/bKiTQ== -"@bitgo/wasm-mps@1.8.1": - version "1.8.1" - resolved "https://registry.npmjs.org/@bitgo/wasm-mps/-/wasm-mps-1.8.1.tgz#946673f5845696cdcf744f8122fd1fc2be3edce1" - integrity sha512-CV8EXYc1BGYtXdCRDxJ5h04nj/LpMgu3VlkfowlodI6UKcj1zotAvk4OMIdgiPPbKVr1l+xibHDXZYx/uf3rnw== +"@bitgo/wasm-mps@1.10.0": + version "1.10.0" + resolved "https://registry.npmjs.org/@bitgo/wasm-mps/-/wasm-mps-1.10.0.tgz#df6a056247ce04c7d92369d257b659876e03261d" + integrity sha512-f42sMCyqqlaId3AtcvdpOfR+mOjAyVopCxCCAqW7wcTAQ8ZBS9rMGQIzTMiqFmZDBMWsAe+QHWA6XseIuzTVdQ== "@bitgo/wasm-solana@^2.6.0": version "2.6.0"