@@ -9066,7 +9073,7 @@ ninja.wallets.splitwallet = {
open: function () {
document.getElementById("splitarea").style.display = "block";
secrets.setRNG();
- secrets.init(7);
+ secrets.init(7); // 7 bits allows for up to 127 shares
},
close: function () {
@@ -9076,12 +9083,16 @@ ninja.wallets.splitwallet = {
mkOutputRow: function (s, id, lbltxt) {
var row = document.createElement("div");
var label = document.createElement("label");
- label.innerHTML = lbltxt + s;
+ label.innerHTML = lbltxt;
var qr = document.createElement("div");
+ var output = document.createElement("span");
+ output.setAttribute("class", "output");
+ output.innerHTML = s;
qr.setAttribute("id", id);
row.setAttribute("class", "splitsharerow");
row.appendChild(label);
+ row.appendChild(output);
row.appendChild(qr);
row.appendChild(document.createElement("br"));
@@ -9102,13 +9113,12 @@ ninja.wallets.splitwallet = {
// Split a private key and update information in the HTML
splitKey: function () {
try {
- var key = new Bitcoin.ECKey(false);
- var bitcoinAddress = key.getBitcoinAddress();
-
var numshares = parseInt(document.getElementById('splitshares').value);
var threshold = parseInt(document.getElementById('splitthreshold').value);
- var hexKey = Crypto.util.bytesToHex(key.getBitcoinPrivateKeyByteArray());
- var shares = secrets.share(hexKey, numshares, threshold).map(this.hexToBytes).map(Bitcoin.Base58.encode);
+ var key = new Bitcoin.ECKey(false);
+ var bitcoinAddress = key.getBitcoinAddress();
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key.getBitcoinHexFormat(), numshares, threshold);
+
var output = document.createElement("div");
output.setAttribute("id", "splitoutput");
var m = {};
@@ -9130,49 +9140,33 @@ ninja.wallets.splitwallet = {
catch (e) {
// browser does not have sufficient JavaScript support to generate a bitcoin address
alert(e);
- document.getElementById("btcaddress").innerHTML = "error";
- document.getElementById("btcprivwif").innerHTML = "error";
- document.getElementById("qrcode_public").innerHTML = "";
- document.getElementById("qrcode_private").innerHTML = "";
}
},
// Combine shares of a private key to retrieve the key
combineShares: function () {
try {
- var element = document.getElementById("combineoutput");
- if (element != null) element.parentNode.removeChild(element);
-
+ document.getElementById("combinedprivatekey").innerHTML = "";
var shares = document.getElementById("combineinput").value.trim().split(/\W+/);
-
- var combined = secrets.combine(shares.map(Bitcoin.Base58.decode).map(Crypto.util.bytesToHex).map(this.stripLeadZeros));
-
- var privkeyBase58 = new Bitcoin.ECKey(this.hexToBytes(combined)).getBitcoinWalletImportFormat();
- var output = document.createElement("div");
- output.setAttribute("id", "combineoutput");
- var txt = document.createElement("input");
- txt.setAttribute("id", "combineoutputtext");
- txt.setAttribute("value", privkeyBase58);
- txt.setAttribute("size", 55);
- var lbl = document.createElement("label");
- lbl.innerHTML = "Private key";
- output.appendChild(lbl);
- output.appendChild(txt);
- document.getElementById("combinecommands").appendChild(output);
+ var combinedBytes = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var privkeyBase58 = new Bitcoin.ECKey(combinedBytes).getBitcoinWalletImportFormat();
+ document.getElementById("combinedprivatekey").innerHTML = privkeyBase58;
}
catch (e) {
alert(e);
}
},
+ // generate shares and format them in base58
getFormattedShares: function (key, numshares, threshold) {
var shares = secrets.share(key, numshares, threshold).map(ninja.wallets.splitwallet.hexToBytes).map(Bitcoin.Base58.encode);
return shares;
},
+ // combine base58 formatted shares and return a bitcoin byte array
combineFormattedShares: function (shares) {
var combined = secrets.combine(shares.map(Bitcoin.Base58.decode).map(Crypto.util.bytesToHex).map(ninja.wallets.splitwallet.stripLeadZeros));
- return combined;
+ return ninja.wallets.splitwallet.hexToBytes(combined);
},
openCloseStep: function (num) {
@@ -9654,46 +9648,107 @@ ninja.wallets.splitwallet = {
},
// test split wallet
- testSplitAndCombinePrivateKey: function () {
+ testSplitAndCombinePrivateKey2of2: function () {
+ // lowercase hex key
+ var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
+ var numshares = 2;
+ var threshold = 2;
+ secrets.setRNG();
+ secrets.init(7);
+
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var btcKey = new Bitcoin.ECKey(combined);
+
+ if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
+ return false;
+ }
+ return true;
+ },
+ // Example use case #1:
+ // Division of 3 shares:
+ // 1 share in a safety deposit box ("Box")
+ // 1 share at Home
+ // 1 share at Work
+ // Threshold of 2 can be redeemed in these permutations
+ // Home + Box
+ // Work + Box
+ // Home + Work
+ testSplitAndCombinePrivateKey2of3: function () {
+ // lowercase hex key
+ var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
+ var numshares = 3;
+ var threshold = 2;
+ secrets.setRNG();
+ secrets.init(7);
+
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ shares.shift();
+ var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var btcKey = new Bitcoin.ECKey(combined);
+
+ if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
+ return false;
+ }
+ return true;
+ },
+ testSplitAndCombinePrivateKey2of4: function () {
+ // uppercase hex key
var key = "292665C3872418ADF1DA7FFA3A646F2F0602246DA6098A91D229C32150F2718B"; //5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb
var numshares = 4;
var threshold = 2;
+ secrets.setRNG();
+ secrets.init(7);
+
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ shares.shift();
+ shares.shift();
+ var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var btcKey = new Bitcoin.ECKey(combined);
- var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold); //secrets.share(key, numshares, threshold).map(ninja.wallets.splitwallet.hexToBytes).map(Bitcoin.Base58.encode);
- var combined = ninja.wallets.splitwallet.combineFormattedShares(shares); // secrets.combine(shares.map(Bitcoin.Base58.decode).map(Crypto.util.bytesToHex).map(ninja.wallets.splitwallet.stripLeadZeros));
-
- var btcKey = new Bitcoin.ECKey(ninja.wallets.splitwallet.hexToBytes(combined));
if (btcKey.getBitcoinHexFormat() != key) {
return false;
}
return true;
},
- testSplitAndCombinePrivateKey2: function () {
- var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da 5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
- var numshares = 4;
- var threshold = 2;
+ // Example use case #2:
+ // Division of 13 shares:
+ // 4 shares in a safety deposit box ("Box")
+ // 3 shares with good friend Angie
+ // 3 shares with good friend Fred
+ // 3 shares with Self at home or office
+ // Threshold of 7 can be redeemed in these permutations
+ // Self + Box (no trust to spend your coins but your friends are backing up your shares)
+ // Angie + Box (Angie will send btc to executor of your will)
+ // Fred + Box (if Angie hasn't already then Fred will send btc to executor of your will)
+ // Angie + Fred + Self (bank fire/theft then you with both your friends can spend the coins)
+ testSplitAndCombinePrivateKey7of13: function () {
+ var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da";
+ var numshares = 12;
+ var threshold = 7;
+ secrets.setRNG();
+ secrets.init(7);
- var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
-
- var btcKey = new Bitcoin.ECKey(ninja.wallets.splitwallet.hexToBytes(combined));
+ var btcKey = new Bitcoin.ECKey(combined);
if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
return false;
}
return true;
},
- testSplitAndCombinePrivateKey3: function () {
- var key = "004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da";
- var numshares = 4;
- var threshold = 2;
+ testCombinePrivateKeyFromXofYShares: function () {
+ var key = "5K9nHKqbwc1xXpa6wV5p3AaCnubvxQDBukKaFkq7ThAkxgMTMEh";
+ // these are 4 of 6 shares
+ var shares = ["3XxjMASmrkk6eXMM9kAJA7qiqViNVBfiwA1GQDLvg4PVScL", "3Y2DkcPuNX8VKZwpnDdxw55wJtcnCvv2nALqe8nBLViHvck",
+ "3Y6qv7kyGwgRBKVHVbUNtzmLYAZWQtTPztPwR8wc7uf4MXR", "3YD4TowZn6jw5ss8U89vrcPHonFW4vSs9VKq8MupV5kevG4"]
+ secrets.setRNG();
+ secrets.init(7);
- var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
-
- var btcKey = new Bitcoin.ECKey(ninja.wallets.splitwallet.hexToBytes(combined));
-
- if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
+ var btcKey = new Bitcoin.ECKey(combined);
+ if (btcKey.getBitcoinWalletImportFormat() != key) {
return false;
}
return true;
diff --git a/src/bitaddress-ui.html b/src/bitaddress-ui.html
index 123065e..5ff8e89 100644
--- a/src/bitaddress-ui.html
+++ b/src/bitaddress-ui.html
@@ -130,13 +130,13 @@
-
Single Wallet
-
Paper Wallet
-
Bulk Wallet
-
Brain Wallet
-
Vanity Wallet
-
Split Wallet
-
Wallet Details
+
Single Wallet
+
Paper Wallet
+
Bulk Wallet
+
Brain Wallet
+
Vanity Wallet
+
Split Wallet
+
Wallet Details
@@ -338,17 +338,13 @@
-
-
-
-
+
+
-
-
-
+
+
-
@@ -358,10 +354,13 @@
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main.css b/src/main.css
index 64fdbe1..cd9b645 100644
--- a/src/main.css
+++ b/src/main.css
@@ -4,7 +4,7 @@
no-repeat left center; width: 17px; height: 17px; display: inline-block; float: right; }
a { position: relative; z-index: 20; }
.right { text-align: right; }
-.walletarea { display: none; border: 2px solid #53c100; }
+.walletarea { display: none; border: 2px solid #009900; }
hr { margin: 20px 0; border-top: 2px dashed #008000; }
.keyarea { height: 110px; text-align: left; position: relative; padding: 5px; }
.keyarea .public { float: left; }
@@ -21,14 +21,14 @@ body { font-family: Arial; }
.question { padding: 10px 15px; text-align: left; cursor: pointer; }
.question:hover, .expandable:hover { color: #77777A; }
.answer { padding: 0 15px 10px 25px; text-align: left; display: none; font-size: 80%; }
-.faq { border: 0; border-top: 2px solid #53c100; }
+.faq { border: 0; border-top: 2px solid #009900; }
#wallets { clear: both; }
#btcaddress, #btcprivwif, #detailaddress, #detailaddresscomp, #detailprivwif, #detailprivwifcomp { font-family: monospace; font-size: 1.25em; }
#seedpoolarea { display: none; }
#seedpooldisplay { font-family: monospace; font-size: 1em; width: 640px; padding: 15px 5px; word-wrap: break-word; }
-.seedpoint { width: 6px; height: 6px; display: block; border-radius: 3px; background-color: #53c100; position: absolute; z-index: 10; }
-#generate { font-family: monospace; font-size: 1.25em; height: 305px; text-align: left; position: relative; padding: 5px; border: 2px solid #53c100; clear: both; }
+.seedpoint { width: 6px; height: 6px; display: block; border-radius: 3px; background-color: #009900; position: absolute; z-index: 10; }
+#generate { font-family: monospace; font-size: 1.25em; height: 305px; text-align: left; position: relative; padding: 5px; border: 2px solid #009900; clear: both; }
#generate span { padding: 5px 5px 0 5px; }
#generatekeyinput { position: relative; z-index: 20; }
#keyarea { height: 250px; }
@@ -41,14 +41,14 @@ body { font-family: Arial; }
#keyarea .public { width: 30%; display: table-cell; }
#singlearea { font-size: 90%; }
#singlesecret { position: relative; top: -130px; float: right; right: 200px; color: red; font-weight: bolder; font-size: 200%; }
-#singleshare { position: relative; top: -110px; float: left; left: 160px; color: #53c100; font-weight: bolder; font-size: 200%; }
-#singlesafety { text-align: left; padding: 5px; border-top: 2px solid #53c100; top: -25px; position: relative; }
+#singleshare { position: relative; top: -110px; float: left; left: 160px; color: #009900; font-weight: bolder; font-size: 200%; }
+#singlesafety { text-align: left; padding: 5px; border-top: 2px solid #009900; top: -25px; position: relative; }
-#main { position: relative; text-align: center; margin: 0px auto; width: 810px; }
+#main { position: relative; text-align: center; margin: 0px auto; width: 808px; }
#logo { width: 578px; height: 80px; }
#paperarea { min-height: 120px; display: none; }
-#paperarea .keyarea { border: 2px solid #53c100; border-top: 0; }
+#paperarea .keyarea { border: 2px solid #009900; border-top: 0; }
#paperarea .keyarea.art { display: block; height: auto; border: 0; font-family: Ubuntu, Arial; padding: 0; margin: 0; }
#paperarea .artwallet .papersvg { width: 486px; height: 261px; border: 0; margin: 0; padding: 0; left: 0; }
#paperarea .artwallet .qrcode_public { top: 52px; left: 17px; z-index: 100; margin: 0; float: none; display: block; position: absolute; background-color: #FFFFFF;
@@ -112,15 +112,23 @@ body { font-family: Arial; }
#vanityarea .label { text-decoration: underline; }
#vanityarea .output { font-family: monospace; font-size: 1.25em; display: block; }
#vanityarea .notes { text-align: left; font-size: 80%; padding: 0 0 20px 0; }
-#vanitystep1area { display: none; text-align: left; position: relative; padding: 15px; border-bottom: 2px solid #53c100; }
+#vanitystep1area { display: none; text-align: left; position: relative; padding: 15px; border-bottom: 2px solid #009900; }
#vanitystep1label { padding-left: 5px; }
-#vanitystep2area { border-top: 2px solid #53c100; display: block; padding: 15px; }
+#vanitystep2area { border-top: 2px solid #009900; display: block; padding: 15px; }
#vanitystep2inputs { padding: 0 15px 10px 15px; }
#vanitycalc { margin-top: 5px; }
+#splitarea { text-align: left; }
+#splitarea span { padding: 0; }
#splitcommands { padding: 10px 15px; text-align: left; }
-#splitstep1area { display: none; text-align: left; position: relative; padding: 0; border-bottom: 2px solid #53c100; }
-.splitsharerow { border-bottom: 2px solid #53c100; padding: 15px; }
+#combinecommands { padding: 10px 15px; }
+#splitstep1area { display: none; text-align: left; position: relative; padding: 0; border-bottom: 2px solid #009900; }
+.splitsharerow { border-bottom: 2px solid #009900; padding: 15px; }
+.splitsharerow:last-child { border-bottom: 0; }
+#combinelabelprivatekey { text-decoration: underline; }
+#splitarea .output { display: block; font-family: monospace; font-size: 1.25em; }
+#splitarea span.output { display: inline; }
+#splitstep2area { padding: 10px 15px; }
.englishjson { text-align: center; padding: 40px 0 20px 0; }
.unittests { text-align: center; }
@@ -142,14 +150,14 @@ body { font-family: Arial; }
.menu
{
text-align: left; margin: 0; padding: 0; display: block;
- background-color: #53c100;
-
- height: 72px; border-top-left-radius: 5px; border-top-right-radius: 5px;
+ background-color: #009900; /* # 009900 # 53c100 */
+ border-top-left-radius: 5px; border-top-right-radius: 5px;
}
.menu .tab
{
- position: relative; float: left; margin: 0; list-style: none; z-index: 110; cursor: pointer;
- border: 0px solid red; top: 1px; padding: 10px 20px; width: 160px; text-align: center;
+ position: relative; display: inline-block; border: 0px solid red;
+ margin: 0; list-style: none; z-index: 110; cursor: pointer;
+ top: 1px; padding: 10px 20px; width: 162px; text-align: center;
}
.menu .tab.selected
{
@@ -163,7 +171,7 @@ body { font-family: Arial; }
.menu .tab.selected:hover { color: #000; }
.pagebreak { height: 50px; }
- .commands { border-bottom: 2px solid #53c100; padding: 10px 2px; margin-bottom: 0; }
+ .commands { border-bottom: 2px solid #009900; padding: 10px 2px; margin-bottom: 0; }
.commands .row { padding: 0 0; text-align: left; }
.commands .row.extra { padding-top: 6px; }
.commands span { padding: 0 10px; }
@@ -171,8 +179,8 @@ body { font-family: Arial; }
.commands span.right { float: right; }
.expandable { padding: 10px 15px; text-align: left; cursor: pointer; }
- #menu { visibility: visible; font-size: 90%; }
- #culturemenu { text-align: right; padding: 0 20px; }
+ #menu { visibility: hidden; font-size: 90%; }
+ #culturemenu { text-align: right; padding: 0 20px; margin-bottom: 3px; }
#culturemenu span { padding: 3px; }
#culturemenu .selected { text-decoration: none; color: #000000; }
@@ -185,7 +193,7 @@ body { font-family: Arial; }
#detailcommands span { padding: 0 10px; }
#detailprivkey { width: 250px; }
#detailprivkeypassphrase { width: 250px; }
- .paper .commands { border: 2px solid #53c100; }
+ .paper .commands { border: 2px solid #009900; }
#bulkstartindex, #paperlimit, #paperlimitperpage { width: 35px; }
#bulklimit { width: 45px; }
@@ -204,7 +212,7 @@ body { font-family: Arial; }
#main { width: auto; }
#singlearea { border: 0; }
#singlesafety { border: 0; }
- #paperarea .keyarea:first-child { border-top: 2px solid #53c100; }
+ #paperarea .keyarea:first-child { border-top: 2px solid #009900; }
#paperarea .keyarea.art:first-child { border: 0; }
.pagebreak { height: 1px; }
.paper #logo { display: none; }
diff --git a/src/ninja.splitwallet.js b/src/ninja.splitwallet.js
index 793eb55..61d8bef 100644
--- a/src/ninja.splitwallet.js
+++ b/src/ninja.splitwallet.js
@@ -2,7 +2,7 @@ ninja.wallets.splitwallet = {
open: function () {
document.getElementById("splitarea").style.display = "block";
secrets.setRNG();
- secrets.init(7);
+ secrets.init(7); // 7 bits allows for up to 127 shares
},
close: function () {
@@ -12,12 +12,16 @@ ninja.wallets.splitwallet = {
mkOutputRow: function (s, id, lbltxt) {
var row = document.createElement("div");
var label = document.createElement("label");
- label.innerHTML = lbltxt + s;
+ label.innerHTML = lbltxt;
var qr = document.createElement("div");
+ var output = document.createElement("span");
+ output.setAttribute("class", "output");
+ output.innerHTML = s;
qr.setAttribute("id", id);
row.setAttribute("class", "splitsharerow");
row.appendChild(label);
+ row.appendChild(output);
row.appendChild(qr);
row.appendChild(document.createElement("br"));
@@ -38,13 +42,12 @@ ninja.wallets.splitwallet = {
// Split a private key and update information in the HTML
splitKey: function () {
try {
- var key = new Bitcoin.ECKey(false);
- var bitcoinAddress = key.getBitcoinAddress();
-
var numshares = parseInt(document.getElementById('splitshares').value);
var threshold = parseInt(document.getElementById('splitthreshold').value);
- var hexKey = Crypto.util.bytesToHex(key.getBitcoinPrivateKeyByteArray());
- var shares = secrets.share(hexKey, numshares, threshold).map(this.hexToBytes).map(Bitcoin.Base58.encode);
+ var key = new Bitcoin.ECKey(false);
+ var bitcoinAddress = key.getBitcoinAddress();
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key.getBitcoinHexFormat(), numshares, threshold);
+
var output = document.createElement("div");
output.setAttribute("id", "splitoutput");
var m = {};
@@ -66,49 +69,33 @@ ninja.wallets.splitwallet = {
catch (e) {
// browser does not have sufficient JavaScript support to generate a bitcoin address
alert(e);
- document.getElementById("btcaddress").innerHTML = "error";
- document.getElementById("btcprivwif").innerHTML = "error";
- document.getElementById("qrcode_public").innerHTML = "";
- document.getElementById("qrcode_private").innerHTML = "";
}
},
// Combine shares of a private key to retrieve the key
combineShares: function () {
try {
- var element = document.getElementById("combineoutput");
- if (element != null) element.parentNode.removeChild(element);
-
+ document.getElementById("combinedprivatekey").innerHTML = "";
var shares = document.getElementById("combineinput").value.trim().split(/\W+/);
-
- var combined = secrets.combine(shares.map(Bitcoin.Base58.decode).map(Crypto.util.bytesToHex).map(this.stripLeadZeros));
-
- var privkeyBase58 = new Bitcoin.ECKey(this.hexToBytes(combined)).getBitcoinWalletImportFormat();
- var output = document.createElement("div");
- output.setAttribute("id", "combineoutput");
- var txt = document.createElement("input");
- txt.setAttribute("id", "combineoutputtext");
- txt.setAttribute("value", privkeyBase58);
- txt.setAttribute("size", 55);
- var lbl = document.createElement("label");
- lbl.innerHTML = "Private key";
- output.appendChild(lbl);
- output.appendChild(txt);
- document.getElementById("combinecommands").appendChild(output);
+ var combinedBytes = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var privkeyBase58 = new Bitcoin.ECKey(combinedBytes).getBitcoinWalletImportFormat();
+ document.getElementById("combinedprivatekey").innerHTML = privkeyBase58;
}
catch (e) {
alert(e);
}
},
+ // generate shares and format them in base58
getFormattedShares: function (key, numshares, threshold) {
var shares = secrets.share(key, numshares, threshold).map(ninja.wallets.splitwallet.hexToBytes).map(Bitcoin.Base58.encode);
return shares;
},
+ // combine base58 formatted shares and return a bitcoin byte array
combineFormattedShares: function (shares) {
var combined = secrets.combine(shares.map(Bitcoin.Base58.decode).map(Crypto.util.bytesToHex).map(ninja.wallets.splitwallet.stripLeadZeros));
- return combined;
+ return ninja.wallets.splitwallet.hexToBytes(combined);
},
openCloseStep: function (num) {
diff --git a/src/ninja.unittests.js b/src/ninja.unittests.js
index 4bdb20b..b97f38f 100644
--- a/src/ninja.unittests.js
+++ b/src/ninja.unittests.js
@@ -461,46 +461,107 @@
},
// test split wallet
- testSplitAndCombinePrivateKey: function () {
+ testSplitAndCombinePrivateKey2of2: function () {
+ // lowercase hex key
+ var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
+ var numshares = 2;
+ var threshold = 2;
+ secrets.setRNG();
+ secrets.init(7);
+
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var btcKey = new Bitcoin.ECKey(combined);
+
+ if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
+ return false;
+ }
+ return true;
+ },
+ // Example use case #1:
+ // Division of 3 shares:
+ // 1 share in a safety deposit box ("Box")
+ // 1 share at Home
+ // 1 share at Work
+ // Threshold of 2 can be redeemed in these permutations
+ // Home + Box
+ // Work + Box
+ // Home + Work
+ testSplitAndCombinePrivateKey2of3: function () {
+ // lowercase hex key
+ var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
+ var numshares = 3;
+ var threshold = 2;
+ secrets.setRNG();
+ secrets.init(7);
+
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ shares.shift();
+ var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var btcKey = new Bitcoin.ECKey(combined);
+
+ if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
+ return false;
+ }
+ return true;
+ },
+ testSplitAndCombinePrivateKey2of4: function () {
+ // uppercase hex key
var key = "292665C3872418ADF1DA7FFA3A646F2F0602246DA6098A91D229C32150F2718B"; //5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb
var numshares = 4;
var threshold = 2;
+ secrets.setRNG();
+ secrets.init(7);
+
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ shares.shift();
+ shares.shift();
+ var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
+ var btcKey = new Bitcoin.ECKey(combined);
- var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold); //secrets.share(key, numshares, threshold).map(ninja.wallets.splitwallet.hexToBytes).map(Bitcoin.Base58.encode);
- var combined = ninja.wallets.splitwallet.combineFormattedShares(shares); // secrets.combine(shares.map(Bitcoin.Base58.decode).map(Crypto.util.bytesToHex).map(ninja.wallets.splitwallet.stripLeadZeros));
-
- var btcKey = new Bitcoin.ECKey(ninja.wallets.splitwallet.hexToBytes(combined));
if (btcKey.getBitcoinHexFormat() != key) {
return false;
}
return true;
},
- testSplitAndCombinePrivateKey2: function () {
- var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da 5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
- var numshares = 4;
- var threshold = 2;
+ // Example use case #2:
+ // Division of 13 shares:
+ // 4 shares in a safety deposit box ("Box")
+ // 3 shares with good friend Angie
+ // 3 shares with good friend Fred
+ // 3 shares with Self at home or office
+ // Threshold of 7 can be redeemed in these permutations
+ // Self + Box (no trust to spend your coins but your friends are backing up your shares)
+ // Angie + Box (Angie will send btc to executor of your will)
+ // Fred + Box (if Angie hasn't already then Fred will send btc to executor of your will)
+ // Angie + Fred + Self (bank fire/theft then you with both your friends can spend the coins)
+ testSplitAndCombinePrivateKey7of13: function () {
+ var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da";
+ var numshares = 12;
+ var threshold = 7;
+ secrets.setRNG();
+ secrets.init(7);
- var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
+ var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
-
- var btcKey = new Bitcoin.ECKey(ninja.wallets.splitwallet.hexToBytes(combined));
+ var btcKey = new Bitcoin.ECKey(combined);
if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
return false;
}
return true;
},
- testSplitAndCombinePrivateKey3: function () {
- var key = "004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da";
- var numshares = 4;
- var threshold = 2;
+ testCombinePrivateKeyFromXofYShares: function () {
+ var key = "5K9nHKqbwc1xXpa6wV5p3AaCnubvxQDBukKaFkq7ThAkxgMTMEh";
+ // these are 4 of 6 shares
+ var shares = ["3XxjMASmrkk6eXMM9kAJA7qiqViNVBfiwA1GQDLvg4PVScL", "3Y2DkcPuNX8VKZwpnDdxw55wJtcnCvv2nALqe8nBLViHvck",
+ "3Y6qv7kyGwgRBKVHVbUNtzmLYAZWQtTPztPwR8wc7uf4MXR", "3YD4TowZn6jw5ss8U89vrcPHonFW4vSs9VKq8MupV5kevG4"]
+ secrets.setRNG();
+ secrets.init(7);
- var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
-
- var btcKey = new Bitcoin.ECKey(ninja.wallets.splitwallet.hexToBytes(combined));
-
- if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
+ var btcKey = new Bitcoin.ECKey(combined);
+ if (btcKey.getBitcoinWalletImportFormat() != key) {
return false;
}
return true;