PHP WebShell
Текущая директория: /opt/BitGoJS/modules/bitgo/test/v2/unit/tss
Просмотр файла: ecdsa.ts
import {
Ecdsa,
ECDSA,
ECDSAMethodTypes,
Wallet,
SignatureShareRecord,
getTxRequest,
ECDSAMethods,
RequestType,
SignatureShareType,
hexToBigInt,
} from '@bitgo/sdk-core';
import { EcdsaTypes, EcdsaPaillierProof } from '@bitgo/sdk-lib-mpc';
import * as openpgp from 'openpgp';
import * as should from 'should';
import { mockSerializedChallengeWithProofs, TestBitGo } from '@bitgo/sdk-test';
import { BitGo } from '../../../../src';
import { nockGetTxRequest, nockSendSignatureShare } from './helpers';
import {
gammaAndMuShareCreationParams,
omicronAndDeltaShareCreationParams,
keyShares,
createUserSignatureParams,
mockSignRT,
mockAShare,
mockMuShare,
mockDShare,
mockSShareFromUser,
mockDShareToBitgo,
mockedBitgoBShare,
mockedBitgoOAndDShare,
mockSShare,
mockSignWithPaillierChallengeRT,
} from '../../fixtures/tss/ecdsaFixtures';
import nock = require('nock');
type KeyShare = ECDSA.KeyShare;
const encryptNShare = ECDSAMethods.encryptNShare;
const createCombinedKey = ECDSAMethods.createCombinedKey;
type GpgKeypair = {
publicKey: string;
privateKey: string;
};
describe('Ecdsa tss helper functions tests', function () {
let mpc: Ecdsa;
let userKeyShare: KeyShare;
let backupKeyShare: KeyShare;
let bitgoKeyShare: KeyShare;
let userKey: ECDSA.KeyCombined;
let backupKey: ECDSA.KeyCombined;
let bitgoKey: ECDSA.KeyCombined;
let userGpgKeypair: GpgKeypair;
let backupGpgKeypair: GpgKeypair;
let bitgoGpgKeypair: GpgKeypair;
let commonKeychain: string;
before(async function () {
mpc = new Ecdsa();
userKeyShare = keyShares.userKeyShare;
backupKeyShare = keyShares.backupKeyShare;
bitgoKeyShare = keyShares.bitgoKeyShare;
userKey = mpc.keyCombine(userKeyShare.pShare, [backupKeyShare.nShares[1], bitgoKeyShare.nShares[1]]);
backupKey = mpc.keyCombine(backupKeyShare.pShare, [userKeyShare.nShares[2], bitgoKeyShare.nShares[2]]);
bitgoKey = mpc.keyCombine(bitgoKeyShare.pShare, [backupKeyShare.nShares[3], userKeyShare.nShares[3]]);
(userKey.xShare.y + userKey.xShare.chaincode).should.equal(backupKey.xShare.y + backupKey.xShare.chaincode);
(userKey.xShare.y + userKey.xShare.chaincode).should.equal(bitgoKey.xShare.y + bitgoKey.xShare.chaincode);
commonKeychain = userKey.xShare.y + userKey.xShare.chaincode;
const gpgKeypairPromises = [
{ name: 'user', email: 'user@bitgo.com' },
{ name: 'backup', email: 'backup@bitgo.com' },
{ name: 'bitgo', email: 'bitgo@bitgo.com' },
].map(async (user) => {
return openpgp.generateKey({
userIDs: [
{
name: user.name,
email: user.email,
},
],
curve: 'secp256k1',
});
});
const gpgKeypairs = await Promise.all(gpgKeypairPromises);
userGpgKeypair = gpgKeypairs[0];
backupGpgKeypair = gpgKeypairs[1];
bitgoGpgKeypair = gpgKeypairs[2];
});
after(function () {
nock.cleanAll();
});
describe('encryptNShare and decryptNShare', function () {
after(function () {
nock.cleanAll();
});
it('should encrypt n shares foreach user', async function () {
for (let i = 2; i <= 3; i++) {
const encryptedNShare = await ECDSAMethods.encryptNShare(
userKeyShare,
i,
bitgoGpgKeypair.publicKey,
userGpgKeypair
);
const decryptedNShare = await ECDSAMethods.decryptNShare({
nShare: encryptedNShare,
senderPublicArmor: userGpgKeypair.publicKey,
recipientPrivateArmor: bitgoGpgKeypair.privateKey,
});
decryptedNShare.u.should.equal(userKeyShare.nShares[i].u);
const publicKey = userKeyShare.pShare.y + userKeyShare.pShare.chaincode;
encryptedNShare.i.should.equal(i);
encryptedNShare.vssProof!.should.equal(userKeyShare.nShares[3].v!);
encryptedNShare.j.should.equal(1);
encryptedNShare.publicShare.should.equal(publicKey);
}
});
it('should error for invalid recipient', async function () {
await encryptNShare(userKeyShare, 1, userGpgKeypair.privateKey, userGpgKeypair).should.be.rejectedWith(
'Invalid recipient'
);
await encryptNShare(backupKeyShare, 2, userGpgKeypair.privateKey, userGpgKeypair).should.be.rejectedWith(
'Invalid recipient'
);
await encryptNShare(bitgoKeyShare, 3, userGpgKeypair.privateKey, userGpgKeypair).should.be.rejectedWith(
'Invalid recipient'
);
});
it('should decrypt n share', async function () {
const encryptedNShare = await ECDSAMethods.encryptNShare(
userKeyShare,
3,
bitgoGpgKeypair.publicKey,
userGpgKeypair
);
const decryptedNShare = await ECDSAMethods.decryptNShare({
nShare: encryptedNShare,
recipientPrivateArmor: bitgoGpgKeypair.privateKey,
senderPublicArmor: userGpgKeypair.publicKey,
});
decryptedNShare.i.should.equal(userKeyShare.nShares[3].i);
decryptedNShare.j.should.equal(userKeyShare.nShares[3].j);
decryptedNShare.n.should.equal(userKeyShare.nShares[3].n);
decryptedNShare.u.should.equal(userKeyShare.nShares[3].u);
decryptedNShare.y.should.equal(userKeyShare.nShares[3].y);
});
});
describe('createCombinedKey', function () {
after(function () {
nock.cleanAll();
});
it('should create combined user key', async function () {
const bitgoToUserShare = await ECDSAMethods.encryptNShare(
bitgoKeyShare,
1,
userGpgKeypair.publicKey,
userGpgKeypair,
false
);
const backupToUserShare = await ECDSAMethods.encryptNShare(
backupKeyShare,
1,
userGpgKeypair.publicKey,
userGpgKeypair,
false
);
const combinedUserKey = await createCombinedKey(
userKeyShare,
[
{
nShare: bitgoToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
isbs58Encoded: false,
},
{
nShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
isbs58Encoded: false,
},
],
commonKeychain
);
combinedUserKey.commonKeychain.should.equal(commonKeychain);
combinedUserKey.signingMaterial.pShare.should.deepEqual(userKeyShare.pShare);
should.exist(combinedUserKey.signingMaterial.backupNShare);
combinedUserKey.signingMaterial.backupNShare?.should.deepEqual(backupKeyShare.nShares[1]);
combinedUserKey.signingMaterial.bitgoNShare.should.deepEqual(bitgoKeyShare.nShares[1]);
should.not.exist(combinedUserKey.signingMaterial.userNShare);
});
it('should create combined backup key', async function () {
const bitgoToBackupShare = await encryptNShare(bitgoKeyShare, 2, backupGpgKeypair.publicKey, userGpgKeypair);
const userToBackupShare = await encryptNShare(userKeyShare, 2, backupGpgKeypair.publicKey, userGpgKeypair);
const combinedBackupKey = await createCombinedKey(
backupKeyShare,
[
{
nShare: bitgoToBackupShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
nShare: userToBackupShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: userGpgKeypair.publicKey,
},
],
commonKeychain
);
combinedBackupKey.commonKeychain.should.equal(commonKeychain);
combinedBackupKey.signingMaterial.pShare.should.deepEqual(backupKeyShare.pShare);
should.exist(combinedBackupKey.signingMaterial.userNShare);
combinedBackupKey.signingMaterial.userNShare?.should.deepEqual(userKeyShare.nShares[2]);
combinedBackupKey.signingMaterial.bitgoNShare.should.deepEqual(bitgoKeyShare.nShares[2]);
should.not.exist(combinedBackupKey.signingMaterial.backupNShare);
});
it('should fail if common keychains do not match', async function () {
const bitgoToUserShare = await encryptNShare(bitgoKeyShare, 1, userGpgKeypair.publicKey, userGpgKeypair);
const backupToUserShare = await encryptNShare(backupKeyShare, 1, userGpgKeypair.publicKey, userGpgKeypair);
// this should fail to combine the keys because we pass in invalid common key chain
await createCombinedKey(
userKeyShare,
[
{
nShare: bitgoToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
nShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
'nottherightkeychain'
).should.be.rejectedWith('Common keychains do not match');
});
it('should fail if gpg keys are mismatched', async function () {
const bitgoToUserShare = await encryptNShare(bitgoKeyShare, 1, userGpgKeypair.publicKey, userGpgKeypair);
const backupToUserShare = await encryptNShare(backupKeyShare, 1, userGpgKeypair.publicKey, userGpgKeypair);
await createCombinedKey(
userKeyShare,
[
{
nShare: bitgoToUserShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
nShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
'nottherightkeychain'
).should.be.rejectedWith('Error decrypting message: Session key decryption failed.');
});
});
describe('tss signing helper function', async function () {
const bitgo = TestBitGo.decorate(BitGo, { env: 'mock' });
bitgo.initializeTestVars();
let wallet: Wallet;
const txRequest = {
txRequestId: 'randomId',
unsignedTxs: [{ signableHex: 'TOO MANY SECRETS', serializedTxHex: 'randomhex2' }],
signatureShares: [
{
from: 'bitgo',
to: 'user',
share: '',
},
],
};
const signablePayload = Buffer.from(txRequest.unsignedTxs[0].signableHex, 'hex');
before('initializes', async function () {
const baseCoin = bitgo.coin('hteth');
const walletData = {
id: '5b34252f1bf349930e34020a00000000',
coin: 'hteth',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
};
wallet = new Wallet(bitgo, baseCoin, walletData);
});
describe('createUserSignShare:', async function () {
let userToBitGoPaillierChallenge: EcdsaTypes.SerializedPaillierChallenge;
let bitgoToUserPaillierChallenge: EcdsaTypes.SerializedPaillierChallenge;
before(async function () {
userToBitGoPaillierChallenge = EcdsaTypes.serializePaillierChallenge({
p: await EcdsaPaillierProof.generateP(hexToBigInt(userKey.yShares[3].n)),
});
bitgoToUserPaillierChallenge = EcdsaTypes.serializePaillierChallenge({
p: await EcdsaPaillierProof.generateP(hexToBigInt(userKey.xShare.n)),
});
});
it('should succeed to create User SignShare', async function () {
const xShare = mpc.appendChallenge(
userKey.xShare,
mockSerializedChallengeWithProofs,
userToBitGoPaillierChallenge
);
const yShare = mpc.appendChallenge(
userKey.yShares[3],
{ ntilde: xShare.ntilde, h1: xShare.h1, h2: xShare.h2 },
bitgoToUserPaillierChallenge
);
const userSignShare = await ECDSAMethods.createUserSignShare(xShare, yShare);
userSignShare.should.have.properties(['wShare', 'kShare']);
const { wShare, kShare } = userSignShare;
wShare.should.have.property('gamma').and.be.a.String();
wShare.should.have.property('w').and.be.a.String();
wShare.should.have.property('k').and.be.a.String();
wShare.should.have.property('ck').and.be.a.String();
wShare.should.have.property('h2').and.be.a.String();
wShare.should.have.property('h1').and.be.a.String();
wShare.should.have.property('ntilde').and.be.a.String();
wShare.should.have.property('y').and.be.a.String();
wShare.should.have.property('n').and.be.a.String();
wShare.should.have.property('m').and.be.a.String();
wShare.should.have.property('l').and.be.a.String();
wShare.should.have.property('i').and.be.a.Number();
kShare['i'].should.equal(3);
kShare['j'].should.equal(1);
kShare.should.have.property('n').and.be.a.String();
kShare.should.have.property('k').and.be.a.String();
kShare.should.have.property('ntilde').and.be.a.String();
kShare.should.have.property('h1').and.be.a.String();
kShare.should.have.property('h2').and.be.a.String();
});
it('should fail if the Xshare doesnt belong to the User', async function () {
let xShare = mpc.appendChallenge(
userKey.xShare,
mockSerializedChallengeWithProofs,
userToBitGoPaillierChallenge
);
xShare = { ...xShare, i: 3 };
const yShare = mpc.appendChallenge(
userKey.yShares[3],
{
ntilde: xShare.ntilde,
h1: xShare.h1,
h2: xShare.h2,
},
bitgoToUserPaillierChallenge
);
await ECDSAMethods.createUserSignShare(xShare, yShare).should.be.rejectedWith(
`Invalid XShare, XShare doesn't belong to the User`
);
});
});
describe('createUserGammaAndMuShare:', async function () {
it('should succeed to create User Gamma Share and MuShare', async function () {
const userShare = await ECDSAMethods.createUserGammaAndMuShare(
gammaAndMuShareCreationParams.wShare,
gammaAndMuShareCreationParams.aShare
);
userShare.should.have.properties(['muShare', 'gShare']);
const { muShare, gShare } = userShare;
muShare?.i?.should.equal(3);
muShare?.j?.should.equal(1);
muShare?.should.have.property('alpha').and.be.a.String();
muShare?.should.have.property('mu').and.be.a.String();
gShare?.should.have.property('beta').and.be.a.String();
gShare?.should.have.property('nu').and.be.a.String();
});
it('should fail if the Wshare / AShare doesnt belong to the User', async function () {
const invalidWShare = { ...gammaAndMuShareCreationParams.wShare, i: 3 };
const invalidAShare = { ...gammaAndMuShareCreationParams.aShare, i: 3 };
await ECDSAMethods.createUserGammaAndMuShare(
invalidWShare,
gammaAndMuShareCreationParams.aShare
).should.be.rejectedWith(`Invalid WShare, doesn't belong to the User`);
await ECDSAMethods.createUserGammaAndMuShare(
gammaAndMuShareCreationParams.wShare,
invalidAShare
).should.be.rejectedWith(`Invalid AShare, is not from Bitgo to User`);
});
});
describe('createUserOmicronAndDeltaShare:', async function () {
it('should succeed to create User Omicron and Mu Shares', async function () {
const userShare = await ECDSAMethods.createUserOmicronAndDeltaShare(omicronAndDeltaShareCreationParams.gShare);
userShare.should.have.properties(['dShare', 'oShare']);
const { dShare, oShare } = userShare;
dShare?.i?.should.equal(3);
dShare?.j?.should.equal(1);
dShare?.should.have.property('delta').and.be.a.String();
dShare?.should.have.property('Gamma').and.be.a.String();
oShare?.should.have.property('omicron').and.be.a.String();
oShare?.should.have.property('delta').and.be.a.String();
});
it(`should fail if the gShare doesn't belong to the User`, async function () {
const invalidGShare = { ...omicronAndDeltaShareCreationParams.gShare, i: 3 };
await ECDSAMethods.createUserOmicronAndDeltaShare(invalidGShare).should.be.rejectedWith(
`Invalid GShare, doesn't belong to the User`
);
});
});
describe('createUserSignatureShare:', async function () {
afterEach(function () {
nock.cleanAll();
});
it('should succeed to create User Signature Share', async function () {
const userSignatureShare = await ECDSAMethods.createUserSignatureShare(
createUserSignatureParams.oShare,
createUserSignatureParams.dShare,
signablePayload
);
const { R, s, y, i } = userSignatureShare;
i.should.be.Number();
R.should.be.a.String();
s.should.be.a.String();
y.should.be.a.String();
});
it(`should fail if the OShare / dShare doesn't belong to the User`, async function () {
const invalidOShare = { ...createUserSignatureParams.oShare, i: 3 };
await ECDSAMethods.createUserSignatureShare(
invalidOShare,
createUserSignatureParams.dShare,
signablePayload
).should.be.rejectedWith(`Invalid OShare, doesn't belong to the User`);
const invalidDShare = { ...createUserSignatureParams.dShare, i: 3 };
await ECDSAMethods.createUserSignatureShare(
createUserSignatureParams.oShare,
invalidDShare,
signablePayload
).should.be.rejectedWith(`Invalid DShare, doesn't seem to be from BitGo`);
});
});
describe('sendSignatureShare Tests', async function () {
afterEach(function () {
nock.cleanAll();
});
const mockAShareString = ECDSAMethods.convertAShare(mockAShare).share;
const mockDShareString = ECDSAMethods.convertDShare(mockDShare).share;
const config = [
{
shareToSend: 'KShare',
mockShareToSend: mockSignRT.kShare,
mockShareToSendString: ECDSAMethods.convertKShare(mockSignRT.kShare).share,
sendType: ECDSAMethodTypes.SendShareType.KShare,
mockShareAsResponse: mockAShare,
mockShareAsResponseString: mockAShareString,
shareReceived: 'AShare',
incorrectReceivedShareString: mockAShare.k,
signerShare: 'a valid signer share',
},
{
shareToSend: 'MUShare',
mockShareToSend: { muShare: mockMuShare, dShare: mockDShareToBitgo, i: mockMuShare.i },
mockShareToSendString: `${ECDSAMethods.convertMuShare(mockMuShare).share}${ECDSAMethods.secondaryDelimeter}${
ECDSAMethods.convertDShare(mockDShareToBitgo).share
}`,
sendType: ECDSAMethodTypes.SendShareType.MUShare,
mockShareAsResponse: mockDShare,
mockShareAsResponseString: mockDShareString,
shareReceived: 'DShare',
incorrectReceivedShareString: mockDShare.Gamma,
},
];
for (let index = 0; index < config.length; index++) {
describe(`sendSignatureShare: ${config[index].shareToSend}`, async function () {
it(`should succeed to send ${config[index].shareToSend}`, async function () {
const mockSendReq = {
from: 'user',
to: 'bitgo',
share: config[index].mockShareToSendString,
} as SignatureShareRecord;
const shareRecord = {
from: 'bitgo',
to: 'user',
share: config[index].mockShareAsResponseString,
} as SignatureShareRecord;
await nockSendSignatureShare({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare: mockSendReq,
response: shareRecord,
tssType: 'ecdsa',
signerShare: config[index].signerShare,
});
txRequest.signatureShares = [shareRecord];
const response = { txRequests: [{ transactions: [{ ...txRequest }] }] };
await nockGetTxRequest({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response: response });
const responseAShare = await ECDSAMethods.sendShareToBitgo(
bitgo,
wallet.id(),
txRequest.txRequestId,
RequestType.tx,
config[index].sendType,
config[index].mockShareToSend,
config[index].signerShare
);
responseAShare.should.deepEqual(config[index].mockShareAsResponse);
});
it(`should fail if we get an invalid ${config[index].shareReceived} as response`, async function () {
const mockSendReq = {
from: 'user',
to: 'bitgo',
share: config[index].mockShareToSendString,
} as SignatureShareRecord;
const invalidSignatureShare = {
from: 'bitgo',
to: 'user',
share: JSON.stringify(config[index].incorrectReceivedShareString),
} as SignatureShareRecord;
const nock = await nockSendSignatureShare(
{
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare: mockSendReq,
response: invalidSignatureShare,
tssType: 'ecdsa',
signerShare: config[index].signerShare,
},
200
);
txRequest.signatureShares = [invalidSignatureShare];
const response = { txRequests: [{ transactions: [{ ...txRequest }] }] };
await nockGetTxRequest({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response: response });
await ECDSAMethods.sendShareToBitgo(
bitgo,
wallet.id(),
txRequest.txRequestId,
RequestType.tx,
config[index].sendType,
config[index].mockShareToSend,
config[index].signerShare
).should.be.rejectedWith(/Invalid .* share/g); // `Invalid ${shareName} share`
nock.isDone().should.equal(true);
});
});
}
});
describe('getTxRequest:', async function () {
afterEach(function () {
nock.cleanAll();
});
it('should succeed to get txRequest by id', async function () {
const response = { txRequests: [txRequest] };
const nock = await nockGetTxRequest({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const txReq = await getTxRequest(bitgo, wallet.id(), txRequest.txRequestId);
txReq.should.deepEqual(txRequest);
nock.isDone().should.equal(true);
});
it('should fail if there are no txRequests', async function () {
const response = { txRequests: [] };
const nock = await nockGetTxRequest({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
await getTxRequest(bitgo, wallet.id(), txRequest.txRequestId).should.be.rejectedWith(
'Unable to find TxRequest with id randomId'
);
nock.isDone().should.equal(true);
});
});
describe('signing share parsers and converters', function () {
afterEach(function () {
nock.cleanAll();
});
it('should successfully parse K share', function () {
const bitgoKShare = mockSignWithPaillierChallengeRT.kShare;
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: ECDSAMethods.convertKShare(mockSignWithPaillierChallengeRT.kShare).share,
} as SignatureShareRecord;
const kShare = ECDSAMethods.parseKShare(share);
kShare.should.deepEqual(bitgoKShare);
});
it('should successfully convert K share to signature share record', function () {
const bitgoKShare = mockSignWithPaillierChallengeRT.kShare;
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: `${mockSignRT.kShare.k}${ECDSAMethods.delimeter}${mockSignRT.kShare.n}${ECDSAMethods.delimeter}${
mockSignRT.kShare.ntilde
}${ECDSAMethods.delimeter}${mockSignRT.kShare.h1}${ECDSAMethods.delimeter}${mockSignRT.kShare.h2}${
ECDSAMethods.delimeter
}${mockSignRT.kShare.proof?.z || ''}${ECDSAMethods.delimeter}${mockSignRT.kShare.proof?.u || ''}${
ECDSAMethods.delimeter
}${mockSignRT.kShare.proof?.w || ''}${ECDSAMethods.delimeter}${mockSignRT.kShare.proof?.s || ''}${
ECDSAMethods.delimeter
}${mockSignRT.kShare.proof?.s1 || ''}${ECDSAMethods.delimeter}${mockSignRT.kShare.proof?.s2 || ''}${
ECDSAMethods.delimeter
}${bitgoKShare.p.join(ECDSAMethods.delimeter)}${ECDSAMethods.delimeter}${bitgoKShare.sigma.join(
ECDSAMethods.delimeter
)}`,
} as SignatureShareRecord;
const kshare = ECDSAMethods.convertKShare(bitgoKShare);
kshare.from.should.equal(share.from);
kshare.to.should.equal(share.to);
kshare.share.should.equal(share.share);
});
it('should successfully parse A share without paillier challenge', function () {
const share = {
to: SignatureShareType.USER,
from: SignatureShareType.BITGO,
share: ECDSAMethods.convertAShare(mockAShare).share,
} as SignatureShareRecord;
const aShare = ECDSAMethods.parseAShare(share);
should.exist(aShare);
aShare.should.deepEqual(mockAShare);
});
it('should successfully parse A share', function () {
const share = {
to: SignatureShareType.USER,
from: SignatureShareType.BITGO,
share: ECDSAMethods.convertAShare(mockAShare).share,
} as SignatureShareRecord;
const aShare = ECDSAMethods.parseAShare(share);
should.exist(aShare);
aShare.should.deepEqual(mockAShare);
});
it('should successfully convert A share to signature share record', function () {
const mockShare = mockAShare;
const share = {
to: SignatureShareType.USER,
from: SignatureShareType.BITGO,
share: `${mockShare.k}${ECDSAMethods.delimeter}${mockShare.alpha}${ECDSAMethods.delimeter}${mockShare.mu}${
ECDSAMethods.delimeter
}${mockShare.n}${ECDSAMethods.delimeter}${mockShare.ntilde}${ECDSAMethods.delimeter}${mockShare.h1}${
ECDSAMethods.delimeter
}${mockShare.h2}${ECDSAMethods.delimeter}${mockShare.proof?.z || ''}${ECDSAMethods.delimeter}${
mockShare.proof?.u || ''
}${ECDSAMethods.delimeter}${mockShare.proof?.w || ''}${ECDSAMethods.delimeter}${mockShare.proof?.s || ''}${
ECDSAMethods.delimeter
}${mockShare.proof?.s1 || ''}${ECDSAMethods.delimeter}${mockShare.proof?.s2 || ''}${ECDSAMethods.delimeter}${
mockShare.gammaProof?.z || ''
}${ECDSAMethods.delimeter}${mockShare.gammaProof?.zprm || ''}${ECDSAMethods.delimeter}${
mockShare.gammaProof?.t || ''
}${ECDSAMethods.delimeter}${mockShare.gammaProof?.v || ''}${ECDSAMethods.delimeter}${
mockShare.gammaProof?.w || ''
}${ECDSAMethods.delimeter}${mockShare.gammaProof?.s || ''}${ECDSAMethods.delimeter}${
mockShare.gammaProof?.s1 || ''
}${ECDSAMethods.delimeter}${mockShare.gammaProof?.s2 || ''}${ECDSAMethods.delimeter}${
mockShare.gammaProof?.t1 || ''
}${ECDSAMethods.delimeter}${mockShare.gammaProof?.t2 || ''}${ECDSAMethods.delimeter}${
mockShare.gammaProof?.u || ''
}${ECDSAMethods.delimeter}${mockShare.gammaProof?.x || ''}${ECDSAMethods.delimeter}${
mockShare.wProof?.z || ''
}${ECDSAMethods.delimeter}${mockShare.wProof?.zprm || ''}${ECDSAMethods.delimeter}${
mockShare.wProof?.t || ''
}${ECDSAMethods.delimeter}${mockShare.wProof?.v || ''}${ECDSAMethods.delimeter}${mockShare.wProof?.w || ''}${
ECDSAMethods.delimeter
}${mockShare.wProof?.s || ''}${ECDSAMethods.delimeter}${mockShare.wProof?.s1 || ''}${ECDSAMethods.delimeter}${
mockShare.wProof?.s2 || ''
}${ECDSAMethods.delimeter}${mockShare.wProof?.t1 || ''}${ECDSAMethods.delimeter}${
mockShare.wProof?.t2 || ''
}${ECDSAMethods.delimeter}${mockShare.wProof?.u || ''}${ECDSAMethods.delimeter}${mockShare.wProof?.x || ''}${
ECDSAMethods.delimeter
}${mockShare.sigma!.join(ECDSAMethods.delimeter)}`,
} as SignatureShareRecord;
const aShare = ECDSAMethods.convertAShare(mockShare);
aShare.from.should.equal(share.from);
aShare.to.should.equal(share.to);
aShare.share.should.equal(share.share);
});
it('should successfully parse Mu share', function () {
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: ECDSAMethods.convertMuShare(mockMuShare).share,
} as SignatureShareRecord;
const muShare = ECDSAMethods.parseMuShare(share);
muShare.i.should.equal(mockMuShare.i);
muShare.j.should.equal(mockMuShare.j);
muShare.alpha.should.equal(mockMuShare.alpha);
muShare.mu.should.equal(mockMuShare.mu);
});
it('should successfully convert Mu share to signature share record', function () {
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: `${mockMuShare.alpha}${ECDSAMethods.delimeter}${mockMuShare.mu}${ECDSAMethods.delimeter}${
mockMuShare.gammaProof?.z || ''
}${ECDSAMethods.delimeter}${mockMuShare.gammaProof?.zprm || ''}${ECDSAMethods.delimeter}${
mockMuShare.gammaProof?.t || ''
}${ECDSAMethods.delimeter}${mockMuShare.gammaProof?.v || ''}${ECDSAMethods.delimeter}${
mockMuShare.gammaProof?.w || ''
}${ECDSAMethods.delimeter}${mockMuShare.gammaProof?.s || ''}${ECDSAMethods.delimeter}${
mockMuShare.gammaProof?.s1 || ''
}${ECDSAMethods.delimeter}${mockMuShare.gammaProof?.s2 || ''}${ECDSAMethods.delimeter}${
mockMuShare.gammaProof?.t1 || ''
}${ECDSAMethods.delimeter}${mockMuShare.gammaProof?.t2 || ''}${ECDSAMethods.delimeter}${
mockMuShare.gammaProof?.u || ''
}${ECDSAMethods.delimeter}${mockMuShare.gammaProof?.x || ''}${ECDSAMethods.delimeter}${
mockMuShare.wProof?.z || ''
}${ECDSAMethods.delimeter}${mockMuShare.wProof?.zprm || ''}${ECDSAMethods.delimeter}${
mockMuShare.wProof?.t || ''
}${ECDSAMethods.delimeter}${mockMuShare.wProof?.v || ''}${ECDSAMethods.delimeter}${
mockMuShare.wProof?.w || ''
}${ECDSAMethods.delimeter}${mockMuShare.wProof?.s || ''}${ECDSAMethods.delimeter}${
mockMuShare.wProof?.s1 || ''
}${ECDSAMethods.delimeter}${mockMuShare.wProof?.s2 || ''}${ECDSAMethods.delimeter}${
mockMuShare.wProof?.t1 || ''
}${ECDSAMethods.delimeter}${mockMuShare.wProof?.t2 || ''}${ECDSAMethods.delimeter}${
mockMuShare.wProof?.u || ''
}${ECDSAMethods.delimeter}${mockMuShare.wProof?.x || ''}`,
} as SignatureShareRecord;
const muShare = ECDSAMethods.convertMuShare(mockMuShare);
muShare.from.should.equal(share.from);
muShare.to.should.equal(share.to);
muShare.share.should.equal(share.share);
});
it('should successfully parse D share', function () {
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: ECDSAMethods.convertDShare(mockDShareToBitgo).share,
} as SignatureShareRecord;
const dShare = ECDSAMethods.parseDShare(share);
dShare.i.should.equal(mockDShareToBitgo.i);
dShare.j.should.equal(mockDShareToBitgo.j);
dShare.delta.should.equal(mockDShareToBitgo.delta);
dShare.Gamma.should.equal(mockDShareToBitgo.Gamma);
});
it('should successfully convert D share to signature share record', function () {
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: `${mockDShareToBitgo.delta}${ECDSAMethods.delimeter}${mockDShareToBitgo.Gamma}`,
} as SignatureShareRecord;
const dShare = ECDSAMethods.convertDShare(mockDShareToBitgo);
dShare.from.should.equal(share.from);
dShare.to.should.equal(share.to);
dShare.share.should.equal(share.share);
});
it('should successfully parse S and D share', function () {
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: `${mockSShareFromUser.R}${ECDSAMethods.delimeter}${mockSShareFromUser.s}${ECDSAMethods.delimeter}${mockSShareFromUser.y}${ECDSAMethods.secondaryDelimeter}${mockDShareToBitgo.delta}${ECDSAMethods.delimeter}${mockDShareToBitgo.Gamma}`,
} as SignatureShareRecord;
const { sShare, dShare } = ECDSAMethods.parseSDShare(share);
sShare.i.should.equal(3);
sShare.R.should.equal(mockSShareFromUser.R);
sShare.s.should.equal(mockSShareFromUser.s);
sShare.y.should.equal(mockSShareFromUser.y);
dShare.i.should.equal(mockDShareToBitgo.i);
dShare.j.should.equal(mockDShareToBitgo.j);
dShare.delta.should.equal(mockDShareToBitgo.delta);
dShare.Gamma.should.equal(mockDShareToBitgo.Gamma);
});
it('should successfully convert S and D share to signature share record', function () {
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: `${mockSShareFromUser.R}${ECDSAMethods.delimeter}${mockSShareFromUser.s}${ECDSAMethods.delimeter}${mockSShareFromUser.y}${ECDSAMethods.secondaryDelimeter}${mockDShareToBitgo.delta}${ECDSAMethods.delimeter}${mockDShareToBitgo.Gamma}`,
} as SignatureShareRecord;
const sdShare = ECDSAMethods.convertSDShare({ sShare: mockSShareFromUser, dShare: mockDShareToBitgo });
sdShare.from.should.equal(share.from);
sdShare.to.should.equal(share.to);
sdShare.share.should.equal(share.share);
});
it('should successfully parse signature share', function () {
const share = {
to: SignatureShareType.USER,
from: SignatureShareType.BITGO,
share: `${mockSShareFromUser.R}${ECDSAMethods.delimeter}${mockSShareFromUser.s}${ECDSAMethods.delimeter}${mockSShareFromUser.y}`,
} as SignatureShareRecord;
const signature = ECDSAMethods.parseSignatureShare(share);
signature.i.should.equal(1);
signature.R.should.equal(mockSShareFromUser.R);
signature.s.should.equal(mockSShareFromUser.s);
signature.y.should.equal(mockSShareFromUser.y);
});
it('should succuesfully parse combined signature', function () {
const mockCombinedSignature = mpc.constructSignature([mockSShareFromUser, mockSShare]);
const share = {
to: SignatureShareType.USER,
from: SignatureShareType.BITGO,
share: `${mockCombinedSignature.recid}${ECDSAMethods.delimeter}${mockCombinedSignature.r}${ECDSAMethods.delimeter}${mockCombinedSignature.s}${ECDSAMethods.delimeter}${mockCombinedSignature.y}`,
} as SignatureShareRecord;
const signature = ECDSAMethods.parseCombinedSignature(share);
signature.recid.should.equal(mockCombinedSignature.recid);
signature.r.should.equal(mockCombinedSignature.r);
signature.s.should.equal(mockCombinedSignature.s);
signature.y.should.equal(mockCombinedSignature.y);
});
it('should successfully convert signature share to signature share record', function () {
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.USER,
share: `${mockSShareFromUser.R}${ECDSAMethods.delimeter}${mockSShareFromUser.s}${ECDSAMethods.delimeter}${mockSShareFromUser.y}`,
} as SignatureShareRecord;
const signatureShare = ECDSAMethods.convertSignatureShare(
mockSShareFromUser,
ECDSAMethods.getParticipantIndex('user'),
ECDSAMethods.getParticipantIndex('bitgo')
);
signatureShare.from.should.equal(share.from);
signatureShare.to.should.equal(share.to);
signatureShare.share.should.equal(share.share);
});
it('should successfully convert B share to signature share record', function () {
const bShare = mockedBitgoBShare.bShare;
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.BITGO,
share: `${bShare.beta}${ECDSAMethods.delimeter}${bShare.gamma}${ECDSAMethods.delimeter}${bShare.k}${
ECDSAMethods.delimeter
}${bShare.nu}${ECDSAMethods.delimeter}${bShare.w}${ECDSAMethods.delimeter}${bShare.y}${
ECDSAMethods.delimeter
}${bShare.l}${ECDSAMethods.delimeter}${bShare.m}${ECDSAMethods.delimeter}${bShare.n}${
ECDSAMethods.delimeter
}${bShare.ntilde}${ECDSAMethods.delimeter}${bShare.h1}${ECDSAMethods.delimeter}${bShare.h2}${
ECDSAMethods.delimeter
}${bShare.ck}${ECDSAMethods.delimeter}${bShare.p!.join(ECDSAMethods.delimeter)}`,
} as SignatureShareRecord;
const signatureShare = ECDSAMethods.convertBShare(bShare);
signatureShare.from.should.equal(share.from);
signatureShare.to.should.equal(share.to);
signatureShare.share.should.equal(share.share);
});
it('should successfully parse B share', function () {
const bShare = mockedBitgoBShare.bShare;
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.BITGO,
share: ECDSAMethods.convertBShare(mockedBitgoBShare.bShare).share,
} as SignatureShareRecord;
const parsedBShare = ECDSAMethods.parseBShare(share);
parsedBShare.should.deepEqual(bShare);
});
it('should successfully convert O share to signature share record', function () {
const oShare = mockedBitgoOAndDShare.oShare;
const delimeter = ECDSAMethods.delimeter;
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.BITGO,
share: `${oShare.Gamma}${delimeter}${oShare.delta}${delimeter}${oShare.k}${delimeter}${oShare.omicron}${delimeter}${oShare.y}`,
} as SignatureShareRecord;
const oShareSigRecord = ECDSAMethods.convertOShare(oShare);
oShareSigRecord.from.should.equal(share.from);
oShareSigRecord.to.should.equal(share.to);
oShareSigRecord.share.should.equal(share.share);
});
it('should successfully parse O share', function () {
const oShare = mockedBitgoOAndDShare.oShare;
const delimeter = ECDSAMethods.delimeter;
const share = {
to: SignatureShareType.BITGO,
from: SignatureShareType.BITGO,
share: `${oShare.Gamma}${delimeter}${oShare.delta}${delimeter}${oShare.k}${delimeter}${oShare.omicron}${delimeter}${oShare.y}`,
} as SignatureShareRecord;
const parsedOShare = ECDSAMethods.parseOShare(share);
parsedOShare.i.should.equal(oShare.i);
parsedOShare.y.should.equal(oShare.y);
parsedOShare.k.should.equal(oShare.k);
parsedOShare.omicron.should.equal(oShare.omicron);
parsedOShare.delta.should.equal(oShare.delta);
parsedOShare.Gamma.should.equal(oShare.Gamma);
});
});
});
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!