Skip to content

feat(sdk-core): getMpcV2RetrofitDataFromMpcV1Keys for EdDSA - #9461

Draft
bitgo-ai-agent-dev[bot] wants to merge 2 commits into
masterfrom
WCI-1263-getMpcV2RetrofitDataFromMpcV1Key-EdDSA
Draft

feat(sdk-core): getMpcV2RetrofitDataFromMpcV1Keys for EdDSA#9461
bitgo-ai-agent-dev[bot] wants to merge 2 commits into
masterfrom
WCI-1263-getMpcV2RetrofitDataFromMpcV1Key-EdDSA

Conversation

@bitgo-ai-agent-dev

Copy link
Copy Markdown
Contributor

What

  • Add EddsaRetrofitData type (s_i_0, expectedPk, chainCode) exported from @bitgo/sdk-core
  • Add public instance method getMpcV2RetrofitDataFromMpcV1Keys on EddsaMPCv2Utils — takes both user and backup MPCv1 key share strings, returns a pair of EddsaRetrofitData objects
  • Add private static helper getMpcV2RetrofitDataFromMpcV1Key — parses a single MPCv1 JSON key share, derives the Ed25519 scalar via RFC 8032 SHA-512 key expansion + clamping, and returns the retrofit data struct
  • Input validation: seed must be exactly 64 hex chars (32 bytes), chaincode must be exactly 64 hex chars, pShare.y must be a non-empty string
  • Zeroize sensitive Buffers (seed bytes, full SHA-512 digest, clamped scalar) in a try/finally block after the hex string is captured

Why

Required by WCI-1264 (getUserAndBackupSession + createKeychains retrofit wiring). The retrofit DKG ceremony (ed25519_dkg_round0_import) needs EddsaRetrofitData seeded from the user's existing MPCv1 keys before the ceremony begins. MPCv1 stores a 32-byte seed rather than the scalar directly; this method performs the RFC 8032 key expansion so both user and backup parties can seed their DKG sessions from their existing KeyCard material, enabling in-place migration from MPCv1 to MPCv2 without re-keying.

Test plan

  • 11 unit tests cover: matching expectedPk, correct chainCode per party, clamped scalar value, bit-level clamping verification, missing pShare.y, empty pShare.y, missing/short uShare.seed, missing uShare.chaincode on user and backup

Ticket: WCI-1263

Add `getMpcV2RetrofitDataFromMpcV1Keys` (public instance method) and
a private static helper `getMpcV2RetrofitDataFromMpcV1Key` on
`EddsaMPCv2Utils`. Also introduce the `EddsaRetrofitData` type and
export it from the package root.

The methods convert MPCv1 EdDSA key shares (JSON with uShare.seed
and uShare.chaincode) into `EddsaRetrofitData` objects that can be
passed to `new EddsaMPSDkg.DKG(…, retrofitData)` to seed a retrofit
DKG ceremony.

Scalar derivation follows RFC 8032 Ed25519 key expansion:
  scalar = clamp(SHA512(seed_bytes)[0:32])
where clamping clears bits 0-2 of byte[0], clears bit 7 of byte[31],
and sets bit 6 of byte[31].

The aggregate public key (expectedPk) is read from the user key's
pShare.y and reused for both parties, since both parties share the
same root public key in the MPCv1 scheme.

Required by WCI-1264 (getUserAndBackupSession + createKeychains
retrofit wiring) to derive the retrofit data before starting the DKG
ceremony.

Ticket: WCI-1263
Session-Id: 9430179b-3b09-4c4c-9c75-723c484f16b5
Task-Id: 29bdbf4d-6e4f-4646-bd79-06a89e5dcf28
… material

Address critical and warning findings from post-commit review:

- Seed length guard: assert seed is exactly 64 hex chars (32 bytes)
  before Buffer.from to prevent silent scalar corruption from empty or
  truncated seeds
- Chaincode length guard: assert chaincode is exactly 64 hex chars so
  corrupt or empty chaincodes are rejected early rather than returned
  as garbage retrofit data
- pShare.y non-empty guard: strengthen typeof check to also require
  length > 0, rejecting empty-string public keys that would silently
  propagate a wrong expectedPk
- Zeroize sensitive Buffers: wrap scalar derivation in try/finally to
  zero seedBytes, the full SHA-512 hash digest, and the clamped scalar
  Buffer after the hex string is captured
- Add tests for all new validation branches: short seed, missing
  chaincode on user/backup, empty pShare.y

Ticket: WCI-1263
Session-Id: 9430179b-3b09-4c4c-9c75-723c484f16b5
Task-Id: 29bdbf4d-6e4f-4646-bd79-06a89e5dcf28
@linear-code

linear-code Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

WCI-1263

@ralph-bitgo
ralph-bitgo Bot force-pushed the WCI-1263-getMpcV2RetrofitDataFromMpcV1Key-EdDSA branch from decc117 to 38ea35e Compare August 10, 2026 16:18
@bitgo-ai-agent-dev
bitgo-ai-agent-dev Bot force-pushed the WCI-1263-getMpcV2RetrofitDataFromMpcV1Key-EdDSA branch from 38ea35e to 4dfa8d0 Compare August 10, 2026 16:18
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.

1 participant