44import assert from 'assert' ;
55import { Hash , randomBytes } from 'crypto' ;
66import { Ecdsa , ECDSA , hexToBigInt } from '@bitgo/sdk-core' ;
7- import { EcdsaPaillierProof , EcdsaTypes , Schnorr , SchnorrProof } from '@bitgo/sdk-lib-mpc' ;
7+ import { EcdsaPaillierProof , EcdsaTypes , SchnorrProof } from '@bitgo/sdk-lib-mpc' ;
88import * as sinon from 'sinon' ;
99import createKeccakHash from 'keccak' ;
10- import * as paillierBigint from 'paillier-bigint' ;
1110import {
1211 schnorrProofs ,
1312 ntildes ,
@@ -19,6 +18,12 @@ import {
1918 mockFKeyShare ,
2019} from '../fixtures/ecdsa' ;
2120
21+ // Need to import and then monkey-patch to make stubbing work with ESM
22+ const paillierBigintModule = require ( 'paillier-bigint' ) ;
23+ const paillierBigint = paillierBigintModule ;
24+ const schnorrModule = require ( '@bitgo/sdk-lib-mpc' ) ;
25+ const Schnorr = schnorrModule . Schnorr ;
26+
2227describe ( 'TSS ECDSA TESTS' , function ( ) {
2328 const MPC = new Ecdsa ( ) ;
2429 const base = BigInt ( '0x010000000000000000000000000000000000000000000000000000000000000000' ) ; // 2^256
@@ -30,23 +35,35 @@ describe('TSS ECDSA TESTS', function () {
3035 ) ;
3136 let A : ECDSA . KeyShare , B : ECDSA . KeyShare , C : ECDSA . KeyShare ;
3237 before ( async ( ) => {
33- const paillierMock = sinon
34- . stub ( paillierBigint , 'generateRandomKeys' )
38+ // Direct monkey patching of the module for ESM compatibility
39+ const originalGenerateRandomKeys = paillierBigint . generateRandomKeys ;
40+
41+ const paillierMock = sinon . stub ( ) ;
42+ paillierMock
3543 . onCall ( 0 )
36- . resolves ( paillerKeys [ 0 ] as unknown as paillierBigint . KeyPair )
44+ . resolves ( paillerKeys [ 0 ] )
3745 . onCall ( 1 )
38- . resolves ( paillerKeys [ 1 ] as unknown as paillierBigint . KeyPair )
46+ . resolves ( paillerKeys [ 1 ] )
3947 . onCall ( 2 )
40- . resolves ( paillerKeys [ 2 ] as unknown as paillierBigint . KeyPair )
48+ . resolves ( paillerKeys [ 2 ] )
4149 . onCall ( 3 )
42- . resolves ( paillerKeys [ 0 ] as unknown as paillierBigint . KeyPair )
50+ . resolves ( paillerKeys [ 0 ] )
4351 . onCall ( 4 )
44- . resolves ( paillerKeys [ 1 ] as unknown as paillierBigint . KeyPair )
52+ . resolves ( paillerKeys [ 1 ] )
4553 . onCall ( 5 )
46- . resolves ( paillerKeys [ 2 ] as unknown as paillierBigint . KeyPair ) ;
54+ . resolves ( paillerKeys [ 2 ] ) ;
55+
56+ // Replace the function directly on the module
57+ paillierBigint . generateRandomKeys = paillierMock ;
58+
59+ // Save references to restore later
60+ ( paillierMock as any ) . originalFn = originalGenerateRandomKeys ;
4761
48- const schnorrProofMock = sinon
49- . stub ( Schnorr , 'createSchnorrProof' )
62+ // Apply the same monkey-patching approach for Schnorr
63+ const originalCreateSchnorrProof = Schnorr . createSchnorrProof ;
64+
65+ const schnorrProofMock = sinon . stub ( ) ;
66+ schnorrProofMock
5067 . onCall ( 0 )
5168 . returns ( schnorrProofs [ 0 ] as unknown as SchnorrProof )
5269 . onCall ( 1 )
@@ -60,6 +77,12 @@ describe('TSS ECDSA TESTS', function () {
6077 . onCall ( 5 )
6178 . returns ( schnorrProofs [ 5 ] as unknown as SchnorrProof ) ;
6279
80+ // Replace the function directly on the module
81+ Schnorr . createSchnorrProof = schnorrProofMock ;
82+
83+ // Save references to restore later
84+ ( schnorrProofMock as any ) . originalFn = originalCreateSchnorrProof ;
85+
6386 [ A , B , C ] = await Promise . all ( [ MPC . keyShare ( 1 , 2 , 3 ) , MPC . keyShare ( 2 , 2 , 3 ) , MPC . keyShare ( 3 , 2 , 3 ) ] ) ;
6487
6588 // Needs to run this serially for testing deterministic key generation
@@ -96,10 +119,13 @@ describe('TSS ECDSA TESTS', function () {
96119 hKeyCombine ,
97120 ] ;
98121 commonPublicKey = aKeyCombine . xShare . y ;
99- paillierMock . reset ( ) ;
100- paillierMock . restore ( ) ;
101- schnorrProofMock . reset ( ) ;
102- schnorrProofMock . restore ( ) ;
122+ // Adding an explicit assertion to check if the stub was used
123+ paillierMock . callCount . should . equal ( 6 , 'paillierMock should be called 6 times' ) ;
124+ schnorrProofMock . callCount . should . equal ( 8 , 'schnorrProofMock should be called 6 times' ) ;
125+
126+ // Restore original functions
127+ paillierBigint . generateRandomKeys = ( paillierMock as any ) . originalFn ;
128+ Schnorr . createSchnorrProof = ( schnorrProofMock as any ) . originalFn ;
103129 } ) ;
104130
105131 describe ( 'Ecdsa Key Generation Test' , function ( ) {
@@ -149,10 +175,7 @@ describe('TSS ECDSA TESTS', function () {
149175 } ) ;
150176
151177 it ( 'should pass if seed length is greater than 64' , async function ( ) {
152- const paillierMock = sinon
153- . stub ( paillierBigint , 'generateRandomKeys' )
154- . onCall ( 0 )
155- . resolves ( paillerKeys [ 0 ] as unknown as paillierBigint . KeyPair ) ;
178+ const paillierMock = sinon . stub ( paillierBigint , 'generateRandomKeys' ) . onCall ( 0 ) . resolves ( paillerKeys [ 0 ] ) ;
156179 const seed72Bytes = Buffer . from (
157180 '4f7e914dc9ec696398675d1544aab61cb7a67662ffcbdb4079ec5d682be565d87c1b2de75c943dec14c96586984860268779498e6732473aed9ed9c2538f50bea0af926bdccc0134' ,
158181 'hex' ,
0 commit comments