Skip to content

Commit e23c562

Browse files
committed
feat: move opensslbytes to own package
BREAKING CHANGE: clients using challenge generation & TSS Recovery functions must now install @bitgo/sdk-opensslbytes separately & provide the openSSLBytes WASM themselves. Ticket: CE-4329
1 parent 09c8047 commit e23c562

49 files changed

Lines changed: 676 additions & 331 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/abstract-cosmos/src/cosmosCoin.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ export class CosmosCoin extends BaseCoin {
136136
* @returns {CosmosLikeCoinRecoveryOutput} the serialized transaction hex string and index
137137
* of the address being swept
138138
*/
139-
async recover(params: RecoveryOptions): Promise<CosmosLikeCoinRecoveryOutput> {
139+
async recover(params: RecoveryOptions, openSSLBytes: Uint8Array): Promise<CosmosLikeCoinRecoveryOutput> {
140140
// Step 1: Check if params contains the required parameters
141141
if (!params.bitgoKey) {
142142
throw new Error('missing bitgoKey');
@@ -157,6 +157,9 @@ export class CosmosCoin extends BaseCoin {
157157
if (!params.walletPassphrase) {
158158
throw new Error('missing wallet passphrase');
159159
}
160+
if (!openSSLBytes) {
161+
throw new Error('missing openSSLBytes');
162+
}
160163

161164
// Step 2: Fetch the bitgo key from params
162165
const userKey = params.userKey.replace(/\s/g, '');
@@ -233,7 +236,7 @@ export class CosmosCoin extends BaseCoin {
233236
}
234237

235238
// Step 7: Sign the tx
236-
signature = await this.signRecoveryTSS(userKeyCombined, backupKeyCombined, signableHex);
239+
signature = await this.signRecoveryTSS(userKeyCombined, backupKeyCombined, signableHex, openSSLBytes);
237240
} else {
238241
// DKLS
239242
const { userKeyShare, backupKeyShare, commonKeyChain } = await ECDSAUtils.getMpcV2RecoveryKeyShares(
@@ -275,7 +278,8 @@ export class CosmosCoin extends BaseCoin {
275278
validatorSrcAddress: string;
276279
validatorDstAddress: string;
277280
amountToRedelegate: string;
278-
}
281+
},
282+
openSSLBytes: Uint8Array
279283
): Promise<CosmosLikeCoinRecoveryOutput> {
280284
if (!params.bitgoKey) {
281285
throw new Error('missing bitgoKey');
@@ -304,7 +308,9 @@ export class CosmosCoin extends BaseCoin {
304308
if (!params.amountToRedelegate) {
305309
throw new Error('missing amountToRedelegate');
306310
}
307-
311+
if (!openSSLBytes) {
312+
throw new Error('missing openSSLBytes');
313+
}
308314
const bitgoKey = params.bitgoKey.replace(/\s/g, '');
309315

310316
const MPC = new Ecdsa();
@@ -362,7 +368,7 @@ export class CosmosCoin extends BaseCoin {
362368
throw new Error('Missing combined key shares for user or backup');
363369
}
364370

365-
const signature = await this.signRecoveryTSS(userKeyCombined, backupKeyCombined, signableHex);
371+
const signature = await this.signRecoveryTSS(userKeyCombined, backupKeyCombined, signableHex, openSSLBytes);
366372
const signableBuffer = Buffer.from(signableHex, 'hex');
367373
MPC.verify(signableBuffer, signature, this.getHashFunction());
368374
const cosmosKeyPair = this.getKeyPair(publicKey);
@@ -442,6 +448,7 @@ export class CosmosCoin extends BaseCoin {
442448
userKeyCombined: ECDSA.KeyCombined,
443449
backupKeyCombined: ECDSA.KeyCombined,
444450
txHex: string,
451+
openSSLBytes: Uint8Array,
445452
{
446453
rangeProofChallenge,
447454
}: {
@@ -454,7 +461,7 @@ export class CosmosCoin extends BaseCoin {
454461

455462
// Since this is a user <> backup signing, we will reuse the same range proof challenge
456463
rangeProofChallenge =
457-
rangeProofChallenge ?? EcdsaTypes.serializeNtildeWithProofs(await EcdsaRangeProof.generateNtilde());
464+
rangeProofChallenge ?? EcdsaTypes.serializeNtildeWithProofs(await EcdsaRangeProof.generateNtilde(openSSLBytes));
458465

459466
const userToBackupPaillierChallenge = await EcdsaPaillierProof.generateP(
460467
hexToBigInt(userKeyCombined.yShares[signerTwoIndex].n)

modules/abstract-eth/src/abstractEthLikeNewCoins.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,17 @@ interface UnformattedTxInfo {
202202
recipient: Recipient;
203203
}
204204

205-
export interface RecoverOptions {
205+
export type RecoverOptionsWithBytes = {
206+
isTss: true;
207+
openSSLBytes: Uint8Array;
208+
};
209+
export type NonTSSRecoverOptions = {
210+
isTss?: false | undefined;
211+
};
212+
213+
export type TSSRecoverOptions = RecoverOptionsWithBytes | NonTSSRecoverOptions;
214+
215+
export type RecoverOptions = {
206216
userKey: string;
207217
backupKey: string;
208218
walletPassphrase?: string;
@@ -213,13 +223,12 @@ export interface RecoverOptions {
213223
gasLimit?: number;
214224
eip1559?: EIP1559;
215225
replayProtectionOptions?: ReplayProtectionOptions;
216-
isTss?: boolean;
217226
bitgoFeeAddress?: string;
218227
bitgoDestinationAddress?: string;
219228
tokenContractAddress?: string;
220229
intendedChain?: string;
221230
common?: EthLikeCommon.default;
222-
}
231+
} & TSSRecoverOptions;
223232

224233
export type GetBatchExecutionInfoRT = {
225234
values: [string[], string[]];
@@ -1055,6 +1064,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
10551064
userKeyCombined: ECDSA.KeyCombined,
10561065
backupKeyCombined: ECDSA.KeyCombined,
10571066
txHex: string,
1067+
openSSLBytes: Uint8Array,
10581068
{
10591069
rangeProofChallenge,
10601070
}: {
@@ -1070,7 +1080,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
10701080
const signerTwoIndex = backupKeyCombined.xShare.i;
10711081

10721082
rangeProofChallenge =
1073-
rangeProofChallenge ?? EcdsaTypes.serializeNtildeWithProofs(await EcdsaRangeProof.generateNtilde());
1083+
rangeProofChallenge ?? EcdsaTypes.serializeNtildeWithProofs(await EcdsaRangeProof.generateNtilde(openSSLBytes));
10741084

10751085
const userToBackupPaillierChallenge = await EcdsaPaillierProof.generateP(
10761086
hexToBigInt(userKeyCombined.yShares[signerTwoIndex].n)
@@ -1273,8 +1283,8 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
12731283
* @param {string} params.bitgoDestinationAddress - target bitgo address where fee will be sent for evm based cross chain recovery txn
12741284
*/
12751285
async recover(params: RecoverOptions): Promise<RecoveryInfo | OfflineVaultTxInfo> {
1276-
if (params.isTss) {
1277-
return this.recoverTSS(params);
1286+
if (params.isTss === true) {
1287+
return this.recoverTSS(params, params.openSSLBytes);
12781288
}
12791289
return this.recoverEthLike(params);
12801290
}
@@ -1929,7 +1939,10 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
19291939
* Recovers a tx with TSS key shares
19301940
* same expected arguments as recover method, but with TSS key shares
19311941
*/
1932-
protected async recoverTSS(params: RecoverOptions): Promise<RecoveryInfo | OfflineVaultTxInfo> {
1942+
protected async recoverTSS(
1943+
params: RecoverOptions,
1944+
openSSLBytes: Uint8Array
1945+
): Promise<RecoveryInfo | OfflineVaultTxInfo> {
19331946
this.validateRecoveryParams(params);
19341947
// Clean up whitespace from entered values
19351948
const userPublicOrPrivateKeyShare = params.userKey.replace(/\s/g, '');
@@ -1982,7 +1995,8 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
19821995
signature = await this.signRecoveryTSS(
19831996
userKeyCombined,
19841997
backupKeyCombined,
1985-
unsignedTx.getMessageToSign(false).toString('hex')
1998+
unsignedTx.getMessageToSign(false).toString('hex'),
1999+
openSSLBytes
19862000
);
19872001
} else {
19882002
const { userKeyShare, backupKeyShare, commonKeyChain } = await ECDSAUtils.getMpcV2RecoveryKeyShares(

modules/bitgo/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
},
118118
"devDependencies": {
119119
"@bitgo/public-types": "2.33.4",
120+
"@bitgo/sdk-opensslbytes": "^1.0.0",
120121
"@bitgo/sdk-test": "^8.0.34",
121122
"@openpgp/web-stream-tools": "0.0.14",
122123
"@types/create-hmac": "^1.1.0",

modules/bitgo/test/v2/unit/internal/tssUtils/ecdsa.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ import { bip32, ecc } from '@bitgo/utxo-lib';
4646
import { Hash } from 'crypto';
4747
import { mockChallengeA, mockChallengeB, mockChallengeC } from './mocks/ecdsaNtilde';
4848

49+
import { loadWebAssembly } from '@bitgo/sdk-opensslbytes';
50+
51+
const openSSLBytes = loadWebAssembly().buffer;
52+
4953
const createKeccakHash = require('keccak');
5054

5155
const encryptNShare = ECDSAMethods.encryptNShare;
@@ -1590,6 +1594,7 @@ describe('TSS Ecdsa Utils:', async function () {
15901594
userPassword,
15911595
signedInstChallenge,
15921596
signedNitroChallenge,
1597+
openSSLBytes,
15931598
deserializedEntChallenge
15941599
).should.not.be.rejected();
15951600
stubUploadChallenge.should.be.calledWith(
@@ -1628,7 +1633,8 @@ describe('TSS Ecdsa Utils:', async function () {
16281633
'ent_id',
16291634
userPassword,
16301635
signedInstChallenge,
1631-
signedNitroChallenge
1636+
signedNitroChallenge,
1637+
openSSLBytes
16321638
).should.not.be.rejected();
16331639
stubUploadChallenge.should.be.calledWith(
16341640
bitgo,

modules/sdk-coin-atom/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"devDependencies": {
5353
"@bitgo/sdk-api": "^1.51.3",
5454
"@bitgo/sdk-test": "^8.0.34",
55+
"@bitgo/sdk-opensslbytes": "^1.0.0",
5556
"@types/lodash": "^4.14.183",
5657
"axios": "^1.3.4"
5758
}

modules/sdk-coin-atom/test/unit/atom.ts

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ import {
2121
} from '../resources/atom';
2222
import should = require('should');
2323

24+
import { loadWebAssembly } from '@bitgo/sdk-opensslbytes';
25+
26+
const openSSLBytes = loadWebAssembly().buffer;
27+
2428
describe('ATOM', function () {
2529
let bitgo: TestBitGoAPI;
2630
let basecoin;
@@ -429,13 +433,16 @@ describe('ATOM', function () {
429433
});
430434

431435
it('should recover funds for non-bitgo recoveries', async function () {
432-
const res = await basecoin.recover({
433-
userKey: wrwUser.userKey,
434-
backupKey: wrwUser.backupKey,
435-
bitgoKey: wrwUser.bitgoKey,
436-
walletPassphrase: wrwUser.walletPassphrase,
437-
recoveryDestination: destinationAddress,
438-
});
436+
const res = await basecoin.recover(
437+
{
438+
userKey: wrwUser.userKey,
439+
backupKey: wrwUser.backupKey,
440+
bitgoKey: wrwUser.bitgoKey,
441+
walletPassphrase: wrwUser.walletPassphrase,
442+
recoveryDestination: destinationAddress,
443+
},
444+
openSSLBytes
445+
);
439446
res.should.not.be.empty();
440447
res.should.hasOwnProperty('serializedTx');
441448
sandBox.assert.calledOnce(basecoin.getAccountBalance);
@@ -453,13 +460,16 @@ describe('ATOM', function () {
453460
});
454461

455462
it('should recover funds for non-bitgo recoveries - DKLS type', async function () {
456-
const res = await basecoin.recover({
457-
userKey: wrwUserDkls.userKey,
458-
backupKey: wrwUserDkls.backupKey,
459-
bitgoKey: wrwUserDkls.bitgoKey,
460-
walletPassphrase: wrwUserDkls.walletPassphrase,
461-
recoveryDestination: wrwUserDkls.destinationAddress,
462-
});
463+
const res = await basecoin.recover(
464+
{
465+
userKey: wrwUserDkls.userKey,
466+
backupKey: wrwUserDkls.backupKey,
467+
bitgoKey: wrwUserDkls.bitgoKey,
468+
walletPassphrase: wrwUserDkls.walletPassphrase,
469+
recoveryDestination: wrwUserDkls.destinationAddress,
470+
},
471+
openSSLBytes
472+
);
463473
res.should.not.be.empty();
464474
res.should.hasOwnProperty('serializedTx');
465475
sandBox.assert.calledOnce(basecoin.getAccountBalance);
@@ -477,15 +487,18 @@ describe('ATOM', function () {
477487
});
478488

479489
it('should redelegate funds to new validator', async function () {
480-
const res = await basecoin.redelegate({
481-
userKey: wrwUser.userKey,
482-
backupKey: wrwUser.backupKey,
483-
bitgoKey: wrwUser.bitgoKey,
484-
walletPassphrase: wrwUser.walletPassphrase,
485-
amountToRedelegate: '10000000000000000',
486-
validatorSrcAddress: 'cosmosvaloper1409te27da74uahh6hn0040x7l272hjs2padjuz',
487-
validatorDstAddress: 'cosmosvaloper183aycgtstp67r6s4vd7ts2npp2ckk4xah7rxj6',
488-
});
490+
const res = await basecoin.redelegate(
491+
{
492+
userKey: wrwUser.userKey,
493+
backupKey: wrwUser.backupKey,
494+
bitgoKey: wrwUser.bitgoKey,
495+
walletPassphrase: wrwUser.walletPassphrase,
496+
amountToRedelegate: '10000000000000000',
497+
validatorSrcAddress: 'cosmosvaloper1409te27da74uahh6hn0040x7l272hjs2padjuz',
498+
validatorDstAddress: 'cosmosvaloper183aycgtstp67r6s4vd7ts2npp2ckk4xah7rxj6',
499+
},
500+
openSSLBytes
501+
);
489502

490503
res.should.not.be.empty();
491504
res.should.hasOwnProperty('serializedTx');
@@ -561,7 +574,7 @@ describe('ATOM', function () {
561574
.should.rejectedWith('missing wallet passphrase');
562575
});
563576

564-
it('should throw error if there is no balance', async function () {
577+
it('should throw error if openSSLBytes is not present', async function () {
565578
await basecoin
566579
.recover({
567580
userKey: wrwUser.userKey,
@@ -570,6 +583,21 @@ describe('ATOM', function () {
570583
walletPassphrase: wrwUser.walletPassphrase,
571584
recoveryDestination: destinationAddress,
572585
})
586+
.should.rejectedWith('missing openSSLBytes');
587+
});
588+
589+
it('should throw error if there is no balance', async function () {
590+
await basecoin
591+
.recover(
592+
{
593+
userKey: wrwUser.userKey,
594+
backupKey: wrwUser.backupKey,
595+
bitgoKey: wrwUser.bitgoKey,
596+
walletPassphrase: wrwUser.walletPassphrase,
597+
recoveryDestination: destinationAddress,
598+
},
599+
openSSLBytes
600+
)
573601
.should.rejectedWith('Did not have enough funds to recover');
574602
});
575603
});

modules/sdk-coin-bld/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
},
5252
"devDependencies": {
5353
"@bitgo/sdk-api": "^1.51.3",
54+
"@bitgo/sdk-opensslbytes": "^1.0.0",
5455
"@bitgo/sdk-test": "^8.0.34",
5556
"@types/lodash": "^4.14.183"
5657
}

0 commit comments

Comments
 (0)