|
| 1 | +import 'should'; |
| 2 | +import sinon from 'sinon'; |
| 3 | +import { DklsUtils, DklsTypes } from '@bitgo/sdk-lib-mpc'; |
| 4 | +import { combineRound4DklsDsgMessages } from '../../../../src/account-lib/mpc/util'; |
| 5 | + |
| 6 | +function makeMsg(from: number, rHex?: string): DklsTypes.SerializedBroadcastMessage { |
| 7 | + return { |
| 8 | + payload: Buffer.from(`payload-${from}`).toString('base64'), |
| 9 | + from, |
| 10 | + signatureR: rHex ? Buffer.from(rHex, 'hex').toString('base64') : undefined, |
| 11 | + }; |
| 12 | +} |
| 13 | + |
| 14 | +describe('combineRound4DklsDsgMessages', function () { |
| 15 | + let stub: sinon.SinonStub; |
| 16 | + |
| 17 | + beforeEach(function () { |
| 18 | + stub = sinon.stub(DklsUtils, 'combinePartialSignatures').returns({ |
| 19 | + R: new Uint8Array([1, 2, 3]), |
| 20 | + S: new Uint8Array([4, 5, 6]), |
| 21 | + }); |
| 22 | + }); |
| 23 | + |
| 24 | + afterEach(function () { |
| 25 | + stub.restore(); |
| 26 | + }); |
| 27 | + |
| 28 | + it('throws when no message contains signatureR', function () { |
| 29 | + const msgs = [makeMsg(0), makeMsg(1), makeMsg(2)]; |
| 30 | + (() => combineRound4DklsDsgMessages(msgs)).should.throw( |
| 31 | + 'None of the round 4 Dkls messages contain a Signature.R value.' |
| 32 | + ); |
| 33 | + }); |
| 34 | + |
| 35 | + it('throws when parties provide different signatureR values', function () { |
| 36 | + const msgs = [makeMsg(0, 'aabbcc'), makeMsg(1, 'ddeeff'), makeMsg(2, 'aabbcc')]; |
| 37 | + (() => combineRound4DklsDsgMessages(msgs)).should.throw( |
| 38 | + 'signatureR mismatch across parties — possible protocol attack' |
| 39 | + ); |
| 40 | + }); |
| 41 | + |
| 42 | + it('succeeds when all parties agree on signatureR', function () { |
| 43 | + const rHex = 'aabbccddeeff0011'; |
| 44 | + const msgs = [makeMsg(0, rHex), makeMsg(1, rHex), makeMsg(2, rHex)]; |
| 45 | + const result = combineRound4DklsDsgMessages(msgs); |
| 46 | + result.should.have.property('R'); |
| 47 | + result.should.have.property('S'); |
| 48 | + stub.calledOnce.should.be.true(); |
| 49 | + stub.firstCall.args[1].should.equal(rHex); |
| 50 | + }); |
| 51 | + |
| 52 | + it('succeeds when only one party provides signatureR', function () { |
| 53 | + const rHex = 'cafebabe'; |
| 54 | + const msgs = [makeMsg(0, rHex), makeMsg(1), makeMsg(2)]; |
| 55 | + const result = combineRound4DklsDsgMessages(msgs); |
| 56 | + result.should.have.property('R'); |
| 57 | + stub.calledOnce.should.be.true(); |
| 58 | + }); |
| 59 | +}); |
0 commit comments