Skip to content

Commit

Permalink
feat(key-card): add example for EdDSA TSS recovery
Browse files Browse the repository at this point in the history
TICKET: WP-2860
  • Loading branch information
islamaminBitGo committed Oct 18, 2024
1 parent 15fe12b commit 07f1ba8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
65 changes: 65 additions & 0 deletions examples/ts/tss-recovery/eddsa-recovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Eddsa } from '@bitgo/sdk-core';
import * as fs from 'fs';
import assert = require('assert');
import { bigIntFromBufferBE, bigIntFromBufferLE, Ed25519Bip32HdTree } from '@bitgo/sdk-lib-mpc';
import sjcl = require('sjcl');

const sampleMessage = "Hello, World!";
const derivationPath = "m/0";
// TODO: Replace the following variables with your own values. Moreover, copy the encrypted user and backup keys from the key card into the userKey.txt and backupKey.txt files.
const commonKeyChain = "<Public key from key card>";
const walletPassphrase = "<Wallet passphrase>";


async function testRecoveryEddsaTss() {
const userKey = fs.readFileSync('userKey.txt', 'utf8').replace(/(\r\n|\n|\r)/gm, "");
const backupKey = fs.readFileSync('backupKey.txt', 'utf8').replace(/(\r\n|\n|\r)/gm, "");
// Produce a signature.
const hdTree = await Ed25519Bip32HdTree.initialize();
const MPC = await Eddsa.initialize(hdTree);
const userSigningMaterial = JSON.parse(sjcl.decrypt(walletPassphrase, userKey));
const backupSigningMaterial = JSON.parse(sjcl.decrypt(walletPassphrase, backupKey));
// Combine the key shares from backup -> user, bitgo -> user, and the user's private share to form the backup signing key offset by the derivation path.
const userSubkey = MPC.keyDerive(
userSigningMaterial.uShare,
[userSigningMaterial.bitgoYShare, userSigningMaterial.backupYShare],
derivationPath,
);
// Combine the offset key shares from user -> backup, bitgo -> backup, and the backup's private share to form the backup signing key.
const backupSubkey = MPC.keyCombine(backupSigningMaterial.uShare, [
userSubkey.yShares[2],
backupSigningMaterial.bitgoYShare,
]);
const messageBuffer = Buffer.from(sampleMessage, 'utf8');
// Partial Sign the message with the user and backup signing keys.
const userSignShare = MPC.signShare(messageBuffer, userSubkey.pShare, [userSubkey.yShares[2]]);
const backupSignShare = MPC.signShare(messageBuffer, backupSubkey.pShare, [backupSubkey.jShares[1]]);
const userSign = MPC.sign(
messageBuffer,
userSignShare.xShare,
[backupSignShare.rShares[1]],
[userSigningMaterial.bitgoYShare]
);
const backupSign = MPC.sign(
messageBuffer,
backupSignShare.xShare,
[userSignShare.rShares[2]],
[backupSigningMaterial.bitgoYShare]
);
// Combine partial signatures to form the final signature.
const signature = MPC.signCombine([userSign, backupSign]);
const signatureBuffer = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
// Deriving the public key at path m/0 from the common key chain.
const derivedPub = hdTree.publicDerive(
{
pk: bigIntFromBufferLE(Buffer.from(commonKeyChain.slice(0, 64), 'hex')),
chaincode: bigIntFromBufferBE(Buffer.from(commonKeyChain.slice(64), 'hex')),
},
derivationPath
);
// Verify the signature.
const isSignatureValid = Eddsa.curve.verify(messageBuffer, signatureBuffer, derivedPub.pk);
assert(isSignatureValid, "Signature is not valid.");
}

testRecoveryEddsaTss().catch((e) => console.error(e));
2 changes: 1 addition & 1 deletion examples/ts/tss-recovery/mpcv2-recovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import assert = require('assert');
import { bigIntFromBufferBE, bigIntToBufferBE, HDTree, Secp256k1Bip32HdTree } from '@bitgo/sdk-lib-mpc';

const sampleMessage = "Hello, World!";
// Replace the following variables with your own values. Moreover, copy the encrypted user and backup keys from the key card into the userKey.txt and backupKey.txt files.
// TODO: Replace the following variables with your own values. Moreover, copy the encrypted user and backup keys from the key card into the userKey.txt and backupKey.txt files.
const commonKeyChain = "<Public key from key card>";
const walletPassphrase = "<Wallet passphrase>";

Expand Down
2 changes: 1 addition & 1 deletion examples/ts/tss-recovery/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "TSS User <> Backup keycard signing",
"scripts": {
"test:ecdsa": "ts-node mpcv2-recovery.ts",
"test:eddsa": "ts-node TBD"
"test:eddsa": "ts-node eddsa-recovery.ts"
},
"dependencies": {
"@bitgo/sdk-core": "28.10.0",
Expand Down

0 comments on commit 07f1ba8

Please sign in to comment.