]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/commitdiff
Mnemonic length can be set when using raw entropy
authorIan Coleman <coleman.ian@gmail.com>
Thu, 10 Nov 2016 07:58:18 +0000 (18:58 +1100)
committerIan Coleman <coleman.ian@gmail.com>
Thu, 10 Nov 2016 07:58:18 +0000 (18:58 +1100)
src/index.html
src/js/index.js
tests.js

index feefbd83fa47b2c5aa4cbb51bc074d512a47e406..beda577e4c38f2adacf2b6a079c354c4ac967d9a 100644 (file)
                                     <label class="col-sm-2 control-label">Mnemonic Length</label>
                                     <div class="col-sm-10">
                                         <select class="mnemonic-length form-control">
-                                            <option value="raw">From entropy length</option>
+                                            <option value="raw">From entropy length (3 words per 32 bits)</option>
                                             <option value="12">12 Words</option>
                                             <option value="15">15 Words</option>
                                             <option value="18">18 Words</option>
index 45f378de867174fb710f54c5c8dd0b9ab93c6a8b..66585a95993a64aff9921657588f8b566e2ebd4f 100644 (file)
@@ -68,6 +68,7 @@
         DOM.network.on("change", networkChanged);
         DOM.useEntropy.on("change", setEntropyVisibility);
         DOM.entropy.on("input", delayedEntropyChanged);
+        DOM.entropyMnemonicLength.on("change", entropyChanged);
         DOM.phrase.on("input", delayedPhraseChanged);
         DOM.passphrase.on("input", delayedPhraseChanged);
         DOM.generate.on("click", generateClicked);
         }
         // Show entropy details
         showEntropyFeedback(entropy);
+        // Use entropy hash if not using raw entropy
+        var bits = entropy.binaryStr;
+        var mnemonicLength = DOM.entropyMnemonicLength.val();
+        if (mnemonicLength != "raw") {
+            // Get bits by hashing entropy with SHA256
+            var hash = sjcl.hash.sha256.hash(entropy.cleanStr);
+            var hex = sjcl.codec.hex.fromBits(hash);
+            bits = BigInteger.parse(hex, 16).toString(2);
+            for (var i=0; i<256-bits.length; i++) {
+                bits = "0" + bits;
+            }
+            // Truncate hash to suit number of words
+            mnemonicLength = parseInt(mnemonicLength);
+            var numberOfBits = 32 * mnemonicLength / 3;
+            bits = bits.substring(0, numberOfBits);
+        }
         // Discard trailing entropy
-        var bitsToUse = Math.floor(entropy.binaryStr.length / 32) * 32;
-        var binaryStr = entropy.binaryStr.substring(0, bitsToUse);
+        var bitsToUse = Math.floor(bits.length / 32) * 32;
+        var binaryStr = bits.substring(0, bitsToUse);
         // Convert entropy string to numeric array
         var entropyArr = [];
         for (var i=0; i<binaryStr.length / 8; i++) {
index 420873dc11bd2a126df003b5f15d62a08f6734aa..37a758f4f1e8626a11bcbf9301f88ef06ca01915 100644 (file)
--- a/tests.js
+++ b/tests.js
@@ -2774,6 +2774,31 @@ page.open(url, function(status) {
 });
 },
 
+// Mnemonic length can be selected even for weak entropy
+function() {
+page.open(url, function(status) {
+    // use entropy
+    page.evaluate(function() {
+        $(".use-entropy").prop("checked", true).trigger("change");
+        $(".entropy").val("012345");
+        $(".mnemonic-length").val("18").trigger("change");
+    });
+    // check the mnemonic is the correct length
+    waitForGenerate(function() {
+        var phrase = page.evaluate(function() {
+            return $(".phrase").val();
+        });
+        var numberOfWords = phrase.split(/\s/g).length;
+        if (numberOfWords != 18) {
+            console.log("Weak entropy cannot be overridden to give 18 word mnemonic");
+            console.log(phrase);
+            fail();
+        }
+        next();
+    });
+});
+},
+
 // If you wish to add more tests, do so here...
 
 // Here is a blank test template