]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blobdiff - src/js/index.js
Add P2WSH and P2WSH-P2SH for bitcoin and testnet
[perso/Immae/Projets/Cryptomonnaies/BIP39.git] / src / js / index.js
index 9807449b0758bbe13192cfe462d2e5a87f4aeae1..db4741256e30ba66b0873800013db5333f364793 100644 (file)
@@ -15,7 +15,6 @@
     var showPrivKey = true;
     var showQr = false;
     var litecoinUseLtub = true;
-    var isDefaultBip44ChangeValue = true;
 
     var entropyChangeTimeoutEvent = null;
     var phraseChangeTimeoutEvent = null;
@@ -45,8 +44,8 @@
     DOM.entropyWeakEntropyOverrideWarning = DOM.entropyContainer.find(".weak-entropy-override-warning");
     DOM.entropyFilterWarning = DOM.entropyContainer.find(".filter-warning");
     DOM.phrase = $(".phrase");
-       DOM.splitPhrase = $(".phraseSplit");
-       DOM.phraseSplitWarn = $(".phraseSplitWarn");
+    DOM.phraseSplit = $(".phraseSplit");
+    DOM.phraseSplitWarn = $(".phraseSplitWarn");
     DOM.passphrase = $(".passphrase");
     DOM.generateContainer = $(".generate-container");
     DOM.generate = $(".generate");
@@ -72,7 +71,6 @@
     DOM.bip44accountXprv = $("#bip44 .account-xprv");
     DOM.bip44accountXpub = $("#bip44 .account-xpub");
     DOM.bip44change = $("#bip44 .change");
-    DOM.defaultBip44ChangeValue = $("#bip44 .default-bip44-change-value");
     DOM.bip49unavailable = $("#bip49 .unavailable");
     DOM.bip49available = $("#bip49 .available");
     DOM.bip49path = $("#bip49-path");
         DOM.litecoinUseLtub.on("change", litecoinUseLtubChanged);
         DOM.bip32path.on("input", calcForDerivationPath);
         DOM.bip44account.on("input", calcForDerivationPath);
-        DOM.bip44change.on("input", modifiedDefaultBip44ChangeValue);
         DOM.bip44change.on("input", calcForDerivationPath);
-        DOM.defaultBip44ChangeValue.on("click", resetDefaultBip44ChangeValue);
         DOM.bip49account.on("input", calcForDerivationPath);
         DOM.bip49change.on("input", calcForDerivationPath);
         DOM.bip84account.on("input", calcForDerivationPath);
         }
         phraseChangeTimeoutEvent = setTimeout(function() {
             phraseChanged();
-            var entropy = mnemonic.toRawEntropyHex(DOM.phrase.val());
+            var entropy = mnemonic.toRawEntropyBin(DOM.phrase.val());
             if (entropy !== null) {
                 DOM.entropyMnemonicLength.val("raw");
                 DOM.entropy.val(entropy);
         calcForDerivationPath();
         // Show the word indexes
         showWordIndexes();
+        writeSplitPhrase(phrase);
     }
 
     function tabChanged() {
             clearDisplay();
             clearEntropyFeedback();
             DOM.phrase.val("");
-                       DOM.phraseSplit.val("");
+            DOM.phraseSplit.val("");
             showValidationError("Blank entropy");
             return;
         }
         showPending();
         // Clear existing mnemonic and passphrase
         DOM.phrase.val("");
-               DOM.phraseSplit.val("");
+        DOM.phraseSplit.val("");
         DOM.passphrase.val("");
         seed = null;
         if (rootKeyChangedTimeoutEvent != null) {
             if (DOM.phrase.val().length > 0) {
                 var newPhrase = convertPhraseToNewLanguage();
                 DOM.phrase.val(newPhrase);
-                               writeSplitPhrase(newPhrase);
                 phraseChanged();
             }
             else {
         // show the words
         var words = mnemonic.toMnemonic(data);
         DOM.phrase.val(words);
-               writeSplitPhrase(words);
         // show the entropy
         var entropyHex = uint8ArrayToHex(data);
         DOM.entropy.val(entropyHex);
                 }
                 catch (e) {}
             }
+            // try parsing using p2wsh network params
+            if ("p2wsh" in n) {
+                try {
+                    bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wsh);
+                    return;
+                }
+                catch (e) {}
+            }
+            // try parsing using p2wsh-in-p2sh network params
+            if ("p2wshInP2sh" in n) {
+                try {
+                    bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wshInP2sh);
+                    return;
+                }
+                catch (e) {}
+            }
         }
         // try the network params as currently specified
         bip32RootKey = bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, network);
                 }
                 catch (e) {}
             }
