5108 lines
No EOL
366 KiB
HTML
5108 lines
No EOL
366 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<!--
|
|
Donation Address: 1NiNja1bUmhSoTXozBRBEtR8LeF9TGbZBN
|
|
|
|
Notice of Copyrights and Licenses:
|
|
***********************************
|
|
The bitaddress.org project, software and embedded resources are copyright bitaddress.org.
|
|
The bitaddress.org name and logo are not part of the open source license.
|
|
|
|
Portions of the all-in-one HTML document contain JavaScript codes that are the copyrights of others.
|
|
The individual copyrights are included throughout the document along with their licenses.
|
|
Included JavaScript libraries are separated with HTML script tags.
|
|
|
|
Summary of JavaScript functions with a redistributable license:
|
|
JavaScript function License
|
|
******************* ***************
|
|
Array.prototype.map Public Domain
|
|
window.Crypto BSD License
|
|
window.SecureRandom BSD License
|
|
window.EllipticCurve BSD License
|
|
window.BigInteger BSD License
|
|
window.QRCode MIT License
|
|
window.Bitcoin MIT License
|
|
|
|
The bitaddress.org software is available under The MIT License (MIT)
|
|
Copyright (c) 2011-2012 bitaddress.org
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
|
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject
|
|
to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
GitHub Repository: https://github.com/pointbiz/bitaddress.org
|
|
-->
|
|
|
|
<title>bitaddress.org</title>
|
|
<script type="text/javascript">
|
|
// Array.prototype.map function is in the public domain.
|
|
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
|
// Reference: http://es5.github.com/#x15.4.4.19
|
|
if (!Array.prototype.map) {
|
|
Array.prototype.map = function (callback, thisArg) {
|
|
var T, A, k;
|
|
if (this == null) {
|
|
throw new TypeError(" this is null or not defined");
|
|
}
|
|
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
|
|
var O = Object(this);
|
|
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
|
|
// 3. Let len be ToUint32(lenValue).
|
|
var len = O.length >>> 0;
|
|
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
|
// See: http://es5.github.com/#x9.11
|
|
if ({}.toString.call(callback) != "[object Function]") {
|
|
throw new TypeError(callback + " is not a function");
|
|
}
|
|
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
|
if (thisArg) {
|
|
T = thisArg;
|
|
}
|
|
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
|
|
// the standard built-in constructor with that name and len is the value of len.
|
|
A = new Array(len);
|
|
// 7. Let k be 0
|
|
k = 0;
|
|
// 8. Repeat, while k < len
|
|
while (k < len) {
|
|
var kValue, mappedValue;
|
|
// a. Let Pk be ToString(k).
|
|
// This is implicit for LHS operands of the in operator
|
|
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
|
|
// This step can be combined with c
|
|
// c. If kPresent is true, then
|
|
if (k in O) {
|
|
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
|
|
kValue = O[k];
|
|
// ii. Let mappedValue be the result of calling the Call internal method of callback
|
|
// with T as the this value and argument list containing kValue, k, and O.
|
|
mappedValue = callback.call(T, kValue, k, O);
|
|
// iii. Call the DefineOwnProperty internal method of A with arguments
|
|
// Pk, Property Descriptor {Value: mappedValue, Writable: true, Enumerable: true, Configurable: true},
|
|
// and false.
|
|
// In browsers that support Object.defineProperty, use the following:
|
|
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
|
|
// For best browser support, use the following:
|
|
A[k] = mappedValue;
|
|
}
|
|
// d. Increase k by 1.
|
|
k++;
|
|
}
|
|
// 9. return A
|
|
return A;
|
|
};
|
|
}
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
/*!
|
|
* Crypto-JS v2.0.0
|
|
* http://code.google.com/p/crypto-js/
|
|
* Copyright (c) 2009, Jeff Mott. All rights reserved.
|
|
* http://code.google.com/p/crypto-js/wiki/License
|
|
*/
|
|
(function () {
|
|
|
|
var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
// Global Crypto object
|
|
var Crypto = window.Crypto = {};
|
|
|
|
// Crypto utilities
|
|
var util = Crypto.util = {
|
|
|
|
// Bit-wise rotate left
|
|
rotl: function (n, b) {
|
|
return (n << b) | (n >>> (32 - b));
|
|
},
|
|
|
|
// Bit-wise rotate right
|
|
rotr: function (n, b) {
|
|
return (n << (32 - b)) | (n >>> b);
|
|
},
|
|
|
|
// Swap big-endian to little-endian and vice versa
|
|
endian: function (n) {
|
|
|
|
// If number given, swap endian
|
|
if (n.constructor == Number) {
|
|
return util.rotl(n, 8) & 0x00FF00FF |
|
|
util.rotl(n, 24) & 0xFF00FF00;
|
|
}
|
|
|
|
// Else, assume array and swap all items
|
|
for (var i = 0; i < n.length; i++)
|
|
n[i] = util.endian(n[i]);
|
|
return n;
|
|
|
|
},
|
|
|
|
// Generate an array of any length of random bytes
|
|
randomBytes: function (n) {
|
|
for (var bytes = []; n > 0; n--)
|
|
bytes.push(Math.floor(Math.random() * 256));
|
|
return bytes;
|
|
},
|
|
|
|
// Convert a byte array to big-endian 32-bit words
|
|
bytesToWords: function (bytes) {
|
|
for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
|
|
words[b >>> 5] |= bytes[i] << (24 - b % 32);
|
|
return words;
|
|
},
|
|
|
|
// Convert big-endian 32-bit words to a byte array
|
|
wordsToBytes: function (words) {
|
|
for (var bytes = [], b = 0; b < words.length * 32; b += 8)
|
|
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
|
|
return bytes;
|
|
},
|
|
|
|
// Convert a byte array to a hex string
|
|
bytesToHex: function (bytes) {
|
|
for (var hex = [], i = 0; i < bytes.length; i++) {
|
|
hex.push((bytes[i] >>> 4).toString(16));
|
|
hex.push((bytes[i] & 0xF).toString(16));
|
|
}
|
|
return hex.join("");
|
|
},
|
|
|
|
// Convert a hex string to a byte array
|
|
hexToBytes: function (hex) {
|
|
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
|
bytes.push(parseInt(hex.substr(c, 2), 16));
|
|
return bytes;
|
|
},
|
|
|
|
// Convert a byte array to a base-64 string
|
|
bytesToBase64: function (bytes) {
|
|
|
|
// Use browser-native function if it exists
|
|
if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes));
|
|
|
|
for (var base64 = [], i = 0; i < bytes.length; i += 3) {
|
|
var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
|
|
for (var j = 0; j < 4; j++) {
|
|
if (i * 8 + j * 6 <= bytes.length * 8)
|
|
base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
|
|
else base64.push("=");
|
|
}
|
|
}
|
|
|
|
return base64.join("");
|
|
|
|
},
|
|
|
|
// Convert a base-64 string to a byte array
|
|
base64ToBytes: function (base64) {
|
|
|
|
// Use browser-native function if it exists
|
|
if (typeof atob == "function") return Binary.stringToBytes(atob(base64));
|
|
|
|
// Remove non-base-64 characters
|
|
base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
|
|
|
|
for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
|
|
if (imod4 == 0) continue;
|
|
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
|
|
(base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
|
|
}
|
|
|
|
return bytes;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Crypto mode namespace
|
|
Crypto.mode = {};
|
|
|
|
// Crypto character encodings
|
|
var charenc = Crypto.charenc = {};
|
|
|
|
// UTF-8 encoding
|
|
var UTF8 = charenc.UTF8 = {
|
|
|
|
// Convert a string to a byte array
|
|
stringToBytes: function (str) {
|
|
return Binary.stringToBytes(unescape(encodeURIComponent(str)));
|
|
},
|
|
|
|
// Convert a byte array to a string
|
|
bytesToString: function (bytes) {
|
|
return decodeURIComponent(escape(Binary.bytesToString(bytes)));
|
|
}
|
|
|
|
};
|
|
|
|
// Binary encoding
|
|
var Binary = charenc.Binary = {
|
|
|
|
// Convert a string to a byte array
|
|
stringToBytes: function (str) {
|
|
for (var bytes = [], i = 0; i < str.length; i++)
|
|
bytes.push(str.charCodeAt(i));
|
|
return bytes;
|
|
},
|
|
|
|
// Convert a byte array to a string
|
|
bytesToString: function (bytes) {
|
|
for (var str = [], i = 0; i < bytes.length; i++)
|
|
str.push(String.fromCharCode(bytes[i]));
|
|
return str.join("");
|
|
}
|
|
|
|
};
|
|
|
|
})();
|
|
|
|
|
|
|
|
/*!
|
|
* Crypto-JS v2.0.0
|
|
* http://code.google.com/p/crypto-js/
|
|
* Copyright (c) 2009, Jeff Mott. All rights reserved.
|
|
* http://code.google.com/p/crypto-js/wiki/License
|
|
*/
|
|
(function () {
|
|
|
|
// Shortcuts
|
|
var C = Crypto,
|
|
util = C.util,
|
|
charenc = C.charenc,
|
|
UTF8 = charenc.UTF8,
|
|
Binary = charenc.Binary;
|
|
|
|
// Constants
|
|
var K = [0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
|
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
|
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
|
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
|
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
|
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
|
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
|
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
|
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
|
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
|
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
|
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
|
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
|
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
|
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
|
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2];
|
|
|
|
// Public API
|
|
var SHA256 = C.SHA256 = function (message, options) {
|
|
var digestbytes = util.wordsToBytes(SHA256._sha256(message));
|
|
return options && options.asBytes ? digestbytes :
|
|
options && options.asString ? Binary.bytesToString(digestbytes) :
|
|
util.bytesToHex(digestbytes);
|
|
};
|
|
|
|
// The core
|
|
SHA256._sha256 = function (message) {
|
|
|
|
// Convert to byte array
|
|
if (message.constructor == String) message = UTF8.stringToBytes(message);
|
|
/* else, assume byte array already */
|
|
|
|
var m = util.bytesToWords(message),
|
|
l = message.length * 8,
|
|
H = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
|
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19],
|
|
w = [],
|
|
a, b, c, d, e, f, g, h, i, j,
|
|
t1, t2;
|
|
|
|
// Padding
|
|
m[l >> 5] |= 0x80 << (24 - l % 32);
|
|
m[((l + 64 >> 9) << 4) + 15] = l;
|
|
|
|
for (var i = 0; i < m.length; i += 16) {
|
|
|
|
a = H[0];
|
|
b = H[1];
|
|
c = H[2];
|
|
d = H[3];
|
|
e = H[4];
|
|
f = H[5];
|
|
g = H[6];
|
|
h = H[7];
|
|
|
|
for (var j = 0; j < 64; j++) {
|
|
|
|
if (j < 16) w[j] = m[j + i];
|
|
else {
|
|
|
|
var gamma0x = w[j - 15],
|
|
gamma1x = w[j - 2],
|
|
gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
|
|
((gamma0x << 14) | (gamma0x >>> 18)) ^
|
|
(gamma0x >>> 3),
|
|
gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
|
|
((gamma1x << 13) | (gamma1x >>> 19)) ^
|
|
(gamma1x >>> 10);
|
|
|
|
w[j] = gamma0 + (w[j - 7] >>> 0) +
|
|
gamma1 + (w[j - 16] >>> 0);
|
|
|
|
}
|
|
|
|
var ch = e & f ^ ~e & g,
|
|
maj = a & b ^ a & c ^ b & c,
|
|
sigma0 = ((a << 30) | (a >>> 2)) ^
|
|
((a << 19) | (a >>> 13)) ^
|
|
((a << 10) | (a >>> 22)),
|
|
sigma1 = ((e << 26) | (e >>> 6)) ^
|
|
((e << 21) | (e >>> 11)) ^
|
|
((e << 7) | (e >>> 25));
|
|
|
|
|
|
t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0);
|
|
t2 = sigma0 + maj;
|
|
|
|
h = g;
|
|
g = f;
|
|
f = e;
|
|
e = d + t1;
|
|
d = c;
|
|
c = b;
|
|
b = a;
|
|
a = t1 + t2;
|
|
|
|
}
|
|
|
|
H[0] += a;
|
|
H[1] += b;
|
|
H[2] += c;
|
|
H[3] += d;
|
|
H[4] += e;
|
|
H[5] += f;
|
|
H[6] += g;
|
|
H[7] += h;
|
|
|
|
}
|
|
|
|
return H;
|
|
|
|
};
|
|
|
|
// Package private blocksize
|
|
SHA256._blocksize = 16;
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
* Crypto-JS v2.0.0
|
|
* http://code.google.com/p/crypto-js/
|
|
* Copyright (c) 2009, Jeff Mott. All rights reserved.
|
|
* http://code.google.com/p/crypto-js/wiki/License
|
|
*
|
|
* A JavaScript implementation of the RIPEMD-160 Algorithm
|
|
* Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
|
|
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
|
* Distributed under the BSD License
|
|
* See http://pajhome.org.uk/crypt/md5 for details.
|
|
* Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
|
|
* Ported to Crypto-JS by Stefan Thomas.
|
|
*/
|
|
|
|
(function () {
|
|
// Shortcuts
|
|
var C = Crypto,
|
|
util = C.util,
|
|
charenc = C.charenc,
|
|
UTF8 = charenc.UTF8,
|
|
Binary = charenc.Binary;
|
|
|
|
// Convert a byte array to little-endian 32-bit words
|
|
util.bytesToLWords = function (bytes) {
|
|
|
|
var output = Array(bytes.length >> 2);
|
|
for (var i = 0; i < output.length; i++)
|
|
output[i] = 0;
|
|
for (var i = 0; i < bytes.length * 8; i += 8)
|
|
output[i >> 5] |= (bytes[i / 8] & 0xFF) << (i % 32);
|
|
return output;
|
|
};
|
|
|
|
// Convert little-endian 32-bit words to a byte array
|
|
util.lWordsToBytes = function (words) {
|
|
var output = [];
|
|
for (var i = 0; i < words.length * 32; i += 8)
|
|
output.push((words[i >> 5] >>> (i % 32)) & 0xff);
|
|
return output;
|
|
};
|
|
|
|
// Public API
|
|
var RIPEMD160 = C.RIPEMD160 = function (message, options) {
|
|
var digestbytes = util.lWordsToBytes(RIPEMD160._rmd160(message));
|
|
return options && options.asBytes ? digestbytes :
|
|
options && options.asString ? Binary.bytesToString(digestbytes) :
|
|
util.bytesToHex(digestbytes);
|
|
};
|
|
|
|
// The core
|
|
RIPEMD160._rmd160 = function (message) {
|
|
// Convert to byte array
|
|
if (message.constructor == String) message = UTF8.stringToBytes(message);
|
|
|
|
var x = util.bytesToLWords(message),
|
|
len = message.length * 8;
|
|
|
|
/* append padding */
|
|
x[len >> 5] |= 0x80 << (len % 32);
|
|
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
|
|
|
var h0 = 0x67452301;
|
|
var h1 = 0xefcdab89;
|
|
var h2 = 0x98badcfe;
|
|
var h3 = 0x10325476;
|
|
var h4 = 0xc3d2e1f0;
|
|
|
|
for (var i = 0; i < x.length; i += 16) {
|
|
var T;
|
|
var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4;
|
|
var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4;
|
|
for (var j = 0; j <= 79; ++j) {
|
|
T = safe_add(A1, rmd160_f(j, B1, C1, D1));
|
|
T = safe_add(T, x[i + rmd160_r1[j]]);
|
|
T = safe_add(T, rmd160_K1(j));
|
|
T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
|
|
A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T;
|
|
T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
|
|
T = safe_add(T, x[i + rmd160_r2[j]]);
|
|
T = safe_add(T, rmd160_K2(j));
|
|
T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
|
|
A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T;
|
|
}
|
|
T = safe_add(h1, safe_add(C1, D2));
|
|
h1 = safe_add(h2, safe_add(D1, E2));
|
|
h2 = safe_add(h3, safe_add(E1, A2));
|
|
h3 = safe_add(h4, safe_add(A1, B2));
|
|
h4 = safe_add(h0, safe_add(B1, C2));
|
|
h0 = T;
|
|
}
|
|
return [h0, h1, h2, h3, h4];
|
|
}
|
|
|
|
function rmd160_f(j, x, y, z) {
|
|
return (0 <= j && j <= 15) ? (x ^ y ^ z) :
|
|
(16 <= j && j <= 31) ? (x & y) | (~x & z) :
|
|
(32 <= j && j <= 47) ? (x | ~y) ^ z :
|
|
(48 <= j && j <= 63) ? (x & z) | (y & ~z) :
|
|
(64 <= j && j <= 79) ? x ^ (y | ~z) :
|
|
"rmd160_f: j out of range";
|
|
}
|
|
function rmd160_K1(j) {
|
|
return (0 <= j && j <= 15) ? 0x00000000 :
|
|
(16 <= j && j <= 31) ? 0x5a827999 :
|
|
(32 <= j && j <= 47) ? 0x6ed9eba1 :
|
|
(48 <= j && j <= 63) ? 0x8f1bbcdc :
|
|
(64 <= j && j <= 79) ? 0xa953fd4e :
|
|
"rmd160_K1: j out of range";
|
|
}
|
|
function rmd160_K2(j) {
|
|
return (0 <= j && j <= 15) ? 0x50a28be6 :
|
|
(16 <= j && j <= 31) ? 0x5c4dd124 :
|
|
(32 <= j && j <= 47) ? 0x6d703ef3 :
|
|
(48 <= j && j <= 63) ? 0x7a6d76e9 :
|
|
(64 <= j && j <= 79) ? 0x00000000 :
|
|
"rmd160_K2: j out of range";
|
|
}
|
|
var rmd160_r1 = [
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
|
|
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
|
|
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
|
|
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
|
];
|
|
var rmd160_r2 = [
|
|
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
|
|
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
|
|
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
|
|
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
|
|
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
|
];
|
|
var rmd160_s1 = [
|
|
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
|
|
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
|
|
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
|
|
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
|
|
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
|
];
|
|
var rmd160_s2 = [
|
|
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
|
|
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
|
|
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
|
|
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
|
|
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
|
];
|
|
|
|
/*
|
|
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
|
* to work around bugs in some JS interpreters.
|
|
*/
|
|
function safe_add(x, y) {
|
|
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
|
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
|
return (msw << 16) | (lsw & 0xFFFF);
|
|
}
|
|
|
|
/*
|
|
* Bitwise rotate a 32-bit number to the left.
|
|
*/
|
|
function bit_rol(num, cnt) {
|
|
return (num << cnt) | (num >>> (32 - cnt));
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
/*!
|
|
* Random number generator with ArcFour PRNG
|
|
*
|
|
* NOTE: For best results, put code like
|
|
* <body onclick='SecureRandom.seedTime();' onkeypress='SecureRandom.seedTime();'>
|
|
* in your main HTML document.
|
|
*
|
|
* Copyright Tom Wu, bitaddress.org BSD License.
|
|
* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
|
|
*/
|
|
(function () {
|
|
|
|
// Constructor function of Global SecureRandom object
|
|
var sr = window.SecureRandom = function () { };
|
|
|
|
// Properties
|
|
sr.state;
|
|
sr.pool;
|
|
sr.pptr;
|
|
|
|
// Pool size must be a multiple of 4 and greater than 32.
|
|
// An array of bytes the size of the pool will be passed to init()
|
|
sr.poolSize = 256;
|
|
|
|
|
|
// --- object methods ---
|
|
|
|
// public method
|
|
// ba: byte array
|
|
sr.prototype.nextBytes = function (ba) {
|
|
var i;
|
|
for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte();
|
|
};
|
|
|
|
|
|
// --- static methods ---
|
|
|
|
// Mix in the current time (w/milliseconds) into the pool
|
|
// NOTE: this method should be called from body click/keypress event handlers to increase entropy
|
|
sr.seedTime = function () {
|
|
sr.seedInt(new Date().getTime());
|
|
}
|
|
|
|
sr.getByte = function () {
|
|
if (sr.state == null) {
|
|
sr.seedTime();
|
|
sr.state = sr.ArcFour(); // Plug in your RNG constructor here
|
|
sr.state.init(sr.pool);
|
|
for (sr.pptr = 0; sr.pptr < sr.pool.length; ++sr.pptr)
|
|
sr.pool[sr.pptr] = 0;
|
|
sr.pptr = 0;
|
|
}
|
|
// TODO: allow reseeding after first request
|
|
return sr.state.next();
|
|
}
|
|
|
|
// Mix in a 32-bit integer into the pool
|
|
sr.seedInt = function (x) {
|
|
sr.pool[sr.pptr++] ^= x & 255;
|
|
sr.pool[sr.pptr++] ^= (x >> 8) & 255;
|
|
sr.pool[sr.pptr++] ^= (x >> 16) & 255;
|
|
sr.pool[sr.pptr++] ^= (x >> 24) & 255;
|
|
if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize;
|
|
}
|
|
|
|
|
|
// Arcfour is a PRNG
|
|
sr.ArcFour = function () {
|
|
function Arcfour() {
|
|
this.i = 0;
|
|
this.j = 0;
|
|
this.S = new Array();
|
|
}
|
|
|
|
// Initialize arcfour context from key, an array of ints, each from [0..255]
|
|
function ARC4init(key) {
|
|
var i, j, t;
|
|
for (i = 0; i < 256; ++i)
|
|
this.S[i] = i;
|
|
j = 0;
|
|
for (i = 0; i < 256; ++i) {
|
|
j = (j + this.S[i] + key[i % key.length]) & 255;
|
|
t = this.S[i];
|
|
this.S[i] = this.S[j];
|
|
this.S[j] = t;
|
|
}
|
|
this.i = 0;
|
|
this.j = 0;
|
|
}
|
|
|
|
function ARC4next() {
|
|
var t;
|
|
this.i = (this.i + 1) & 255;
|
|
this.j = (this.j + this.S[this.i]) & 255;
|
|
t = this.S[this.i];
|
|
this.S[this.i] = this.S[this.j];
|
|
this.S[this.j] = t;
|
|
return this.S[(t + this.S[this.i]) & 255];
|
|
}
|
|
|
|
Arcfour.prototype.init = ARC4init;
|
|
Arcfour.prototype.next = ARC4next;
|
|
|
|
return new Arcfour();
|
|
};
|
|
|
|
|
|
// Initialize the pool with junk if needed.
|
|
if (sr.pool == null) {
|
|
sr.pool = new Array();
|
|
sr.pptr = 0;
|
|
var t;
|
|
if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
|
|
// Extract entropy (256 bits) from NS4 RNG if available
|
|
var z = window.crypto.random(32);
|
|
for (t = 0; t < z.length; ++t)
|
|
sr.pool[sr.pptr++] = z.charCodeAt(t) & 255;
|
|
}
|
|
while (sr.pptr < sr.poolSize) { // extract some randomness from Math.random()
|
|
t = Math.floor(65536 * Math.random());
|
|
sr.pool[sr.pptr++] = t >>> 8;
|
|
sr.pool[sr.pptr++] = t & 255;
|
|
}
|
|
sr.pptr = 0;
|
|
sr.seedTime();
|
|
// entropy
|
|
sr.seedInt(window.screenX);
|
|
sr.seedInt(window.screenY);
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
/*!
|
|
* Basic Javascript Elliptic Curve implementation
|
|
* Ported loosely from BouncyCastle's Java EC code
|
|
* Only Fp curves implemented for now
|
|
*
|
|
* Copyright Tom Wu, bitaddress.org BSD License.
|
|
* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
|
|
*/
|
|
(function () {
|
|
|
|
// Constructor function of Global EllipticCurve object
|
|
var ec = window.EllipticCurve = function () { };
|
|
|
|
|
|
// ----------------
|
|
// ECFieldElementFp constructor
|
|
ec.FieldElementFp = function (q, x) {
|
|
this.x = x;
|
|
// TODO if(x.compareTo(q) >= 0) error
|
|
this.q = q;
|
|
}
|
|
|
|
ec.FieldElementFp.prototype.equals = function (other) {
|
|
if (other == this) return true;
|
|
return (this.q.equals(other.q) && this.x.equals(other.x));
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.toBigInteger = function () {
|
|
return this.x;
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.negate = function () {
|
|
return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q));
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.add = function (b) {
|
|
return new ec.FieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q));
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.subtract = function (b) {
|
|
return new ec.FieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q));
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.multiply = function (b) {
|
|
return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q));
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.square = function () {
|
|
return new ec.FieldElementFp(this.q, this.x.square().mod(this.q));
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.divide = function (b) {
|
|
return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q));
|
|
};
|
|
|
|
ec.FieldElementFp.prototype.getByteLength = function () {
|
|
return Math.floor((this.toBigInteger().bitLength() + 7) / 8);
|
|
};
|
|
|
|
// ----------------
|
|
// ECPointFp constructor
|
|
ec.PointFp = function (curve, x, y, z) {
|
|
this.curve = curve;
|
|
this.x = x;
|
|
this.y = y;
|
|
// Projective coordinates: either zinv == null or z * zinv == 1
|
|
// z and zinv are just BigIntegers, not fieldElements
|
|
if (z == null) {
|
|
this.z = BigInteger.ONE;
|
|
}
|
|
else {
|
|
this.z = z;
|
|
}
|
|
this.zinv = null;
|
|
//TODO: compression flag
|
|
};
|
|
|
|
ec.PointFp.prototype.getX = function () {
|
|
if (this.zinv == null) {
|
|
this.zinv = this.z.modInverse(this.curve.q);
|
|
}
|
|
return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));
|
|
};
|
|
|
|
ec.PointFp.prototype.getY = function () {
|
|
if (this.zinv == null) {
|
|
this.zinv = this.z.modInverse(this.curve.q);
|
|
}
|
|
return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));
|
|
};
|
|
|
|
ec.PointFp.prototype.equals = function (other) {
|
|
if (other == this) return true;
|
|
if (this.isInfinity()) return other.isInfinity();
|
|
if (other.isInfinity()) return this.isInfinity();
|
|
var u, v;
|
|
// u = Y2 * Z1 - Y1 * Z2
|
|
u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q);
|
|
if (!u.equals(BigInteger.ZERO)) return false;
|
|
// v = X2 * Z1 - X1 * Z2
|
|
v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q);
|
|
return v.equals(BigInteger.ZERO);
|
|
};
|
|
|
|
ec.PointFp.prototype.isInfinity = function () {
|
|
if ((this.x == null) && (this.y == null)) return true;
|
|
return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);
|
|
};
|
|
|
|
ec.PointFp.prototype.negate = function () {
|
|
return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z);
|
|
};
|
|
|
|
ec.PointFp.prototype.add = function (b) {
|
|
if (this.isInfinity()) return b;
|
|
if (b.isInfinity()) return this;
|
|
|
|
// u = Y2 * Z1 - Y1 * Z2
|
|
var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q);
|
|
// v = X2 * Z1 - X1 * Z2
|
|
var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q);
|
|
|
|
|
|
if (BigInteger.ZERO.equals(v)) {
|
|
if (BigInteger.ZERO.equals(u)) {
|
|
return this.twice(); // this == b, so double
|
|
}
|
|
return this.curve.getInfinity(); // this = -b, so infinity
|
|
}
|
|
|
|
var THREE = new BigInteger("3");
|
|
var x1 = this.x.toBigInteger();
|
|
var y1 = this.y.toBigInteger();
|
|
var x2 = b.x.toBigInteger();
|
|
var y2 = b.y.toBigInteger();
|
|
|
|
var v2 = v.square();
|
|
var v3 = v2.multiply(v);
|
|
var x1v2 = x1.multiply(v2);
|
|
var zu2 = u.square().multiply(this.z);
|
|
|
|
// x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)
|
|
var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q);
|
|
// y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3
|
|
var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q);
|
|
// z3 = v^3 * z1 * z2
|
|
var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q);
|
|
|
|
return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
|
|
};
|
|
|
|
ec.PointFp.prototype.twice = function () {
|
|
if (this.isInfinity()) return this;
|
|
if (this.y.toBigInteger().signum() == 0) return this.curve.getInfinity();
|
|
|
|
// TODO: optimized handling of constants
|
|
var THREE = new BigInteger("3");
|
|
var x1 = this.x.toBigInteger();
|
|
var y1 = this.y.toBigInteger();
|
|
|
|
var y1z1 = y1.multiply(this.z);
|
|
var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q);
|
|
var a = this.curve.a.toBigInteger();
|
|
|
|
// w = 3 * x1^2 + a * z1^2
|
|
var w = x1.square().multiply(THREE);
|
|
if (!BigInteger.ZERO.equals(a)) {
|
|
w = w.add(this.z.square().multiply(a));
|
|
}
|
|
w = w.mod(this.curve.q);
|
|
// x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)
|
|
var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q);
|
|
// y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3
|
|
var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q);
|
|
// z3 = 8 * (y1 * z1)^3
|
|
var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q);
|
|
|
|
return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
|
|
};
|
|
|
|
// Simple NAF (Non-Adjacent Form) multiplication algorithm
|
|
// TODO: modularize the multiplication algorithm
|
|
ec.PointFp.prototype.multiply = function (k) {
|
|
if (this.isInfinity()) return this;
|
|
if (k.signum() == 0) return this.curve.getInfinity();
|
|
|
|
var e = k;
|
|
var h = e.multiply(new BigInteger("3"));
|
|
|
|
var neg = this.negate();
|
|
var R = this;
|
|
|
|
var i;
|
|
for (i = h.bitLength() - 2; i > 0; --i) {
|
|
R = R.twice();
|
|
|
|
var hBit = h.testBit(i);
|
|
var eBit = e.testBit(i);
|
|
|
|
if (hBit != eBit) {
|
|
R = R.add(hBit ? this : neg);
|
|
}
|
|
}
|
|
|
|
return R;
|
|
};
|
|
|
|
// Compute this*j + x*k (simultaneous multiplication)
|
|
ec.PointFp.prototype.multiplyTwo = function (j, x, k) {
|
|
var i;
|
|
if (j.bitLength() > k.bitLength())
|
|
i = j.bitLength() - 1;
|
|
else
|
|
i = k.bitLength() - 1;
|
|
|
|
var R = this.curve.getInfinity();
|
|
var both = this.add(x);
|
|
while (i >= 0) {
|
|
R = R.twice();
|
|
if (j.testBit(i)) {
|
|
if (k.testBit(i)) {
|
|
R = R.add(both);
|
|
}
|
|
else {
|
|
R = R.add(this);
|
|
}
|
|
}
|
|
else {
|
|
if (k.testBit(i)) {
|
|
R = R.add(x);
|
|
}
|
|
}
|
|
--i;
|
|
}
|
|
|
|
return R;
|
|
};
|
|
|
|
// patched by bitaddress.org and Casascius for use with Bitcoin.ECKey
|
|
// patched by coretechs to support compressed public keys
|
|
ec.PointFp.prototype.getEncoded = function (compressed) {
|
|
var x = this.getX().toBigInteger();
|
|
var y = this.getY().toBigInteger();
|
|
var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol.
|
|
var enc = ec.integerToBytes(x, len);
|
|
|
|
// when compressed prepend byte depending if y point is even or odd
|
|
if (compressed) {
|
|
if (y.isEven()) {
|
|
enc.unshift(0x02);
|
|
}
|
|
else {
|
|
enc.unshift(0x03);
|
|
}
|
|
}
|
|
else {
|
|
enc.unshift(0x04);
|
|
enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point
|
|
}
|
|
return enc;
|
|
};
|
|
|
|
ec.PointFp.decodeFrom = function (curve, enc) {
|
|
var type = enc[0];
|
|
var dataLen = enc.length - 1;
|
|
|
|
// Extract x and y as byte arrays
|
|
var xBa = enc.slice(1, 1 + dataLen / 2);
|
|
var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen);
|
|
|
|
// Prepend zero byte to prevent interpretation as negative integer
|
|
xBa.unshift(0);
|
|
yBa.unshift(0);
|
|
|
|
// Convert to BigIntegers
|
|
var x = new BigInteger(xBa);
|
|
var y = new BigInteger(yBa);
|
|
|
|
// Return point
|
|
return new ec.PointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));
|
|
};
|
|
|
|
ec.PointFp.prototype.add2D = function (b) {
|
|
if (this.isInfinity()) return b;
|
|
if (b.isInfinity()) return this;
|
|
|
|
if (this.x.equals(b.x)) {
|
|
if (this.y.equals(b.y)) {
|
|
// this = b, i.e. this must be doubled
|
|
return this.twice();
|
|
}
|
|
// this = -b, i.e. the result is the point at infinity
|
|
return this.curve.getInfinity();
|
|
}
|
|
|
|
var x_x = b.x.subtract(this.x);
|
|
var y_y = b.y.subtract(this.y);
|
|
var gamma = y_y.divide(x_x);
|
|
|
|
var x3 = gamma.square().subtract(this.x).subtract(b.x);
|
|
var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);
|
|
|
|
return new ec.PointFp(this.curve, x3, y3);
|
|
};
|
|
|
|
ec.PointFp.prototype.twice2D = function () {
|
|
if (this.isInfinity()) return this;
|
|
if (this.y.toBigInteger().signum() == 0) {
|
|
// if y1 == 0, then (x1, y1) == (x1, -y1)
|
|
// and hence this = -this and thus 2(x1, y1) == infinity
|
|
return this.curve.getInfinity();
|
|
}
|
|
|
|
var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2));
|
|
var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3));
|
|
var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO));
|
|
|
|
var x3 = gamma.square().subtract(this.x.multiply(TWO));
|
|
var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);
|
|
|
|
return new ec.PointFp(this.curve, x3, y3);
|
|
};
|
|
|
|
ec.PointFp.prototype.multiply2D = function (k) {
|
|
if (this.isInfinity()) return this;
|
|
if (k.signum() == 0) return this.curve.getInfinity();
|
|
|
|
var e = k;
|
|
var h = e.multiply(new BigInteger("3"));
|
|
|
|
var neg = this.negate();
|
|
var R = this;
|
|
|
|
var i;
|
|
for (i = h.bitLength() - 2; i > 0; --i) {
|
|
R = R.twice();
|
|
|
|
var hBit = h.testBit(i);
|
|
var eBit = e.testBit(i);
|
|
|
|
if (hBit != eBit) {
|
|
R = R.add2D(hBit ? this : neg);
|
|
}
|
|
}
|
|
|
|
return R;
|
|
};
|
|
|
|
ec.PointFp.prototype.isOnCurve = function () {
|
|
var x = this.getX().toBigInteger();
|
|
var y = this.getY().toBigInteger();
|
|
var a = this.curve.getA().toBigInteger();
|
|
var b = this.curve.getB().toBigInteger();
|
|
var n = this.curve.getQ();
|
|
var lhs = y.multiply(y).mod(n);
|
|
var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n);
|
|
return lhs.equals(rhs);
|
|
};
|
|
|
|
ec.PointFp.prototype.validate = function () {
|
|
var n = this.curve.getQ();
|
|
|
|
// Check Q != O
|
|
if (this.isInfinity()) {
|
|
throw new Error("Point is at infinity.");
|
|
}
|
|
|
|
// Check coordinate bounds
|
|
var x = this.getX().toBigInteger();
|
|
var y = this.getY().toBigInteger();
|
|
if (x.compareTo(BigInteger.ONE) < 0 || x.compareTo(n.subtract(BigInteger.ONE)) > 0) {
|
|
throw new Error('x coordinate out of bounds');
|
|
}
|
|
if (y.compareTo(BigInteger.ONE) < 0 || y.compareTo(n.subtract(BigInteger.ONE)) > 0) {
|
|
throw new Error('y coordinate out of bounds');
|
|
}
|
|
|
|
// Check y^2 = x^3 + ax + b (mod n)
|
|
if (!this.isOnCurve()) {
|
|
throw new Error("Point is not on the curve.");
|
|
}
|
|
|
|
// Check nQ = 0 (Q is a scalar multiple of G)
|
|
if (this.multiply(n).isInfinity()) {
|
|
// TODO: This check doesn't work - fix.
|
|
throw new Error("Point is not a scalar multiple of G.");
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
|
|
|
|
|
|
// ----------------
|
|
// ECCurveFp constructor
|
|
ec.CurveFp = function (q, a, b) {
|
|
this.q = q;
|
|
this.a = this.fromBigInteger(a);
|
|
this.b = this.fromBigInteger(b);
|
|
this.infinity = new ec.PointFp(this, null, null);
|
|
}
|
|
|
|
ec.CurveFp.prototype.getQ = function () {
|
|
return this.q;
|
|
};
|
|
|
|
ec.CurveFp.prototype.getA = function () {
|
|
return this.a;
|
|
};
|
|
|
|
ec.CurveFp.prototype.getB = function () {
|
|
return this.b;
|
|
};
|
|
|
|
ec.CurveFp.prototype.equals = function (other) {
|
|
if (other == this) return true;
|
|
return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b));
|
|
};
|
|
|
|
ec.CurveFp.prototype.getInfinity = function () {
|
|
return this.infinity;
|
|
};
|
|
|
|
ec.CurveFp.prototype.fromBigInteger = function (x) {
|
|
return new ec.FieldElementFp(this.q, x);
|
|
};
|
|
|
|
// for now, work with hex strings because they're easier in JS
|
|
ec.CurveFp.prototype.decodePointHex = function (s) {
|
|
switch (parseInt(s.substr(0, 2), 16)) { // first byte
|
|
case 0:
|
|
return this.infinity;
|
|
case 2:
|
|
case 3:
|
|
// point compression not supported yet
|
|
return null;
|
|
case 4:
|
|
case 6:
|
|
case 7:
|
|
var len = (s.length - 2) / 2;
|
|
var xHex = s.substr(2, len);
|
|
var yHex = s.substr(len + 2, len);
|
|
|
|
return new ec.PointFp(this,
|
|
this.fromBigInteger(new BigInteger(xHex, 16)),
|
|
this.fromBigInteger(new BigInteger(yHex, 16)));
|
|
|
|
default: // unsupported
|
|
return null;
|
|
}
|
|
};
|
|
|
|
|
|
ec.fromHex = function (s) { return new BigInteger(s, 16); };
|
|
|
|
ec.integerToBytes = function (i, len) {
|
|
var bytes = i.toByteArrayUnsigned();
|
|
if (len < bytes.length) {
|
|
bytes = bytes.slice(bytes.length - len);
|
|
} else while (len > bytes.length) {
|
|
bytes.unshift(0);
|
|
}
|
|
return bytes;
|
|
};
|
|
|
|
|
|
// Named EC curves
|
|
// ----------------
|
|
// X9ECParameters constructor
|
|
ec.X9Parameters = function (curve, g, n, h) {
|
|
this.curve = curve;
|
|
this.g = g;
|
|
this.n = n;
|
|
this.h = h;
|
|
}
|
|
ec.X9Parameters.prototype.getCurve = function () { return this.curve; };
|
|
ec.X9Parameters.prototype.getG = function () { return this.g; };
|
|
ec.X9Parameters.prototype.getN = function () { return this.n; };
|
|
ec.X9Parameters.prototype.getH = function () { return this.h; };
|
|
|
|
// secp256k1 is the Curve used by Bitcoin
|
|
ec.secNamedCurves = {
|
|
// used by Bitcoin
|
|
"secp256k1": function () {
|
|
// p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
|
|
var p = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
|
|
var a = BigInteger.ZERO;
|
|
var b = ec.fromHex("7");
|
|
var n = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
|
|
var h = BigInteger.ONE;
|
|
var curve = new ec.CurveFp(p, a, b);
|
|
var G = curve.decodePointHex("04"
|
|
+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
|
|
+ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
|
|
return new ec.X9Parameters(curve, G, n, h);
|
|
}
|
|
};
|
|
|
|
// secp256k1 called by Bitcoin's ECKEY
|
|
ec.getSECCurveByName = function (name) {
|
|
if (ec.secNamedCurves[name] == undefined) return null;
|
|
return ec.secNamedCurves[name]();
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
/*!
|
|
* Basic JavaScript BN library - subset useful for RSA encryption.
|
|
*
|
|
* Copyright (c) 2005 Tom Wu
|
|
* All Rights Reserved.
|
|
* BSD License
|
|
* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
|
|
*
|
|
* Copyright Stephan Thomas
|
|
* Copyright bitaddress.org
|
|
*/
|
|
|
|
(function () {
|
|
|
|
// (public) Constructor function of Global BigInteger object
|
|
var BigInteger = window.BigInteger = function BigInteger(a, b, c) {
|
|
if (a != null)
|
|
if ("number" == typeof a) this.fromNumber(a, b, c);
|
|
else if (b == null && "string" != typeof a) this.fromString(a, 256);
|
|
else this.fromString(a, b);
|
|
};
|
|
|
|
// Bits per digit
|
|
var dbits;
|
|
|
|
// JavaScript engine analysis
|
|
var canary = 0xdeadbeefcafe;
|
|
var j_lm = ((canary & 0xffffff) == 0xefcafe);
|
|
|
|
// return new, unset BigInteger
|
|
function nbi() { return new BigInteger(null); }
|
|
|
|
// am: Compute w_j += (x*this_i), propagate carries,
|
|
// c is initial carry, returns final carry.
|
|
// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
|
|
// We need to select the fastest one that works in this environment.
|
|
|
|
// am1: use a single mult and divide to get the high bits,
|
|
// max digit bits should be 26 because
|
|
// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
|
|
function am1(i, x, w, j, c, n) {
|
|
while (--n >= 0) {
|
|
var v = x * this[i++] + w[j] + c;
|
|
c = Math.floor(v / 0x4000000);
|
|
w[j++] = v & 0x3ffffff;
|
|
}
|
|
return c;
|
|
}
|
|
// am2 avoids a big mult-and-extract completely.
|
|
// Max digit bits should be <= 30 because we do bitwise ops
|
|
// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
|
|
function am2(i, x, w, j, c, n) {
|
|
var xl = x & 0x7fff, xh = x >> 15;
|
|
while (--n >= 0) {
|
|
var l = this[i] & 0x7fff;
|
|
var h = this[i++] >> 15;
|
|
var m = xh * l + h * xl;
|
|
l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
|
|
c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
|
|
w[j++] = l & 0x3fffffff;
|
|
}
|
|
return c;
|
|
}
|
|
// Alternately, set max digit bits to 28 since some
|
|
// browsers slow down when dealing with 32-bit numbers.
|
|
function am3(i, x, w, j, c, n) {
|
|
var xl = x & 0x3fff, xh = x >> 14;
|
|
while (--n >= 0) {
|
|
var l = this[i] & 0x3fff;
|
|
var h = this[i++] >> 14;
|
|
var m = xh * l + h * xl;
|
|
l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
|
|
c = (l >> 28) + (m >> 14) + xh * h;
|
|
w[j++] = l & 0xfffffff;
|
|
}
|
|
return c;
|
|
}
|
|
if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
|
|
BigInteger.prototype.am = am2;
|
|
dbits = 30;
|
|
}
|
|
else if (j_lm && (navigator.appName != "Netscape")) {
|
|
BigInteger.prototype.am = am1;
|
|
dbits = 26;
|
|
}
|
|
else { // Mozilla/Netscape seems to prefer am3
|
|
BigInteger.prototype.am = am3;
|
|
dbits = 28;
|
|
}
|
|
|
|
BigInteger.prototype.DB = dbits;
|
|
BigInteger.prototype.DM = ((1 << dbits) - 1);
|
|
BigInteger.prototype.DV = (1 << dbits);
|
|
|
|
var BI_FP = 52;
|
|
BigInteger.prototype.FV = Math.pow(2, BI_FP);
|
|
BigInteger.prototype.F1 = BI_FP - dbits;
|
|
BigInteger.prototype.F2 = 2 * dbits - BI_FP;
|
|
|
|
// Digit conversions
|
|
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
var BI_RC = new Array();
|
|
var rr, vv;
|
|
rr = "0".charCodeAt(0);
|
|
for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
|
|
rr = "a".charCodeAt(0);
|
|
for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
|
|
rr = "A".charCodeAt(0);
|
|
for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
|
|
|
|
function int2char(n) { return BI_RM.charAt(n); }
|
|
function intAt(s, i) {
|
|
var c = BI_RC[s.charCodeAt(i)];
|
|
return (c == null) ? -1 : c;
|
|
}
|
|
|
|
|
|
|
|
// return bigint initialized to value
|
|
function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
|
|
|
|
|
|
// returns bit length of the integer x
|
|
function nbits(x) {
|
|
var r = 1, t;
|
|
if ((t = x >>> 16) != 0) { x = t; r += 16; }
|
|
if ((t = x >> 8) != 0) { x = t; r += 8; }
|
|
if ((t = x >> 4) != 0) { x = t; r += 4; }
|
|
if ((t = x >> 2) != 0) { x = t; r += 2; }
|
|
if ((t = x >> 1) != 0) { x = t; r += 1; }
|
|
return r;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// (protected) copy this to r
|
|
BigInteger.prototype.copyTo = function (r) {
|
|
for (var i = this.t - 1; i >= 0; --i) r[i] = this[i];
|
|
r.t = this.t;
|
|
r.s = this.s;
|
|
};
|
|
|
|
|
|
// (protected) set from integer value x, -DV <= x < DV
|
|
BigInteger.prototype.fromInt = function (x) {
|
|
this.t = 1;
|
|
this.s = (x < 0) ? -1 : 0;
|
|
if (x > 0) this[0] = x;
|
|
else if (x < -1) this[0] = x + DV;
|
|
else this.t = 0;
|
|
};
|
|
|
|
// (protected) set from string and radix
|
|
BigInteger.prototype.fromString = function (s, b) {
|
|
var k;
|
|
if (b == 16) k = 4;
|
|
else if (b == 8) k = 3;
|
|
else if (b == 256) k = 8; // byte array
|
|
else if (b == 2) k = 1;
|
|
else if (b == 32) k = 5;
|
|
else if (b == 4) k = 2;
|
|
else { this.fromRadix(s, b); return; }
|
|
this.t = 0;
|
|
this.s = 0;
|
|
var i = s.length, mi = false, sh = 0;
|
|
while (--i >= 0) {
|
|
var x = (k == 8) ? s[i] & 0xff : intAt(s, i);
|
|
if (x < 0) {
|
|
if (s.charAt(i) == "-") mi = true;
|
|
continue;
|
|
}
|
|
mi = false;
|
|
if (sh == 0)
|
|
this[this.t++] = x;
|
|
else if (sh + k > this.DB) {
|
|
this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
|
|
this[this.t++] = (x >> (this.DB - sh));
|
|
}
|
|
else
|
|
this[this.t - 1] |= x << sh;
|
|
sh += k;
|
|
if (sh >= this.DB) sh -= this.DB;
|
|
}
|
|
if (k == 8 && (s[0] & 0x80) != 0) {
|
|
this.s = -1;
|
|
if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
|
|
}
|
|
this.clamp();
|
|
if (mi) BigInteger.ZERO.subTo(this, this);
|
|
};
|
|
|
|
|
|
// (protected) clamp off excess high words
|
|
BigInteger.prototype.clamp = function () {
|
|
var c = this.s & this.DM;
|
|
while (this.t > 0 && this[this.t - 1] == c) --this.t;
|
|
};
|
|
|
|
// (protected) r = this << n*DB
|
|
BigInteger.prototype.dlShiftTo = function (n, r) {
|
|
var i;
|
|
for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i];
|
|
for (i = n - 1; i >= 0; --i) r[i] = 0;
|
|
r.t = this.t + n;
|
|
r.s = this.s;
|
|
};
|
|
|
|
// (protected) r = this >> n*DB
|
|
BigInteger.prototype.drShiftTo = function (n, r) {
|
|
for (var i = n; i < this.t; ++i) r[i - n] = this[i];
|
|
r.t = Math.max(this.t - n, 0);
|
|
r.s = this.s;
|
|
};
|
|
|
|
|
|
// (protected) r = this << n
|
|
BigInteger.prototype.lShiftTo = function (n, r) {
|
|
var bs = n % this.DB;
|
|
var cbs = this.DB - bs;
|
|
var bm = (1 << cbs) - 1;
|
|
var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i;
|
|
for (i = this.t - 1; i >= 0; --i) {
|
|
r[i + ds + 1] = (this[i] >> cbs) | c;
|
|
c = (this[i] & bm) << bs;
|
|
}
|
|
for (i = ds - 1; i >= 0; --i) r[i] = 0;
|
|
r[ds] = c;
|
|
r.t = this.t + ds + 1;
|
|
r.s = this.s;
|
|
r.clamp();
|
|
};
|
|
|
|
|
|
// (protected) r = this >> n
|
|
BigInteger.prototype.rShiftTo = function (n, r) {
|
|
r.s = this.s;
|
|
var ds = Math.floor(n / this.DB);
|
|
if (ds >= this.t) { r.t = 0; return; }
|
|
var bs = n % this.DB;
|
|
var cbs = this.DB - bs;
|
|
var bm = (1 << bs) - 1;
|
|
r[0] = this[ds] >> bs;
|
|
for (var i = ds + 1; i < this.t; ++i) {
|
|
r[i - ds - 1] |= (this[i] & bm) << cbs;
|
|
r[i - ds] = this[i] >> bs;
|
|
}
|
|
if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
|
|
r.t = this.t - ds;
|
|
r.clamp();
|
|
};
|
|
|
|
|
|
// (protected) r = this - a
|
|
BigInteger.prototype.subTo = function (a, r) {
|
|
var i = 0, c = 0, m = Math.min(a.t, this.t);
|
|
while (i < m) {
|
|
c += this[i] - a[i];
|
|
r[i++] = c & this.DM;
|
|
c >>= this.DB;
|
|
}
|
|
if (a.t < this.t) {
|
|
c -= a.s;
|
|
while (i < this.t) {
|
|
c += this[i];
|
|
r[i++] = c & this.DM;
|
|
c >>= this.DB;
|
|
}
|
|
c += this.s;
|
|
}
|
|
else {
|
|
c += this.s;
|
|
while (i < a.t) {
|
|
c -= a[i];
|
|
r[i++] = c & this.DM;
|
|
c >>= this.DB;
|
|
}
|
|
c -= a.s;
|
|
}
|
|
r.s = (c < 0) ? -1 : 0;
|
|
if (c < -1) r[i++] = this.DV + c;
|
|
else if (c > 0) r[i++] = c;
|
|
r.t = i;
|
|
r.clamp();
|
|
};
|
|
|
|
|
|
// (protected) r = this * a, r != this,a (HAC 14.12)
|
|
// "this" should be the larger one if appropriate.
|
|
BigInteger.prototype.multiplyTo = function (a, r) {
|
|
var x = this.abs(), y = a.abs();
|
|
var i = x.t;
|
|
r.t = i + y.t;
|
|
while (--i >= 0) r[i] = 0;
|
|
for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
|
|
r.s = 0;
|
|
r.clamp();
|
|
if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
|
|
};
|
|
|
|
|
|
// (protected) r = this^2, r != this (HAC 14.16)
|
|
BigInteger.prototype.squareTo = function (r) {
|
|
var x = this.abs();
|
|
var i = r.t = 2 * x.t;
|
|
while (--i >= 0) r[i] = 0;
|
|
for (i = 0; i < x.t - 1; ++i) {
|
|
var c = x.am(i, x[i], r, 2 * i, 0, 1);
|
|
if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
|
|
r[i + x.t] -= x.DV;
|
|
r[i + x.t + 1] = 1;
|
|
}
|
|
}
|
|
if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
|
|
r.s = 0;
|
|
r.clamp();
|
|
};
|
|
|
|
|
|
|
|
// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
|
|
// r != q, this != m. q or r may be null.
|
|
BigInteger.prototype.divRemTo = function (m, q, r) {
|
|
var pm = m.abs();
|
|
if (pm.t <= 0) return;
|
|
var pt = this.abs();
|
|
if (pt.t < pm.t) {
|
|
if (q != null) q.fromInt(0);
|
|
if (r != null) this.copyTo(r);
|
|
return;
|
|
}
|
|
if (r == null) r = nbi();
|
|
var y = nbi(), ts = this.s, ms = m.s;
|
|
var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
|
|
if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); }
|
|
else { pm.copyTo(y); pt.copyTo(r); }
|
|
var ys = y.t;
|
|
var y0 = y[ys - 1];
|
|
if (y0 == 0) return;
|
|
var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
|
|
var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2;
|
|
var i = r.t, j = i - ys, t = (q == null) ? nbi() : q;
|
|
y.dlShiftTo(j, t);
|
|
if (r.compareTo(t) >= 0) {
|
|
r[r.t++] = 1;
|
|
r.subTo(t, r);
|
|
}
|
|
BigInteger.ONE.dlShiftTo(ys, t);
|
|
t.subTo(y, y); // "negative" y so we can replace sub with am later
|
|
while (y.t < ys) y[y.t++] = 0;
|
|
while (--j >= 0) {
|
|
// Estimate quotient digit
|
|
var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
|
|
if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out
|
|
y.dlShiftTo(j, t);
|
|
r.subTo(t, r);
|
|
while (r[i] < --qd) r.subTo(t, r);
|
|
}
|
|
}
|
|
if (q != null) {
|
|
r.drShiftTo(ys, q);
|
|
if (ts != ms) BigInteger.ZERO.subTo(q, q);
|
|
}
|
|
r.t = ys;
|
|
r.clamp();
|
|
if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
|
|
if (ts < 0) BigInteger.ZERO.subTo(r, r);
|
|
};
|
|
|
|
|
|
// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
|
|
// justification:
|
|
// xy == 1 (mod m)
|
|
// xy = 1+km
|
|
// xy(2-xy) = (1+km)(1-km)
|
|
// x[y(2-xy)] = 1-k^2m^2
|
|
// x[y(2-xy)] == 1 (mod m^2)
|
|
// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
|
|
// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
|
|
// JS multiply "overflows" differently from C/C++, so care is needed here.
|
|
BigInteger.prototype.invDigit = function () {
|
|
if (this.t < 1) return 0;
|
|
var x = this[0];
|
|
if ((x & 1) == 0) return 0;
|
|
var y = x & 3; // y == 1/x mod 2^2
|
|
y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
|
|
y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
|
|
y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
|
|
// last step - calculate inverse mod DV directly;
|
|
// assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
|
|
y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits
|
|
// we really want the negative inverse, and -DV < y < DV
|
|
return (y > 0) ? this.DV - y : -y;
|
|
};
|
|
|
|
|
|
// (protected) true iff this is even
|
|
BigInteger.prototype.isEven = function () { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; };
|
|
|
|
|
|
// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
|
|
BigInteger.prototype.exp = function (e, z) {
|
|
if (e > 0xffffffff || e < 1) return BigInteger.ONE;
|
|
var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1;
|
|
g.copyTo(r);
|
|
while (--i >= 0) {
|
|
z.sqrTo(r, r2);
|
|
if ((e & (1 << i)) > 0) z.mulTo(r2, g, r);
|
|
else { var t = r; r = r2; r2 = t; }
|
|
}
|
|
return z.revert(r);
|
|
};
|
|
|
|
|
|
// (public) return string representation in given radix
|
|
BigInteger.prototype.toString = function (b) {
|
|
if (this.s < 0) return "-" + this.negate().toString(b);
|
|
var k;
|
|
if (b == 16) k = 4;
|
|
else if (b == 8) k = 3;
|
|
else if (b == 2) k = 1;
|
|
else if (b == 32) k = 5;
|
|
else if (b == 4) k = 2;
|
|
else return this.toRadix(b);
|
|
var km = (1 << k) - 1, d, m = false, r = "", i = this.t;
|
|
var p = this.DB - (i * this.DB) % k;
|
|
if (i-- > 0) {
|
|
if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); }
|
|
while (i >= 0) {
|
|
if (p < k) {
|
|
d = (this[i] & ((1 << p) - 1)) << (k - p);
|
|
d |= this[--i] >> (p += this.DB - k);
|
|
}
|
|
else {
|
|
d = (this[i] >> (p -= k)) & km;
|
|
if (p <= 0) { p += this.DB; --i; }
|
|
}
|
|
if (d > 0) m = true;
|
|
if (m) r += int2char(d);
|
|
}
|
|
}
|
|
return m ? r : "0";
|
|
};
|
|
|
|
|
|
// (public) -this
|
|
BigInteger.prototype.negate = function () { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; };
|
|
|
|
// (public) |this|
|
|
BigInteger.prototype.abs = function () { return (this.s < 0) ? this.negate() : this; };
|
|
|
|
// (public) return + if this > a, - if this < a, 0 if equal
|
|
BigInteger.prototype.compareTo = function (a) {
|
|
var r = this.s - a.s;
|
|
if (r != 0) return r;
|
|
var i = this.t;
|
|
r = i - a.t;
|
|
if (r != 0) return r;
|
|
while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r;
|
|
return 0;
|
|
}
|
|
|
|
// (public) return the number of bits in "this"
|
|
BigInteger.prototype.bitLength = function () {
|
|
if (this.t <= 0) return 0;
|
|
return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
|
|
};
|
|
|
|
// (public) this mod a
|
|
BigInteger.prototype.mod = function (a) {
|
|
var r = nbi();
|
|
this.abs().divRemTo(a, null, r);
|
|
if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
|
|
return r;
|
|
}
|
|
|
|
// (public) this^e % m, 0 <= e < 2^32
|
|
BigInteger.prototype.modPowInt = function (e, m) {
|
|
var z;
|
|
if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
|
|
return this.exp(e, z);
|
|
};
|
|
|
|
// "constants"
|
|
BigInteger.ZERO = nbv(0);
|
|
BigInteger.ONE = nbv(1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copyright (c) 2005-2009 Tom Wu
|
|
// All Rights Reserved.
|
|
// See "LICENSE" for details.
|
|
// Extended JavaScript BN functions, required for RSA private ops.
|
|
// Version 1.1: new BigInteger("0", 10) returns "proper" zero
|
|
// Version 1.2: square() API, isProbablePrime fix
|
|
|
|
|
|
// return index of lowest 1-bit in x, x < 2^31
|
|
function lbit(x) {
|
|
if (x == 0) return -1;
|
|
var r = 0;
|
|
if ((x & 0xffff) == 0) { x >>= 16; r += 16; }
|
|
if ((x & 0xff) == 0) { x >>= 8; r += 8; }
|
|
if ((x & 0xf) == 0) { x >>= 4; r += 4; }
|
|
if ((x & 3) == 0) { x >>= 2; r += 2; }
|
|
if ((x & 1) == 0) ++r;
|
|
return r;
|
|
}
|
|
|
|
// return number of 1 bits in x
|
|
function cbit(x) {
|
|
var r = 0;
|
|
while (x != 0) { x &= x - 1; ++r; }
|
|
return r;
|
|
}
|
|
|
|
var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
|
|
var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
|
|
|
|
|
|
|
|
// (protected) return x s.t. r^x < DV
|
|
BigInteger.prototype.chunkSize = function (r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); };
|
|
|
|
// (protected) convert to radix string
|
|
BigInteger.prototype.toRadix = function (b) {
|
|
if (b == null) b = 10;
|
|
if (this.signum() == 0 || b < 2 || b > 36) return "0";
|
|
var cs = this.chunkSize(b);
|
|
var a = Math.pow(b, cs);
|
|
var d = nbv(a), y = nbi(), z = nbi(), r = "";
|
|
this.divRemTo(d, y, z);
|
|
while (y.signum() > 0) {
|
|
r = (a + z.intValue()).toString(b).substr(1) + r;
|
|
y.divRemTo(d, y, z);
|
|
}
|
|
return z.intValue().toString(b) + r;
|
|
};
|
|
|
|
// (protected) convert from radix string
|
|
BigInteger.prototype.fromRadix = function (s, b) {
|
|
this.fromInt(0);
|
|
if (b == null) b = 10;
|
|
var cs = this.chunkSize(b);
|
|
var d = Math.pow(b, cs), mi = false, j = 0, w = 0;
|
|
for (var i = 0; i < s.length; ++i) {
|
|
var x = intAt(s, i);
|
|
if (x < 0) {
|
|
if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
|
|
continue;
|
|
}
|
|
w = b * w + x;
|
|
if (++j >= cs) {
|
|
this.dMultiply(d);
|
|
this.dAddOffset(w, 0);
|
|
j = 0;
|
|
w = 0;
|
|
}
|
|
}
|
|
if (j > 0) {
|
|
this.dMultiply(Math.pow(b, j));
|
|
this.dAddOffset(w, 0);
|
|
}
|
|
if (mi) BigInteger.ZERO.subTo(this, this);
|
|
};
|
|
|
|
// (protected) alternate constructor
|
|
BigInteger.prototype.fromNumber = function (a, b, c) {
|
|
if ("number" == typeof b) {
|
|
// new BigInteger(int,int,RNG)
|
|
if (a < 2) this.fromInt(1);
|
|
else {
|
|
this.fromNumber(a, c);
|
|
if (!this.testBit(a - 1)) // force MSB set
|
|
this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
|
|
if (this.isEven()) this.dAddOffset(1, 0); // force odd
|
|
while (!this.isProbablePrime(b)) {
|
|
this.dAddOffset(2, 0);
|
|
if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// new BigInteger(int,RNG)
|
|
var x = new Array(), t = a & 7;
|
|
x.length = (a >> 3) + 1;
|
|
b.nextBytes(x);
|
|
if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0;
|
|
this.fromString(x, 256);
|
|
}
|
|
};
|
|
|
|
// (protected) r = this op a (bitwise)
|
|
BigInteger.prototype.bitwiseTo = function (a, op, r) {
|
|
var i, f, m = Math.min(a.t, this.t);
|
|
for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]);
|
|
if (a.t < this.t) {
|
|
f = a.s & this.DM;
|
|
for (i = m; i < this.t; ++i) r[i] = op(this[i], f);
|
|
r.t = this.t;
|
|
}
|
|
else {
|
|
f = this.s & this.DM;
|
|
for (i = m; i < a.t; ++i) r[i] = op(f, a[i]);
|
|
r.t = a.t;
|
|
}
|
|
r.s = op(this.s, a.s);
|
|
r.clamp();
|
|
};
|
|
|
|
// (protected) this op (1<<n)
|
|
BigInteger.prototype.changeBit = function (n, op) {
|
|
var r = BigInteger.ONE.shiftLeft(n);
|
|
this.bitwiseTo(r, op, r);
|
|
return r;
|
|
};
|
|
|
|
// (protected) r = this + a
|
|
BigInteger.prototype.addTo = function (a, r) {
|
|
var i = 0, c = 0, m = Math.min(a.t, this.t);
|
|
while (i < m) {
|
|
c += this[i] + a[i];
|
|
r[i++] = c & this.DM;
|
|
c >>= this.DB;
|
|
}
|
|
if (a.t < this.t) {
|
|
c += a.s;
|
|
while (i < this.t) {
|
|
c += this[i];
|
|
r[i++] = c & this.DM;
|
|
c >>= this.DB;
|
|
}
|
|
c += this.s;
|
|
}
|
|
else {
|
|
c += this.s;
|
|
while (i < a.t) {
|
|
c += a[i];
|
|
r[i++] = c & this.DM;
|
|
c >>= this.DB;
|
|
}
|
|
c += a.s;
|
|
}
|
|
r.s = (c < 0) ? -1 : 0;
|
|
if (c > 0) r[i++] = c;
|
|
else if (c < -1) r[i++] = this.DV + c;
|
|
r.t = i;
|
|
r.clamp();
|
|
};
|
|
|
|
// (protected) this *= n, this >= 0, 1 < n < DV
|
|
BigInteger.prototype.dMultiply = function (n) {
|
|
this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
|
|
++this.t;
|
|
this.clamp();
|
|
};
|
|
|
|
// (protected) this += n << w words, this >= 0
|
|
BigInteger.prototype.dAddOffset = function (n, w) {
|
|
if (n == 0) return;
|
|
while (this.t <= w) this[this.t++] = 0;
|
|
this[w] += n;
|
|
while (this[w] >= this.DV) {
|
|
this[w] -= this.DV;
|
|
if (++w >= this.t) this[this.t++] = 0;
|
|
++this[w];
|
|
}
|
|
};
|
|
|
|
// (protected) r = lower n words of "this * a", a.t <= n
|
|
// "this" should be the larger one if appropriate.
|
|
BigInteger.prototype.multiplyLowerTo = function (a, n, r) {
|
|
var i = Math.min(this.t + a.t, n);
|
|
r.s = 0; // assumes a,this >= 0
|
|
r.t = i;
|
|
while (i > 0) r[--i] = 0;
|
|
var j;
|
|
for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
|
|
for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i);
|
|
r.clamp();
|
|
};
|
|
|
|
|
|
// (protected) r = "this * a" without lower n words, n > 0
|
|
// "this" should be the larger one if appropriate.
|
|
BigInteger.prototype.multiplyUpperTo = function (a, n, r) {
|
|
--n;
|
|
var i = r.t = this.t + a.t - n;
|
|
r.s = 0; // assumes a,this >= 0
|
|
while (--i >= 0) r[i] = 0;
|
|
for (i = Math.max(n - this.t, 0); i < a.t; ++i)
|
|
r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
|
|
r.clamp();
|
|
r.drShiftTo(1, r);
|
|
};
|
|
|
|
// (protected) this % n, n < 2^26
|
|
BigInteger.prototype.modInt = function (n) {
|
|
if (n <= 0) return 0;
|
|
var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0;
|
|
if (this.t > 0)
|
|
if (d == 0) r = this[0] % n;
|
|
else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n;
|
|
return r;
|
|
};
|
|
|
|
|
|
// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
|
|
BigInteger.prototype.millerRabin = function (t) {
|
|
var n1 = this.subtract(BigInteger.ONE);
|
|
var k = n1.getLowestSetBit();
|
|
if (k <= 0) return false;
|
|
var r = n1.shiftRight(k);
|
|
t = (t + 1) >> 1;
|
|
if (t > lowprimes.length) t = lowprimes.length;
|
|
var a = nbi();
|
|
for (var i = 0; i < t; ++i) {
|
|
//Pick bases at random, instead of starting at 2
|
|
a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
|
|
var y = a.modPow(r, this);
|
|
if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
|
|
var j = 1;
|
|
while (j++ < k && y.compareTo(n1) != 0) {
|
|
y = y.modPowInt(2, this);
|
|
if (y.compareTo(BigInteger.ONE) == 0) return false;
|
|
}
|
|
if (y.compareTo(n1) != 0) return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
|
|
|
|
// (public)
|
|
BigInteger.prototype.clone = function () { var r = nbi(); this.copyTo(r); return r; };
|
|
|
|
// (public) return value as integer
|
|
BigInteger.prototype.intValue = function () {
|
|
if (this.s < 0) {
|
|
if (this.t == 1) return this[0] - this.DV;
|
|
else if (this.t == 0) return -1;
|
|
}
|
|
else if (this.t == 1) return this[0];
|
|
else if (this.t == 0) return 0;
|
|
// assumes 16 < DB < 32
|
|
return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
|
|
};
|
|
|
|
|
|
// (public) return value as byte
|
|
BigInteger.prototype.byteValue = function () { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; };
|
|
|
|
// (public) return value as short (assumes DB>=16)
|
|
BigInteger.prototype.shortValue = function () { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; };
|
|
|
|
// (public) 0 if this == 0, 1 if this > 0
|
|
BigInteger.prototype.signum = function () {
|
|
if (this.s < 0) return -1;
|
|
else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
|
|
else return 1;
|
|
};
|
|
|
|
|
|
// (public) convert to bigendian byte array
|
|
BigInteger.prototype.toByteArray = function () {
|
|
var i = this.t, r = new Array();
|
|
r[0] = this.s;
|
|
var p = this.DB - (i * this.DB) % 8, d, k = 0;
|
|
if (i-- > 0) {
|
|
if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p)
|
|
r[k++] = d | (this.s << (this.DB - p));
|
|
while (i >= 0) {
|
|
if (p < 8) {
|
|
d = (this[i] & ((1 << p) - 1)) << (8 - p);
|
|
d |= this[--i] >> (p += this.DB - 8);
|
|
}
|
|
else {
|
|
d = (this[i] >> (p -= 8)) & 0xff;
|
|
if (p <= 0) { p += this.DB; --i; }
|
|
}
|
|
if ((d & 0x80) != 0) d |= -256;
|
|
if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k;
|
|
if (k > 0 || d != this.s) r[k++] = d;
|
|
}
|
|
}
|
|
return r;
|
|
};
|
|
|
|
BigInteger.prototype.equals = function (a) { return (this.compareTo(a) == 0); };
|
|
BigInteger.prototype.min = function (a) { return (this.compareTo(a) < 0) ? this : a; };
|
|
BigInteger.prototype.max = function (a) { return (this.compareTo(a) > 0) ? this : a; };
|
|
|
|
// (public) this & a
|
|
function op_and(x, y) { return x & y; }
|
|
BigInteger.prototype.and = function (a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; };
|
|
|
|
// (public) this | a
|
|
function op_or(x, y) { return x | y; }
|
|
BigInteger.prototype.or = function (a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; };
|
|
|
|
// (public) this ^ a
|
|
function op_xor(x, y) { return x ^ y; }
|
|
BigInteger.prototype.xor = function (a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; };
|
|
|
|
// (public) this & ~a
|
|
function op_andnot(x, y) { return x & ~y; }
|
|
BigInteger.prototype.andNot = function (a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; };
|
|
|
|
// (public) ~this
|
|
BigInteger.prototype.not = function () {
|
|
var r = nbi();
|
|
for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i];
|
|
r.t = this.t;
|
|
r.s = ~this.s;
|
|
return r;
|
|
};
|
|
|
|
// (public) this << n
|
|
BigInteger.prototype.shiftLeft = function (n) {
|
|
var r = nbi();
|
|
if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r);
|
|
return r;
|
|
};
|
|
|
|
// (public) this >> n
|
|
BigInteger.prototype.shiftRight = function (n) {
|
|
var r = nbi();
|
|
if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r);
|
|
return r;
|
|
};
|
|
|
|
// (public) returns index of lowest 1-bit (or -1 if none)
|
|
BigInteger.prototype.getLowestSetBit = function () {
|
|
for (var i = 0; i < this.t; ++i)
|
|
if (this[i] != 0) return i * this.DB + lbit(this[i]);
|
|
if (this.s < 0) return this.t * this.DB;
|
|
return -1;
|
|
};
|
|
|
|
// (public) return number of set bits
|
|
BigInteger.prototype.bitCount = function () {
|
|
var r = 0, x = this.s & this.DM;
|
|
for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x);
|
|
return r;
|
|
};
|
|
|
|
// (public) true iff nth bit is set
|
|
BigInteger.prototype.testBit = function (n) {
|
|
var j = Math.floor(n / this.DB);
|
|
if (j >= this.t) return (this.s != 0);
|
|
return ((this[j] & (1 << (n % this.DB))) != 0);
|
|
};
|
|
|
|
// (public) this | (1<<n)
|
|
BigInteger.prototype.setBit = function (n) { return this.changeBit(n, op_or); };
|
|
// (public) this & ~(1<<n)
|
|
BigInteger.prototype.clearBit = function (n) { return this.changeBit(n, op_andnot); };
|
|
// (public) this ^ (1<<n)
|
|
BigInteger.prototype.flipBit = function (n) { return this.changeBit(n, op_xor); };
|
|
// (public) this + a
|
|
BigInteger.prototype.add = function (a) { var r = nbi(); this.addTo(a, r); return r; };
|
|
// (public) this - a
|
|
BigInteger.prototype.subtract = function (a) { var r = nbi(); this.subTo(a, r); return r; };
|
|
// (public) this * a
|
|
BigInteger.prototype.multiply = function (a) { var r = nbi(); this.multiplyTo(a, r); return r; };
|
|
// (public) this / a
|
|
BigInteger.prototype.divide = function (a) { var r = nbi(); this.divRemTo(a, r, null); return r; };
|
|
// (public) this % a
|
|
BigInteger.prototype.remainder = function (a) { var r = nbi(); this.divRemTo(a, null, r); return r; };
|
|
// (public) [this/a,this%a]
|
|
BigInteger.prototype.divideAndRemainder = function (a) {
|
|
var q = nbi(), r = nbi();
|
|
this.divRemTo(a, q, r);
|
|
return new Array(q, r);
|
|
};
|
|
|
|
// (public) this^e % m (HAC 14.85)
|
|
BigInteger.prototype.modPow = function (e, m) {
|
|
var i = e.bitLength(), k, r = nbv(1), z;
|
|
if (i <= 0) return r;
|
|
else if (i < 18) k = 1;
|
|
else if (i < 48) k = 3;
|
|
else if (i < 144) k = 4;
|
|
else if (i < 768) k = 5;
|
|
else k = 6;
|
|
if (i < 8)
|
|
z = new Classic(m);
|
|
else if (m.isEven())
|
|
z = new Barrett(m);
|
|
else
|
|
z = new Montgomery(m);
|
|
|
|
// precomputation
|
|
var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1;
|
|
g[1] = z.convert(this);
|
|
if (k > 1) {
|
|
var g2 = nbi();
|
|
z.sqrTo(g[1], g2);
|
|
while (n <= km) {
|
|
g[n] = nbi();
|
|
z.mulTo(g2, g[n - 2], g[n]);
|
|
n += 2;
|
|
}
|
|
}
|
|
|
|
var j = e.t - 1, w, is1 = true, r2 = nbi(), t;
|
|
i = nbits(e[j]) - 1;
|
|
while (j >= 0) {
|
|
if (i >= k1) w = (e[j] >> (i - k1)) & km;
|
|
else {
|
|
w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
|
|
if (j > 0) w |= e[j - 1] >> (this.DB + i - k1);
|
|
}
|
|
|
|
n = k;
|
|
while ((w & 1) == 0) { w >>= 1; --n; }
|
|
if ((i -= n) < 0) { i += this.DB; --j; }
|
|
if (is1) { // ret == 1, don't bother squaring or multiplying it
|
|
g[w].copyTo(r);
|
|
is1 = false;
|
|
}
|
|
else {
|
|
while (n > 1) { z.sqrTo(r, r2); z.sqrTo(r2, r); n -= 2; }
|
|
if (n > 0) z.sqrTo(r, r2); else { t = r; r = r2; r2 = t; }
|
|
z.mulTo(r2, g[w], r);
|
|
}
|
|
|
|
while (j >= 0 && (e[j] & (1 << i)) == 0) {
|
|
z.sqrTo(r, r2); t = r; r = r2; r2 = t;
|
|
if (--i < 0) { i = this.DB - 1; --j; }
|
|
}
|
|
}
|
|
return z.revert(r);
|
|
};
|
|
|
|
// (public) 1/this % m (HAC 14.61)
|
|
BigInteger.prototype.modInverse = function (m) {
|
|
var ac = m.isEven();
|
|
if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
|
|
var u = m.clone(), v = this.clone();
|
|
var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
|
|
while (u.signum() != 0) {
|
|
while (u.isEven()) {
|
|
u.rShiftTo(1, u);
|
|
if (ac) {
|
|
if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); }
|
|
a.rShiftTo(1, a);
|
|
}
|
|
else if (!b.isEven()) b.subTo(m, b);
|
|
b.rShiftTo(1, b);
|
|
}
|
|
while (v.isEven()) {
|
|
v.rShiftTo(1, v);
|
|
if (ac) {
|
|
if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); }
|
|
c.rShiftTo(1, c);
|
|
}
|
|
else if (!d.isEven()) d.subTo(m, d);
|
|
d.rShiftTo(1, d);
|
|
}
|
|
if (u.compareTo(v) >= 0) {
|
|
u.subTo(v, u);
|
|
if (ac) a.subTo(c, a);
|
|
b.subTo(d, b);
|
|
}
|
|
else {
|
|
v.subTo(u, v);
|
|
if (ac) c.subTo(a, c);
|
|
d.subTo(b, d);
|
|
}
|
|
}
|
|
if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
|
|
if (d.compareTo(m) >= 0) return d.subtract(m);
|
|
if (d.signum() < 0) d.addTo(m, d); else return d;
|
|
if (d.signum() < 0) return d.add(m); else return d;
|
|
};
|
|
|
|
|
|
// (public) this^e
|
|
BigInteger.prototype.pow = function (e) { return this.exp(e, new NullExp()); };
|
|
|
|
// (public) gcd(this,a) (HAC 14.54)
|
|
BigInteger.prototype.gcd = function (a) {
|
|
var x = (this.s < 0) ? this.negate() : this.clone();
|
|
var y = (a.s < 0) ? a.negate() : a.clone();
|
|
if (x.compareTo(y) < 0) { var t = x; x = y; y = t; }
|
|
var i = x.getLowestSetBit(), g = y.getLowestSetBit();
|
|
if (g < 0) return x;
|
|
if (i < g) g = i;
|
|
if (g > 0) {
|
|
x.rShiftTo(g, x);
|
|
y.rShiftTo(g, y);
|
|
}
|
|
while (x.signum() > 0) {
|
|
if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
|
|
if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);
|
|
if (x.compareTo(y) >= 0) {
|
|
x.subTo(y, x);
|
|
x.rShiftTo(1, x);
|
|
}
|
|
else {
|
|
y.subTo(x, y);
|
|
y.rShiftTo(1, y);
|
|
}
|
|
}
|
|
if (g > 0) y.lShiftTo(g, y);
|
|
return y;
|
|
};
|
|
|
|
// (public) test primality with certainty >= 1-.5^t
|
|
BigInteger.prototype.isProbablePrime = function (t) {
|
|
var i, x = this.abs();
|
|
if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
|
|
for (i = 0; i < lowprimes.length; ++i)
|
|
if (x[0] == lowprimes[i]) return true;
|
|
return false;
|
|
}
|
|
if (x.isEven()) return false;
|
|
i = 1;
|
|
while (i < lowprimes.length) {
|
|
var m = lowprimes[i], j = i + 1;
|
|
while (j < lowprimes.length && m < lplim) m *= lowprimes[j++];
|
|
m = x.modInt(m);
|
|
while (i < j) if (m % lowprimes[i++] == 0) return false;
|
|
}
|
|
return x.millerRabin(t);
|
|
};
|
|
|
|
|
|
// JSBN-specific extension
|
|
|
|
// (public) this^2
|
|
BigInteger.prototype.square = function () { var r = nbi(); this.squareTo(r); return r; };
|
|
|
|
|
|
// NOTE: BigInteger interfaces not implemented in jsbn:
|
|
// BigInteger(int signum, byte[] magnitude)
|
|
// double doubleValue()
|
|
// float floatValue()
|
|
// int hashCode()
|
|
// long longValue()
|
|
// static BigInteger valueOf(long val)
|
|
|
|
|
|
|
|
// Copyright Stephan Thomas (start) --- //
|
|
// BigInteger monkey patching
|
|
BigInteger.valueOf = nbv;
|
|
BigInteger.prototype.toByteArrayUnsigned = function () {
|
|
var ba = this.toByteArray();
|
|
if (ba.length) {
|
|
if (ba[0] == 0) {
|
|
ba = ba.slice(1);
|
|
}
|
|
return ba.map(function (v) {
|
|
return (v < 0) ? v + 256 : v;
|
|
});
|
|
} else {
|
|
// Empty array, nothing to do
|
|
return ba;
|
|
}
|
|
};
|
|
BigInteger.fromByteArrayUnsigned = function (ba) {
|
|
if (!ba.length) {
|
|
return ba.valueOf(0);
|
|
} else if (ba[0] & 0x80) {
|
|
// Prepend a zero so the BigInteger class doesn't mistake this
|
|
// for a negative integer.
|
|
return new BigInteger([0].concat(ba));
|
|
} else {
|
|
return new BigInteger(ba);
|
|
}
|
|
};
|
|
// Copyright Stephan Thomas (end) --- //
|
|
|
|
|
|
|
|
|
|
// ****** REDUCTION ******* //
|
|
|
|
// Modular reduction using "classic" algorithm
|
|
function Classic(m) { this.m = m; }
|
|
Classic.prototype.convert = function (x) {
|
|
if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
|
|
else return x;
|
|
};
|
|
Classic.prototype.revert = function (x) { return x; };
|
|
Classic.prototype.reduce = function (x) { x.divRemTo(this.m, null, x); };
|
|
Classic.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
|
|
Classic.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
|
|
|
|
|
|
|
|
|
|
|
|
// Montgomery reduction
|
|
function Montgomery(m) {
|
|
this.m = m;
|
|
this.mp = m.invDigit();
|
|
this.mpl = this.mp & 0x7fff;
|
|
this.mph = this.mp >> 15;
|
|
this.um = (1 << (m.DB - 15)) - 1;
|
|
this.mt2 = 2 * m.t;
|
|
}
|
|
// xR mod m
|
|
Montgomery.prototype.convert = function (x) {
|
|
var r = nbi();
|
|
x.abs().dlShiftTo(this.m.t, r);
|
|
r.divRemTo(this.m, null, r);
|
|
if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
|
|
return r;
|
|
}
|
|
// x/R mod m
|
|
Montgomery.prototype.revert = function (x) {
|
|
var r = nbi();
|
|
x.copyTo(r);
|
|
this.reduce(r);
|
|
return r;
|
|
};
|
|
// x = x/R mod m (HAC 14.32)
|
|
Montgomery.prototype.reduce = function (x) {
|
|
while (x.t <= this.mt2) // pad x so am has enough room later
|
|
x[x.t++] = 0;
|
|
for (var i = 0; i < this.m.t; ++i) {
|
|
// faster way of calculating u0 = x[i]*mp mod DV
|
|
var j = x[i] & 0x7fff;
|
|
var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
|
|
// use am to combine the multiply-shift-add into one call
|
|
j = i + this.m.t;
|
|
x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
|
|
// propagate carry
|
|
while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
|
|
}
|
|
x.clamp();
|
|
x.drShiftTo(this.m.t, x);
|
|
if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
|
|
};
|
|
// r = "xy/R mod m"; x,y != r
|
|
Montgomery.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
|
|
// r = "x^2/R mod m"; x != r
|
|
Montgomery.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
|
|
|
|
|
|
|
|
|
|
|
|
// A "null" reducer
|
|
function NullExp() { }
|
|
NullExp.prototype.convert = function (x) { return x; };
|
|
NullExp.prototype.revert = function (x) { return x; };
|
|
NullExp.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); };
|
|
NullExp.prototype.sqrTo = function (x, r) { x.squareTo(r); };
|
|
|
|
|
|
|
|
|
|
|
|
// Barrett modular reduction
|
|
function Barrett(m) {
|
|
// setup Barrett
|
|
this.r2 = nbi();
|
|
this.q3 = nbi();
|
|
BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
|
|
this.mu = this.r2.divide(m);
|
|
this.m = m;
|
|
}
|
|
Barrett.prototype.convert = function (x) {
|
|
if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);
|
|
else if (x.compareTo(this.m) < 0) return x;
|
|
else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
|
|
};
|
|
Barrett.prototype.revert = function (x) { return x; };
|
|
// x = x mod m (HAC 14.42)
|
|
Barrett.prototype.reduce = function (x) {
|
|
x.drShiftTo(this.m.t - 1, this.r2);
|
|
if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); }
|
|
this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
|
|
this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
|
|
while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1);
|
|
x.subTo(this.r2, x);
|
|
while (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
|
|
};
|
|
// r = x*y mod m; x,y != r
|
|
Barrett.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
|
|
// r = x^2 mod m; x != r
|
|
Barrett.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
|
|
|
|
})();
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
//---------------------------------------------------------------------
|
|
// QRCode for JavaScript
|
|
//
|
|
// Copyright (c) 2009 Kazuhiko Arase
|
|
//
|
|
// URL: http://www.d-project.com/
|
|
//
|
|
// Licensed under the MIT license:
|
|
// http://www.opensource.org/licenses/mit-license.php
|
|
//
|
|
// The word "QR Code" is registered trademark of
|
|
// DENSO WAVE INCORPORATED
|
|
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
(function () {
|
|
//---------------------------------------------------------------------
|
|
// QRCode
|
|
//---------------------------------------------------------------------
|
|
|
|
var QRCode = window.QRCode = function (typeNumber, errorCorrectLevel) {
|
|
this.typeNumber = typeNumber;
|
|
this.errorCorrectLevel = errorCorrectLevel;
|
|
this.modules = null;
|
|
this.moduleCount = 0;
|
|
this.dataCache = null;
|
|
this.dataList = new Array();
|
|
}
|
|
|
|
QRCode.prototype = {
|
|
|
|
addData: function (data) {
|
|
var newData = new QRCode.QR8bitByte(data);
|
|
this.dataList.push(newData);
|
|
this.dataCache = null;
|
|
},
|
|
|
|
isDark: function (row, col) {
|
|
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
|
|
throw new Error(row + "," + col);
|
|
}
|
|
return this.modules[row][col];
|
|
},
|
|
|
|
getModuleCount: function () {
|
|
return this.moduleCount;
|
|
},
|
|
|
|
make: function () {
|
|
this.makeImpl(false, this.getBestMaskPattern());
|
|
},
|
|
|
|
makeImpl: function (test, maskPattern) {
|
|
|
|
this.moduleCount = this.typeNumber * 4 + 17;
|
|
this.modules = new Array(this.moduleCount);
|
|
|
|
for (var row = 0; row < this.moduleCount; row++) {
|
|
|
|
this.modules[row] = new Array(this.moduleCount);
|
|
|
|
for (var col = 0; col < this.moduleCount; col++) {
|
|
this.modules[row][col] = null; //(col + row) % 3;
|
|
}
|
|
}
|
|
|
|
this.setupPositionProbePattern(0, 0);
|
|
this.setupPositionProbePattern(this.moduleCount - 7, 0);
|
|
this.setupPositionProbePattern(0, this.moduleCount - 7);
|
|
this.setupPositionAdjustPattern();
|
|
this.setupTimingPattern();
|
|
this.setupTypeInfo(test, maskPattern);
|
|
|
|
if (this.typeNumber >= 7) {
|
|
this.setupTypeNumber(test);
|
|
}
|
|
|
|
if (this.dataCache == null) {
|
|
this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
|
|
}
|
|
|
|
this.mapData(this.dataCache, maskPattern);
|
|
},
|
|
|
|
setupPositionProbePattern: function (row, col) {
|
|
|
|
for (var r = -1; r <= 7; r++) {
|
|
|
|
if (row + r <= -1 || this.moduleCount <= row + r) continue;
|
|
|
|
for (var c = -1; c <= 7; c++) {
|
|
|
|
if (col + c <= -1 || this.moduleCount <= col + c) continue;
|
|
|
|
if ((0 <= r && r <= 6 && (c == 0 || c == 6))
|
|
|| (0 <= c && c <= 6 && (r == 0 || r == 6))
|
|
|| (2 <= r && r <= 4 && 2 <= c && c <= 4)) {
|
|
this.modules[row + r][col + c] = true;
|
|
} else {
|
|
this.modules[row + r][col + c] = false;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
getBestMaskPattern: function () {
|
|
|
|
var minLostPoint = 0;
|
|
var pattern = 0;
|
|
|
|
for (var i = 0; i < 8; i++) {
|
|
|
|
this.makeImpl(true, i);
|
|
|
|
var lostPoint = QRCode.Util.getLostPoint(this);
|
|
|
|
if (i == 0 || minLostPoint > lostPoint) {
|
|
minLostPoint = lostPoint;
|
|
pattern = i;
|
|
}
|
|
}
|
|
|
|
return pattern;
|
|
},
|
|
|
|
createMovieClip: function (target_mc, instance_name, depth) {
|
|
|
|
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
|
|
var cs = 1;
|
|
|
|
this.make();
|
|
|
|
for (var row = 0; row < this.modules.length; row++) {
|
|
|
|
var y = row * cs;
|
|
|
|
for (var col = 0; col < this.modules[row].length; col++) {
|
|
|
|
var x = col * cs;
|
|
var dark = this.modules[row][col];
|
|
|
|
if (dark) {
|
|
qr_mc.beginFill(0, 100);
|
|
qr_mc.moveTo(x, y);
|
|
qr_mc.lineTo(x + cs, y);
|
|
qr_mc.lineTo(x + cs, y + cs);
|
|
qr_mc.lineTo(x, y + cs);
|
|
qr_mc.endFill();
|
|
}
|
|
}
|
|
}
|
|
|
|
return qr_mc;
|
|
},
|
|
|
|
setupTimingPattern: function () {
|
|
|
|
for (var r = 8; r < this.moduleCount - 8; r++) {
|
|
if (this.modules[r][6] != null) {
|
|
continue;
|
|
}
|
|
this.modules[r][6] = (r % 2 == 0);
|
|
}
|
|
|
|
for (var c = 8; c < this.moduleCount - 8; c++) {
|
|
if (this.modules[6][c] != null) {
|
|
continue;
|
|
}
|
|
this.modules[6][c] = (c % 2 == 0);
|
|
}
|
|
},
|
|
|
|
setupPositionAdjustPattern: function () {
|
|
|
|
var pos = QRCode.Util.getPatternPosition(this.typeNumber);
|
|
|
|
for (var i = 0; i < pos.length; i++) {
|
|
|
|
for (var j = 0; j < pos.length; j++) {
|
|
|
|
var row = pos[i];
|
|
var col = pos[j];
|
|
|
|
if (this.modules[row][col] != null) {
|
|
continue;
|
|
}
|
|
|
|
for (var r = -2; r <= 2; r++) {
|
|
|
|
for (var c = -2; c <= 2; c++) {
|
|
|
|
if (r == -2 || r == 2 || c == -2 || c == 2
|
|
|| (r == 0 && c == 0)) {
|
|
this.modules[row + r][col + c] = true;
|
|
} else {
|
|
this.modules[row + r][col + c] = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
setupTypeNumber: function (test) {
|
|
|
|
var bits = QRCode.Util.getBCHTypeNumber(this.typeNumber);
|
|
|
|
for (var i = 0; i < 18; i++) {
|
|
var mod = (!test && ((bits >> i) & 1) == 1);
|
|
this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
|
|
}
|
|
|
|
for (var i = 0; i < 18; i++) {
|
|
var mod = (!test && ((bits >> i) & 1) == 1);
|
|
this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
|
|
}
|
|
},
|
|
|
|
setupTypeInfo: function (test, maskPattern) {
|
|
|
|
var data = (this.errorCorrectLevel << 3) | maskPattern;
|
|
var bits = QRCode.Util.getBCHTypeInfo(data);
|
|
|
|
// vertical
|
|
for (var i = 0; i < 15; i++) {
|
|
|
|
var mod = (!test && ((bits >> i) & 1) == 1);
|
|
|
|
if (i < 6) {
|
|
this.modules[i][8] = mod;
|
|
} else if (i < 8) {
|
|
this.modules[i + 1][8] = mod;
|
|
} else {
|
|
this.modules[this.moduleCount - 15 + i][8] = mod;
|
|
}
|
|
}
|
|
|
|
// horizontal
|
|
for (var i = 0; i < 15; i++) {
|
|
|
|
var mod = (!test && ((bits >> i) & 1) == 1);
|
|
|
|
if (i < 8) {
|
|
this.modules[8][this.moduleCount - i - 1] = mod;
|
|
} else if (i < 9) {
|
|
this.modules[8][15 - i - 1 + 1] = mod;
|
|
} else {
|
|
this.modules[8][15 - i - 1] = mod;
|
|
}
|
|
}
|
|
|
|
// fixed module
|
|
this.modules[this.moduleCount - 8][8] = (!test);
|
|
|
|
},
|
|
|
|
mapData: function (data, maskPattern) {
|
|
|
|
var inc = -1;
|
|
var row = this.moduleCount - 1;
|
|
var bitIndex = 7;
|
|
var byteIndex = 0;
|
|
|
|
for (var col = this.moduleCount - 1; col > 0; col -= 2) {
|
|
|
|
if (col == 6) col--;
|
|
|
|
while (true) {
|
|
|
|
for (var c = 0; c < 2; c++) {
|
|
|
|
if (this.modules[row][col - c] == null) {
|
|
|
|
var dark = false;
|
|
|
|
if (byteIndex < data.length) {
|
|
dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
|
|
}
|
|
|
|
var mask = QRCode.Util.getMask(maskPattern, row, col - c);
|
|
|
|
if (mask) {
|
|
dark = !dark;
|
|
}
|
|
|
|
this.modules[row][col - c] = dark;
|
|
bitIndex--;
|
|
|
|
if (bitIndex == -1) {
|
|
byteIndex++;
|
|
bitIndex = 7;
|
|
}
|
|
}
|
|
}
|
|
|
|
row += inc;
|
|
|
|
if (row < 0 || this.moduleCount <= row) {
|
|
row -= inc;
|
|
inc = -inc;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
QRCode.PAD0 = 0xEC;
|
|
QRCode.PAD1 = 0x11;
|
|
|
|
QRCode.createData = function (typeNumber, errorCorrectLevel, dataList) {
|
|
|
|
var rsBlocks = QRCode.RSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
|
|
|
|
var buffer = new QRCode.BitBuffer();
|
|
|
|
for (var i = 0; i < dataList.length; i++) {
|
|
var data = dataList[i];
|
|
buffer.put(data.mode, 4);
|
|
buffer.put(data.getLength(), QRCode.Util.getLengthInBits(data.mode, typeNumber));
|
|
data.write(buffer);
|
|
}
|
|
|
|
// calc num max data.
|
|
var totalDataCount = 0;
|
|
for (var i = 0; i < rsBlocks.length; i++) {
|
|
totalDataCount += rsBlocks[i].dataCount;
|
|
}
|
|
|
|
if (buffer.getLengthInBits() > totalDataCount * 8) {
|
|
throw new Error("code length overflow. ("
|
|
+ buffer.getLengthInBits()
|
|
+ ">"
|
|
+ totalDataCount * 8
|
|
+ ")");
|
|
}
|
|
|
|
// end code
|
|
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
|
|
buffer.put(0, 4);
|
|
}
|
|
|
|
// padding
|
|
while (buffer.getLengthInBits() % 8 != 0) {
|
|
buffer.putBit(false);
|
|
}
|
|
|
|
// padding
|
|
while (true) {
|
|
|
|
if (buffer.getLengthInBits() >= totalDataCount * 8) {
|
|
break;
|
|
}
|
|
buffer.put(QRCode.PAD0, 8);
|
|
|
|
if (buffer.getLengthInBits() >= totalDataCount * 8) {
|
|
break;
|
|
}
|
|
buffer.put(QRCode.PAD1, 8);
|
|
}
|
|
|
|
return QRCode.createBytes(buffer, rsBlocks);
|
|
};
|
|
|
|
QRCode.createBytes = function (buffer, rsBlocks) {
|
|
|
|
var offset = 0;
|
|
|
|
var maxDcCount = 0;
|
|
var maxEcCount = 0;
|
|
|
|
var dcdata = new Array(rsBlocks.length);
|
|
var ecdata = new Array(rsBlocks.length);
|
|
|
|
for (var r = 0; r < rsBlocks.length; r++) {
|
|
|
|
var dcCount = rsBlocks[r].dataCount;
|
|
var ecCount = rsBlocks[r].totalCount - dcCount;
|
|
|
|
maxDcCount = Math.max(maxDcCount, dcCount);
|
|
maxEcCount = Math.max(maxEcCount, ecCount);
|
|
|
|
dcdata[r] = new Array(dcCount);
|
|
|
|
for (var i = 0; i < dcdata[r].length; i++) {
|
|
dcdata[r][i] = 0xff & buffer.buffer[i + offset];
|
|
}
|
|
offset += dcCount;
|
|
|
|
var rsPoly = QRCode.Util.getErrorCorrectPolynomial(ecCount);
|
|
var rawPoly = new QRCode.Polynomial(dcdata[r], rsPoly.getLength() - 1);
|
|
|
|
var modPoly = rawPoly.mod(rsPoly);
|
|
ecdata[r] = new Array(rsPoly.getLength() - 1);
|
|
for (var i = 0; i < ecdata[r].length; i++) {
|
|
var modIndex = i + modPoly.getLength() - ecdata[r].length;
|
|
ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
|
|
}
|
|
|
|
}
|
|
|
|
var totalCodeCount = 0;
|
|
for (var i = 0; i < rsBlocks.length; i++) {
|
|
totalCodeCount += rsBlocks[i].totalCount;
|
|
}
|
|
|
|
var data = new Array(totalCodeCount);
|
|
var index = 0;
|
|
|
|
for (var i = 0; i < maxDcCount; i++) {
|
|
for (var r = 0; r < rsBlocks.length; r++) {
|
|
if (i < dcdata[r].length) {
|
|
data[index++] = dcdata[r][i];
|
|
}
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i < maxEcCount; i++) {
|
|
for (var r = 0; r < rsBlocks.length; r++) {
|
|
if (i < ecdata[r].length) {
|
|
data[index++] = ecdata[r][i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return data;
|
|
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
// QR8bitByte
|
|
//---------------------------------------------------------------------
|
|
QRCode.QR8bitByte = function (data) {
|
|
this.mode = QRCode.Mode.MODE_8BIT_BYTE;
|
|
this.data = data;
|
|
}
|
|
|
|
QRCode.QR8bitByte.prototype = {
|
|
getLength: function (buffer) {
|
|
return this.data.length;
|
|
},
|
|
|
|
write: function (buffer) {
|
|
for (var i = 0; i < this.data.length; i++) {
|
|
// not JIS ...
|
|
buffer.put(this.data.charCodeAt(i), 8);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRMode
|
|
//---------------------------------------------------------------------
|
|
QRCode.Mode = {
|
|
MODE_NUMBER: 1 << 0,
|
|
MODE_ALPHA_NUM: 1 << 1,
|
|
MODE_8BIT_BYTE: 1 << 2,
|
|
MODE_KANJI: 1 << 3
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRErrorCorrectLevel
|
|
//---------------------------------------------------------------------
|
|
QRCode.ErrorCorrectLevel = {
|
|
L: 1,
|
|
M: 0,
|
|
Q: 3,
|
|
H: 2
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRMaskPattern
|
|
//---------------------------------------------------------------------
|
|
QRCode.MaskPattern = {
|
|
PATTERN000: 0,
|
|
PATTERN001: 1,
|
|
PATTERN010: 2,
|
|
PATTERN011: 3,
|
|
PATTERN100: 4,
|
|
PATTERN101: 5,
|
|
PATTERN110: 6,
|
|
PATTERN111: 7
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRUtil
|
|
//---------------------------------------------------------------------
|
|
|
|
QRCode.Util = {
|
|
|
|
PATTERN_POSITION_TABLE: [
|
|
[],
|
|
[6, 18],
|
|
[6, 22],
|
|
[6, 26],
|
|
[6, 30],
|
|
[6, 34],
|
|
[6, 22, 38],
|
|
[6, 24, 42],
|
|
[6, 26, 46],
|
|
[6, 28, 50],
|
|
[6, 30, 54],
|
|
[6, 32, 58],
|
|
[6, 34, 62],
|
|
[6, 26, 46, 66],
|
|
[6, 26, 48, 70],
|
|
[6, 26, 50, 74],
|
|
[6, 30, 54, 78],
|
|
[6, 30, 56, 82],
|
|
[6, 30, 58, 86],
|
|
[6, 34, 62, 90],
|
|
[6, 28, 50, 72, 94],
|
|
[6, 26, 50, 74, 98],
|
|
[6, 30, 54, 78, 102],
|
|
[6, 28, 54, 80, 106],
|
|
[6, 32, 58, 84, 110],
|
|
[6, 30, 58, 86, 114],
|
|
[6, 34, 62, 90, 118],
|
|
[6, 26, 50, 74, 98, 122],
|
|
[6, 30, 54, 78, 102, 126],
|
|
[6, 26, 52, 78, 104, 130],
|
|
[6, 30, 56, 82, 108, 134],
|
|
[6, 34, 60, 86, 112, 138],
|
|
[6, 30, 58, 86, 114, 142],
|
|
[6, 34, 62, 90, 118, 146],
|
|
[6, 30, 54, 78, 102, 126, 150],
|
|
[6, 24, 50, 76, 102, 128, 154],
|
|
[6, 28, 54, 80, 106, 132, 158],
|
|
[6, 32, 58, 84, 110, 136, 162],
|
|
[6, 26, 54, 82, 110, 138, 166],
|
|
[6, 30, 58, 86, 114, 142, 170]
|
|
],
|
|
|
|
G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
|
|
G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
|
|
G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
|
|
|
|
getBCHTypeInfo: function (data) {
|
|
var d = data << 10;
|
|
while (QRCode.Util.getBCHDigit(d) - QRCode.Util.getBCHDigit(QRCode.Util.G15) >= 0) {
|
|
d ^= (QRCode.Util.G15 << (QRCode.Util.getBCHDigit(d) - QRCode.Util.getBCHDigit(QRCode.Util.G15)));
|
|
}
|
|
return ((data << 10) | d) ^ QRCode.Util.G15_MASK;
|
|
},
|
|
|
|
getBCHTypeNumber: function (data) {
|
|
var d = data << 12;
|
|
while (QRCode.Util.getBCHDigit(d) - QRCode.Util.getBCHDigit(QRCode.Util.G18) >= 0) {
|
|
d ^= (QRCode.Util.G18 << (QRCode.Util.getBCHDigit(d) - QRCode.Util.getBCHDigit(QRCode.Util.G18)));
|
|
}
|
|
return (data << 12) | d;
|
|
},
|
|
|
|
getBCHDigit: function (data) {
|
|
|
|
var digit = 0;
|
|
|
|
while (data != 0) {
|
|
digit++;
|
|
data >>>= 1;
|
|
}
|
|
|
|
return digit;
|
|
},
|
|
|
|
getPatternPosition: function (typeNumber) {
|
|
return QRCode.Util.PATTERN_POSITION_TABLE[typeNumber - 1];
|
|
},
|
|
|
|
getMask: function (maskPattern, i, j) {
|
|
|
|
switch (maskPattern) {
|
|
|
|
case QRCode.MaskPattern.PATTERN000: return (i + j) % 2 == 0;
|
|
case QRCode.MaskPattern.PATTERN001: return i % 2 == 0;
|
|
case QRCode.MaskPattern.PATTERN010: return j % 3 == 0;
|
|
case QRCode.MaskPattern.PATTERN011: return (i + j) % 3 == 0;
|
|
case QRCode.MaskPattern.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
|
|
case QRCode.MaskPattern.PATTERN101: return (i * j) % 2 + (i * j) % 3 == 0;
|
|
case QRCode.MaskPattern.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
|
|
case QRCode.MaskPattern.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
|
|
|
|
default:
|
|
throw new Error("bad maskPattern:" + maskPattern);
|
|
}
|
|
},
|
|
|
|
getErrorCorrectPolynomial: function (errorCorrectLength) {
|
|
|
|
var a = new QRCode.Polynomial([1], 0);
|
|
|
|
for (var i = 0; i < errorCorrectLength; i++) {
|
|
a = a.multiply(new QRCode.Polynomial([1, QRCode.Math.gexp(i)], 0));
|
|
}
|
|
|
|
return a;
|
|
},
|
|
|
|
getLengthInBits: function (mode, type) {
|
|
|
|
if (1 <= type && type < 10) {
|
|
|
|
// 1 - 9
|
|
|
|
switch (mode) {
|
|
case QRCode.Mode.MODE_NUMBER: return 10;
|
|
case QRCode.Mode.MODE_ALPHA_NUM: return 9;
|
|
case QRCode.Mode.MODE_8BIT_BYTE: return 8;
|
|
case QRCode.Mode.MODE_KANJI: return 8;
|
|
default:
|
|
throw new Error("mode:" + mode);
|
|
}
|
|
|
|
} else if (type < 27) {
|
|
|
|
// 10 - 26
|
|
|
|
switch (mode) {
|
|
case QRCode.Mode.MODE_NUMBER: return 12;
|
|
case QRCode.Mode.MODE_ALPHA_NUM: return 11;
|
|
case QRCode.Mode.MODE_8BIT_BYTE: return 16;
|
|
case QRCode.Mode.MODE_KANJI: return 10;
|
|
default:
|
|
throw new Error("mode:" + mode);
|
|
}
|
|
|
|
} else if (type < 41) {
|
|
|
|
// 27 - 40
|
|
|
|
switch (mode) {
|
|
case QRCode.Mode.MODE_NUMBER: return 14;
|
|
case QRCode.Mode.MODE_ALPHA_NUM: return 13;
|
|
case QRCode.Mode.MODE_8BIT_BYTE: return 16;
|
|
case QRCode.Mode.MODE_KANJI: return 12;
|
|
default:
|
|
throw new Error("mode:" + mode);
|
|
}
|
|
|
|
} else {
|
|
throw new Error("type:" + type);
|
|
}
|
|
},
|
|
|
|
getLostPoint: function (qrCode) {
|
|
|
|
var moduleCount = qrCode.getModuleCount();
|
|
|
|
var lostPoint = 0;
|
|
|
|
// LEVEL1
|
|
|
|
for (var row = 0; row < moduleCount; row++) {
|
|
|
|
for (var col = 0; col < moduleCount; col++) {
|
|
|
|
var sameCount = 0;
|
|
var dark = qrCode.isDark(row, col);
|
|
|
|
for (var r = -1; r <= 1; r++) {
|
|
|
|
if (row + r < 0 || moduleCount <= row + r) {
|
|
continue;
|
|
}
|
|
|
|
for (var c = -1; c <= 1; c++) {
|
|
|
|
if (col + c < 0 || moduleCount <= col + c) {
|
|
continue;
|
|
}
|
|
|
|
if (r == 0 && c == 0) {
|
|
continue;
|
|
}
|
|
|
|
if (dark == qrCode.isDark(row + r, col + c)) {
|
|
sameCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sameCount > 5) {
|
|
lostPoint += (3 + sameCount - 5);
|
|
}
|
|
}
|
|
}
|
|
|
|
// LEVEL2
|
|
|
|
for (var row = 0; row < moduleCount - 1; row++) {
|
|
for (var col = 0; col < moduleCount - 1; col++) {
|
|
var count = 0;
|
|
if (qrCode.isDark(row, col)) count++;
|
|
if (qrCode.isDark(row + 1, col)) count++;
|
|
if (qrCode.isDark(row, col + 1)) count++;
|
|
if (qrCode.isDark(row + 1, col + 1)) count++;
|
|
if (count == 0 || count == 4) {
|
|
lostPoint += 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
// LEVEL3
|
|
|
|
for (var row = 0; row < moduleCount; row++) {
|
|
for (var col = 0; col < moduleCount - 6; col++) {
|
|
if (qrCode.isDark(row, col)
|
|
&& !qrCode.isDark(row, col + 1)
|
|
&& qrCode.isDark(row, col + 2)
|
|
&& qrCode.isDark(row, col + 3)
|
|
&& qrCode.isDark(row, col + 4)
|
|
&& !qrCode.isDark(row, col + 5)
|
|
&& qrCode.isDark(row, col + 6)) {
|
|
lostPoint += 40;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (var col = 0; col < moduleCount; col++) {
|
|
for (var row = 0; row < moduleCount - 6; row++) {
|
|
if (qrCode.isDark(row, col)
|
|
&& !qrCode.isDark(row + 1, col)
|
|
&& qrCode.isDark(row + 2, col)
|
|
&& qrCode.isDark(row + 3, col)
|
|
&& qrCode.isDark(row + 4, col)
|
|
&& !qrCode.isDark(row + 5, col)
|
|
&& qrCode.isDark(row + 6, col)) {
|
|
lostPoint += 40;
|
|
}
|
|
}
|
|
}
|
|
|
|
// LEVEL4
|
|
|
|
var darkCount = 0;
|
|
|
|
for (var col = 0; col < moduleCount; col++) {
|
|
for (var row = 0; row < moduleCount; row++) {
|
|
if (qrCode.isDark(row, col)) {
|
|
darkCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
|
|
lostPoint += ratio * 10;
|
|
|
|
return lostPoint;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRMath
|
|
//---------------------------------------------------------------------
|
|
|
|
QRCode.Math = {
|
|
|
|
glog: function (n) {
|
|
|
|
if (n < 1) {
|
|
throw new Error("glog(" + n + ")");
|
|
}
|
|
|
|
return QRCode.Math.LOG_TABLE[n];
|
|
},
|
|
|
|
gexp: function (n) {
|
|
|
|
while (n < 0) {
|
|
n += 255;
|
|
}
|
|
|
|
while (n >= 256) {
|
|
n -= 255;
|
|
}
|
|
|
|
return QRCode.Math.EXP_TABLE[n];
|
|
},
|
|
|
|
EXP_TABLE: new Array(256),
|
|
|
|
LOG_TABLE: new Array(256)
|
|
|
|
};
|
|
|
|
for (var i = 0; i < 8; i++) {
|
|
QRCode.Math.EXP_TABLE[i] = 1 << i;
|
|
}
|
|
for (var i = 8; i < 256; i++) {
|
|
QRCode.Math.EXP_TABLE[i] = QRCode.Math.EXP_TABLE[i - 4]
|
|
^ QRCode.Math.EXP_TABLE[i - 5]
|
|
^ QRCode.Math.EXP_TABLE[i - 6]
|
|
^ QRCode.Math.EXP_TABLE[i - 8];
|
|
}
|
|
for (var i = 0; i < 255; i++) {
|
|
QRCode.Math.LOG_TABLE[QRCode.Math.EXP_TABLE[i]] = i;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRPolynomial
|
|
//---------------------------------------------------------------------
|
|
|
|
QRCode.Polynomial = function (num, shift) {
|
|
|
|
if (num.length == undefined) {
|
|
throw new Error(num.length + "/" + shift);
|
|
}
|
|
|
|
var offset = 0;
|
|
|
|
while (offset < num.length && num[offset] == 0) {
|
|
offset++;
|
|
}
|
|
|
|
this.num = new Array(num.length - offset + shift);
|
|
for (var i = 0; i < num.length - offset; i++) {
|
|
this.num[i] = num[i + offset];
|
|
}
|
|
}
|
|
|
|
QRCode.Polynomial.prototype = {
|
|
|
|
get: function (index) {
|
|
return this.num[index];
|
|
},
|
|
|
|
getLength: function () {
|
|
return this.num.length;
|
|
},
|
|
|
|
multiply: function (e) {
|
|
|
|
var num = new Array(this.getLength() + e.getLength() - 1);
|
|
|
|
for (var i = 0; i < this.getLength(); i++) {
|
|
for (var j = 0; j < e.getLength(); j++) {
|
|
num[i + j] ^= QRCode.Math.gexp(QRCode.Math.glog(this.get(i)) + QRCode.Math.glog(e.get(j)));
|
|
}
|
|
}
|
|
|
|
return new QRCode.Polynomial(num, 0);
|
|
},
|
|
|
|
mod: function (e) {
|
|
|
|
if (this.getLength() - e.getLength() < 0) {
|
|
return this;
|
|
}
|
|
|
|
var ratio = QRCode.Math.glog(this.get(0)) - QRCode.Math.glog(e.get(0));
|
|
|
|
var num = new Array(this.getLength());
|
|
|
|
for (var i = 0; i < this.getLength(); i++) {
|
|
num[i] = this.get(i);
|
|
}
|
|
|
|
for (var i = 0; i < e.getLength(); i++) {
|
|
num[i] ^= QRCode.Math.gexp(QRCode.Math.glog(e.get(i)) + ratio);
|
|
}
|
|
|
|
// recursive call
|
|
return new QRCode.Polynomial(num, 0).mod(e);
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRRSBlock
|
|
//---------------------------------------------------------------------
|
|
|
|
QRCode.RSBlock = function (totalCount, dataCount) {
|
|
this.totalCount = totalCount;
|
|
this.dataCount = dataCount;
|
|
}
|
|
|
|
QRCode.RSBlock.RS_BLOCK_TABLE = [
|
|
|
|
// L
|
|
// M
|
|
// Q
|
|
// H
|
|
|
|
// 1
|
|
[1, 26, 19],
|
|
[1, 26, 16],
|
|
[1, 26, 13],
|
|
[1, 26, 9],
|
|
|
|
// 2
|
|
[1, 44, 34],
|
|
[1, 44, 28],
|
|
[1, 44, 22],
|
|
[1, 44, 16],
|
|
|
|
// 3
|
|
[1, 70, 55],
|
|
[1, 70, 44],
|
|
[2, 35, 17],
|
|
[2, 35, 13],
|
|
|
|
// 4
|
|
[1, 100, 80],
|
|
[2, 50, 32],
|
|
[2, 50, 24],
|
|
[4, 25, 9],
|
|
|
|
// 5
|
|
[1, 134, 108],
|
|
[2, 67, 43],
|
|
[2, 33, 15, 2, 34, 16],
|
|
[2, 33, 11, 2, 34, 12],
|
|
|
|
// 6
|
|
[2, 86, 68],
|
|
[4, 43, 27],
|
|
[4, 43, 19],
|
|
[4, 43, 15],
|
|
|
|
// 7
|
|
[2, 98, 78],
|
|
[4, 49, 31],
|
|
[2, 32, 14, 4, 33, 15],
|
|
[4, 39, 13, 1, 40, 14],
|
|
|
|
// 8
|
|
[2, 121, 97],
|
|
[2, 60, 38, 2, 61, 39],
|
|
[4, 40, 18, 2, 41, 19],
|
|
[4, 40, 14, 2, 41, 15],
|
|
|
|
// 9
|
|
[2, 146, 116],
|
|
[3, 58, 36, 2, 59, 37],
|
|
[4, 36, 16, 4, 37, 17],
|
|
[4, 36, 12, 4, 37, 13],
|
|
|
|
// 10
|
|
[2, 86, 68, 2, 87, 69],
|
|
[4, 69, 43, 1, 70, 44],
|
|
[6, 43, 19, 2, 44, 20],
|
|
[6, 43, 15, 2, 44, 16]
|
|
|
|
];
|
|
|
|
QRCode.RSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) {
|
|
|
|
var rsBlock = QRCode.RSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
|
|
|
|
if (rsBlock == undefined) {
|
|
throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
|
|
}
|
|
|
|
var length = rsBlock.length / 3;
|
|
|
|
var list = new Array();
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
|
|
var count = rsBlock[i * 3 + 0];
|
|
var totalCount = rsBlock[i * 3 + 1];
|
|
var dataCount = rsBlock[i * 3 + 2];
|
|
|
|
for (var j = 0; j < count; j++) {
|
|
list.push(new QRCode.RSBlock(totalCount, dataCount));
|
|
}
|
|
}
|
|
|
|
return list;
|
|
};
|
|
|
|
QRCode.RSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) {
|
|
|
|
switch (errorCorrectLevel) {
|
|
case QRCode.ErrorCorrectLevel.L:
|
|
return QRCode.RSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
|
|
case QRCode.ErrorCorrectLevel.M:
|
|
return QRCode.RSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
|
|
case QRCode.ErrorCorrectLevel.Q:
|
|
return QRCode.RSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
|
|
case QRCode.ErrorCorrectLevel.H:
|
|
return QRCode.RSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
|
|
default:
|
|
return undefined;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
// QRBitBuffer
|
|
//---------------------------------------------------------------------
|
|
|
|
QRCode.BitBuffer = function () {
|
|
this.buffer = new Array();
|
|
this.length = 0;
|
|
}
|
|
|
|
QRCode.BitBuffer.prototype = {
|
|
|
|
get: function (index) {
|
|
var bufIndex = Math.floor(index / 8);
|
|
return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
|
|
},
|
|
|
|
put: function (num, length) {
|
|
for (var i = 0; i < length; i++) {
|
|
this.putBit(((num >>> (length - i - 1)) & 1) == 1);
|
|
}
|
|
},
|
|
|
|
getLengthInBits: function () {
|
|
return this.length;
|
|
},
|
|
|
|
putBit: function (bit) {
|
|
|
|
var bufIndex = Math.floor(this.length / 8);
|
|
if (this.buffer.length <= bufIndex) {
|
|
this.buffer.push(0);
|
|
}
|
|
|
|
if (bit) {
|
|
this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
|
|
}
|
|
|
|
this.length++;
|
|
}
|
|
};
|
|
})();
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
var Bitcoin = {};
|
|
|
|
(function () {
|
|
var B58 = Bitcoin.Base58 = {
|
|
alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
|
|
base: BigInteger.valueOf(58),
|
|
|
|
/**
|
|
* Convert a byte array to a base58-encoded string.
|
|
*
|
|
* Written by Mike Hearn for BitcoinJ.
|
|
* Copyright (c) 2011 Google Inc.
|
|
*
|
|
* Ported to JavaScript by Stefan Thomas.
|
|
*/
|
|
encode: function (input) {
|
|
var bi = BigInteger.fromByteArrayUnsigned(input);
|
|
var chars = [];
|
|
|
|
while (bi.compareTo(B58.base) >= 0) {
|
|
var mod = bi.mod(B58.base);
|
|
chars.unshift(B58.alphabet[mod.intValue()]);
|
|
bi = bi.subtract(mod).divide(B58.base);
|
|
}
|
|
chars.unshift(B58.alphabet[bi.intValue()]);
|
|
|
|
// Convert leading zeros too.
|
|
for (var i = 0; i < input.length; i++) {
|
|
if (input[i] == 0x00) {
|
|
chars.unshift(B58.alphabet[0]);
|
|
} else break;
|
|
}
|
|
|
|
s = chars.join('');
|
|
return s;
|
|
},
|
|
|
|
/**
|
|
* Convert a base58-encoded string to a byte array.
|
|
*
|
|
* Written by Mike Hearn for BitcoinJ.
|
|
* Copyright (c) 2011 Google Inc.
|
|
*
|
|
* Ported to JavaScript by Stefan Thomas.
|
|
*/
|
|
decode: function (input) {
|
|
bi = BigInteger.valueOf(0);
|
|
var leadingZerosNum = 0;
|
|
for (var i = input.length - 1; i >= 0; i--) {
|
|
var alphaIndex = B58.alphabet.indexOf(input[i]);
|
|
bi = bi.add(BigInteger.valueOf(alphaIndex)
|
|
.multiply(B58.base.pow(input.length - 1 - i)));
|
|
|
|
// This counts leading zero bytes
|
|
if (input[i] == "1") leadingZerosNum++;
|
|
else leadingZerosNum = 0;
|
|
}
|
|
var bytes = bi.toByteArrayUnsigned();
|
|
|
|
// Add leading zeros
|
|
while (leadingZerosNum-- > 0) bytes.unshift(0);
|
|
|
|
return bytes;
|
|
}
|
|
};
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
Bitcoin.Address = function (bytes) {
|
|
if ("string" == typeof bytes) {
|
|
bytes = Bitcoin.Address.decodeString(bytes);
|
|
}
|
|
this.hash = bytes;
|
|
this.version = Bitcoin.Address.networkVersion;
|
|
};
|
|
|
|
Bitcoin.Address.networkVersion = 0x00; // mainnet
|
|
|
|
Bitcoin.Address.prototype.toString = function () {
|
|
// Get a copy of the hash
|
|
var hash = this.hash.slice(0);
|
|
|
|
// Version
|
|
hash.unshift(this.version);
|
|
var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
|
|
var bytes = hash.concat(checksum.slice(0, 4));
|
|
return Bitcoin.Base58.encode(bytes);
|
|
};
|
|
|
|
Bitcoin.Address.prototype.getHashBase64 = function () {
|
|
return Crypto.util.bytesToBase64(this.hash);
|
|
};
|
|
|
|
Bitcoin.Address.decodeString = function (string) {
|
|
var bytes = Bitcoin.Base58.decode(string);
|
|
var hash = bytes.slice(0, 21);
|
|
var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
|
|
|
|
if (checksum[0] != bytes[21] ||
|
|
checksum[1] != bytes[22] ||
|
|
checksum[2] != bytes[23] ||
|
|
checksum[3] != bytes[24]) {
|
|
throw "Checksum validation failed!";
|
|
}
|
|
|
|
var version = hash.shift();
|
|
|
|
if (version != 0) {
|
|
throw "Version " + version + " not supported!";
|
|
}
|
|
|
|
return hash;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bitcoin.ECDSA = (function () {
|
|
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
|
|
var rng = new SecureRandom();
|
|
|
|
function implShamirsTrick(P, k, Q, l) {
|
|
var m = Math.max(k.bitLength(), l.bitLength());
|
|
var Z = P.add2D(Q);
|
|
var R = P.curve.getInfinity();
|
|
|
|
for (var i = m - 1; i >= 0; --i) {
|
|
R = R.twice2D();
|
|
|
|
R.z = BigInteger.ONE;
|
|
|
|
if (k.testBit(i)) {
|
|
if (l.testBit(i)) {
|
|
R = R.add2D(Z);
|
|
} else {
|
|
R = R.add2D(P);
|
|
}
|
|
} else {
|
|
if (l.testBit(i)) {
|
|
R = R.add2D(Q);
|
|
}
|
|
}
|
|
}
|
|
|
|
return R;
|
|
};
|
|
|
|
var ECDSA = {
|
|
getBigRandom: function (limit) {
|
|
return new BigInteger(limit.bitLength(), rng)
|
|
.mod(limit.subtract(BigInteger.ONE))
|
|
.add(BigInteger.ONE);
|
|
},
|
|
sign: function (hash, priv) {
|
|
var d = priv;
|
|
var n = ecparams.getN();
|
|
var e = BigInteger.fromByteArrayUnsigned(hash);
|
|
|
|
do {
|
|
var k = ECDSA.getBigRandom(n);
|
|
var G = ecparams.getG();
|
|
var Q = G.multiply(k);
|
|
var r = Q.getX().toBigInteger().mod(n);
|
|
} while (r.compareTo(BigInteger.ZERO) <= 0);
|
|
|
|
var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
|
|
|
|
return ECDSA.serializeSig(r, s);
|
|
},
|
|
|
|
serializeSig: function (r, s) {
|
|
var rBa = r.toByteArrayUnsigned();
|
|
var sBa = s.toByteArrayUnsigned();
|
|
|
|
var sequence = [];
|
|
sequence.push(0x02); // INTEGER
|
|
sequence.push(rBa.length);
|
|
sequence = sequence.concat(rBa);
|
|
|
|
sequence.push(0x02); // INTEGER
|
|
sequence.push(sBa.length);
|
|
sequence = sequence.concat(sBa);
|
|
|
|
sequence.unshift(sequence.length);
|
|
sequence.unshift(0x30) // SEQUENCE
|
|
|
|
return sequence;
|
|
},
|
|
|
|
verify: function (hash, sig, pubkey) {
|
|
var obj = ECDSA.parseSig(sig);
|
|
var r = obj.r;
|
|
var s = obj.s;
|
|
|
|
var n = ecparams.getN();
|
|
var e = BigInteger.fromByteArrayUnsigned(hash);
|
|
|
|
if (r.compareTo(BigInteger.ONE) < 0 ||
|
|
r.compareTo(n) >= 0)
|
|
return false;
|
|
|
|
if (s.compareTo(BigInteger.ONE) < 0 ||
|
|
s.compareTo(n) >= 0)
|
|
return false;
|
|
|
|
var c = s.modInverse(n);
|
|
|
|
var u1 = e.multiply(c).mod(n);
|
|
var u2 = r.multiply(c).mod(n);
|
|
|
|
var G = ecparams.getG();
|
|
var Q = ECPointFp.decodeFrom(ecparams.getCurve(), pubkey);
|
|
|
|
var point = implShamirsTrick(G, u1, Q, u2);
|
|
|
|
var v = point.x.toBigInteger().mod(n);
|
|
|
|
return v.equals(r);
|
|
},
|
|
|
|
parseSig: function (sig) {
|
|
var cursor;
|
|
if (sig[0] != 0x30)
|
|
throw new Error("Signature not a valid DERSequence");
|
|
|
|
cursor = 2;
|
|
if (sig[cursor] != 0x02)
|
|
throw new Error("First element in signature must be a DERInteger"); ;
|
|
var rBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]);
|
|
|
|
cursor += 2 + sig[cursor + 1];
|
|
if (sig[cursor] != 0x02)
|
|
throw new Error("Second element in signature must be a DERInteger");
|
|
var sBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]);
|
|
|
|
cursor += 2 + sig[cursor + 1];
|
|
|
|
//if (cursor != sig.length)
|
|
// throw new Error("Extra bytes in signature");
|
|
|
|
var r = BigInteger.fromByteArrayUnsigned(rBa);
|
|
var s = BigInteger.fromByteArrayUnsigned(sBa);
|
|
|
|
return { r: r, s: s };
|
|
}
|
|
};
|
|
|
|
return ECDSA;
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bitcoin.ECKey = (function () {
|
|
var ECDSA = Bitcoin.ECDSA;
|
|
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
|
|
var rng = new SecureRandom();
|
|
|
|
var ECKey = function (input) {
|
|
if (!input) {
|
|
// Generate new key
|
|
var n = ecparams.getN();
|
|
this.priv = ECDSA.getBigRandom(n);
|
|
} else if (input instanceof BigInteger) {
|
|
// Input is a private key value
|
|
this.priv = input;
|
|
} else if (Bitcoin.Util.isArray(input)) {
|
|
// Prepend zero byte to prevent interpretation as negative integer
|
|
this.priv = BigInteger.fromByteArrayUnsigned(input);
|
|
} else if ("string" == typeof input) {
|
|
// Prepend zero byte to prevent interpretation as negative integer
|
|
this.priv = BigInteger.fromByteArrayUnsigned(Crypto.util.base64ToBytes(input));
|
|
}
|
|
};
|
|
|
|
ECKey.privateKeyPrefix = 0x80; // mainnet
|
|
|
|
ECKey.prototype.getPub = function () {
|
|
if (this.pub) return this.pub;
|
|
return this.pub = ecparams.getG().multiply(this.priv).getEncoded(0);
|
|
};
|
|
|
|
ECKey.prototype.getPubCompressed = function () {
|
|
if (this.pubCompressed) return this.pubCompressed;
|
|
return this.pubCompressed = ecparams.getG().multiply(this.priv).getEncoded(1);
|
|
};
|
|
|
|
ECKey.prototype.getPubKeyHash = function () {
|
|
if (this.pubKeyHash) return this.pubKeyHash;
|
|
return this.pubKeyHash = Bitcoin.Util.sha256ripe160(this.getPub());
|
|
};
|
|
|
|
ECKey.prototype.getPubKeyHashCompressed = function () {
|
|
if (this.pubKeyHashCompressed) return this.pubKeyHashCompressed;
|
|
return this.pubKeyHashCompressed = Bitcoin.Util.sha256ripe160(this.getPubCompressed());
|
|
};
|
|
|
|
ECKey.prototype.getBitcoinAddress = function () {
|
|
var hash = this.getPubKeyHash();
|
|
var addr = new Bitcoin.Address(hash);
|
|
return addr.toString();
|
|
};
|
|
|
|
ECKey.prototype.getBitcoinAddressCompressed = function () {
|
|
var hash = this.getPubKeyHashCompressed();
|
|
var addr = new Bitcoin.Address(hash);
|
|
return addr.toString();
|
|
};
|
|
|
|
// Sipa Private Key Wallet Import Format
|
|
ECKey.prototype.getBitcoinWalletImportFormat = function () {
|
|
var bytes = this.getBitcoinPrivateKeyByteArray();
|
|
bytes.unshift(ECKey.privateKeyPrefix); // prepend 0x80 byte
|
|
var checksum = Crypto.SHA256(Crypto.SHA256(bytes, { asBytes: true }), { asBytes: true });
|
|
bytes = bytes.concat(checksum.slice(0, 4));
|
|
var privWif = Bitcoin.Base58.encode(bytes);
|
|
return privWif;
|
|
};
|
|
|
|
// Sipa Private Key Wallet Import Format Compressed
|
|
ECKey.prototype.getBitcoinWalletImportFormatCompressed = function () {
|
|
var bytes = this.getBitcoinPrivateKeyByteArray();
|
|
bytes.unshift(ECKey.privateKeyPrefix); // prepend 0x80 byte
|
|
bytes.push(0x01); // append 0x01 byte for compressed format
|
|
var checksum = Crypto.SHA256(Crypto.SHA256(bytes, { asBytes: true }), { asBytes: true });
|
|
bytes = bytes.concat(checksum.slice(0, 4));
|
|
var privWifComp = Bitcoin.Base58.encode(bytes);
|
|
return privWifComp;
|
|
};
|
|
|
|
// Private Key Hex Format
|
|
ECKey.prototype.getBitcoinHexFormat = function () {
|
|
return Crypto.util.bytesToHex(this.getBitcoinPrivateKeyByteArray()).toString().toUpperCase();
|
|
};
|
|
|
|
// Private Key Base64 Format
|
|
ECKey.prototype.getBitcoinBase64Format = function () {
|
|
return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray());
|
|
};
|
|
|
|
ECKey.prototype.getBitcoinPrivateKeyByteArray = function () {
|
|
// Get a copy of private key as a byte array
|
|
var bytes = this.priv.toByteArrayUnsigned();
|
|
// zero pad if private key is less than 32 bytes
|
|
while (bytes.length < 32) bytes.unshift(0x00);
|
|
return bytes;
|
|
};
|
|
|
|
ECKey.prototype.setPub = function (pub) {
|
|
this.pub = pub;
|
|
};
|
|
|
|
ECKey.prototype.setPubCompressed = function (pubCompressed) {
|
|
this.pubCompressed = pubCompressed;
|
|
};
|
|
|
|
ECKey.prototype.toString = function (format) {
|
|
format = format || "";
|
|
|
|
if (format.toString().toLowerCase() == "base64" || format.toString().toLowerCase() == "b64") {
|
|
return this.getBitcoinBase64Format();
|
|
}
|
|
// Wallet Import Format
|
|
else if (format.toString().toLowerCase() == "wif") {
|
|
return this.getBitcoinWalletImportFormat();
|
|
}
|
|
else if (format.toString().toLowerCase() == "wifcomp") {
|
|
return this.getBitcoinWalletImportFormatCompressed();
|
|
}
|
|
else {
|
|
return this.getBitcoinHexFormat();
|
|
}
|
|
};
|
|
|
|
ECKey.prototype.sign = function (hash) {
|
|
return ECDSA.sign(hash, this.priv);
|
|
};
|
|
|
|
ECKey.prototype.verify = function (hash, sig) {
|
|
return ECDSA.verify(hash, sig, this.getPub());
|
|
};
|
|
|
|
return ECKey;
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Bitcoin utility functions
|
|
Bitcoin.Util = {
|
|
isArray: Array.isArray || function (o) {
|
|
return Object.prototype.toString.call(o) === '[object Array]';
|
|
},
|
|
makeFilledArray: function (len, val) {
|
|
var array = [];
|
|
var i = 0;
|
|
while (i < len) {
|
|
array[i++] = val;
|
|
}
|
|
return array;
|
|
},
|
|
numToVarInt: function (i) {
|
|
// TODO: THIS IS TOTALLY UNTESTED!
|
|
if (i < 0xfd) {
|
|
// unsigned char
|
|
return [i];
|
|
} else if (i <= 1 << 16) {
|
|
// unsigned short (LE)
|
|
return [0xfd, i >>> 8, i & 255];
|
|
} else if (i <= 1 << 32) {
|
|
// unsigned int (LE)
|
|
return [0xfe].concat(Crypto.util.wordsToBytes([i]));
|
|
} else {
|
|
// unsigned long long (LE)
|
|
return [0xff].concat(Crypto.util.wordsToBytes([i >>> 32, i]));
|
|
}
|
|
},
|
|
valueToBigInt: function (valueBuffer) {
|
|
if (valueBuffer instanceof BigInteger) return valueBuffer;
|
|
|
|
// Prepend zero byte to prevent interpretation as negative integer
|
|
return BigInteger.fromByteArrayUnsigned(valueBuffer);
|
|
},
|
|
formatValue: function (valueBuffer) {
|
|
var value = this.valueToBigInt(valueBuffer).toString();
|
|
var integerPart = value.length > 8 ? value.substr(0, value.length - 8) : '0';
|
|
var decimalPart = value.length > 8 ? value.substr(value.length - 8) : value;
|
|
while (decimalPart.length < 8) decimalPart = "0" + decimalPart;
|
|
decimalPart = decimalPart.replace(/0*$/, '');
|
|
while (decimalPart.length < 2) decimalPart += "0";
|
|
return integerPart + "." + decimalPart;
|
|
},
|
|
parseValue: function (valueString) {
|
|
var valueComp = valueString.split('.');
|
|
var integralPart = valueComp[0];
|
|
var fractionalPart = valueComp[1] || "0";
|
|
while (fractionalPart.length < 8) fractionalPart += "0";
|
|
fractionalPart = fractionalPart.replace(/^0+/g, '');
|
|
var value = BigInteger.valueOf(parseInt(integralPart));
|
|
value = value.multiply(BigInteger.valueOf(100000000));
|
|
value = value.add(BigInteger.valueOf(parseInt(fractionalPart)));
|
|
return value;
|
|
},
|
|
sha256ripe160: function (data) {
|
|
return Crypto.RIPEMD160(Crypto.SHA256(data, { asBytes: true }), { asBytes: true });
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style type="text/css">
|
|
#main { font-family: Arial; position: relative; text-align: center; margin: 0px auto; width: 795px; }
|
|
#logo { width: 578px; height: 80px; }
|
|
.right { text-align: right; }
|
|
.keyarea { font-family: Courier New; height: 110px; text-align: left; position: relative; padding: 5px; }
|
|
.keyarea .public { float: left; }
|
|
.keyarea .pubaddress { display: inline-block; height: 40px; padding: 0 0 0 10px; float: left; }
|
|
.keyarea .privwif { margin: 0; float: right; text-align: right; padding: 0 10px 0 0; position: relative; }
|
|
.keyarea .label { text-decoration: underline; }
|
|
.keyarea .output { display: block; }
|
|
.keyarea .qrcode_public { display: inline-block; float: left; }
|
|
.keyarea .qrcode_private { display: inline-block; position: relative; top: 28px; float: right; }
|
|
#faqs ol { padding: 0 0 0 25px; }
|
|
#faqs li { padding: 3px 0; }
|
|
|
|
#singlearea { border: 2px solid green; }
|
|
#singlearea #keyarea { display: none; }
|
|
#singlearea #generate { font-family: Courier New; height: 110px; text-align: left; position: relative; padding: 5px; }
|
|
#singlearea #generate span { padding: 5px 5px 0 5px; }
|
|
#paperarea { min-height: 120px; display: none; }
|
|
#paperarea .keyarea { border: 2px solid green; border-top: 0; }
|
|
#paperarea .keyarea.art { display: block; height: auto; border: 0; font-family: Ubuntu, Arial; padding: 0; margin: 0; }
|
|
#paperarea .artwallet .papersvg { width: 486px; height: 261px; border: 0; margin: 0; padding: 0; left: 0; }
|
|
#paperarea .artwallet .qrcode_public { top: 55px; left: 17px; z-index: 100; margin: 0; float: none; display: block; position: absolute; background-color: #FFFFFF;
|
|
padding: 5px 5px 2px 5px; }
|
|
#paperarea .artwallet .qrcode_private { top: 108px; left: 360px; z-index: 100; margin: 0; float: none; display: block; position: absolute; background-color: #FFFFFF;
|
|
padding: 5px 5px 2px 5px; }
|
|
#paperarea .artwallet .btcaddress
|
|
{
|
|
position: absolute; top: 240px; left: 139px; z-index: 100; font-size: 10px; background-color: transparent;
|
|
font-weight:bold; color: #8e6502; margin: 0;
|
|
-webkit-transform-origin:top left; -webkit-transform:rotate(-90deg);
|
|
-moz-transform-origin:top left; -moz-transform:rotate(-90deg);
|
|
-ms-transform-origin:top left; -ms-transform:rotate(-90deg);
|
|
-o-transform-origin:top left; -o-transform:rotate(-90deg);
|
|
transform-origin:top left; transform:rotate(-90deg);
|
|
}
|
|
#paperarea .artwallet .btcprivwif
|
|
{
|
|
position: absolute; top: 236px; left: 346px; z-index: 100; font-size: 7px; background-color: transparent;
|
|
font-weight:bold; color: #8e6502; margin: 0;
|
|
-webkit-transform-origin:top left; -webkit-transform:rotate(-90deg);
|
|
-moz-transform-origin:top left; -moz-transform:rotate(-90deg);
|
|
-ms-transform-origin:top left; -ms-transform:rotate(-90deg);
|
|
-o-transform-origin:top left; -o-transform:rotate(-90deg);
|
|
transform-origin:top left; transform:rotate(-90deg);
|
|
}
|
|
#bulkarea { display: none; padding: 4px 0 0 0; border: 2px solid green; }
|
|
#bulkarea .label { text-decoration: none; }
|
|
#bulkarea .format { font-style: italic; font-size: 90%; }
|
|
#bulktextarea { font-size: 90%; width: 98%; margin: 4px 0 0 0; }
|
|
#brainarea { display: none; border: 2px solid green; min-height: 120px; }
|
|
#brainarea .keyarea { display: none; }
|
|
#detailarea { display: none; margin: 0; padding: 10px; border: 2px solid green; text-align: left; }
|
|
#detailarea .notes { text-align: left; font-size: 80%; padding: 0 0 20px 0; }
|
|
#detailarea .item { margin: 10px 0; position: relative; }
|
|
#detailarea .label { display: block; text-decoration: underline; }
|
|
#detailarea .output { display: block; min-height: 20px; }
|
|
#detailarea #detailqrcodepublic { position: relative; float: left; margin: 0 10px 0 0; }
|
|
#detailarea #detailqrcodepubliccomp { position: relative; float: right; margin: 0 0 0 10px; }
|
|
#detailarea #detailqrcodeprivate { position: relative; float: left; margin: 0 10px 0 0; }
|
|
#detailarea #detailqrcodeprivatecomp { position: relative; float: right; margin: 0 0 0 10px; }
|
|
#vanityarea { display: none; border: 2px solid green; text-align: left; }
|
|
#vanityarea .label { text-decoration: underline; }
|
|
#vanityarea .output { display: block; }
|
|
#vanityarea .notes { text-align: left; font-size: 80%; padding: 0 0 20px 0; }
|
|
#vanitystep1area { display: none; text-align: left; position: relative; padding: 15px; border-bottom: 2px solid green; }
|
|
#vanitystep1label { padding-left: 5px; }
|
|
#vanitystep2area { border-top: 2px solid green; display: block; padding: 15px; }
|
|
#vanitystep2inputs { padding: 0 15px 10px 15px; }
|
|
#vanitypubkey { word-wrap: break-word; }
|
|
|
|
#bulkfaqs { display: none; }
|
|
.bulkquestion { padding: 10px 15px; text-align: left; cursor: pointer; }
|
|
#commands .expandable { padding: 10px 15px; }
|
|
.expandable { padding: 15px 15px; text-align: left; cursor: pointer; }
|
|
.bulkquestion:hover, .expandable:hover { color: #77777A; }
|
|
.bulkanswer { padding: 0 15px 10px 25px; text-align: left; display: none; font-size: 80%; }
|
|
.bulkfaq { border: 2px solid green; border-top: 0; }
|
|
|
|
#testnet { font-family: Tahoma; display: none; background-color: Orange; color: #000000; border-radius: 5px; font-weight: bold; padding: 10px 0; margin: 0 auto 20px auto; }
|
|
|
|
/* IE8 */
|
|
.qrcodetable { border-width: 0px; border-style: none; border-color: #0000ff; border-collapse: collapse; }
|
|
.qrcodetddark { border-width: 0px; border-style: none; border-color: #0000ff; border-collapse: collapse; padding: 0; margin: 0; width: 2px; height: 2px; background-color: #000000; }
|
|
.qrcodetdlight { border-width: 0px; border-style: none; border-color: #0000ff; border-collapse: collapse; padding: 0; margin: 0; width: 2px; height: 2px; background-color: #ffffff; }
|
|
|
|
@media screen
|
|
{
|
|
#tagline { margin: 0 0 15px 0; font-style: italic; }
|
|
.menu { text-align: left; }
|
|
.menu .tab { border-top-left-radius: 5px; border-top-right-radius: 5px; display: inline-block; background-color: #6C8C6C;
|
|
border: 2px solid green; padding: 5px; margin: 0 2px 0 0; position: relative; top: 2px; z-index: 110; cursor: pointer; }
|
|
.menu .tab:hover { color: #FFF; }
|
|
.menu .tab.selected { background-color: #FFF; border-bottom: 2px solid #FFF; cursor: default; }
|
|
.menu .tab.selected:hover { color: #000; }
|
|
.pagebreak { height: 50px; }
|
|
#commands { padding: 0; border: 2px solid green; border-bottom: 0; }
|
|
#commands span { padding: 0 10px; }
|
|
#commands span.print { float: right; }
|
|
#commands span.right { float: right; }
|
|
#singlecommands { visibility: hidden; padding: 10px 0; }
|
|
#bulkcommands { display: none; padding: 10px 0; }
|
|
#papercommands { display: none; padding: 10px 0; }
|
|
#braincommands { display: none; padding: 10px 0; }
|
|
#braincommands .row { text-align: left; }
|
|
#braincommands .row .label { width: 150px; display: inline-block; }
|
|
#braincommands .row.extra { padding: 6px 0 0 0; }
|
|
#braincommands .notes { font-size: 80%; display: block; padding: 5px 10px; }
|
|
#brainpassphrase { width: 280px; }
|
|
#brainpassphraseconfirm { width: 280px; }
|
|
#detailcommands { display: none; padding: 10px 0; }
|
|
#detailcommands span { padding: 0 10px; }
|
|
#detailprivkey { width: 250px; }
|
|
#vanitycommands { display: none; padding: 0; }
|
|
#vanitycommands span { padding: 0px; }
|
|
|
|
.paper #commands { border-bottom: 2px solid green; padding: 0; margin-bottom: 0; }
|
|
#bulkstartindex, #paperlimit, #paperlimitperpage { width: 35px; }
|
|
#bulklimit { width: 45px; }
|
|
.more { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAAWdEVYdENyZWF0aW9uIFRpbWUAMDEvMDIvMTLltnQyAAAB1UlEQVQ4jYWTS04bQRCGv3q0x8gMYJCwknCGLDgLVwiH4grhLFaUXdhkQ0A8pBg/FOLpnmbhMYzxRKlNS1Vdf/31V5XknGnb+eXJCBjzbzu9OLu+azu845Opysej4wHmshF4uJ2TUrb3CV0gIBAKRboC5C2vdkDE9fdty6/xDegvXz+NgDbFUejZ+PjDgExmtpxS9vYwMe5u5iyX8RRoa5Ic+C4qx9KUN1MGu4E618yqJ5axAp44KA7ZL3eYzp/HKdVIw7WK8d6BuDvcod9TQlBEIOXEdPlElSoUJabIIs4Z7h9yNDwgqOMayLXw7epHVIBggrsgspZPUBQyiCgugRQji7TAVDF1XB2TlQoOYCqovkmpopS9fcoiM3ue0rOCYf8IU8NklWxiiOQ3EPXtWagIqo6KYWYEc4IGvMViA6RrnCJKVS9B8ypRHG1YKNa0Ur+C+MPt/I2BKWVZUO4FgvQ47PcptEDF+T2Z8TiZUMWIyGtpd+Bze5VTSqP57O/4YG+AN/RXbSiPkwmL5z/be/L+mM4vT2JKeUW7EXD1erMz/Lo4u77f0K9DDhdA1XG11jh9vWBb99Z9gAg5QZ2hzpmUa0RSW4f/gqSY0s3Vz+tufEjvHS8Tg6BXC7qVbQAAAABJRU5ErkJggg==)
|
|
no-repeat left center; width: 17px; height: 17px; display: inline-block; float: right; }
|
|
.less { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK6wAACusBgosNWgAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAAWdEVYdENyZWF0aW9uIFRpbWUAMDEvMDIvMTLltnQyAAABuklEQVQ4ja2US25TQRBFT336OSEY5ESyBfEakNiLt0AW5S2QvQQxAiZIYBwSz/yByH7dxcB2bPMME+hJS/W5fetWVUtE8K/HfzdcXfdfqsr4onuGuRz4Jrdzcg6Gg9HfQYAxAqmlSMMlQJO5/oliE4AtQLcR++btZQ+wPVsvVXbTfXFGEMyWU9rVM0yMu/Gc5bJ+DdztxWcH3otKVzbPmyq5LnwfzSgEBMxlhqJEBFWVKKUgG66rur53oH7aOeWkUlJSRCBHZracssorlLXttHpCpzonaYukjmsiivDu08daAZIJ7oLIVg9BUQgQUVwSua5Z5AWmiqnj6pisVXAAU0F1J6WK0q6e024Fs4cplbXonFxgapisk00MkdiBqDd7oSKoOiqGmZHMSZrwPRYHIMfaKaKsyhI01oni6IaFYptSyiOIT27nOwaq5FyQrUAIC/nBhK+UErRSos55z4878CrneJyTnHOvquymf3mOb+hvy/jw+QuLh5/NORkORvsGrq77dc6xpr0RcH07y3oF8G04GN0f6HdEDhdA1XG1vXb6dsAa+3Z8AREiQwkoEeQoiBzocHDkf/wnvwC5IpRVsUDNUgAAAABJRU5ErkJggg==)
|
|
no-repeat left center; width: 17px; height: 17px; display: inline-block; float: right; }
|
|
.footer { font-family: Arial; font-size: 90%; clear: both; width: 700px; padding: 10px 0 10px 0; margin: 50px auto auto auto; }
|
|
.footer div span { padding: 10px; }
|
|
.footer .authorbtc { float: left; width: 470px; }
|
|
.footer .authorbtc span { text-align: left; display: block; padding: 0 20px; }
|
|
.footer .authorbtc div { position: relative; z-index: 100; }
|
|
.footer .authorpgp { position: relative; }
|
|
.footer .authorpgp span { text-align: right; display: block; padding: 0 20px; }
|
|
.footer .copyright { font-size: 80%; clear: both; padding: 5px 0; }
|
|
.footer .copyright span { padding: 10px 2px; }
|
|
}
|
|
@media print
|
|
{
|
|
#main { width: auto; }
|
|
#paperarea .keyarea:first-child { border-top: 2px solid green; }
|
|
#paperarea .keyarea.art:first-child { border: 0; }
|
|
.pagebreak { height: 1px; }
|
|
.paper #logo { display: none; }
|
|
.menu { display: none; }
|
|
.footer { display: none; }
|
|
#commands { display: none; }
|
|
#tagline { display: none; }
|
|
#faqs { display: none; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body onclick="SecureRandom.seedTime();" onkeypress="SecureRandom.seedTime();" onmousemove="ninja.seed(event);">
|
|
<div id="main">
|
|
<img alt="bitaddress.org" title="bitaddress.org" id="logo" src="data:image/png;base64,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" />
|
|
<div id="tagline">Open Source JavaScript Client-Side Bitcoin Wallet Generator</div>
|
|
<div id="testnet"></div>
|
|
<div class="menu">
|
|
<div class="tab selected" id="singlewallet" onclick="ninja.tabSwitch(this);">Single Wallet</div>
|
|
<div class="tab" id="paperwallet" onclick="ninja.tabSwitch(this);">Paper Wallet</div>
|
|
<div class="tab" id="bulkwallet" onclick="ninja.tabSwitch(this);">Bulk Wallet</div>
|
|
<div class="tab" id="brainwallet" onclick="ninja.tabSwitch(this);">Brain Wallet</div>
|
|
<div class="tab" id="vanitywallet" onclick="ninja.tabSwitch(this);">Vanity Wallet</div>
|
|
<div class="tab" id="detailwallet" onclick="ninja.tabSwitch(this);">Wallet Details</div>
|
|
</div>
|
|
|
|
<div id="commands">
|
|
<div id="singlecommands">
|
|
<span><input type="button" id="newaddress" value="Generate New Address" onclick="ninja.wallets.singlewallet.generateNewAddressAndKey();" /></span>
|
|
<span class="print"><input type="button" name="print" value="Print" onclick="window.print();" /></span>
|
|
</div>
|
|
<div id="papercommands">
|
|
<span>Hide Art? <input type="checkbox" id="paperart" onchange="ninja.wallets.paperwallet.toggleArt(this);" /></span>
|
|
<span>Addresses per page: <input type="text" id="paperlimitperpage" /></span>
|
|
<span>Addresses to generate: <input type="text" id="paperlimit" /></span>
|
|
<span><input type="button" id="papergenerate" value="Generate" onclick="ninja.wallets.paperwallet.build(document.getElementById('paperlimit').value * 1, document.getElementById('paperlimitperpage').value * 1, !document.getElementById('paperart').checked);" /></span>
|
|
<span class="print"><input type="button" name="print" value="Print" onclick="window.print();" /></span>
|
|
</div>
|
|
<div id="bulkcommands">
|
|
<span>Start index: <input type="text" id="bulkstartindex" value="1" /></span>
|
|
<span>Rows to generate: <input type="text" id="bulklimit" value="3" /></span>
|
|
<span><input type="button" id="bulkgenerate" value="Generate" onclick="ninja.wallets.bulkwallet.buildCSV(document.getElementById('bulklimit').value * 1, document.getElementById('bulkstartindex').value * 1);" /> </span>
|
|
<span class="print"><input type="button" name="print" value="Print" onclick="window.print();" /></span>
|
|
</div>
|
|
<div id="braincommands">
|
|
<div class="row">
|
|
<span class="label">Enter Passphrase: </span>
|
|
<input tabindex="1" type="password" id="brainpassphrase" value="" onfocus="this.select();" onkeypress="if (event.keyCode == 13) ninja.wallets.brainwallet.view();" />
|
|
<span>Show? <input type="checkbox" id="brainpassphraseshow" onchange="ninja.wallets.brainwallet.showToggle(this);" /></span>
|
|
<span class="print"><input type="button" name="print" value="Print" onclick="window.print();" /></span>
|
|
</div>
|
|
<div class="row extra">
|
|
<span class="label" id="brainlabelconfirm">Confirm Passphrase: </span>
|
|
<input tabindex="2" type="password" id="brainpassphraseconfirm" value="" onfocus="this.select();" onkeypress="if (event.keyCode == 13) ninja.wallets.brainwallet.view();" />
|
|
<span><input tabindex="3" type="button" id="brainview" value="View" onclick="ninja.wallets.brainwallet.view();" /></span>
|
|
<span class="notes right">Algorithm: SHA256(passphrase)</span>
|
|
</div>
|
|
</div>
|
|
<div id="vanitycommands">
|
|
<div id="vanitystep1label" class="expandable" onclick="ninja.wallets.vanitywallet.openCloseStep(1);">
|
|
<span>Step 1 - Generate your "Step1 Key Pair" <input type="button" id="vanitynewkeypair"
|
|
value="Generate" onclick="ninja.wallets.vanitywallet.generateKeyPair();" /></span>
|
|
<div id="vanitystep1icon" class="more"></div>
|
|
</div>
|
|
</div>
|
|
<div id="detailcommands">
|
|
<span>Enter Private Key (any format) <input type="text" id="detailprivkey" value="" onfocus="this.select();" onkeypress="if (event.keyCode == 13) ninja.wallets.detailwallet.viewDetails();" /></span>
|
|
<span><input type="button" id="detailview" value="View Details" onclick="ninja.wallets.detailwallet.viewDetails();" /></span>
|
|
<span class="print"><input type="button" name="print" value="Print" onclick="window.print();" /></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="wallets">
|
|
<div id="singlearea">
|
|
<div id="generate">
|
|
<span>Generating Bitcoin Address...<br /></span>
|
|
<span>MOVE your mouse around to add some extra randomness...<br /></span>
|
|
</div>
|
|
<div id="keyarea" class="keyarea">
|
|
<div class="public">
|
|
<div id="qrcode_public" class="qrcode_public"></div>
|
|
<div class="pubaddress">
|
|
<span class="label">Bitcoin Address:</span>
|
|
<span class="output" id="btcaddress"></span>
|
|
</div>
|
|
</div>
|
|
<div class="private">
|
|
<div id="qrcode_private" class="qrcode_private"></div>
|
|
<div class="privwif">
|
|
<span class="label">Private Key (Wallet Import Format):</span>
|
|
<span class="output" id="btcprivwif"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="paperarea"></div>
|
|
|
|
<div id="bulkarea">
|
|
<span class="label">Comma Separated Values:</span> <span class="format">Index,Address,Private Key (WIF)</span>
|
|
<textarea rows="20" cols="88" id="bulktextarea"></textarea>
|
|
</div>
|
|
|
|
<div id="brainarea">
|
|
<div id="brainkeyarea" class="keyarea">
|
|
<div class="public">
|
|
<div id="brainqrcodepublic" class="qrcode_public"></div>
|
|
<div class="pubaddress">
|
|
<span class="label">Bitcoin Address:</span>
|
|
<span class="output" id="brainbtcaddress"></span>
|
|
</div>
|
|
</div>
|
|
<div class="private">
|
|
<div id="brainqrcodeprivate" class="qrcode_private"></div>
|
|
<div class="privwif">
|
|
<span class="label">Private Key (Wallet Import Format):</span>
|
|
<span class="output" id="brainbtcprivwif"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="vanityarea">
|
|
<div id="vanitystep1area">
|
|
<div>
|
|
<span class="label">Step 1 Public Key:</span>
|
|
<div class="output" id="vanitypubkey"></div>
|
|
<div class="notes"><br />Copy and paste the above into the Your-Part-Public-Key field in the Vanity Pool Website.</div>
|
|
</div>
|
|
<div>
|
|
<span class="label">Step 1 Private Key:</span>
|
|
<span class="output" id=vanityprivatekey></span>
|
|
<div class="notes"><br />Copy and paste the above Private Key field into a text file. Ideally save to an encrypted drive.
|
|
You will need this to retrieve the Bitcoin Private Key once the Pool has found your prefix.</div>
|
|
</div>
|
|
</div>
|
|
<div id="vanitystep2label" class="expandable" onclick="ninja.wallets.vanitywallet.openCloseStep(2);">
|
|
<span>Step 2 - Calculate your Vanity Wallet</span>
|
|
<div id="vanitystep2icon" class="more"></div>
|
|
</div>
|
|
<div id="vanitystep2inputs">
|
|
<div>Enter Your Part Private Key (generated in Step 1 above and previously saved):</div>
|
|
<div><input type="text" id="vanityprivkey" value="" maxlength=64 size=80 onfocus="this.select();" /></div>
|
|
<div>Enter Pool Part Private Key (from Vanity Pool):</div>
|
|
<div><input type="text" id="vanitypoolprivkey" value="" maxlength=64 size=80 onfocus="this.select();" /></div>
|
|
<div></div><input type="button" id="vanityadd" value="Calculate Vanity Wallet" onclick="ninja.wallets.vanitywallet.addKeys();" />
|
|
</div>
|
|
<div id="vanitystep2area">
|
|
<div>
|
|
<span class="label">Vanity Private Key (WIF):</span>
|
|
<span class="output" id="vanityprivatekeywif"></span>
|
|
<div class="notes"><br />The above is the Private Key to load into your wallet. </div>
|
|
</div>
|
|
<div>
|
|
<span class="label">Vanity Bitcoin Address:</span>
|
|
<span class="output" id="vanityaddress"></span>
|
|
<div class="notes"><br />The above is your new address that should include your required prefix.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="detailarea">
|
|
<div class="notes">
|
|
Your Bitcoin Private Key is a unique secret number that only you know. It can be encoded in a number of different formats.
|
|
Below we show the Bitcoin Address and Public Key that corresponds to your Private Key as well as your Private Key in the most popular encoding formats (WIF, HEX, B64, MINI).
|
|
<br /><br />
|
|
Bitcoin v0.6+ stores public keys in compressed format. The client now also supports import and export of private keys with importprivkey/dumpprivkey. The format of the exported
|
|
private key is determined by whether the address was generated in an old or new wallet.
|
|
</div>
|
|
<div class="item">
|
|
<div id="detailqrcodepublic" class="qrcode_public"></div>
|
|
<span class="label">Bitcoin Address:</span>
|
|
<span class="output" id="detailaddress"></span>
|
|
</div>
|
|
<br />
|
|
<div class="item right">
|
|
<div id="detailqrcodepubliccomp" class="qrcode_public"></div>
|
|
<span class="label">Bitcoin Address (compressed):</span>
|
|
<span class="output" id="detailaddresscomp"></span>
|
|
</div>
|
|
<br />
|
|
<div class="item">
|
|
<span class="label">Public Key (130 characters [0-9A-F]):</span>
|
|
<span class="output" id="detailpubkey"></span>
|
|
</div>
|
|
<div class="item">
|
|
<span class="label">Public Key (compressed, 66 characters [0-9A-F]):</span>
|
|
<span class="output" id="detailpubkeycomp"></span>
|
|
</div>
|
|
<hr />
|
|
<div class="item">
|
|
<div id="detailqrcodeprivate" class="qrcode_private"></div>
|
|
<span class="label">Private Key WIF (51 characters base58, starts with a <span id="detailwifprefix">'5'</span>):</span>
|
|
<span class="output" id="detailprivwif"></span>
|
|
</div>
|
|
<br /><br />
|
|
<div class="item right">
|
|
<div id="detailqrcodeprivatecomp" class="qrcode_private"></div>
|
|
<span class="label">Private Key WIF (compressed, 52 characters base58, starts with a <span id="detailcompwifprefix">'K' or 'L'</span>):</span>
|
|
<span class="output" id="detailprivwifcomp"></span>
|
|
</div>
|
|
<br /><br />
|
|
<div class="item">
|
|
<span class="label">Private Key Hexadecimal Format (64 characters [0-9A-F]):</span>
|
|
<span class="output" id="detailprivhex"></span>
|
|
</div>
|
|
<div class="item">
|
|
<span class="label">Private Key Base64 (44 characters):</span>
|
|
<span class="output" id="detailprivb64"></span>
|
|
</div>
|
|
<div class="item" style="display: none;" id="detailmini">
|
|
<span class="label">Private Key Mini Format (22, 26 or 30 characters, starts with an 'S'):</span>
|
|
<span class="output" id="detailprivmini"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="faqs">
|
|
<div id="bulkfaqs">
|
|
<div id="bulkfaq1" class="bulkfaq">
|
|
<div id="bulkq1" class="bulkquestion" onclick="ninja.wallets.bulkwallet.openCloseFaq(1);">
|
|
<span>Why should I use a Bulk Wallet to accept Bitcoins on my website?</span>
|
|
<div id="bulke1" class="more"></div>
|
|
</div>
|
|
<div id="bulka1" class="bulkanswer">
|
|
The traditional approach to accepting bitcoins on your website requires that
|
|
you install the official bitcoin client daemon ("bitcoind"). Many website hosting packages
|
|
don't support installing the bitcoin daemon. Also, running the bitcoin daemon on your
|
|
web server means your private keys are hosted on the server and could get stolen if your web
|
|
server is hacked. When using a Bulk Wallet you can upload only the bitcoin addresses
|
|
and not the private keys to your web server. Then you don't have to worry about your
|
|
bitcoin wallet being stolen if your web server is hacked.
|
|
</div>
|
|
</div>
|
|
<div id="bulkfaq2" class="bulkfaq">
|
|
<div id="bulkq2" class="bulkquestion" onclick="ninja.wallets.bulkwallet.openCloseFaq(2);">
|
|
<span>How do I use a Bulk Wallet to accept Bitcoins on my website?</span>
|
|
<div id="bulke2" class="more"></div>
|
|
</div>
|
|
<div id="bulka2" class="bulkanswer">
|
|
<ol>
|
|
<li>Use the Bulk Wallet tab to pre-generate a large number of bitcoin addresses (10,000+). Copy and paste the generated
|
|
comma separated values (CSV) list to a secure text file on your computer. Backup the file you just created to a secure location.</li>
|
|
<li>Import the bitcoin addresses into a database table on your web server.
|
|
(Don't put the wallet/private keys on your web server, otherwise you risk hackers stealing your coins.
|
|
Just the bitcoin addresses as they will be shown to customers.)</li>
|
|
<li>Provide an option on your website's shopping cart for your customer to pay in Bitcoin. When the customer chooses to pay in Bitcoin you will
|
|
then display one of the addresses from your database to the customer as his "payment address" and save it with his shopping cart order.</li>
|
|
<li>You now need to be notified when the payment arrives. Google "bitcoin payment notification" and subscribe to at least
|
|
one bitcoin payment notification service. There are various services that will notify you via Web Services, API, SMS, Email, etc.
|
|
Once you receive this notification, which could be programmatically automated, you can process the customer's order.
|
|
To manually check if a payment has arrived you can use Block Explorer. Replace THEADDRESSGOESHERE with the bitcoin address
|
|
you are checking. It could take between 10 minutes to one hour for the transaction to be confirmed.
|
|
<br />
|
|
http://www.blockexplorer.com/address/THEADDRESSGOESHERE
|
|
<br /><br />
|
|
Unconfirmed transactions can be viewed at: http://blockchain.info/ <br />
|
|
You should see the transaction there within 30 seconds.
|
|
</li>
|
|
<li>Bitcoins will safely pile up on the block chain. Use the original wallet file you generated in step 1 to spend them.</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="footer" class="footer">
|
|
<div class="authorbtc">
|
|
<div>
|
|
<span>Donations: <b>1NiNja</b>1bUmhSoTXozBRBEtR8LeF9TGbZBN</span>
|
|
<span><a href="http://firstbits.com/1ninja" target="_blank">firstbits.com/1ninja</a></span>
|
|
</div>
|
|
</div>
|
|
<div class="authorpgp">
|
|
<span><a href="ninja_bitaddress.org.txt" target="_blank">PGP Public Key</a></span>
|
|
<span><a href="pgpsignedmsg.txt" target="_blank">Signed Version History (v2.0)</a></span>
|
|
<span><a href="https://github.com/pointbiz/bitaddress.org" target="_blank">GitHub Repository</a></span>
|
|
</div>
|
|
<div class="copyright">
|
|
<span>Copyright bitaddress.org.</span>
|
|
<span>JavaScript copyrights are included in the source.</span>
|
|
<span>No warranty.</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
var ninja = {
|
|
qrCode: {
|
|
// determine which type number is big enough for the input text length
|
|
getTypeNumber: function (text) {
|
|
var lengthCalculation = text.length * 8 + 12; // length as calculated by the QRCode
|
|
if (lengthCalculation < 72) { return 1; }
|
|
else if (lengthCalculation < 128) { return 2; }
|
|
else if (lengthCalculation < 208) { return 3; }
|
|
else if (lengthCalculation < 288) { return 4; }
|
|
else if (lengthCalculation < 368) { return 5; }
|
|
else if (lengthCalculation < 480) { return 6; }
|
|
else if (lengthCalculation < 528) { return 7; }
|
|
else if (lengthCalculation < 688) { return 8; }
|
|
else if (lengthCalculation < 800) { return 9; }
|
|
else if (lengthCalculation < 976) { return 10; }
|
|
return null;
|
|
},
|
|
|
|
createCanvas: function (text, sizeMultiplier) {
|
|
sizeMultiplier = (sizeMultiplier == undefined) ? 2 : sizeMultiplier; // default 2
|
|
// create the qrcode itself
|
|
var typeNumber = ninja.qrCode.getTypeNumber(text);
|
|
var qrcode = new QRCode(typeNumber, QRCode.ErrorCorrectLevel.H);
|
|
qrcode.addData(text);
|
|
qrcode.make();
|
|
var width = qrcode.getModuleCount() * sizeMultiplier;
|
|
var height = qrcode.getModuleCount() * sizeMultiplier;
|
|
// create canvas element
|
|
var canvas = document.createElement('canvas');
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
var ctx = canvas.getContext('2d');
|
|
// compute tileW/tileH based on width/height
|
|
var tileW = width / qrcode.getModuleCount();
|
|
var tileH = height / qrcode.getModuleCount();
|
|
// draw in the canvas
|
|
for (var row = 0; row < qrcode.getModuleCount(); row++) {
|
|
for (var col = 0; col < qrcode.getModuleCount(); col++) {
|
|
ctx.fillStyle = qrcode.isDark(row, col) ? "#000000" : "#ffffff";
|
|
ctx.fillRect(col * tileW, row * tileH, tileW, tileH);
|
|
}
|
|
}
|
|
// return just built canvas
|
|
return canvas;
|
|
},
|
|
|
|
// generate a QRCode and return it's representation as an Html table
|
|
createTableHtml: function (text) {
|
|
var typeNumber = ninja.qrCode.getTypeNumber(text);
|
|
var qr = new QRCode(typeNumber, QRCode.ErrorCorrectLevel.H);
|
|
qr.addData(text);
|
|
qr.make();
|
|
var tableHtml = "<table class='qrcodetable'>";
|
|
for (var r = 0; r < qr.getModuleCount(); r++) {
|
|
tableHtml += "<tr>";
|
|
for (var c = 0; c < qr.getModuleCount(); c++) {
|
|
if (qr.isDark(r, c)) {
|
|
tableHtml += "<td class='qrcodetddark'/>";
|
|
} else {
|
|
tableHtml += "<td class='qrcodetdlight'/>";
|
|
}
|
|
}
|
|
tableHtml += "</tr>";
|
|
}
|
|
tableHtml += "</table>";
|
|
return tableHtml;
|
|
},
|
|
|
|
// show QRCodes with canvas OR table (IE8)
|
|
// parameter: keyValuePair
|
|
// example: { "id1": "string1", "id2": "string2"}
|
|
// "id1" is the id of a div element where you want a QRCode inserted.
|
|
// "string1" is the string you want encoded into the QRCode.
|
|
showQrCode: function (keyValuePair, sizeMultiplier) {
|
|
for (var key in keyValuePair) {
|
|
var value = keyValuePair[key];
|
|
try {
|
|
if (document.getElementById(key)) {
|
|
document.getElementById(key).innerHTML = "";
|
|
document.getElementById(key).appendChild(ninja.qrCode.createCanvas(value, sizeMultiplier));
|
|
}
|
|
}
|
|
catch (e) {
|
|
// for browsers that do not support canvas (IE8)
|
|
document.getElementById(key).innerHTML = ninja.qrCode.createTableHtml(value);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
// number of mouse movements to wait for
|
|
seedLimit: (function () {
|
|
var num = Crypto.util.randomBytes(12)[11];
|
|
return 50 + Math.floor(num);
|
|
})(),
|
|
|
|
seedCount: 0, // counter
|
|
|
|
// seed function exists to wait for mouse movement to add more entropy before generating an address
|
|
seed: function (evt) {
|
|
if (!evt) var evt = window.event;
|
|
|
|
// seed a bunch (minimum seedLimit) of times based on mouse moves
|
|
SecureRandom.seedTime();
|
|
// seed mouse position X and Y
|
|
if (evt) SecureRandom.seedInt((evt.clientX * evt.clientY));
|
|
|
|
ninja.seedCount++;
|
|
// seeding is over now we generate and display the address
|
|
if (ninja.seedCount == ninja.seedLimit) {
|
|
ninja.wallets.singlewallet.generateNewAddressAndKey();
|
|
|
|
// show UI
|
|
document.getElementById("generate").style.display = "none";
|
|
document.getElementById("keyarea").style.display = "block";
|
|
document.getElementById("singlecommands").style.visibility = "visible";
|
|
}
|
|
},
|
|
|
|
tabSwitch: function (walletTab) {
|
|
if (walletTab.className.indexOf("selected") == -1) {
|
|
// unselect all tabs
|
|
for (var wType in ninja.wallets) {
|
|
document.getElementById(wType).className = "tab";
|
|
ninja.wallets[wType].close();
|
|
}
|
|
walletTab.className += " selected";
|
|
ninja.wallets[walletTab.getAttribute("id")].open();
|
|
}
|
|
},
|
|
|
|
privateKeyFormat: {
|
|
// 51 characters base58, always starts with a '5'
|
|
isSipaWalletImportFormat: function (key) {
|
|
key = key.toString();
|
|
return (ninja.testnetMode) ?
|
|
(/^9[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key)) :
|
|
(/^5[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key));
|
|
},
|
|
// 52 characters base58
|
|
isCompSipaWalletImportFormat: function (key) {
|
|
key = key.toString();
|
|
return (ninja.testnetMode) ?
|
|
(/^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key)) :
|
|
(/^[LK][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key));
|
|
},
|
|
// 64 characters [0-9A-F]
|
|
isHexFormat: function (key) {
|
|
key = key.toString();
|
|
return /^[A-Fa-f0-9]{64}$/.test(key);
|
|
},
|
|
// 44 characters
|
|
isBase64Format: function (key) {
|
|
key = key.toString();
|
|
return (/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test(key));
|
|
},
|
|
// 22, 26 or 30 characters, always starts with an 'S'
|
|
isMiniFormat: function (key) {
|
|
key = key.toString();
|
|
var validChars22 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21}$/.test(key);
|
|
var validChars26 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{25}$/.test(key);
|
|
var validChars30 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{29}$/.test(key);
|
|
var testBytes = Crypto.SHA256(key + "?", { asBytes: true });
|
|
|
|
return ((testBytes[0] === 0x00 || testBytes[0] === 0x01) && (validChars22 || validChars26 || validChars30));
|
|
}
|
|
},
|
|
|
|
wallets: {
|
|
singlewallet: {
|
|
open: function () {
|
|
document.getElementById("singlearea").style.display = "block";
|
|
document.getElementById("singlecommands").style.display = "block";
|
|
},
|
|
|
|
close: function () {
|
|
document.getElementById("singlearea").style.display = "none";
|
|
document.getElementById("singlecommands").style.display = "none";
|
|
},
|
|
|
|
// If user has not moved the mouse or if they are on a mobile device
|
|
// we will force the generation after a random period of time.
|
|
forceGenerate: function () {
|
|
// if the mouse has not moved enough
|
|
if (ninja.seedCount < ninja.seedLimit) {
|
|
SecureRandom.seedTime();
|
|
ninja.seedCount = ninja.seedLimit - 1;
|
|
ninja.seed();
|
|
}
|
|
},
|
|
|
|
// generate bitcoin address and private key and update information in the HTML
|
|
generateNewAddressAndKey: function () {
|
|
try {
|
|
var key = new Bitcoin.ECKey(false);
|
|
var bitcoinAddress = key.getBitcoinAddress();
|
|
var privateKeyWif = key.getBitcoinWalletImportFormat();
|
|
document.getElementById("btcaddress").innerHTML = bitcoinAddress;
|
|
document.getElementById("btcprivwif").innerHTML = privateKeyWif;
|
|
var keyValuePair = {
|
|
"qrcode_public": bitcoinAddress,
|
|
"qrcode_private": privateKeyWif
|
|
};
|
|
ninja.qrCode.showQrCode(keyValuePair);
|
|
}
|
|
catch (e) {
|
|
// browser does not have sufficient JavaScript support to generate a bitcoin address
|
|
alert(e);
|
|
document.getElementById("btcaddress").innerHTML = "error";
|
|
document.getElementById("btcprivwif").innerHTML = "error";
|
|
document.getElementById("qrcode_public").innerHTML = "";
|
|
document.getElementById("qrcode_private").innerHTML = "";
|
|
}
|
|
}
|
|
},
|
|
|
|
bulkwallet: {
|
|
open: function () {
|
|
document.getElementById("bulkarea").style.display = "block";
|
|
document.getElementById("bulkcommands").style.display = "block";
|
|
document.getElementById("bulkfaqs").style.display = "block";
|
|
// show a default CSV list if the text area is empty
|
|
if (document.getElementById("bulktextarea").value == "") {
|
|
// return control of the thread to the browser to render the tab switch UI then build a default CSV list
|
|
setTimeout(function () { ninja.wallets.bulkwallet.buildCSV(3, 1); }, 200);
|
|
}
|
|
},
|
|
|
|
close: function () {
|
|
document.getElementById("bulkarea").style.display = "none";
|
|
document.getElementById("bulkcommands").style.display = "none";
|
|
document.getElementById("bulkfaqs").style.display = "none";
|
|
},
|
|
|
|
// use this function to bulk generate addresses
|
|
// rowLimit: number of Bitcoin Addresses to generate
|
|
// startIndex: add this number to the row index for output purposes
|
|
// returns:
|
|
// index,bitcoinAddress,privateKeyWif
|
|
buildCSV: function (rowLimit, startIndex) {
|
|
var bulkWallet = ninja.wallets.bulkwallet;
|
|
document.getElementById("bulktextarea").value = "Generating addresses... " + rowLimit;
|
|
bulkWallet.csv = [];
|
|
bulkWallet.csvRowLimit = rowLimit;
|
|
bulkWallet.csvRowsRemaining = rowLimit;
|
|
bulkWallet.csvStartIndex = --startIndex;
|
|
setTimeout(bulkWallet.batchCSV, 0);
|
|
},
|
|
|
|
csv: [],
|
|
csvRowsRemaining: null, // use to keep track of how many rows are left to process when building a large CSV array
|
|
csvRowLimit: 0,
|
|
csvStartIndex: 0,
|
|
|
|
batchCSV: function () {
|
|
var bulkWallet = ninja.wallets.bulkwallet;
|
|
if (bulkWallet.csvRowsRemaining > 0) {
|
|
bulkWallet.csvRowsRemaining--;
|
|
var key = new Bitcoin.ECKey(false);
|
|
|
|
bulkWallet.csv.push((bulkWallet.csvRowLimit - bulkWallet.csvRowsRemaining + bulkWallet.csvStartIndex)
|
|
+ ",\"" + key.getBitcoinAddress() + "\",\"" + key.toString("wif")
|
|
//+ "\",\"" + key.toString("wifcomp") // uncomment these lines to add different private key formats to the CSV
|
|
//+ "\",\"" + key.getBitcoinHexFormat()
|
|
//+ "\",\"" + key.toString("base64")
|
|
+ "\"");
|
|
|
|
document.getElementById("bulktextarea").value = "Generating addresses... " + bulkWallet.csvRowsRemaining;
|
|
|
|
// release thread to browser to render UI
|
|
setTimeout(bulkWallet.batchCSV, 0);
|
|
}
|
|
// processing is finished so put CSV in text area
|
|
else if (bulkWallet.csvRowsRemaining === 0) {
|
|
document.getElementById("bulktextarea").value = bulkWallet.csv.join("\n");
|
|
}
|
|
},
|
|
|
|
openCloseFaq: function (faqNum) {
|
|
// do close
|
|
if (document.getElementById("bulka" + faqNum).style.display == "block") {
|
|
document.getElementById("bulka" + faqNum).style.display = "none";
|
|
document.getElementById("bulke" + faqNum).setAttribute("class", "more");
|
|
}
|
|
// do open
|
|
else {
|
|
document.getElementById("bulka" + faqNum).style.display = "block";
|
|
document.getElementById("bulke" + faqNum).setAttribute("class", "less");
|
|
}
|
|
}
|
|
},
|
|
|
|
paperwallet: {
|
|
open: function () {
|
|
document.getElementById("main").setAttribute("class", "paper"); // add 'paper' class to main div
|
|
var paperArea = document.getElementById("paperarea");
|
|
paperArea.style.display = "block";
|
|
document.getElementById("papercommands").style.display = "block";
|
|
var perPageLimitElement = document.getElementById("paperlimitperpage");
|
|
var limitElement = document.getElementById("paperlimit");
|
|
var pageBreakAt = (ninja.wallets.paperwallet.useArtisticWallet) ? ninja.wallets.paperwallet.pageBreakAtArtisticDefault : ninja.wallets.paperwallet.pageBreakAtDefault;
|
|
if (perPageLimitElement && perPageLimitElement.value < 1) {
|
|
perPageLimitElement.value = pageBreakAt;
|
|
}
|
|
if (limitElement && limitElement.value < 1) {
|
|
limitElement.value = pageBreakAt;
|
|
}
|
|
if (paperArea.innerHTML == "") {
|
|
ninja.wallets.paperwallet.build(pageBreakAt, pageBreakAt, !document.getElementById('paperart').checked);
|
|
}
|
|
},
|
|
|
|
close: function () {
|
|
document.getElementById("paperarea").style.display = "none";
|
|
document.getElementById("papercommands").style.display = "none";
|
|
document.getElementById("main").setAttribute("class", ""); // remove 'paper' class from main div
|
|
},
|
|
|
|
remaining: null, // use to keep track of how many addresses are left to process when building the paper wallet
|
|
count: 0,
|
|
pageBreakAtDefault: 7,
|
|
pageBreakAtArtisticDefault: 3,
|
|
useArtisticWallet: true,
|
|
pageBreakAt: null,
|
|
|
|
build: function (numWallets, pageBreakAt, useArtisticWallet) {
|
|
if (numWallets < 1) numWallets = 1;
|
|
ninja.wallets.paperwallet.remaining = numWallets;
|
|
ninja.wallets.paperwallet.count = 0;
|
|
ninja.wallets.paperwallet.useArtisticWallet = useArtisticWallet;
|
|
ninja.wallets.paperwallet.pageBreakAt = pageBreakAt;
|
|
document.getElementById("paperarea").innerHTML = "";
|
|
setTimeout(ninja.wallets.paperwallet.batch, 0);
|
|
},
|
|
|
|
batch: function () {
|
|
if (ninja.wallets.paperwallet.remaining > 0) {
|
|
var paperArea = document.getElementById("paperarea");
|
|
ninja.wallets.paperwallet.count++;
|
|
var i = ninja.wallets.paperwallet.count;
|
|
var pageBreakAt = ninja.wallets.paperwallet.pageBreakAt;
|
|
var div = document.createElement("div");
|
|
div.setAttribute("id", "keyarea" + i);
|
|
if (ninja.wallets.paperwallet.useArtisticWallet) {
|
|
div.innerHTML = ninja.wallets.paperwallet.templateArtisticHtml(i);
|
|
div.setAttribute("class", "keyarea art");
|
|
}
|
|
else {
|
|
div.innerHTML = ninja.wallets.paperwallet.templateHtml(i);
|
|
div.setAttribute("class", "keyarea");
|
|
}
|
|
if (paperArea.innerHTML != "") {
|
|
// page break
|
|
if (i % pageBreakAt == 1 && ninja.wallets.paperwallet.count >= pageBreakAt) {
|
|
var pBreak = document.createElement("div");
|
|
pBreak.setAttribute("class", "pagebreak");
|
|
document.getElementById("paperarea").appendChild(pBreak);
|
|
div.style.pageBreakBefore = "always";
|
|
if (!ninja.wallets.paperwallet.useArtisticWallet) {
|
|
div.style.borderTop = "2px solid green";
|
|
}
|
|
}
|
|
}
|
|
document.getElementById("paperarea").appendChild(div);
|
|
ninja.wallets.paperwallet.generateNewWallet(i);
|
|
ninja.wallets.paperwallet.remaining--;
|
|
setTimeout(ninja.wallets.paperwallet.batch, 0);
|
|
}
|
|
},
|
|
|
|
// generate bitcoin address, private key, QR Code and update information in the HTML
|
|
// idPostFix: 1, 2, 3, etc.
|
|
generateNewWallet: function (idPostFix) {
|
|
var key = new Bitcoin.ECKey(false);
|
|
var bitcoinAddress = key.getBitcoinAddress();
|
|
var privateKeyWif = key.getBitcoinWalletImportFormat();
|
|
if (ninja.wallets.paperwallet.useArtisticWallet) {
|
|
ninja.wallets.paperwallet.showArtisticWallet(idPostFix, bitcoinAddress, privateKeyWif);
|
|
}
|
|
else {
|
|
ninja.wallets.paperwallet.showWallet(idPostFix, bitcoinAddress, privateKeyWif);
|
|
}
|
|
},
|
|
|
|
templateHtml: function (i) {
|
|
var walletHtml =
|
|
"<div class='public'>" +
|
|
"<div id='qrcode_public" + i + "' class='qrcode_public'></div>" +
|
|
"<div class='pubaddress'>" +
|
|
"<span class='label'>Bitcoin Address:</span>" +
|
|
"<span class='output' id='btcaddress" + i + "'></span>" +
|
|
"</div>" +
|
|
"</div>" +
|
|
"<div class='private'>" +
|
|
"<div id='qrcode_private" + i + "' class='qrcode_private'></div>" +
|
|
"<div class='privwif'>" +
|
|
"<span class='label'>Private Key (Wallet Import Format):</span>" +
|
|
"<span class='output' id='btcprivwif" + i + "'></span>" +
|
|
"</div>" +
|
|
"</div>";
|
|
return walletHtml;
|
|
},
|
|
|
|
showWallet: function (idPostFix, bitcoinAddress, privateKeyWif) {
|
|
document.getElementById("btcaddress" + idPostFix).innerHTML = bitcoinAddress;
|
|
document.getElementById("btcprivwif" + idPostFix).innerHTML = privateKeyWif;
|
|
var keyValuePair = {};
|
|
keyValuePair["qrcode_public" + idPostFix] = bitcoinAddress;
|
|
keyValuePair["qrcode_private" + idPostFix] = privateKeyWif;
|
|
ninja.qrCode.showQrCode(keyValuePair);
|
|
document.getElementById("keyarea" + idPostFix).style.display = "block";
|
|
},
|
|
|
|
templateArtisticHtml: function (i) {
|
|
var walletHtml =
|
|
"<div class='artwallet' id='artwallet" + i + "'>" +
|
|
//"<iframe src='bitcoin-wallet-01.svg' id='papersvg" + i + "' class='papersvg' ></iframe>" +
|
|
"<img id='papersvg" + i + "' class='papersvg' src='data:image/png;base64,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' />" +
|
|
"<div id='qrcode_public" + i + "' class='qrcode_public'></div>" +
|
|
"<div id='qrcode_private" + i + "' class='qrcode_private'></div>" +
|
|
"<div class='btcaddress' id='btcaddress" + i + "'></div>" +
|
|
"<div class='btcprivwif' id='btcprivwif" + i + "'></div>" +
|
|
"</div>";
|
|
return walletHtml;
|
|
},
|
|
|
|
showArtisticWallet: function (idPostFix, bitcoinAddress, privateKeyWif) {
|
|
var keyValuePair = {};
|
|
keyValuePair["qrcode_public" + idPostFix] = bitcoinAddress;
|
|
keyValuePair["qrcode_private" + idPostFix] = privateKeyWif;
|
|
ninja.qrCode.showQrCode(keyValuePair, 2.4);
|
|
document.getElementById("btcaddress" + idPostFix).innerHTML = bitcoinAddress;
|
|
document.getElementById("btcprivwif" + idPostFix).innerHTML = privateKeyWif;
|
|
|
|
// CODE to modify SVG DOM elements
|
|
//var paperSvg = document.getElementById("papersvg" + idPostFix);
|
|
//if (paperSvg) {
|
|
// svgDoc = paperSvg.contentDocument;
|
|
// if (svgDoc) {
|
|
// var bitcoinAddressElement = svgDoc.getElementById("bitcoinaddress");
|
|
// var privateKeyElement = svgDoc.getElementById("privatekey");
|
|
// if (bitcoinAddressElement && privateKeyElement) {
|
|
// bitcoinAddressElement.textContent = bitcoinAddress;
|
|
// privateKeyElement.textContent = privateKeyWif;
|
|
// }
|
|
// }
|
|
//}
|
|
},
|
|
|
|
toggleArt: function (element) {
|
|
if (!element.checked) {
|
|
// show Art
|
|
document.getElementById("paperlimitperpage").value = ninja.wallets.paperwallet.pageBreakAtArtisticDefault;
|
|
document.getElementById("paperlimit").value = ninja.wallets.paperwallet.pageBreakAtArtisticDefault;
|
|
}
|
|
else {
|
|
// hide Art
|
|
document.getElementById("paperlimitperpage").value = ninja.wallets.paperwallet.pageBreakAtDefault;
|
|
document.getElementById("paperlimit").value = ninja.wallets.paperwallet.pageBreakAtDefault;
|
|
}
|
|
}
|
|
},
|
|
|
|
brainwallet: {
|
|
open: function () {
|
|
document.getElementById("brainarea").style.display = "block";
|
|
document.getElementById("braincommands").style.display = "block";
|
|
document.getElementById("brainpassphrase").focus();
|
|
},
|
|
|
|
close: function () {
|
|
document.getElementById("brainarea").style.display = "none";
|
|
document.getElementById("braincommands").style.display = "none";
|
|
},
|
|
|
|
minPassphraseLength: 15,
|
|
|
|
view: function () {
|
|
var key = document.getElementById("brainpassphrase").value.toString().replace(/^\s+|\s+$/g, ""); // trim white space
|
|
document.getElementById("brainpassphrase").value = key;
|
|
var keyConfirm = document.getElementById("brainpassphraseconfirm").value.toString().replace(/^\s+|\s+$/g, ""); // trim white space
|
|
document.getElementById("brainpassphraseconfirm").value = keyConfirm;
|
|
|
|
if (key == keyConfirm || document.getElementById("brainpassphraseshow").checked) {
|
|
// enforce a minimum passphrase length
|
|
if (key.length >= ninja.wallets.brainwallet.minPassphraseLength) {
|
|
var bytes = Crypto.SHA256(key, { asBytes: true });
|
|
var btcKey = new Bitcoin.ECKey(bytes);
|
|
var bitcoinAddress = btcKey.getBitcoinAddress();
|
|
var privWif = btcKey.getBitcoinWalletImportFormat();
|
|
document.getElementById("brainbtcaddress").innerHTML = bitcoinAddress;
|
|
document.getElementById("brainbtcprivwif").innerHTML = privWif;
|
|
ninja.qrCode.showQrCode({
|
|
"brainqrcodepublic": bitcoinAddress,
|
|
"brainqrcodeprivate": privWif
|
|
});
|
|
document.getElementById("brainkeyarea").style.display = "block";
|
|
}
|
|
else {
|
|
alert("The passphrase you entered is too short.\n\n"
|
|
+ "Warning: Choosing a strong passphrase is important to avoid brute force attempts to guess your passphrase and steal your bitcoins.");
|
|
ninja.wallets.brainwallet.clear();
|
|
}
|
|
}
|
|
else {
|
|
alert("The passphrase does not match the confirm passphrase.");
|
|
ninja.wallets.brainwallet.clear();
|
|
}
|
|
},
|
|
|
|
clear: function () {
|
|
document.getElementById("brainkeyarea").style.display = "none";
|
|
},
|
|
|
|
showToggle: function (element) {
|
|
if (element.checked) {
|
|
document.getElementById("brainpassphrase").setAttribute("type", "text");
|
|
document.getElementById("brainpassphraseconfirm").style.visibility = "hidden";
|
|
document.getElementById("brainlabelconfirm").style.visibility = "hidden";
|
|
}
|
|
else {
|
|
document.getElementById("brainpassphrase").setAttribute("type", "password");
|
|
document.getElementById("brainpassphraseconfirm").style.visibility = "visible";
|
|
document.getElementById("brainlabelconfirm").style.visibility = "visible";
|
|
}
|
|
}
|
|
},
|
|
|
|
vanitywallet: {
|
|
open: function () {
|
|
document.getElementById("vanityarea").style.display = "block";
|
|
document.getElementById("vanitycommands").style.display = "block";
|
|
},
|
|
|
|
close: function () {
|
|
document.getElementById("vanityarea").style.display = "none";
|
|
document.getElementById("vanitycommands").style.display = "none";
|
|
document.getElementById("vanitystep1area").style.display = "none";
|
|
document.getElementById("vanitystep2area").style.display = "none";
|
|
document.getElementById("vanitystep1icon").setAttribute("class", "more");
|
|
document.getElementById("vanitystep2icon").setAttribute("class", "more");
|
|
},
|
|
|
|
generateKeyPair: function () {
|
|
var key = new Bitcoin.ECKey(false);
|
|
var publicKey = Crypto.util.bytesToHex(key.getPub()).toString().toUpperCase();
|
|
var privateKey = Crypto.util.bytesToHex(key.getBitcoinPrivateKeyByteArray()).toString().toUpperCase();
|
|
|
|
document.getElementById("vanitypubkey").innerHTML = publicKey;
|
|
document.getElementById("vanityprivatekey").innerHTML = privateKey;
|
|
document.getElementById("vanityarea").style.display = "block";
|
|
document.getElementById("vanitystep1area").style.display = "none";
|
|
},
|
|
|
|
addKeys: function () {
|
|
var privateKeyWif = false;
|
|
var bitcoinAddress = false;
|
|
try {
|
|
var privateKeyString = document.getElementById("vanityprivkey").value;
|
|
var privatePoolKeyString = document.getElementById("vanitypoolprivkey").value;
|
|
|
|
var privateKey = BigInteger.fromByteArrayUnsigned(Crypto.util.hexToBytes(privateKeyString));
|
|
if (ninja.privateKeyFormat.isHexFormat(privatePoolKeyString)) {
|
|
var privatePoolKey = BigInteger.fromByteArrayUnsigned(Crypto.util.hexToBytes(privatePoolKeyString));
|
|
}
|
|
else if (ninja.privateKeyFormat.isCompSipaWalletImportFormat(privatePoolKeyString)) {
|
|
var bytes = Bitcoin.Base58.decode(privatePoolKeyString);
|
|
bytes.shift();
|
|
bytes.pop();
|
|
bytes = bytes.slice(0, bytes.length - 4);
|
|
if (bytes.length == 32) {
|
|
var privatePoolKey = BigInteger.fromByteArrayUnsigned(bytes);
|
|
}
|
|
}
|
|
else if (ninja.privateKeyFormat.isSipaWalletImportFormat(privatePoolKeyString)) {
|
|
var bytes = Bitcoin.Base58.decode(privatePoolKeyString);
|
|
bytes.shift();
|
|
bytes = bytes.slice(0, bytes.length - 4);
|
|
if (bytes.length == 32) {
|
|
var privatePoolKey = BigInteger.fromByteArrayUnsigned(bytes);
|
|
}
|
|
}
|
|
|
|
if (privatePoolKey != undefined) {
|
|
var n = EllipticCurve.getSECCurveByName("secp256k1").getN();
|
|
var newPrivateKey = new Bitcoin.ECKey(privateKey.add(privatePoolKey).mod(n));
|
|
bitcoinAddress = newPrivateKey.getBitcoinAddress();
|
|
privateKeyWif = newPrivateKey.getBitcoinWalletImportFormat();
|
|
}
|
|
|
|
} catch (e) {
|
|
alert(e);
|
|
}
|
|
document.getElementById("vanityprivatekeywif").innerHTML = privateKeyWif;
|
|
document.getElementById("vanityaddress").innerHTML = bitcoinAddress;
|
|
document.getElementById("vanitystep2area").style.display = "block";
|
|
},
|
|
|
|
openCloseStep: function (num) {
|
|
// do close
|
|
if (document.getElementById("vanitystep" + num + "area").style.display == "block") {
|
|
document.getElementById("vanitystep" + num + "area").style.display = "none";
|
|
document.getElementById("vanitystep" + num + "icon").setAttribute("class", "more");
|
|
}
|
|
// do open
|
|
else {
|
|
document.getElementById("vanitystep" + num + "area").style.display = "block";
|
|
document.getElementById("vanitystep" + num + "icon").setAttribute("class", "less");
|
|
}
|
|
}
|
|
},
|
|
|
|
detailwallet: {
|
|
open: function () {
|
|
document.getElementById("detailarea").style.display = "block";
|
|
document.getElementById("detailcommands").style.display = "block";
|
|
document.getElementById("detailprivkey").focus();
|
|
},
|
|
|
|
close: function () {
|
|
document.getElementById("detailarea").style.display = "none";
|
|
document.getElementById("detailcommands").style.display = "none";
|
|
},
|
|
|
|
viewDetails: function () {
|
|
var key = document.getElementById("detailprivkey").value.toString().replace(/^\s+|\s+$/g, ""); // trim white space
|
|
document.getElementById("detailprivkey").value = key;
|
|
var keyFormat = ninja.privateKeyFormat;
|
|
// hide Private Key Mini Format
|
|
document.getElementById("detailmini").style.display = "none";
|
|
|
|
if (keyFormat.isSipaWalletImportFormat(key)) {
|
|
var bytes = Bitcoin.Base58.decode(key);
|
|
bytes.shift();
|
|
bytes = bytes.slice(0, bytes.length - 4);
|
|
if (bytes.length != 32) {
|
|
alert("The text you entered is not a valid Private Key");
|
|
ninja.wallets.detailwallet.clear();
|
|
}
|
|
else {
|
|
var btcKey = new Bitcoin.ECKey(bytes);
|
|
}
|
|
}
|
|
else if (keyFormat.isCompSipaWalletImportFormat(key)) {
|
|
var bytes = Bitcoin.Base58.decode(key);
|
|
bytes.shift();
|
|
bytes.pop();
|
|
bytes = bytes.slice(0, bytes.length - 4);
|
|
if (bytes.length != 32) {
|
|
alert("The text you entered is not a valid Private Key");
|
|
ninja.wallets.detailwallet.clear();
|
|
}
|
|
else {
|
|
var btcKey = new Bitcoin.ECKey(bytes);
|
|
}
|
|
}
|
|
else if (keyFormat.isHexFormat(key)) {
|
|
var bytes = Crypto.util.hexToBytes(key);
|
|
var btcKey = new Bitcoin.ECKey(bytes);
|
|
}
|
|
else if (keyFormat.isBase64Format(key)) {
|
|
var bytes = Crypto.util.base64ToBytes(key);
|
|
if (bytes.length != 32) {
|
|
alert("The text you entered is not a valid Private Key");
|
|
ninja.wallets.detailwallet.clear();
|
|
}
|
|
else {
|
|
var btcKey = new Bitcoin.ECKey(bytes);
|
|
}
|
|
}
|
|
else if (keyFormat.isMiniFormat(key)) {
|
|
var bytes = Crypto.SHA256(key, { asBytes: true });
|
|
var btcKey = new Bitcoin.ECKey(bytes);
|
|
document.getElementById("detailprivmini").innerHTML = key;
|
|
document.getElementById("detailmini").style.display = "block";
|
|
}
|
|
else {
|
|
// enforce a minimum passphrase length
|
|
if (key.length >= ninja.wallets.brainwallet.minPassphraseLength) {
|
|
// Deterministic Wallet confirm box to ask if user wants to SHA256 the input to get a private key
|
|
var usePassphrase = confirm("The text you entered is not a valid Private Key!\n\n"
|
|
+ "Would you like to use the entered text as a passphrase and create a Private Key using a SHA256 hash of the passphrase?\n\n"
|
|
+ "Warning: Choosing a strong passphrase is important to avoid brute force attempts to guess your passphrase and steal your bitcoins.");
|
|
if (usePassphrase) {
|
|
var bytes = Crypto.SHA256(key, { asBytes: true });
|
|
var btcKey = new Bitcoin.ECKey(bytes);
|
|
}
|
|
else {
|
|
ninja.wallets.detailwallet.clear();
|
|
}
|
|
}
|
|
else {
|
|
alert("The text you entered is not a valid Private Key");
|
|
ninja.wallets.detailwallet.clear();
|
|
}
|
|
}
|
|
|
|
if (btcKey != undefined) {
|
|
var pubKey = Crypto.util.bytesToHex(btcKey.getPub()).toUpperCase();
|
|
var pubKeyComp = Crypto.util.bytesToHex(btcKey.getPubCompressed()).toUpperCase();
|
|
var halfWayIndex = Math.floor(pubKey.length / 2);
|
|
var pubKeyFirstHalf = pubKey.substr(0, halfWayIndex);
|
|
var pubKeySecondHalf = pubKey.substr(halfWayIndex, pubKey.length - halfWayIndex);
|
|
document.getElementById("detailpubkey").innerHTML = pubKeyFirstHalf + "<br />" + pubKeySecondHalf;
|
|
document.getElementById("detailpubkeycomp").innerHTML = pubKeyComp;
|
|
document.getElementById("detailaddress").innerHTML = btcKey.getBitcoinAddress();
|
|
document.getElementById("detailaddresscomp").innerHTML = btcKey.getBitcoinAddressCompressed();
|
|
document.getElementById("detailprivwif").innerHTML = btcKey.getBitcoinWalletImportFormat();
|
|
document.getElementById("detailprivwifcomp").innerHTML = btcKey.getBitcoinWalletImportFormatCompressed();
|
|
document.getElementById("detailprivhex").innerHTML = btcKey.toString().toUpperCase();
|
|
document.getElementById("detailprivb64").innerHTML = btcKey.toString("base64");
|
|
ninja.qrCode.showQrCode({
|
|
"detailqrcodepublic": btcKey.getBitcoinAddress(),
|
|
"detailqrcodepubliccomp": btcKey.getBitcoinAddressCompressed(),
|
|
"detailqrcodeprivate": btcKey.getBitcoinWalletImportFormat(),
|
|
"detailqrcodeprivatecomp": btcKey.getBitcoinWalletImportFormatCompressed()
|
|
});
|
|
}
|
|
},
|
|
|
|
clear: function () {
|
|
document.getElementById("detailpubkey").innerHTML = "";
|
|
document.getElementById("detailpubkeycomp").innerHTML = "";
|
|
document.getElementById("detailaddress").innerHTML = "";
|
|
document.getElementById("detailaddresscomp").innerHTML = "";
|
|
document.getElementById("detailprivwif").innerHTML = "";
|
|
document.getElementById("detailprivwifcomp").innerHTML = "";
|
|
document.getElementById("detailprivhex").innerHTML = "";
|
|
document.getElementById("detailprivb64").innerHTML = "";
|
|
document.getElementById("detailprivmini").innerHTML = "";
|
|
document.getElementById("detailqrcodepublic").innerHTML = "";
|
|
document.getElementById("detailqrcodepubliccomp").innerHTML = "";
|
|
document.getElementById("detailqrcodeprivate").innerHTML = "";
|
|
document.getElementById("detailqrcodeprivatecomp").innerHTML = "";
|
|
}
|
|
}
|
|
},
|
|
|
|
getQueryString: function () {
|
|
var result = {}, queryString = location.search.substring(1), re = /([^&=]+)=([^&]*)/g, m;
|
|
while (m = re.exec(queryString)) {
|
|
result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// testnet, check if testnet edition should be activated
|
|
if (ninja.getQueryString()["testnet"] == "true" || ninja.getQueryString()["testnet"] == "1") {
|
|
document.getElementById("testnet").innerHTML = "TESTNET EDITION ACTIVATED";
|
|
document.getElementById("testnet").style.display = "block";
|
|
document.getElementById("detailwifprefix").innerHTML = "'9'";
|
|
document.getElementById("detailcompwifprefix").innerHTML = "'c'";
|
|
Bitcoin.Address.networkVersion = 0x6F; // testnet
|
|
Bitcoin.ECKey.privateKeyPrefix = 0xEF; // testnet
|
|
ninja.testnetMode = true;
|
|
}
|
|
|
|
// if users does not move mouse after random amount of time then generate the key anyway.
|
|
setTimeout(ninja.wallets.singlewallet.forceGenerate, ninja.seedLimit * 20);
|
|
</script>
|
|
</body>
|
|
</html> |