Skip to content

feat(sdk-core): add signRecoveryMpcV2 for EdDSA MPCv2 offline signing#9024

Open
vibhavgo wants to merge 1 commit into
masterfrom
WCI-397/sdk-core
Open

feat(sdk-core): add signRecoveryMpcV2 for EdDSA MPCv2 offline signing#9024
vibhavgo wants to merge 1 commit into
masterfrom
WCI-397/sdk-core

Conversation

@vibhavgo

@vibhavgo vibhavgo commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Description

Adds signRecoveryMpcV2 to modules/sdk-core/src/bitgo/utils/tss/eddsa/eddsaMPCv2.ts as a standalone export for EdDSA MPCv2 recovery signing flows. The function drives the MPS DSG protocol locally to completion using user and backup key shares (obtained from getEddsaMPCv2RecoveryKeyShares), then verifies the resulting 64-byte Ed25519 signature against the child public key derived via deriveUnhardenedMps. Mirrors the existing ECDSA signRecoveryMpcV2 pattern.

Issue Number

WCI-397

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Unit tests added in modules/sdk-core/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.ts under describe('signRecoveryMpcV2'):

  • Valid path — runs full 2-party MPS signing with real DKG key shares, asserts the returned Buffer is 64 bytes and verifies with nacl.sign.detached.verify against deriveUnhardenedMps
  • Tampered message — signs one message, verifies against a different message, asserts nacl verification returns false
  • Wrong commonKeyChain — passes a key chain from a different DKG session, asserts the function throws "EdDSA MPCv2 recovery signature verification failed"

Run with:

yarn run unit-test --scope @bitgo/sdk-core -- -- --grep "signRecoveryMpcV2"

@vibhavgo vibhavgo requested review from a team as code owners June 15, 2026 11:39
@linear-code

linear-code Bot commented Jun 15, 2026

Copy link
Copy Markdown

WCI-397

@vibhavgo vibhavgo requested a review from Marzooqa June 15, 2026 11:39
lcovar
lcovar previously approved these changes Jun 15, 2026
@vibhavgo vibhavgo force-pushed the WCI-396/sdk-core branch 2 times, most recently from d225f17 to 95b7c38 Compare June 15, 2026 16:41
@vibhavgo vibhavgo force-pushed the WCI-397/sdk-core branch 4 times, most recently from 7b079de to 7d7406e Compare June 15, 2026 17:28
Base automatically changed from WCI-396/sdk-core to master June 16, 2026 11:39
@vibhavgo vibhavgo dismissed lcovar’s stale review June 16, 2026 11:39

The base branch was changed.

Ticket: WCI-397

Implements local 2-party MPS signing for EdDSA MPCv2 recovery flows, mirroring
the existing ECDSA signRecoveryMpcV2 pattern. The function runs the MPS DSG
protocol to round 3 using user and backup key shares, then verifies the resulting
64-byte Ed25519 signature against the child public key derived via deriveUnhardenedMps.

- export `signRecoveryMpcV2` from eddsaMPCv2.ts
  - drives `MPSUtil.executeTillRound(3, ...)` locally with user + backup DSG instances
  - derives the child public key via `deriveUnhardenedMps(commonKeyChain, derivationPath)`
  - verifies the signature with `nacl.sign.detached.verify`; throws on mismatch
- add unit tests for `signRecoveryMpcV2`
  - valid path: 64-byte signature verifies against derived public key
  - tampered message: signature does not verify against a different message
  - wrong commonKeyChain: throws "EdDSA MPCv2 recovery signature verification failed"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants