aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Coleman <coleman.ian@gmail.com>2016-11-03 16:34:56 +1100
committerIan Coleman <coleman.ian@gmail.com>2016-11-04 15:14:13 +1100
commitc6624d51f4e5607202e48903352574c47571baab (patch)
treeee57075575c8f9b88e13eb7efff083bb9fa2b39c
parentd737abf6809622228faf7d5fe54101e2d87d72a4 (diff)
downloadBIP39-c6624d51f4e5607202e48903352574c47571baab.tar.gz
BIP39-c6624d51f4e5607202e48903352574c47571baab.tar.zst
BIP39-c6624d51f4e5607202e48903352574c47571baab.zip
Entropy can be supplied by user
-rw-r--r--bip39-standalone.html1936
-rw-r--r--src/index.html56
-rw-r--r--src/js/entropy.js1774
-rw-r--r--src/js/index.js106
-rw-r--r--tests.js607
5 files changed, 4465 insertions, 14 deletions
diff --git a/bip39-standalone.html b/bip39-standalone.html
index 5993b86..e3af3a6 100644
--- a/bip39-standalone.html
+++ b/bip39-standalone.html
@@ -69,12 +69,14 @@
69 <div class="col-md-12"> 69 <div class="col-md-12">
70 <h2>Mnemonic</h2> 70 <h2>Mnemonic</h2>
71 <form class="form-horizontal" role="form"> 71 <form class="form-horizontal" role="form">
72 <div class="col-sm-2"></div>
73 <div class="col-sm-10">
74 <p>You can enter an existing BIP39 mnemonic, or generate a new random one. Typing your own twelve words will probably not work how you expect, since the words require a particular structure (the last word is a checksum)</p>
75 <p>For more info see the <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki" target="_blank">BIP39 spec</a></p>
76 </div>
77 <div class="form-group"> 72 <div class="form-group">
73 <div class="col-sm-2"></div>
74 <div class="col-sm-10">
75 <p>You can enter an existing BIP39 mnemonic, or generate a new random one. Typing your own twelve words will probably not work how you expect, since the words require a particular structure (the last word is a checksum)</p>
76 <p>For more info see the <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki" target="_blank">BIP39 spec</a></p>
77 </div>
78 </div>
79 <div class="form-group generate-container">
78 <label class="col-sm-2 control-label"></label> 80 <label class="col-sm-2 control-label"></label>
79 <div class="col-sm-10"> 81 <div class="col-sm-10">
80 <div class="form-inline"> 82 <div class="form-inline">
@@ -96,7 +98,30 @@
96 </div> 98 </div>
97 </div> 99 </div>
98 </div> 100 </div>
99 <div class="form-group"> 101 <div class="entropy-container hidden">
102 <label for="entropy" class="col-sm-2 control-label">Entropy</label>
103 <div class="col-sm-10">
104 <input id="entropy" class="entropy form-control" placeholder="Accepts binary, base 6, 6-sided dice, base 10, hexadecimal">
105 <span class="help-block">
106 <div class="text-danger">
107 This is an advanced feature.
108 Your mnemonic may be insecure if this feature is used incorrectly.
109 <a href="#entropy-notes">Read more</a>
110 </div>
111 <div class="text-danger entropy-error"></div>
112 </span>
113 </div>
114 </div>
115 <div class="form-group">
116 <div class="col-sm-2"></div>
117 <div class="col-sm-10 checkbox">
118 <label>
119 <input type="checkbox" class="use-entropy">
120 Supply my own source of entropy
121 </label>
122 </div>
123 </div>
124 <div class="form-group">
100 <label class="col-sm-2 control-label"></label> 125 <label class="col-sm-2 control-label"></label>
101 <div class="col-sm-10 languages"> 126 <div class="col-sm-10 languages">
102 <a href="#english">English</a> 127 <a href="#english">English</a>
@@ -357,6 +382,24 @@
357 but be careful - it can be easy to make mistakes if you 382 but be careful - it can be easy to make mistakes if you
358 don't know what you're doing 383 don't know what you're doing
359 </p> 384 </p>
385 <h3 id="entropy-notes">Entropy</h3>
386 <p>
387 Entropy values must be sourced from a
388 <a href="https://en.wikipedia.org/wiki/Random_number_generation" target="_blank">strong source of randomness</a>.
389 This means flipping a fair coin, rolling a fair dice, noise measurements etc. Do <strong>NOT</strong> use
390 phrases from books, lyrics from songs, your birthday or steet address, keyboard mashing, or anything you <i>think</i>
391 is random, because chances are <em>overwhelming</em> that it isn't random enough for the needs of this tool.
392 </p>
393 <p>
394 The random mnemonic generator on this page uses a
395 <a href="https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues" target="_blank">cryptographically secure random number generator</a>,
396 and can generally be trusted more than your own intuition about randomness.
397 If cryptographic randomness isn't available in your browser, this page will show a warning and <i>will not generate
398 random mnemonics</i>.
399 </p>
400 <p>
401 <a href="https://bitcointalk.org/index.php?topic=311000.msg3345309#msg3345309" target="_blank">You are not a good source of entropy.</a>
402 </p>
360 </div> 403 </div>
361 </div> 404 </div>
362 405
@@ -16169,6 +16212,1781 @@ var Mnemonic = function(language) {
16169 16212
16170} 16213}
16171</script> 16214</script>
16215 <script>window.Entropy = new (function() {
16216
16217 var matchers = {
16218 binary: /[0-1]/gi,
16219 base6: /[0-5]/gi,
16220 dice: /[1-6]/gi, // ie dice numbers
16221 base10: /[0-9]/gi,
16222 hex: /[0-9A-F]/gi,
16223 }
16224
16225 this.fromString = function(rawEntropyStr) {
16226 // Find type of entropy being used (binary, hex, dice etc)
16227 var base = getBase(rawEntropyStr);
16228 // Convert dice to base6 entropy (ie 1-6 to 0-5)
16229 if (base.str == "dice") {
16230 var newRawEntropyStr = "";
16231 for (var i=0; i<rawEntropyStr.length; i++) {
16232 var c = rawEntropyStr[i];
16233 if ("123456".indexOf(c) > -1) {
16234 newRawEntropyStr += (parseInt(c) - 1).toString();
16235 }
16236 else {
16237 newRawEntropyStr += c
16238 }
16239 }
16240 rawEntropyStr = newRawEntropyStr;
16241 base.str = "base 6 (dice)";
16242 base.matcher = matchers.base6;
16243 }
16244 var entropyParts = rawEntropyStr.match(base.matcher) || [];
16245 var entropyStr = entropyParts.join("");
16246 // Detect empty entropy
16247 if (entropyStr.length == 0) {
16248 return {
16249 binaryStr: "",
16250 hexStr: "",
16251 cleanStr: "",
16252 base: base,
16253 };
16254 }
16255 // Pull leading zeros off
16256 var leadingZeros = "";
16257 while (entropyStr[0] == "0") {
16258 leadingZeros += "0";
16259 entropyStr = entropyStr.substring(1);
16260 }
16261 // Convert leading zeros to binary equivalent
16262 var numBinLeadingZeros = Math.ceil(Math.log2(base.asInt) * leadingZeros.length);
16263 var binLeadingZeros = "";
16264 for (var i=0; i<numBinLeadingZeros; i++) {
16265 binLeadingZeros += "0";
16266 }
16267 // Convert leading zeros to hex equivalent
16268 var numHexLeadingZeros = Math.floor(numBinLeadingZeros / 4);
16269 var hexLeadingZeros = "";
16270 for (var i=0; i<numHexLeadingZeros; i++) {
16271 hexLeadingZeros += "0";
16272 }
16273 // Handle entropy of zero
16274 if (entropyStr == "") {
16275 return {
16276 binaryStr: binLeadingZeros,
16277 hexStr: hexLeadingZeros || "0",
16278 cleanStr: leadingZeros,
16279 base: base,
16280 }
16281 }
16282 // If using hex, should always be multiples of 4 bits, which can get
16283 // out of sync if first number has leading 0 bits, eg 2 in hex is 0010
16284 // which would show up as 10, thus missing 2 bits it should have.
16285 if (base.asInt == 16) {
16286 var firstDigit = parseInt(entropyStr[0], 16);
16287 if (firstDigit >= 4 && firstDigit < 8) {
16288 binLeadingZeros += "0";
16289 }
16290 else if (firstDigit >= 2 && firstDigit < 4) {
16291 binLeadingZeros += "00";
16292 }
16293 else if (firstDigit >= 1 && firstDigit < 2) {
16294 binLeadingZeros += "000";
16295 }
16296 }
16297 // Convert entropy to different foramts
16298 var entropyInt = BigInteger.parse(entropyStr, base.asInt);
16299 var entropyBin = binLeadingZeros + entropyInt.toString(2);
16300 var entropyHex = hexLeadingZeros + entropyInt.toString(16);
16301 var entropyClean = leadingZeros + entropyStr;
16302 var e = {
16303 binaryStr: entropyBin,
16304 hexStr: entropyHex,
16305 cleanStr: entropyClean,
16306 base: base,
16307 }
16308 return e;
16309 }
16310
16311 function getBase(str) {
16312 // Need to get the lowest base for the supplied entropy.
16313 // This prevents interpreting, say, dice rolls as hexadecimal.
16314 var binaryMatches = str.match(matchers.binary) || [];
16315 var base6Matches = str.match(matchers.base6) || [];
16316 var diceMatches = str.match(matchers.dice) || [];
16317 var base10Matches = str.match(matchers.base10) || [];
16318 var hexMatches = str.match(matchers.hex) || [];
16319 // Find the lowest base that can be used, whilst ignoring any irrelevant chars
16320 if (binaryMatches.length == hexMatches.length) {
16321 return {
16322 matcher: matchers.binary,
16323 asInt: 2,
16324 str: "binary",
16325 }
16326 }
16327 if (diceMatches.length == hexMatches.length) {
16328 return {
16329 matcher: matchers.dice,
16330 asInt: 6,
16331 str: "dice",
16332 }
16333 }
16334 if (base6Matches.length == hexMatches.length) {
16335 return {
16336 matcher: matchers.base6,
16337 asInt: 6,
16338 str: "base 6",
16339 }
16340 }
16341 if (base10Matches.length == hexMatches.length) {
16342 return {
16343 matcher: matchers.base10,
16344 asInt: 10,
16345 str: "base 10",
16346 }
16347 }
16348 return {
16349 matcher: matchers.hex,
16350 asInt: 16,
16351 str: "hexadecimal",
16352 }
16353 }
16354
16355 // Polyfill for Math.log2
16356 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2#Polyfill
16357 Math.log2 = Math.log2 || function(x) {
16358 return Math.log(x) * Math.LOG2E;
16359 };
16360
16361})();
16362
16363
16364// BigInteger library included here because
16365// only the entropy library depends on it
16366// so if entropy detection is removed so is the dependency
16367
16368
16369/*
16370 JavaScript BigInteger library version 0.9.1
16371 http://silentmatt.com/biginteger/
16372
16373 Copyright (c) 2009 Matthew Crumley <email@matthewcrumley.com>
16374 Copyright (c) 2010,2011 by John Tobey <John.Tobey@gmail.com>
16375 Licensed under the MIT license.
16376
16377 Support for arbitrary internal representation base was added by
16378 Vitaly Magerya.
16379*/
16380
16381/*
16382 File: biginteger.js
16383
16384 Exports:
16385
16386 <BigInteger>
16387*/
16388(function(exports) {
16389"use strict";
16390/*
16391 Class: BigInteger
16392 An arbitrarily-large integer.
16393
16394 <BigInteger> objects should be considered immutable. None of the "built-in"
16395 methods modify *this* or their arguments. All properties should be
16396 considered private.
16397
16398 All the methods of <BigInteger> instances can be called "statically". The
16399 static versions are convenient if you don't already have a <BigInteger>
16400 object.
16401
16402 As an example, these calls are equivalent.
16403
16404 > BigInteger(4).multiply(5); // returns BigInteger(20);
16405 > BigInteger.multiply(4, 5); // returns BigInteger(20);
16406
16407 > var a = 42;
16408 > var a = BigInteger.toJSValue("0b101010"); // Not completely useless...
16409*/
16410
16411var CONSTRUCT = {}; // Unique token to call "private" version of constructor
16412
16413/*
16414 Constructor: BigInteger()
16415 Convert a value to a <BigInteger>.
16416
16417 Although <BigInteger()> is the constructor for <BigInteger> objects, it is
16418 best not to call it as a constructor. If *n* is a <BigInteger> object, it is
16419 simply returned as-is. Otherwise, <BigInteger()> is equivalent to <parse>
16420 without a radix argument.
16421
16422 > var n0 = BigInteger(); // Same as <BigInteger.ZERO>
16423 > var n1 = BigInteger("123"); // Create a new <BigInteger> with value 123
16424 > var n2 = BigInteger(123); // Create a new <BigInteger> with value 123
16425 > var n3 = BigInteger(n2); // Return n2, unchanged
16426
16427 The constructor form only takes an array and a sign. *n* must be an
16428 array of numbers in little-endian order, where each digit is between 0
16429 and BigInteger.base. The second parameter sets the sign: -1 for
16430 negative, +1 for positive, or 0 for zero. The array is *not copied and
16431 may be modified*. If the array contains only zeros, the sign parameter
16432 is ignored and is forced to zero.
16433
16434 > new BigInteger([5], -1): create a new BigInteger with value -5
16435
16436 Parameters:
16437
16438 n - Value to convert to a <BigInteger>.
16439
16440 Returns:
16441
16442 A <BigInteger> value.
16443
16444 See Also:
16445
16446 <parse>, <BigInteger>
16447*/
16448function BigInteger(n, s, token) {
16449 if (token !== CONSTRUCT) {
16450 if (n instanceof BigInteger) {
16451 return n;
16452 }
16453 else if (typeof n === "undefined") {
16454 return ZERO;
16455 }
16456 return BigInteger.parse(n);
16457 }
16458
16459 n = n || []; // Provide the nullary constructor for subclasses.
16460 while (n.length && !n[n.length - 1]) {
16461 --n.length;
16462 }
16463 this._d = n;
16464 this._s = n.length ? (s || 1) : 0;
16465}
16466
16467BigInteger._construct = function(n, s) {
16468 return new BigInteger(n, s, CONSTRUCT);
16469};
16470
16471// Base-10 speedup hacks in parse, toString, exp10 and log functions
16472// require base to be a power of 10. 10^7 is the largest such power
16473// that won't cause a precision loss when digits are multiplied.
16474var BigInteger_base = 10000000;
16475var BigInteger_base_log10 = 7;
16476
16477BigInteger.base = BigInteger_base;
16478BigInteger.base_log10 = BigInteger_base_log10;
16479
16480var ZERO = new BigInteger([], 0, CONSTRUCT);
16481// Constant: ZERO
16482// <BigInteger> 0.
16483BigInteger.ZERO = ZERO;
16484
16485var ONE = new BigInteger([1], 1, CONSTRUCT);
16486// Constant: ONE
16487// <BigInteger> 1.
16488BigInteger.ONE = ONE;
16489
16490var M_ONE = new BigInteger(ONE._d, -1, CONSTRUCT);
16491// Constant: M_ONE
16492// <BigInteger> -1.
16493BigInteger.M_ONE = M_ONE;
16494
16495// Constant: _0
16496// Shortcut for <ZERO>.
16497BigInteger._0 = ZERO;
16498
16499// Constant: _1
16500// Shortcut for <ONE>.
16501BigInteger._1 = ONE;
16502
16503/*
16504 Constant: small
16505 Array of <BigIntegers> from 0 to 36.
16506
16507 These are used internally for parsing, but useful when you need a "small"
16508 <BigInteger>.
16509
16510 See Also:
16511
16512 <ZERO>, <ONE>, <_0>, <_1>
16513*/
16514BigInteger.small = [
16515 ZERO,
16516 ONE,
16517 /* Assuming BigInteger_base > 36 */
16518 new BigInteger( [2], 1, CONSTRUCT),
16519 new BigInteger( [3], 1, CONSTRUCT),
16520 new BigInteger( [4], 1, CONSTRUCT),
16521 new BigInteger( [5], 1, CONSTRUCT),
16522 new BigInteger( [6], 1, CONSTRUCT),
16523 new BigInteger( [7], 1, CONSTRUCT),
16524 new BigInteger( [8], 1, CONSTRUCT),
16525 new BigInteger( [9], 1, CONSTRUCT),
16526 new BigInteger([10], 1, CONSTRUCT),
16527 new BigInteger([11], 1, CONSTRUCT),
16528 new BigInteger([12], 1, CONSTRUCT),
16529 new BigInteger([13], 1, CONSTRUCT),
16530 new BigInteger([14], 1, CONSTRUCT),
16531 new BigInteger([15], 1, CONSTRUCT),
16532 new BigInteger([16], 1, CONSTRUCT),
16533 new BigInteger([17], 1, CONSTRUCT),
16534 new BigInteger([18], 1, CONSTRUCT),
16535 new BigInteger([19], 1, CONSTRUCT),
16536 new BigInteger([20], 1, CONSTRUCT),
16537 new BigInteger([21], 1, CONSTRUCT),
16538 new BigInteger([22], 1, CONSTRUCT),
16539 new BigInteger([23], 1, CONSTRUCT),
16540 new BigInteger([24], 1, CONSTRUCT),
16541 new BigInteger([25], 1, CONSTRUCT),
16542 new BigInteger([26], 1, CONSTRUCT),
16543 new BigInteger([27], 1, CONSTRUCT),
16544 new BigInteger([28], 1, CONSTRUCT),
16545 new BigInteger([29], 1, CONSTRUCT),
16546 new BigInteger([30], 1, CONSTRUCT),
16547 new BigInteger([31], 1, CONSTRUCT),
16548 new BigInteger([32], 1, CONSTRUCT),
16549 new BigInteger([33], 1, CONSTRUCT),
16550 new BigInteger([34], 1, CONSTRUCT),
16551 new BigInteger([35], 1, CONSTRUCT),
16552 new BigInteger([36], 1, CONSTRUCT)
16553];
16554
16555// Used for parsing/radix conversion
16556BigInteger.digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
16557
16558/*
16559 Method: toString
16560 Convert a <BigInteger> to a string.
16561
16562 When *base* is greater than 10, letters are upper case.
16563
16564 Parameters:
16565
16566 base - Optional base to represent the number in (default is base 10).
16567 Must be between 2 and 36 inclusive, or an Error will be thrown.
16568
16569 Returns:
16570
16571 The string representation of the <BigInteger>.
16572*/
16573BigInteger.prototype.toString = function(base) {
16574 base = +base || 10;
16575 if (base < 2 || base > 36) {
16576 throw new Error("illegal radix " + base + ".");
16577 }
16578 if (this._s === 0) {
16579 return "0";
16580 }
16581 if (base === 10) {
16582 var str = this._s < 0 ? "-" : "";
16583 str += this._d[this._d.length - 1].toString();
16584 for (var i = this._d.length - 2; i >= 0; i--) {
16585 var group = this._d[i].toString();
16586 while (group.length < BigInteger_base_log10) group = '0' + group;
16587 str += group;
16588 }
16589 return str;
16590 }
16591 else {
16592 var numerals = BigInteger.digits;
16593 base = BigInteger.small[base];
16594 var sign = this._s;
16595
16596 var n = this.abs();
16597 var digits = [];
16598 var digit;
16599
16600 while (n._s !== 0) {
16601 var divmod = n.divRem(base);
16602 n = divmod[0];
16603 digit = divmod[1];
16604 // TODO: This could be changed to unshift instead of reversing at the end.
16605 // Benchmark both to compare speeds.
16606 digits.push(numerals[digit.valueOf()]);
16607 }
16608 return (sign < 0 ? "-" : "") + digits.reverse().join("");
16609 }
16610};
16611
16612// Verify strings for parsing
16613BigInteger.radixRegex = [
16614 /^$/,
16615 /^$/,
16616 /^[01]*$/,
16617 /^[012]*$/,
16618 /^[0-3]*$/,
16619 /^[0-4]*$/,
16620 /^[0-5]*$/,
16621 /^[0-6]*$/,
16622 /^[0-7]*$/,
16623 /^[0-8]*$/,
16624 /^[0-9]*$/,
16625 /^[0-9aA]*$/,
16626 /^[0-9abAB]*$/,
16627 /^[0-9abcABC]*$/,
16628 /^[0-9a-dA-D]*$/,
16629 /^[0-9a-eA-E]*$/,
16630 /^[0-9a-fA-F]*$/,
16631 /^[0-9a-gA-G]*$/,
16632 /^[0-9a-hA-H]*$/,
16633 /^[0-9a-iA-I]*$/,
16634 /^[0-9a-jA-J]*$/,
16635 /^[0-9a-kA-K]*$/,
16636 /^[0-9a-lA-L]*$/,
16637 /^[0-9a-mA-M]*$/,
16638 /^[0-9a-nA-N]*$/,
16639 /^[0-9a-oA-O]*$/,
16640 /^[0-9a-pA-P]*$/,
16641 /^[0-9a-qA-Q]*$/,
16642 /^[0-9a-rA-R]*$/,
16643 /^[0-9a-sA-S]*$/,
16644 /^[0-9a-tA-T]*$/,
16645 /^[0-9a-uA-U]*$/,
16646 /^[0-9a-vA-V]*$/,
16647 /^[0-9a-wA-W]*$/,
16648 /^[0-9a-xA-X]*$/,
16649 /^[0-9a-yA-Y]*$/,
16650 /^[0-9a-zA-Z]*$/
16651];
16652
16653/*
16654 Function: parse
16655 Parse a string into a <BigInteger>.
16656
16657 *base* is optional but, if provided, must be from 2 to 36 inclusive. If
16658 *base* is not provided, it will be guessed based on the leading characters
16659 of *s* as follows:
16660
16661 - "0x" or "0X": *base* = 16
16662 - "0c" or "0C": *base* = 8
16663 - "0b" or "0B": *base* = 2
16664 - else: *base* = 10
16665
16666 If no base is provided, or *base* is 10, the number can be in exponential
16667 form. For example, these are all valid:
16668
16669 > BigInteger.parse("1e9"); // Same as "1000000000"
16670 > BigInteger.parse("1.234*10^3"); // Same as 1234
16671 > BigInteger.parse("56789 * 10 ** -2"); // Same as 567
16672
16673 If any characters fall outside the range defined by the radix, an exception
16674 will be thrown.
16675
16676 Parameters:
16677
16678 s - The string to parse.
16679 base - Optional radix (default is to guess based on *s*).
16680
16681 Returns:
16682
16683 a <BigInteger> instance.
16684*/
16685BigInteger.parse = function(s, base) {
16686 // Expands a number in exponential form to decimal form.
16687 // expandExponential("-13.441*10^5") === "1344100";
16688 // expandExponential("1.12300e-1") === "0.112300";
16689 // expandExponential(1000000000000000000000000000000) === "1000000000000000000000000000000";
16690 function expandExponential(str) {
16691 str = str.replace(/\s*[*xX]\s*10\s*(\^|\*\*)\s*/, "e");
16692
16693 return str.replace(/^([+\-])?(\d+)\.?(\d*)[eE]([+\-]?\d+)$/, function(x, s, n, f, c) {
16694 c = +c;
16695 var l = c < 0;
16696 var i = n.length + c;
16697 x = (l ? n : f).length;
16698 c = ((c = Math.abs(c)) >= x ? c - x + l : 0);
16699 var z = (new Array(c + 1)).join("0");
16700 var r = n + f;
16701 return (s || "") + (l ? r = z + r : r += z).substr(0, i += l ? z.length : 0) + (i < r.length ? "." + r.substr(i) : "");
16702 });
16703 }
16704
16705 s = s.toString();
16706 if (typeof base === "undefined" || +base === 10) {
16707 s = expandExponential(s);
16708 }
16709
16710 var prefixRE;
16711 if (typeof base === "undefined") {
16712 prefixRE = '0[xcb]';
16713 }
16714 else if (base == 16) {
16715 prefixRE = '0x';
16716 }
16717 else if (base == 8) {
16718 prefixRE = '0c';
16719 }
16720 else if (base == 2) {
16721 prefixRE = '0b';
16722 }
16723 else {
16724 prefixRE = '';
16725 }
16726 var parts = new RegExp('^([+\\-]?)(' + prefixRE + ')?([0-9a-z]*)(?:\\.\\d*)?$', 'i').exec(s);
16727 if (parts) {
16728 var sign = parts[1] || "+";
16729 var baseSection = parts[2] || "";
16730 var digits = parts[3] || "";
16731
16732 if (typeof base === "undefined") {
16733 // Guess base
16734 if (baseSection === "0x" || baseSection === "0X") { // Hex
16735 base = 16;
16736 }
16737 else if (baseSection === "0c" || baseSection === "0C") { // Octal
16738 base = 8;
16739 }
16740 else if (baseSection === "0b" || baseSection === "0B") { // Binary
16741 base = 2;
16742 }
16743 else {
16744 base = 10;
16745 }
16746 }
16747 else if (base < 2 || base > 36) {
16748 throw new Error("Illegal radix " + base + ".");
16749 }
16750
16751 base = +base;
16752
16753 // Check for digits outside the range
16754 if (!(BigInteger.radixRegex[base].test(digits))) {
16755 throw new Error("Bad digit for radix " + base);
16756 }
16757
16758 // Strip leading zeros, and convert to array
16759 digits = digits.replace(/^0+/, "").split("");
16760 if (digits.length === 0) {
16761 return ZERO;
16762 }
16763
16764 // Get the sign (we know it's not zero)
16765 sign = (sign === "-") ? -1 : 1;
16766
16767 // Optimize 10
16768 if (base == 10) {
16769 var d = [];
16770 while (digits.length >= BigInteger_base_log10) {
16771 d.push(parseInt(digits.splice(digits.length-BigInteger.base_log10, BigInteger.base_log10).join(''), 10));
16772 }
16773 d.push(parseInt(digits.join(''), 10));
16774 return new BigInteger(d, sign, CONSTRUCT);
16775 }
16776
16777 // Do the conversion
16778 var d = ZERO;
16779 base = BigInteger.small[base];
16780 var small = BigInteger.small;
16781 for (var i = 0; i < digits.length; i++) {
16782 d = d.multiply(base).add(small[parseInt(digits[i], 36)]);
16783 }
16784 return new BigInteger(d._d, sign, CONSTRUCT);
16785 }
16786 else {
16787 throw new Error("Invalid BigInteger format: " + s);
16788 }
16789};
16790
16791/*
16792 Function: add
16793 Add two <BigIntegers>.
16794
16795 Parameters:
16796
16797 n - The number to add to *this*. Will be converted to a <BigInteger>.
16798
16799 Returns:
16800
16801 The numbers added together.
16802
16803 See Also:
16804
16805 <subtract>, <multiply>, <quotient>, <next>
16806*/
16807BigInteger.prototype.add = function(n) {
16808 if (this._s === 0) {
16809 return BigInteger(n);
16810 }
16811
16812 n = BigInteger(n);
16813 if (n._s === 0) {
16814 return this;
16815 }
16816 if (this._s !== n._s) {
16817 n = n.negate();
16818 return this.subtract(n);
16819 }
16820
16821 var a = this._d;
16822 var b = n._d;
16823 var al = a.length;
16824 var bl = b.length;
16825 var sum = new Array(Math.max(al, bl) + 1);
16826 var size = Math.min(al, bl);
16827 var carry = 0;
16828 var digit;
16829
16830 for (var i = 0; i < size; i++) {
16831 digit = a[i] + b[i] + carry;
16832 sum[i] = digit % BigInteger_base;
16833 carry = (digit / BigInteger_base) | 0;
16834 }
16835 if (bl > al) {
16836 a = b;
16837 al = bl;
16838 }
16839 for (i = size; carry && i < al; i++) {
16840 digit = a[i] + carry;
16841 sum[i] = digit % BigInteger_base;
16842 carry = (digit / BigInteger_base) | 0;
16843 }
16844 if (carry) {
16845 sum[i] = carry;
16846 }
16847
16848 for ( ; i < al; i++) {
16849 sum[i] = a[i];
16850 }
16851
16852 return new BigInteger(sum, this._s, CONSTRUCT);
16853};
16854
16855/*
16856 Function: negate
16857 Get the additive inverse of a <BigInteger>.
16858
16859 Returns:
16860
16861 A <BigInteger> with the same magnatude, but with the opposite sign.
16862
16863 See Also:
16864
16865 <abs>
16866*/
16867BigInteger.prototype.negate = function() {
16868 return new BigInteger(this._d, (-this._s) | 0, CONSTRUCT);
16869};
16870
16871/*
16872 Function: abs
16873 Get the absolute value of a <BigInteger>.
16874
16875 Returns:
16876
16877 A <BigInteger> with the same magnatude, but always positive (or zero).
16878
16879 See Also:
16880
16881 <negate>
16882*/
16883BigInteger.prototype.abs = function() {
16884 return (this._s < 0) ? this.negate() : this;
16885};
16886
16887/*
16888 Function: subtract
16889 Subtract two <BigIntegers>.
16890
16891 Parameters:
16892
16893 n - The number to subtract from *this*. Will be converted to a <BigInteger>.
16894
16895 Returns:
16896
16897 The *n* subtracted from *this*.
16898
16899 See Also:
16900
16901 <add>, <multiply>, <quotient>, <prev>
16902*/
16903BigInteger.prototype.subtract = function(n) {
16904 if (this._s === 0) {
16905 return BigInteger(n).negate();
16906 }
16907
16908 n = BigInteger(n);
16909 if (n._s === 0) {
16910 return this;
16911 }
16912 if (this._s !== n._s) {
16913 n = n.negate();
16914 return this.add(n);
16915 }
16916
16917 var m = this;
16918 // negative - negative => -|a| - -|b| => -|a| + |b| => |b| - |a|
16919 if (this._s < 0) {
16920 m = new BigInteger(n._d, 1, CONSTRUCT);
16921 n = new BigInteger(this._d, 1, CONSTRUCT);
16922 }
16923
16924 // Both are positive => a - b
16925 var sign = m.compareAbs(n);
16926 if (sign === 0) {
16927 return ZERO;
16928 }
16929 else if (sign < 0) {
16930 // swap m and n
16931 var t = n;
16932 n = m;
16933 m = t;
16934 }
16935
16936 // a > b
16937 var a = m._d;
16938 var b = n._d;
16939 var al = a.length;
16940 var bl = b.length;
16941 var diff = new Array(al); // al >= bl since a > b
16942 var borrow = 0;
16943 var i;
16944 var digit;
16945
16946 for (i = 0; i < bl; i++) {
16947 digit = a[i] - borrow - b[i];
16948 if (digit < 0) {
16949 digit += BigInteger_base;
16950 borrow = 1;
16951 }
16952 else {
16953 borrow = 0;
16954 }
16955 diff[i] = digit;
16956 }
16957 for (i = bl; i < al; i++) {
16958 digit = a[i] - borrow;
16959 if (digit < 0) {
16960 digit += BigInteger_base;
16961 }
16962 else {
16963 diff[i++] = digit;
16964 break;
16965 }
16966 diff[i] = digit;
16967 }
16968 for ( ; i < al; i++) {
16969 diff[i] = a[i];
16970 }
16971
16972 return new BigInteger(diff, sign, CONSTRUCT);
16973};
16974
16975(function() {
16976 function addOne(n, sign) {
16977 var a = n._d;
16978 var sum = a.slice();
16979 var carry = true;
16980 var i = 0;
16981
16982 while (true) {
16983 var digit = (a[i] || 0) + 1;
16984 sum[i] = digit % BigInteger_base;
16985 if (digit <= BigInteger_base - 1) {
16986 break;
16987 }
16988 ++i;
16989 }
16990
16991 return new BigInteger(sum, sign, CONSTRUCT);
16992 }
16993
16994 function subtractOne(n, sign) {
16995 var a = n._d;
16996 var sum = a.slice();
16997 var borrow = true;
16998 var i = 0;
16999
17000 while (true) {
17001 var digit = (a[i] || 0) - 1;
17002 if (digit < 0) {
17003 sum[i] = digit + BigInteger_base;
17004 }
17005 else {
17006 sum[i] = digit;
17007 break;
17008 }
17009 ++i;
17010 }
17011
17012 return new BigInteger(sum, sign, CONSTRUCT);
17013 }
17014
17015 /*
17016 Function: next
17017 Get the next <BigInteger> (add one).
17018
17019 Returns:
17020
17021 *this* + 1.
17022
17023 See Also:
17024
17025 <add>, <prev>
17026 */
17027 BigInteger.prototype.next = function() {
17028 switch (this._s) {
17029 case 0:
17030 return ONE;
17031 case -1:
17032 return subtractOne(this, -1);
17033 // case 1:
17034 default:
17035 return addOne(this, 1);
17036 }
17037 };
17038
17039 /*
17040 Function: prev
17041 Get the previous <BigInteger> (subtract one).
17042
17043 Returns:
17044
17045 *this* - 1.
17046
17047 See Also:
17048
17049 <next>, <subtract>
17050 */
17051 BigInteger.prototype.prev = function() {
17052 switch (this._s) {
17053 case 0:
17054 return M_ONE;
17055 case -1:
17056 return addOne(this, -1);
17057 // case 1:
17058 default:
17059 return subtractOne(this, 1);
17060 }
17061 };
17062})();
17063
17064/*
17065 Function: compareAbs
17066 Compare the absolute value of two <BigIntegers>.
17067
17068 Calling <compareAbs> is faster than calling <abs> twice, then <compare>.
17069
17070 Parameters:
17071
17072 n - The number to compare to *this*. Will be converted to a <BigInteger>.
17073
17074 Returns:
17075
17076 -1, 0, or +1 if *|this|* is less than, equal to, or greater than *|n|*.
17077
17078 See Also:
17079
17080 <compare>, <abs>
17081*/
17082BigInteger.prototype.compareAbs = function(n) {
17083 if (this === n) {
17084 return 0;
17085 }
17086
17087 if (!(n instanceof BigInteger)) {
17088 if (!isFinite(n)) {
17089 return(isNaN(n) ? n : -1);
17090 }
17091 n = BigInteger(n);
17092 }
17093
17094 if (this._s === 0) {
17095 return (n._s !== 0) ? -1 : 0;
17096 }
17097 if (n._s === 0) {
17098 return 1;
17099 }
17100
17101 var l = this._d.length;
17102 var nl = n._d.length;
17103 if (l < nl) {
17104 return -1;
17105 }
17106 else if (l > nl) {
17107 return 1;
17108 }
17109
17110 var a = this._d;
17111 var b = n._d;
17112 for (var i = l-1; i >= 0; i--) {
17113 if (a[i] !== b[i]) {
17114 return a[i] < b[i] ? -1 : 1;
17115 }
17116 }
17117
17118 return 0;
17119};
17120
17121/*
17122 Function: compare
17123 Compare two <BigIntegers>.
17124
17125 Parameters:
17126
17127 n - The number to compare to *this*. Will be converted to a <BigInteger>.
17128
17129 Returns:
17130
17131 -1, 0, or +1 if *this* is less than, equal to, or greater than *n*.
17132
17133 See Also:
17134
17135 <compareAbs>, <isPositive>, <isNegative>, <isUnit>
17136*/
17137BigInteger.prototype.compare = function(n) {
17138 if (this === n) {
17139 return 0;
17140 }
17141
17142 n = BigInteger(n);
17143
17144 if (this._s === 0) {
17145 return -n._s;
17146 }
17147
17148 if (this._s === n._s) { // both positive or both negative
17149 var cmp = this.compareAbs(n);
17150 return cmp * this._s;
17151 }
17152 else {
17153 return this._s;
17154 }
17155};
17156
17157/*
17158 Function: isUnit
17159 Return true iff *this* is either 1 or -1.
17160
17161 Returns:
17162
17163 true if *this* compares equal to <BigInteger.ONE> or <BigInteger.M_ONE>.
17164
17165 See Also:
17166
17167 <isZero>, <isNegative>, <isPositive>, <compareAbs>, <compare>,
17168 <BigInteger.ONE>, <BigInteger.M_ONE>
17169*/
17170BigInteger.prototype.isUnit = function() {
17171 return this === ONE ||
17172 this === M_ONE ||
17173 (this._d.length === 1 && this._d[0] === 1);
17174};
17175
17176/*
17177 Function: multiply
17178 Multiply two <BigIntegers>.
17179
17180 Parameters:
17181
17182 n - The number to multiply *this* by. Will be converted to a
17183 <BigInteger>.
17184
17185 Returns:
17186
17187 The numbers multiplied together.
17188
17189 See Also:
17190
17191 <add>, <subtract>, <quotient>, <square>
17192*/
17193BigInteger.prototype.multiply = function(n) {
17194 // TODO: Consider adding Karatsuba multiplication for large numbers
17195 if (this._s === 0) {
17196 return ZERO;
17197 }
17198
17199 n = BigInteger(n);
17200 if (n._s === 0) {
17201 return ZERO;
17202 }
17203 if (this.isUnit()) {
17204 if (this._s < 0) {
17205 return n.negate();
17206 }
17207 return n;
17208 }
17209 if (n.isUnit()) {
17210 if (n._s < 0) {
17211 return this.negate();
17212 }
17213 return this;
17214 }
17215 if (this === n) {
17216 return this.square();
17217 }
17218
17219 var r = (this._d.length >= n._d.length);
17220 var a = (r ? this : n)._d; // a will be longer than b
17221 var b = (r ? n : this)._d;
17222 var al = a.length;
17223 var bl = b.length;
17224
17225 var pl = al + bl;
17226 var partial = new Array(pl);
17227 var i;
17228 for (i = 0; i < pl; i++) {
17229 partial[i] = 0;
17230 }
17231
17232 for (i = 0; i < bl; i++) {
17233 var carry = 0;
17234 var bi = b[i];
17235 var jlimit = al + i;
17236 var digit;
17237 for (var j = i; j < jlimit; j++) {
17238 digit = partial[j] + bi * a[j - i] + carry;
17239 carry = (digit / BigInteger_base) | 0;
17240 partial[j] = (digit % BigInteger_base) | 0;
17241 }
17242 if (carry) {
17243 digit = partial[j] + carry;
17244 carry = (digit / BigInteger_base) | 0;
17245 partial[j] = digit % BigInteger_base;
17246 }
17247 }
17248 return new BigInteger(partial, this._s * n._s, CONSTRUCT);
17249};
17250
17251// Multiply a BigInteger by a single-digit native number
17252// Assumes that this and n are >= 0
17253// This is not really intended to be used outside the library itself
17254BigInteger.prototype.multiplySingleDigit = function(n) {
17255 if (n === 0 || this._s === 0) {
17256 return ZERO;
17257 }
17258 if (n === 1) {
17259 return this;
17260 }
17261
17262 var digit;
17263 if (this._d.length === 1) {
17264 digit = this._d[0] * n;
17265 if (digit >= BigInteger_base) {
17266 return new BigInteger([(digit % BigInteger_base)|0,
17267 (digit / BigInteger_base)|0], 1, CONSTRUCT);
17268 }
17269 return new BigInteger([digit], 1, CONSTRUCT);
17270 }
17271
17272 if (n === 2) {
17273 return this.add(this);
17274 }
17275 if (this.isUnit()) {
17276 return new BigInteger([n], 1, CONSTRUCT);
17277 }
17278
17279 var a = this._d;
17280 var al = a.length;
17281
17282 var pl = al + 1;
17283 var partial = new Array(pl);
17284 for (var i = 0; i < pl; i++) {
17285 partial[i] = 0;
17286 }
17287
17288 var carry = 0;
17289 for (var j = 0; j < al; j++) {
17290 digit = n * a[j] + carry;
17291 carry = (digit / BigInteger_base) | 0;
17292 partial[j] = (digit % BigInteger_base) | 0;
17293 }
17294 if (carry) {
17295 partial[j] = carry;
17296 }
17297
17298 return new BigInteger(partial, 1, CONSTRUCT);
17299};
17300
17301/*
17302 Function: square
17303 Multiply a <BigInteger> by itself.
17304
17305 This is slightly faster than regular multiplication, since it removes the
17306 duplicated multiplcations.
17307
17308 Returns:
17309
17310 > this.multiply(this)
17311
17312 See Also:
17313 <multiply>
17314*/
17315BigInteger.prototype.square = function() {
17316 // Normally, squaring a 10-digit number would take 100 multiplications.
17317 // Of these 10 are unique diagonals, of the remaining 90 (100-10), 45 are repeated.
17318 // This procedure saves (N*(N-1))/2 multiplications, (e.g., 45 of 100 multiplies).
17319 // Based on code by Gary Darby, Intellitech Systems Inc., www.DelphiForFun.org
17320
17321 if (this._s === 0) {
17322 return ZERO;
17323 }
17324 if (this.isUnit()) {
17325 return ONE;
17326 }
17327
17328 var digits = this._d;
17329 var length = digits.length;
17330 var imult1 = new Array(length + length + 1);
17331 var product, carry, k;
17332 var i;
17333
17334 // Calculate diagonal
17335 for (i = 0; i < length; i++) {
17336 k = i * 2;
17337 product = digits[i] * digits[i];
17338 carry = (product / BigInteger_base) | 0;
17339 imult1[k] = product % BigInteger_base;
17340 imult1[k + 1] = carry;
17341 }
17342
17343 // Calculate repeating part
17344 for (i = 0; i < length; i++) {
17345 carry = 0;
17346 k = i * 2 + 1;
17347 for (var j = i + 1; j < length; j++, k++) {
17348 product = digits[j] * digits[i] * 2 + imult1[k] + carry;
17349 carry = (product / BigInteger_base) | 0;
17350 imult1[k] = product % BigInteger_base;
17351 }
17352 k = length + i;
17353 var digit = carry + imult1[k];
17354 carry = (digit / BigInteger_base) | 0;
17355 imult1[k] = digit % BigInteger_base;
17356 imult1[k + 1] += carry;
17357 }
17358
17359 return new BigInteger(imult1, 1, CONSTRUCT);
17360};
17361
17362/*
17363 Function: quotient
17364 Divide two <BigIntegers> and truncate towards zero.
17365
17366 <quotient> throws an exception if *n* is zero.
17367
17368 Parameters:
17369
17370 n - The number to divide *this* by. Will be converted to a <BigInteger>.
17371
17372 Returns:
17373
17374 The *this* / *n*, truncated to an integer.
17375
17376 See Also:
17377
17378 <add>, <subtract>, <multiply>, <divRem>, <remainder>
17379*/
17380BigInteger.prototype.quotient = function(n) {
17381 return this.divRem(n)[0];
17382};
17383
17384/*
17385 Function: divide
17386 Deprecated synonym for <quotient>.
17387*/
17388BigInteger.prototype.divide = BigInteger.prototype.quotient;
17389
17390/*
17391 Function: remainder
17392 Calculate the remainder of two <BigIntegers>.
17393
17394 <remainder> throws an exception if *n* is zero.
17395
17396 Parameters:
17397
17398 n - The remainder after *this* is divided *this* by *n*. Will be
17399 converted to a <BigInteger>.
17400
17401 Returns:
17402
17403 *this* % *n*.
17404
17405 See Also:
17406
17407 <divRem>, <quotient>
17408*/
17409BigInteger.prototype.remainder = function(n) {
17410 return this.divRem(n)[1];
17411};
17412
17413/*
17414 Function: divRem
17415 Calculate the integer quotient and remainder of two <BigIntegers>.
17416
17417 <divRem> throws an exception if *n* is zero.
17418
17419 Parameters:
17420
17421 n - The number to divide *this* by. Will be converted to a <BigInteger>.
17422
17423 Returns:
17424
17425 A two-element array containing the quotient and the remainder.
17426
17427 > a.divRem(b)
17428
17429 is exactly equivalent to
17430
17431 > [a.quotient(b), a.remainder(b)]
17432
17433 except it is faster, because they are calculated at the same time.
17434
17435 See Also:
17436
17437 <quotient>, <remainder>
17438*/
17439BigInteger.prototype.divRem = function(n) {
17440 n = BigInteger(n);
17441 if (n._s === 0) {
17442 throw new Error("Divide by zero");
17443 }
17444 if (this._s === 0) {
17445 return [ZERO, ZERO];
17446 }
17447 if (n._d.length === 1) {
17448 return this.divRemSmall(n._s * n._d[0]);
17449 }
17450
17451 // Test for easy cases -- |n1| <= |n2|
17452 switch (this.compareAbs(n)) {
17453 case 0: // n1 == n2
17454 return [this._s === n._s ? ONE : M_ONE, ZERO];
17455 case -1: // |n1| < |n2|
17456 return [ZERO, this];
17457 }
17458
17459 var sign = this._s * n._s;
17460 var a = n.abs();
17461 var b_digits = this._d;
17462 var b_index = b_digits.length;
17463 var digits = n._d.length;
17464 var quot = [];
17465 var guess;
17466
17467 var part = new BigInteger([], 0, CONSTRUCT);
17468
17469 while (b_index) {
17470 part._d.unshift(b_digits[--b_index]);
17471 part = new BigInteger(part._d, 1, CONSTRUCT);
17472
17473 if (part.compareAbs(n) < 0) {
17474 quot.push(0);
17475 continue;
17476 }
17477 if (part._s === 0) {
17478 guess = 0;
17479 }
17480 else {
17481 var xlen = part._d.length, ylen = a._d.length;
17482 var highx = part._d[xlen-1]*BigInteger_base + part._d[xlen-2];
17483 var highy = a._d[ylen-1]*BigInteger_base + a._d[ylen-2];
17484 if (part._d.length > a._d.length) {
17485 // The length of part._d can either match a._d length,
17486 // or exceed it by one.
17487 highx = (highx+1)*BigInteger_base;
17488 }
17489 guess = Math.ceil(highx/highy);
17490 }
17491 do {
17492 var check = a.multiplySingleDigit(guess);
17493 if (check.compareAbs(part) <= 0) {
17494 break;
17495 }
17496 guess--;
17497 } while (guess);
17498
17499 quot.push(guess);
17500 if (!guess) {
17501 continue;
17502 }
17503 var diff = part.subtract(check);
17504 part._d = diff._d.slice();
17505 }
17506
17507 return [new BigInteger(quot.reverse(), sign, CONSTRUCT),
17508 new BigInteger(part._d, this._s, CONSTRUCT)];
17509};
17510
17511// Throws an exception if n is outside of (-BigInteger.base, -1] or
17512// [1, BigInteger.base). It's not necessary to call this, since the
17513// other division functions will call it if they are able to.
17514BigInteger.prototype.divRemSmall = function(n) {
17515 var r;
17516 n = +n;
17517 if (n === 0) {
17518 throw new Error("Divide by zero");
17519 }
17520
17521 var n_s = n < 0 ? -1 : 1;
17522 var sign = this._s * n_s;
17523 n = Math.abs(n);
17524
17525 if (n < 1 || n >= BigInteger_base) {
17526 throw new Error("Argument out of range");
17527 }
17528
17529 if (this._s === 0) {
17530 return [ZERO, ZERO];
17531 }
17532
17533 if (n === 1 || n === -1) {
17534 return [(sign === 1) ? this.abs() : new BigInteger(this._d, sign, CONSTRUCT), ZERO];
17535 }
17536
17537 // 2 <= n < BigInteger_base
17538
17539 // divide a single digit by a single digit
17540 if (this._d.length === 1) {
17541 var q = new BigInteger([(this._d[0] / n) | 0], 1, CONSTRUCT);
17542 r = new BigInteger([(this._d[0] % n) | 0], 1, CONSTRUCT);
17543 if (sign < 0) {
17544 q = q.negate();
17545 }
17546 if (this._s < 0) {
17547 r = r.negate();
17548 }
17549 return [q, r];
17550 }
17551
17552 var digits = this._d.slice();
17553 var quot = new Array(digits.length);
17554 var part = 0;
17555 var diff = 0;
17556 var i = 0;
17557 var guess;
17558
17559 while (digits.length) {
17560 part = part * BigInteger_base + digits[digits.length - 1];
17561 if (part < n) {
17562 quot[i++] = 0;
17563 digits.pop();
17564 diff = BigInteger_base * diff + part;
17565 continue;
17566 }
17567 if (part === 0) {
17568 guess = 0;
17569 }
17570 else {
17571 guess = (part / n) | 0;
17572 }
17573
17574 var check = n * guess;
17575 diff = part - check;
17576 quot[i++] = guess;
17577 if (!guess) {
17578 digits.pop();
17579 continue;
17580 }
17581
17582 digits.pop();
17583 part = diff;
17584 }
17585
17586 r = new BigInteger([diff], 1, CONSTRUCT);
17587 if (this._s < 0) {
17588 r = r.negate();
17589 }
17590 return [new BigInteger(quot.reverse(), sign, CONSTRUCT), r];
17591};
17592
17593/*
17594 Function: isEven
17595 Return true iff *this* is divisible by two.
17596
17597 Note that <BigInteger.ZERO> is even.
17598
17599 Returns:
17600
17601 true if *this* is even, false otherwise.
17602
17603 See Also:
17604
17605 <isOdd>
17606*/
17607BigInteger.prototype.isEven = function() {
17608 var digits = this._d;
17609 return this._s === 0 || digits.length === 0 || (digits[0] % 2) === 0;
17610};
17611
17612/*
17613 Function: isOdd
17614 Return true iff *this* is not divisible by two.
17615
17616 Returns:
17617
17618 true if *this* is odd, false otherwise.
17619
17620 See Also:
17621
17622 <isEven>
17623*/
17624BigInteger.prototype.isOdd = function() {
17625 return !this.isEven();
17626};
17627
17628/*
17629 Function: sign
17630 Get the sign of a <BigInteger>.
17631
17632 Returns:
17633
17634 * -1 if *this* < 0
17635 * 0 if *this* == 0
17636 * +1 if *this* > 0
17637
17638 See Also:
17639
17640 <isZero>, <isPositive>, <isNegative>, <compare>, <BigInteger.ZERO>
17641*/
17642BigInteger.prototype.sign = function() {
17643 return this._s;
17644};
17645
17646/*
17647 Function: isPositive
17648 Return true iff *this* > 0.
17649
17650 Returns:
17651
17652 true if *this*.compare(<BigInteger.ZERO>) == 1.
17653
17654 See Also:
17655
17656 <sign>, <isZero>, <isNegative>, <isUnit>, <compare>, <BigInteger.ZERO>
17657*/
17658BigInteger.prototype.isPositive = function() {
17659 return this._s > 0;
17660};
17661
17662/*
17663 Function: isNegative
17664 Return true iff *this* < 0.
17665
17666 Returns:
17667
17668 true if *this*.compare(<BigInteger.ZERO>) == -1.
17669
17670 See Also:
17671
17672 <sign>, <isPositive>, <isZero>, <isUnit>, <compare>, <BigInteger.ZERO>
17673*/
17674BigInteger.prototype.isNegative = function() {
17675 return this._s < 0;
17676};
17677
17678/*
17679 Function: isZero
17680 Return true iff *this* == 0.
17681
17682 Returns:
17683
17684 true if *this*.compare(<BigInteger.ZERO>) == 0.
17685
17686 See Also:
17687
17688 <sign>, <isPositive>, <isNegative>, <isUnit>, <BigInteger.ZERO>
17689*/
17690BigInteger.prototype.isZero = function() {
17691 return this._s === 0;
17692};
17693
17694/*
17695 Function: exp10
17696 Multiply a <BigInteger> by a power of 10.
17697
17698 This is equivalent to, but faster than
17699
17700 > if (n >= 0) {
17701 > return this.multiply(BigInteger("1e" + n));
17702 > }
17703 > else { // n <= 0
17704 > return this.quotient(BigInteger("1e" + -n));
17705 > }
17706
17707 Parameters:
17708
17709 n - The power of 10 to multiply *this* by. *n* is converted to a
17710 javascipt number and must be no greater than <BigInteger.MAX_EXP>
17711 (0x7FFFFFFF), or an exception will be thrown.
17712
17713 Returns:
17714
17715 *this* * (10 ** *n*), truncated to an integer if necessary.
17716
17717 See Also:
17718
17719 <pow>, <multiply>
17720*/
17721BigInteger.prototype.exp10 = function(n) {
17722 n = +n;
17723 if (n === 0) {
17724 return this;
17725 }
17726 if (Math.abs(n) > Number(MAX_EXP)) {
17727 throw new Error("exponent too large in BigInteger.exp10");
17728 }
17729 // Optimization for this == 0. This also keeps us from having to trim zeros in the positive n case
17730 if (this._s === 0) {
17731 return ZERO;
17732 }
17733 if (n > 0) {
17734 var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT);
17735
17736 for (; n >= BigInteger_base_log10; n -= BigInteger_base_log10) {
17737 k._d.unshift(0);
17738 }
17739 if (n == 0)
17740 return k;
17741 k._s = 1;
17742 k = k.multiplySingleDigit(Math.pow(10, n));
17743 return (this._s < 0 ? k.negate() : k);
17744 } else if (-n >= this._d.length*BigInteger_base_log10) {
17745 return ZERO;
17746 } else {
17747 var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT);
17748
17749 for (n = -n; n >= BigInteger_base_log10; n -= BigInteger_base_log10) {
17750 k._d.shift();
17751 }
17752 return (n == 0) ? k : k.divRemSmall(Math.pow(10, n))[0];
17753 }
17754};
17755
17756/*
17757 Function: pow
17758 Raise a <BigInteger> to a power.
17759
17760 In this implementation, 0**0 is 1.
17761
17762 Parameters:
17763
17764 n - The exponent to raise *this* by. *n* must be no greater than
17765 <BigInteger.MAX_EXP> (0x7FFFFFFF), or an exception will be thrown.
17766
17767 Returns:
17768
17769 *this* raised to the *nth* power.
17770
17771 See Also:
17772
17773 <modPow>
17774*/
17775BigInteger.prototype.pow = function(n) {
17776 if (this.isUnit()) {
17777 if (this._s > 0) {
17778 return this;
17779 }
17780 else {
17781 return BigInteger(n).isOdd() ? this : this.negate();
17782 }
17783 }
17784
17785 n = BigInteger(n);
17786 if (n._s === 0) {
17787 return ONE;
17788 }
17789 else if (n._s < 0) {
17790 if (this._s === 0) {
17791 throw new Error("Divide by zero");
17792 }
17793 else {
17794 return ZERO;
17795 }
17796 }
17797 if (this._s === 0) {
17798 return ZERO;
17799 }
17800 if (n.isUnit()) {
17801 return this;
17802 }
17803
17804 if (n.compareAbs(MAX_EXP) > 0) {
17805 throw new Error("exponent too large in BigInteger.pow");
17806 }
17807 var x = this;
17808 var aux = ONE;
17809 var two = BigInteger.small[2];
17810
17811 while (n.isPositive()) {
17812 if (n.isOdd()) {
17813 aux = aux.multiply(x);
17814 if (n.isUnit()) {
17815 return aux;
17816 }
17817 }
17818 x = x.square();
17819 n = n.quotient(two);
17820 }
17821
17822 return aux;
17823};
17824
17825/*
17826 Function: modPow
17827 Raise a <BigInteger> to a power (mod m).
17828
17829 Because it is reduced by a modulus, <modPow> is not limited by
17830 <BigInteger.MAX_EXP> like <pow>.
17831
17832 Parameters:
17833
17834 exponent - The exponent to raise *this* by. Must be positive.
17835 modulus - The modulus.
17836
17837 Returns:
17838
17839 *this* ^ *exponent* (mod *modulus*).
17840
17841 See Also:
17842
17843 <pow>, <mod>
17844*/
17845BigInteger.prototype.modPow = function(exponent, modulus) {
17846 var result = ONE;
17847 var base = this;
17848
17849 while (exponent.isPositive()) {
17850 if (exponent.isOdd()) {
17851 result = result.multiply(base).remainder(modulus);
17852 }
17853
17854 exponent = exponent.quotient(BigInteger.small[2]);
17855 if (exponent.isPositive()) {
17856 base = base.square().remainder(modulus);
17857 }
17858 }
17859
17860 return result;
17861};
17862
17863/*
17864 Function: log
17865 Get the natural logarithm of a <BigInteger> as a native JavaScript number.
17866
17867 This is equivalent to
17868
17869 > Math.log(this.toJSValue())
17870
17871 but handles values outside of the native number range.
17872
17873 Returns:
17874
17875 log( *this* )
17876
17877 See Also:
17878
17879 <toJSValue>
17880*/
17881BigInteger.prototype.log = function() {
17882 switch (this._s) {
17883 case 0: return -Infinity;
17884 case -1: return NaN;
17885 default: // Fall through.
17886 }
17887
17888 var l = this._d.length;
17889
17890 if (l*BigInteger_base_log10 < 30) {
17891 return Math.log(this.valueOf());
17892 }
17893
17894 var N = Math.ceil(30/BigInteger_base_log10);
17895 var firstNdigits = this._d.slice(l - N);
17896 return Math.log((new BigInteger(firstNdigits, 1, CONSTRUCT)).valueOf()) + (l - N) * Math.log(BigInteger_base);
17897};
17898
17899/*
17900 Function: valueOf
17901 Convert a <BigInteger> to a native JavaScript integer.
17902
17903 This is called automatically by JavaScipt to convert a <BigInteger> to a
17904 native value.
17905
17906 Returns:
17907
17908 > parseInt(this.toString(), 10)
17909
17910 See Also:
17911
17912 <toString>, <toJSValue>
17913*/
17914BigInteger.prototype.valueOf = function() {
17915 return parseInt(this.toString(), 10);
17916};
17917
17918/*
17919 Function: toJSValue
17920 Convert a <BigInteger> to a native JavaScript integer.
17921
17922 This is the same as valueOf, but more explicitly named.
17923
17924 Returns:
17925
17926 > parseInt(this.toString(), 10)
17927
17928 See Also:
17929
17930 <toString>, <valueOf>
17931*/
17932BigInteger.prototype.toJSValue = function() {
17933 return parseInt(this.toString(), 10);
17934};
17935
17936var MAX_EXP = BigInteger(0x7FFFFFFF);
17937// Constant: MAX_EXP
17938// The largest exponent allowed in <pow> and <exp10> (0x7FFFFFFF or 2147483647).
17939BigInteger.MAX_EXP = MAX_EXP;
17940
17941(function() {
17942 function makeUnary(fn) {
17943 return function(a) {
17944 return fn.call(BigInteger(a));
17945 };
17946 }
17947
17948 function makeBinary(fn) {
17949 return function(a, b) {
17950 return fn.call(BigInteger(a), BigInteger(b));
17951 };
17952 }
17953
17954 function makeTrinary(fn) {
17955 return function(a, b, c) {
17956 return fn.call(BigInteger(a), BigInteger(b), BigInteger(c));
17957 };
17958 }
17959
17960 (function() {
17961 var i, fn;
17962 var unary = "toJSValue,isEven,isOdd,sign,isZero,isNegative,abs,isUnit,square,negate,isPositive,toString,next,prev,log".split(",");
17963 var binary = "compare,remainder,divRem,subtract,add,quotient,divide,multiply,pow,compareAbs".split(",");
17964 var trinary = ["modPow"];
17965
17966 for (i = 0; i < unary.length; i++) {
17967 fn = unary[i];
17968 BigInteger[fn] = makeUnary(BigInteger.prototype[fn]);
17969 }
17970
17971 for (i = 0; i < binary.length; i++) {
17972 fn = binary[i];
17973 BigInteger[fn] = makeBinary(BigInteger.prototype[fn]);
17974 }
17975
17976 for (i = 0; i < trinary.length; i++) {
17977 fn = trinary[i];
17978 BigInteger[fn] = makeTrinary(BigInteger.prototype[fn]);
17979 }
17980
17981 BigInteger.exp10 = function(x, n) {
17982 return BigInteger(x).exp10(n);
17983 };
17984 })();
17985})();
17986
17987exports.BigInteger = BigInteger;
17988})(typeof exports !== 'undefined' ? exports : this);
17989</script>
16172 <script>(function() { 17990 <script>(function() {
16173 17991
16174 // mnemonics is populated as required by getLanguage 17992 // mnemonics is populated as required by getLanguage
@@ -16185,14 +18003,20 @@ var Mnemonic = function(language) {
16185 var showPubKey = true; 18003 var showPubKey = true;
16186 var showPrivKey = true; 18004 var showPrivKey = true;
16187 18005
18006 var entropyChangeTimeoutEvent = null;
16188 var phraseChangeTimeoutEvent = null; 18007 var phraseChangeTimeoutEvent = null;
16189 var rootKeyChangedTimeoutEvent = null; 18008 var rootKeyChangedTimeoutEvent = null;
16190 18009
16191 var DOM = {}; 18010 var DOM = {};
16192 DOM.network = $(".network"); 18011 DOM.network = $(".network");
16193 DOM.phraseNetwork = $("#network-phrase"); 18012 DOM.phraseNetwork = $("#network-phrase");
18013 DOM.useEntropy = $(".use-entropy");
18014 DOM.entropyContainer = $(".entropy-container");
18015 DOM.entropy = $(".entropy");
18016 DOM.entropyError = $(".entropy-error");
16194 DOM.phrase = $(".phrase"); 18017 DOM.phrase = $(".phrase");
16195 DOM.passphrase = $(".passphrase"); 18018 DOM.passphrase = $(".passphrase");
18019 DOM.generateContainer = $(".generate-container");
16196 DOM.generate = $(".generate"); 18020 DOM.generate = $(".generate");
16197 DOM.seed = $(".seed"); 18021 DOM.seed = $(".seed");
16198 DOM.rootKey = $(".root-key"); 18022 DOM.rootKey = $(".root-key");
@@ -16224,6 +18048,8 @@ var Mnemonic = function(language) {
16224 function init() { 18048 function init() {
16225 // Events 18049 // Events
16226 DOM.network.on("change", networkChanged); 18050 DOM.network.on("change", networkChanged);
18051 DOM.useEntropy.on("change", setEntropyVisibility);
18052 DOM.entropy.on("input", delayedEntropyChanged);
16227 DOM.phrase.on("input", delayedPhraseChanged); 18053 DOM.phrase.on("input", delayedPhraseChanged);
16228 DOM.passphrase.on("input", delayedPhraseChanged); 18054 DOM.passphrase.on("input", delayedPhraseChanged);
16229 DOM.generate.on("click", generateClicked); 18055 DOM.generate.on("click", generateClicked);
@@ -16260,6 +18086,21 @@ var Mnemonic = function(language) {
16260 } 18086 }
16261 } 18087 }
16262 18088
18089 function setEntropyVisibility() {
18090 if (isUsingOwnEntropy()) {
18091 DOM.entropyContainer.removeClass("hidden");
18092 DOM.generateContainer.addClass("hidden");
18093 DOM.phrase.prop("readonly", true);
18094 DOM.entropy.focus();
18095 entropyChanged();
18096 }
18097 else {
18098 DOM.entropyContainer.addClass("hidden");
18099 DOM.generateContainer.removeClass("hidden");
18100 DOM.phrase.prop("readonly", false);
18101 }
18102 }
18103
16263 function delayedPhraseChanged() { 18104 function delayedPhraseChanged() {
16264 hideValidationError(); 18105 hideValidationError();
16265 showPending(); 18106 showPending();
@@ -16287,6 +18128,20 @@ var Mnemonic = function(language) {
16287 hidePending(); 18128 hidePending();
16288 } 18129 }
16289 18130
18131 function delayedEntropyChanged() {
18132 hideValidationError();
18133 showPending();
18134 if (entropyChangeTimeoutEvent != null) {
18135 clearTimeout(entropyChangeTimeoutEvent);
18136 }
18137 entropyChangeTimeoutEvent = setTimeout(entropyChanged, 400);
18138 }
18139
18140 function entropyChanged() {
18141 setMnemonicFromEntropy();
18142 phraseChanged();
18143 }
18144
16290 function delayedRootKeyChanged() { 18145 function delayedRootKeyChanged() {
16291 // Warn if there is an existing mnemonic or passphrase. 18146 // Warn if there is an existing mnemonic or passphrase.
16292 if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) { 18147 if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) {
@@ -16339,6 +18194,9 @@ var Mnemonic = function(language) {
16339 } 18194 }
16340 18195
16341 function generateClicked() { 18196 function generateClicked() {
18197 if (isUsingOwnEntropy()) {
18198 return;
18199 }
16342 clearDisplay(); 18200 clearDisplay();
16343 showPending(); 18201 showPending();
16344 setTimeout(function() { 18202 setTimeout(function() {
@@ -16770,7 +18628,12 @@ var Mnemonic = function(language) {
16770 } 18628 }
16771 18629
16772 function getLanguageFromUrl() { 18630 function getLanguageFromUrl() {
16773 return window.location.hash.substring(1); 18631 for (var language in WORDLISTS) {
18632 if (window.location.hash.indexOf(language) > -1) {
18633 return language;
18634 }
18635 }
18636 return "";
16774 } 18637 }
16775 18638
16776 function setMnemonicLanguage() { 18639 function setMnemonicLanguage() {
@@ -16821,6 +18684,65 @@ var Mnemonic = function(language) {
16821 return phrase; 18684 return phrase;
16822 } 18685 }
16823 18686
18687 function isUsingOwnEntropy() {
18688 return DOM.useEntropy.prop("checked");
18689 }
18690
18691 function setMnemonicFromEntropy() {
18692 hideEntropyError();
18693 // Work out minimum base for entropy
18694 var entropyStr = DOM.entropy.val();
18695 var entropy = Entropy.fromString(entropyStr);
18696 if (entropy.hexStr.length == 0) {
18697 return;
18698 }
18699 // Show entropy details
18700 var extraBits = 32 - (entropy.binaryStr.length % 32);
18701 var extraChars = Math.ceil(extraBits * Math.log(2) / Math.log(entropy.base.asInt));
18702 var strength = "an extremely weak";
18703 if (entropy.hexStr.length >= 8) {
18704 strength = "a very weak";
18705 }
18706 if (entropy.hexStr.length >= 12) {
18707 strength = "a weak";
18708 }
18709 if (entropy.hexStr.length >= 24) {
18710 strength = "a strong";
18711 }
18712 if (entropy.hexStr.length >= 32) {
18713 strength = "a very strong";
18714 }
18715 if (entropy.hexStr.length >= 40) {
18716 strength = "an extremely strong";
18717 }
18718 if (entropy.hexStr.length >=48) {
18719 strength = "an even stronger"
18720 }
18721 var msg = "Have " + entropy.binaryStr.length + " bits of entropy, " + extraChars + " more " + entropy.base.str + " chars required to generate " + strength + " mnemonic: " + entropy.cleanStr;
18722 showEntropyError(msg);
18723 // Discard trailing entropy
18724 var hexStr = entropy.hexStr.substring(0, Math.floor(entropy.hexStr.length / 8) * 8);
18725 // Convert entropy string to numeric array
18726 var entropyArr = [];
18727 for (var i=0; i<hexStr.length / 2; i++) {
18728 var entropyByte = parseInt(hexStr[i*2].concat(hexStr[i*2+1]), 16);
18729 entropyArr.push(entropyByte)
18730 }
18731 // Convert entropy array to mnemonic
18732 var phrase = mnemonic.toMnemonic(entropyArr);
18733 // Set the mnemonic in the UI
18734 DOM.phrase.val(phrase);
18735 }
18736
18737 function hideEntropyError() {
18738 DOM.entropyError.addClass("hidden");
18739 }
18740
18741 function showEntropyError(msg) {
18742 DOM.entropyError.text(msg);
18743 DOM.entropyError.removeClass("hidden");
18744 }
18745
16824 var networks = [ 18746 var networks = [
16825 { 18747 {
16826 name: "Bitcoin", 18748 name: "Bitcoin",
diff --git a/src/index.html b/src/index.html
index 3ec4aa9..cb7a781 100644
--- a/src/index.html
+++ b/src/index.html
@@ -65,12 +65,14 @@
65 <div class="col-md-12"> 65 <div class="col-md-12">
66 <h2>Mnemonic</h2> 66 <h2>Mnemonic</h2>
67 <form class="form-horizontal" role="form"> 67 <form class="form-horizontal" role="form">
68 <div class="col-sm-2"></div>
69 <div class="col-sm-10">
70 <p>You can enter an existing BIP39 mnemonic, or generate a new random one. Typing your own twelve words will probably not work how you expect, since the words require a particular structure (the last word is a checksum)</p>
71 <p>For more info see the <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki" target="_blank">BIP39 spec</a></p>
72 </div>
73 <div class="form-group"> 68 <div class="form-group">
69 <div class="col-sm-2"></div>
70 <div class="col-sm-10">
71 <p>You can enter an existing BIP39 mnemonic, or generate a new random one. Typing your own twelve words will probably not work how you expect, since the words require a particular structure (the last word is a checksum)</p>
72 <p>For more info see the <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki" target="_blank">BIP39 spec</a></p>
73 </div>
74 </div>
75 <div class="form-group generate-container">
74 <label class="col-sm-2 control-label"></label> 76 <label class="col-sm-2 control-label"></label>
75 <div class="col-sm-10"> 77 <div class="col-sm-10">
76 <div class="form-inline"> 78 <div class="form-inline">
@@ -92,7 +94,30 @@
92 </div> 94 </div>
93 </div> 95 </div>
94 </div> 96 </div>
95 <div class="form-group"> 97 <div class="entropy-container hidden">
98 <label for="entropy" class="col-sm-2 control-label">Entropy</label>
99 <div class="col-sm-10">
100 <input id="entropy" class="entropy form-control" placeholder="Accepts binary, base 6, 6-sided dice, base 10, hexadecimal">
101 <span class="help-block">
102 <div class="text-danger">
103 This is an advanced feature.
104 Your mnemonic may be insecure if this feature is used incorrectly.
105 <a href="#entropy-notes">Read more</a>
106 </div>
107 <div class="text-danger entropy-error"></div>
108 </span>
109 </div>
110 </div>
111 <div class="form-group">
112 <div class="col-sm-2"></div>
113 <div class="col-sm-10 checkbox">
114 <label>
115 <input type="checkbox" class="use-entropy">
116 Supply my own source of entropy
117 </label>
118 </div>
119 </div>
120 <div class="form-group">
96 <label class="col-sm-2 control-label"></label> 121 <label class="col-sm-2 control-label"></label>
97 <div class="col-sm-10 languages"> 122 <div class="col-sm-10 languages">
98 <a href="#english">English</a> 123 <a href="#english">English</a>
@@ -353,6 +378,24 @@
353 but be careful - it can be easy to make mistakes if you 378 but be careful - it can be easy to make mistakes if you
354 don't know what you're doing 379 don't know what you're doing
355 </p> 380 </p>
381 <h3 id="entropy-notes">Entropy</h3>
382 <p>
383 Entropy values must be sourced from a
384 <a href="https://en.wikipedia.org/wiki/Random_number_generation" target="_blank">strong source of randomness</a>.
385 This means flipping a fair coin, rolling a fair dice, noise measurements etc. Do <strong>NOT</strong> use
386 phrases from books, lyrics from songs, your birthday or steet address, keyboard mashing, or anything you <i>think</i>
387 is random, because chances are <em>overwhelming</em> that it isn't random enough for the needs of this tool.
388 </p>
389 <p>
390 The random mnemonic generator on this page uses a
391 <a href="https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues" target="_blank">cryptographically secure random number generator</a>,
392 and can generally be trusted more than your own intuition about randomness.
393 If cryptographic randomness isn't available in your browser, this page will show a warning and <i>will not generate
394 random mnemonics</i>.
395 </p>
396 <p>
397 <a href="https://bitcointalk.org/index.php?topic=311000.msg3345309#msg3345309" target="_blank">You are not a good source of entropy.</a>
398 </p>
356 </div> 399 </div>
357 </div> 400 </div>
358 401
@@ -465,6 +508,7 @@
465 <script src="js/wordlist_french.js"></script> 508 <script src="js/wordlist_french.js"></script>
466 <script src="js/wordlist_italian.js"></script> 509 <script src="js/wordlist_italian.js"></script>
467 <script src="js/jsbip39.js"></script> 510 <script src="js/jsbip39.js"></script>
511 <script src="js/entropy.js"></script>
468 <script src="js/index.js"></script> 512 <script src="js/index.js"></script>
469 </body> 513 </body>
470</html> 514</html>
diff --git a/src/js/entropy.js b/src/js/entropy.js
new file mode 100644
index 0000000..1e556ce
--- /dev/null
+++ b/src/js/entropy.js
@@ -0,0 +1,1774 @@
1window.Entropy = new (function() {
2
3 var matchers = {
4 binary: /[0-1]/gi,
5 base6: /[0-5]/gi,
6 dice: /[1-6]/gi, // ie dice numbers
7 base10: /[0-9]/gi,
8 hex: /[0-9A-F]/gi,
9 }
10
11 this.fromString = function(rawEntropyStr) {
12 // Find type of entropy being used (binary, hex, dice etc)
13 var base = getBase(rawEntropyStr);
14 // Convert dice to base6 entropy (ie 1-6 to 0-5)
15 if (base.str == "dice") {
16 var newRawEntropyStr = "";
17 for (var i=0; i<rawEntropyStr.length; i++) {
18 var c = rawEntropyStr[i];
19 if ("123456".indexOf(c) > -1) {
20 newRawEntropyStr += (parseInt(c) - 1).toString();
21 }
22 else {
23 newRawEntropyStr += c
24 }
25 }
26 rawEntropyStr = newRawEntropyStr;
27 base.str = "base 6 (dice)";
28 base.matcher = matchers.base6;
29 }
30 var entropyParts = rawEntropyStr.match(base.matcher) || [];
31 var entropyStr = entropyParts.join("");
32 // Detect empty entropy
33 if (entropyStr.length == 0) {
34 return {
35 binaryStr: "",
36 hexStr: "",
37 cleanStr: "",
38 base: base,
39 };
40 }
41 // Pull leading zeros off
42 var leadingZeros = "";
43 while (entropyStr[0] == "0") {
44 leadingZeros += "0";
45 entropyStr = entropyStr.substring(1);
46 }
47 // Convert leading zeros to binary equivalent
48 var numBinLeadingZeros = Math.ceil(Math.log2(base.asInt) * leadingZeros.length);
49 var binLeadingZeros = "";
50 for (var i=0; i<numBinLeadingZeros; i++) {
51 binLeadingZeros += "0";
52 }
53 // Convert leading zeros to hex equivalent
54 var numHexLeadingZeros = Math.floor(numBinLeadingZeros / 4);
55 var hexLeadingZeros = "";
56 for (var i=0; i<numHexLeadingZeros; i++) {
57 hexLeadingZeros += "0";
58 }
59 // Handle entropy of zero
60 if (entropyStr == "") {
61 return {
62 binaryStr: binLeadingZeros,
63 hexStr: hexLeadingZeros || "0",
64 cleanStr: leadingZeros,
65 base: base,
66 }
67 }
68 // If using hex, should always be multiples of 4 bits, which can get
69 // out of sync if first number has leading 0 bits, eg 2 in hex is 0010
70 // which would show up as 10, thus missing 2 bits it should have.
71 if (base.asInt == 16) {
72 var firstDigit = parseInt(entropyStr[0], 16);
73 if (firstDigit >= 4 && firstDigit < 8) {
74 binLeadingZeros += "0";
75 }
76 else if (firstDigit >= 2 && firstDigit < 4) {
77 binLeadingZeros += "00";
78 }
79 else if (firstDigit >= 1 && firstDigit < 2) {
80 binLeadingZeros += "000";
81 }
82 }
83 // Convert entropy to different foramts
84 var entropyInt = BigInteger.parse(entropyStr, base.asInt);
85 var entropyBin = binLeadingZeros + entropyInt.toString(2);
86 var entropyHex = hexLeadingZeros + entropyInt.toString(16);
87 var entropyClean = leadingZeros + entropyStr;
88 var e = {
89 binaryStr: entropyBin,
90 hexStr: entropyHex,
91 cleanStr: entropyClean,
92 base: base,
93 }
94 return e;
95 }
96
97 function getBase(str) {
98 // Need to get the lowest base for the supplied entropy.
99 // This prevents interpreting, say, dice rolls as hexadecimal.
100 var binaryMatches = str.match(matchers.binary) || [];
101 var base6Matches = str.match(matchers.base6) || [];
102 var diceMatches = str.match(matchers.dice) || [];
103 var base10Matches = str.match(matchers.base10) || [];
104 var hexMatches = str.match(matchers.hex) || [];
105 // Find the lowest base that can be used, whilst ignoring any irrelevant chars
106 if (binaryMatches.length == hexMatches.length) {
107 return {
108 matcher: matchers.binary,
109 asInt: 2,
110 str: "binary",
111 }
112 }
113 if (diceMatches.length == hexMatches.length) {
114 return {
115 matcher: matchers.dice,
116 asInt: 6,
117 str: "dice",
118 }
119 }
120 if (base6Matches.length == hexMatches.length) {
121 return {
122 matcher: matchers.base6,
123 asInt: 6,
124 str: "base 6",
125 }
126 }
127 if (base10Matches.length == hexMatches.length) {
128 return {
129 matcher: matchers.base10,
130 asInt: 10,
131 str: "base 10",
132 }
133 }
134 return {
135 matcher: matchers.hex,
136 asInt: 16,
137 str: "hexadecimal",
138 }
139 }
140
141 // Polyfill for Math.log2
142 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2#Polyfill
143 Math.log2 = Math.log2 || function(x) {
144 return Math.log(x) * Math.LOG2E;
145 };
146
147})();
148
149
150// BigInteger library included here because
151// only the entropy library depends on it
152// so if entropy detection is removed so is the dependency
153
154
155/*
156 JavaScript BigInteger library version 0.9.1
157 http://silentmatt.com/biginteger/
158
159 Copyright (c) 2009 Matthew Crumley <email@matthewcrumley.com>
160 Copyright (c) 2010,2011 by John Tobey <John.Tobey@gmail.com>
161 Licensed under the MIT license.
162
163 Support for arbitrary internal representation base was added by
164 Vitaly Magerya.
165*/
166
167/*
168 File: biginteger.js
169
170 Exports:
171
172 <BigInteger>
173*/
174(function(exports) {
175"use strict";
176/*
177 Class: BigInteger
178 An arbitrarily-large integer.
179
180 <BigInteger> objects should be considered immutable. None of the "built-in"
181 methods modify *this* or their arguments. All properties should be
182 considered private.
183
184 All the methods of <BigInteger> instances can be called "statically". The
185 static versions are convenient if you don't already have a <BigInteger>
186 object.
187
188 As an example, these calls are equivalent.
189
190 > BigInteger(4).multiply(5); // returns BigInteger(20);
191 > BigInteger.multiply(4, 5); // returns BigInteger(20);
192
193 > var a = 42;
194 > var a = BigInteger.toJSValue("0b101010"); // Not completely useless...
195*/
196
197var CONSTRUCT = {}; // Unique token to call "private" version of constructor
198
199/*
200 Constructor: BigInteger()
201 Convert a value to a <BigInteger>.
202
203 Although <BigInteger()> is the constructor for <BigInteger> objects, it is
204 best not to call it as a constructor. If *n* is a <BigInteger> object, it is
205 simply returned as-is. Otherwise, <BigInteger()> is equivalent to <parse>
206 without a radix argument.
207
208 > var n0 = BigInteger(); // Same as <BigInteger.ZERO>
209 > var n1 = BigInteger("123"); // Create a new <BigInteger> with value 123
210 > var n2 = BigInteger(123); // Create a new <BigInteger> with value 123
211 > var n3 = BigInteger(n2); // Return n2, unchanged
212
213 The constructor form only takes an array and a sign. *n* must be an
214 array of numbers in little-endian order, where each digit is between 0
215 and BigInteger.base. The second parameter sets the sign: -1 for
216 negative, +1 for positive, or 0 for zero. The array is *not copied and
217 may be modified*. If the array contains only zeros, the sign parameter
218 is ignored and is forced to zero.
219
220 > new BigInteger([5], -1): create a new BigInteger with value -5
221
222 Parameters:
223
224 n - Value to convert to a <BigInteger>.
225
226 Returns:
227
228 A <BigInteger> value.
229
230 See Also:
231
232 <parse>, <BigInteger>
233*/
234function BigInteger(n, s, token) {
235 if (token !== CONSTRUCT) {
236 if (n instanceof BigInteger) {
237 return n;
238 }
239 else if (typeof n === "undefined") {
240 return ZERO;
241 }
242 return BigInteger.parse(n);
243 }
244
245 n = n || []; // Provide the nullary constructor for subclasses.
246 while (n.length && !n[n.length - 1]) {
247 --n.length;
248 }
249 this._d = n;
250 this._s = n.length ? (s || 1) : 0;
251}
252
253BigInteger._construct = function(n, s) {
254 return new BigInteger(n, s, CONSTRUCT);
255};
256
257// Base-10 speedup hacks in parse, toString, exp10 and log functions
258// require base to be a power of 10. 10^7 is the largest such power
259// that won't cause a precision loss when digits are multiplied.
260var BigInteger_base = 10000000;
261var BigInteger_base_log10 = 7;
262
263BigInteger.base = BigInteger_base;
264BigInteger.base_log10 = BigInteger_base_log10;
265
266var ZERO = new BigInteger([], 0, CONSTRUCT);
267// Constant: ZERO
268// <BigInteger> 0.
269BigInteger.ZERO = ZERO;
270
271var ONE = new BigInteger([1], 1, CONSTRUCT);
272// Constant: ONE
273// <BigInteger> 1.
274BigInteger.ONE = ONE;
275
276var M_ONE = new BigInteger(ONE._d, -1, CONSTRUCT);
277// Constant: M_ONE
278// <BigInteger> -1.
279BigInteger.M_ONE = M_ONE;
280
281// Constant: _0
282// Shortcut for <ZERO>.
283BigInteger._0 = ZERO;
284
285// Constant: _1
286// Shortcut for <ONE>.
287BigInteger._1 = ONE;
288
289/*
290 Constant: small
291 Array of <BigIntegers> from 0 to 36.
292
293 These are used internally for parsing, but useful when you need a "small"
294 <BigInteger>.
295
296 See Also:
297
298 <ZERO>, <ONE>, <_0>, <_1>
299*/
300BigInteger.small = [
301 ZERO,
302 ONE,
303 /* Assuming BigInteger_base > 36 */
304 new BigInteger( [2], 1, CONSTRUCT),
305 new BigInteger( [3], 1, CONSTRUCT),
306 new BigInteger( [4], 1, CONSTRUCT),
307 new BigInteger( [5], 1, CONSTRUCT),
308 new BigInteger( [6], 1, CONSTRUCT),
309 new BigInteger( [7], 1, CONSTRUCT),
310 new BigInteger( [8], 1, CONSTRUCT),
311 new BigInteger( [9], 1, CONSTRUCT),
312 new BigInteger([10], 1, CONSTRUCT),
313 new BigInteger([11], 1, CONSTRUCT),
314 new BigInteger([12], 1, CONSTRUCT),
315 new BigInteger([13], 1, CONSTRUCT),
316 new BigInteger([14], 1, CONSTRUCT),
317 new BigInteger([15], 1, CONSTRUCT),
318 new BigInteger([16], 1, CONSTRUCT),
319 new BigInteger([17], 1, CONSTRUCT),
320 new BigInteger([18], 1, CONSTRUCT),
321 new BigInteger([19], 1, CONSTRUCT),
322 new BigInteger([20], 1, CONSTRUCT),
323 new BigInteger([21], 1, CONSTRUCT),
324 new BigInteger([22], 1, CONSTRUCT),
325 new BigInteger([23], 1, CONSTRUCT),
326 new BigInteger([24], 1, CONSTRUCT),
327 new BigInteger([25], 1, CONSTRUCT),
328 new BigInteger([26], 1, CONSTRUCT),
329 new BigInteger([27], 1, CONSTRUCT),
330 new BigInteger([28], 1, CONSTRUCT),
331 new BigInteger([29], 1, CONSTRUCT),
332 new BigInteger([30], 1, CONSTRUCT),
333 new BigInteger([31], 1, CONSTRUCT),
334 new BigInteger([32], 1, CONSTRUCT),
335 new BigInteger([33], 1, CONSTRUCT),
336 new BigInteger([34], 1, CONSTRUCT),
337 new BigInteger([35], 1, CONSTRUCT),
338 new BigInteger([36], 1, CONSTRUCT)
339];
340
341// Used for parsing/radix conversion
342BigInteger.digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
343
344/*
345 Method: toString
346 Convert a <BigInteger> to a string.
347
348 When *base* is greater than 10, letters are upper case.
349
350 Parameters:
351
352 base - Optional base to represent the number in (default is base 10).
353 Must be between 2 and 36 inclusive, or an Error will be thrown.
354
355 Returns:
356
357 The string representation of the <BigInteger>.
358*/
359BigInteger.prototype.toString = function(base) {
360 base = +base || 10;
361 if (base < 2 || base > 36) {
362 throw new Error("illegal radix " + base + ".");
363 }
364 if (this._s === 0) {
365 return "0";
366 }
367 if (base === 10) {
368 var str = this._s < 0 ? "-" : "";
369 str += this._d[this._d.length - 1].toString();
370 for (var i = this._d.length - 2; i >= 0; i--) {
371 var group = this._d[i].toString();
372 while (group.length < BigInteger_base_log10) group = '0' + group;
373 str += group;
374 }
375 return str;
376 }
377 else {
378 var numerals = BigInteger.digits;
379 base = BigInteger.small[base];
380 var sign = this._s;
381
382 var n = this.abs();
383 var digits = [];
384 var digit;
385
386 while (n._s !== 0) {
387 var divmod = n.divRem(base);
388 n = divmod[0];
389 digit = divmod[1];
390 // TODO: This could be changed to unshift instead of reversing at the end.
391 // Benchmark both to compare speeds.
392 digits.push(numerals[digit.valueOf()]);
393 }
394 return (sign < 0 ? "-" : "") + digits.reverse().join("");
395 }
396};
397
398// Verify strings for parsing
399BigInteger.radixRegex = [
400 /^$/,
401 /^$/,
402 /^[01]*$/,
403 /^[012]*$/,
404 /^[0-3]*$/,
405 /^[0-4]*$/,
406 /^[0-5]*$/,
407 /^[0-6]*$/,
408 /^[0-7]*$/,
409 /^[0-8]*$/,
410 /^[0-9]*$/,
411 /^[0-9aA]*$/,
412 /^[0-9abAB]*$/,
413 /^[0-9abcABC]*$/,
414 /^[0-9a-dA-D]*$/,
415 /^[0-9a-eA-E]*$/,
416 /^[0-9a-fA-F]*$/,
417 /^[0-9a-gA-G]*$/,
418 /^[0-9a-hA-H]*$/,
419 /^[0-9a-iA-I]*$/,
420 /^[0-9a-jA-J]*$/,
421 /^[0-9a-kA-K]*$/,
422 /^[0-9a-lA-L]*$/,
423 /^[0-9a-mA-M]*$/,
424 /^[0-9a-nA-N]*$/,
425 /^[0-9a-oA-O]*$/,
426 /^[0-9a-pA-P]*$/,
427 /^[0-9a-qA-Q]*$/,
428 /^[0-9a-rA-R]*$/,
429 /^[0-9a-sA-S]*$/,
430 /^[0-9a-tA-T]*$/,
431 /^[0-9a-uA-U]*$/,
432 /^[0-9a-vA-V]*$/,
433 /^[0-9a-wA-W]*$/,
434 /^[0-9a-xA-X]*$/,
435 /^[0-9a-yA-Y]*$/,
436 /^[0-9a-zA-Z]*$/
437];
438
439/*
440 Function: parse
441 Parse a string into a <BigInteger>.
442
443 *base* is optional but, if provided, must be from 2 to 36 inclusive. If
444 *base* is not provided, it will be guessed based on the leading characters
445 of *s* as follows:
446
447 - "0x" or "0X": *base* = 16
448 - "0c" or "0C": *base* = 8
449 - "0b" or "0B": *base* = 2
450 - else: *base* = 10
451
452 If no base is provided, or *base* is 10, the number can be in exponential
453 form. For example, these are all valid:
454
455 > BigInteger.parse("1e9"); // Same as "1000000000"
456 > BigInteger.parse("1.234*10^3"); // Same as 1234
457 > BigInteger.parse("56789 * 10 ** -2"); // Same as 567
458
459 If any characters fall outside the range defined by the radix, an exception
460 will be thrown.
461
462 Parameters:
463
464 s - The string to parse.
465 base - Optional radix (default is to guess based on *s*).
466
467 Returns:
468
469 a <BigInteger> instance.
470*/
471BigInteger.parse = function(s, base) {
472 // Expands a number in exponential form to decimal form.
473 // expandExponential("-13.441*10^5") === "1344100";
474 // expandExponential("1.12300e-1") === "0.112300";
475 // expandExponential(1000000000000000000000000000000) === "1000000000000000000000000000000";
476 function expandExponential(str) {
477 str = str.replace(/\s*[*xX]\s*10\s*(\^|\*\*)\s*/, "e");
478
479 return str.replace(/^([+\-])?(\d+)\.?(\d*)[eE]([+\-]?\d+)$/, function(x, s, n, f, c) {
480 c = +c;
481 var l = c < 0;
482 var i = n.length + c;
483 x = (l ? n : f).length;
484 c = ((c = Math.abs(c)) >= x ? c - x + l : 0);
485 var z = (new Array(c + 1)).join("0");
486 var r = n + f;
487 return (s || "") + (l ? r = z + r : r += z).substr(0, i += l ? z.length : 0) + (i < r.length ? "." + r.substr(i) : "");
488 });
489 }
490
491 s = s.toString();
492 if (typeof base === "undefined" || +base === 10) {
493 s = expandExponential(s);
494 }
495
496 var prefixRE;
497 if (typeof base === "undefined") {
498 prefixRE = '0[xcb]';
499 }
500 else if (base == 16) {
501 prefixRE = '0x';
502 }
503 else if (base == 8) {
504 prefixRE = '0c';
505 }
506 else if (base == 2) {
507 prefixRE = '0b';
508 }
509 else {
510 prefixRE = '';
511 }
512 var parts = new RegExp('^([+\\-]?)(' + prefixRE + ')?([0-9a-z]*)(?:\\.\\d*)?$', 'i').exec(s);
513 if (parts) {
514 var sign = parts[1] || "+";
515 var baseSection = parts[2] || "";
516 var digits = parts[3] || "";
517
518 if (typeof base === "undefined") {
519 // Guess base
520 if (baseSection === "0x" || baseSection === "0X") { // Hex
521 base = 16;
522 }
523 else if (baseSection === "0c" || baseSection === "0C") { // Octal
524 base = 8;
525 }
526 else if (baseSection === "0b" || baseSection === "0B") { // Binary
527 base = 2;
528 }
529 else {
530 base = 10;
531 }
532 }
533 else if (base < 2 || base > 36) {
534 throw new Error("Illegal radix " + base + ".");
535 }
536
537 base = +base;
538
539 // Check for digits outside the range
540 if (!(BigInteger.radixRegex[base].test(digits))) {
541 throw new Error("Bad digit for radix " + base);
542 }
543
544 // Strip leading zeros, and convert to array
545 digits = digits.replace(/^0+/, "").split("");
546 if (digits.length === 0) {
547 return ZERO;
548 }
549
550 // Get the sign (we know it's not zero)
551 sign = (sign === "-") ? -1 : 1;
552
553 // Optimize 10
554 if (base == 10) {
555 var d = [];
556 while (digits.length >= BigInteger_base_log10) {
557 d.push(parseInt(digits.splice(digits.length-BigInteger.base_log10, BigInteger.base_log10).join(''), 10));
558 }
559 d.push(parseInt(digits.join(''), 10));
560 return new BigInteger(d, sign, CONSTRUCT);
561 }
562
563 // Do the conversion
564 var d = ZERO;
565 base = BigInteger.small[base];
566 var small = BigInteger.small;
567 for (var i = 0; i < digits.length; i++) {
568 d = d.multiply(base).add(small[parseInt(digits[i], 36)]);
569 }
570 return new BigInteger(d._d, sign, CONSTRUCT);
571 }
572 else {
573 throw new Error("Invalid BigInteger format: " + s);
574 }
575};
576
577/*
578 Function: add
579 Add two <BigIntegers>.
580
581 Parameters:
582
583 n - The number to add to *this*. Will be converted to a <BigInteger>.
584
585 Returns:
586
587 The numbers added together.
588
589 See Also:
590
591 <subtract>, <multiply>, <quotient>, <next>
592*/
593BigInteger.prototype.add = function(n) {
594 if (this._s === 0) {
595 return BigInteger(n);
596 }
597
598 n = BigInteger(n);
599 if (n._s === 0) {
600 return this;
601 }
602 if (this._s !== n._s) {
603 n = n.negate();
604 return this.subtract(n);
605 }
606
607 var a = this._d;
608 var b = n._d;
609 var al = a.length;
610 var bl = b.length;
611 var sum = new Array(Math.max(al, bl) + 1);
612 var size = Math.min(al, bl);
613 var carry = 0;
614 var digit;
615
616 for (var i = 0; i < size; i++) {
617 digit = a[i] + b[i] + carry;
618 sum[i] = digit % BigInteger_base;
619 carry = (digit / BigInteger_base) | 0;
620 }
621 if (bl > al) {
622 a = b;
623 al = bl;
624 }
625 for (i = size; carry && i < al; i++) {
626 digit = a[i] + carry;
627 sum[i] = digit % BigInteger_base;
628 carry = (digit / BigInteger_base) | 0;
629 }
630 if (carry) {
631 sum[i] = carry;
632 }
633
634 for ( ; i < al; i++) {
635 sum[i] = a[i];
636 }
637
638 return new BigInteger(sum, this._s, CONSTRUCT);
639};
640
641/*
642 Function: negate
643 Get the additive inverse of a <BigInteger>.
644
645 Returns:
646
647 A <BigInteger> with the same magnatude, but with the opposite sign.
648
649 See Also:
650
651 <abs>
652*/
653BigInteger.prototype.negate = function() {
654 return new BigInteger(this._d, (-this._s) | 0, CONSTRUCT);
655};
656
657/*
658 Function: abs
659 Get the absolute value of a <BigInteger>.
660
661 Returns:
662
663 A <BigInteger> with the same magnatude, but always positive (or zero).
664
665 See Also:
666
667 <negate>
668*/
669BigInteger.prototype.abs = function() {
670 return (this._s < 0) ? this.negate() : this;
671};
672
673/*
674 Function: subtract
675 Subtract two <BigIntegers>.
676
677 Parameters:
678
679 n - The number to subtract from *this*. Will be converted to a <BigInteger>.
680
681 Returns:
682
683 The *n* subtracted from *this*.
684
685 See Also:
686
687 <add>, <multiply>, <quotient>, <prev>
688*/
689BigInteger.prototype.subtract = function(n) {
690 if (this._s === 0) {
691 return BigInteger(n).negate();
692 }
693
694 n = BigInteger(n);
695 if (n._s === 0) {
696 return this;
697 }
698 if (this._s !== n._s) {
699 n = n.negate();
700 return this.add(n);
701 }
702
703 var m = this;
704 // negative - negative => -|a| - -|b| => -|a| + |b| => |b| - |a|
705 if (this._s < 0) {
706 m = new BigInteger(n._d, 1, CONSTRUCT);
707 n = new BigInteger(this._d, 1, CONSTRUCT);
708 }
709
710 // Both are positive => a - b
711 var sign = m.compareAbs(n);
712 if (sign === 0) {
713 return ZERO;
714 }
715 else if (sign < 0) {
716 // swap m and n
717 var t = n;
718 n = m;
719 m = t;
720 }
721
722 // a > b
723 var a = m._d;
724 var b = n._d;
725 var al = a.length;
726 var bl = b.length;
727 var diff = new Array(al); // al >= bl since a > b
728 var borrow = 0;
729 var i;
730 var digit;
731
732 for (i = 0; i < bl; i++) {
733 digit = a[i] - borrow - b[i];
734 if (digit < 0) {
735 digit += BigInteger_base;
736 borrow = 1;
737 }
738 else {
739 borrow = 0;
740 }
741 diff[i] = digit;
742 }
743 for (i = bl; i < al; i++) {
744 digit = a[i] - borrow;
745 if (digit < 0) {
746 digit += BigInteger_base;
747 }
748 else {
749 diff[i++] = digit;
750 break;
751 }
752 diff[i] = digit;
753 }
754 for ( ; i < al; i++) {
755 diff[i] = a[i];
756 }
757
758 return new BigInteger(diff, sign, CONSTRUCT);
759};
760
761(function() {
762 function addOne(n, sign) {
763 var a = n._d;
764 var sum = a.slice();
765 var carry = true;
766 var i = 0;
767
768 while (true) {
769 var digit = (a[i] || 0) + 1;
770 sum[i] = digit % BigInteger_base;
771 if (digit <= BigInteger_base - 1) {
772 break;
773 }
774 ++i;
775 }
776
777 return new BigInteger(sum, sign, CONSTRUCT);
778 }
779
780 function subtractOne(n, sign) {
781 var a = n._d;
782 var sum = a.slice();
783 var borrow = true;
784 var i = 0;
785
786 while (true) {
787 var digit = (a[i] || 0) - 1;
788 if (digit < 0) {
789 sum[i] = digit + BigInteger_base;
790 }
791 else {
792 sum[i] = digit;
793 break;
794 }
795 ++i;
796 }
797
798 return new BigInteger(sum, sign, CONSTRUCT);
799 }
800
801 /*
802 Function: next
803 Get the next <BigInteger> (add one).
804
805 Returns:
806
807 *this* + 1.
808
809 See Also:
810
811 <add>, <prev>
812 */
813 BigInteger.prototype.next = function() {
814 switch (this._s) {
815 case 0:
816 return ONE;
817 case -1:
818 return subtractOne(this, -1);
819 // case 1:
820 default:
821 return addOne(this, 1);
822 }
823 };
824
825 /*
826 Function: prev
827 Get the previous <BigInteger> (subtract one).
828
829 Returns:
830
831 *this* - 1.
832
833 See Also:
834
835 <next>, <subtract>
836 */
837 BigInteger.prototype.prev = function() {
838 switch (this._s) {
839 case 0:
840 return M_ONE;
841 case -1:
842 return addOne(this, -1);
843 // case 1:
844 default:
845 return subtractOne(this, 1);
846 }
847 };
848})();
849
850/*
851 Function: compareAbs
852 Compare the absolute value of two <BigIntegers>.
853
854 Calling <compareAbs> is faster than calling <abs> twice, then <compare>.
855
856 Parameters:
857
858 n - The number to compare to *this*. Will be converted to a <BigInteger>.
859
860 Returns:
861
862 -1, 0, or +1 if *|this|* is less than, equal to, or greater than *|n|*.
863
864 See Also:
865
866 <compare>, <abs>
867*/
868BigInteger.prototype.compareAbs = function(n) {
869 if (this === n) {
870 return 0;
871 }
872
873 if (!(n instanceof BigInteger)) {
874 if (!isFinite(n)) {
875 return(isNaN(n) ? n : -1);
876 }
877 n = BigInteger(n);
878 }
879
880 if (this._s === 0) {
881 return (n._s !== 0) ? -1 : 0;
882 }
883 if (n._s === 0) {
884 return 1;
885 }
886
887 var l = this._d.length;
888 var nl = n._d.length;
889 if (l < nl) {
890 return -1;
891 }
892 else if (l > nl) {
893 return 1;
894 }
895
896 var a = this._d;
897 var b = n._d;
898 for (var i = l-1; i >= 0; i--) {
899 if (a[i] !== b[i]) {
900 return a[i] < b[i] ? -1 : 1;
901 }
902 }
903
904 return 0;
905};
906
907/*
908 Function: compare
909 Compare two <BigIntegers>.
910
911 Parameters:
912
913 n - The number to compare to *this*. Will be converted to a <BigInteger>.
914
915 Returns:
916
917 -1, 0, or +1 if *this* is less than, equal to, or greater than *n*.
918
919 See Also:
920
921 <compareAbs>, <isPositive>, <isNegative>, <isUnit>
922*/
923BigInteger.prototype.compare = function(n) {
924 if (this === n) {
925 return 0;
926 }
927
928 n = BigInteger(n);
929
930 if (this._s === 0) {
931 return -n._s;
932 }
933
934 if (this._s === n._s) { // both positive or both negative
935 var cmp = this.compareAbs(n);
936 return cmp * this._s;
937 }
938 else {
939 return this._s;
940 }
941};
942
943/*
944 Function: isUnit
945 Return true iff *this* is either 1 or -1.
946
947 Returns:
948
949 true if *this* compares equal to <BigInteger.ONE> or <BigInteger.M_ONE>.
950
951 See Also:
952
953 <isZero>, <isNegative>, <isPositive>, <compareAbs>, <compare>,
954 <BigInteger.ONE>, <BigInteger.M_ONE>
955*/
956BigInteger.prototype.isUnit = function() {
957 return this === ONE ||
958 this === M_ONE ||
959 (this._d.length === 1 && this._d[0] === 1);
960};
961
962/*
963 Function: multiply
964 Multiply two <BigIntegers>.
965
966 Parameters:
967
968 n - The number to multiply *this* by. Will be converted to a
969 <BigInteger>.
970
971 Returns:
972
973 The numbers multiplied together.
974
975 See Also:
976
977 <add>, <subtract>, <quotient>, <square>
978*/
979BigInteger.prototype.multiply = function(n) {
980 // TODO: Consider adding Karatsuba multiplication for large numbers
981 if (this._s === 0) {
982 return ZERO;
983 }
984
985 n = BigInteger(n);
986 if (n._s === 0) {
987 return ZERO;
988 }
989 if (this.isUnit()) {
990 if (this._s < 0) {
991 return n.negate();
992 }
993 return n;
994 }
995 if (n.isUnit()) {
996 if (n._s < 0) {
997 return this.negate();
998 }
999 return this;
1000 }
1001 if (this === n) {
1002 return this.square();
1003 }
1004
1005 var r = (this._d.length >= n._d.length);
1006 var a = (r ? this : n)._d; // a will be longer than b
1007 var b = (r ? n : this)._d;
1008 var al = a.length;
1009 var bl = b.length;
1010
1011 var pl = al + bl;
1012 var partial = new Array(pl);
1013 var i;
1014 for (i = 0; i < pl; i++) {
1015 partial[i] = 0;
1016 }
1017
1018 for (i = 0; i < bl; i++) {
1019 var carry = 0;
1020 var bi = b[i];
1021 var jlimit = al + i;
1022 var digit;
1023 for (var j = i; j < jlimit; j++) {
1024 digit = partial[j] + bi * a[j - i] + carry;
1025 carry = (digit / BigInteger_base) | 0;
1026 partial[j] = (digit % BigInteger_base) | 0;
1027 }
1028 if (carry) {
1029 digit = partial[j] + carry;
1030 carry = (digit / BigInteger_base) | 0;
1031 partial[j] = digit % BigInteger_base;
1032 }
1033 }
1034 return new BigInteger(partial, this._s * n._s, CONSTRUCT);
1035};
1036
1037// Multiply a BigInteger by a single-digit native number
1038// Assumes that this and n are >= 0
1039// This is not really intended to be used outside the library itself
1040BigInteger.prototype.multiplySingleDigit = function(n) {
1041 if (n === 0 || this._s === 0) {
1042 return ZERO;
1043 }
1044 if (n === 1) {
1045 return this;
1046 }
1047
1048 var digit;
1049 if (this._d.length === 1) {
1050 digit = this._d[0] * n;
1051 if (digit >= BigInteger_base) {
1052 return new BigInteger([(digit % BigInteger_base)|0,
1053 (digit / BigInteger_base)|0], 1, CONSTRUCT);
1054 }
1055 return new BigInteger([digit], 1, CONSTRUCT);
1056 }
1057
1058 if (n === 2) {
1059 return this.add(this);
1060 }
1061 if (this.isUnit()) {
1062 return new BigInteger([n], 1, CONSTRUCT);
1063 }
1064
1065 var a = this._d;
1066 var al = a.length;
1067
1068 var pl = al + 1;
1069 var partial = new Array(pl);
1070 for (var i = 0; i < pl; i++) {
1071 partial[i] = 0;
1072 }
1073
1074 var carry = 0;
1075 for (var j = 0; j < al; j++) {
1076 digit = n * a[j] + carry;
1077 carry = (digit / BigInteger_base) | 0;
1078 partial[j] = (digit % BigInteger_base) | 0;
1079 }
1080 if (carry) {
1081 partial[j] = carry;
1082 }
1083
1084 return new BigInteger(partial, 1, CONSTRUCT);
1085};
1086
1087/*
1088 Function: square
1089 Multiply a <BigInteger> by itself.
1090
1091 This is slightly faster than regular multiplication, since it removes the
1092 duplicated multiplcations.
1093
1094 Returns:
1095
1096 > this.multiply(this)
1097
1098 See Also:
1099 <multiply>
1100*/
1101BigInteger.prototype.square = function() {
1102 // Normally, squaring a 10-digit number would take 100 multiplications.
1103 // Of these 10 are unique diagonals, of the remaining 90 (100-10), 45 are repeated.
1104 // This procedure saves (N*(N-1))/2 multiplications, (e.g., 45 of 100 multiplies).
1105 // Based on code by Gary Darby, Intellitech Systems Inc., www.DelphiForFun.org
1106
1107 if (this._s === 0) {
1108 return ZERO;
1109 }
1110 if (this.isUnit()) {
1111 return ONE;
1112 }
1113
1114 var digits = this._d;
1115 var length = digits.length;
1116 var imult1 = new Array(length + length + 1);
1117 var product, carry, k;
1118 var i;
1119
1120 // Calculate diagonal
1121 for (i = 0; i < length; i++) {
1122 k = i * 2;
1123 product = digits[i] * digits[i];
1124 carry = (product / BigInteger_base) | 0;
1125 imult1[k] = product % BigInteger_base;
1126 imult1[k + 1] = carry;
1127 }
1128
1129 // Calculate repeating part
1130 for (i = 0; i < length; i++) {
1131 carry = 0;
1132 k = i * 2 + 1;
1133 for (var j = i + 1; j < length; j++, k++) {
1134 product = digits[j] * digits[i] * 2 + imult1[k] + carry;
1135 carry = (product / BigInteger_base) | 0;
1136 imult1[k] = product % BigInteger_base;
1137 }
1138 k = length + i;
1139 var digit = carry + imult1[k];
1140 carry = (digit / BigInteger_base) | 0;
1141 imult1[k] = digit % BigInteger_base;
1142 imult1[k + 1] += carry;
1143 }
1144
1145 return new BigInteger(imult1, 1, CONSTRUCT);
1146};
1147
1148/*
1149 Function: quotient
1150 Divide two <BigIntegers> and truncate towards zero.
1151
1152 <quotient> throws an exception if *n* is zero.
1153
1154 Parameters:
1155
1156 n - The number to divide *this* by. Will be converted to a <BigInteger>.
1157
1158 Returns:
1159
1160 The *this* / *n*, truncated to an integer.
1161
1162 See Also:
1163
1164 <add>, <subtract>, <multiply>, <divRem>, <remainder>
1165*/
1166BigInteger.prototype.quotient = function(n) {
1167 return this.divRem(n)[0];
1168};
1169
1170/*
1171 Function: divide
1172 Deprecated synonym for <quotient>.
1173*/
1174BigInteger.prototype.divide = BigInteger.prototype.quotient;
1175
1176/*
1177 Function: remainder
1178 Calculate the remainder of two <BigIntegers>.
1179
1180 <remainder> throws an exception if *n* is zero.
1181
1182 Parameters:
1183
1184 n - The remainder after *this* is divided *this* by *n*. Will be
1185 converted to a <BigInteger>.
1186
1187 Returns:
1188
1189 *this* % *n*.
1190
1191 See Also:
1192
1193 <divRem>, <quotient>
1194*/
1195BigInteger.prototype.remainder = function(n) {
1196 return this.divRem(n)[1];
1197};
1198
1199/*
1200 Function: divRem
1201 Calculate the integer quotient and remainder of two <BigIntegers>.
1202
1203 <divRem> throws an exception if *n* is zero.
1204
1205 Parameters:
1206
1207 n - The number to divide *this* by. Will be converted to a <BigInteger>.
1208
1209 Returns:
1210
1211 A two-element array containing the quotient and the remainder.
1212
1213 > a.divRem(b)
1214
1215 is exactly equivalent to
1216
1217 > [a.quotient(b), a.remainder(b)]
1218
1219 except it is faster, because they are calculated at the same time.
1220
1221 See Also:
1222
1223 <quotient>, <remainder>
1224*/
1225BigInteger.prototype.divRem = function(n) {
1226 n = BigInteger(n);
1227 if (n._s === 0) {
1228 throw new Error("Divide by zero");
1229 }
1230 if (this._s === 0) {
1231 return [ZERO, ZERO];
1232 }
1233 if (n._d.length === 1) {
1234 return this.divRemSmall(n._s * n._d[0]);
1235 }
1236
1237 // Test for easy cases -- |n1| <= |n2|
1238 switch (this.compareAbs(n)) {
1239 case 0: // n1 == n2
1240 return [this._s === n._s ? ONE : M_ONE, ZERO];
1241 case -1: // |n1| < |n2|
1242 return [ZERO, this];
1243 }
1244
1245 var sign = this._s * n._s;
1246 var a = n.abs();
1247 var b_digits = this._d;
1248 var b_index = b_digits.length;
1249 var digits = n._d.length;
1250 var quot = [];
1251 var guess;
1252
1253 var part = new BigInteger([], 0, CONSTRUCT);
1254
1255 while (b_index) {
1256 part._d.unshift(b_digits[--b_index]);
1257 part = new BigInteger(part._d, 1, CONSTRUCT);
1258
1259 if (part.compareAbs(n) < 0) {
1260 quot.push(0);
1261 continue;
1262 }
1263 if (part._s === 0) {
1264 guess = 0;
1265 }
1266 else {
1267 var xlen = part._d.length, ylen = a._d.length;
1268 var highx = part._d[xlen-1]*BigInteger_base + part._d[xlen-2];
1269 var highy = a._d[ylen-1]*BigInteger_base + a._d[ylen-2];
1270 if (part._d.length > a._d.length) {
1271 // The length of part._d can either match a._d length,
1272 // or exceed it by one.
1273 highx = (highx+1)*BigInteger_base;
1274 }
1275 guess = Math.ceil(highx/highy);
1276 }
1277 do {
1278 var check = a.multiplySingleDigit(guess);
1279 if (check.compareAbs(part) <= 0) {
1280 break;
1281 }
1282 guess--;
1283 } while (guess);
1284
1285 quot.push(guess);
1286 if (!guess) {
1287 continue;
1288 }
1289 var diff = part.subtract(check);
1290 part._d = diff._d.slice();
1291 }
1292
1293 return [new BigInteger(quot.reverse(), sign, CONSTRUCT),
1294 new BigInteger(part._d, this._s, CONSTRUCT)];
1295};
1296
1297// Throws an exception if n is outside of (-BigInteger.base, -1] or
1298// [1, BigInteger.base). It's not necessary to call this, since the
1299// other division functions will call it if they are able to.
1300BigInteger.prototype.divRemSmall = function(n) {
1301 var r;
1302 n = +n;
1303 if (n === 0) {
1304 throw new Error("Divide by zero");
1305 }
1306
1307 var n_s = n < 0 ? -1 : 1;
1308 var sign = this._s * n_s;
1309 n = Math.abs(n);
1310
1311 if (n < 1 || n >= BigInteger_base) {
1312 throw new Error("Argument out of range");
1313 }
1314
1315 if (this._s === 0) {
1316 return [ZERO, ZERO];
1317 }
1318
1319 if (n === 1 || n === -1) {
1320 return [(sign === 1) ? this.abs() : new BigInteger(this._d, sign, CONSTRUCT), ZERO];
1321 }
1322
1323 // 2 <= n < BigInteger_base
1324
1325 // divide a single digit by a single digit
1326 if (this._d.length === 1) {
1327 var q = new BigInteger([(this._d[0] / n) | 0], 1, CONSTRUCT);
1328 r = new BigInteger([(this._d[0] % n) | 0], 1, CONSTRUCT);
1329 if (sign < 0) {
1330 q = q.negate();
1331 }
1332 if (this._s < 0) {
1333 r = r.negate();
1334 }
1335 return [q, r];
1336 }
1337
1338 var digits = this._d.slice();
1339 var quot = new Array(digits.length);
1340 var part = 0;
1341 var diff = 0;
1342 var i = 0;
1343 var guess;
1344
1345 while (digits.length) {
1346 part = part * BigInteger_base + digits[digits.length - 1];
1347 if (part < n) {
1348 quot[i++] = 0;
1349 digits.pop();
1350 diff = BigInteger_base * diff + part;
1351 continue;
1352 }
1353 if (part === 0) {
1354 guess = 0;
1355 }
1356 else {
1357 guess = (part / n) | 0;
1358 }
1359
1360 var check = n * guess;
1361 diff = part - check;
1362 quot[i++] = guess;
1363 if (!guess) {
1364 digits.pop();
1365 continue;
1366 }
1367
1368 digits.pop();
1369 part = diff;
1370 }
1371
1372 r = new BigInteger([diff], 1, CONSTRUCT);
1373 if (this._s < 0) {
1374 r = r.negate();
1375 }
1376 return [new BigInteger(quot.reverse(), sign, CONSTRUCT), r];
1377};
1378
1379/*
1380 Function: isEven
1381 Return true iff *this* is divisible by two.
1382
1383 Note that <BigInteger.ZERO> is even.
1384
1385 Returns:
1386
1387 true if *this* is even, false otherwise.
1388
1389 See Also:
1390
1391 <isOdd>
1392*/
1393BigInteger.prototype.isEven = function() {
1394 var digits = this._d;
1395 return this._s === 0 || digits.length === 0 || (digits[0] % 2) === 0;
1396};
1397
1398/*
1399 Function: isOdd
1400 Return true iff *this* is not divisible by two.
1401
1402 Returns:
1403
1404 true if *this* is odd, false otherwise.
1405
1406 See Also:
1407
1408 <isEven>
1409*/
1410BigInteger.prototype.isOdd = function() {
1411 return !this.isEven();
1412};
1413
1414/*
1415 Function: sign
1416 Get the sign of a <BigInteger>.
1417
1418 Returns:
1419
1420 * -1 if *this* < 0
1421 * 0 if *this* == 0
1422 * +1 if *this* > 0
1423
1424 See Also:
1425
1426 <isZero>, <isPositive>, <isNegative>, <compare>, <BigInteger.ZERO>
1427*/
1428BigInteger.prototype.sign = function() {
1429 return this._s;
1430};
1431
1432/*
1433 Function: isPositive
1434 Return true iff *this* > 0.
1435
1436 Returns:
1437
1438 true if *this*.compare(<BigInteger.ZERO>) == 1.
1439
1440 See Also:
1441
1442 <sign>, <isZero>, <isNegative>, <isUnit>, <compare>, <BigInteger.ZERO>
1443*/
1444BigInteger.prototype.isPositive = function() {
1445 return this._s > 0;
1446};
1447
1448/*
1449 Function: isNegative
1450 Return true iff *this* < 0.
1451
1452 Returns:
1453
1454 true if *this*.compare(<BigInteger.ZERO>) == -1.
1455
1456 See Also:
1457
1458 <sign>, <isPositive>, <isZero>, <isUnit>, <compare>, <BigInteger.ZERO>
1459*/
1460BigInteger.prototype.isNegative = function() {
1461 return this._s < 0;
1462};
1463
1464/*
1465 Function: isZero
1466 Return true iff *this* == 0.
1467
1468 Returns:
1469
1470 true if *this*.compare(<BigInteger.ZERO>) == 0.
1471
1472 See Also:
1473
1474 <sign>, <isPositive>, <isNegative>, <isUnit>, <BigInteger.ZERO>
1475*/
1476BigInteger.prototype.isZero = function() {
1477 return this._s === 0;
1478};
1479
1480/*
1481 Function: exp10
1482 Multiply a <BigInteger> by a power of 10.
1483
1484 This is equivalent to, but faster than
1485
1486 > if (n >= 0) {
1487 > return this.multiply(BigInteger("1e" + n));
1488 > }
1489 > else { // n <= 0
1490 > return this.quotient(BigInteger("1e" + -n));
1491 > }
1492
1493 Parameters:
1494
1495 n - The power of 10 to multiply *this* by. *n* is converted to a
1496 javascipt number and must be no greater than <BigInteger.MAX_EXP>
1497 (0x7FFFFFFF), or an exception will be thrown.
1498
1499 Returns:
1500
1501 *this* * (10 ** *n*), truncated to an integer if necessary.
1502
1503 See Also:
1504
1505 <pow>, <multiply>
1506*/
1507BigInteger.prototype.exp10 = function(n) {
1508 n = +n;
1509 if (n === 0) {
1510 return this;
1511 }
1512 if (Math.abs(n) > Number(MAX_EXP)) {
1513 throw new Error("exponent too large in BigInteger.exp10");
1514 }
1515 // Optimization for this == 0. This also keeps us from having to trim zeros in the positive n case
1516 if (this._s === 0) {
1517 return ZERO;
1518 }
1519 if (n > 0) {
1520 var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT);
1521
1522 for (; n >= BigInteger_base_log10; n -= BigInteger_base_log10) {
1523 k._d.unshift(0);
1524 }
1525 if (n == 0)
1526 return k;
1527 k._s = 1;
1528 k = k.multiplySingleDigit(Math.pow(10, n));
1529 return (this._s < 0 ? k.negate() : k);
1530 } else if (-n >= this._d.length*BigInteger_base_log10) {
1531 return ZERO;
1532 } else {
1533 var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT);
1534
1535 for (n = -n; n >= BigInteger_base_log10; n -= BigInteger_base_log10) {
1536 k._d.shift();
1537 }
1538 return (n == 0) ? k : k.divRemSmall(Math.pow(10, n))[0];
1539 }
1540};
1541
1542/*
1543 Function: pow
1544 Raise a <BigInteger> to a power.
1545
1546 In this implementation, 0**0 is 1.
1547
1548 Parameters:
1549
1550 n - The exponent to raise *this* by. *n* must be no greater than
1551 <BigInteger.MAX_EXP> (0x7FFFFFFF), or an exception will be thrown.
1552
1553 Returns:
1554
1555 *this* raised to the *nth* power.
1556
1557 See Also:
1558
1559 <modPow>
1560*/
1561BigInteger.prototype.pow = function(n) {
1562 if (this.isUnit()) {
1563 if (this._s > 0) {
1564 return this;
1565 }
1566 else {
1567 return BigInteger(n).isOdd() ? this : this.negate();
1568 }
1569 }
1570
1571 n = BigInteger(n);
1572 if (n._s === 0) {
1573 return ONE;
1574 }
1575 else if (n._s < 0) {
1576 if (this._s === 0) {
1577 throw new Error("Divide by zero");
1578 }
1579 else {
1580 return ZERO;
1581 }
1582 }
1583 if (this._s === 0) {
1584 return ZERO;
1585 }
1586 if (n.isUnit()) {
1587 return this;
1588 }
1589
1590 if (n.compareAbs(MAX_EXP) > 0) {
1591 throw new Error("exponent too large in BigInteger.pow");
1592 }
1593 var x = this;
1594 var aux = ONE;
1595 var two = BigInteger.small[2];
1596
1597 while (n.isPositive()) {
1598 if (n.isOdd()) {
1599 aux = aux.multiply(x);
1600 if (n.isUnit()) {
1601 return aux;
1602 }
1603 }
1604 x = x.square();
1605 n = n.quotient(two);
1606 }
1607
1608 return aux;
1609};
1610
1611/*
1612 Function: modPow
1613 Raise a <BigInteger> to a power (mod m).
1614
1615 Because it is reduced by a modulus, <modPow> is not limited by
1616 <BigInteger.MAX_EXP> like <pow>.
1617
1618 Parameters:
1619
1620 exponent - The exponent to raise *this* by. Must be positive.
1621 modulus - The modulus.
1622
1623 Returns:
1624
1625 *this* ^ *exponent* (mod *modulus*).
1626
1627 See Also:
1628
1629 <pow>, <mod>
1630*/
1631BigInteger.prototype.modPow = function(exponent, modulus) {
1632 var result = ONE;
1633 var base = this;
1634
1635 while (exponent.isPositive()) {
1636 if (exponent.isOdd()) {
1637 result = result.multiply(base).remainder(modulus);
1638 }
1639
1640 exponent = exponent.quotient(BigInteger.small[2]);
1641 if (exponent.isPositive()) {
1642 base = base.square().remainder(modulus);
1643 }
1644 }
1645
1646 return result;
1647};
1648
1649/*
1650 Function: log
1651 Get the natural logarithm of a <BigInteger> as a native JavaScript number.
1652
1653 This is equivalent to
1654
1655 > Math.log(this.toJSValue())
1656
1657 but handles values outside of the native number range.
1658
1659 Returns:
1660
1661 log( *this* )
1662
1663 See Also:
1664
1665 <toJSValue>
1666*/
1667BigInteger.prototype.log = function() {
1668 switch (this._s) {
1669 case 0: return -Infinity;
1670 case -1: return NaN;
1671 default: // Fall through.
1672 }
1673
1674 var l = this._d.length;
1675
1676 if (l*BigInteger_base_log10 < 30) {
1677 return Math.log(this.valueOf());
1678 }
1679
1680 var N = Math.ceil(30/BigInteger_base_log10);
1681 var firstNdigits = this._d.slice(l - N);
1682 return Math.log((new BigInteger(firstNdigits, 1, CONSTRUCT)).valueOf()) + (l - N) * Math.log(BigInteger_base);
1683};
1684
1685/*
1686 Function: valueOf
1687 Convert a <BigInteger> to a native JavaScript integer.
1688
1689 This is called automatically by JavaScipt to convert a <BigInteger> to a
1690 native value.
1691
1692 Returns:
1693
1694 > parseInt(this.toString(), 10)
1695
1696 See Also:
1697
1698 <toString>, <toJSValue>
1699*/
1700BigInteger.prototype.valueOf = function() {
1701 return parseInt(this.toString(), 10);
1702};
1703
1704/*
1705 Function: toJSValue
1706 Convert a <BigInteger> to a native JavaScript integer.
1707
1708 This is the same as valueOf, but more explicitly named.
1709
1710 Returns:
1711
1712 > parseInt(this.toString(), 10)
1713
1714 See Also:
1715
1716 <toString>, <valueOf>
1717*/
1718BigInteger.prototype.toJSValue = function() {
1719 return parseInt(this.toString(), 10);
1720};
1721
1722var MAX_EXP = BigInteger(0x7FFFFFFF);
1723// Constant: MAX_EXP
1724// The largest exponent allowed in <pow> and <exp10> (0x7FFFFFFF or 2147483647).
1725BigInteger.MAX_EXP = MAX_EXP;
1726
1727(function() {
1728 function makeUnary(fn) {
1729 return function(a) {
1730 return fn.call(BigInteger(a));
1731 };
1732 }
1733
1734 function makeBinary(fn) {
1735 return function(a, b) {
1736 return fn.call(BigInteger(a), BigInteger(b));
1737 };
1738 }
1739
1740 function makeTrinary(fn) {
1741 return function(a, b, c) {
1742 return fn.call(BigInteger(a), BigInteger(b), BigInteger(c));
1743 };
1744 }
1745
1746 (function() {
1747 var i, fn;
1748 var unary = "toJSValue,isEven,isOdd,sign,isZero,isNegative,abs,isUnit,square,negate,isPositive,toString,next,prev,log".split(",");
1749 var binary = "compare,remainder,divRem,subtract,add,quotient,divide,multiply,pow,compareAbs".split(",");
1750 var trinary = ["modPow"];
1751
1752 for (i = 0; i < unary.length; i++) {
1753 fn = unary[i];
1754 BigInteger[fn] = makeUnary(BigInteger.prototype[fn]);
1755 }
1756
1757 for (i = 0; i < binary.length; i++) {
1758 fn = binary[i];
1759 BigInteger[fn] = makeBinary(BigInteger.prototype[fn]);
1760 }
1761
1762 for (i = 0; i < trinary.length; i++) {
1763 fn = trinary[i];
1764 BigInteger[fn] = makeTrinary(BigInteger.prototype[fn]);
1765 }
1766
1767 BigInteger.exp10 = function(x, n) {
1768 return BigInteger(x).exp10(n);
1769 };
1770 })();
1771})();
1772
1773exports.BigInteger = BigInteger;
1774})(typeof exports !== 'undefined' ? exports : this);
diff --git a/src/js/index.js b/src/js/index.js
index 0e4cc05..cd7f281 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -14,14 +14,20 @@
14 var showPubKey = true; 14 var showPubKey = true;
15 var showPrivKey = true; 15 var showPrivKey = true;
16 16
17 var entropyChangeTimeoutEvent = null;
17 var phraseChangeTimeoutEvent = null; 18 var phraseChangeTimeoutEvent = null;
18 var rootKeyChangedTimeoutEvent = null; 19 var rootKeyChangedTimeoutEvent = null;
19 20
20 var DOM = {}; 21 var DOM = {};
21 DOM.network = $(".network"); 22 DOM.network = $(".network");
22 DOM.phraseNetwork = $("#network-phrase"); 23 DOM.phraseNetwork = $("#network-phrase");
24 DOM.useEntropy = $(".use-entropy");
25 DOM.entropyContainer = $(".entropy-container");
26 DOM.entropy = $(".entropy");
27 DOM.entropyError = $(".entropy-error");
23 DOM.phrase = $(".phrase"); 28 DOM.phrase = $(".phrase");
24 DOM.passphrase = $(".passphrase"); 29 DOM.passphrase = $(".passphrase");
30 DOM.generateContainer = $(".generate-container");
25 DOM.generate = $(".generate"); 31 DOM.generate = $(".generate");
26 DOM.seed = $(".seed"); 32 DOM.seed = $(".seed");
27 DOM.rootKey = $(".root-key"); 33 DOM.rootKey = $(".root-key");
@@ -53,6 +59,8 @@
53 function init() { 59 function init() {
54 // Events 60 // Events
55 DOM.network.on("change", networkChanged); 61 DOM.network.on("change", networkChanged);
62 DOM.useEntropy.on("change", setEntropyVisibility);
63 DOM.entropy.on("input", delayedEntropyChanged);
56 DOM.phrase.on("input", delayedPhraseChanged); 64 DOM.phrase.on("input", delayedPhraseChanged);
57 DOM.passphrase.on("input", delayedPhraseChanged); 65 DOM.passphrase.on("input", delayedPhraseChanged);
58 DOM.generate.on("click", generateClicked); 66 DOM.generate.on("click", generateClicked);
@@ -89,6 +97,21 @@
89 } 97 }
90 } 98 }
91 99
100 function setEntropyVisibility() {
101 if (isUsingOwnEntropy()) {
102 DOM.entropyContainer.removeClass("hidden");
103 DOM.generateContainer.addClass("hidden");
104 DOM.phrase.prop("readonly", true);
105 DOM.entropy.focus();
106 entropyChanged();
107 }
108 else {
109 DOM.entropyContainer.addClass("hidden");
110 DOM.generateContainer.removeClass("hidden");
111 DOM.phrase.prop("readonly", false);
112 }
113 }
114
92 function delayedPhraseChanged() { 115 function delayedPhraseChanged() {
93 hideValidationError(); 116 hideValidationError();
94 showPending(); 117 showPending();
@@ -116,6 +139,20 @@
116 hidePending(); 139 hidePending();
117 } 140 }
118 141
142 function delayedEntropyChanged() {
143 hideValidationError();
144 showPending();
145 if (entropyChangeTimeoutEvent != null) {
146 clearTimeout(entropyChangeTimeoutEvent);
147 }
148 entropyChangeTimeoutEvent = setTimeout(entropyChanged, 400);
149 }
150
151 function entropyChanged() {
152 setMnemonicFromEntropy();
153 phraseChanged();
154 }
155
119 function delayedRootKeyChanged() { 156 function delayedRootKeyChanged() {
120 // Warn if there is an existing mnemonic or passphrase. 157 // Warn if there is an existing mnemonic or passphrase.
121 if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) { 158 if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) {
@@ -168,6 +205,9 @@
168 } 205 }
169 206
170 function generateClicked() { 207 function generateClicked() {
208 if (isUsingOwnEntropy()) {
209 return;
210 }
171 clearDisplay(); 211 clearDisplay();
172 showPending(); 212 showPending();
173 setTimeout(function() { 213 setTimeout(function() {
@@ -599,7 +639,12 @@
599 } 639 }
600 640
601 function getLanguageFromUrl() { 641 function getLanguageFromUrl() {
602 return window.location.hash.substring(1); 642 for (var language in WORDLISTS) {
643 if (window.location.hash.indexOf(language) > -1) {
644 return language;
645 }
646 }
647 return "";
603 } 648 }
604 649
605 function setMnemonicLanguage() { 650 function setMnemonicLanguage() {
@@ -650,6 +695,65 @@
650 return phrase; 695 return phrase;
651 } 696 }
652 697
698 function isUsingOwnEntropy() {
699 return DOM.useEntropy.prop("checked");
700 }
701
702 function setMnemonicFromEntropy() {
703 hideEntropyError();
704 // Work out minimum base for entropy
705 var entropyStr = DOM.entropy.val();
706 var entropy = Entropy.fromString(entropyStr);
707 if (entropy.hexStr.length == 0) {
708 return;
709 }
710 // Show entropy details
711 var extraBits = 32 - (entropy.binaryStr.length % 32);
712 var extraChars = Math.ceil(extraBits * Math.log(2) / Math.log(entropy.base.asInt));
713 var strength = "an extremely weak";
714 if (entropy.hexStr.length >= 8) {
715 strength = "a very weak";
716 }
717 if (entropy.hexStr.length >= 12) {
718 strength = "a weak";
719 }
720 if (entropy.hexStr.length >= 24) {
721 strength = "a strong";
722 }
723 if (entropy.hexStr.length >= 32) {
724 strength = "a very strong";
725 }
726 if (entropy.hexStr.length >= 40) {
727 strength = "an extremely strong";
728 }
729 if (entropy.hexStr.length >=48) {
730 strength = "an even stronger"
731 }
732 var msg = "Have " + entropy.binaryStr.length + " bits of entropy, " + extraChars + " more " + entropy.base.str + " chars required to generate " + strength + " mnemonic: " + entropy.cleanStr;
733 showEntropyError(msg);
734 // Discard trailing entropy
735 var hexStr = entropy.hexStr.substring(0, Math.floor(entropy.hexStr.length / 8) * 8);
736 // Convert entropy string to numeric array
737 var entropyArr = [];
738 for (var i=0; i<hexStr.length / 2; i++) {
739 var entropyByte = parseInt(hexStr[i*2].concat(hexStr[i*2+1]), 16);
740 entropyArr.push(entropyByte)
741 }
742 // Convert entropy array to mnemonic
743 var phrase = mnemonic.toMnemonic(entropyArr);
744 // Set the mnemonic in the UI
745 DOM.phrase.val(phrase);
746 }
747
748 function hideEntropyError() {
749 DOM.entropyError.addClass("hidden");
750 }
751
752 function showEntropyError(msg) {
753 DOM.entropyError.text(msg);
754 DOM.entropyError.removeClass("hidden");
755 }
756
653 var networks = [ 757 var networks = [
654 { 758 {
655 name: "Bitcoin", 759 name: "Bitcoin",
diff --git a/tests.js b/tests.js
index 914be24..ec368cb 100644
--- a/tests.js
+++ b/tests.js
@@ -1960,6 +1960,613 @@ page.open(url, function(status) {
1960}); 1960});
1961}, 1961},
1962 1962
1963// Entropy unit tests
1964function() {
1965page.open(url, function(status) {
1966 var error = page.evaluate(function() {
1967 var e;
1968 // binary entropy is detected
1969 e = Entropy.fromString("01010101");
1970 if (e.base.str != "binary") {
1971 return "Binary entropy not detected correctly";
1972 }
1973 // base6 entropy is detected
1974 e = Entropy.fromString("012345012345");
1975 if (e.base.str != "base 6") {
1976 return "base6 entropy not detected correctly";
1977 }
1978 // dice entropy is detected
1979 e = Entropy.fromString("123456123456");
1980 if (e.base.str != "base 6 (dice)") {
1981 return "dice entropy not detected correctly";
1982 }
1983 // base10 entropy is detected
1984 e = Entropy.fromString("0123456789");
1985 if (e.base.str != "base 10") {
1986 return "base10 entropy not detected correctly";
1987 }
1988 // hex entropy is detected
1989 e = Entropy.fromString("0123456789ABCDEF");
1990 if (e.base.str != "hexadecimal") {
1991 return "hexadecimal entropy not detected correctly";
1992 }
1993 // entropy is case insensitive
1994 e = Entropy.fromString("aBcDeF");
1995 if (e.cleanStr != "aBcDeF") {
1996 return "Entropy should not be case sensitive";
1997 }
1998 // dice entropy is converted to base6
1999 e = Entropy.fromString("123456");
2000 if (e.cleanStr != "012345") {
2001 return "Dice entropy is not automatically converted to base6";
2002 }
2003 // dice entropy is preferred to base6 if ambiguous
2004 e = Entropy.fromString("12345");
2005 if (e.base.str != "base 6 (dice)") {
2006 return "dice not used as default over base 6";
2007 }
2008 // unused characters are ignored
2009 e = Entropy.fromString("fghijkl");
2010 if (e.cleanStr != "f") {
2011 return "additional characters are not ignored";
2012 }
2013 // the lowest base is used by default
2014 // 7 could be decimal or hexadecimal, but should be detected as decimal
2015 e = Entropy.fromString("7");
2016 if (e.base.str != "base 10") {
2017 return "lowest base is not used";
2018 }
2019 // Hexadecimal representation is returned
2020 e = Entropy.fromString("1010");
2021 if (e.hexStr != "A") {
2022 return "Hexadecimal representation not returned";
2023 }
2024 // Leading zeros are retained
2025 e = Entropy.fromString("000A");
2026 if (e.cleanStr != "000A") {
2027 return "Leading zeros are not retained";
2028 }
2029 // Leading zeros are correctly preserved for hex in binary string
2030 e = Entropy.fromString("2A");
2031 if (e.binaryStr != "00101010") {
2032 return "Hex leading zeros are not correct in binary";
2033 }
2034 // Keyboard mashing results in weak entropy
2035 // Despite being a long string, it's less than 30 bits of entropy
2036 e = Entropy.fromString("aj;se ifj; ask,dfv js;ifj");
2037 if (e.binaryStr.length >= 30) {
2038 return "Keyboard mashing should produce weak entropy";
2039 }
2040 return false;
2041 });
2042 if (error) {
2043 console.log("Entropy unit tests");
2044 console.log(error);
2045 fail();
2046 };
2047 next();
2048});
2049},
2050
2051// Entropy can be entered by the user
2052function() {
2053page.open(url, function(status) {
2054 expected = {
2055 mnemonic: "abandon abandon ability",
2056 address: "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug",
2057 }
2058 // use entropy
2059 page.evaluate(function() {
2060 $(".use-entropy").prop("checked", true).trigger("change");
2061 $(".entropy").val("00000000 00000000 00000000 00000000").trigger("input");
2062 });
2063 // check the mnemonic is set and address is correct
2064 waitForGenerate(function() {
2065 var actual = page.evaluate(function() {
2066 return {
2067 address: $(".address:first").text(),
2068 mnemonic: $(".phrase").val(),
2069 }
2070 });
2071 if (actual.mnemonic != expected.mnemonic) {
2072 console.log("Entropy does not generate correct mnemonic");
2073 console.log("Expected: " + expected.mnemonic);
2074 console.log("Got: " + actual.mnemonic);
2075 fail();
2076 }
2077 if (actual.address != expected.address) {
2078 console.log("Entropy does not generate correct address");
2079 console.log("Expected: " + expected.address);
2080 console.log("Got: " + actual.address);
2081 fail();
2082 }
2083 next();
2084 });
2085});
2086},
2087
2088// A warning about entropy is shown to the user, with additional information
2089function() {
2090page.open(url, function(status) {
2091 // get text content from entropy sections of page
2092 var hasWarning = page.evaluate(function() {
2093 var entropyText = $(".entropy-container").text();
2094 var warning = "mnemonic may be insecure";
2095 if (entropyText.indexOf(warning) == -1) {
2096 return false;
2097 }
2098 var readMoreText = $("#entropy-notes").parent().text();
2099 var goodSources = "flipping a fair coin, rolling a fair dice, noise measurements etc";
2100 if (readMoreText.indexOf(goodSources) == -1) {
2101 return false;
2102 }
2103 return true;
2104 });
2105 // check the warnings and information are shown
2106 if (!hasWarning) {
2107 console.log("Page does not contain warning about using own entropy");
2108 fail();
2109 }
2110 next();
2111});
2112},
2113
2114// The types of entropy available are described to the user
2115function() {
2116page.open(url, function(status) {
2117 // get placeholder text for entropy field
2118 var placeholder = page.evaluate(function() {
2119 return $(".entropy").attr("placeholder");
2120 });
2121 var options = [
2122 "binary",
2123 "base 6",
2124 "dice",
2125 "base 10",
2126 "hexadecimal",
2127 ];
2128 for (var i=0; i<options.length; i++) {
2129 var option = options[i];
2130 if (placeholder.indexOf(option) == -1) {
2131 console.log("Available entropy type is not shown to user: " + option);
2132 fail();
2133 }
2134 }
2135 next();
2136});
2137},
2138
2139// The actual entropy used is shown to the user
2140function() {
2141page.open(url, function(status) {
2142 // use entropy
2143 var badEntropySource = page.evaluate(function() {
2144 var entropy = "Not A Very Good Entropy Source At All";
2145 $(".use-entropy").prop("checked", true).trigger("change");
2146 $(".entropy").val(entropy).trigger("input");
2147 });
2148 // check the actual entropy being used is shown
2149 waitForGenerate(function() {
2150 var expectedText = "AedEceAA";
2151 var entropyText = page.evaluate(function() {
2152 return $(".entropy-container").text();
2153 });
2154 if (entropyText.indexOf(expectedText) == -1) {
2155 console.log("Actual entropy used is not shown");
2156 fail();
2157 }
2158 next();
2159 });
2160});
2161},
2162
2163// Binary entropy can be entered
2164function() {
2165page.open(url, function(status) {
2166 // use entropy
2167 page.evaluate(function() {
2168 $(".use-entropy").prop("checked", true).trigger("change");
2169 $(".entropy").val("01").trigger("input");
2170 });
2171 // check the entropy is shown to be the correct type
2172 waitForGenerate(function() {
2173 var entropyText = page.evaluate(function() {
2174 return $(".entropy-container").text();
2175 });
2176 if (entropyText.indexOf("binary") == -1) {
2177 console.log("Binary entropy is not detected and presented to user");
2178 fail();
2179 }
2180 next();
2181 });
2182});
2183},
2184
2185// Base 6 entropy can be entered
2186function() {
2187page.open(url, function(status) {
2188 // use entropy
2189 page.evaluate(function() {
2190 $(".use-entropy").prop("checked", true).trigger("change");
2191 $(".entropy").val("012345").trigger("input");
2192 });
2193 // check the entropy is shown to be the correct type
2194 waitForGenerate(function() {
2195 var entropyText = page.evaluate(function() {
2196 return $(".entropy-container").text();
2197 });
2198 if (entropyText.indexOf("base 6") == -1) {
2199 console.log("Base 6 entropy is not detected and presented to user");
2200 fail();
2201 }
2202 next();
2203 });
2204});
2205},
2206
2207// Base 6 dice entropy can be entered
2208function() {
2209page.open(url, function(status) {
2210 // use entropy
2211 page.evaluate(function() {
2212 $(".use-entropy").prop("checked", true).trigger("change");
2213 $(".entropy").val("123456").trigger("input");
2214 });
2215 // check the entropy is shown to be the correct type
2216 waitForGenerate(function() {
2217 var entropyText = page.evaluate(function() {
2218 return $(".entropy-container").text();
2219 });
2220 if (entropyText.indexOf("dice") == -1) {
2221 console.log("Dice entropy is not detected and presented to user");
2222 fail();
2223 }
2224 next();
2225 });
2226});
2227},
2228
2229// Base 10 entropy can be entered
2230function() {
2231page.open(url, function(status) {
2232 // use entropy
2233 page.evaluate(function() {
2234 $(".use-entropy").prop("checked", true).trigger("change");
2235 $(".entropy").val("789").trigger("input");
2236 });
2237 // check the entropy is shown to be the correct type
2238 waitForGenerate(function() {
2239 var entropyText = page.evaluate(function() {
2240 return $(".entropy-container").text();
2241 });
2242 if (entropyText.indexOf("base 10") == -1) {
2243 console.log("Base 10 entropy is not detected and presented to user");
2244 fail();
2245 }
2246 next();
2247 });
2248});
2249},
2250
2251// Hexadecimal entropy can be entered
2252function() {
2253page.open(url, function(status) {
2254 // use entropy
2255 page.evaluate(function() {
2256 $(".use-entropy").prop("checked", true).trigger("change");
2257 $(".entropy").val("abcdef").trigger("input");
2258 });
2259 // check the entropy is shown to be the correct type
2260 waitForGenerate(function() {
2261 var entropyText = page.evaluate(function() {
2262 return $(".entropy-container").text();
2263 });
2264 if (entropyText.indexOf("hexadecimal") == -1) {
2265 console.log("Hexadecimal entropy is not detected and presented to user");
2266 fail();
2267 }
2268 next();
2269 });
2270});
2271},
2272
2273// Dice entropy value is shown as the converted base 6 value
2274function() {
2275page.open(url, function(status) {
2276 // use entropy
2277 page.evaluate(function() {
2278 $(".use-entropy").prop("checked", true).trigger("change");
2279 $(".entropy").val("123456").trigger("input");
2280 });
2281 // check the entropy is shown as base 6, not as the original dice value
2282 waitForGenerate(function() {
2283 var entropyText = page.evaluate(function() {
2284 return $(".entropy-container").text();
2285 });
2286 if (entropyText.indexOf("012345") == -1) {
2287 console.log("Dice entropy is not shown to user as base 6 value");
2288 fail();
2289 }
2290 if (entropyText.indexOf("123456") > -1) {
2291 console.log("Dice entropy value is shown instead of true base 6 value");
2292 fail();
2293 }
2294 next();
2295 });
2296});
2297},
2298
2299// The number of bits of entropy accumulated is shown
2300function() {
2301page.open(url, function(status) {
2302 var tests = {
2303 "0000 0000 0000 0000 0000": "20",
2304 "0": "1",
2305 "0000": "4",
2306 "6": "3",
2307 "7": "3",
2308 "8": "4",
2309 "F": "4",
2310 "29": "5",
2311 "0A": "8",
2312 "1A": "8", // hex is always multiple of 4 bits of entropy
2313 "2A": "8",
2314 "4A": "8",
2315 "8A": "8",
2316 "FA": "8",
2317 "000A": "16",
2318 "2220": "10",
2319 "2221": "9", // uses dice, so entropy is actually 1110
2320 "2227": "12",
2321 "222F": "16",
2322 "FFFF": "16",
2323 }
2324 // Arrange tests in array so last one can be easily detected
2325 var entropys = [];
2326 var results = [];
2327 for (var entropy in tests) {
2328 entropys.push(entropy);
2329 results.push(tests[entropy]);
2330 }
2331 // use entropy
2332 page.evaluate(function(e) {
2333 $(".use-entropy").prop("checked", true).trigger("change");
2334 });
2335 // Run each test
2336 var nextTest = function runNextTest(i) {
2337 var entropy = entropys[i];
2338 var expected = results[i];
2339 // set entropy
2340 page.evaluate(function(e) {
2341 $(".addresses").empty(); // bit of a hack, but needed for waitForGenerate
2342 $(".entropy").val(e).trigger("input");
2343 }, entropy);
2344 // check the number of bits of entropy is shown
2345 waitForGenerate(function() {
2346 var entropyText = page.evaluate(function() {
2347 return $(".entropy-container").text();
2348 });
2349 if (entropyText.indexOf("Have " + expected + " bits of entropy") == -1) {
2350 console.log("Accumulated entropy is not shown correctly for " + entropy);
2351 fail();
2352 }
2353 var isLastTest = i == results.length - 1;
2354 if (isLastTest) {
2355 next();
2356 }
2357 else {
2358 runNextTest(i+1);
2359 }
2360 });
2361 }
2362 nextTest(0);
2363});
2364},
2365
2366// The number of bits of entropy to reach the next mnemonic strength is shown
2367function() {
2368page.open(url, function(status) {
2369 // use entropy
2370 page.evaluate(function() {
2371 $(".use-entropy").prop("checked", true).trigger("change");
2372 $(".entropy").val("7654321").trigger("input");
2373 });
2374 // check the amount of additional entropy required is shown
2375 waitForGenerate(function() {
2376 var entropyText = page.evaluate(function() {
2377 return $(".entropy-container").text();
2378 });
2379 if (entropyText.indexOf("3 more base 10 chars required") == -1) {
2380 console.log("Additional entropy requirement is not shown");
2381 fail();
2382 }
2383 next();
2384 });
2385});
2386},
2387
2388// The next strength above 0-word mnemonics is considered extremely weak
2389// The next strength above 3-word mnemonics is considered very weak
2390// The next strength above 6-word mnemonics is considered weak
2391// The next strength above 9-word mnemonics is considered strong
2392// The next strength above 12-word mnemonics is considered very strong
2393// The next strength above 15-word mnemonics is considered extremely strong
2394function() {
2395page.open(url, function(status) {
2396 var tests = [
2397 {
2398 entropy: "A",
2399 words: 0,
2400 nextStrength: "an extremely weak",
2401 },
2402 {
2403 entropy: "AAAAAAAA",
2404 words: 3,
2405 nextStrength: "a very weak",
2406 },
2407 {
2408 entropy: "AAAAAAAA B",
2409 words: 3,
2410 nextStrength: "a very weak",
2411 },
2412 {
2413 entropy: "AAAAAAAA BBBBBBBB",
2414 words: 6,
2415 nextStrength: "a weak",
2416 },
2417 {
2418 entropy: "AAAAAAAA BBBBBBBB CCCCCCCC",
2419 words: 9,
2420 nextStrength: "a strong",
2421 },
2422 {
2423 entropy: "AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD",
2424 words: 12,
2425 nextStrength: "a very strong",
2426 },
2427 {
2428 entropy: "AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE",
2429 words: 15,
2430 nextStrength: "an extremely strong",
2431 }
2432 ];
2433 // use entropy
2434 page.evaluate(function() {
2435 $(".use-entropy").prop("checked", true).trigger("change");
2436 });
2437 var nextTest = function runNextTest(i) {
2438 test = tests[i];
2439 page.evaluate(function(e) {
2440 $(".addresses").empty();
2441 $(".entropy").val(e).trigger("input");
2442 }, test.entropy);
2443 waitForGenerate(function() {
2444 // check the strength of the current mnemonic
2445 var mnemonic = page.evaluate(function() {
2446 return $(".phrase").val();
2447 });
2448 if (test.words == 0) {
2449 if (mnemonic.length > 0) {
2450 console.log("Mnemonic length for " + test.nextStrength + " strength is not " + test.words);
2451 console.log("Mnemonic: " + mnemonic);
2452 fail();
2453 }
2454 }
2455 else {
2456 if (mnemonic.split(" ").length != test.words) {
2457 console.log("Mnemonic length for " + test.nextStrength + " strength is not " + test.words);
2458 console.log("Mnemonic: " + mnemonic);
2459 fail();
2460 }
2461 }
2462 // check the strength of the next mnemonic is shown
2463 var entropyText = page.evaluate(function() {
2464 return $(".entropy-container").text();
2465 });
2466 if (entropyText.indexOf("required to generate " + test.nextStrength + " mnemonic") == -1) {
2467 console.log("Strength indicator for " + test.nextStrength + " mnemonic is incorrect");
2468 fail();
2469 }
2470 var isLastTest = i == tests.length - 1;
2471 if (isLastTest) {
2472 next();
2473 }
2474 else {
2475 runNextTest(i+1);
2476 }
2477 });
2478 }
2479 nextTest(0);
2480});
2481},
2482
2483// Entropy is truncated from the right
2484function() {
2485page.open(url, function(status) {
2486 var expected = "abandon abandon ability";
2487 // use entropy
2488 page.evaluate(function() {
2489 $(".use-entropy").prop("checked", true).trigger("change");
2490 var entropy = "00000000 00000000 00000000 00000000";
2491 entropy += "11111111 11111111 11111111 1111"; // Missing last byte, only first 8 bytes are used
2492 $(".entropy").val(entropy).trigger("input");
2493 });
2494 // check the entropy is truncated from the right
2495 waitForGenerate(function() {
2496 var actual = page.evaluate(function() {
2497 return $(".phrase").val();
2498 });
2499 if (actual != expected) {
2500 console.log("Entropy is not truncated from the right");
2501 console.log("Expected: " + expected);
2502 console.log("Got: " + actual);
2503 fail();
2504 }
2505 next();
2506 });
2507});
2508},
2509
2510// Very large entropy results in very long mnemonics
2511function() {
2512page.open(url, function(status) {
2513 // use entropy
2514 page.evaluate(function() {
2515 $(".use-entropy").prop("checked", true).trigger("change");
2516 var entropy = "";
2517 // Generate a very long entropy string
2518 for (var i=0; i<33; i++) {
2519 entropy += "AAAAAAAA"; // 3 words * 33 iterations = 99 words
2520 }
2521 $(".entropy").val(entropy).trigger("input");
2522 });
2523 // check the mnemonic is very long
2524 waitForGenerate(function() {
2525 var wordCount = page.evaluate(function() {
2526 return $(".phrase").val().split(" ").length;
2527 });
2528 if (wordCount != 99) {
2529 console.log("Large entropy does not generate long mnemonic");
2530 console.log("Expected 99 words, got " + wordCount);
2531 fail();
2532 }
2533 next();
2534 });
2535});
2536},
2537
2538// Is compatible with bip32jp entropy
2539// https://bip32jp.github.io/english/index.html
2540// NOTES:
2541// Is incompatible with:
2542// base 6 with leading zeros
2543// base 6 wth 12 words / 53 chars
2544// base 20
2545function() {
2546page.open(url, function(status) {
2547 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";
2548 // use entropy
2549 page.evaluate(function() {
2550 $(".use-entropy").prop("checked", true).trigger("change");
2551 var entropy = "123450123450123450123450123450123450123450123450123450123450123450123450123450123450123450123450123";
2552 $(".entropy").val(entropy).trigger("input");
2553 });
2554 // check the mnemonic matches the expected value from bip32jp
2555 waitForGenerate(function() {
2556 var actual = page.evaluate(function() {
2557 return $(".phrase").val();
2558 });
2559 if (actual != expected) {
2560 console.log("Mnemonic does not match bip32jp for base 6 entropy");
2561 console.log("Expected: " + expected);
2562 console.log("Got: " + actual);
2563 fail();
2564 }
2565 next();
2566 });
2567});
2568},
2569
1963// If you wish to add more tests, do so here... 2570// If you wish to add more tests, do so here...
1964 2571
1965// Here is a blank test template 2572// Here is a blank test template