Repository navigation
fix: validate BitGo GPG key and session state in ECDSA MPCv2 offline signing - #10155
Conversation
58ab47f to
3b54625
Compare
c631edb to
0288a3d
Compare
3b54625 to
90596a4
Compare
0288a3d to
fb394c5
Compare
fb394c5 to
c12637c
Compare
|
|
…signing The DKLS23 offline round helpers accepted the BitGo public GPG key from the request and processed the same encrypted session blob repeatedly, so a malicious online relay could replay round-2 or round-3 state, obtain two partial signatures under one nonce, and recover the signer's key share (CWE-323). Round 2 and round 3 now validate the BitGo public GPG key against the known BitGo key table in the same environments that already enforce this for keygen, and each encrypted session blob is consumed exactly once: rejected early through an in-memory digest registry in sdk-core and durably through the express consumed-shares registry via a lazy markSessionConsumed hook, mirroring the EdDSA MPCv2 rounds. Session envelopes are minted with a creation stamp in the adata and validated against the registry retention window, bounding the replay window the same way. The session digest, stamped-adata validation, and registry are hoisted from the EdDSA MPCv2 module into a shared TSS module so both DSG protocols enforce an identical single-use contract. References: WAL-2457
c12637c to
7495f3b
Compare
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
|
@claude Please do a thorough review of this PR. Focus especially on:
Please call out concrete issues clearly and separate them by severity if possible. |
|
Claude finished @lokesh-bitgo's task in 39s —— View job Review of PR #10155 (ECDSA MPCv2 offline signing: GPG pin and single-use sessions)I read the full diff, the new shared module and the express wiring. I did not run the test suites. The PR description reports them passing, and I haven't re-verified that. Verdict: The core design is sound and consistent with the EdDSA MPCv2 hardening. I found no blocking bugs. There are a few compatibility and robustness points worth deciding on before merge. What looks correct
Medium
Low
Test coverage gaps
|
Summary
Aligns the ECDSA MPCv2 (DKLS23) offline signing rounds (
MPCv2Round2/MPCv2Round3) with the existing keygen helpers and with the EdDSA MPCv2 rounds hardened in #10127:ConsumedShareRegistryvia the same lazymarkSessionConsumedhook the EdDSA rounds use — preventing nonce reuse from a replayed blob (CWE-323).OFFLINE_SIGNING_SHARE_MAX_AGE_MSfrom the GG18 offline-signing helpers so one retention window covers all protocols.Linear: WAL-2457
Changes
EcdsaMPCv2Utils.createOfflineRound1Share/createOfflineRound2Share: mint session envelopes with aDate.now()adata stamp.EcdsaMPCv2Utils.createOfflineRound2Share/createOfflineRound3Share: pin the BitGo GPG key (isBitgoMpcPubKey(..., 'mpcv2')gated byenvRequiresBitgoPubGpgKeyConfig), reject an already-consumed session blob via the digest registry before processing, validate the stamped adata before decryption, and mark the blob consumed (durable hook first, then in-memory) immediately before the DSG nonce state is restored.encryptedSessionSingleUse.ts(moved from the EdDSA MPCv2 module);eddsaMPCv2.tsand the sdk-core index re-point at it.MPCv2Round2/MPCv2Round3cases pass the sharedmarkConsumedOfflineSessionClosureinto the round helpers; the signer-mode startup warning now mentions both protocols.Test Plan
encryptedRound1Session/encryptedRound2Session, including JSON-reformatted envelopes;externalSignsuite — 22 passing, including route-level replay rejection in the ECDSA MPCv2 full flow.