Skip to content

Commit

Permalink
Merge pull request #15 from tka85/fix-export-and-improve-examples
Browse files Browse the repository at this point in the history
Improves examples + adds index.js
  • Loading branch information
ilap authored Feb 13, 2020
2 parents 0ce6b89 + aeb5bc5 commit 4d4675c
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 25 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ npm install slip39
See `example/main.js`

``` javascript
const slip39 = require('./src/slip39.js');
const slip39 = require('../src/slip39.js');
const assert = require('assert');
// threshold (N) number of group shares required to reconstruct the master secret.
const threshold = 2;
Expand Down
116 changes: 94 additions & 22 deletions example/main.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
const slip39 = require('../src/slip39.js');
const assert = require('assert');
// threshold (N) number of group shares required to reconstruct the master secret.
// threshold (N) number of group-shares required to reconstruct the master secret.
const threshold = 2;
const masterSecret = 'ABCDEFGHIJKLMNOP'.encodeHex();
const passphrase = 'TREZOR';

function recover(groupShares, pass) {
const recoveredSecret = slip39.recoverSecret(groupShares, pass);
console.log('\tMaster secret: ' + masterSecret.decodeHex());
console.log('\tRecovered one: ' + recoveredSecret.decodeHex());
assert(masterSecret.decodeHex() === recoveredSecret.decodeHex());
}

function printShares(shares) {
shares.forEach((s, i) => console.log(`\t${i + 1}) ${s}`));
}

/**
* 4 groups shares.
* = two for Alice
* = one for friends and
* = one for family members
* Two of these group shares are required to reconstruct the master secret.
* 4 groups shares:
* = two for Alice
* = one for friends and
* = one for family members
* Any two of these four group-shares are required to reconstruct the master secret.
* All possible master secret recovery combinations; goal is to reconstruct any 2-of-4 group-shares:
* Case 1) [requires 1 person: Alice] Alice alone with her 1-of-1 member-shares reconstructs both the 1st and 2nd group-shares
* Case 2) [requires 4 persons: Alice + any 3 of her 5 friends] Alice with her 1-of-1 member-shares reconstructs 1st (or 2nd) group-share + any 3-of-5 friend member-shares reconstruct the 3rd group-share
* Case 3) [requires 3 persons: Alice + any 2 of her 6 family relatives] Alice with her 1-of-1 member-shares reconstructs 1st (or 2nd) group-share + any 2-of-6 family member-shares reconstruct the 4th group-share
* Case 4) [requires 5 persons: any 3 of her 5 friends + any 2 of her 6 family relatives] any 3-of-5 friend member-shares reconstruct the 3rd group-share + any 2-of-6 family member-shares reconstruct the 4th group-share
*/
const groups = [
// Alice group shares. 1 is enough to reconstruct a group share,
// therefore she needs at least two group shares to reconstruct the master secret.
// Alice group-shares. 1 is enough to reconstruct a group-share,
// therefore she needs at least two group-shares to reconstruct the master secret.
[1, 1],
[1, 1],
// 3 of 5 Friends' shares are required to reconstruct this group share
// 3 of 5 Friends' shares are required to reconstruct this group-share
[3, 5],
// 2 of 6 Family's shares are required to reconstruct this group share
// 2 of 6 Family's shares are required to reconstruct this group-share
[2, 6]
];

Expand All @@ -29,19 +45,75 @@ const slip = slip39.fromArray(masterSecret, {
groups: groups
});

// One of Alice's share
const aliceShare = slip.fromPath('r/0').mnemonics;
let neededShares;
let aliceBothGroupShares;
let aliceFirstGroupShare;
let aliceSecondGroupShare;
let friendGroupShares;
let familyGroupShares;


/*
* Example of Case 1
*/
// The 1st, and only, member-share (member 0) of the 1st group-share (group 0) + the 1st, and only, member-share (member 0) of the 2nd group-share (group 1)
aliceBothGroupShares = slip.fromPath('r/0/0').mnemonics
.concat(slip.fromPath('r/1/0').mnemonics);

neededShares = aliceBothGroupShares;

console.log(`\n* Shares used by Alice alone for restoring the master secret (total of ${neededShares.length} member-shares):`);
printShares(neededShares);
recover(neededShares, passphrase);

/*
* Example of Case 2
*/
// The 1st, and only, member-share (member 0) of the 2nd group-share (group 1)
aliceSecondGroupShare = slip.fromPath('r/1/0').mnemonics;

// ...plus the 3rd member-share (member 2) + the 4th member-share (member 3) + the 5th member-share (member 4) of the 3rd group-share (group 2)
friendGroupShares = slip.fromPath('r/2/2').mnemonics
.concat(slip.fromPath('r/2/3').mnemonics)
.concat(slip.fromPath('r/2/4').mnemonics);

// and any two of family's shares.
const familyShares = slip.fromPath('r/3/1').mnemonics
.concat(slip.fromPath('r/3/3').mnemonics);
neededShares = aliceSecondGroupShare.concat(friendGroupShares);

console.log(`\n* Shares used by Alice + 3 friends for restoring the master secret (total of ${neededShares.length} member-shares):`);
printShares(neededShares);
recover(neededShares, passphrase);


/*
* Example of Case 3
*/
// The 1st, and only, member-share (member 0) of the 1st group-share (group 0)
aliceFirstGroupShare = slip.fromPath('r/0/0').mnemonics;

// ...plus the 2nd member-share (member 1) + the 3rd member-share (member 2) of the 4th group-share (group 3)
familyGroupShares = slip.fromPath('r/3/1').mnemonics
.concat(slip.fromPath('r/3/2').mnemonics);

neededShares = aliceFirstGroupShare.concat(familyGroupShares);

console.log(`\n* Shares used by Alice + 2 family members for restoring the master secret (total of ${neededShares.length} member-shares):`);
printShares(neededShares);
recover(neededShares, passphrase);

/*
* Example of Case 4
*/
// The 3rd member-share (member 2) + the 4th member-share (member 3) + the 5th member-share (member 4) of the 3rd group-share (group 2)
friendGroupShares = slip.fromPath('r/2/2').mnemonics
.concat(slip.fromPath('r/2/3').mnemonics)
.concat(slip.fromPath('r/2/4').mnemonics);

const allShares = aliceShare.concat(familyShares);
// ...plus the 2nd member-share (member 1) + the 3rd member-share (member 2) of the 4th group-share (group 3)
familyGroupShares = slip.fromPath('r/3/1').mnemonics
.concat(slip.fromPath('r/3/2').mnemonics);

console.log('Shares used for restoring the master secret:');
allShares.forEach((s) => console.log(s));
neededShares = friendGroupShares.concat(familyGroupShares);

const recoveredSecret = slip39.recoverSecret(allShares, passphrase);
console.log('Master secret: ' + masterSecret.decodeHex());
console.log('Recovered one: ' + recoveredSecret.decodeHex());
assert(masterSecret.decodeHex() === recoveredSecret.decodeHex());
console.log(`\n* Shares used by 3 friends + 2 family members for restoring the master secret (total of ${neededShares.length} member-shares):`);
printShares(neededShares);
recover(neededShares, passphrase);
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./src/slip39');
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "slip39",
"version": "0.1.6",
"description": "The javascript implementation of the SLIP39 for Shamir's Secret-Sharing for Mnemonic Codes.",
"main": "main.js",
"main": "index.js",
"scripts": {
"test": "mocha"
},
Expand All @@ -23,4 +23,4 @@
"devDependencies": {
"mocha": "^6.2.0"
}
}
}

0 comments on commit 4d4675c

Please sign in to comment.