aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Coleman <coleman.ian@gmail.com>2016-11-08 21:59:08 +1100
committerIan Coleman <coleman.ian@gmail.com>2016-11-08 21:59:08 +1100
commit0d0f07f9374078ba71cf7f81cd6c2ab8df8d4693 (patch)
tree0c4c900044065e6b4838375619d881145bdd2064
parent425b75a925717eb6f9813503569592a8160c5f34 (diff)
downloadBIP39-0d0f07f9374078ba71cf7f81cd6c2ab8df8d4693.tar.gz
BIP39-0d0f07f9374078ba71cf7f81cd6c2ab8df8d4693.tar.zst
BIP39-0d0f07f9374078ba71cf7f81cd6c2ab8df8d4693.zip
No leading zeros for first char unless hex
-rw-r--r--src/js/entropy.js28
-rw-r--r--tests.js58
2 files changed, 54 insertions, 32 deletions
diff --git a/src/js/entropy.js b/src/js/entropy.js
index 8e29d40..c804fda 100644
--- a/src/js/entropy.js
+++ b/src/js/entropy.js
@@ -71,17 +71,21 @@ window.Entropy = new (function() {
71 // This is done by changing all 6s to 0s 71 // This is done by changing all 6s to 0s
72 if (base.str == "dice") { 72 if (base.str == "dice") {
73 var newRawEntropyStr = ""; 73 var newRawEntropyStr = "";
74 var newInts = [];
74 for (var i=0; i<rawEntropyStr.length; i++) { 75 for (var i=0; i<rawEntropyStr.length; i++) {
75 var c = rawEntropyStr[i]; 76 var c = rawEntropyStr[i];
76 if ("12345".indexOf(c) > -1) { 77 if ("12345".indexOf(c) > -1) {
77 newRawEntropyStr += c; 78 newRawEntropyStr += c;
79 newInts[i] = base.ints[i];
78 } 80 }
79 else { 81 else {
80 newRawEntropyStr += "0"; 82 newRawEntropyStr += "0";
83 newInts[i] = 0;
81 } 84 }
82 } 85 }
83 rawEntropyStr = newRawEntropyStr; 86 rawEntropyStr = newRawEntropyStr;
84 base.str = "base 6 (dice)"; 87 base.str = "base 6 (dice)";
88 base.ints = newInts;
85 base.parts = matchers.base6(rawEntropyStr); 89 base.parts = matchers.base6(rawEntropyStr);
86 base.matcher = matchers.base6; 90 base.matcher = matchers.base6;
87 } 91 }
@@ -109,25 +113,23 @@ window.Entropy = new (function() {
109 if (base.ints.length == 0) { 113 if (base.ints.length == 0) {
110 return { 114 return {
111 binaryStr: binLeadingZeros, 115 binaryStr: binLeadingZeros,
112 cleanStr: leadingZeros, 116 cleanStr: leadingZeros.join(""),
113 base: base, 117 base: base,
114 } 118 }
115 } 119 }
116 // If the first integer is small, it must be padded with zeros. 120 // If the first integer is small, it must be padded with zeros.
117 // Otherwise the chance of the first bit being 1 is 100%, which is 121 // Otherwise the chance of the first bit being 1 is 100%, which is
118 // obviously incorrect. 122 // obviously incorrect.
119 // This is not perfect for unusual bases, eg base 6 has 2.6 bits, so is 123 // This is not perfect for unusual bases, so is only done for bases
120 // slightly biased toward having leading zeros, but it's still better 124 // of 2^n, eg octal or hexadecimal
121 // than ignoring it completely. 125 if (base.asInt == 16) {
122 // TODO: revise this, it seems very fishy. For example, in base 10, there are 126 var firstInt = base.ints[0];
123 // 8 opportunities to start with 0 but only 2 to start with 1 127 var firstIntBits = firstInt.toString(2).length;
124 var firstInt = base.ints[0]; 128 var maxFirstIntBits = (base.asInt-1).toString(2).length;
125 var firstIntBits = Math.floor(Math.log2(firstInt))+1; 129 var missingFirstIntBits = maxFirstIntBits - firstIntBits;
126 var maxFirstIntBits = Math.floor(Math.log2(base.asInt-1))+1; 130 for (var i=0; i<missingFirstIntBits; i++) {
127 var missingFirstIntBits = maxFirstIntBits - firstIntBits; 131 binLeadingZeros += "0";
128 var firstIntLeadingZeros = ""; 132 }
129 for (var i=0; i<missingFirstIntBits; i++) {
130 binLeadingZeros += "0";
131 } 133 }
132 // Convert base.ints to BigInteger. 134 // Convert base.ints to BigInteger.
133 // Due to using unusual bases, eg cards of base52, this is not as simple as 135 // Due to using unusual bases, eg cards of base52, this is not as simple as
diff --git a/tests.js b/tests.js
index 809162c..102144f 100644
--- a/tests.js
+++ b/tests.js
@@ -2130,11 +2130,31 @@ page.open(url, function(status) {
2130 catch (e) { 2130 catch (e) {
2131 return e.message; 2131 return e.message;
2132 } 2132 }
2133 // Leading zeros are correctly preserved for base 6 in binary string 2133 // Leading zeros are not used for base 6 as binary string
2134 try { 2134 try {
2135 e = Entropy.fromString("2"); 2135 e = Entropy.fromString("2");
2136 if (e.binaryStr != "010") { 2136 if (e.binaryStr != "10") {
2137 return "Base 6 leading zeros are not correct in binary"; 2137 return "Base 6 as binary has leading zeros";
2138 }
2139 }
2140 catch (e) {
2141 return e.message;
2142 }
2143 // Leading zeros are not used for base 10 as binary string
2144 try {
2145 e = Entropy.fromString("7");
2146 if (e.binaryStr != "111") {
2147 return "Base 10 as binary has leading zeros";
2148 }
2149 }
2150 catch (e) {
2151 return e.message;
2152 }
2153 // Leading zeros are not used for card entropy as binary string
2154 try {
2155 e = Entropy.fromString("2c");
2156 if (e.binaryStr != "1") {
2157 return "Card entropy as binary has leading zeros";
2138 } 2158 }
2139 } 2159 }
2140 catch (e) { 2160 catch (e) {
@@ -2167,19 +2187,19 @@ page.open(url, function(status) {
2167 var cards = [ 2187 var cards = [
2168 [ "ac", "00000" ], 2188 [ "ac", "00000" ],
2169 [ "acac", "00000000000" ], 2189 [ "acac", "00000000000" ],
2170 [ "acac2c", "00000000000000001" ], 2190 [ "acac2c", "000000000001" ],
2171 [ "acks", "00000110011" ], 2191 [ "acks", "00000110011" ],
2172 [ "acacks", "00000000000110011" ], 2192 [ "acacks", "00000000000110011" ],
2173 [ "2c", "000001" ], 2193 [ "2c", "1" ],
2174 [ "3d", "001111" ], 2194 [ "3d", "1111" ],
2175 [ "4h", "011101" ], 2195 [ "4h", "11101" ],
2176 [ "5s", "101011" ], 2196 [ "5s", "101011" ],
2177 [ "6c", "000101" ], 2197 [ "6c", "101" ],
2178 [ "7d", "010011" ], 2198 [ "7d", "10011" ],
2179 [ "8h", "100001" ], 2199 [ "8h", "100001" ],
2180 [ "9s", "101111" ], 2200 [ "9s", "101111" ],
2181 [ "tc", "001001" ], 2201 [ "tc", "1001" ],
2182 [ "jd", "010111" ], 2202 [ "jd", "10111" ],
2183 [ "qh", "100101" ], 2203 [ "qh", "100101" ],
2184 [ "ks", "110011" ], 2204 [ "ks", "110011" ],
2185 [ "ks2c", "101001011101" ], 2205 [ "ks2c", "101001011101" ],
@@ -2465,11 +2485,11 @@ page.open(url, function(status) {
2465 [ "0000 0000 0000 0000 0000", "20" ], 2485 [ "0000 0000 0000 0000 0000", "20" ],
2466 [ "0", "1" ], 2486 [ "0", "1" ],
2467 [ "0000", "4" ], 2487 [ "0000", "4" ],
2468 [ "6", "3" ], 2488 [ "6", "2" ], // 6 in card is 0 in base 6, 0 in base 6 is 2.6 bits (rounded down to 2 bits)
2469 [ "7", "4" ], 2489 [ "7", "3" ], // 7 in base 10 is 111 in base 2, no leading zeros
2470 [ "8", "4" ], 2490 [ "8", "4" ],
2471 [ "F", "4" ], 2491 [ "F", "4" ],
2472 [ "29", "7" ], 2492 [ "29", "5" ],
2473 [ "0A", "8" ], 2493 [ "0A", "8" ],
2474 [ "1A", "8" ], // hex is always multiple of 4 bits of entropy 2494 [ "1A", "8" ], // hex is always multiple of 4 bits of entropy
2475 [ "2A", "8" ], 2495 [ "2A", "8" ],
@@ -2477,9 +2497,9 @@ page.open(url, function(status) {
2477 [ "8A", "8" ], 2497 [ "8A", "8" ],
2478 [ "FA", "8" ], 2498 [ "FA", "8" ],
2479 [ "000A", "16" ], 2499 [ "000A", "16" ],
2480 [ "2220", "11" ], 2500 [ "5555", "11" ],
2481 [ "2221", "11" ], // uses dice, so entropy is actually 1110 2501 [ "6666", "10" ], // uses dice, so entropy is actually 0000 in base 6, which is 4 lots of 2.58 bits, which is 10.32 bits (rounded down to 10 bits)
2482 [ "2227", "14" ], 2502 [ "2227", "12" ],
2483 [ "222F", "16" ], 2503 [ "222F", "16" ],
2484 [ "FFFF", "16" ], 2504 [ "FFFF", "16" ],
2485 ] 2505 ]
@@ -2710,11 +2730,11 @@ page.open(url, function(status) {
2710// base 20 2730// base 20
2711function() { 2731function() {
2712page.open(url, function(status) { 2732page.open(url, function(status) {
2713 var expected = "defy trip fatal jaguar mean rack rifle survey satisfy drift twist champion steel wife state furnace night consider glove olympic oblige donor novel left"; 2733 var expected = "train then jungle barely whip fiber purpose puppy eagle cloud clump hospital robot brave balcony utility detect estate old green desk skill multiply virus";
2714 // use entropy 2734 // use entropy
2715 page.evaluate(function() { 2735 page.evaluate(function() {
2716 $(".use-entropy").prop("checked", true).trigger("change"); 2736 $(".use-entropy").prop("checked", true).trigger("change");
2717 var entropy = "123450123450123450123450123450123450123450123450123450123450123450123450123450123450123450123450123"; 2737 var entropy = "543210543210543210543210543210543210543210543210543210543210543210543210543210543210543210543210543";
2718 $(".entropy").val(entropy).trigger("input"); 2738 $(".entropy").val(entropy).trigger("input");
2719 }); 2739 });
2720 // check the mnemonic matches the expected value from bip32jp 2740 // check the mnemonic matches the expected value from bip32jp