Skip to content

feat(sdk-core): Add support for preHashed flr atomic txn in EcdsaMPCv…#8814

Merged
mohd-kashif merged 1 commit into
masterfrom
CECHO-1138
May 20, 2026
Merged

feat(sdk-core): Add support for preHashed flr atomic txn in EcdsaMPCv…#8814
mohd-kashif merged 1 commit into
masterfrom
CECHO-1138

Conversation

@mohd-kashif
Copy link
Copy Markdown
Contributor

@mohd-kashif mohd-kashif commented May 20, 2026

Summary

  • Fix DKLS MPCv2 signing for FLR Avalanche atomic cross-chain transactions (C-chain ↔ P-chain export/import)
  • The SDK user-party was applying keccak256 to signableHex for all transactions, but Avalanche atomic txs have signableHex = SHA-256(txBody) — already a final signing hash. The WP/HSM BitGo-party uses this
    SHA-256 directly (isPreHashed=true), so the two DKLS parties disagreed on the message hash, causing "Failed to combine signature shares"
  • Detect Avalanche atomic transactions by their codec type ID prefix (0x0000 vs EVM RLP 0xf8xx) and skip keccak256, using signableHex as the DKLS message hash directly

Problem

FLR cross-chain atomic exports (C→P) use Avalanche's codec format, not EVM RLP. The signableHex returned by buildTransactionWithIntent is SHA-256(txBody) — a 32-byte pre-hashed digest ready for ECDSA
signing.

EcdsaMPCv2Utils.getHashStringAndDerivationPath() unconditionally applied keccak256 to signableHex, producing:

  • SDK (user party): keccak256(SHA-256(txBody)) — wrong
  • WP/HSM (BitGo party): SHA-256(txBody) — correct (via MPCv2Signer.isPreHashed)

The two DKLS parties initialized their DSG sessions with different message hashes, making it impossible to combine partial signatures into a valid ECDSA signature.

Fix

In getHashStringAndDerivationPath(), extract serializedTxHex from the txRequest and check if it starts with 0000 (Avalanche codec type ID). If so, return Buffer.from(signableHex, 'hex') directly as
hashBuffer, bypassing keccak256. This matches the WP/HSM behavior so both DKLS parties agree on the same 32-byte message hash.

There is no collision risk: Avalanche codec type ID 0x0000 cannot appear as a valid EVM RLP prefix (RLP-encoded transactions start with 0xf8xx or higher).

Changes

modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts

  • Extract serializedTxHex from txRequest.transactions[0].unsignedTx
  • Add early return when serializedTxHex.startsWith('0000') to use signableHex as raw DKLS hash

modules/sdk-core/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts

  • Test 1: Full 3-round DKLS signing with a real Avalanche ExportInC transaction (codec 0x0000 prefix). BitGo party uses raw SHA-256 hash (matching WP isPreHashed=true). Verifies with shouldHash=false.
    Asserts recid:R:S:pubkey format, 32-byte R/S components, and valid recovery ID.
  • Test 2: Regression test — regular EVM transaction (0xf86c RLP prefix) still applies keccak256. BitGo party uses keccak256(signableHex). Ensures standard EVM signing is unaffected.

Test plan

  • New test: Avalanche atomic export tx signs correctly with pre-hashed SHA-256 (no keccak256)
  • New test: Regular EVM tx still applies keccak256 (regression guard)
  • Existing DKLS MPCv2 signing tests pass (CI)
  • E2E: FLR C→P export with MPCv2 wallet on testnet (sandbox c2pMpcToMpcTss.ts)

Ticket: CECHO-1138

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 20, 2026

CECHO-1138

@mohd-kashif mohd-kashif self-assigned this May 20, 2026
@mohd-kashif mohd-kashif marked this pull request as ready for review May 20, 2026 08:35
@mohd-kashif mohd-kashif requested review from a team as code owners May 20, 2026 08:35
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support in sdk-core ECDSA MPCv2 DKLS signing to correctly handle FLR Avalanche atomic (C-chain ↔ P-chain) transactions where signableHex is already a final 32-byte SHA-256 digest, preventing the SDK from incorrectly applying keccak256 and causing signature-share combination failures.

Changes:

  • Detect Avalanche atomic transactions via serializedTxHex codec prefix (0000) and treat signableHex as a pre-hashed digest (skip coin hash function).
  • Add an end-to-end DKLS offline signing unit test for a real Avalanche atomic export transaction using shouldHash=false.
  • Add a regression unit test intended to ensure regular FLR EVM transactions still use keccak256.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts Adds Avalanche-atomic detection and bypasses keccak256 by using signableHex directly as the DKLS message hash.
modules/sdk-core/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts Adds a full DKLS signing test for pre-hashed Avalanche atomic txs and a regression test for the EVM keccak path.
Comments suppressed due to low confidence (1)

modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts:1036

  • The comment says “standard EVM RLP starts with 0xf8xx”, but EVM transactions can also be EIP-2718 typed txs whose serialized form starts with a type byte (e.g. 01, 02, 03) followed by RLP. Consider updating the comment to avoid misleading readers; the non-collision argument can still hold, but should account for typed tx prefixes as well.
    // This matches the WP/HSM BitGo-party behaviour (MPCv2Signer.isPreHashed)
    // so both DKLS parties agree on the same message hash.
    // Detection: Avalanche codec type ID prefix is 0x0000; standard EVM RLP
    // starts with 0xf8xx, so there is no collision.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts Outdated
Comment thread modules/sdk-core/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts Outdated

This comment was marked as low quality.

@mohd-kashif mohd-kashif merged commit 2ef142d into master May 20, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants