aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Coleman <coleman.ian@gmail.com>2016-12-19 13:54:51 +1100
committerIan Coleman <coleman.ian@gmail.com>2016-12-19 13:55:21 +1100
commitba3cb9ecae2667e98af71f5b38a862ba604e8e1c (patch)
tree380d24d03b7a3e6c7e02592901a62d605b2df61e
parent52da415f0385a6a89070498d14259aed980f989b (diff)
downloadBIP39-ba3cb9ecae2667e98af71f5b38a862ba604e8e1c.tar.gz
BIP39-ba3cb9ecae2667e98af71f5b38a862ba604e8e1c.tar.zst
BIP39-ba3cb9ecae2667e98af71f5b38a862ba604e8e1c.zip
xpub key can be used as bip32 root key
-rw-r--r--bip39-standalone.html26
-rw-r--r--src/js/index.js26
-rw-r--r--tests.js103
3 files changed, 147 insertions, 8 deletions
diff --git a/bip39-standalone.html b/bip39-standalone.html
index 0f7d7d0..367d9a2 100644
--- a/bip39-standalone.html
+++ b/bip39-standalone.html
@@ -18868,11 +18868,11 @@ window.Entropy = new (function() {
18868 // Calculate and display 18868 // Calculate and display
18869 calcBip32RootKeyFromBase58(rootKeyBase58); 18869 calcBip32RootKeyFromBase58(rootKeyBase58);
18870 calcForDerivationPath(); 18870 calcForDerivationPath();
18871 hidePending();
18872 } 18871 }
18873 18872
18874 function calcForDerivationPath() { 18873 function calcForDerivationPath() {
18875 showPending(); 18874 showPending();
18875 clearAddressesList();
18876 hideValidationError(); 18876 hideValidationError();
18877 // Get the derivation path 18877 // Get the derivation path
18878 var derivationPath = getDerivationPath(); 18878 var derivationPath = getDerivationPath();
@@ -18974,7 +18974,12 @@ window.Entropy = new (function() {
18974 continue; 18974 continue;
18975 } 18975 }
18976 var hardened = bit[bit.length-1] == "'"; 18976 var hardened = bit[bit.length-1] == "'";
18977 if (hardened) { 18977 var isPriv = "privKey" in extendedKey;
18978 var invalidDerivationPath = hardened && !isPriv;
18979 if (invalidDerivationPath) {
18980 extendedKey = null;
18981 }
18982 else if (hardened) {
18978 extendedKey = extendedKey.deriveHardened(index); 18983 extendedKey = extendedKey.deriveHardened(index);
18979 } 18984 }
18980 else { 18985 else {
@@ -19093,6 +19098,12 @@ window.Entropy = new (function() {
19093 } 19098 }
19094 } 19099 }
19095 } 19100 }
19101 // Check no hardened derivation path when using xpub keys
19102 var hardened = path.indexOf("'") > -1;
19103 var isXpubkey = !("privKey" in bip32RootKey);
19104 if (hardened && isXpubkey) {
19105 return "Hardened derivation path is invalid with xpub key";
19106 }
19096 return false; 19107 return false;
19097 } 19108 }
19098 19109
@@ -19119,7 +19130,11 @@ window.Entropy = new (function() {
19119 DOM.seed.val(seed); 19130 DOM.seed.val(seed);
19120 var rootKey = bip32RootKey.toBase58(); 19131 var rootKey = bip32RootKey.toBase58();
19121 DOM.rootKey.val(rootKey); 19132 DOM.rootKey.val(rootKey);
19122 var extendedPrivKey = bip32ExtendedKey.toBase58(); 19133 var xprvkeyB58 = "NA";
19134 if (bip32ExtendedKey.privKey) {
19135 xprvkeyB58 = bip32ExtendedKey.toBase58();
19136 }
19137 var extendedPrivKey = xprvkeyB58;
19123 DOM.extendedPrivKey.val(extendedPrivKey); 19138 DOM.extendedPrivKey.val(extendedPrivKey);
19124 var extendedPubKey = bip32ExtendedKey.toBase58(false); 19139 var extendedPubKey = bip32ExtendedKey.toBase58(false);
19125 DOM.extendedPubKey.val(extendedPubKey); 19140 DOM.extendedPubKey.val(extendedPubKey);
@@ -19153,7 +19168,10 @@ window.Entropy = new (function() {
19153 key = bip32ExtendedKey.derive(index); 19168 key = bip32ExtendedKey.derive(index);
19154 } 19169 }
19155 var address = key.getAddress().toString(); 19170 var address = key.getAddress().toString();
19156 var privkey = key.privKey.toWIF(network); 19171 var privkey = "NA";
19172 if (key.privKey) {
19173 privkey = key.privKey.toWIF(network);
19174 }
19157 var pubkey = key.pubKey.toHex(); 19175 var pubkey = key.pubKey.toHex();
19158 var indexText = getDerivationPath() + "/" + index; 19176 var indexText = getDerivationPath() + "/" + index;
19159 if (useHardenedAddresses) { 19177 if (useHardenedAddresses) {
diff --git a/src/js/index.js b/src/js/index.js
index cac420e..45edea8 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -228,11 +228,11 @@
228 // Calculate and display 228 // Calculate and display
229 calcBip32RootKeyFromBase58(rootKeyBase58); 229 calcBip32RootKeyFromBase58(rootKeyBase58);
230 calcForDerivationPath(); 230 calcForDerivationPath();
231 hidePending();
232 } 231 }
233 232
234 function calcForDerivationPath() { 233 function calcForDerivationPath() {
235 showPending(); 234 showPending();
235 clearAddressesList();
236 hideValidationError(); 236 hideValidationError();
237 // Get the derivation path 237 // Get the derivation path
238 var derivationPath = getDerivationPath(); 238 var derivationPath = getDerivationPath();
@@ -334,7 +334,12 @@
334 continue; 334 continue;
335 } 335 }
336 var hardened = bit[bit.length-1] == "'"; 336 var hardened = bit[bit.length-1] == "'";
337 if (hardened) { 337 var isPriv = "privKey" in extendedKey;
338 var invalidDerivationPath = hardened && !isPriv;
339 if (invalidDerivationPath) {
340 extendedKey = null;
341 }
342 else if (hardened) {
338 extendedKey = extendedKey.deriveHardened(index); 343 extendedKey = extendedKey.deriveHardened(index);
339 } 344 }
340 else { 345 else {
@@ -453,6 +458,12 @@
453 } 458 }
454 } 459 }
455 } 460 }
461 // Check no hardened derivation path when using xpub keys
462 var hardened = path.indexOf("'") > -1;
463 var isXpubkey = !("privKey" in bip32RootKey);
464 if (hardened && isXpubkey) {
465 return "Hardened derivation path is invalid with xpub key";
466 }
456 return false; 467 return false;
457 } 468 }
458 469
@@ -479,7 +490,11 @@
479 DOM.seed.val(seed); 490 DOM.seed.val(seed);
480 var rootKey = bip32RootKey.toBase58(); 491 var rootKey = bip32RootKey.toBase58();
481 DOM.rootKey.val(rootKey); 492 DOM.rootKey.val(rootKey);
482 var extendedPrivKey = bip32ExtendedKey.toBase58(); 493 var xprvkeyB58 = "NA";
494 if (bip32ExtendedKey.privKey) {
495 xprvkeyB58 = bip32ExtendedKey.toBase58();
496 }
497 var extendedPrivKey = xprvkeyB58;
483 DOM.extendedPrivKey.val(extendedPrivKey); 498 DOM.extendedPrivKey.val(extendedPrivKey);
484 var extendedPubKey = bip32ExtendedKey.toBase58(false); 499 var extendedPubKey = bip32ExtendedKey.toBase58(false);
485 DOM.extendedPubKey.val(extendedPubKey); 500 DOM.extendedPubKey.val(extendedPubKey);
@@ -513,7 +528,10 @@
513 key = bip32ExtendedKey.derive(index); 528 key = bip32ExtendedKey.derive(index);
514 } 529 }
515 var address = key.getAddress().toString(); 530 var address = key.getAddress().toString();
516 var privkey = key.privKey.toWIF(network); 531 var privkey = "NA";
532 if (key.privKey) {
533 privkey = key.privKey.toWIF(network);
534 }
517 var pubkey = key.pubKey.toHex(); 535 var pubkey = key.pubKey.toHex();
518 var indexText = getDerivationPath() + "/" + index; 536 var indexText = getDerivationPath() + "/" + index;
519 if (useHardenedAddresses) { 537 if (useHardenedAddresses) {
diff --git a/tests.js b/tests.js
index d5a73f6..19a3712 100644
--- a/tests.js
+++ b/tests.js
@@ -3138,6 +3138,109 @@ page.open(url, function(status) {
3138}); 3138});
3139}, 3139},
3140 3140
3141// github issue 40
3142// BIP32 root key can be set as an xpub
3143function() {
3144page.open(url, function(status) {
3145 // set the phrase
3146 page.evaluate(function() {
3147 // set xpub for account 0 of bip44 for 'abandon abandon ability'
3148 var bip44AccountXpub = "xpub6CzDCPbtLrrn4VpVbyyQLHbdSMpZoHN4iuW64VswCyEpfjM2mJGdaHJ2DyuZwtst96E16VvcERb8BBeJdHSCVmAq9RhtRQg6eAZFrTKCNqf";
3149 $("#root-key").val(bip44AccountXpub);
3150 $("#root-key").trigger("input");
3151 });
3152 waitForFeedback(function() {
3153 page.evaluate(function() {
3154 // Use bip32 tab
3155 $("#bip32-tab a").click();
3156 });
3157 waitForGenerate(function() {
3158 page.evaluate(function() {
3159 // derive external addresses for this xpub
3160 var firstAccountDerivationPath = "m/0";
3161 $("#bip32-path").val(firstAccountDerivationPath);
3162 $("#bip32-path").trigger("input");
3163 });
3164 waitForGenerate(function() {
3165 // check the addresses are generated
3166 var expected = "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
3167 var actual = page.evaluate(function() {
3168 return $(".address:first").text();
3169 });
3170 if (actual != expected) {
3171 console.log("xpub key does not generate addresses in table");
3172 console.log("Expected: " + expected);
3173 console.log("Actual: " + actual);
3174 fail();
3175 }
3176 // check the xprv key is not set
3177 var expected = "NA";
3178 var actual = page.evaluate(function() {
3179 return $(".extended-priv-key").val();
3180 });
3181 if (actual != expected) {
3182 console.log("xpub key as root shows derived bip32 xprv key");
3183 console.log("Expected: " + expected);
3184 console.log("Actual: " + actual);
3185 fail();
3186 }
3187 // check the private key is not set
3188 var expected = "NA";
3189 var actual = page.evaluate(function() {
3190 return $(".privkey:first").text();
3191 });
3192 if (actual != expected) {
3193 console.log("xpub key generates private key in addresses table");
3194 console.log("Expected: " + expected);
3195 console.log("Actual: " + actual);
3196 fail();
3197 }
3198 next();
3199 });
3200 });
3201 });
3202});
3203},
3204
3205// github issue 40
3206// xpub for bip32 root key will not work with hardened derivation paths
3207function() {
3208page.open(url, function(status) {
3209 // set the phrase
3210 page.evaluate(function() {
3211 // set xpub for account 0 of bip44 for 'abandon abandon ability'
3212 var bip44AccountXpub = "xpub6CzDCPbtLrrn4VpVbyyQLHbdSMpZoHN4iuW64VswCyEpfjM2mJGdaHJ2DyuZwtst96E16VvcERb8BBeJdHSCVmAq9RhtRQg6eAZFrTKCNqf";
3213 $("#root-key").val(bip44AccountXpub);
3214 $("#root-key").trigger("input");
3215 });
3216 waitForFeedback(function() {
3217 // Check feedback is correct
3218 var expected = "Hardened derivation path is invalid with xpub key";
3219 var actual = page.evaluate(function() {
3220 return $(".feedback").text();
3221 });
3222 if (actual != expected) {
3223 console.log("xpub key with hardened derivation path does not show feedback");
3224 console.log("Expected: " + expected);
3225 console.log("Actual: " + actual);
3226 fail();
3227 }
3228 // Check no addresses are shown
3229 var expected = 0;
3230 var actual = page.evaluate(function() {
3231 return $(".addresses tr").length;
3232 });
3233 if (actual != expected) {
3234 console.log("addresses still show after setting xpub key with hardened derivation path");
3235 console.log("Expected: " + expected);
3236 console.log("Actual: " + actual);
3237 fail();
3238 }
3239 next();
3240 });
3241});
3242},
3243
3141 3244
3142// If you wish to add more tests, do so here... 3245// If you wish to add more tests, do so here...
3143 3246