aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/js/entropy.js46
-rw-r--r--src/js/index.js52
2 files changed, 56 insertions, 42 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})();
diff --git a/src/js/index.js b/src/js/index.js
index f4163ee..254b62f 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -791,20 +791,21 @@
791 } 791 }
792 792
793 function showEntropyFeedback(entropy) { 793 function showEntropyFeedback(entropy) {
794 var numberOfBits = entropy.binaryStr.length;
794 var strength = "extremely weak"; 795 var strength = "extremely weak";
795 if (entropy.binaryStr.length >= 64) { 796 if (numberOfBits >= 64) {
796 strength = "very weak"; 797 strength = "very weak";
797 } 798 }
798 if (entropy.binaryStr.length >= 96) { 799 if (numberOfBits >= 96) {
799 strength = "weak"; 800 strength = "weak";
800 } 801 }
801 if (entropy.binaryStr.length >= 128) { 802 if (numberOfBits >= 128) {
802 strength = "strong"; 803 strength = "strong";
803 } 804 }
804 if (entropy.binaryStr.length >= 160) { 805 if (numberOfBits >= 160) {
805 strength = "very strong"; 806 strength = "very strong";
806 } 807 }
807 if (entropy.binaryStr.length >= 192) { 808 if (numberOfBits >= 192) {
808 strength = "extremely strong"; 809 strength = "extremely strong";
809 } 810 }
810 // If time to crack is less than one day, and password is considered 811 // If time to crack is less than one day, and password is considered
@@ -825,38 +826,17 @@
825 console.log("Error detecting entropy strength with zxcvbn:"); 826 console.log("Error detecting entropy strength with zxcvbn:");
826 console.log(e); 827 console.log(e);
827 } 828 }
828 var bitsStr = getNumberOfEntropyBits(entropy);
829 var wordCount = Math.floor(entropy.binaryStr.length / 32) * 3;
830 var entropyTypeStr = getEntropyTypeStr(entropy); 829 var entropyTypeStr = getEntropyTypeStr(entropy);
830 var wordCount = Math.floor(numberOfBits / 32) * 3;
831 var bitsPerEvent = Math.log2(entropy.base.asInt).toFixed(2);
831 DOM.entropyFiltered.html(entropy.cleanHtml); 832 DOM.entropyFiltered.html(entropy.cleanHtml);
832 DOM.entropyType.text(entropyTypeStr); 833 DOM.entropyType.text(entropyTypeStr);
833 DOM.entropyStrength.text(strength); 834 DOM.entropyStrength.text(strength);
834 DOM.entropyEventCount.text(entropy.base.ints.length); 835 DOM.entropyEventCount.text(entropy.base.ints.length);
835 DOM.entropyBits.text(bitsStr); 836 DOM.entropyBits.text(numberOfBits);
836 DOM.entropyWordCount.text(wordCount); 837 DOM.entropyWordCount.text(wordCount);
837 DOM.entropyBinary.text(entropy.binaryStr); 838 DOM.entropyBinary.text(entropy.binaryStr);
838 DOM.entropyBitsPerEvent.text(Math.log2(entropy.base.asInt).toFixed(2)); 839 DOM.entropyBitsPerEvent.text(bitsPerEvent);
839 }
840
841 function getNumberOfEntropyBits(entropy) {
842 var bitsStr = entropy.binaryStr.length.toString();
843 // If using cards, assume they are not reused, thus additional entropy
844 // decreases as more cards are used. This means entropy is measured
845 // using n!, not base^n.
846 // eg the second last card can be only one of two, not one of fifty two
847 // so the added entropy for that card is only one bit at most
848 if (entropy.base.asInt == 52) {
849 var totalDecks = Math.ceil(entropy.base.parts.length / 52);
850 var totalCards = totalDecks * 52;
851 var totalCombos = factorial(52).pow(totalDecks);
852 var totalRemainingCards = totalCards - entropy.base.parts.length;
853 var remainingDecks = Math.floor(totalRemainingCards / 52);
854 var remainingCards = totalRemainingCards % 52;
855 var remainingCombos = factorial(52).pow(remainingDecks) * factorial(remainingCards);
856 var currentCombos = totalCombos.divide(remainingCombos);
857 bitsStr = currentCombos.toString(2).length.toString();
858 }
859 return bitsStr
860 } 840 }
861 841
862 function getEntropyTypeStr(entropy) { 842 function getEntropyTypeStr(entropy) {
@@ -922,18 +902,6 @@
922 return typeStr; 902 return typeStr;
923 } 903 }
924 904
925 // Depends on BigInteger
926 function factorial(n) {
927 if (n == 0) {
928 return 1;
929 }
930 f = BigInteger.ONE;
931 for (var i=1; i<=n; i++) {
932 f = f.multiply(new BigInteger(i));
933 }
934 return f;
935 }
936
937 var networks = [ 905 var networks = [
938 { 906 {
939 name: "Bitcoin", 907 name: "Bitcoin",