]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blobdiff - src/js/entropy.js
Replace most libraries with combined libs
[perso/Immae/Projets/Cryptomonnaies/BIP39.git] / src / js / entropy.js
index b7274bbea7ccb5781aa084b45d0219d5e99e4e0e..62b271125a4939ac8d2249cd9d1508cadf966ae9 100644 (file)
@@ -16,7 +16,7 @@
 
 window.Entropy = new (function() {
 
-    var TWO = new BigInteger(2);
+    var TWO = new libs.BigInteger.BigInteger(2);
 
     // matchers returns an array of the matched events for each type of entropy.
     // eg
@@ -67,9 +67,9 @@ window.Entropy = new (function() {
         return ints;
     }
 
-    this.fromString = function(rawEntropyStr) {
+    this.fromString = function(rawEntropyStr, baseStr) {
         // Find type of entropy being used (binary, hex, dice etc)
-        var base = getBase(rawEntropyStr);
+        var base = getBase(rawEntropyStr, baseStr);
         // Convert dice to base6 entropy (ie 1-6 to 0-5)
         // This is done by changing all 6s to 0s
         if (base.str == "dice") {
@@ -103,11 +103,11 @@ window.Entropy = new (function() {
         // Convert base.ints to BigInteger.
         // Due to using unusual bases, eg cards of base52, this is not as simple as
         // using BigInteger.parse()
-        var entropyInt = BigInteger.ZERO;
+        var entropyInt = libs.BigInteger.BigInteger.ZERO;
         for (var i=base.ints.length-1; i>=0; i--) {
-            var thisInt = BigInteger.parse(base.ints[i]);
+            var thisInt = libs.BigInteger.BigInteger.parse(base.ints[i]);
             var power = (base.ints.length - 1) - i;
-            var additionalEntropy = BigInteger.parse(base.asInt).pow(power).multiply(thisInt);
+            var additionalEntropy = libs.BigInteger.BigInteger.parse(base.asInt).pow(power).multiply(thisInt);
             entropyInt = entropyInt.add(additionalEntropy);
         }
         // Convert entropy to binary
@@ -166,13 +166,14 @@ window.Entropy = new (function() {
         return s;
     }
 
-    function getBase(str) {
+    function getBase(str, baseStr) {
         // Need to get the lowest base for the supplied entropy.
         // This prevents interpreting, say, dice rolls as hexadecimal.
         var binaryMatches = matchers.binary(str);
         var hexMatches = matchers.hex(str);
+        var autodetect = baseStr === undefined;
         // Find the lowest base that can be used, whilst ignoring any irrelevant chars
-        if (binaryMatches.length == hexMatches.length && hexMatches.length > 0) {
+        if ((binaryMatches.length == hexMatches.length && hexMatches.length > 0 && autodetect) || baseStr === "binary") {
             var ints = binaryMatches.map(function(i) { return parseInt(i, 2) });
             return {
                 ints: ints,
@@ -183,7 +184,7 @@ window.Entropy = new (function() {
             }
         }
         var cardMatches = matchers.card(str);
-        if (cardMatches.length >= hexMatches.length / 2) {
+        if ((cardMatches.length >= hexMatches.length / 2 && autodetect) || baseStr === "card") {
             var ints = convertCardsToInts(cardMatches);
             return {
                 ints: ints,
@@ -194,7 +195,7 @@ window.Entropy = new (function() {
             }
         }
         var diceMatches = matchers.dice(str);
-        if (diceMatches.length == hexMatches.length && hexMatches.length > 0) {
+        if ((diceMatches.length == hexMatches.length && hexMatches.length > 0 && autodetect) || baseStr === "dice") {
             var ints = diceMatches.map(function(i) { return parseInt(i) });
             return {
                 ints: ints,
@@ -205,7 +206,7 @@ window.Entropy = new (function() {
             }
         }
         var base6Matches = matchers.base6(str);
-        if (base6Matches.length == hexMatches.length && hexMatches.length > 0) {
+        if ((base6Matches.length == hexMatches.length && hexMatches.length > 0 && autodetect) || baseStr === "base 6") {
             var ints = base6Matches.map(function(i) { return parseInt(i) });
             return {
                 ints: ints,
@@ -216,7 +217,7 @@ window.Entropy = new (function() {
             }
         }
         var base10Matches = matchers.base10(str);
-        if (base10Matches.length == hexMatches.length && hexMatches.length > 0) {
+        if ((base10Matches.length == hexMatches.length && hexMatches.length > 0 && autodetect) || baseStr === "base 10") {
             var ints = base10Matches.map(function(i) { return parseInt(i) });
             return {
                 ints: ints,
@@ -263,7 +264,12 @@ window.Entropy = new (function() {
         }
         // Work out the total number of bits for this many decks
         // See http://crypto.stackexchange.com/q/41886
-        var gainedBits = Math.log2(factorial(52 * numberOfDecks));
+        var gainedBits = 0;
+        // Equivalent of Math.log2(factorial(52*numberOfDecks))
+        // which becomes infinity for numberOfDecks > 4
+        for (var i=1; i<=52*numberOfDecks; i++) {
+            gainedBits = gainedBits + Math.log2(i);
+        }
         var lostBits = 52 * Math.log2(factorial(numberOfDecks));
         var maxBits = gainedBits - lostBits;
         // Convert the drawn cards to a binary representation.
@@ -288,15 +294,12 @@ window.Entropy = new (function() {
         // Create a normalized string of the selected cards
         var normalizedCards = cards.join("").toUpperCase();
         // Convert to binary using the SHA256 hash of the normalized cards.
-        // If the number of bits is more than 256, multiple rounds of hashing
+        // If the number of bits is more than 256, multiple hashes
         // are used until the required number of bits is reached.
         var entropyBin = "";
         var iterations = 0;
         while (entropyBin.length < numberOfBits) {
-            var hashedCards = sjcl.hash.sha256.hash(normalizedCards);
-            for (var j=0; j<iterations; j++) {
-                hashedCards = sjcl.hash.sha256.hash(hashedCards);
-            }
+            var hashedCards = sjcl.hash.sha256.hash(normalizedCards + ":" + iterations);
             var hashHex = sjcl.codec.hex.fromBits(hashedCards);
             for (var i=0; i<hashHex.length; i++) {
                 var decimal = parseInt(hashHex[i], 16);
@@ -325,7 +328,7 @@ window.Entropy = new (function() {
         // Math.LOG2E
         // log2(8) gave 2.9999999999999996 which when floored causes issues.
         // So instead use the BigInteger library to get it right.
-        return BigInteger.log(x) / BigInteger.log(2);
+        return libs.BigInteger.BigInteger.log(x) / libs.BigInteger.BigInteger.log(2);
     };
 
     // Depends on BigInteger
@@ -333,9 +336,9 @@ window.Entropy = new (function() {
         if (n == 0) {
             return 1;
         }
-        f = BigInteger.ONE;
+        f = libs.BigInteger.BigInteger.ONE;
         for (var i=1; i<=n; i++) {
-            f = f.multiply(new BigInteger(i));
+            f = f.multiply(new libs.BigInteger.BigInteger(i));
         }
         return f;
     }