Skip to content

Commit d7284e8

Browse files
Merge remote-tracking branch 'origin/WP-2860/add-examples-for-tss-recovery'
2 parents 9ead0c0 + 06aeac1 commit d7284e8

File tree

5 files changed

+101
-2
lines changed

5 files changed

+101
-2
lines changed

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ In this directory, you can find examples on how to use the BitGoJS SDK with Type
1717
- [List Wallet Shares](./ts/list-wallet-shares.ts)
1818
- [List Wallet Transfers](./ts/list-wallet-transfers.ts)
1919
- [List Wallets](./ts/list-wallets.ts)
20+
- [Recover TSS](./ts/tss-recovery.ts)
2021
- [Recover XRP](./ts/recover-xrp.ts)
2122
- [Resend Wallet Share Invite](./ts/resend-wallet-share-invite.ts)
2223
- [Send Wallet Transaction](./ts/send-wallet-transaction.ts)

examples/ts/tss-recovery/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Verifying user and backup key signing on a TSS Keycard Examples
2+
3+
## Prerequisites
4+
5+
Install yarn and nvm.
6+
7+
## Running the Examples
8+
9+
Navigate into `examples/ts/tss-recovery` and run `yarn install`.
10+
11+
```
12+
$ cd examples/ts/tss-recovery
13+
$ nvm use
14+
$ yarn install
15+
```
16+
17+
Use `npx ts-node` to run the desired example:
18+
19+
```
20+
$ npx ts-node eddsa-recovery.ts
21+
```
22+
23+
or,
24+
25+
```
26+
$ yarn test:ecdsa
27+
```
28+
29+
```
30+
$ yarn test:eddsa
31+
```
32+
33+
**Note**: Complete the required TODO's for each script, i.e. replace the content of backupKey.txt and userKey.txt with the appropriate keys from your keycard and fill in the commonkeychain + wallet passphrase in the script you want to run.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Eddsa } from '@bitgo/sdk-core';
2+
import * as fs from 'fs';
3+
import assert = require('assert');
4+
import { bigIntFromBufferBE, bigIntFromBufferLE, Ed25519Bip32HdTree } from '@bitgo/sdk-lib-mpc';
5+
import sjcl = require('sjcl');
6+
7+
const sampleMessage = "Hello, World!";
8+
const derivationPath = "m/0";
9+
// 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.
10+
const commonKeyChain = "<Public key from key card>";
11+
const walletPassphrase = "<Wallet passphrase>";
12+
13+
14+
async function testRecoveryEddsaTss() {
15+
const userKey = fs.readFileSync('userKey.txt', 'utf8').replace(/(\r\n|\n|\r)/gm, "");
16+
const backupKey = fs.readFileSync('backupKey.txt', 'utf8').replace(/(\r\n|\n|\r)/gm, "");
17+
// Produce a signature.
18+
const hdTree = await Ed25519Bip32HdTree.initialize();
19+
const MPC = await Eddsa.initialize(hdTree);
20+
const userSigningMaterial = JSON.parse(sjcl.decrypt(walletPassphrase, userKey));
21+
const backupSigningMaterial = JSON.parse(sjcl.decrypt(walletPassphrase, backupKey));
22+
// 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.
23+
const userSubkey = MPC.keyDerive(
24+
userSigningMaterial.uShare,
25+
[userSigningMaterial.bitgoYShare, userSigningMaterial.backupYShare],
26+
derivationPath,
27+
);
28+
// Combine the offset key shares from user -> backup, bitgo -> backup, and the backup's private share to form the backup signing key.
29+
const backupSubkey = MPC.keyCombine(backupSigningMaterial.uShare, [
30+
userSubkey.yShares[2],
31+
backupSigningMaterial.bitgoYShare,
32+
]);
33+
const messageBuffer = Buffer.from(sampleMessage, 'utf8');
34+
// Partial Sign the message with the user and backup signing keys.
35+
const userSignShare = MPC.signShare(messageBuffer, userSubkey.pShare, [userSubkey.yShares[2]]);
36+
const backupSignShare = MPC.signShare(messageBuffer, backupSubkey.pShare, [backupSubkey.jShares[1]]);
37+
const userSign = MPC.sign(
38+
messageBuffer,
39+
userSignShare.xShare,
40+
[backupSignShare.rShares[1]],
41+
[userSigningMaterial.bitgoYShare]
42+
);
43+
const backupSign = MPC.sign(
44+
messageBuffer,
45+
backupSignShare.xShare,
46+
[userSignShare.rShares[2]],
47+
[backupSigningMaterial.bitgoYShare]
48+
);
49+
// Combine partial signatures to form the final signature.
50+
const signature = MPC.signCombine([userSign, backupSign]);
51+
const signatureBuffer = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
52+
// Deriving the public key at path m/0 from the common key chain.
53+
const derivedPub = hdTree.publicDerive(
54+
{
55+
pk: bigIntFromBufferLE(Buffer.from(commonKeyChain.slice(0, 64), 'hex')),
56+
chaincode: bigIntFromBufferBE(Buffer.from(commonKeyChain.slice(64), 'hex')),
57+
},
58+
derivationPath
59+
);
60+
// Verify the signature.
61+
const isSignatureValid = Eddsa.curve.verify(messageBuffer, signatureBuffer, derivedPub.pk);
62+
assert(isSignatureValid, "Signature is not valid.");
63+
}
64+
65+
testRecoveryEddsaTss().catch((e) => console.error(e));

examples/ts/tss-recovery/mpcv2-recovery.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import assert = require('assert');
66
import { bigIntFromBufferBE, bigIntToBufferBE, HDTree, Secp256k1Bip32HdTree } from '@bitgo/sdk-lib-mpc';
77

88
const sampleMessage = "Hello, World!";
9-
// 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.
9+
// 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.
1010
const commonKeyChain = "<Public key from key card>";
1111
const walletPassphrase = "<Wallet passphrase>";
1212

examples/ts/tss-recovery/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "TSS User <> Backup keycard signing",
55
"scripts": {
66
"test:ecdsa": "ts-node mpcv2-recovery.ts",
7-
"test:eddsa": "ts-node TBD"
7+
"test:eddsa": "ts-node eddsa-recovery.ts"
88
},
99
"dependencies": {
1010
"@bitgo/sdk-core": "28.10.0",

0 commit comments

Comments
 (0)