-
Notifications
You must be signed in to change notification settings - Fork 0
feat(ebe): support mpc signing for eddsa #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
b57fd78 to
62c91a3
Compare
| R = 'r', | ||
| G = 'g', | ||
|
|
||
| // TODO: Add ECDSA share types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope this helps, for ECDSA I found this variant of shares on account-lib/mpc/tss/ecdsa/types.ts file from the SDK:
export type SignConvert = { xShare?: XShareWithChallenges; // XShare of the current participant yShare?: YShare; // YShare corresponding to the other participant kShare?: KShare; // KShare received from the other participant bShare?: BShare; // Private Beta share of the participant muShare?: MUShare; // muShare received from the other participant aShare?: AShare; wShare?: WShare; };
TL;DR: x, y, k, a, b, mu, w are the shares for ECDSA (also g but already added for EdDSA).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dw about ECSSA, i'll add them when we get to ECDSA signing
|
|
||
| export async function signMpcTransaction(req: EnclavedApiSpecRouteRequest<'v1.mpc.sign', 'post'>) { | ||
| const { source, pub, encryptedDataKey } = req.decoded; | ||
| const { coin: coinName, shareType } = req.params; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change: "coin" also comes from req.decoded (not params).
| const { coin: coinName, shareType } = req.params; | ||
|
|
||
| if (!source || !pub) { | ||
| throw new Error('Source and public key are required for MPC signing'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: shouldn't we also need to do the logger.error call here? (and in the shareType check).
| // Response type for /mpc/sign endpoint | ||
| const SignMpcResponse: HttpResponse = { | ||
| // TODO: Define proper response type for MPC transaction signing | ||
| 200: t.any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reminder: add type to return type (is always the same type or does it varies depending what coin are you signing?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
| try { | ||
| kmsResponse = await superagent | ||
| .post(`${this.url}/generateDataKey`) | ||
| .set('x-api-key', 'abc') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need to keep adding the api key, I removed it some weeks ago : D
| try { | ||
| kmsResponse = await superagent | ||
| .post(`${this.url}/decryptDataKey`) | ||
| .set('x-api-key', 'abc') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as prev comment.
mtexeira-simtlix
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a couple of comments
2b43409 to
bf30d2a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for MPC signing for EDDSA by introducing new routes, handlers, and associated tests while refactoring import paths to a shared types directory.
- Updates import paths across multiple modules to use the new shared folder structure.
- Introduces new API route "v1.mpc.sign" with corresponding handler (signMpcTransaction) and supporting functions for EDDSA MPC signing.
- Adjusts test cases to align with the new file structure and updated dependency versions.
Reviewed Changes
Copilot reviewed 33 out of 37 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/types/request.ts | Updated import paths for Config and EnclavedExpressClient. |
| src/shared/responseHandler.ts | Changed Config import to shared/types. |
| src/shared/middleware.ts | Updated import path for isMasterExpressConfig. |
| src/shared/appUtils.ts | Adjusted import for Config and TlsMode. |
| src/routes/master.ts | Moved master API router imports to new locations. |
| src/routes/enclaved.ts | Corrected import order and paths for EnclavedConfig. |
| src/masterExpressApp.ts | Updated import order for config initialization. |
| src/kms/kmsClient.ts | Added functions to generate and decrypt data keys. |
| src/enclavedBitgoExpress/routers/enclavedApiSpec.ts | Added new route definition for v1.mpc.sign. |
| src/enclavedApp.ts | Adjusted imports for Enclaved configuration. |
| src/app.ts | Updated imports for determineAppMode and AppMode. |
| src/api/master/routers/* | Updated handler imports and middleware usage. |
| src/api/enclaved/handlers/signMpcTransaction.ts | Implements new EDDSA MPC signing logic. |
| Tests | Updated test imports and configurations for new structure. |
Comments suppressed due to low confidence (1)
src/api/enclaved/handlers/signMpcTransaction.ts:156
- [nitpick] Verify that using 'RSA-2048' as the key type for generating the data key is intentional in the context of EDDSA MPC signing, as the algorithm mismatch might be confusing.
const dataKey = await generateDataKey({ keyType: 'RSA-2048', cfg });
| .set('x-api-key', 'abc') | ||
| .send(params); | ||
| } catch (error: any) { | ||
| console.log('Error generating data key from KMS', error); |
Copilot
AI
Jun 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider replacing console.log with the configured logger (e.g., logger.error) for better consistency in error logging.
| console.log('Error generating data key from KMS', error); | |
| debugLogger('Error generating data key from KMS: %O', error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's do that.
mohammadalfaiyazbitgo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, couple of nits that can be followed up on.
| if (!source || !pub) { | ||
| throw new Error('Source and public key are required for MPC signing'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just type them as required in the codec?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I guess because this endpoint handles both signing rounds?
| if (!shareType) { | ||
| throw new Error('Share type is required for MPC signing'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here?
| if (!txRequest) { | ||
| throw new Error('txRequest is required for commitment share generation'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this check is in both rounds, why not just make it required?
| const SignMpcRequest = { | ||
| source: t.string, | ||
| pub: t.string, | ||
| txRequest: t.union([t.undefined, t.any]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this required in both signing cases so can we define it as non-nullable?
| .set('x-api-key', 'abc') | ||
| .send(params); | ||
| } catch (error: any) { | ||
| console.log('Error generating data key from KMS', error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's do that.
| .set('x-api-key', 'abc') | ||
| .send(params); | ||
| } catch (error: any) { | ||
| console.log('Error decrypting data key from KMS', error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
debugLogger.
| @@ -0,0 +1,27 @@ | |||
| import z from 'zod'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the kms code moved to the same repo? i didn't realize we're using zod for it.

No description provided.