Conversation
zahin-mohammad
left a comment
There was a problem hiding this comment.
Built and tested locally — tsc --noEmit is clean in both sdk-lib-mpc and sdk-core, and the new sdk-core EdDSA MPCv2 test suite passes (6/6). Confirmed #8697 is the follow-up that wires EddsaMPCv2Utils.signRequestBase into these helpers.
One semantics concern that I think is worth resolving before merge because it freezes on the public surface — MPSUtil.generateEdDsaDKGKeyShares is barrel-exported, so the seed contract becomes part of the SDK API. The rest are follow-up-safe: helper renames (still internal until #8697 lands deep-import callers), test-util consolidation (pure refactor), and a few test/cleanup nits.
See inline comments.
- Add getSignatureShareRoundOne/Two/Three helpers in sdk-core for building PGP-signed MPS broadcast messages per signing round - Add verifyBitGoMessageRoundOne/Two helpers for verifying peer PGP signatures and deserialising incoming MPS messages - Parameterise partyId (default: USER=0) and peerPartyId (type: MPCv2PartiesEnum, default: BITGO=2) to support non-user signers without hardcoding - Wire eddsaMpcV2 type in sendSignatureShareV2 (common.ts) - Add generateEdDsaDKGKeyShares to sdk-lib-mpc MPSUtil with split EdDsaDKGPartySeed (encKey / dkgSeed) to eliminate seed dual-use; add length assertions - Replace duplicate test-util copy with a re-export from the production source - Add unit tests covering all helpers including BACKUP party path, tampered-message rejection for both round-1 and round-2 verify, and deterministic-seed behaviour Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> TICKET: WCI-153
zahin-mohammad
left a comment
There was a problem hiding this comment.
LGTM — all 7 prior comments are resolved in this revision:
- ✅ Seed dual-use split into
EdDsaDKGPartySeed { encKey, dkgSeed }with>= 32 byteasserts (the only blocking item, sinceMPSUtil.generateEdDsaDKGKeySharesis barrel-exported) - ✅ Test-util duplicate replaced with a re-export from the production source
- ✅ Helpers renamed to match ECDSA convention (
getSignatureShareRoundOne/Two/Three,verifyBitGoMessageRoundOne/Two) - ✅
bitgoGpgKey→peerGpgKey;peerPartyIdtyped asMPCv2PartiesEnumdirectly (no moreascast) - ✅ Dead
void bitgoSignedMsg1line removed - ✅ Test coverage filled: round-2 tampered-signature, BACKUP path for all three rounds, deterministic split-seed test with 3-party public-key agreement assertion
Residual nits — non-blocking, address in a follow-up
verifyBitGoMessage*name vs parameterized peer. The functions acceptpeerPartyId: MPCv2PartiesEnum, but the name still saysBitGo. Default ofBITGOkeeps it mostly accurate, but if a USER/BACKUP peer ever flows through, the name lies. ConsiderverifyPeerMessageRoundOne/Twoif you want the public surface to match the contract.- Type inconsistency in
eddsaMPCv2.ts. Signing helpers use literalpartyId: 0 | 1andotherSignerPartyId: 0 | 1 | 2, while verify helpers useMPCv2PartiesEnum. Unifying onMPCv2PartiesEnumeverywhere — optionally with aSignerPartyId = USER | BACKUPalias to enforce non-BITGO origination — would make the contract uniform across the file. - Redundant runtime assert in
partyIdToSignatureShareType. The literal0 | 1 | 2parameter type already prevents invalid values at compile time, so theassertis dead defensive code. Harmless; remove if you want to keep the file tight.
None of these block merge — happy to approve as-is.
| export async function verifyBitGoMessageRoundOne( | ||
| parsedRound1Output: EddsaMPCv2SignatureShareRound1Output, | ||
| peerGpgKey: openpgp.Key, | ||
| peerPartyId: MPCv2PartiesEnum = MPCv2PartiesEnum.BITGO |
There was a problem hiding this comment.
function is named verifyBitGoMessageRound* but accepts a peerPartyId param -- should this be verifyPeerMessageRound*, or is it BitGo-only and the param should be removed?
| import { generateGPGKeyPair } from '../../../../../../src/bitgo/utils/opengpgUtils'; | ||
| import { MPCv2PartiesEnum } from '../../../../../../src/bitgo/utils/tss/ecdsa/typesMPCv2'; | ||
|
|
||
| describe('EdDSA MPS DSG helper functions', async () => { |
There was a problem hiding this comment.
mocha describe callbacks shouldn't be async -- can cause tests to silently not run in some versions
PGP-signed MPS broadcast messages per signing round
and deserialising incoming MPS messages
default: BITGO=2) to support non-user signers without hardcoding
(encKey / dkgSeed) to eliminate seed dual-use; add length assertions
rejection for both round-1 and round-2 verify, and deterministic-seed behaviour
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
TICKET: WCI-153