+            // try parsing using p2wsh network params
+            if ("p2wsh" in n) {
+                try {
+                    bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wsh);
+                    return "";
+                }
+                catch (e) {}
+            }
+            // try parsing using p2wsh-in-p2sh network params
+            if ("p2wshInP2sh" in n) {
+                try {
+                    bitcoinjs.bitcoin.HDNode.fromBase58(rootKeyBase58, n.p2wshInP2sh);
+                    return "";
+                }
+                catch (e) {}
+            }
         }
         // try the network params as currently specified
         try {
             var purpose = parseIntNoNaN(DOM.bip44purpose.val(), 44);
             var coin = parseIntNoNaN(DOM.bip44coin.val(), 0);
             var account = parseIntNoNaN(DOM.bip44account.val(), 0);
-            var change = parseIntNoNaN(DOM.bip44change.val(), "");
-            var path = "m";
-            path += "/" + purpose + "'";
-            path += "/" + coin + "'";
-            path += "/" + account + "'";
-            if (change !== "") {
-              path += "/" + change;
-            }
+            var change = parseIntNoNaN(DOM.bip44change.val(), 0);
+            var path = "m/";
+            path += purpose + "'/";
+            path += coin + "'/";
+            path += account + "'/";
+            path += change;
             DOM.bip44path.val(path);
             var derivationPath = DOM.bip44path.val();
             console.log("Using derivation path from BIP44 tab: " + derivationPath);
             (bip141TabSelected() && DOM.bip141semantics.val() == "p2wpkh-p2sh");
     }
 
+    function p2wshSelected() {
+        return bip141TabSelected() && DOM.bip141semantics.val() == "p2wsh";
+    }
+
+    function p2wshInP2shSelected() {
+        return (bip141TabSelected() && DOM.bip141semantics.val() == "p2wsh-p2sh");
+    }
+
     function TableRow(index, isLast) {
 
         var self = this;
         var segwitAvailable = networkHasSegwit();
         var isP2wpkh = p2wpkhSelected();
         var isP2wpkhInP2sh = p2wpkhInP2shSelected();
+        var isP2wsh = p2wshSelected();
+        var isP2wshInP2sh = p2wshInP2shSelected();
 
         function init() {
             calculateValues();
                         var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes);
                         address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network)
                     }
+                    else if (isP2wsh) {
+                        // TODO
+                        address = "";
+                    }
+                    else if (isP2wshInP2sh) {
+                        // TODO
+                        address = "";
+                    }
                 }
 
                 if ((networks[DOM.network.val()].name == "CRW - Crown")) {
         }
         return phrase;
     }
-       
-       function writeSplitPhrase(phrase) {
-               var wordCount = phrase.split(/\s/g).length;                                                             //get number of words in phrase       
-               var left=[];                                                                                                                    //initialize array of indexs
-               for (var i=0;i<wordCount;i++) left.push(i);                                                             //add all indexs to array
-               var group=[[],[],[]],                                                                                                   //make array for 3 groups
-                       groupI=-1;                                                                                                                      //initialize group index
-               var seed = Math.abs(sjcl.hash.sha256.hash(phrase)[0])% 2147483647;              //start seed at sudo random value based on hash of words
-               while (left.length>0) {                                                                                                 //while indexs left
-                       groupI=(groupI+1)%3;                                                                                            //get next group to insert index into
-                       seed = seed * 16807 % 2147483647;                                                                       //change random value.(simple predicatable random number generator works well for this use)
-                       var selected=Math.floor(left.length*(seed - 1) / 2147483646);           //get index in left we will use for this group
-                       group[groupI].push(left[selected]);                                                                     //add index to group
-                       left.splice(selected,1);                                                                                        //remove selected index
-               }
-               var cards=[phrase.split(/\s/g),phrase.split(/\s/g),phrase.split(/\s/g)];//make array of cards
-               for (var i=0;i<3;i++) {                                                                                                 //go through each card
-                       for (var ii=0;ii<wordCount/3;ii++) cards[i][group[i][ii]]='XXXX';       //erase words listed in the group
-                       cards[i]='Card '+(i+1)+': '+wordArrayToPhrase(cards[i]);                                                                //combine words on card back to string
-               }
-               DOM.splitPhrase.val(cards.join("\r\n"));                                                                //make words visible
-               var triesPerSecond=10000000000;                                                                                 //assumed number of tries per second
-               var hackTime=Math.pow(2,wordCount*10/3)/triesPerSecond;                                 //get number of bits of unknown data per card
-               if (hackTime<1) {
-                       hackTime="<1 second";
-               } else if (hackTime<86400) {
-                       hackTime=Math.floor(hackTime)+" seconds";
-               } else if(hackTime<31557600) {
-                       hackTime=Math.floor(hackTime/86400)+" days";
-               } else {
-                       hackTime=Math.floor(hackTime/31557600)+" years";
-               }
-               DOM.phraseSplitWarn.html("Time to hack with only one card: "+hackTime);
-       }
+
+    function writeSplitPhrase(phrase) {
+        var wordCount = phrase.split(/\s/g).length;
+        var left=[];
+        for (var i=0;i<wordCount;i++) left.push(i);
+        var group=[[],[],[]],
+            groupI=-1;
+        var seed = Math.abs(sjcl.hash.sha256.hash(phrase)[0])% 2147483647;
+        while (left.length>0) {
+            groupI=(groupI+1)%3;
+            seed = seed * 16807 % 2147483647;
+            var selected=Math.floor(left.length*(seed - 1) / 2147483646);
+            group[groupI].push(left[selected]);
+            left.splice(selected,1);
+        }
+        var cards=[phrase.split(/\s/g),phrase.split(/\s/g),phrase.split(/\s/g)];
+        for (var i=0;i<3;i++) {
+            for (var ii=0;ii<wordCount/3;ii++) cards[i][group[i][ii]]='XXXX';
+            cards[i]='Card '+(i+1)+': '+wordArrayToPhrase(cards[i]);
+        }
+        DOM.phraseSplit.val(cards.join("\r\n"));
+        var triesPerSecond=10000000000;
+        var hackTime=Math.pow(2,wordCount*10/3)/triesPerSecond;
+        var displayRedText = false;
+        if (hackTime<1) {
+            hackTime="<1 second";
+            displayRedText = true;
+        } else if (hackTime<86400) {
+            hackTime=Math.floor(hackTime)+" seconds";
+            displayRedText = true;
+        } else if(hackTime<31557600) {
+            hackTime=Math.floor(hackTime/86400)+" days";
+            displayRedText = true;
+        } else {
+            hackTime=Math.floor(hackTime/31557600)+" years";
+        }
+        DOM.phraseSplitWarn.html("Time to hack with only one card: "+hackTime);
+        if (displayRedText) {
+            DOM.phraseSplitWarn.addClass("text-danger");
+        } else {
+            DOM.phraseSplitWarn.removeClass("text-danger");
+        }
+    }
 
     function isUsingOwnEntropy() {
         return DOM.useEntropy.prop("checked");
         var phrase = mnemonic.toMnemonic(entropyArr);
         // Set the mnemonic in the UI
         DOM.phrase.val(phrase);
-               writeSplitPhrase(phrase);
+        writeSplitPhrase(phrase);
         // Show the word indexes
         showWordIndexes();
         // Show the checksum
         return DOM.bip141tab.hasClass("active");
     }
 
