X-Git-Url: https://git.immae.eu/?p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FBIP39.git;a=blobdiff_plain;f=src%2Fjs%2Findex.js;h=d169ed28dc2ebcd808c2d1ec9edbb0b1455d3280;hp=52fb3ff94d32f94e739b794d501d03c8162b2e09;hb=f12242014d1ed5c7606c3350a9780c3883abc565;hpb=36523e0d9714a8ff9996ec3e062a8e16e28c3415 diff --git a/src/js/index.js b/src/js/index.js index 52fb3ff..d169ed2 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -16,6 +16,7 @@ var showQr = false; var litecoinUseLtub = true; + var entropyTypeAutoDetect = true; var entropyChangeTimeoutEvent = null; var phraseChangeTimeoutEvent = null; var rootKeyChangedTimeoutEvent = null; @@ -32,6 +33,7 @@ DOM.entropy = $(".entropy"); DOM.entropyFiltered = DOM.entropyContainer.find(".filtered"); DOM.entropyType = DOM.entropyContainer.find(".type"); + DOM.entropyTypeInputs = DOM.entropyContainer.find("input[name='entropy-type']"); DOM.entropyCrackTime = DOM.entropyContainer.find(".crack-time"); DOM.entropyEventCount = DOM.entropyContainer.find(".event-count"); DOM.entropyBits = DOM.entropyContainer.find(".bits"); @@ -44,6 +46,8 @@ DOM.entropyWeakEntropyOverrideWarning = DOM.entropyContainer.find(".weak-entropy-override-warning"); DOM.entropyFilterWarning = DOM.entropyContainer.find(".filter-warning"); DOM.phrase = $(".phrase"); + DOM.phraseSplit = $(".phraseSplit"); + DOM.phraseSplitWarn = $(".phraseSplitWarn"); DOM.passphrase = $(".passphrase"); DOM.generateContainer = $(".generate-container"); DOM.generate = $(".generate"); @@ -126,6 +130,7 @@ DOM.useEntropy.on("change", setEntropyVisibility); DOM.entropy.on("input", delayedEntropyChanged); DOM.entropyMnemonicLength.on("change", entropyChanged); + DOM.entropyTypeInputs.on("change", entropyTypeChanged); DOM.phrase.on("input", delayedPhraseChanged); DOM.passphrase.on("input", delayedPhraseChanged); DOM.generate.on("click", generateClicked); @@ -232,7 +237,16 @@ if (phraseChangeTimeoutEvent != null) { clearTimeout(phraseChangeTimeoutEvent); } - phraseChangeTimeoutEvent = setTimeout(phraseChanged, 400); + phraseChangeTimeoutEvent = setTimeout(function() { + phraseChanged(); + var entropy = mnemonic.toRawEntropyHex(DOM.phrase.val()); + if (entropy !== null) { + DOM.entropyMnemonicLength.val("raw"); + DOM.entropy.val(entropy); + DOM.entropyTypeInputs.filter("[value='hexadecimal']").prop("checked", true); + entropyTypeAutoDetect = false; + } + }, 400); } function phraseChanged() { @@ -251,6 +265,7 @@ calcForDerivationPath(); // Show the word indexes showWordIndexes(); + writeSplitPhrase(phrase); } function tabChanged() { @@ -297,6 +312,7 @@ clearDisplay(); clearEntropyFeedback(); DOM.phrase.val(""); + DOM.phraseSplit.val(""); showValidationError("Blank entropy"); return; } @@ -319,6 +335,11 @@ } } + function entropyTypeChanged() { + entropyTypeAutoDetect = false; + entropyChanged(); + } + function delayedRootKeyChanged() { // Warn if there is an existing mnemonic or passphrase. if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) { @@ -331,6 +352,7 @@ showPending(); // Clear existing mnemonic and passphrase DOM.phrase.val(""); + DOM.phraseSplit.val(""); DOM.passphrase.val(""); seed = null; if (rootKeyChangedTimeoutEvent != null) { @@ -527,6 +549,22 @@ } 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); @@ -669,6 +707,22 @@ } 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 { @@ -956,6 +1010,14 @@ (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; @@ -967,6 +1029,8 @@ var segwitAvailable = networkHasSegwit(); var isP2wpkh = p2wpkhSelected(); var isP2wpkhInP2sh = p2wpkhInP2shSelected(); + var isP2wsh = p2wshSelected(); + var isP2wshInP2sh = p2wshInP2shSelected(); function init() { calculateValues(); @@ -1021,19 +1085,7 @@ indexText = indexText + "'"; } // Ethereum values are different - if ((networks[DOM.network.val()].name == "ETH - Ethereum") - || (networks[DOM.network.val()].name == "ETC - Ethereum Classic") - || (networks[DOM.network.val()].name == "PIRL - Pirl") - || (networks[DOM.network.val()].name == "MIX - MIX") - || (networks[DOM.network.val()].name == "MUSIC - Musicoin") - || (networks[DOM.network.val()].name == "POA - Poa") - || (networks[DOM.network.val()].name == "EXP - Expanse") - || (networks[DOM.network.val()].name == "CLO - Callisto") - || (networks[DOM.network.val()].name == "DXN - DEXON") - || (networks[DOM.network.val()].name == "ELLA - Ellaism") - || (networks[DOM.network.val()].name == "ESN - Ethersocial Network") - || (networks[DOM.network.val()].name == "VET - VeChain") - ) { + if (networkIsEthereum()) { var privKeyBuffer = keyPair.d.toBuffer(32); privkey = privKeyBuffer.toString('hex'); var addressBuffer = ethUtil.privateToAddress(privKeyBuffer); @@ -1109,6 +1161,21 @@ var scriptpubkey = bitcoinjs.bitcoin.script.scriptHash.output.encode(addressbytes); address = bitcoinjs.bitcoin.address.fromOutputScript(scriptpubkey, network) } + else if (isP2wsh) { + // https://github.com/bitcoinjs/bitcoinjs-lib/blob/v3.3.2/test/integration/addresses.js#L71 + // This is a 1-of-1 + var witnessScript = bitcoinjs.bitcoin.script.multisig.output.encode(1, [key.getPublicKeyBuffer()]); + var scriptPubKey = bitcoinjs.bitcoin.script.witnessScriptHash.output.encode(bitcoinjs.bitcoin.crypto.sha256(witnessScript)); + address = bitcoinjs.bitcoin.address.fromOutputScript(scriptPubKey, network); + } + else if (isP2wshInP2sh) { + // https://github.com/bitcoinjs/bitcoinjs-lib/blob/v3.3.2/test/integration/transactions.js#L183 + // This is a 1-of-1 + var witnessScript = bitcoinjs.bitcoin.script.multisig.output.encode(1, [key.getPublicKeyBuffer()]); + var redeemScript = bitcoinjs.bitcoin.script.witnessScriptHash.output.encode(bitcoinjs.bitcoin.crypto.sha256(witnessScript)); + var scriptPubKey = bitcoinjs.bitcoin.script.scriptHash.output.encode(bitcoinjs.bitcoin.crypto.hash160(redeemScript)); + address = bitcoinjs.bitcoin.address.fromOutputScript(scriptPubKey, network) + } } if ((networks[DOM.network.val()].name == "CRW - Crown")) { @@ -1442,6 +1509,49 @@ return phrase; } + function writeSplitPhrase(phrase) { + var wordCount = phrase.split(/\s/g).length; + var left=[]; + for (var i=0;i0) { + 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