aboutsummaryrefslogtreecommitdiff
path: root/src/js/entropy.js
diff options
context:
space:
mode:
authorIan Coleman <coleman.ian@gmail.com>2016-11-17 14:28:26 +1100
committerIan Coleman <coleman.ian@gmail.com>2016-11-17 14:28:26 +1100
commit6422c1cd57afbb4f0c71b0157ba6ad9598f82bc4 (patch)
tree935e8579a4f71fdd6e6f50ebf2294a46a80357ff /src/js/entropy.js
parentbbc29c80f429d7493fdb9cb7987000d633734db5 (diff)
downloadBIP39-6422c1cd57afbb4f0c71b0157ba6ad9598f82bc4.tar.gz
BIP39-6422c1cd57afbb4f0c71b0157ba6ad9598f82bc4.tar.zst
BIP39-6422c1cd57afbb4f0c71b0157ba6ad9598f82bc4.zip
Entropy library assumes cards are discarded
and removed the duplicate logic from the UI logic.
Diffstat (limited to 'src/js/entropy.js')
-rw-r--r--src/js/entropy.js46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/js/entropy.js b/src/js/entropy.js
index c28620a..5900346 100644
--- a/src/js/entropy.js
+++ b/src/js/entropy.js
@@ -117,6 +117,40 @@ window.Entropy = new (function() {
117 while (entropyBin.length < expectedBits) { 117 while (entropyBin.length < expectedBits) {
118 entropyBin = "0" + entropyBin; 118 entropyBin = "0" + entropyBin;
119 } 119 }
120 // Assume cards are NOT replaced.
121 // Additional entropy decreases as more cards are used. This means
122 // entropy is measured using n!, not base^n.
123 // eg the second last card can be only one of two, not one of fifty two
124 // so the added entropy for that card is only one bit at most
125 if (base.asInt == 52) {
126 // Get the maximum value without replacement
127 var totalDecks = Math.ceil(base.parts.length / 52);
128 var totalCards = totalDecks * 52;
129 var totalCombos = factorial(52).pow(totalDecks);
130 var totalRemainingCards = totalCards - base.parts.length;
131 var remainingDecks = Math.floor(totalRemainingCards / 52);
132 var remainingCards = totalRemainingCards % 52;
133 var remainingCombos = factorial(52).pow(remainingDecks).multiply(factorial(remainingCards));
134 var currentCombos = totalCombos.divide(remainingCombos);
135 var numberOfBits = Math.log2(currentCombos);
136 var maxWithoutReplace = BigInteger.pow(2, numberOfBits);
137 // aggresive flooring of numberOfBits by BigInteger.pow means a
138 // more accurate result can be had for small numbers using the
139 // built-in Math.pow function.
140 if (numberOfBits < 32) {
141 maxWithoutReplace = BigInteger(Math.round(Math.pow(2, numberOfBits)));
142 }
143 // Get the maximum value with replacement
144 var maxWithReplace = BigInteger.pow(52, base.parts.length);
145 // Calculate the new value by scaling the original value down
146 var withoutReplace = entropyInt.multiply(maxWithoutReplace).divide(maxWithReplace);
147 // Left pad with zeros based on number of bits
148 var entropyBin = withoutReplace.toString(2);
149 var numberOfBitsInt = Math.floor(numberOfBits);
150 while (entropyBin.length < numberOfBitsInt) {
151 entropyBin = "0" + entropyBin;
152 }
153 }
120 // Supply a 'filtered' entropy string for display purposes 154 // Supply a 'filtered' entropy string for display purposes
121 var entropyClean = base.parts.join(""); 155 var entropyClean = base.parts.join("");
122 var entropyHtml = base.parts.join(""); 156 var entropyHtml = base.parts.join("");
@@ -221,4 +255,16 @@ window.Entropy = new (function() {
221 return BigInteger.log(x) / BigInteger.log(2); 255 return BigInteger.log(x) / BigInteger.log(2);
222 }; 256 };
223 257
258 // Depends on BigInteger
259 function factorial(n) {
260 if (n == 0) {
261 return 1;
262 }
263 f = BigInteger.ONE;
264 for (var i=1; i<=n; i++) {
265 f = f.multiply(new BigInteger(i));
266 }
267 return f;
268 }
269
224})(); 270})();