-    function setBip44ChangeValue() {
-        if (isDefaultBip44ChangeValue) {
-            if (networkIsEthereum()) {
-                DOM.bip44change.val("");
-            } else {
-                DOM.bip44change.val(0);
-            }
-        }
-    }
-
-    function modifiedDefaultBip44ChangeValue() {
-        isDefaultBip44ChangeValue = false;
-    }
-
-    function resetDefaultBip44ChangeValue() {
-        isDefaultBip44ChangeValue = true;
-        setBip44ChangeValue();
-    }
-
     function setHdCoin(coinValue) {
         DOM.bip44coin.val(coinValue);
         DOM.bip49coin.val(coinValue);
         DOM.bip84coin.val(coinValue);
-        setBip44ChangeValue();
     }
 
     function showSegwitAvailable() {
         else if (p2wpkhInP2shSelected() && "p2wpkhInP2sh" in network) {
             network = network.p2wpkhInP2sh;
         }
+        else if (p2wshSelected() && "p2wsh" in network) {
+            network = network.p2wsh;
+        }
+        else if (p2wshInP2shSelected() && "p2wshInP2sh" in network) {
+            network = network.p2wshInP2sh;
+        }
     }
 
     function lastIndexInTable() {
                 network = bitcoinjs.bitcoin.networks.axe;
                 setHdCoin(4242);
             },
-               },
-               {
+        },
+        {
             name: "ANON - ANON",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.anon;
                 setHdCoin(2941);
             },
         },
-               {
+        {
             name: "tBND - Blocknode Testnet",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.blocknode_testnet;
                 setHdCoin(91);
             },
         },
-               {
+        {
             name: "BST - BlockStamp",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.blockstamp;
                 setHdCoin(1);
             },
         },
-               {
+        {
             name: "BITG - Bitcoin Green",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.bitcoingreen;
                 setHdCoin(168);
             },
         },
-               {
+        {
             name: "HUSH - Hush (Legacy)",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.hush;
                 setHdCoin(197);
             },
         },
-               {
+        {
             name: "HUSH - Hush3",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.hush3;
                 setHdCoin(174);
             },
         },
-               {
+        {
             name: "PHR - Phore",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.phore;
                 setHdCoin(6);
             },
         },
-               {
+        {
             name: "PRJ - ProjectCoin",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.projectcoin;
               setHdCoin(19165);
             },
         },
-       {
+    {
           name: "SLS - Salus",
           onSelect: function() {
               network = bitcoinjs.bitcoin.networks.salus;
                 setHdCoin(181);
             },
         },
-               {
+        {
             name: "XAX - Artax",
             onSelect: function() {
                 network = bitcoinjs.bitcoin.networks.artax;