Skip to content

feat(sdk-core): add externalSigner createOfflineRound2Share handler#8834

Merged
vibhavgo merged 1 commit into
masterfrom
WCI-477
May 26, 2026
Merged

feat(sdk-core): add externalSigner createOfflineRound2Share handler#8834
vibhavgo merged 1 commit into
masterfrom
WCI-477

Conversation

@vibhavgo
Copy link
Copy Markdown
Contributor

Add the EdDSA MPCv2 offline round-2 handler for external signer flows. It restores the encrypted round-1 DSG session and produces the round-2 share plus encrypted carry-over state for round 3.

  • Restore user DSG session from encrypted round-1 state and verify BitGo round-1 output from txRequest signature shares.
  • Run WASM round 1 and build the round-2 signature share with user GPG.
  • Encrypt round-2 session state with MPS_DSG_SIGNING_ROUND2_STATE adata.
  • Support SJCL and v2 envelope decryption paths for round-1 session input.
  • Add unit tests with signBitgoEddsaRound1 helper, happy path, and guards.

Ticket: WCI-477

@vibhavgo vibhavgo requested review from a team as code owners May 22, 2026 10:29
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 22, 2026

WCI-477

@Marzooqa Marzooqa self-requested a review May 25, 2026 08:06
Marzooqa
Marzooqa previously approved these changes May 25, 2026
Copy link
Copy Markdown
Contributor

@Marzooqa Marzooqa left a comment

Choose a reason for hiding this comment

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

Implementation is correct and consistent with the ECDSA pattern — correct use of verifyPeerMessageRoundOne, handleIncomingMessages, ed25519 GPG, and userMsgPayload carry-over in sessionPayload. Three minor nits inline; none blocking.

Comment thread modules/sdk-core/src/bitgo/utils/tss/eddsa/eddsaMPCv2.ts
Comment thread modules/sdk-core/src/bitgo/utils/tss/eddsa/eddsaMPCv2.ts
Comment thread modules/sdk-core/src/bitgo/utils/tss/eddsa/eddsaMPCv2.ts
Base automatically changed from WCI-378 to master May 25, 2026 08:35
@vibhavgo vibhavgo dismissed Marzooqa’s stale review May 25, 2026 08:35

The base branch was changed.

@vibhavgo vibhavgo force-pushed the WCI-477 branch 2 times, most recently from da5cd64 to c072f46 Compare May 25, 2026 09:23
Add the EdDSA MPCv2 offline round-1 handler for external signer flows.
It stores encrypted carry-over state for the next signing round.

- Generate the round-1 EdDSA MPCv2 signature share from a fresh DSG session.
- Persist DSG session state and user message payload in the round-1 session.
- Encrypt session and ephemeral GPG private key data with signing-context adata.
- Cover SJCL encryption, v2 envelopes, payload shape, and transaction guards.

Ticket: WCI-378
Copy link
Copy Markdown
Contributor

@Marzooqa Marzooqa left a comment

Choose a reason for hiding this comment

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

Implementation is correct — session restore, userMsgPayload carry-over, handleIncomingMessages round-2 output, and re-encryption with ROUND2_STATE adata all look good. Previous nits addressed. One minor dead code note: the assert(Array.isArray(transactions) && transactions.length === 1, ...) after getSignableHexAndDerivationPath is unreachable since that method already makes the same check — safe to remove in a follow-up.

Copy link
Copy Markdown
Contributor

@Marzooqa Marzooqa left a comment

Choose a reason for hiding this comment

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

Implementation is correct — session restore, userMsgPayload carry-over, handleIncomingMessages round-2 output, and re-encryption with ROUND2_STATE adata all look good. Previous nits addressed. One minor dead code note: the assert(Array.isArray(transactions) && transactions.length === 1, ...) after getSignableHexAndDerivationPath is unreachable since that method already makes the same check — safe to remove in a follow-up.

@vibhavgo
Copy link
Copy Markdown
Contributor Author

Implementation is correct — session restore, userMsgPayload carry-over, handleIncomingMessages round-2 output, and re-encryption with ROUND2_STATE adata all look good. Previous nits addressed. One minor dead code note: the assert(Array.isArray(transactions) && transactions.length === 1, ...) after getSignableHexAndDerivationPath is unreachable since that method already makes the same check — safe to remove in a follow-up.

From TypeScript narrowing perspective, the local assert is still useful, because TS does not understand that a previous helper call proved txRequest.transactions is defined.
src/bitgo/utils/tss/eddsa/eddsaMPCv2.ts:635:29 - error TS18048: 'transactions' is possibly 'undefined'.

635 const signatureShares = transactions[0].signatureShares;

@vibhavgo vibhavgo merged commit f7c3244 into master May 26, 2026
22 checks passed
@vibhavgo vibhavgo deleted the WCI-477 branch May 26, 2026 09:22
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