Skip to content

Instantly share code, notes, and snippets.

@rouslanovitch
Created December 20, 2017 16:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rouslanovitch/3f85357bada792e662868f26c46a8927 to your computer and use it in GitHub Desktop.
Save rouslanovitch/3f85357bada792e662868f26c46a8927 to your computer and use it in GitHub Desktop.
BIP38 Doge KO
<!DOCTYPE html>
<!-- saved from url=(0023)http://dogeaddress.com/ -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!--
<script async="" src="./Dogecoin Wallet Generator_files/cloudflare.min.js"></script><script async="" src="./Dogecoin Wallet Generator_files/analytics.js"></script><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-46664038-1', 'dogeaddress.com');
ga('send', 'pageview');
</script>-->
<!--
This is a modified version o
GitHub Repository: https://github.com/litecoin-project/liteaddress.org
DOnate to the original author:
Donation Address: 1NiNja1bUmhSoTXozBRBEtR8LeF9TGbZBN
Notice of Copyrights and Licenses:
***********************************
The bitaddress.org project, software and embedded resources are copyright bitaddress.org (pointbiz).
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
window.Crypto_scrypt MIT License
The bitaddress.org software is available under The MIT License (MIT)
Copyright (c) 2011-2013 bitaddress.org (pointbiz)
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>Dogecoin Wallet Generator</title>
<meta charset="utf-8">
<!--
<script type="text/javascript">
//<![CDATA[
try{if (!window.CloudFlare) {var CloudFlare=[{verbose:0,p:0,byc:0,owlid:"cf",bag2:1,mirage2:0,oracle:0,paths:{cloudflare:"/cdn-cgi/nexp/acv=4125811108/"},atok:"3f036966287cf316bbc21f1e840694ac",petok:"527799992392ba671c93729e0abe276825de9aaa-1387008762-1800",zone:"liteaddress.org",rocket:"0",apps:{}}];CloudFlare.push({"apps":{"ape":"f1912a9733ebfe19f336d188b453c2de"}});var a=document.createElement("script"),b=document.getElementsByTagName("script")[0];a.async=!0;a.src="//ajax.cloudflare.com/cdn-cgi/nexp/acv=616370821/cloudflare.min.js";b.parentNode.insertBefore(a,b);}}catch(e){};
//]]>
</script>
-->
<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.5.4 Crypto.js
* http://code.google.com/p/crypto-js/
* Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
* http://code.google.com/p/crypto-js/wiki/License
*/
if (typeof Crypto == "undefined" || !Crypto.util) {
(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] & 0xFF) << (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) {
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) {
// 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 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) & 0xFF);
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("");
}
};
})();
}
</script>
<script type="text/javascript">
/*!
* Crypto-JS v2.5.4 SHA256.js
* http://code.google.com/p/crypto-js/
* Copyright (c) 2009-2013, 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) >>> 0;
d = c;
c = b;
b = a;
a = (t1 + t2) >>> 0;
}
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;
SHA256._digestsize = 32;
})();
</script>
<script type="text/javascript">
/*!
* Crypto-JS v2.5.4 PBKDF2.js
* http://code.google.com/p/crypto-js/
* Copyright (c) 2009-2013, 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;
C.PBKDF2 = function (password, salt, keylen, options) {
// Convert to byte arrays
if (password.constructor == String) password = UTF8.stringToBytes(password);
if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
/* else, assume byte arrays already */
// Defaults
var hasher = options && options.hasher || C.SHA1,
iterations = options && options.iterations || 1;
// Pseudo-random function
function PRF(password, salt) {
return C.HMAC(hasher, salt, password, { asBytes: true });
}
// Generate key
var derivedKeyBytes = [],
blockindex = 1;
while (derivedKeyBytes.length < keylen) {
var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
for (var u = block, i = 1; i < iterations; i++) {
u = PRF(password, u);
for (var j = 0; j < block.length; j++) block[j] ^= u[j];
}
derivedKeyBytes = derivedKeyBytes.concat(block);
blockindex++;
}
// Truncate excess bytes
derivedKeyBytes.length = keylen;
return options && options.asBytes ? derivedKeyBytes :
options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
util.bytesToHex(derivedKeyBytes);
};
})();
</script>
<script type="text/javascript">
/*!
* Crypto-JS v2.5.4 HMAC.js
* http://code.google.com/p/crypto-js/
* Copyright (c) 2009-2013, 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;
C.HMAC = function (hasher, message, key, options) {
// Convert to byte arrays
if (message.constructor == String) message = UTF8.stringToBytes(message);
if (key.constructor == String) key = UTF8.stringToBytes(key);
/* else, assume byte arrays already */
// Allow arbitrary length keys
if (key.length > hasher._blocksize * 4)
key = hasher(key, { asBytes: true });
// XOR keys with pad constants
var okey = key.slice(0),
ikey = key.slice(0);
for (var i = 0; i < hasher._blocksize * 4; i++) {
okey[i] ^= 0x5C;
ikey[i] ^= 0x36;
}
var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true });
return options && options.asBytes ? hmacbytes :
options && options.asString ? Binary.bytesToString(hmacbytes) :
util.bytesToHex(hmacbytes);
};
})();
</script>
<script type="text/javascript">
/*!
* Crypto-JS v2.5.4 AES.js
* http://code.google.com/p/crypto-js/
* Copyright (c) 2009-2013, 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;
// Precomputed SBOX
var SBOX = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16];
// Compute inverse SBOX lookup table
for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
// Compute multiplication in GF(2^8) lookup tables
var MULT2 = [],
MULT3 = [],
MULT9 = [],
MULTB = [],
MULTD = [],
MULTE = [];
function xtime(a, b) {
for (var result = 0, i = 0; i < 8; i++) {
if (b & 1) result ^= a;
var hiBitSet = a & 0x80;
a = (a << 1) & 0xFF;
if (hiBitSet) a ^= 0x1b;
b >>>= 1;
}
return result;
}
for (var i = 0; i < 256; i++) {
MULT2[i] = xtime(i, 2);
MULT3[i] = xtime(i, 3);
MULT9[i] = xtime(i, 9);
MULTB[i] = xtime(i, 0xB);
MULTD[i] = xtime(i, 0xD);
MULTE[i] = xtime(i, 0xE);
}
// Precomputed RCon lookup
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
// Inner state
var state = [[], [], [], []],
keylength,
nrounds,
keyschedule;
var AES = C.AES = {
/**
* Public API
*/
encrypt: function (message, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions) mode.fixOptions(options);
var
// Convert to bytes if message is a string
m = (
message.constructor == String ?
UTF8.stringToBytes(message) :
message
),
// Generate random IV
iv = options.iv || util.randomBytes(AES._blocksize * 4),
// Generate key
k = (
password.constructor == String ?
// Derive key from pass-phrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password
);
// Encrypt
AES._init(k);
mode.encrypt(AES, m, iv);
// Return ciphertext
m = options.iv ? m : iv.concat(m);
return (options && options.asBytes) ? m : util.bytesToBase64(m);
},
decrypt: function (ciphertext, password, options) {
options = options || {};
// Determine mode
var mode = options.mode || new C.mode.OFB;
// Allow mode to override options
if (mode.fixOptions) mode.fixOptions(options);
var
// Convert to bytes if ciphertext is a string
c = (
ciphertext.constructor == String ?
util.base64ToBytes(ciphertext) :
ciphertext
),
// Separate IV and message
iv = options.iv || c.splice(0, AES._blocksize * 4),
// Generate key
k = (
password.constructor == String ?
// Derive key from pass-phrase
C.PBKDF2(password, iv, 32, { asBytes: true }) :
// else, assume byte array representing cryptographic key
password
);
// Decrypt
AES._init(k);
mode.decrypt(AES, c, iv);
// Return plaintext
return (options && options.asBytes) ? c : UTF8.bytesToString(c);
},
/**
* Package private methods and properties
*/
_blocksize: 4,
_encryptblock: function (m, offset) {
// Set input
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = m[offset + col * 4 + row];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[col][row];
}
for (var round = 1; round < nrounds; round++) {
// Sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = SBOX[state[row][col]];
}
// Shift rows
state[1].push(state[1].shift());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].unshift(state[3].pop());
// Mix columns
for (var col = 0; col < 4; col++) {
var s0 = state[0][col],
s1 = state[1][col],
s2 = state[2][col],
s3 = state[3][col];
state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[round * 4 + col][row];
}
}
// Sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = SBOX[state[row][col]];
}
// Shift rows
state[1].push(state[1].shift());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].unshift(state[3].pop());
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
}
// Set output
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
m[offset + col * 4 + row] = state[row][col];
}
},
_decryptblock: function (c, offset) {
// Set input
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = c[offset + col * 4 + row];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
}
for (var round = 1; round < nrounds; round++) {
// Inv shift rows
state[1].unshift(state[1].pop());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].push(state[3].shift());
// Inv sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = INVSBOX[state[row][col]];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
}
// Inv mix columns
for (var col = 0; col < 4; col++) {
var s0 = state[0][col],
s1 = state[1][col],
s2 = state[2][col],
s3 = state[3][col];
state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
}
}
// Inv shift rows
state[1].unshift(state[1].pop());
state[2].push(state[2].shift());
state[2].push(state[2].shift());
state[3].push(state[3].shift());
// Inv sub bytes
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] = INVSBOX[state[row][col]];
}
// Add round key
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++)
state[row][col] ^= keyschedule[col][row];
}
// Set output
for (var row = 0; row < AES._blocksize; row++) {
for (var col = 0; col < 4; col++)
c[offset + col * 4 + row] = state[row][col];
}
},
/**
* Private methods
*/
_init: function (k) {
keylength = k.length / 4;
nrounds = keylength + 6;
AES._keyexpansion(k);
},
// Generate a key schedule
_keyexpansion: function (k) {
keyschedule = [];
for (var row = 0; row < keylength; row++) {
keyschedule[row] = [
k[row * 4],
k[row * 4 + 1],
k[row * 4 + 2],
k[row * 4 + 3]
];
}
for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
var temp = [
keyschedule[row - 1][0],
keyschedule[row - 1][1],
keyschedule[row - 1][2],
keyschedule[row - 1][3]
];
if (row % keylength == 0) {
// Rot word
temp.push(temp.shift());
// Sub word
temp[0] = SBOX[temp[0]];
temp[1] = SBOX[temp[1]];
temp[2] = SBOX[temp[2]];
temp[3] = SBOX[temp[3]];
temp[0] ^= RCON[row / keylength];
} else if (keylength > 6 && row % keylength == 4) {
// Sub word
temp[0] = SBOX[temp[0]];
temp[1] = SBOX[temp[1]];
temp[2] = SBOX[temp[2]];
temp[3] = SBOX[temp[3]];
}
keyschedule[row] = [
keyschedule[row - keylength][0] ^ temp[0],
keyschedule[row - keylength][1] ^ temp[1],
keyschedule[row - keylength][2] ^ temp[2],
keyschedule[row - keylength][3] ^ temp[3]
];
}
}
};
})();
</script>
<script type="text/javascript">
/*!
* Crypto-JS 2.5.4 BlockModes.js
* contribution from Simon Greatrix
*/
(function (C) {
// Create pad namespace
var C_pad = C.pad = {};
// Calculate the number of padding bytes required.
function _requiredPadding(cipher, message) {
var blockSizeInBytes = cipher._blocksize * 4;
var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
return reqd;
}
// Remove padding when the final byte gives the number of padding bytes.
var _unpadLength = function (cipher, message, alg, padding) {
var pad = message.pop();
if (pad == 0) {
throw new Error("Invalid zero-length padding specified for " + alg
+ ". Wrong cipher specification or key used?");
}
var maxPad = cipher._blocksize * 4;
if (pad > maxPad) {
throw new Error("Invalid padding length of " + pad
+ " specified for " + alg
+ ". Wrong cipher specification or key used?");
}
for (var i = 1; i < pad; i++) {
var b = message.pop();
if (padding != undefined && padding != b) {
throw new Error("Invalid padding byte of 0x" + b.toString(16)
+ " specified for " + alg
+ ". Wrong cipher specification or key used?");
}
}
};
// No-operation padding, used for stream ciphers
C_pad.NoPadding = {
pad: function (cipher, message) { },
unpad: function (cipher, message) { }
};
// Zero Padding.
//
// If the message is not an exact number of blocks, the final block is
// completed with 0x00 bytes. There is no unpadding.
C_pad.ZeroPadding = {
pad: function (cipher, message) {
var blockSizeInBytes = cipher._blocksize * 4;
var reqd = message.length % blockSizeInBytes;
if (reqd != 0) {
for (reqd = blockSizeInBytes - reqd; reqd > 0; reqd--) {
message.push(0x00);
}
}
},
unpad: function (cipher, message) {
while (message[message.length - 1] == 0) {
message.pop();
}
}
};
// ISO/IEC 7816-4 padding.
//
// Pads the plain text with an 0x80 byte followed by as many 0x00
// bytes are required to complete the block.
C_pad.iso7816 = {
pad: function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
message.push(0x80);
for (; reqd > 1; reqd--) {
message.push(0x00);
}
},
unpad: function (cipher, message) {
var padLength;
for (padLength = cipher._blocksize * 4; padLength > 0; padLength--) {
var b = message.pop();
if (b == 0x80) return;
if (b != 0x00) {
throw new Error("ISO-7816 padding byte must be 0, not 0x" + b.toString(16) + ". Wrong cipher specification or key used?");
}
}
throw new Error("ISO-7816 padded beyond cipher block size. Wrong cipher specification or key used?");
}
};
// ANSI X.923 padding
//
// The final block is padded with zeros except for the last byte of the
// last block which contains the number of padding bytes.
C_pad.ansix923 = {
pad: function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 1; i < reqd; i++) {
message.push(0x00);
}
message.push(reqd);
},
unpad: function (cipher, message) {
_unpadLength(cipher, message, "ANSI X.923", 0);
}
};
// ISO 10126
//
// The final block is padded with random bytes except for the last
// byte of the last block which contains the number of padding bytes.
C_pad.iso10126 = {
pad: function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 1; i < reqd; i++) {
message.push(Math.floor(Math.random() * 256));
}
message.push(reqd);
},
unpad: function (cipher, message) {
_unpadLength(cipher, message, "ISO 10126", undefined);
}
};
// PKCS7 padding
//
// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
// value of each added byte is the number of bytes that are added,
// i.e. N bytes, each of value N are added.
C_pad.pkcs7 = {
pad: function (cipher, message) {
var reqd = _requiredPadding(cipher, message);
for (var i = 0; i < reqd; i++) {
message.push(reqd);
}
},
unpad: function (cipher, message) {
_unpadLength(cipher, message, "PKCS 7", message[message.length - 1]);
}
};
// Create mode namespace
var C_mode = C.mode = {};
/**
* Mode base "class".
*/
var Mode = C_mode.Mode = function (padding) {
if (padding) {
this._padding = padding;
}
};
Mode.prototype = {
encrypt: function (cipher, m, iv) {
this._padding.pad(cipher, m);
this._doEncrypt(cipher, m, iv);
},
decrypt: function (cipher, m, iv) {
this._doDecrypt(cipher, m, iv);
this._padding.unpad(cipher, m);
},
// Default padding
_padding: C_pad.iso7816
};
/**
* Electronic Code Book mode.
*
* ECB applies the cipher directly against each block of the input.
*
* ECB does not require an initialization vector.
*/
var ECB = C_mode.ECB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var ECB_prototype = ECB.prototype = new Mode;
// Concrete steps for Mode template
ECB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Encrypt each block
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
cipher._encryptblock(m, offset);
}
};
ECB_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Decrypt each block
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
cipher._decryptblock(c, offset);
}
};
// ECB never uses an IV
ECB_prototype.fixOptions = function (options) {
options.iv = [];
};
/**
* Cipher block chaining
*
* The first block is XORed with the IV. Subsequent blocks are XOR with the
* previous cipher output.
*/
var CBC = C_mode.CBC = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CBC_prototype = CBC.prototype = new Mode;
// Concrete steps for Mode template
CBC_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// Encrypt each block
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
if (offset == 0) {
// XOR first block using IV
for (var i = 0; i < blockSizeInBytes; i++)
m[i] ^= iv[i];
} else {
// XOR this block using previous crypted block
for (var i = 0; i < blockSizeInBytes; i++)
m[offset + i] ^= m[offset + i - blockSizeInBytes];
}
// Encrypt block
cipher._encryptblock(m, offset);
}
};
CBC_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
// At the start, the previously crypted block is the IV
var prevCryptedBlock = iv;
// Decrypt each block
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
// Save this crypted block
var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
// Decrypt block
cipher._decryptblock(c, offset);
// XOR decrypted block using previous crypted block
for (var i = 0; i < blockSizeInBytes; i++) {
c[offset + i] ^= prevCryptedBlock[i];
}
prevCryptedBlock = thisCryptedBlock;
}
};
/**
* Cipher feed back
*
* The cipher output is XORed with the plain text to produce the cipher output,
* which is then fed back into the cipher to produce a bit pattern to XOR the
* next block with.
*
* This is a stream cipher mode and does not require padding.
*/
var CFB = C_mode.CFB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CFB_prototype = CFB.prototype = new Mode;
// Override padding
CFB_prototype._padding = C_pad.NoPadding;
// Concrete steps for Mode template
CFB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < m.length; i++) {
var j = i % blockSizeInBytes;
if (j == 0) cipher._encryptblock(keystream, 0);
m[i] ^= keystream[j];
keystream[j] = m[i];
}
};
CFB_prototype._doDecrypt = function (cipher, c, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < c.length; i++) {
var j = i % blockSizeInBytes;
if (j == 0) cipher._encryptblock(keystream, 0);
var b = c[i];
c[i] ^= keystream[j];
keystream[j] = b;
}
};
/**
* Output feed back
*
* The cipher repeatedly encrypts its own output. The output is XORed with the
* plain text to produce the cipher text.
*
* This is a stream cipher mode and does not require padding.
*/
var OFB = C_mode.OFB = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var OFB_prototype = OFB.prototype = new Mode;
// Override padding
OFB_prototype._padding = C_pad.NoPadding;
// Concrete steps for Mode template
OFB_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4,
keystream = iv.slice(0);
// Encrypt each byte
for (var i = 0; i < m.length; i++) {
// Generate keystream
if (i % blockSizeInBytes == 0)
cipher._encryptblock(keystream, 0);
// Encrypt byte
m[i] ^= keystream[i % blockSizeInBytes];
}
};
OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;
/**
* Counter
* @author Gergely Risko
*
* After every block the last 4 bytes of the IV is increased by one
* with carry and that IV is used for the next block.
*
* This is a stream cipher mode and does not require padding.
*/
var CTR = C_mode.CTR = function () {
// Call parent constructor
Mode.apply(this, arguments);
};
// Inherit from Mode
var CTR_prototype = CTR.prototype = new Mode;
// Override padding
CTR_prototype._padding = C_pad.NoPadding;
CTR_prototype._doEncrypt = function (cipher, m, iv) {
var blockSizeInBytes = cipher._blocksize * 4;
var counter = iv.slice(0);
for (var i = 0; i < m.length; ) {
// do not lose iv
var keystream = counter.slice(0);
// Generate keystream for next block
cipher._encryptblock(keystream, 0);
// XOR keystream with block
for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
m[i] ^= keystream[j];
}
// Increase counter
if (++(counter[blockSizeInBytes - 1]) == 256) {
counter[blockSizeInBytes - 1] = 0;
if (++(counter[blockSizeInBytes - 2]) == 256) {
counter[blockSizeInBytes - 2] = 0;
if (++(counter[blockSizeInBytes - 3]) == 256) {
counter[blockSizeInBytes - 3] = 0;
++(counter[blockSizeInBytes - 4]);
}
}
}
}
};
CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;
})(Crypto);
</script>
<script type="text/javascript">
/*!
* Crypto-JS v2.0.0 RIPEMD-160
* 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">
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/faa10f0f6a1fff0b9a99fffb9bc30cee33b17212/src/ecdsa.js
/*!
* 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
// q instanceof BigInteger
// x instanceof BigInteger
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);
};
// D.1.4 91
/**
* return a sqrt root - the routine verifies that the calculation
* returns the right value - if none exists it returns null.
*
* Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
* Ported to JavaScript by bitaddress.org
*/
ec.FieldElementFp.prototype.sqrt = function () {
if (!this.q.testBit(0)) throw new Error("even value of q");
// p mod 4 == 3
if (this.q.testBit(1)) {
// z = g^(u+1) + p, p = 4u + 3
var z = new ec.FieldElementFp(this.q, this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), this.q));
return z.square().equals(this) ? z : null;
}
// p mod 4 == 1
var qMinusOne = this.q.subtract(BigInteger.ONE);
var legendreExponent = qMinusOne.shiftRight(1);
if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) return null;
var u = qMinusOne.shiftRight(2);
var k = u.shiftLeft(1).add(BigInteger.ONE);
var Q = this.x;
var fourQ = Q.shiftLeft(2).mod(this.q);
var U, V;
do {
var rand = new SecureRandom();
var P;
do {
P = new BigInteger(this.q.bitLength(), rand);
}
while (P.compareTo(this.q) >= 0 || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne)));
var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k);
U = result[0];
V = result[1];
if (V.multiply(V).mod(this.q).equals(fourQ)) {
// Integer division by 2, mod q
if (V.testBit(0)) {
V = V.add(this.q);
}
V = V.shiftRight(1);
return new ec.FieldElementFp(this.q, V);
}
}
while (U.equals(BigInteger.ONE) || U.equals(qMinusOne));
return null;
};
/*
* Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
* Ported to JavaScript by bitaddress.org
*/
ec.FieldElementFp.fastLucasSequence = function (p, P, Q, k) {
// TODO Research and apply "common-multiplicand multiplication here"
var n = k.bitLength();
var s = k.getLowestSetBit();
var Uh = BigInteger.ONE;
var Vl = BigInteger.TWO;
var Vh = P;
var Ql = BigInteger.ONE;
var Qh = BigInteger.ONE;
for (var j = n - 1; j >= s + 1; --j) {
Ql = Ql.multiply(Qh).mod(p);
if (k.testBit(j)) {
Qh = Ql.multiply(Q).mod(p);
Uh = Uh.multiply(Vh).mod(p);
Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p);
Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p);
}
else {
Qh = Ql;
Uh = Uh.multiply(Vl).subtract(Ql).mod(p);
Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p);
Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p);
}
}
Ql = Ql.multiply(Qh).mod(p);
Qh = Ql.multiply(Q).mod(p);
Uh = Uh.multiply(Vl).subtract(Ql).mod(p);
Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p);
Ql = Ql.multiply(Qh).mod(p);
for (var j = 1; j <= s; ++j) {
Uh = Uh.multiply(Vl).mod(p);
Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p);
Ql = Ql.multiply(Ql).mod(p);
}
return [Uh, Vl];
};
// ----------------
// ECPointFp constructor
ec.PointFp = function (curve, x, y, z, compressed) {
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;
// compression flag
this.compressed = !!compressed;
};
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.toString = function () {
return '(' + this.getX().toBigInteger().toString() + ',' + this.getY().toBigInteger().toString() + ')';
};
/**
* Validate an elliptic curve point.
*
* See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive
*/
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
// compressed support added by bitaddress.org
ec.CurveFp.prototype.decodePointHex = function (s) {
var firstByte = parseInt(s.substr(0, 2), 16);
switch (firstByte) { // first byte
case 0:
return this.infinity;
case 2: // compressed
case 3: // compressed
var yTilde = firstByte & 1;
var xHex = s.substr(2, s.length - 2);
var X1 = new BigInteger(xHex, 16);
return this.decompressPoint(yTilde, X1);
case 4: // uncompressed
case 6: // hybrid
case 7: // hybrid
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;
}
};
/*
* Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
* Ported to JavaScript by bitaddress.org
*
* Number yTilde
* BigInteger X1
*/
ec.CurveFp.prototype.decompressPoint = function (yTilde, X1) {
var x = this.fromBigInteger(X1);
var alpha = x.multiply(x.square().add(this.getA())).add(this.getB());
var beta = alpha.sqrt();
// if we can't find a sqrt we haven't got a point on the curve - run!
if (beta == null) throw new Error("Invalid point compression");
var betaValue = beta.toBigInteger();
var bit0 = betaValue.testBit(0) ? 1 : 0;
if (bit0 != yTilde) {
// Use the other root
beta = this.fromBigInteger(this.getQ().subtract(betaValue));
}
return new ec.PointFp(this, x, beta, null, true);
};
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. v1.3
*
* 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 (this.s < 0) ? -r : 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) --- //
// https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js
// BigInteger monkey patching
BigInteger.valueOf = nbv;
/**
* Returns a byte array representation of the big integer.
*
* This returns the absolute of the contained value in big endian
* form. A value of zero results in an empty array.
*/
BigInteger.prototype.toByteArrayUnsigned = function () {
var ba = this.abs().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;
}
};
/**
* Turns a byte array into a big integer.
*
* This function will interpret a byte array as a big integer in big
* endian notation and ignore leading zeros.
*/
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);
}
};
/**
* Converts big integer to signed byte representation.
*
* The format for this value uses a the most significant bit as a sign
* bit. If the most significant bit is already occupied by the
* absolute value, an extra byte is prepended and the sign bit is set
* there.
*
* Examples:
*
* 0 => 0x00
* 1 => 0x01
* -1 => 0x81
* 127 => 0x7f
* -127 => 0xff
* 128 => 0x0080
* -128 => 0x8080
* 255 => 0x00ff
* -255 => 0x80ff
* 16300 => 0x3fac
* -16300 => 0xbfac
* 62300 => 0x00f35c
* -62300 => 0x80f35c
*/
BigInteger.prototype.toByteArraySigned = function () {
var val = this.abs().toByteArrayUnsigned();
var neg = this.compareTo(BigInteger.ZERO) < 0;
if (neg) {
if (val[0] & 0x80) {
val.unshift(0x80);
} else {
val[0] |= 0x80;
}
} else {
if (val[0] & 0x80) {
val.unshift(0x00);
}
}
return val;
};
/**
* Parse a signed big integer byte representation.
*
* For details on the format please see BigInteger.toByteArraySigned.
*/
BigInteger.fromByteArraySigned = function (ba) {
// Check for negative value
if (ba[0] & 0x80) {
// Remove sign bit
ba[0] &= 0x7f;
return BigInteger.fromByteArrayUnsigned(ba).negate();
} else {
return BigInteger.fromByteArrayUnsigned(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">
/*
Copyright (c) 2011 Stefan Thomas
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.
*/
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/1a7fc9d063f864058809d06ef4542af40be3558f/src/bitcoin.js
(function (exports) {
var Bitcoin = exports;
})(
'object' === typeof module ? module.exports : (window.Bitcoin = {})
);
</script>
<script type="text/javascript">
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/c952aaeb3ee472e3776655b8ea07299ebed702c7/src/base58.js
(function (Bitcoin) {
Bitcoin.Base58 = {
alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/,
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;
}
return chars.join('');
},
/**
* 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) {
var bi = BigInteger.valueOf(0);
var leadingZerosNum = 0;
for (var i = input.length - 1; i >= 0; i--) {
var alphaIndex = B58.alphabet.indexOf(input[i]);
if (alphaIndex < 0) {
throw "Invalid character";
}
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;
}
};
var B58 = Bitcoin.Base58;
})(
'undefined' != typeof Bitcoin ? Bitcoin : module.exports
);
</script>
<script type="text/javascript">
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/address.js
Bitcoin.Address = function (bytes) {
if ("string" == typeof bytes) {
bytes = Bitcoin.Address.decodeString(bytes);
}
this.hash = bytes;
this.version = Bitcoin.Address.networkVersion;
};
Bitcoin.Address.networkVersion = 0x1E; // mainnet
/**
* Serialize this object as a standard Bitcoin address.
*
* Returns the address as a base58-encoded string in the standardized format.
*/
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);
};
/**
* Parse a Bitcoin address contained in a string.
*/
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;
};
</script>
<script type="text/javascript">
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/e90780d3d3b8fc0d027d2bcb38b80479902f223e/src/ecdsa.js
Bitcoin.ECDSA = (function () {
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
var rng = new SecureRandom();
var P_OVER_FOUR = null;
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);
},
verify: function (hash, sig, pubkey) {
var r, s;
if (Bitcoin.Util.isArray(sig)) {
var obj = ECDSA.parseSig(sig);
r = obj.r;
s = obj.s;
} else if ("object" === typeof sig && sig.r && sig.s) {
r = sig.r;
s = sig.s;
} else {
throw "Invalid value for signature";
}
var Q;
if (pubkey instanceof ec.PointFp) {
Q = pubkey;
} else if (Bitcoin.Util.isArray(pubkey)) {
Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey);
} else {
throw "Invalid format for pubkey value, must be byte array or ec.PointFp";
}
var e = BigInteger.fromByteArrayUnsigned(hash);
return ECDSA.verifyRaw(e, r, s, Q);
},
verifyRaw: function (e, r, s, Q) {
var n = ecparams.getN();
var G = ecparams.getG();
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);
// TODO(!!!): For some reason Shamir's trick isn't working with
// signed message verification!? Probably an implementation
// error!
//var point = implShamirsTrick(G, u1, Q, u2);
var point = G.multiply(u1).add(Q.multiply(u2));
var v = point.getX().toBigInteger().mod(n);
return v.equals(r);
},
/**
* Serialize a signature into DER format.
*
* Takes two BigIntegers representing r and s and returns a byte array.
*/
serializeSig: function (r, s) {
var rBa = r.toByteArraySigned();
var sBa = s.toByteArraySigned();
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;
},
/**
* Parses a byte array containing a DER-encoded signature.
*
* This function will return an object of the form:
*
* {
* r: BigInteger,
* s: BigInteger
* }
*/
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 };
},
parseSigCompact: function (sig) {
if (sig.length !== 65) {
throw "Signature has the wrong length";
}
// Signature is prefixed with a type byte storing three bits of
// information.
var i = sig[0] - 27;
if (i < 0 || i > 7) {
throw "Invalid signature type";
}
var n = ecparams.getN();
var r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n);
var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n);
return { r: r, s: s, i: i };
},
/**
* Recover a public key from a signature.
*
* See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public
* Key Recovery Operation".
*
* http://www.secg.org/download/aid-780/sec1-v2.pdf
*/
recoverPubKey: function (r, s, hash, i) {
// The recovery parameter i has two bits.
i = i & 3;
// The less significant bit specifies whether the y coordinate
// of the compressed point is even or not.
var isYEven = i & 1;
// The more significant bit specifies whether we should use the
// first or second candidate key.
var isSecondKey = i >> 1;
var n = ecparams.getN();
var G = ecparams.getG();
var curve = ecparams.getCurve();
var p = curve.getQ();
var a = curve.getA().toBigInteger();
var b = curve.getB().toBigInteger();
// We precalculate (p + 1) / 4 where p is if the field order
if (!P_OVER_FOUR) {
P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4));
}
// 1.1 Compute x
var x = isSecondKey ? r.add(n) : r;
// 1.3 Convert x to point
var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p);
var beta = alpha.modPow(P_OVER_FOUR, p);
var xorOdd = beta.isEven() ? (i % 2) : ((i + 1) % 2);
// If beta is even, but y isn't or vice versa, then convert it,
// otherwise we're done and y == beta.
var y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta);
// 1.4 Check that nR is at infinity
var R = new EllipticCurve.PointFp(curve,
curve.fromBigInteger(x),
curve.fromBigInteger(y));
R.validate();
// 1.5 Compute e from M
var e = BigInteger.fromByteArrayUnsigned(hash);
var eNeg = BigInteger.ZERO.subtract(e).mod(n);
// 1.6 Compute Q = r^-1 (sR - eG)
var rInv = r.modInverse(n);
var Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv);
Q.validate();
if (!ECDSA.verifyRaw(e, r, s, Q)) {
throw "Pubkey recovery unsuccessful";
}
var pubKey = new Bitcoin.ECKey();
pubKey.pub = Q;
return pubKey;
},
/**
* Calculate pubkey extraction parameter.
*
* When extracting a pubkey from a signature, we have to
* distinguish four different cases. Rather than putting this
* burden on the verifier, Bitcoin includes a 2-bit value with the
* signature.
*
* This function simply tries all four cases and returns the value
* that resulted in a successful pubkey recovery.
*/
calcPubkeyRecoveryParam: function (address, r, s, hash) {
for (var i = 0; i < 4; i++) {
try {
var pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i);
if (pubkey.getBitcoinAddress().toString() == address) {
return i;
}
} catch (e) { }
}
throw "Unable to find valid recovery factor";
}
};
return ECDSA;
})();
</script>
<script type="text/javascript">
//https://raw.github.com/pointbiz/bitcoinjs-lib/9b2f94a028a7bc9bed94e0722563e9ff1d8e8db8/src/eckey.js
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) {
var bytes = null;
if (ECKey.isWalletImportFormat(input)) {
bytes = ECKey.decodeWalletImportFormat(input);
} else if (ECKey.isCompressedWalletImportFormat(input)) {
bytes = ECKey.decodeCompressedWalletImportFormat(input);
this.compressed = true;
} else if (ECKey.isMiniFormat(input)) {
bytes = Crypto.SHA256(input, { asBytes: true });
} else if (ECKey.isHexFormat(input)) {
bytes = Crypto.util.hexToBytes(input);
} else if (ECKey.isBase64Format(input)) {
bytes = Crypto.util.base64ToBytes(input);
}
if (bytes == null || bytes.length != 32) {
this.priv = null;
} else {
// Prepend zero byte to prevent interpretation as negative integer
this.priv = BigInteger.fromByteArrayUnsigned(bytes);
}
}
this.compressed = (this.compressed == undefined) ? !!ECKey.compressByDefault : this.compressed;
};
ECKey.privateKeyPrefix = 0x9E; // mainnet 0xb0 testnet 0xEF
/**
* Whether public keys should be returned compressed by default.
*/
ECKey.compressByDefault = false;
/**
* Set whether the public key should be returned compressed or not.
*/
ECKey.prototype.setCompressed = function (v) {
this.compressed = !!v;
if (this.pubPoint) this.pubPoint.compressed = this.compressed;
return this;
};
/*
* Return public key as a byte array in DER encoding
*/
ECKey.prototype.getPub = function () {
if (this.compressed) {
if (this.pubComp) return this.pubComp;
return this.pubComp = this.getPubPoint().getEncoded(1);
} else {
if (this.pubUncomp) return this.pubUncomp;
return this.pubUncomp = this.getPubPoint().getEncoded(0);
}
};
/**
* Return public point as ECPoint object.
*/
ECKey.prototype.getPubPoint = function () {
if (!this.pubPoint) {
this.pubPoint = ecparams.getG().multiply(this.priv);
this.pubPoint.compressed = this.compressed;
}
return this.pubPoint;
};
ECKey.prototype.getPubKeyHex = function () {
if (this.compressed) {
if (this.pubKeyHexComp) return this.pubKeyHexComp;
return this.pubKeyHexComp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase();
} else {
if (this.pubKeyHexUncomp) return this.pubKeyHexUncomp;
return this.pubKeyHexUncomp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase();
}
};
/**
* Get the pubKeyHash for this key.
*
* This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as
* a byte array.
*/
ECKey.prototype.getPubKeyHash = function () {
if (this.compressed) {
if (this.pubKeyHashComp) return this.pubKeyHashComp;
return this.pubKeyHashComp = Bitcoin.Util.sha256ripe160(this.getPub());
} else {
if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp;
return this.pubKeyHashUncomp = Bitcoin.Util.sha256ripe160(this.getPub());
}
};
ECKey.prototype.getBitcoinAddress = function () {
var hash = this.getPubKeyHash();
var addr = new Bitcoin.Address(hash);
return addr.toString();
};
/*
* Takes a public point as a hex string or byte array
*/
ECKey.prototype.setPub = function (pub) {
// byte array
if (Bitcoin.Util.isArray(pub)) {
pub = Crypto.util.bytesToHex(pub).toString().toUpperCase();
}
var ecPoint = ecparams.getCurve().decodePointHex(pub);
this.setCompressed(ecPoint.compressed);
this.pubPoint = ecPoint;
return this;
};
// Sipa Private Key Wallet Import Format
ECKey.prototype.getBitcoinWalletImportFormat = function () {
var bytes = this.getBitcoinPrivateKeyByteArray();
bytes.unshift(ECKey.privateKeyPrefix); // prepend 0x80 byte
if (this.compressed) 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 privWif = Bitcoin.Base58.encode(bytes);
return privWif;
};
// 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.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 {
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());
};
/**
* Parse a wallet import format private key contained in a string.
*/
ECKey.decodeWalletImportFormat = function (privStr) {
var bytes = Bitcoin.Base58.decode(privStr);
var hash = bytes.slice(0, 33);
var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
if (checksum[0] != bytes[33] ||
checksum[1] != bytes[34] ||
checksum[2] != bytes[35] ||
checksum[3] != bytes[36]) {
throw "Checksum validation failed!";
}
var version = hash.shift();
if (version != ECKey.privateKeyPrefix) {
throw "Version " + version + " not supported!";
}
return hash;
};
/**
* Parse a compressed wallet import format private key contained in a string.
*/
ECKey.decodeCompressedWalletImportFormat = function (privStr) {
var bytes = Bitcoin.Base58.decode(privStr);
var hash = bytes.slice(0, 34);
var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
if (checksum[0] != bytes[34] ||
checksum[1] != bytes[35] ||
checksum[2] != bytes[36] ||
checksum[3] != bytes[37]) {
throw "Checksum validation failed!";
}
var version = hash.shift();
if (version != ECKey.privateKeyPrefix) {
throw "Version " + version + " not supported!";
}
hash.pop();
return hash;
};
// 64 characters [0-9A-F]
ECKey.isHexFormat = function (key) {
key = key.toString();
return /^[A-Fa-f0-9]{64}$/.test(key);
};
// 51 characters base58, always starts with a '6'
ECKey.isWalletImportFormat = function (key) {
key = key.toString();
return (ECKey.privateKeyPrefix == 0x9E) ?
(/^6[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key)) :
(/^9[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key));
};
// 52 characters base58
ECKey.isCompressedWalletImportFormat = function (key) {
key = key.toString();
return (ECKey.privateKeyPrefix == 0x9E) ?
(/^T[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key)) :
(/^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key));
};
// 44 characters
ECKey.isBase64Format = function (key) {
key = key.toString();
return (/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test(key));
};
// 22, 26 or 30 characters, always starts with an 'S'
ECKey.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));
};
return ECKey;
})();
</script>
<script type="text/javascript">
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/util.js
// Bitcoin utility functions
Bitcoin.Util = {
/**
* Cross-browser compatibility version of Array.isArray.
*/
isArray: Array.isArray || function (o) {
return Object.prototype.toString.call(o) === '[object Array]';
},
/**
* Create an array of a certain length filled with a specific value.
*/
makeFilledArray: function (len, val) {
var array = [];
var i = 0;
while (i < len) {
array[i++] = val;
}
return array;
},
/**
* Turn an integer into a "var_int".
*
* "var_int" is a variable length integer used by Bitcoin's binary format.
*
* Returns a byte array.
*/
numToVarInt: function (i) {
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]));
}
},
/**
* Parse a Bitcoin value byte array, returning a BigInteger.
*/
valueToBigInt: function (valueBuffer) {
if (valueBuffer instanceof BigInteger) return valueBuffer;
// Prepend zero byte to prevent interpretation as negative integer
return BigInteger.fromByteArrayUnsigned(valueBuffer);
},
/**
* Format a Bitcoin value as a string.
*
* Takes a BigInteger or byte-array and returns that amount of Bitcoins in a
* nice standard formatting.
*
* Examples:
* 12.3555
* 0.1234
* 900.99998888
* 34.00
*/
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;
},
/**
* Parse a floating point string as a Bitcoin value.
*
* Keep in mind that parsing user input is messy. You should always display
* the parsed value back to the user to make sure we understood his input
* correctly.
*/
parseValue: function (valueString) {
// TODO: Detect other number formats (e.g. comma as decimal separator)
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;
},
/**
* Calculate RIPEMD160(SHA256(data)).
*
* Takes an arbitrary byte array as inputs and returns the hash as a byte
* array.
*/
sha256ripe160: function (data) {
return Crypto.RIPEMD160(Crypto.SHA256(data, { asBytes: true }), { asBytes: true });
},
// double sha256
dsha256: function (data) {
return Crypto.SHA256(Crypto.SHA256(data, { asBytes: true }), { asBytes: true });
}
};
</script>
<script type="text/javascript">
/*
* Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
*
* 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.
*/
// https://github.com/cheongwy/node-scrypt-js
(function () {
var MAX_VALUE = 2147483647;
var workerUrl = null;
//function scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen)
/*
* N = Cpu cost
* r = Memory cost
* p = parallelization cost
*
*/
window.Crypto_scrypt = function (passwd, salt, N, r, p, dkLen, callback) {
if (N == 0 || (N & (N - 1)) != 0) throw Error("N must be > 0 and a power of 2");
if (N > MAX_VALUE / 128 / r) throw Error("Parameter N is too large");
if (r > MAX_VALUE / 128 / p) throw Error("Parameter r is too large");
var PBKDF2_opts = { iterations: 1, hasher: Crypto.SHA256, asBytes: true };
var B = Crypto.PBKDF2(passwd, salt, p * 128 * r, PBKDF2_opts);
try {
var i = 0;
var worksDone = 0;
var makeWorker = function () {
if (!workerUrl) {
var code = '(' + scryptCore.toString() + ')()';
var blob;
try {
blob = new Blob([code], { type: "text/javascript" });
} catch (e) {
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
blob = new BlobBuilder();
blob.append(code);
blob = blob.getBlob("text/javascript");
}
workerUrl = URL.createObjectURL(blob);
}
var worker = new Worker(workerUrl);
worker.onmessage = function (event) {
var Bi = event.data[0], Bslice = event.data[1];
worksDone++;
if (i < p) {
worker.postMessage([N, r, p, B, i++]);
}
var length = Bslice.length, destPos = Bi * 128 * r, srcPos = 0;
while (length--) {
B[destPos++] = Bslice[srcPos++];
}
if (worksDone == p) {
callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts));
}
};
return worker;
};
var workers = [makeWorker(), makeWorker()];
workers[0].postMessage([N, r, p, B, i++]);
if (p > 1) {
workers[1].postMessage([N, r, p, B, i++]);
}
} catch (e) {
window.setTimeout(function () {
scryptCore();
callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts));
}, 0);
}
// using this function to enclose everything needed to create a worker (but also invokable directly for synchronous use)
function scryptCore() {
var XY = [], V = [];
if (typeof B === 'undefined') {
onmessage = function (event) {
var data = event.data;
var N = data[0], r = data[1], p = data[2], B = data[3], i = data[4];
var Bslice = [];
arraycopy32(B, i * 128 * r, Bslice, 0, 128 * r);
smix(Bslice, 0, r, N, V, XY);
postMessage([i, Bslice]);
};
} else {
for (var i = 0; i < p; i++) {
smix(B, i * 128 * r, r, N, V, XY);
}
}
function smix(B, Bi, r, N, V, XY) {
var Xi = 0;
var Yi = 128 * r;
var i;
arraycopy32(B, Bi, XY, Xi, Yi);
for (i = 0; i < N; i++) {
arraycopy32(XY, Xi, V, i * Yi, Yi);
blockmix_salsa8(XY, Xi, Yi, r);
}
for (i = 0; i < N; i++) {
var j = integerify(XY, Xi, r) & (N - 1);
blockxor(V, j * Yi, XY, Xi, Yi);
blockmix_salsa8(XY, Xi, Yi, r);
}
arraycopy32(XY, Xi, B, Bi, Yi);
}
function blockmix_salsa8(BY, Bi, Yi, r) {
var X = [];
var i;
arraycopy32(BY, Bi + (2 * r - 1) * 64, X, 0, 64);
for (i = 0; i < 2 * r; i++) {
blockxor(BY, i * 64, X, 0, 64);
salsa20_8(X);
arraycopy32(X, 0, BY, Yi + (i * 64), 64);
}
for (i = 0; i < r; i++) {
arraycopy32(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64);
}
for (i = 0; i < r; i++) {
arraycopy32(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64);
}
}
function R(a, b) {
return (a << b) | (a >>> (32 - b));
}
function salsa20_8(B) {
var B32 = new Array(32);
var x = new Array(32);
var i;
for (i = 0; i < 16; i++) {
B32[i] = (B[i * 4 + 0] & 0xff) << 0;
B32[i] |= (B[i * 4 + 1] & 0xff) << 8;
B32[i] |= (B[i * 4 + 2] & 0xff) << 16;
B32[i] |= (B[i * 4 + 3] & 0xff) << 24;
}
arraycopy(B32, 0, x, 0, 16);
for (i = 8; i > 0; i -= 2) {
x[4] ^= R(x[0] + x[12], 7); x[8] ^= R(x[4] + x[0], 9);
x[12] ^= R(x[8] + x[4], 13); x[0] ^= R(x[12] + x[8], 18);
x[9] ^= R(x[5] + x[1], 7); x[13] ^= R(x[9] + x[5], 9);
x[1] ^= R(x[13] + x[9], 13); x[5] ^= R(x[1] + x[13], 18);
x[14] ^= R(x[10] + x[6], 7); x[2] ^= R(x[14] + x[10], 9);
x[6] ^= R(x[2] + x[14], 13); x[10] ^= R(x[6] + x[2], 18);
x[3] ^= R(x[15] + x[11], 7); x[7] ^= R(x[3] + x[15], 9);
x[11] ^= R(x[7] + x[3], 13); x[15] ^= R(x[11] + x[7], 18);
x[1] ^= R(x[0] + x[3], 7); x[2] ^= R(x[1] + x[0], 9);
x[3] ^= R(x[2] + x[1], 13); x[0] ^= R(x[3] + x[2], 18);
x[6] ^= R(x[5] + x[4], 7); x[7] ^= R(x[6] + x[5], 9);
x[4] ^= R(x[7] + x[6], 13); x[5] ^= R(x[4] + x[7], 18);
x[11] ^= R(x[10] + x[9], 7); x[8] ^= R(x[11] + x[10], 9);
x[9] ^= R(x[8] + x[11], 13); x[10] ^= R(x[9] + x[8], 18);
x[12] ^= R(x[15] + x[14], 7); x[13] ^= R(x[12] + x[15], 9);
x[14] ^= R(x[13] + x[12], 13); x[15] ^= R(x[14] + x[13], 18);
}
for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i];
for (i = 0; i < 16; i++) {
var bi = i * 4;
B[bi + 0] = (B32[i] >> 0 & 0xff);
B[bi + 1] = (B32[i] >> 8 & 0xff);
B[bi + 2] = (B32[i] >> 16 & 0xff);
B[bi + 3] = (B32[i] >> 24 & 0xff);
}
}
function blockxor(S, Si, D, Di, len) {
var i = len >> 6;
while (i--) {
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
}
}
function integerify(B, bi, r) {
var n;
bi += (2 * r - 1) * 64;
n = (B[bi + 0] & 0xff) << 0;
n |= (B[bi + 1] & 0xff) << 8;
n |= (B[bi + 2] & 0xff) << 16;
n |= (B[bi + 3] & 0xff) << 24;
return n;
}
function arraycopy(src, srcPos, dest, destPos, length) {
while (length--) {
dest[destPos++] = src[srcPos++];
}
}
function arraycopy32(src, srcPos, dest, destPos, length) {
var i = length >> 5;
while (i--) {
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
}
}
} // scryptCore
}; // window.Crypto_scrypt
})();
</script>
<style type="text/css">
.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; }
.right { text-align: right; }
.walletarea { display: none; border: 2px solid green; }
.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 20px 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; }
.pubkeyhex { word-wrap: break-word; }
.faqs ol { padding: 0 0 0 25px; }
.faqs li { padding: 3px 0; }
body { font-family: Arial; }
#keyarea { height: 250px; font-family: Arial; }
#keyarea .pubaddress { float: none; display: block; padding: 0; height: auto; }
#keyarea .label { text-decoration: none; }
#keyarea .privwif { float: none; text-align: right; position: relative; padding: 0; }
#keyarea .qrcode_public { float: none; display: block; }
#keyarea .qrcode_private { float: none; display: block; top: 0; text-align: right; }
#keyarea .private { width: 30%; display: table-cell; }
#keyarea .public { width: 30%; display: table-cell; }
#singlearea { font-size: 90%; }
#singlesecret { position: relative; top: -130px; float: right; right: 200px; color: red; font-weight: bolder; font-size: 200%; }
#singleshare { position: relative; top: -110px; float: left; left: 160px; color: green; font-weight: bolder; font-size: 200%; }
#singlesafety { text-align: left; padding: 5px; border-top: 2px solid green; top: -30px; position: relative; }
#main { position: relative; text-align: center; margin: 0px auto; width: 1005px; }
#generate { font-family: Courier New; height: 158px; text-align: left; position: relative; padding: 5px; border: 2px solid green; }
#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: 52px; 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: 104px; 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: #000000; 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: #000000; 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 .btcencryptedkey
{
position: absolute; top: 224px; left: 362px; z-index: 100; font-size: 8px; background-color: transparent;
font-weight:bold; color: #000000; margin: 0;
-webkit-transform-origin:top left; -webkit-transform:rotate(-0deg);
-moz-transform-origin:top left; -moz-transform:rotate(-0deg);
-ms-transform-origin:top left; -ms-transform:rotate(-0deg);
-o-transform-origin:top left; -o-transform:rotate(-0deg);
transform-origin:top left; transform:rotate(-0deg);
}
#bulkarea .body { padding: 5px 0 0 0; }
#bulkarea .format { font-style: italic; font-size: 90%; }
#bulktextarea { font-size: 90%; width: 98%; margin: 4px 0 0 0; }
.bulkquestion { padding: 10px 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: 0; border-top: 2px solid green; }
#brainarea .keyarea { visibility: hidden; min-height: 110px; }
#detailkeyarea { padding: 10px; }
#detailarea { margin: 0; text-align: left; }
#detailarea .notes { text-align: left; font-size: 80%; padding: 0 0 20px 0; }
#detailarea .pubqr .item .label { text-decoration: none; }
#detailarea .pubqr .item { float: left; margin: 10px 0; position: relative; }
#detailarea .pubqr .item.right { float: right; position: relative; top: 0; }
#detailarea .privqr .item .label { text-decoration: none; }
#detailarea .privqr .item { float: left; margin: 0; position: relative; }
#detailarea .privqr .item.right { float: right; position: relative; }
#detailarea .item { margin: 10px 0; position: relative; font-size: 90%; }
#detailarea .item.clear { clear: both; padding-top: 10px; }
#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; }
#detailpubkey { width: 566px; }
#detailbip38commands { display: none; padding-top: 5px; }
#vanityarea { 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; }
#vanitycalc { margin-top: 5px; }
.englishjson { text-align: center; padding: 40px 0 20px 0; }
.unittests { text-align: center; }
.unittests div { width: 894px; font-family: monospace; text-align: left; margin: auto; padding: 5px; border: 1px solid black; }
#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; }
#busyblock { position: fixed; display: none; background: url("data:image/gif;base64,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") #ccc no-repeat center; opacity: 0.4; width: 100%; height: 100%; top: 0; left: 0; z-index: 5000; }
#busyblock.busy { display: block; }
.hide { display: none; }
.show { display: block; }
/* 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; }
.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 { border-bottom: 2px solid green; padding: 10px 2px; margin-bottom: 0; }
.commands .row { padding: 0 0; text-align: left; }
.commands .row.extra { padding-top: 6px; }
.commands span { padding: 0 10px; }
.commands span.print { float: right; }
.commands span.right { float: right; }
.expandable { padding: 10px 15px; text-align: left; cursor: pointer; }
#menu { visibility: hidden; font-size: 90%; }
#culturemenu { text-align: right; padding: 0 20px; }
#culturemenu span { padding: 3px; }
#culturemenu .selected { text-decoration: none; color: #000000; }
#braincommands .row .label { width: 200px; display: inline-block; }
#braincommands .notes { font-size: 80%; display: block; padding: 5px 10px; }
#brainpassphrase { width: 280px; }
#brainpassphraseconfirm { width: 280px; }
#brainwarning { }
#detailcommands { padding: 10px 0; }
#detailcommands span { padding: 0 10px; }
#detailprivkey { width: 250px; }
#detailprivkeypassphrase { width: 250px; }
.paper .commands { border: 2px solid green; }
#bulkstartindex, #paperlimit, #paperlimitperpage { width: 35px; }
#bulklimit { width: 45px; }
.footer { font-family: Arial; font-size: 90%; clear: both; width: 750px; padding: 10px 0 10px 0; margin: 50px auto auto auto; }
.footer div span.item { padding: 10px; }
.footer .authorbtc { float: left; width: 470px; }
.footer .authorbtc span.item { text-align: left; display: block; padding: 0 20px; }
.footer .authorbtc div { position: relative; z-index: 100; }
.footer .authorpgp { position: relative; }
.footer .authorpgp span.item { 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; }
#singlearea { border: 0; }
#singlesafety { border: 0; }
#paperarea .keyarea:first-child { border-top: 2px solid green; }
#paperarea .keyarea.art:first-child { border: 0; }
.pagebreak { height: 1px; }
.paper #logo { display: none; }
.menu, .footer, .commands, #tagline, #faqs, #culturemenu { display: none; }
#detailprivwif { width: 285px; word-wrap: break-word; }
#detailprivwifcomp { width: 285px; word-wrap: break-word; text-align: right; }
#detailarea .privqr .item { width: 285px; }
}
</style>
<style type="text/css"></style><style type="text/css">.cf-hidden { display: none; } .cf-invisible { visibility: hidden; }</style></head>
<body onclick="SecureRandom.seedTime();" onkeypress="SecureRandom.seedTime();" onmousemove="ninja.seeder.seed(event);" style="">
<div id="busyblock"></div>
<div id="main">
<img alt="liteaddress.org" title="liteaddress.org" id="logo" src="data:image/png;base64,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">
<div id="tagline">Open Source JavaScript Client-Side Dogecoin Wallet Generator based on <a href="http://liteaddress.org/">liteaddress.org</a>
<br>
Please feed Doge <b>DRog1</b>DLpQcfB7Tx9Qxkc9qWxK1NGsreHWfCphfN
<br>
Wallet art by <a href="http://www.reddit.com/user/Anacoluthia">Anacoluthia</a>
<br>
Hosting by <a href="http://www.reddit.com/user/Skibumstevo">Skibumstevo</a></div>
<div id="testnet"></div>
<div class="menu" id="menu" style="visibility: visible;">
<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="generate" style="display: none;">
<span id="generatelabelbitcoinaddress">Generating Dogecoin Address...</span><br>
<span id="generatelabelmovemouse">MOVE your mouse around to add some extra randomness...</span><br>
</div>
<div id="wallets">
<div id="singlearea" class="walletarea" style="display: block;">
<div class="commands">
<div id="singlecommands" class="row">
<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" id="singleprint" onclick="window.print();"></span>
</div>
</div>
<div id="keyarea" class="keyarea">
<div class="public">
<div class="pubaddress">
<span class="label" id="singlelabelbitcoinaddress">Dogecoin Address</span>
</div>
<div id="qrcode_public" class="qrcode_public"><canvas width="1320" height="1320" style="width: 132px; height: 132px;"></canvas></div>
<div class="pubaddress">
<span class="output" id="btcaddress">DLSn69EW8KJ8msQwkwNLjFifQ2Y1Pd3VXw</span>
</div>
<div id="singleshare">SHARE</div>
</div>
<div class="private">
<div class="privwif">
<span class="label" id="singlelabelprivatekey">Private Key (Wallet Import Format)</span>
</div>
<div id="qrcode_private" class="qrcode_private"><canvas width="1640" height="1640" style="width: 164px; height: 164px;"></canvas></div>
<div class="privwif">
<span class="output" id="btcprivwif">6KaXL32eqQk4NGFHDSgWe3UnanZvFcEEGpWn7f33TGXKBHVgb9x</span>
</div>
<div id="singlesecret">SECRET</div>
</div>
</div>
<div id="singlesafety">
<p id="singletip1"><b>A Dogecoin wallet</b> is as simple as a single pairing of a Dogecoin address with it's corresponding Dogecoin private key. Such a wallet has been generated for you in your web browser and is displayed above.</p>
<p id="singletip2"><b>To safeguard this wallet</b> you must print or otherwise record the Dogecoin address and private key. It is important to make a backup copy of the private key and store it in a safe location. This site does not have knowledge of your private key. If you are familiar with PGP you can download this all-in-one HTML page and check that you have an authentic version from the author of this site by matching the SHA1 hash of this HTML with the SHA1 hash available in the signed version history document linked on the footer of this site. If you leave/refresh the site or press the "Generate New Address" button then a new private key will be generated and the previously displayed private key will not be retrievable. Your Dogecoin private key should be kept a secret. Whomever you share the private key with has access to spend all the Dogecoins associated with that address. If you print your wallet then store it in a zip lock bag to keep it safe from water. Treat a paper wallet like cash.</p>
<p id="singletip3"><b>Add funds</b> to this wallet by instructing others to send Dogecoins to your Dogecoin address.</p>
<p id="singletip4"><b>Check your balance</b> by going to dogechain.info and entering your Dogecoin address.</p>
<p id="singletip5"><b>Spend your Dogecoins</b> by going to blockchain.info and sweep the full balance of your private key into your account at their website. You can also spend your funds by downloading one of the popular Dogecoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a Dogecoin p2p client and spend funds your key will be bundled with other private keys in the p2p client wallet. When you perform a transaction your change will be sent to another Dogecoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining Dogecoins will be stored there. Satoshi advised that one should never delete a wallet.</p>
</div>
</div>
<div id="paperarea">
<div class="commands">
<div id="papercommands" class="row">
<span><label id="paperlabelhideart">Hide Art?</label> <input type="checkbox" id="paperart" onchange="ninja.wallets.paperwallet.toggleArt(this);"></span>
<span><label id="paperlabeladdressestogenerate">Addresses to generate:</label> <input type="text" id="paperlimit"></span>
<span><input type="button" id="papergenerate" value="Generate" onclick="ninja.wallets.paperwallet.build(document.getElementById(&#39;paperlimit&#39;).value * 1, document.getElementById(&#39;paperlimitperpage&#39;).value * 1, !document.getElementById(&#39;paperart&#39;).checked, document.getElementById(&#39;paperpassphrase&#39;).value);"></span>
<span class="print"><input type="button" name="print" value="Print" id="paperprint" onclick="window.print();"></span>
</div>
<div id="paperadvancedcommands" class="row extra">
<span><label id="paperlabelencrypt">BIP38 Encrypt?</label> <input type="checkbox" id="paperencrypt" onchange="ninja.wallets.paperwallet.toggleEncrypt(this);"></span>
<span><label id="paperlabelBIPpassphrase">Passphrase:</label> <input type="text" id="paperpassphrase"></span>
<span><label id="paperlabeladdressesperpage">Addresses per page:</label> <input type="text" id="paperlimitperpage"></span>
</div>
</div>
<div id="paperkeyarea"></div>
</div>
<div id="bulkarea" class="walletarea">
<div class="commands">
<div id="bulkcommands" class="row">
<span><label id="bulklabelstartindex">Start index:</label> <input type="text" id="bulkstartindex" value="1"></span>
<span><label id="bulklabelrowstogenerate">Rows to generate:</label> <input type="text" id="bulklimit" value="3"></span>
<span><label id="bulklabelcompressed">Compressed addresses?</label> <input type="checkbox" id="bulkcompressed"></span>
<span><input type="button" id="bulkgenerate" value="Generate" onclick="ninja.wallets.bulkwallet.buildCSV(document.getElementById(&#39;bulklimit&#39;).value * 1, document.getElementById(&#39;bulkstartindex&#39;).value * 1, document.getElementById(&#39;bulkcompressed&#39;).checked);"> </span>
<span class="print"><input type="button" name="print" id="bulkprint" value="Print" onclick="window.print();"></span>
</div>
</div>
<div class="body">
<span class="label" id="bulklabelcsv">Comma Separated Values:</span> <span class="format" id="bulklabelformat">Index,Address,Private Key (WIF)</span>
<textarea rows="20" cols="88" id="bulktextarea"></textarea>
</div>
<div class="faqs">
<div id="bulkfaq1" class="bulkfaq">
<div id="bulkq1" class="bulkquestion" onclick="ninja.wallets.bulkwallet.openCloseFaq(1);">
<span id="bulklabelq1">Why should I use a Bulk Wallet to accept Dogecoins on my website?</span>
<div id="bulke1" class="more"></div>
</div>
<div id="bulka1" class="bulkanswer">The traditional approach to accepting Dogecoins on your website requires that you install the official Dogecoin client daemon ("Dogecoind"). Many website hosting packages don't support installing the Dogecoin daemon. Also, running the Dogecoin 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 Dogecoin addresses and not the private keys to your web server. Then you don't have to worry about your Dogecoin 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 id="bulklabelq2">How do I use a Bulk Wallet to accept Dogecoins on my website?</span>
<div id="bulke2" class="more"></div>
</div>
<div id="bulka2" class="bulkanswer">
<ol>
<li id="bulklabela2li1">Use the Bulk Wallet tab to pre-generate a large number of Dogecoin 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 id="bulklabela2li2">Import the Dogecoin 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 Dogecoin addresses as they will be shown to customers.)</li>
<li id="bulklabela2li3">Provide an option on your website's shopping cart for your customer to pay in Dogecoin. When the customer chooses to pay in Dogecoin 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 id="bulklabela2li4">You now need to be notified when the payment arrives. Google "Dogecoin payment notification" and subscribe to at least one Dogecoin 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 Dogecoin 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 id="bulklabela2li5">Dogecoins 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="brainarea" class="walletarea">
<div id="braincommands" class="commands">
<div class="row">
<span id="brainlabelenterpassphrase" 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><label id="brainlabelshow">Show?</label> <input type="checkbox" id="brainpassphraseshow" onchange="ninja.wallets.brainwallet.showToggle(this);"></span>
<span class="print"><input type="button" name="print" id="brainprint" 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 id="brainalgorithm" class="notes right">Algorithm: SHA256(passphrase)</span>
</div>
<div class="row extra"><span id="brainwarning"></span></div>
</div>
<div id="brainkeyarea" class="keyarea">
<div class="public">
<div id="brainqrcodepublic" class="qrcode_public"></div>
<div class="pubaddress">
<span class="label" id="brainlabelbitcoinaddress">Dogecoin 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" id="brainlabelprivatekey">Private Key (Wallet Import Format):</span>
<span class="output" id="brainbtcprivwif"></span>
</div>
</div>
</div>
</div>
<div id="vanityarea" class="walletarea">
<div id="vanitystep1label" class="commands expandable" onclick="ninja.wallets.vanitywallet.openCloseStep(1);">
<span><label id="vanitylabelstep1">Step 1 - Generate your "Step1 Key Pair"</label> <input type="button" id="vanitynewkeypair" value="Generate" onclick="ninja.wallets.vanitywallet.generateKeyPair();"></span>
<div id="vanitystep1icon" class="more"></div>
</div>
<div id="vanitystep1area">
<div>
<span class="label" id="vanitylabelstep1publickey">Step 1 Public Key:</span>
<div class="output pubkeyhex" id="vanitypubkey"></div>
<br><div class="notes" id="vanitylabelstep1pubnotes">Copy and paste the above into the Your-Part-Public-Key field in the Vanity Pool Website.</div>
</div>
<div>
<span class="label" id="vanitylabelstep1privatekey">Step 1 Private Key:</span>
<span class="output" id="vanityprivatekey"></span>
<br><div class="notes" id="vanitylabelstep1privnotes">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 Dogecoin Private Key once the Pool has found your prefix.</div>
</div>
</div>
<div id="vanitystep2label" class="expandable" onclick="ninja.wallets.vanitywallet.openCloseStep(2);">
<span id="vanitylabelstep2calculateyourvanitywallet">Step 2 - Calculate your Vanity Wallet</span>
<div id="vanitystep2icon" class="more"></div>
</div>
<div id="vanitystep2inputs">
<div>
<span id="vanitylabelenteryourpart">Enter Your Part Private Key (generated in Step 1 above and previously saved):</span>
<br><span class="notes" id="vanitylabelnote1">[NOTE: this input box can accept a public key or private key]</span>
</div>
<div><textarea id="vanityinput1" rows="2" cols="90" onfocus="this.select();"></textarea></div>
<div>
<span id="vanitylabelenteryourpoolpart">Enter Pool Part Private Key (from Vanity Pool):</span>
<br><span class="notes" id="vanitylabelnote2">[NOTE: this input box can accept a public key or private key]</span>
</div>
<div><textarea id="vanityinput2" rows="2" cols="90" onfocus="this.select();"></textarea></div>
<div>
<label for="vanityradioadd" id="vanitylabelradioadd">Add</label> <input type="radio" id="vanityradioadd" name="vanityradio" value="add" checked="">
<label for="vanityradiomultiply" id="vanitylabelradiomultiply">Multiply</label> <input type="radio" id="vanityradiomultiply" name="vanityradio" value="multiply">
</div>
<div><input type="button" id="vanitycalc" value="Calculate Vanity Wallet" onclick="ninja.wallets.vanitywallet.addKeys();"></div>
</div>
<div id="vanitystep2area">
<div>
<span class="label" id="vanitylabelbitcoinaddress">Vanity Dogecoin Address:</span>
<span class="output" id="vanityaddress"></span>
<br><div class="notes" id="vanitylabelnotesbitcoinaddress">The above is your new address that should include your required prefix.</div>
</div>
<div>
<span class="label" id="vanitylabelpublickeyhex">Vanity Public Key (HEX):</span>
<span class="output pubkeyhex" id="vanitypublickeyhex"></span>
<br><div class="notes" id="vanitylabelnotespublickeyhex">The above is the Public Key in hexadecimal format. </div>
</div>
<div>
<span class="label" id="vanitylabelprivatekey">Vanity Private Key (WIF):</span>
<span class="output" id="vanityprivatekeywif"></span>
<br><div class="notes" id="vanitylabelnotesprivatekey">The above is the Private Key to load into your wallet. </div>
</div>
</div>
</div>
<div id="detailarea" class="walletarea">
<div id="detailcommands" class="commands">
<span><label id="detaillabelenterprivatekey">Enter Private Key (any format)</label> <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" id="detailprint" value="Print" onclick="window.print();"></span>
<div id="detailbip38commands">
<span><label id="detaillabelpassphrase">Enter BIP38 Passphrase</label> <input type="text" id="detailprivkeypassphrase" value="" onfocus="this.select();" onkeypress="if (event.keyCode == 13) ninja.wallets.detailwallet.viewDetails();"></span>
<span><input type="button" id="detaildecrypt" value="Decrypt BIP38" onclick="ninja.wallets.detailwallet.viewDetails();"></span>
</div>
</div>
<div id="detailkeyarea">
<div class="notes">
<span id="detaillabelnote1">Your Dogecoin 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 Dogecoin 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, BIP38).</span>
<br><br>
<span id="detaillabelnote2">Dogecoin 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.</span>
</div>
<div class="pubqr">
<div class="item">
<span class="label" id="detaillabelbitcoinaddress">Dogecoin Address</span>
<div id="detailqrcodepublic" class="qrcode_public"></div>
<span class="output" id="detailaddress"></span>
</div>
<div class="item right">
<span class="label" id="detaillabelbitcoinaddresscomp">Dogecoin Address Compressed</span>
<div id="detailqrcodepubliccomp" class="qrcode_public"></div>
<span class="output" id="detailaddresscomp"></span>
</div>
</div>
<br><br>
<div class="item clear">
<span class="label" id="detaillabelpublickey">Public Key (130 characters [0-9A-F]):</span>
<span class="output pubkeyhex" id="detailpubkey"></span>
</div>
<div class="item">
<span class="label" id="detaillabelpublickeycomp">Public Key (compressed, 66 characters [0-9A-F]):</span>
<span class="output" id="detailpubkeycomp"></span>
</div>
<hr>
<div class="privqr">
<div class="item">
<span class="label"><span id="detaillabelprivwif">Private Key WIF<br>51 characters base58, starts with a</span> <span id="detailwifprefix">'6'</span></span>
<div id="detailqrcodeprivate" class="qrcode_private"></div>
<span class="output" id="detailprivwif"></span>
</div>
<div class="item right">
<span class="label"><span id="detaillabelprivwifcomp">Private Key WIF Compressed<br>52 characters base58, starts with a</span> <span id="detailcompwifprefix">'T'</span></span>
<div id="detailqrcodeprivatecomp" class="qrcode_private"></div>
<span class="output" id="detailprivwifcomp"></span>
</div>
</div>
<br><br>
<div class="item clear">
<span class="label" id="detaillabelprivhex">Private Key Hexadecimal Format (64 characters [0-9A-F]):</span>
<span class="output" id="detailprivhex"></span>
</div>
<div class="item">
<span class="label" id="detaillabelprivb64">Private Key Base64 (44 characters):</span>
<span class="output" id="detailprivb64"></span>
</div>
<div class="item" style="display: none;" id="detailmini">
<span class="label" id="detaillabelprivmini">Private Key Mini Format (22, 26 or 30 characters, starts with an 'S'):</span>
<span class="output" id="detailprivmini"></span>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var ninja = { wallets: {} };
ninja.privateKey = {
isPrivateKey: function (key) {
return (
Bitcoin.ECKey.isWalletImportFormat(key) ||
Bitcoin.ECKey.isCompressedWalletImportFormat(key) ||
Bitcoin.ECKey.isHexFormat(key) ||
Bitcoin.ECKey.isBase64Format(key) ||
Bitcoin.ECKey.isMiniFormat(key)
);
},
getECKeyFromAdding: function (privKey1, privKey2) {
var n = EllipticCurve.getSECCurveByName("secp256k1").getN();
var ecKey1 = new Bitcoin.ECKey(privKey1);
var ecKey2 = new Bitcoin.ECKey(privKey2);
// if both keys are the same return null
if (ecKey1.getBitcoinHexFormat() == ecKey2.getBitcoinHexFormat()) return null;
if (ecKey1 == null || ecKey2 == null) return null;
var combinedPrivateKey = new Bitcoin.ECKey(ecKey1.priv.add(ecKey2.priv).mod(n));
// compressed when both keys are compressed
if (ecKey1.compressed && ecKey2.compressed) combinedPrivateKey.setCompressed(true);
return combinedPrivateKey;
},
getECKeyFromMultiplying: function (privKey1, privKey2) {
var n = EllipticCurve.getSECCurveByName("secp256k1").getN();
var ecKey1 = new Bitcoin.ECKey(privKey1);
var ecKey2 = new Bitcoin.ECKey(privKey2);
// if both keys are the same return null
if (ecKey1.getBitcoinHexFormat() == ecKey2.getBitcoinHexFormat()) return null;
if (ecKey1 == null || ecKey2 == null) return null;
var combinedPrivateKey = new Bitcoin.ECKey(ecKey1.priv.multiply(ecKey2.priv).mod(n));
// compressed when both keys are compressed
if (ecKey1.compressed && ecKey2.compressed) combinedPrivateKey.setCompressed(true);
return combinedPrivateKey;
},
// 58 base58 characters starting with 6P
isBIP38Format: function (key) {
key = key.toString();
return (/^6P[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{56}$/.test(key));
},
BIP38EncryptedKeyToByteArrayAsync: function (base58Encrypted, passphrase, callback) {
var hex;
try {
hex = Bitcoin.Base58.decode(base58Encrypted);
} catch (e) {
callback(new Error(ninja.translator.get("detailalertnotvalidprivatekey")));
return;
}
// 43 bytes: 2 bytes prefix, 37 bytes payload, 4 bytes checksum
if (hex.length != 43) {
callback(new Error(ninja.translator.get("detailalertnotvalidprivatekey")));
return;
}
// first byte is always 0x01
else if (hex[0] != 0x01) {
callback(new Error(ninja.translator.get("detailalertnotvalidprivatekey")));
return;
}
var expChecksum = hex.slice(-4);
hex = hex.slice(0, -4);
var checksum = Bitcoin.Util.dsha256(hex);
if (checksum[0] != expChecksum[0] || checksum[1] != expChecksum[1] || checksum[2] != expChecksum[2] || checksum[3] != expChecksum[3]) {
callback(new Error(ninja.translator.get("detailalertnotvalidprivatekey")));
return;
}
var isCompPoint = false;
var isECMult = false;
var hasLotSeq = false;
// second byte for non-EC-multiplied key
if (hex[1] == 0x42) {
// key should use compression
if (hex[2] == 0xe0) {
isCompPoint = true;
}
// key should NOT use compression
else if (hex[2] != 0xc0) {
callback(new Error(ninja.translator.get("detailalertnotvalidprivatekey")));
return;
}
}
// second byte for EC-multiplied key
else if (hex[1] == 0x43) {
isECMult = true;
isCompPoint = (hex[2] & 0x20) != 0;
hasLotSeq = (hex[2] & 0x04) != 0;
if ((hex[2] & 0x24) != hex[2]) {
callback(new Error(ninja.translator.get("detailalertnotvalidprivatekey")));
return;
}
}
else {
callback(new Error(ninja.translator.get("detailalertnotvalidprivatekey")));
return;
}
var decrypted;
var AES_opts = { mode: new Crypto.mode.ECB(Crypto.pad.NoPadding), asBytes: true };
var verifyHashAndReturn = function () {
var tmpkey = new Bitcoin.ECKey(decrypted); // decrypted using closure
var base58AddrText = tmpkey.setCompressed(isCompPoint).getBitcoinAddress(); // isCompPoint using closure
checksum = Bitcoin.Util.dsha256(base58AddrText); // checksum using closure
if (checksum[0] != hex[3] || checksum[1] != hex[4] || checksum[2] != hex[5] || checksum[3] != hex[6]) {
callback(new Error(ninja.translator.get("bip38alertincorrectpassphrase"))); // callback using closure
return;
}
callback(tmpkey.getBitcoinPrivateKeyByteArray()); // callback using closure
};
if (!isECMult) {
var addresshash = hex.slice(3, 7);
Crypto_scrypt(passphrase, addresshash, 16384, 8, 8, 64, function (derivedBytes) {
var k = derivedBytes.slice(32, 32 + 32);
decrypted = Crypto.AES.decrypt(hex.slice(7, 7 + 32), k, AES_opts);
for (var x = 0; x < 32; x++) decrypted[x] ^= derivedBytes[x];
verifyHashAndReturn(); //TODO: pass in 'decrypted' as a param
});
}
else {
var ownerentropy = hex.slice(7, 7 + 8);
var ownersalt = !hasLotSeq ? ownerentropy : ownerentropy.slice(0, 4);
Crypto_scrypt(passphrase, ownersalt, 16384, 8, 8, 32, function (prefactorA) {
var passfactor;
if (!hasLotSeq) { // hasLotSeq using closure
passfactor = prefactorA;
} else {
var prefactorB = prefactorA.concat(ownerentropy); // ownerentropy using closure
passfactor = Bitcoin.Util.dsha256(prefactorB);
}
var kp = new Bitcoin.ECKey(passfactor);
var passpoint = kp.setCompressed(true).getPub();
var encryptedpart2 = hex.slice(23, 23 + 16);
var addresshashplusownerentropy = hex.slice(3, 3 + 12);
Crypto_scrypt(passpoint, addresshashplusownerentropy, 1024, 1, 1, 64, function (derived) {
var k = derived.slice(32);
var unencryptedpart2 = Crypto.AES.decrypt(encryptedpart2, k, AES_opts);
for (var i = 0; i < 16; i++) { unencryptedpart2[i] ^= derived[i + 16]; }
var encryptedpart1 = hex.slice(15, 15 + 8).concat(unencryptedpart2.slice(0, 0 + 8));
var unencryptedpart1 = Crypto.AES.decrypt(encryptedpart1, k, AES_opts);
for (var i = 0; i < 16; i++) { unencryptedpart1[i] ^= derived[i]; }
var seedb = unencryptedpart1.slice(0, 0 + 16).concat(unencryptedpart2.slice(8, 8 + 8));
var factorb = Bitcoin.Util.dsha256(seedb);
var ps = EllipticCurve.getSECCurveByName("secp256k1");
var privateKey = BigInteger.fromByteArrayUnsigned(passfactor).multiply(BigInteger.fromByteArrayUnsigned(factorb)).remainder(ps.getN());
decrypted = privateKey.toByteArrayUnsigned();
verifyHashAndReturn();
});
});
}
},
BIP38PrivateKeyToEncryptedKeyAsync: function (base58Key, passphrase, compressed, callback) {
var privKey = new Bitcoin.ECKey(base58Key);
var privKeyBytes = privKey.getBitcoinPrivateKeyByteArray();
var address = privKey.setCompressed(compressed).getBitcoinAddress();
// compute sha256(sha256(address)) and take first 4 bytes
var salt = Bitcoin.Util.dsha256(address).slice(0, 4);
// derive key using scrypt
var AES_opts = { mode: new Crypto.mode.ECB(Crypto.pad.NoPadding), asBytes: true };
Crypto_scrypt(passphrase, salt, 16384, 8, 8, 64, function (derivedBytes) {
for (var i = 0; i < 32; ++i) {
privKeyBytes[i] ^= derivedBytes[i];
}
// 0x01 0x42 + flagbyte + salt + encryptedhalf1 + encryptedhalf2
var flagByte = compressed ? 0xe0 : 0xc0;
var encryptedKey = [0x01, 0x42, flagByte].concat(salt);
encryptedKey = encryptedKey.concat(Crypto.AES.encrypt(privKeyBytes, derivedBytes.slice(32), AES_opts));
encryptedKey = encryptedKey.concat(Bitcoin.Util.dsha256(encryptedKey).slice(0, 4));
callback(Bitcoin.Base58.encode(encryptedKey));
});
},
BIP38GenerateIntermediatePointAsync: function (passphrase, lotNum, sequenceNum, callback) {
var noNumbers = lotNum === null || sequenceNum === null;
var rng = new SecureRandom();
var ownerEntropy, ownerSalt;
if (noNumbers) {
ownerSalt = ownerEntropy = new Array(8);
rng.nextBytes(ownerEntropy);
}
else {
// 1) generate 4 random bytes
ownerSalt = new Array(4);
rng.nextBytes(ownerSalt);
// 2) Encode the lot and sequence numbers as a 4 byte quantity (big-endian):
// lotnumber * 4096 + sequencenumber. Call these four bytes lotsequence.
var lotSequence = BigInteger(4096 * lotNum + sequenceNum).toByteArrayUnsigned();
// 3) Concatenate ownersalt + lotsequence and call this ownerentropy.
var ownerEntropy = ownerSalt.concat(lotSequence);
}
// 4) Derive a key from the passphrase using scrypt
Crypto_scrypt(passphrase, ownerSalt, 16384, 8, 8, 32, function (prefactor) {
// Take SHA256(SHA256(prefactor + ownerentropy)) and call this passfactor
var passfactorBytes = noNumbers ? prefactor : Bitcoin.Util.dsha256(prefactor.concat(ownerEntropy));
var passfactor = BigInteger.fromByteArrayUnsigned(passfactorBytes);
// 5) Compute the elliptic curve point G * passfactor, and convert the result to compressed notation (33 bytes)
var ellipticCurve = EllipticCurve.getSECCurveByName("secp256k1");
var passpoint = ellipticCurve.getG().multiply(passfactor).getEncoded(1);
// 6) Convey ownersalt and passpoint to the party generating the keys, along with a checksum to ensure integrity.
// magic bytes "2C E9 B3 E1 FF 39 E2 51" followed by ownerentropy, and then passpoint
var magicBytes = [0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2, 0x51];
if (noNumbers) magicBytes[7] = 0x53;
var intermediate = magicBytes.concat(ownerEntropy).concat(passpoint);
// base58check encode
intermediate = intermediate.concat(Bitcoin.Util.dsha256(intermediate).slice(0, 4));
callback(Bitcoin.Base58.encode(intermediate));
});
},
BIP38GenerateECAddressAsync: function (intermediate, compressed, callback) {
// decode IPS
var x = Bitcoin.Base58.decode(intermediate);
//if(x.slice(49, 4) !== Bitcoin.Util.dsha256(x.slice(0,49)).slice(0,4)) {
// callback({error: 'Invalid intermediate passphrase string'});
//}
var noNumbers = (x[7] === 0x53);
var ownerEntropy = x.slice(8, 8 + 8);
var passpoint = x.slice(16, 16 + 33);
// 1) Set flagbyte.
// set bit 0x20 for compressed key
// set bit 0x04 if ownerentropy contains a value for lotsequence
var flagByte = (compressed ? 0x20 : 0x00) | (noNumbers ? 0x00 : 0x04);
// 2) Generate 24 random bytes, call this seedb.
var seedB = new Array(24);
var rng = new SecureRandom();
rng.nextBytes(seedB);
// Take SHA256(SHA256(seedb)) to yield 32 bytes, call this factorb.
var factorB = Bitcoin.Util.dsha256(seedB);
// 3) ECMultiply passpoint by factorb. Use the resulting EC point as a public key and hash it into a Bitcoin
// address using either compressed or uncompressed public key methodology (specify which methodology is used
// inside flagbyte). This is the generated Bitcoin address, call it generatedaddress.
var ec = EllipticCurve.getSECCurveByName("secp256k1").getCurve();
var generatedPoint = ec.decodePointHex(ninja.publicKey.getHexFromByteArray(passpoint));
var generatedBytes = generatedPoint.multiply(BigInteger.fromByteArrayUnsigned(factorB)).getEncoded(compressed);
var generatedAddress = (new Bitcoin.Address(Bitcoin.Util.sha256ripe160(generatedBytes))).toString();
// 4) Take the first four bytes of SHA256(SHA256(generatedaddress)) and call it addresshash.
var addressHash = Bitcoin.Util.dsha256(generatedAddress).slice(0, 4);
// 5) Now we will encrypt seedb. Derive a second key from passpoint using scrypt
Crypto_scrypt(passpoint, addressHash.concat(ownerEntropy), 1024, 1, 1, 64, function (derivedBytes) {
// 6) Do AES256Encrypt(seedb[0...15]] xor derivedhalf1[0...15], derivedhalf2), call the 16-byte result encryptedpart1
for (var i = 0; i < 16; ++i) {
seedB[i] ^= derivedBytes[i];
}
var AES_opts = { mode: new Crypto.mode.ECB(Crypto.pad.NoPadding), asBytes: true };
var encryptedPart1 = Crypto.AES.encrypt(seedB.slice(0, 16), derivedBytes.slice(32), AES_opts);
// 7) Do AES256Encrypt((encryptedpart1[8...15] + seedb[16...23]) xor derivedhalf1[16...31], derivedhalf2), call the 16-byte result encryptedseedb.
var message2 = encryptedPart1.slice(8, 8 + 8).concat(seedB.slice(16, 16 + 8));
for (var i = 0; i < 16; ++i) {
message2[i] ^= derivedBytes[i + 16];
}
var encryptedSeedB = Crypto.AES.encrypt(message2, derivedBytes.slice(32), AES_opts);
// 0x01 0x43 + flagbyte + addresshash + ownerentropy + encryptedpart1[0...7] + encryptedpart2
var encryptedKey = [0x01, 0x43, flagByte].concat(addressHash).concat(ownerEntropy).concat(encryptedPart1.slice(0, 8)).concat(encryptedSeedB);
// base58check encode
encryptedKey = encryptedKey.concat(Bitcoin.Util.dsha256(encryptedKey).slice(0, 4));
callback(generatedAddress, Bitcoin.Base58.encode(encryptedKey));
});
}
};
ninja.publicKey = {
isPublicKeyHexFormat: function (key) {
key = key.toString();
return ninja.publicKey.isUncompressedPublicKeyHexFormat(key) || ninja.publicKey.isCompressedPublicKeyHexFormat(key);
},
// 130 characters [0-9A-F] starts with 04
isUncompressedPublicKeyHexFormat: function (key) {
key = key.toString();
return /^04[A-Fa-f0-9]{128}$/.test(key);
},
// 66 characters [0-9A-F] starts with 02 or 03
isCompressedPublicKeyHexFormat: function (key) {
key = key.toString();
return /^0[2-3][A-Fa-f0-9]{64}$/.test(key);
},
getBitcoinAddressFromByteArray: function (pubKeyByteArray) {
var pubKeyHash = Bitcoin.Util.sha256ripe160(pubKeyByteArray);
var addr = new Bitcoin.Address(pubKeyHash);
return addr.toString();
},
getHexFromByteArray: function (pubKeyByteArray) {
return Crypto.util.bytesToHex(pubKeyByteArray).toString().toUpperCase();
},
getByteArrayFromAdding: function (pubKeyHex1, pubKeyHex2) {
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
var curve = ecparams.getCurve();
var ecPoint1 = curve.decodePointHex(pubKeyHex1);
var ecPoint2 = curve.decodePointHex(pubKeyHex2);
// if both points are the same return null
if (ecPoint1.equals(ecPoint2)) return null;
var compressed = (ecPoint1.compressed && ecPoint2.compressed);
var pubKey = ecPoint1.add(ecPoint2).getEncoded(compressed);
return pubKey;
},
getByteArrayFromMultiplying: function (pubKeyHex, ecKey) {
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
var ecPoint = ecparams.getCurve().decodePointHex(pubKeyHex);
var compressed = (ecPoint.compressed && ecKey.compressed);
// if both points are the same return null
ecKey.setCompressed(false);
if (ecPoint.equals(ecKey.getPubPoint())) {
return null;
}
var bigInt = ecKey.priv;
var pubKey = ecPoint.multiply(bigInt).getEncoded(compressed);
return pubKey;
},
// used by unit test
getDecompressedPubKeyHex: function (pubKeyHexComp) {
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
var ecPoint = ecparams.getCurve().decodePointHex(pubKeyHexComp);
var pubByteArray = ecPoint.getEncoded(0);
var pubHexUncompressed = ninja.publicKey.getHexFromByteArray(pubByteArray);
return pubHexUncompressed;
}
};
</script>
<script type="text/javascript">
ninja.seeder = {
// 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.seeder.seedCount++;
// seeding is over now we generate and display the address
if (ninja.seeder.seedCount == ninja.seeder.seedLimit) {
ninja.wallets.singlewallet.open();
// UI
document.getElementById("generate").style.display = "none";
document.getElementById("menu").style.visibility = "visible";
}
},
// 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.seeder.seedCount < ninja.seeder.seedLimit) {
SecureRandom.seedTime();
ninja.seeder.seedCount = ninja.seeder.seedLimit - 1;
ninja.seeder.seed();
}
}
};
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');
var scale = 10.0;
canvas.width = width * scale;
canvas.height = height * scale;
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
var ctx = canvas.getContext('2d');
ctx.scale(scale, scale);
// 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);
}
}
}
};
ninja.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();
}
};
ninja.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;
};
// use when passing an Array of Functions
ninja.runSerialized = function (functions, onComplete) {
onComplete = onComplete || function () { };
if (functions.length === 0) onComplete();
else {
// run the first function, and make it call this
// function when finished with the rest of the list
var f = functions.shift();
f(function () { ninja.runSerialized(functions, onComplete); });
}
};
ninja.forSerialized = function (initial, max, whatToDo, onComplete) {
onComplete = onComplete || function () { };
if (initial === max) { onComplete(); }
else {
// same idea as runSerialized
whatToDo(initial, function () { ninja.forSerialized(++initial, max, whatToDo, onComplete); });
}
};
// use when passing an Object (dictionary) of Functions
ninja.foreachSerialized = function (collection, whatToDo, onComplete) {
var keys = [];
for (var name in collection) {
keys.push(name);
}
ninja.forSerialized(0, keys.length, function (i, callback) {
whatToDo(keys[i], callback);
}, onComplete);
};
</script>
<script type="text/javascript">
ninja.translator = {
currentCulture: "en",
translate: function (culture) {
var dict = ninja.translator.translations[culture];
if (dict) {
// set current culture
ninja.translator.currentCulture = culture;
// update menu UI
for (var cult in ninja.translator.translations) {
document.getElementById("culture" + cult).setAttribute("class", "");
}
document.getElementById("culture" + culture).setAttribute("class", "selected");
// apply translations
for (var id in dict) {
if (document.getElementById(id) && document.getElementById(id).value) {
document.getElementById(id).value = dict[id];
}
else if (document.getElementById(id)) {
document.getElementById(id).innerHTML = dict[id];
}
}
}
},
get: function (id) {
var translation = ninja.translator.translations[ninja.translator.currentCulture][id];
return translation;
},
translations: {
"en": {
// javascript alerts or messages
"testneteditionactivated": "TESTNET EDITION ACTIVATED",
"paperlabelbitcoinaddress": "Litecoin Address:",
"paperlabelprivatekey": "Private Key (Wallet Import Format):",
"paperlabelencryptedkey": "Encrypted Private Key (Password required)",
"bulkgeneratingaddresses": "Generating addresses... ",
"brainalertpassphrasetooshort": "The passphrase you entered is too short.\n\n",
"brainalertpassphrasewarning": "Warning: Choosing a strong passphrase is important to avoid brute force attempts to guess your passphrase and steal your litecoins.",
"brainalertpassphrasedoesnotmatch": "The passphrase does not match the confirm passphrase.",
"detailalertnotvalidprivatekey": "The text you entered is not a valid Private Key",
"detailconfirmsha256": "The text you entered is not a valid Private Key!\n\nWould you like to use the entered text as a passphrase and create a Private Key using a SHA256 hash of the passphrase?\n\nWarning: Choosing a strong passphrase is important to avoid brute force attempts to guess your passphrase and steal your litecoins.",
"bip38alertincorrectpassphrase": "Incorrect passphrase for this encrypted private key.",
"bip38alertpassphraserequired": "Passphrase required for BIP38 key",
"vanityinvalidinputcouldnotcombinekeys": "Invalid input. Could not combine keys.",
"vanityalertinvalidinputpublickeysmatch": "Invalid input. The Public Key of both entries match. You must input two different keys.",
"vanityalertinvalidinputcannotmultiple": "Invalid input. Cannot multiply two public keys. Select 'Add' to add two public keys to get a litecoin address.",
"vanityprivatekeyonlyavailable": "Only available when combining two private keys",
"vanityalertinvalidinputprivatekeysmatch": "Invalid input. The Private Key of both entries match. You must input two different keys."
},
"es": {
// javascript alerts or messages
"testneteditionactivated": "Testnet se activa",
"paperlabelbitcoinaddress": "Dirección Litecoin:",
"paperlabelprivatekey": "Clave privada (formato para importar):",
"paperlabelencryptedkey": "Clave privada cifrada (contraseña necesaria)",
"bulkgeneratingaddresses": "Generación de direcciones... ",
"brainalertpassphrasetooshort": "La contraseña introducida es demasiado corta.\n\n",
"brainalertpassphrasewarning": "Aviso: Es importante escoger una contraseña fuerte para evitar ataques de fuerza bruta a fin de adivinarla y robar tus litecoins.",
"brainalertpassphrasedoesnotmatch": "Las contraseñas no coinciden.",
"detailalertnotvalidprivatekey": "El texto que has introducido no es una clave privada válida",
"detailconfirmsha256": "El texto que has introducido no es una clave privada válida\n\n¿Quieres usar ese texto como si fuera una contraseña y generar una clave privada usando un hash SHA256 de tal contraseña?\n\nAviso: Es importante escoger una contraseña fuerte para evitar ataques de fuerza bruta a fin de adivinarla y robar tus litecoins.",
"bip38alertincorrectpassphrase": "Incorrect passphrase for this encrypted private key.", //TODO: please translate
"bip38alertpassphraserequired": "Passphrase required for BIP38 key", //TODO: please translate
"vanityinvalidinputcouldnotcombinekeys": "Entrada no válida. No se puede combinar llaves.",
"vanityalertinvalidinputpublickeysmatch": "Entrada no válida. La clave pública de ambos coincidan entradas. Debe introducir dos claves diferentes.",
"vanityalertinvalidinputcannotmultiple": "Entrada no válida. No se puede multiplicar dos claves públicas. Seleccione 'Añadir' para agregar dos claves públicas para obtener una dirección litecoin.",
"vanityprivatekeyonlyavailable": "Sólo está disponible cuando se combinan dos claves privadas",
"vanityalertinvalidinputprivatekeysmatch": "Entrada no válida. La clave privada de ambos coincidan entradas. Debe introducir dos claves diferentes.",
// header and menu html
"tagline": "Generador de carteras Litecoin de código abierto en lado de cliente con Javascript",
"generatelabelbitcoinaddress": "Generando dirección Litecoin...",
"generatelabelmovemouse": "Mueve un poco el ratón para crear entropía...",
"singlewallet": "Una sola cartera",
"paperwallet": "Cartera en papel",
"bulkwallet": "Direcciones en masa",
"brainwallet": "Cartera mental",
"vanitywallet": "Cartera personalizada",
"detailwallet": "Detalles de la cartera",
// footer html
"footerlabeldonations": "Donaciones:",
"footerlabeltranslatedby": "Traducción: <b>12345</b>Vypv2QSmuRXcciT5oEB27mPbWGeva",
"footerlabelpgp": "PGP",
"footerlabelversion": "Histórico de versiones",
"footerlabelgithub": "Repositorio GitHub",
"footerlabelcopyright1": "Copyright bitaddress.org.",
"footerlabelcopyright2": "Copyright del código JavaScript: en el fuente.",
"footerlabelnowarranty": "Sin garantía.",
// single wallet html
"newaddress": "Generar dirección",
"singleprint": "Imprimir",
"singlelabelbitcoinaddress": "Dirección Litecoin",
"singlelabelprivatekey": "Clave privada (formato para importar):",
"singletip1": "<b>A Litecoin wallet</b> is as simple as a single pairing of a Litecoin address with it's corresponding Litecoin private key. Such a wallet has been generated for you in your web browser and is displayed above.", //TODO: please translate
"singletip2": "<b>To safeguard this wallet</b> you must print or otherwise record the Litecoin address and private key. It is important to make a backup copy of the private key and store it in a safe location. This site does not have knowledge of your private key. If you are familiar with PGP you can download this all-in-one HTML page and check that you have an authentic version from the author of this site by matching the SHA1 hash of this HTML with the SHA1 hash available in the signed version history document linked on the footer of this site. If you leave/refresh the site or press the Generate New Address button then a new private key will be generated and the previously displayed private key will not be retrievable. Your Litecoin private key should be kept a secret. Whomever you share the private key with has access to spend all the litecoins associated with that address. If you print your wallet then store it in a zip lock bag to keep it safe from water. Treat a paper wallet like cash.", //TODO: please translate
"singletip3": "<b>Add funds</b> to this wallet by instructing others to send litecoins to your Litecoin address.", //TODO: please translate
"singletip4": "<b>Check your balance</b> by going to blockchain.info or blockexplorer.com and entering your Litecoin address.", //TODO: please translate
"singletip5": "<b>Spend your litecoins</b> by going to blockchain.info or mtgox.com and sweep the full balance of your private key into your account at their website. You can also spend your funds by downloading one of the popular litecoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a litecoin p2p client and spend funds your key will be bundled with other private keys in the p2p client wallet. When you perform a transaction your change will be sent to another litecoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining litecoins will be stored there. Satoshi advised that one should never delete a wallet.", //TODO: please translate
// paper wallet html
"paperlabelhideart": "Ocultar diseño",
"paperlabeladdressesperpage": "Direcciones por página:",
"paperlabeladdressestogenerate": "Direcciones en total:",
"papergenerate": "Generar",
"paperprint": "Imprimir",
"paperlabelBIPpassphrase": "Passphrase:", //TODO: please translate
"paperlabelencrypt": "BIP38 Encrypt?", //TODO: please translate
// bulk wallet html
"bulklabelstartindex": "Empezar en:",
"bulklabelrowstogenerate": "Filas a generar:",
"bulklabelcompressed": "Compressed addresses?", //TODO: please translate
"bulkgenerate": "Generar",
"bulkprint": "Imprimir",
"bulklabelcsv": "Valores separados por coma:",
"bulklabelformat": "Índice,Dirección,Clave privada (formato para importar)",
"bulklabelq1": "¿Por qué debo usar \"Direcciones en masa\" para aceptar Litecoins en mi web?",
"bulka1": "La forma tradicional de aceptar litecoins en tu web requiere tener instalado el cliente oficial de litecoin (\"litecoind\"). Sin embargo muchos servicios de hosting no permiten instalar dicho cliente. Además, ejecutar el cliente en tu servidor supone que las claves privadas están también en el servidor y podrían ser comprometidas en caso de intrusión. Al usar este mecanismo, puedes subir al servidor sólo las dirección de litecoin y no las claves privadas. De esta forma no te tienes que preocupar de que alguien robe la cartera si se cuelan en el servidor.",
"bulklabelq2": "¿Cómo uso \"Direcciones en masa\" para aceptar litecoins en mi web?",
"bulklabela2li1": "Usa el tab \"Direcciones en masa\" para generar por anticipado muchas direcciones (más de 10000). Copia y pega la lista de valores separados por comas (CSV) a un archivo de texto seguro (cifrado) en tu ordenador. Guarda una copia de seguridad en algún lugar seguro.",
"bulklabela2li2": "Importa las direcciones en la base de datos de tu servidor. No subas la cartera ni las claves públicas, o de lo contrario te lo pueden robar. Sube sólo las direcciones, ya que es lo que se va a mostrar a los clientes.",
"bulklabela2li3": "Ofrece una alternativa en el carro de la compra de tu web para que los clientes paguen con Litecoin. Cuando el cliente elija pagar con Litecoin, les muestras una de las direcciones de la base de datos como su \"dirección de pago\" y guardas esto junto con el pedido.",
"bulklabela2li4": "Ahora te hace falta recibir una notificación del pago. Busca en google \"notificación de pagos litecoin\" (o \"litecoin payment notification\" en inglés) y suscríbete a alguno de los servicios que aparezcan. Hay varios de ellos, que te pueden notificar vía Web services, API, SMS, email, etc. Una vez te llegue la notificación, lo cual puede ser automatizado, entonces ya puedes procesar el pedido. Para comprobar a mano si has recibido un pago, puedes usar Block Explorer: reemplaza DIRECCION a continuación por la dirección que estés comprobando. La transacción puede tardar entre 10 minutos y una hora en ser confirmada. <br />http://www.blockexplorer.com/address/DIRECCION<br /><br />Puedes ver las transacciones sin confirmar en: http://blockchain.info/ <br />Las transacciones sin confirmar suelen aparecer ahí en unos 30 segundos.",
"bulklabela2li5": "Las litecoins que recibas se almacenarán de forma segura en la cadena de bloques. Usa la cartera original que generaste en el paso 1 para usarlas.",
// brain wallet html
"brainlabelenterpassphrase": "Contraseña:",
"brainlabelshow": "Mostrar",
"brainprint": "Imprimir",
"brainlabelconfirm": "Confirmar contraseña:",
"brainview": "Ver",
"brainalgorithm": "Algoritmo: SHA256(contraseña)",
"brainlabelbitcoinaddress": "Dirección Litecoin:",
"brainlabelprivatekey": "Clave privada (formato para importar):",
// vanity wallet html
"vanitylabelstep1": "Paso 1 - Genera tu par de claves",
"vanitynewkeypair": "Generar",
"vanitylabelstep1publickey": "Clave pública:",
"vanitylabelstep1pubnotes": "Copia y pega la línea de arriba en el campo \"Your-Part-Public-Key\" de la web de Vanity Pool.",
"vanitylabelstep1privatekey": "Clave privada:",
"vanitylabelstep1privnotes": "Copia y pega la clave pública de arriba en un archivo de texto. Es mejor que lo almacenes en un volumen cifrado. Lo necesitarás para recuperar la clave privada una vez Vanity Pool haya encontrado tu prefijo.",
"vanitylabelstep2calculateyourvanitywallet": "Paso 2 - Calcula tu cartera personalizada",
"vanitylabelenteryourpart": "Introduce la clave privada generada en el paso 1, y que has guardado:",
"vanitylabelenteryourpoolpart": "Introduce la clave privada obtenida de la Vanity Pool:",
"vanitylabelnote1": "[NOTA: esta casilla de entrada puede aceptar una clave pública o clave privada]",
"vanitylabelnote2": "[NOTA: esta casilla de entrada puede aceptar una clave pública o clave privada]",
"vanitylabelradioadd": "Añadir",
"vanitylabelradiomultiply": "Multiplicar",
"vanitycalc": "Calcular cartera personalizada",
"vanitylabelbitcoinaddress": "Dirección Litecoin personalizada:",
"vanitylabelnotesbitcoinaddress": "Esta es tu nueva dirección, que debería tener el prefijo deseado.",
"vanitylabelpublickeyhex": "Clave pública personalizada (HEX):",
"vanitylabelnotespublickeyhex": "Lo anterior es la clave pública en formato hexadecimal.",
"vanitylabelprivatekey": "Clave privada personalizada (formato para importar):",
"vanitylabelnotesprivatekey": "Esto es la clave privada para introducir en tu cartera.",
// detail wallet html
"detaillabelenterprivatekey": "Introduce la clave privada (en cualquier formato)",
"detailview": "Ver detalles",
"detailprint": "Imprimir",
"detaillabelnote1": "Tu clave privada es un número secreto, único, que sólo tú conoces. Se puede expresar en varios formatos. Aquí abajo mostramos la dirección y la clave pública que se corresponden con tu clave privada, así como la clave privada en los formatos más conocidos (para importar, hex, base64 y mini).",
"detaillabelnote2": "Litecoin v0.6+ almacena las claves públicas comprimidas. El cliente también soporta importar/exportar claves privadas usando importprivkey/dumpprivkey. El formato de las claves privadas exportadas depende de si la dirección se generó en una cartera antigua o nueva.",
"detaillabelbitcoinaddress": "Dirección Litecoin:",
"detaillabelbitcoinaddresscomp": "Dirección Litecoin (comprimida):",
"detaillabelpublickey": "Clave pública (130 caracteres [0-9A-F]):",
"detaillabelpublickeycomp": "Clave pública (comprimida, 66 caracteres [0-9A-F]):",
"detaillabelprivwif": "Clave privada para importar<br />51 caracteres en base58, empieza con un",
"detaillabelprivwifcomp": "Clave privada para importar<br />comprimida, 52 caracteres en base58, empieza con",
"detaillabelprivhex": "Clave privada en formato hexadecimal (64 caracteres [0-9A-F]):",
"detaillabelprivb64": "Clave privada en base64 (44 caracteres):",
"detaillabelprivmini": "Clave privada en formato mini (22, 26 o 30 caracteres, empieza por 'S'):",
"detaillabelpassphrase": "BIP38 Passphrase", //TODO: please translate
"detaildecrypt": "Decrypt BIP38" //TODO: please translate
},
"fr": {
// javascript alerts or messages
"testneteditionactivated": "ÉDITION TESTNET ACTIVÉE",
"paperlabelbitcoinaddress": "Adresse Litecoin:",
"paperlabelprivatekey": "Clé Privée (Format d'importation de porte-monnaie):",
"paperlabelencryptedkey": "Encrypted Private Key (Password required)", //TODO: please translate
"bulkgeneratingaddresses": "Création de l'adresse... ",
"brainalertpassphrasetooshort": "Le mot de passe que vous avez entré est trop court.\n\n",
"brainalertpassphrasewarning": "Attention: Choisir un mot de passe solide est important pour vous protéger des attaques bruteforce visant à trouver votre mot de passe et voler vos Litecoins.",
"brainalertpassphrasedoesnotmatch": "Le mot de passe ne correspond pas au mot de passe de vérification.",
"detailalertnotvalidprivatekey": "Le texte que vous avez entré n'est pas une Clé Privée valide",
"detailconfirmsha256": "Le texte que vous avez entré n'est pas une Clé Privée valide!\n\nVoulez-vous utiliser le texte comme un mot de passe et créer une Clé Privée à partir d'un hash SHA256 de ce mot de passe?\n\nAttention: Choisir un mot de passe solide est important pour vous protéger des attaques bruteforce visant à trouver votre mot de passe et voler vos Litecoins.",
"bip38alertincorrectpassphrase": "Incorrect passphrase for this encrypted private key.", //TODO: please translate
"bip38alertpassphraserequired": "Passphrase required for BIP38 key", //TODO: please translate
"vanityinvalidinputcouldnotcombinekeys": "Entrée non valide. Impossible de combiner les clés.",
"vanityalertinvalidinputpublickeysmatch": "Entrée non valide. La clé publique des deux entrées est identique. Vous devez entrer deux clés différentes.",
"vanityalertinvalidinputcannotmultiple": "Entrée non valide. Il n'est pas possible de multiplier deux clés publiques. Sélectionner 'Ajouter' pour ajouter deux clés publiques pour obtenir une adresse Litecoin.",
"vanityprivatekeyonlyavailable": "Seulement disponible si vos combinez deux clés privées",
"vanityalertinvalidinputprivatekeysmatch": "Entrée non valide. La clé Privée des deux entrées est identique. Vous devez entrer deux clés différentes.",
// header and menu html
"tagline": "Générateur De Porte-Monnaie Litecoin Javascript Hors-Ligne",
"generatelabelbitcoinaddress": "Création de l'adresse Litecoin...",
"generatelabelmovemouse": "BOUGEZ votre souris pour ajouter de l'entropie...",
"singlewallet": "Porte-Monnaie Simple",
"paperwallet": "Porte-Monnaie Papier",
"bulkwallet": "Porte-Monnaie En Vrac",
"brainwallet": "Porte-Monnaie Cerveau",
"vanitywallet": "Porte-Monnaie Vanité",
"detailwallet": "Détails du Porte-Monnaie",
// footer html
"footerlabeldonations": "Dons:",
"footerlabeltranslatedby": "Traduction: 1Gy7NYSJNUYqUdXTBow5d7bCUEJkUFDFSq",
"footerlabelpgp": "PGP",
"footerlabelversion": "Historique De Version",
"footerlabelgithub": "Dépôt GitHub",
"footerlabelcopyright1": "Copyright bitaddress.org.",
"footerlabelcopyright2": "Les droits d'auteurs JavaScript sont inclus dans le code source.",
"footerlabelnowarranty": "Aucune garantie.",
// single wallet html
"newaddress": "Générer Une Nouvelle Adresse",
"singleprint": "Imprimer",
"singlelabelbitcoinaddress": "Adresse Litecoin:",
"singlelabelprivatekey": "Clé Privée (Format d'importation de porte-monnaie):",
"singletip1": "<b>A Litecoin wallet</b> is as simple as a single pairing of a Litecoin address with it's corresponding Litecoin private key. Such a wallet has been generated for you in your web browser and is displayed above.", //TODO: please translate
"singletip2": "<b>To safeguard this wallet</b> you must print or otherwise record the Litecoin address and private key. It is important to make a backup copy of the private key and store it in a safe location. This site does not have knowledge of your private key. If you are familiar with PGP you can download this all-in-one HTML page and check that you have an authentic version from the author of this site by matching the SHA1 hash of this HTML with the SHA1 hash available in the signed version history document linked on the footer of this site. If you leave/refresh the site or press the Generate New Address button then a new private key will be generated and the previously displayed private key will not be retrievable. Your Litecoin private key should be kept a secret. Whomever you share the private key with has access to spend all the litecoins associated with that address. If you print your wallet then store it in a zip lock bag to keep it safe from water. Treat a paper wallet like cash.", //TODO: please translate
"singletip3": "<b>Add funds</b> to this wallet by instructing others to send litecoins to your Litecoin address.", //TODO: please translate
"singletip4": "<b>Check your balance</b> by going to blockchain.info or blockexplorer.com and entering your Litecoin address.", //TODO: please translate
"singletip5": "<b>Spend your litecoins</b> by going to blockchain.info or mtgox.com and sweep the full balance of your private key into your account at their website. You can also spend your funds by downloading one of the popular litecoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a litecoin p2p client and spend funds your key will be bundled with other private keys in the p2p client wallet. When you perform a transaction your change will be sent to another litecoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining litecoins will be stored there. Satoshi advised that one should never delete a wallet.", //TODO: please translate
// paper wallet html
"paperlabelhideart": "Retirer Le Style?",
"paperlabeladdressesperpage": "Adresses par page:",
"paperlabeladdressestogenerate": "Nombre d'adresses à créer:",
"papergenerate": "Générer",
"paperprint": "Imprimer",
"paperlabelBIPpassphrase": "Passphrase:", //TODO: please translate
"paperlabelencrypt": "BIP38 Encrypt?", //TODO: please translate
// bulk wallet html
"bulklabelstartindex": "Commencer à l'index:",
"bulklabelrowstogenerate": "Colonnes à générer:",
"bulklabelcompressed": "Compressed addresses?", //TODO: please translate
"bulkgenerate": "Générer",
"bulkprint": "Imprimer",
"bulklabelcsv": "Valeurs Séparées Par Des Virgules (CSV):",
"bulklabelformat": "Index,Adresse,Clé Privée (WIF)",
"bulklabelq1": "Pourquoi utiliserais-je un Porte-monnaie en vrac pour accepter les Litecoins sur mon site web?",
"bulka1": "L'approche traditionnelle pour accepter des Litecoins sur votre site web requière l'installation du logiciel Litecoin officiel (\"litecoind\"). Plusieurs hébergeurs ne supportent pas l'installation du logiciel Litecoin. De plus, faire fonctionner le logiciel Litecoin sur votre serveur web signifie que vos clés privées sont hébergées sur le serveur et pourraient donc être volées si votre serveur web était compromis. En utilisant un Porte-monnaie en vrac, vous pouvez publiquer seulement les adresses Litecoin sur votre serveur et non les clés privées. Vous n'avez alors pas à vous inquiéter du risque de vous faire voler votre porte-monnaie si votre serveur était compromis.",
"bulklabelq2": "Comment utiliser le Porte-monnaie en vrac pour utiliser le Litecoin sur mon site web?",
"bulklabela2li1": "Utilisez le Porte-monnaie en vrac pour pré-générer une large quantité d'adresses Litecoin (10,000+). Copiez collez les données séparées par des virgules (CSV) dans un fichier texte sécurisé dans votre ordinateur. Sauvegardez ce fichier dans un endroit sécurisé.",
"bulklabela2li2": "Importez les adresses Litecoin dans une base de donnée sur votre serveur web. (N'ajoutez pas le porte-monnaie ou les clés privées sur votre serveur web, sinon vous courrez le risque de vous faire voler si votre serveur est compromis. Ajoutez seulement les adresses Litecoin qui seront visibles à vos visiteurs.)",
"bulklabela2li3": "Ajoutez une option dans votre panier en ligne pour que vos clients puissent vous payer en Litecoin. Quand un client choisi de vous payer en Litecoin, vous pouvez afficher une des adresses de votre base de donnée comme \"adresse de paiment\" pour votre client et sauvegarder cette adresse avec sa commande.",
"bulklabela2li4": "Vous avez maintenant besoin d'être avisé quand le paiement est reçu. Cherchez \"litecoin payment notification\" sur Google et inscrivez-vous à un service de notification de paiement Litecoin. Il y a plusieurs services qui vous avertiront via des services Web, API, SMS, Email, etc. Une fois que vous avez reçu la notification, qui devrait être programmée automatiquement, vous pouvez traiter la commande de votre client. Pour vérifier manuellement si un paiement est arrivé, vous pouvez utiliser Block Explorer. Remplacez ADRESSE par l'adresse Litecoin que vous souhaitez vérifier. La confirmation de la transaction pourrait prendre de 10 à 60 minutes pour être confirmée.<br />http://www.blockexplorer.com/address/ADRESSE<br /><br />Les transactions non confirmées peuvent être visualisées ici: http://blockchain.info/ <br />Vous devriez voir la transaction à l'intérieur de 30 secondes.",
"bulklabela2li5": "Les Litecoins vos s'accumuler de façon sécuritaire dans la chaîne de blocs. Utilisez le porte-monnaie original que vous avez généré à l'étape 1 pour les dépenser.",
// brain wallet html
"brainlabelenterpassphrase": "Entrez votre mot de passe: ",
"brainlabelshow": "Afficher?",
"brainprint": "Imprimer",
"brainlabelconfirm": "Confirmer le mot de passe: ",
"brainview": "Visualiser",
"brainalgorithm": "Algorithme: SHA256(mot de passe)",
"brainlabelbitcoinaddress": "Adresse Litecoin:",
"brainlabelprivatekey": "Clé Privée (Format d'importation de porte-monnaie):",
// vanity wallet html
"vanitylabelstep1": "Étape 1 - Générer votre \"Étape 1 Paire De Clés\"",
"vanitynewkeypair": "Générer",
"vanitylabelstep1publickey": "Étape 1 Clé Publique:",
"vanitylabelstep1pubnotes": "Copiez celle-ci dans la case Votre-Clé-Publique du site de Vanity Pool.",
"vanitylabelstep1privatekey": "Step 1 Clé Privée:",
"vanitylabelstep1privnotes": "Copiez la cette Clé Privée dans un fichier texte. Idéalement, sauvegardez la dans un fichier encrypté. Vous en aurez besoin pour récupérer la Clé Privée lors que Vanity Pool aura trouvé votre préfixe.",
"vanitylabelstep2calculateyourvanitywallet": "Étape 2 - Calculer votre Porte-monnaie Vanité",
"vanitylabelenteryourpart": "Entrez votre Clé Privée (générée à l'étape 1 plus haut et précédemment sauvegardée):",
"vanitylabelenteryourpoolpart": "Entrez la Clé Privée (provenant de Vanity Pool):",
"vanitylabelnote1": "[NOTE: cette case peut accepter une clé publique ou un clé privée]",
"vanitylabelnote2": "[NOTE: cette case peut accepter une clé publique ou un clé privée]",
"vanitylabelradioadd": "Ajouter",
"vanitylabelradiomultiply": "Multiplier",
"vanitycalc": "Calculer Le Porte-monnaie Vanité",
"vanitylabelbitcoinaddress": "Adresse Litecoin Vanité:",
"vanitylabelnotesbitcoinaddress": "Ci-haut est votre nouvelle adresse qui devrait inclure le préfix requis.",
"vanitylabelpublickeyhex": "Clé Public Vanité (HEX):",
"vanitylabelnotespublickeyhex": "Celle-ci est la Clé Publique dans le format hexadécimal. ",
"vanitylabelprivatekey": "Clé Privée Vanité (WIF):",
"vanitylabelnotesprivatekey": "Celle-ci est la Clé Privée pour accéder à votre porte-monnaie. ",
// detail wallet html
"detaillabelenterprivatekey": "Entrez la Clé Privée (quel que soit son format)",
"detailview": "Voir les détails",
"detailprint": "Imprimer",
"detaillabelnote1": "Votre Clé Privée Litecoin est un nombre secret que vous êtes le seul à connaître. Il peut être encodé sous la forme d'un nombre sous différents formats. Ci-bas, nous affichons l'adresse Litecoin et la Clé Publique qui corresponds à la Clé Privée ainsi que la Clé Privée dans les formats d'encodage les plus populaires (WIF, HEX, B64, MINI).",
"detaillabelnote2": "Litecoin v0.6+ conserve les clés publiques dans un format compressé. Le logiciel supporte maintenant aussi l'importation et l'exportation de clés privées avec importprivkey/dumpprivkey. Le format de la clé privée exportée est déterminé selon la version du porte-monnaie Litecoin.",
"detaillabelbitcoinaddress": "Adresse Litecoin:",
"detaillabelbitcoinaddresscomp": "Adresse Litecoin (compressée):",
"detaillabelpublickey": "Clé Publique (130 caractères [0-9A-F]):",
"detaillabelpublickeycomp": "Clé Publique (compressée, 66 caractères [0-9A-F]):",
"detaillabelprivwif": "Clé Privée WIF<br />51 caractères base58, débute avec un a",
"detaillabelprivwifcomp": "Clé Privée WIF<br />compressée, 52 caractères base58, débute avec un a",
"detaillabelprivhex": "Clé Privée Format Hexadecimal (64 caractères [0-9A-F]):",
"detaillabelprivb64": "Clé Privée Base64 (44 caractères):",
"detaillabelprivmini": "Clé Privée Format Mini (22, 26 ou 30 caractères, débute avec un 'S'):",
"detaillabelpassphrase": "BIP38 Passphrase", //TODO: please translate
"detaildecrypt": "Decrypt BIP38" //TODO: please translate
},
"el": {
// javascript alerts or messages
"testneteditionactivated": "ΕΝΕΡΓΗ ΕΚΔΟΣΗ TESTNET",
"paperlabelbitcoinaddress": "Διεύθυνση Litecoin:",
"paperlabelprivatekey": "Προσωπικό Κλειδί (Μορφή εισαγωγής σε πορτοφόλι):",
"paperlabelencryptedkey": "Encrypted Private Key (Password required)", //TODO: please translate
"bulkgeneratingaddresses": "Δημιουργία διευθύνσεων... ",
"brainalertpassphrasetooshort": "Η φράση κωδικός που δώσατε είναι πολύ αδύναμη.\n\n",
"brainalertpassphrasewarning": "Προσοχή: Είναι σημαντικό να επιλέξετε μια ισχυρή φράση κωδικό που θα σας προφυλάξει από απόπειρες παραβίασής της τύπου brute force και κλοπή των litecoins σας.",
"brainalertpassphrasedoesnotmatch": "Η φράση κωδικός και η επιβεβαίωση της δε συμφωνούν.",
"detailalertnotvalidprivatekey": "Το κείμενο που εισάγατε δεν αντιστοιχεί σε έγκυρο Προσωπικό Κλειδί",
"detailconfirmsha256": "Το κείμενο που εισάγατε δεν αντιστοιχεί σε έγκυρο Προσωπικό Κλειδί!\n\nΘα θέλατε να χρησιμοποιηθεί το κείμενο ως κωδικός για τη δημιουργία ενός Προσωπικού Κλειδιού που θα δημιουργηθεί από το SHA265 hash της φράσης κωδικού;\n\nΠροσοχή: Είναι σημαντικό να επιλέξετε έναν ισχυρό κωδικό ώστε να είναι δύσκολο να τον μαντέψει κάποιος και να κλέψει τα litecoins σας.",
"bip38alertincorrectpassphrase": "Λάθος φράση κωδικός αποκρυπτογράφησης Προσωπικού Κλειδιού.",
"bip38alertpassphraserequired": "Απαιτείται η φράση κωδικός για το Κλειδί BIP38",
"vanityinvalidinputcouldnotcombinekeys": "Μη έγκυρη εισαγωγή. Ο συνδυασμός των κλειδιών είναι αδύνατος.",
"vanityalertinvalidinputpublickeysmatch": "Μη έγκυρη εισαγωγή. Τα Δημόσια Κλειδιά των δύο εγγραφών είναι όμοια. Πρέπει να εισάγετε δύο διαφορετικά Κλειδιά.",
"vanityalertinvalidinputcannotmultiple": "Μη έγκυρη εισαγωγή. Δεν είναι δυνατός ο πολλαπλασιασμός δύο Δημόσιων Κλειδιών. Επιλέξτε 'Πρόσθεση' για να προσθέσετε δύο Δημόσια Κλειδιά για δημιουργία μίας Διεύθυνσης Litecoin.",
"vanityprivatekeyonlyavailable": "Διαθέσιμο μόνο κατά το συνδυασμό δύο Προσωπικών Κλειδιών",
"vanityalertinvalidinputprivatekeysmatch": "Μη έγκυρη εισαγωγή. Τα Προσωπικά Κλειδιά των δύο εγγραφών είναι όμοια. Πρέπει να εισάγετε δύο διαφορετικά Κλειδιά.",
// header and menu html
"tagline": "Δημιουργός Διευθύνσεων Litecoin, ανοικτού κώδικα Javascript",
"generatelabelbitcoinaddress": "Δημιουργία Διεύθυνσης Litecoin...",
"generatelabelmovemouse": "ΚΟΥΝΗΣΤΕ το ποντίκι τριγύρω για να προσθέσετε επιπλέον τυχαιότητα...",
"singlewallet": "Απλό Πορτοφόλι",
"paperwallet": "Χάρτινο Πορτοφόλι",
"bulkwallet": "Πολλαπλά Πορτοφόλια",
"brainwallet": "Μνημονικό Πορτοφόλι",
"vanitywallet": "Πορτοφόλι Vanity",
"detailwallet": "Λεπτομέρειες Πορτοφολιού",
// footer html
"footerlabeldonations": "Δωρεές:",
"footerlabeltranslatedby": "Μετάφραση: <a href='http://LitecoinX.gr/'><b>LitecoinX.gr</b></a> 1BitcoiNxkUPcTFxwMqxhRiPEiQRzYskf6",
"footerlabelpgp": "PGP",
"footerlabelversion": "ιστορικό εκδόσεων",
"footerlabelgithub": "Αποθετήριο GitHub",
"footerlabelcopyright1": "Copyright bitaddress.org.",
"footerlabelcopyright2": "Τα πνευματικά δικαιώματα της JavaScript περιλαμβάνονται στον κώδικα.",
"footerlabelnowarranty": "Καμία εγγύηση.",
// single wallet html
"newaddress": "Δημιουργία μιας νέας Διεύθυνσης",
"singleprint": "Εκτύπωση",
"singlelabelbitcoinaddress": "Διεύθυνση Litecoin:",
"singlelabelprivatekey": "Προσωπικό Κλειδί (Μορφή εισαγωγής σε πορτοφόλι):",
"singletip1": "<b>A Litecoin wallet</b> is as simple as a single pairing of a Litecoin address with it's corresponding Litecoin private key. Such a wallet has been generated for you in your web browser and is displayed above.", //TODO: please translate
"singletip2": "<b>To safeguard this wallet</b> you must print or otherwise record the Litecoin address and private key. It is important to make a backup copy of the private key and store it in a safe location. This site does not have knowledge of your private key. If you are familiar with PGP you can download this all-in-one HTML page and check that you have an authentic version from the author of this site by matching the SHA1 hash of this HTML with the SHA1 hash available in the signed version history document linked on the footer of this site. If you leave/refresh the site or press the Generate New Address button then a new private key will be generated and the previously displayed private key will not be retrievable. Your Litecoin private key should be kept a secret. Whomever you share the private key with has access to spend all the litecoins associated with that address. If you print your wallet then store it in a zip lock bag to keep it safe from water. Treat a paper wallet like cash.", //TODO: please translate
"singletip3": "<b>Add funds</b> to this wallet by instructing others to send litecoins to your Litecoin address.", //TODO: please translate
"singletip4": "<b>Check your balance</b> by going to blockchain.info or blockexplorer.com and entering your Litecoin address.", //TODO: please translate
"singletip5": "<b>Spend your litecoins</b> by going to blockchain.info or mtgox.com and sweep the full balance of your private key into your account at their website. You can also spend your funds by downloading one of the popular litecoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a litecoin p2p client and spend funds your key will be bundled with other private keys in the p2p client wallet. When you perform a transaction your change will be sent to another litecoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining litecoins will be stored there. Satoshi advised that one should never delete a wallet.", //TODO: please translate
// paper wallet html
"paperlabelhideart": "Απόκρυψη γραφικού;",
"paperlabeladdressesperpage": "Διευθύνσεις ανά σελίδα:",
"paperlabeladdressestogenerate": "Πλήθος διευθύνσεων:",
"papergenerate": "Δημιουργία",
"paperprint": "Εκτύπωση",
"paperlabelBIPpassphrase": "Passphrase:", //TODO: please translate
"paperlabelencrypt": "BIP38 Encrypt?", //TODO: please translate
// bulk wallet html
"bulklabelstartindex": "Ξεκίνημα δείκτη:",
"bulklabelrowstogenerate": "Πλήθος σειρών:",
"bulklabelcompressed": "Συμπιεσμένες διευθύνσεις;",
"bulkgenerate": "Δημιουργία",
"bulkprint": "Εκτύπωση",
"bulklabelcsv": "Τιμές που χωρίζονται με κόμμα (CSV):",
"bulklabelformat": "Δείκτης,Διεύθυνση,Προσωπικό Κλειδί (WIF)",
"bulklabelq1": "Γιατί να χρησιμοποιήσω Πολλαπλά Πορτοφόλια στην ιστοσελίδα μου;",
"bulka1": "Ο παραδοσιακός τρόπος για να δέχεστε litecoins στην ιστοσελίδα σας, απαιτεί την εγκατάσταση και λειτουργία του επίσημου δαίμονα πελάτη litecoin (\"litecoind\"). Αρκετά πακέτα φιλοξενίας δεν υποστηρίζουν την εγκατάστασή του. Επιπλέον, η εκτέλεση του πελάτη litecoin στον web server σας συνεπάγεται και τη φιλοξενία των προσωπικών σας κλειδιών στον ίδιο server, τα οποία μπορεί να υποκλαπούν αν ο server πέσει θύμα επίθεσης. Χρησιμοποιώντας τα Πολλαπλά Πορτοφόλια, ανεβάζετε στον server σας μόνο τις διευθύνσεις Litecoin κι όχι τα προσωπικά κλειδιά. Με αυτό τον τρόπο δεν χρειάζεται να ανησυχείτε μήπως υποκλαπεί το πορτοφόλι σας.",
"bulklabelq2": "Πως χρησιμοποιώ τα Πολλαπλά Πορτοφόλια για να δέχομαι litecoins στην ιστοσελίδα μου;",
"bulklabela2li1": "Χρησιμοποιήστε την καρτέλα Πολλαπλά Πορτοφόλια για να δημιουργήσετε έναν μεγάλο αριθμό διευθύνσεων Litecoin (10.000+). Αντιγράψτε κι επικολλήστε τη λίστα των χωρισμένων με κόμμα τιμών (CSV) που δημιουργήθηκαν, σε ένα ασφαλές αρχείο στον υπολογιστή σας. Αντιγράψτε το αρχείο που δημιουργήσατε σε μια ασφαλή τοποθεσία.",
"bulklabela2li2": "Εισάγετε τις διευθύνσεις Litecoin σε έναν πίνακα βάσης δεδομένων στον web server σας. (Μην αντιγράψετε τα προσωπικά κλειδιά ή το πορτοφόλι στον web server γιατί διακινδυνεύετε να σας τα κλέψουν. Μόνο τις διευθύνσεις Litecoin που θα εμφανίζονται στους πελάτες.)",
"bulklabela2li3": "Παρέχετε στο καλάθι αγορών σας μια επιλογή για πληρωμή σε Litecoin. Όταν ο πελάτης επιλέγει να πληρώσει με Litecoin, θα εμφανίσετε σε αυτόν μια από τις διευθύνσεις από τη βάση δεδομένων, ως την «προσωπική του διεύθυνση πληρωμής» την οποία θα αποθηκεύσετε μαζί με την εντολή αγοράς.",
"bulklabela2li4": "Τώρα χρειάζεται να ειδοποιηθείτε μόλις γίνει η πληρωμή. Ψάξτε στο Google για «litecoin payment notification» κι εγγραφείτε σε τουλάχιστο μία υπηρεσία ειδοποίησης πληρωμής. Υπάρχουν διάφορες υπηρεσίες που θα σας ειδοποιήσουν με Web υπηρεσίες, API, SMS, Email, κλπ. Όταν λάβετε την ειδοποίηση, η οποία μπορεί να αυτοματοποιηθεί προγραμματιστικά, εκτελείτε την εντολή του πελάτη. Για να ελέγξετε χειροκίνητα την πληρωμή μπορείτε να χρησιμοποιήσετε τον Block Explorer. Αντικαταστήστε το THEADDRESSGOESHERE με τη Litecoin διεύθυνσή σας. Η επιβεβαίωση της πληρωμής ενδέχεται να διαρκέσει από δέκα λεπτά έως μία ώρα.<br />http://www.blockexplorer.com/address/THEADDRESSGOESHERE<br /><br />Μπορείτε να δείτε τις συναλλαγές που δεν έχουν επιβεβαιωθεί στο: http://blockchain.info/ <br />Θα πρέπει να δείτε τη συναλλαγή εκεί εντός 30 δευτερολέπτων.",
"bulklabela2li5": "Τα Litecoins θα συσσωρεύονται με ασφάλεια στην αλυσίδα των μπλοκ. Χρησιμοποιήστε το αρχικό πορτοφόλι που δημιουργήσατε στο βήμα 1 για να τα ξοδέψετε.",
// brain wallet html
"brainlabelenterpassphrase": "Εισάγετε κωδικό: ",
"brainlabelshow": "Εμφάνιση;",
"brainprint": "Εκτύπωση",
"brainlabelconfirm": "Επιβεβαιώστε τον κωδικό: ",
"brainview": "Δημιουργία",
"brainalgorithm": "Αλγόριθμος: SHA256(κωδικός)",
"brainlabelbitcoinaddress": "Διεύθυνση Litecoin:",
"brainlabelprivatekey": "Προσωπικό Κλειδί (Μορφή εισαγωγής σε πορτοφόλι):",
// vanity wallet html
"vanitylabelstep1": "Βήμα 1 - Δημιουργήστε το «Ζεύγος κλειδιών του Βήματος 1»",
"vanitynewkeypair": "Δημιουργία",
"vanitylabelstep1publickey": "Βήμα 1 Δημόσιο Κλειδί:",
"vanitylabelstep1pubnotes": "Αντιγράψτε κι επικολλήστε το παραπάνω στο πεδίο Your-Part-Public-Key στην ιστοσελίδα του Vanity Pool.",
"vanitylabelstep1privatekey": "Step 1 Προσωπικό Κλειδί:",
"vanitylabelstep1privnotes": "Αντιγράψτε κι επικολλήστε το παραπάνω Προσωπικό Κλειδί σε ένα αρχείο κειμένου. Ιδανικά, αποθηκεύστε το σε έναν κρυπτογραφημένο δίσκο. Θα το χρειαστείτε για να ανακτήσετε το Litecoin Προσωπικό Κλειδί όταν βρεθεί το πρόθεμά σας από το Vanity Pool.",
"vanitylabelstep2calculateyourvanitywallet": "Βήμα 2 - Υπολογίστε το Vanity Πορτοφόλι σας.",
"vanitylabelenteryourpart": "Εισάγετε το Προσωπικό Κλειδί που δημιουργήσατε στο Βήμα 1 κι αποθηκεύσατε:",
"vanitylabelenteryourpoolpart": "Εισάγετε το Προσωπικό Κλειδί από το Vanity Pool:",
"vanitylabelnote1": "[ΣΗΜΕΙΩΣΗ: Το πεδίο αυτό μπορεί να δεχθεί είτε ένα Δημόσιο είτε ένα Προσωπικό Κλειδί.]",
"vanitylabelnote2": "[ΣΗΜΕΙΩΣΗ: Το πεδίο αυτό μπορεί να δεχθεί είτε ένα Δημόσιο είτε ένα Προσωπικό Κλειδί.]",
"vanitylabelradioadd": "Πρόσθεσε",
"vanitylabelradiomultiply": "Πολλαπλασίασε",
"vanitycalc": "Υπολογισμός του Πορτοφολιού Vanity",
"vanitylabelbitcoinaddress": "Vanity Διεύθυνση Litecoin:",
"vanitylabelnotesbitcoinaddress": "Παραπάνω είναι η διεύθυνσή σας που θα πρέπει να περιλαμβάνει το επιθυμητό πρόθεμα.",
"vanitylabelpublickeyhex": "Vanity Δημόσιο Κλειδί (HEX):",
"vanitylabelnotespublickeyhex": "Παραπάνω είναι το Δημόσιο Κλειδί σε δεκαεξαδική μορφή. ",
"vanitylabelprivatekey": "Vanity Προσωπικό Κλειδί (WIF):",
"vanitylabelnotesprivatekey": "Παραπάνω είναι το Προσωπικό Κλειδί που θα φορτώσετε στο Πορτοφόλι σας. ",
// detail wallet html
"detaillabelenterprivatekey": "Εισάγετε το Προσωπικό Κλειδί (οποιαδήποτε μορφή)",
"detailview": "Προβολή λεπτομερειών",
"detailprint": "Εκτύπωση",
"detaillabelnote1": "Το Litecoin Προσωπικό Κλειδί είναι ένας μοναδικός και μυστικός αριθμός που μόνο εσείς πρέπει να γνωρίζετε, ο οποίος μπορεί να κωδικοποιηθεί σε πολλές διαφορετικές μορφές. Εμφανίζουμε παρακάτω τη διεύθυνση Litecoin και το Δημόσιο Κλειδί, μαζί με το Προσωπικό Κλειδί, στις πιο δημοφιλείς μορφές (WIF, HEX, B64, MINI).",
"detaillabelnote2": "Το Litecoin v0.6+ αποθηκεύει τα Προσωπικά Κλειδιά σε συμπιεσμένη μορφή. Το πρόγραμμα υποστηρίζει επίσης εισαγωγή κι εξαγωγή των Προσωπικών Κλειδιών με τις εντολές importprivkey/dumpprivkey. Η μορφή του εξαγόμενου Προσωπικού Κλειδιού προσδιορίζεται από το αν η διεύθυνση δημιουργήθηκε σε ένα παλιό ή νέο πορτοφόλι.",
"detaillabelbitcoinaddress": "Διεύθυνση Litecoin:",
"detaillabelbitcoinaddresscomp": "Συμπιεσμένη Διεύθυνση Litecoin:",
"detaillabelpublickey": "Δημόσιο Κλειδί (130 χαρακτήρες [0-9A-F]):",
"detaillabelpublickeycomp": "Δημόσιο Κλειδί (Συμπιεσμένο, 66 χαρακτήρες [0-9A-F]):",
"detaillabelprivwif": "Προσωπικό Κλειδί WIF<br />51 χαρακτήρες base58, ξεκινάει με",
"detaillabelprivwifcomp": "Προσωπικό Κλειδί WIF<br />Συμπιεσμένο, 52 χαρακτήρες base58, ξεκινάει με",
"detaillabelprivhex": "Προσωπικό Κλειδί Δεκαεξαδική Μορφή (64 χαρακτήρες [0-9A-F]):",
"detaillabelprivb64": "Προσωπικό Κλειδί Base64 (44 χαρακτήρες):",
"detaillabelprivmini": "Προσωπικό Κλειδί Μορφή Mini (22, 26 ή 30 χαρακτήρες, ξεκινάει με 'S'):",
"detaillabelpassphrase": "BIP38 Κωδικός",
"detaildecrypt": "Αποκωδικοποίηση BIP38"
}
}
};
ninja.translator.showEnglishJson = function () {
var english = ninja.translator.translations["en"];
var spanish = ninja.translator.translations["es"];
var spanishClone = {};
for (var key in spanish) {
spanishClone[key] = spanish[key];
}
var newLang = {};
for (var key in english) {
newLang[key] = english[key];
delete spanishClone[key];
}
for (var key in spanishClone) {
if (document.getElementById(key)) {
if (document.getElementById(key).value) {
newLang[key] = document.getElementById(key).value;
}
else {
newLang[key] = document.getElementById(key).innerHTML;
}
}
}
var div = document.createElement("div");
div.setAttribute("class", "englishjson");
div.innerHTML = "<h3>English Json</h3>";
var elem = document.createElement("textarea");
elem.setAttribute("rows", "15");
elem.setAttribute("cols", "110");
elem.setAttribute("wrap", "off");
var langJson = "{\n";
for (var key in newLang) {
langJson += "\t\"" + key + "\"" + ": " + "\"" + newLang[key].replace(/\"/g, "\\\"").replace(/\n/g, "\\n") + "\",\n";
}
langJson = langJson.substr(0, langJson.length - 2);
langJson += "\n}\n";
elem.innerHTML = langJson;
div.appendChild(elem);
document.body.appendChild(div);
};
</script>
<script type="text/javascript">
ninja.wallets.singlewallet = {
open: function () {
if (document.getElementById("btcaddress").innerHTML == "") {
ninja.wallets.singlewallet.generateNewAddressAndKey();
}
document.getElementById("singlearea").style.display = "block";
},
close: function () {
document.getElementById("singlearea").style.display = "none";
},
// 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, 4);
}
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 = "";
}
}
};
</script>
<script type="text/javascript">
ninja.wallets.paperwallet = {
open: function () {
document.getElementById("main").setAttribute("class", "paper"); // add 'paper' class to main div
var paperArea = document.getElementById("paperarea");
paperArea.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 (document.getElementById("paperkeyarea").innerHTML == "") {
document.getElementById("paperpassphrase").disabled = true;
document.getElementById("paperencrypt").checked = false;
ninja.wallets.paperwallet.encrypt = false;
ninja.wallets.paperwallet.build(pageBreakAt, pageBreakAt, !document.getElementById('paperart').checked, document.getElementById('paperpassphrase').value);
}
},
close: function () {
document.getElementById("paperarea").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, passphrase) {
if (numWallets < 1) numWallets = 1;
if (pageBreakAt < 1) pageBreakAt = 1;
ninja.wallets.paperwallet.remaining = numWallets;
ninja.wallets.paperwallet.count = 0;
ninja.wallets.paperwallet.useArtisticWallet = useArtisticWallet;
ninja.wallets.paperwallet.pageBreakAt = pageBreakAt;
document.getElementById("paperkeyarea").innerHTML = "";
if (ninja.wallets.paperwallet.encrypt) {
document.getElementById("busyblock").className = "busy";
ninja.privateKey.BIP38GenerateIntermediatePointAsync(passphrase, null, null, function (intermediate) {
ninja.wallets.paperwallet.intermediatePoint = intermediate;
document.getElementById("busyblock").className = "";
setTimeout(ninja.wallets.paperwallet.batch, 0);
});
}
else {
setTimeout(ninja.wallets.paperwallet.batch, 0);
}
},
batch: function () {
if (ninja.wallets.paperwallet.remaining > 0) {
var paperArea = document.getElementById("paperkeyarea");
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 - 1) % pageBreakAt == 0 && i >= pageBreakAt) {
var pBreak = document.createElement("div");
pBreak.setAttribute("class", "pagebreak");
document.getElementById("paperkeyarea").appendChild(pBreak);
div.style.pageBreakBefore = "always";
if (!ninja.wallets.paperwallet.useArtisticWallet) {
div.style.borderTop = "2px solid green";
}
}
}
document.getElementById("paperkeyarea").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) {
if (ninja.wallets.paperwallet.encrypt) {
ninja.privateKey.BIP38GenerateECAddressAsync(ninja.wallets.paperwallet.intermediatePoint, false, function (address, encryptedKey) {
if (ninja.wallets.paperwallet.useArtisticWallet) {
ninja.wallets.paperwallet.showArtisticWallet(idPostFix, address, encryptedKey);
}
else {
ninja.wallets.paperwallet.showWallet(idPostFix, address, encryptedKey);
}
});
}
else {
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 privateKeyLabel = ninja.translator.get("paperlabelprivatekey");
if (ninja.wallets.paperwallet.encrypt) {
privateKeyLabel = ninja.translator.get("paperlabelencryptedkey");
}
var walletHtml =
"<div class='public'>" +
"<div id='qrcode_public" + i + "' class='qrcode_public'></div>" +
"<div class='pubaddress'>" +
"<span class='label'>" + ninja.translator.get("paperlabelbitcoinaddress") + "</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'>" + privateKeyLabel + "</span>" +
"<span class='output' id='btcprivwif" + i + "'></span>" +
"</div>" +
"</div>";
return walletHtml;
},
showWallet: function (idPostFix, bitcoinAddress, privateKey) {
document.getElementById("btcaddress" + idPostFix).innerHTML = bitcoinAddress;
document.getElementById("btcprivwif" + idPostFix).innerHTML = privateKey;
var keyValuePair = {};
keyValuePair["qrcode_public" + idPostFix] = bitcoinAddress;
keyValuePair["qrcode_private" + idPostFix] = privateKey;
ninja.qrCode.showQrCode(keyValuePair);
document.getElementById("keyarea" + idPostFix).style.display = "block";
},
templateArtisticHtml: function (i) {
var keyelement = 'btcprivwif';
var image = 'data:image/png;base64,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';;
if (ninja.wallets.paperwallet.encrypt) {
keyelement = 'btcencryptedkey'
}
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='" + image + "' />" +
"<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='" + keyelement + "' id='" + keyelement + i + "'></div>" +
"</div>";
return walletHtml;
},
showArtisticWallet: function (idPostFix, bitcoinAddress, privateKey) {
var keyValuePair = {};
keyValuePair["qrcode_public" + idPostFix] = bitcoinAddress;
keyValuePair["qrcode_private" + idPostFix] = privateKey;
ninja.qrCode.showQrCode(keyValuePair, 2.5);
document.getElementById("btcaddress" + idPostFix).innerHTML = bitcoinAddress;
if (ninja.wallets.paperwallet.encrypt) {
var third = privateKey.length / 3;
document.getElementById("btcencryptedkey" + idPostFix).innerHTML = privateKey.slice(0, third) + '<br />' + privateKey.slice(third, 2 * third) + '<br />' + privateKey.slice(2 * third);
}
else {
document.getElementById("btcprivwif" + idPostFix).innerHTML = privateKey;
}
// 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) {
ninja.wallets.paperwallet.resetLimits();
},
toggleEncrypt: function (element) {
// enable/disable passphrase textbox
document.getElementById("paperpassphrase").disabled = !element.checked;
ninja.wallets.paperwallet.encrypt = element.checked;
ninja.wallets.paperwallet.resetLimits();
},
resetLimits: function () {
var hideArt = document.getElementById("paperart");
var paperEncrypt = document.getElementById("paperencrypt");
var limit;
var limitperpage;
document.getElementById("paperkeyarea").style.fontSize = "100%";
if (!hideArt.checked) {
limit = ninja.wallets.paperwallet.pageBreakAtArtisticDefault;
limitperpage = ninja.wallets.paperwallet.pageBreakAtArtisticDefault;
}
else if (hideArt.checked && paperEncrypt.checked) {
limit = ninja.wallets.paperwallet.pageBreakAtDefault;
limitperpage = ninja.wallets.paperwallet.pageBreakAtDefault;
// reduce font size
document.getElementById("paperkeyarea").style.fontSize = "95%";
}
else if (hideArt.checked && !paperEncrypt.checked) {
limit = ninja.wallets.paperwallet.pageBreakAtDefault;
limitperpage = ninja.wallets.paperwallet.pageBreakAtDefault;
}
document.getElementById("paperlimitperpage").value = limitperpage;
document.getElementById("paperlimit").value = limit;
}
};
</script>
<script type="text/javascript">
ninja.wallets.bulkwallet = {
open: function () {
document.getElementById("bulkarea").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, document.getElementById("bulkcompressed").checked); }, 200);
}
},
close: function () {
document.getElementById("bulkarea").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, compressedAddrs) {
var bulkWallet = ninja.wallets.bulkwallet;
document.getElementById("bulktextarea").value = ninja.translator.get("bulkgeneratingaddresses") + rowLimit;
bulkWallet.csv = [];
bulkWallet.csvRowLimit = rowLimit;
bulkWallet.csvRowsRemaining = rowLimit;
bulkWallet.csvStartIndex = --startIndex;
bulkWallet.compressedAddrs = !!compressedAddrs;
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);
key.setCompressed(bulkWallet.compressedAddrs);
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 = ninja.translator.get("bulkgeneratingaddresses") + 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");
}
}
};
</script>
<script type="text/javascript">
ninja.wallets.brainwallet = {
open: function () {
document.getElementById("brainarea").style.display = "block";
document.getElementById("brainpassphrase").focus();
document.getElementById("brainwarning").innerHTML = ninja.translator.get("brainalertpassphrasewarning");
},
close: function () {
document.getElementById("brainarea").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.visibility = "visible";
}
else {
alert(ninja.translator.get("brainalertpassphrasetooshort") + ninja.translator.get("brainalertpassphrasewarning"));
ninja.wallets.brainwallet.clear();
}
}
else {
alert(ninja.translator.get("brainalertpassphrasedoesnotmatch"));
ninja.wallets.brainwallet.clear();
}
},
clear: function () {
document.getElementById("brainkeyarea").style.visibility = "hidden";
},
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";
}
}
};
</script>
<script type="text/javascript">
ninja.wallets.vanitywallet = {
open: function () {
document.getElementById("vanityarea").style.display = "block";
},
close: function () {
document.getElementById("vanityarea").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 = key.getPubKeyHex();
var privateKey = key.getBitcoinHexFormat();
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 = ninja.translator.get("vanityinvalidinputcouldnotcombinekeys");
var bitcoinAddress = ninja.translator.get("vanityinvalidinputcouldnotcombinekeys");
var publicKeyHex = ninja.translator.get("vanityinvalidinputcouldnotcombinekeys");
try {
var input1KeyString = document.getElementById("vanityinput1").value;
var input2KeyString = document.getElementById("vanityinput2").value;
// both inputs are public keys
if (ninja.publicKey.isPublicKeyHexFormat(input1KeyString) && ninja.publicKey.isPublicKeyHexFormat(input2KeyString)) {
// add both public keys together
if (document.getElementById("vanityradioadd").checked) {
var pubKeyByteArray = ninja.publicKey.getByteArrayFromAdding(input1KeyString, input2KeyString);
if (pubKeyByteArray == null) {
alert(ninja.translator.get("vanityalertinvalidinputpublickeysmatch"));
}
else {
privateKeyWif = ninja.translator.get("vanityprivatekeyonlyavailable");
bitcoinAddress = ninja.publicKey.getBitcoinAddressFromByteArray(pubKeyByteArray);
publicKeyHex = ninja.publicKey.getHexFromByteArray(pubKeyByteArray);
}
}
else {
alert(ninja.translator.get("vanityalertinvalidinputcannotmultiple"));
}
}
// one public key and one private key
else if ((ninja.publicKey.isPublicKeyHexFormat(input1KeyString) && ninja.privateKey.isPrivateKey(input2KeyString))
|| (ninja.publicKey.isPublicKeyHexFormat(input2KeyString) && ninja.privateKey.isPrivateKey(input1KeyString))
) {
privateKeyWif = ninja.translator.get("vanityprivatekeyonlyavailable");
var pubKeyHex = (ninja.publicKey.isPublicKeyHexFormat(input1KeyString)) ? input1KeyString : input2KeyString;
var ecKey = (ninja.privateKey.isPrivateKey(input1KeyString)) ? new Bitcoin.ECKey(input1KeyString) : new Bitcoin.ECKey(input2KeyString);
// add
if (document.getElementById("vanityradioadd").checked) {
var pubKeyCombined = ninja.publicKey.getByteArrayFromAdding(pubKeyHex, ecKey.getPubKeyHex());
}
// multiply
else {
var pubKeyCombined = ninja.publicKey.getByteArrayFromMultiplying(pubKeyHex, ecKey);
}
if (pubKeyCombined == null) {
alert(ninja.translator.get("vanityalertinvalidinputpublickeysmatch"));
} else {
bitcoinAddress = ninja.publicKey.getBitcoinAddressFromByteArray(pubKeyCombined);
publicKeyHex = ninja.publicKey.getHexFromByteArray(pubKeyCombined);
}
}
// both inputs are private keys
else if (ninja.privateKey.isPrivateKey(input1KeyString) && ninja.privateKey.isPrivateKey(input2KeyString)) {
var combinedPrivateKey;
// add both private keys together
if (document.getElementById("vanityradioadd").checked) {
combinedPrivateKey = ninja.privateKey.getECKeyFromAdding(input1KeyString, input2KeyString);
}
// multiply both private keys together
else {
combinedPrivateKey = ninja.privateKey.getECKeyFromMultiplying(input1KeyString, input2KeyString);
}
if (combinedPrivateKey == null) {
alert(ninja.translator.get("vanityalertinvalidinputprivatekeysmatch"));
}
else {
bitcoinAddress = combinedPrivateKey.getBitcoinAddress();
privateKeyWif = combinedPrivateKey.getBitcoinWalletImportFormat();
publicKeyHex = combinedPrivateKey.getPubKeyHex();
}
}
} catch (e) {
alert(e);
}
document.getElementById("vanityprivatekeywif").innerHTML = privateKeyWif;
document.getElementById("vanityaddress").innerHTML = bitcoinAddress;
document.getElementById("vanitypublickeyhex").innerHTML = publicKeyHex;
document.getElementById("vanitystep2area").style.display = "block";
document.getElementById("vanitystep2icon").setAttribute("class", "less");
},
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");
}
}
};
</script>
<script type="text/javascript">
ninja.wallets.detailwallet = {
open: function () {
document.getElementById("detailarea").style.display = "block";
document.getElementById("detailprivkey").focus();
},
close: function () {
document.getElementById("detailarea").style.display = "none";
},
viewDetails: function () {
var bip38 = false;
var key = document.getElementById("detailprivkey").value.toString().replace(/^\s+|\s+$/g, ""); // trim white space
if (key == "") {
ninja.wallets.detailwallet.clear();
return;
}
document.getElementById("detailprivkey").value = key;
if (Bitcoin.ECKey.isMiniFormat(key)) {
// show Private Key Mini Format
document.getElementById("detailprivmini").innerHTML = key;
document.getElementById("detailmini").style.display = "block";
document.getElementById("detailbip38commands").style.display = "none";
}
else if (ninja.privateKey.isBIP38Format(key)) {
if (document.getElementById("detailbip38commands").style.display != "block") {
document.getElementById("detailbip38commands").style.display = "block";
document.getElementById("detailprivkeypassphrase").focus();
return;
}
else {
bip38 = true;
}
}
else {
// hide Private Key Mini Format
document.getElementById("detailmini").style.display = "none";
document.getElementById("detailbip38commands").style.display = "none";
}
if (bip38) {
var passphrase = document.getElementById("detailprivkeypassphrase").value.toString().replace(/^\s+|\s+$/g, ""); // trim white space
if (passphrase == "") {
alert(ninja.translator.get("bip38alertpassphraserequired"));
return;
}
ninja.privateKey.BIP38EncryptedKeyToByteArrayAsync(key, passphrase, function (btcKeyOrError) {
document.getElementById("busyblock").className = "";
if (btcKeyOrError.message) {
alert(btcKeyOrError.message);
ninja.wallets.detailwallet.clear();
} else {
ninja.wallets.detailwallet.populateKeyDetails(new Bitcoin.ECKey(btcKeyOrError));
}
});
document.getElementById("busyblock").className = "busy";
}
else {
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.priv == null) {
// 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(ninja.translator.get("detailconfirmsha256"));
if (usePassphrase) {
var bytes = Crypto.SHA256(key, { asBytes: true });
var btcKey = new Bitcoin.ECKey(bytes);
}
else {
ninja.wallets.detailwallet.clear();
}
}
else {
alert(ninja.translator.get("detailalertnotvalidprivatekey"));
ninja.wallets.detailwallet.clear();
}
}
ninja.wallets.detailwallet.populateKeyDetails(btcKey);
}
},
populateKeyDetails: function (btcKey) {
if (btcKey.priv != null) {
btcKey.setCompressed(false);
document.getElementById("detailprivhex").innerHTML = btcKey.toString().toUpperCase();
document.getElementById("detailprivb64").innerHTML = btcKey.toString("base64");
var bitcoinAddress = btcKey.getBitcoinAddress();
var wif = btcKey.getBitcoinWalletImportFormat();
document.getElementById("detailpubkey").innerHTML = btcKey.getPubKeyHex();
document.getElementById("detailaddress").innerHTML = bitcoinAddress;
document.getElementById("detailprivwif").innerHTML = wif;
btcKey.setCompressed(true);
var bitcoinAddressComp = btcKey.getBitcoinAddress();
var wifComp = btcKey.getBitcoinWalletImportFormat();
document.getElementById("detailpubkeycomp").innerHTML = btcKey.getPubKeyHex();
document.getElementById("detailaddresscomp").innerHTML = bitcoinAddressComp;
document.getElementById("detailprivwifcomp").innerHTML = wifComp;
ninja.qrCode.showQrCode({
"detailqrcodepublic": bitcoinAddress,
"detailqrcodepubliccomp": bitcoinAddressComp,
"detailqrcodeprivate": wif,
"detailqrcodeprivatecomp": wifComp
}, 4);
}
},
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 = "";
document.getElementById("detailbip38commands").style.display = "none";
}
};
</script>
<script type="text/javascript">
(function (ninja) {
var ut = ninja.unitTests = {
runSynchronousTests: function () {
document.getElementById("busyblock").className = "busy";
var div = document.createElement("div");
div.setAttribute("class", "unittests");
div.setAttribute("id", "unittests");
var testResults = "";
var passCount = 0;
var testCount = 0;
for (var test in ut.synchronousTests) {
var exceptionMsg = "";
var resultBool = false;
try {
resultBool = ut.synchronousTests[test]();
} catch (ex) {
exceptionMsg = ex.toString();
resultBool = false;
}
if (resultBool == true) {
var passFailStr = "pass";
passCount++;
}
else {
var passFailStr = "<b>FAIL " + exceptionMsg + "</b>";
}
testCount++;
testResults += test + ": " + passFailStr + "<br/>";
}
testResults += passCount + " of " + testCount + " synchronous tests passed";
if (passCount < testCount) {
testResults += "<b>" + (testCount - passCount) + " unit test(s) failed</b>";
}
div.innerHTML = "<h3>Unit Tests</h3><div id=\"unittestresults\">" + testResults + "<br/><br/></div>";
document.body.appendChild(div);
document.getElementById("busyblock").className = "";
},
runAsynchronousTests: function () {
var div = document.createElement("div");
div.setAttribute("class", "unittests");
div.setAttribute("id", "asyncunittests");
div.innerHTML = "<h3>Async Unit Tests</h3><div id=\"asyncunittestresults\"></div><br/><br/><br/><br/>";
document.body.appendChild(div);
// run the asynchronous tests one after another so we don't crash the browser
ninja.foreachSerialized(ninja.unitTests.asynchronousTests, function (name, cb) {
document.getElementById("busyblock").className = "busy";
ninja.unitTests.asynchronousTests[name](cb);
}, function () {
document.getElementById("asyncunittestresults").innerHTML += "running of asynchronous unit tests complete!<br/>";
document.getElementById("busyblock").className = "";
});
},
synchronousTests: {
//ninja.publicKey tests
testIsPublicKeyHexFormat: function () {
var key = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var bool = ninja.publicKey.isPublicKeyHexFormat(key);
if (bool != true) {
return false;
}
return true;
},
testGetHexFromByteArray: function () {
var bytes = [4, 120, 152, 47, 64, 250, 12, 11, 122, 85, 113, 117, 131, 175, 201, 154, 78, 223, 211, 1, 162, 114, 157, 197, 155, 11, 142, 185, 225, 134, 146, 188, 181, 33, 240, 84, 250, 217, 130, 175, 76, 193, 147, 58, 253, 31, 27, 86, 62, 167, 121, 166, 170, 108, 206, 54, 163, 11, 148, 125, 214, 83, 230, 62, 68];
var key = ninja.publicKey.getHexFromByteArray(bytes);
if (key != "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44") {
return false;
}
return true;
},
testHexToBytes: function () {
var key = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var bytes = Crypto.util.hexToBytes(key);
if (bytes.toString() != "4,120,152,47,64,250,12,11,122,85,113,117,131,175,201,154,78,223,211,1,162,114,157,197,155,11,142,185,225,134,146,188,181,33,240,84,250,217,130,175,76,193,147,58,253,31,27,86,62,167,121,166,170,108,206,54,163,11,148,125,214,83,230,62,68") {
return false;
}
return true;
},
testGetBitcoinAddressFromByteArray: function () {
var bytes = [4, 120, 152, 47, 64, 250, 12, 11, 122, 85, 113, 117, 131, 175, 201, 154, 78, 223, 211, 1, 162, 114, 157, 197, 155, 11, 142, 185, 225, 134, 146, 188, 181, 33, 240, 84, 250, 217, 130, 175, 76, 193, 147, 58, 253, 31, 27, 86, 62, 167, 121, 166, 170, 108, 206, 54, 163, 11, 148, 125, 214, 83, 230, 62, 68];
var address = ninja.publicKey.getBitcoinAddressFromByteArray(bytes);
if (address != "1Cnz9ULjzBPYhDw1J8bpczDWCEXnC9HuU1") {
return false;
}
return true;
},
testGetByteArrayFromAdding: function () {
var key1 = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var key2 = "0419153E53FECAD7FF07FEC26F7DDEB1EDD66957711AA4554B8475F10AFBBCD81C0159DC0099AD54F733812892EB9A11A8C816A201B3BAF0D97117EBA2033C9AB2";
var bytes = ninja.publicKey.getByteArrayFromAdding(key1, key2);
if (bytes.toString() != "4,151,19,227,152,54,37,184,255,4,83,115,216,102,189,76,82,170,57,4,196,253,2,41,74,6,226,33,167,199,250,74,235,223,128,233,99,150,147,92,57,39,208,84,196,71,68,248,166,106,138,95,172,253,224,70,187,65,62,92,81,38,253,79,0") {
return false;
}
return true;
},
testGetByteArrayFromAddingCompressed: function () {
var key1 = "0278982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB5";
var key2 = "0219153E53FECAD7FF07FEC26F7DDEB1EDD66957711AA4554B8475F10AFBBCD81C";
var bytes = ninja.publicKey.getByteArrayFromAdding(key1, key2);
var hex = ninja.publicKey.getHexFromByteArray(bytes);
if (hex != "029713E3983625B8FF045373D866BD4C52AA3904C4FD02294A06E221A7C7FA4AEB") {
return false;
}
return true;
},
testGetByteArrayFromAddingUncompressedAndCompressed: function () {
var key1 = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var key2 = "0219153E53FECAD7FF07FEC26F7DDEB1EDD66957711AA4554B8475F10AFBBCD81C";
var bytes = ninja.publicKey.getByteArrayFromAdding(key1, key2);
if (bytes.toString() != "4,151,19,227,152,54,37,184,255,4,83,115,216,102,189,76,82,170,57,4,196,253,2,41,74,6,226,33,167,199,250,74,235,223,128,233,99,150,147,92,57,39,208,84,196,71,68,248,166,106,138,95,172,253,224,70,187,65,62,92,81,38,253,79,0") {
return false;
}
return true;
},
testGetByteArrayFromAddingShouldReturnNullWhenSameKey1: function () {
var key1 = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var key2 = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var bytes = ninja.publicKey.getByteArrayFromAdding(key1, key2);
if (bytes != null) {
return false;
}
return true;
},
testGetByteArrayFromAddingShouldReturnNullWhenSameKey2: function () {
var key1 = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var key2 = "0278982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB5";
var bytes = ninja.publicKey.getByteArrayFromAdding(key1, key2);
if (bytes != null) {
return false;
}
return true;
},
testGetByteArrayFromMultiplying: function () {
var key1 = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var key2 = "SQE6yipP5oW8RBaStWoB47xsRQ8pat";
var bytes = ninja.publicKey.getByteArrayFromMultiplying(key1, new Bitcoin.ECKey(key2));
if (bytes.toString() != "4,102,230,163,180,107,9,21,17,48,35,245,227,110,199,119,144,57,41,112,64,245,182,40,224,41,230,41,5,26,206,138,57,115,35,54,105,7,180,5,106,217,57,229,127,174,145,215,79,121,163,191,211,143,215,50,48,156,211,178,72,226,68,150,52") {
return false;
}
return true;
},
testGetByteArrayFromMultiplyingCompressedOutputsUncompressed: function () {
var key1 = "0278982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB5";
var key2 = "SQE6yipP5oW8RBaStWoB47xsRQ8pat";
var bytes = ninja.publicKey.getByteArrayFromMultiplying(key1, new Bitcoin.ECKey(key2));
if (bytes.toString() != "4,102,230,163,180,107,9,21,17,48,35,245,227,110,199,119,144,57,41,112,64,245,182,40,224,41,230,41,5,26,206,138,57,115,35,54,105,7,180,5,106,217,57,229,127,174,145,215,79,121,163,191,211,143,215,50,48,156,211,178,72,226,68,150,52") {
return false;
}
return true;
},
testGetByteArrayFromMultiplyingCompressedOutputsCompressed: function () {
var key1 = "0278982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB5";
var key2 = "L1n4cgNZAo2KwdUc15zzstvo1dcxpBw26NkrLqfDZtU9AEbPkLWu";
var ecKey = new Bitcoin.ECKey(key2);
var bytes = ninja.publicKey.getByteArrayFromMultiplying(key1, ecKey);
if (bytes.toString() != "2,102,230,163,180,107,9,21,17,48,35,245,227,110,199,119,144,57,41,112,64,245,182,40,224,41,230,41,5,26,206,138,57") {
return false;
}
return true;
},
testGetByteArrayFromMultiplyingShouldReturnNullWhenSameKey1: function () {
var key1 = "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44";
var key2 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var bytes = ninja.publicKey.getByteArrayFromMultiplying(key1, new Bitcoin.ECKey(key2));
if (bytes != null) {
return false;
}
return true;
},
testGetByteArrayFromMultiplyingShouldReturnNullWhenSameKey2: function () {
var key1 = "0278982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB5";
var key2 = "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S";
var bytes = ninja.publicKey.getByteArrayFromMultiplying(key1, new Bitcoin.ECKey(key2));
if (bytes != null) {
return false;
}
return true;
},
// confirms multiplication is working and BigInteger was created correctly (Pub Key B vs Priv Key A)
testGetPubHexFromMultiplyingPrivAPubB: function () {
var keyPub = "04F04BF260DCCC46061B5868F60FE962C77B5379698658C98A93C3129F5F98938020F36EBBDE6F1BEAF98E5BD0E425747E68B0F2FB7A2A59EDE93F43C0D78156FF";
var keyPriv = "B1202A137E917536B3B4C5010C3FF5DDD4784917B3EEF21D3A3BF21B2E03310C";
var bytes = ninja.publicKey.getByteArrayFromMultiplying(keyPub, new Bitcoin.ECKey(keyPriv));
var pubHex = ninja.publicKey.getHexFromByteArray(bytes);
if (pubHex != "04C6732006AF4AE571C7758DF7A7FB9E3689DFCF8B53D8724D3A15517D8AB1B4DBBE0CB8BB1C4525F8A3001771FC7E801D3C5986A555E2E9441F1AD6D181356076") {
return false;
}
return true;
},
// confirms multiplication is working and BigInteger was created correctly (Pub Key A vs Priv Key B)
testGetPubHexFromMultiplyingPrivBPubA: function () {
var keyPub = "0429BF26C0AF7D31D608474CEBD49DA6E7C541B8FAD95404B897643476CE621CFD05E24F7AE8DE8033AADE5857DB837E0B704A31FDDFE574F6ECA879643A0D3709";
var keyPriv = "7DE52819F1553C2BFEDE6A2628B6FDDF03C2A07EB21CF77ACA6C2C3D252E1FD9";
var bytes = ninja.publicKey.getByteArrayFromMultiplying(keyPub, new Bitcoin.ECKey(keyPriv));
var pubHex = ninja.publicKey.getHexFromByteArray(bytes);
if (pubHex != "04C6732006AF4AE571C7758DF7A7FB9E3689DFCF8B53D8724D3A15517D8AB1B4DBBE0CB8BB1C4525F8A3001771FC7E801D3C5986A555E2E9441F1AD6D181356076") {
return false;
}
return true;
},
// Private Key tests
testBadKeyIsNotWif: function () {
return !(Bitcoin.ECKey.isWalletImportFormat("bad key"));
},
testBadKeyIsNotWifCompressed: function () {
return !(Bitcoin.ECKey.isCompressedWalletImportFormat("bad key"));
},
testBadKeyIsNotHex: function () {
return !(Bitcoin.ECKey.isHexFormat("bad key"));
},
testBadKeyIsNotBase64: function () {
return !(Bitcoin.ECKey.isBase64Format("bad key"));
},
testBadKeyIsNotMini: function () {
return !(Bitcoin.ECKey.isMiniFormat("bad key"));
},
testBadKeyReturnsNullPrivFromECKey: function () {
var key = "bad key";
var ecKey = new Bitcoin.ECKey(key);
if (ecKey.priv != null) {
return false;
}
return true;
},
testGetBitcoinPrivateKeyByteArray: function () {
var key = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var bytes = [41, 38, 101, 195, 135, 36, 24, 173, 241, 218, 127, 250, 58, 100, 111, 47, 6, 2, 36, 109, 166, 9, 138, 145, 210, 41, 195, 33, 80, 242, 113, 139];
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinPrivateKeyByteArray().toString() != bytes.toString()) {
return false;
}
return true;
},
testECKeyDecodeWalletImportFormat: function () {
var key = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var bytes1 = [41, 38, 101, 195, 135, 36, 24, 173, 241, 218, 127, 250, 58, 100, 111, 47, 6, 2, 36, 109, 166, 9, 138, 145, 210, 41, 195, 33, 80, 242, 113, 139];
var bytes2 = Bitcoin.ECKey.decodeWalletImportFormat(key);
if (bytes1.toString() != bytes2.toString()) {
return false;
}
return true;
},
testECKeyDecodeCompressedWalletImportFormat: function () {
var key = "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S";
var bytes1 = [41, 38, 101, 195, 135, 36, 24, 173, 241, 218, 127, 250, 58, 100, 111, 47, 6, 2, 36, 109, 166, 9, 138, 145, 210, 41, 195, 33, 80, 242, 113, 139];
var bytes2 = Bitcoin.ECKey.decodeCompressedWalletImportFormat(key);
if (bytes1.toString() != bytes2.toString()) {
return false;
}
return true;
},
testWifToPubKeyHex: function () {
var key = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getPubKeyHex() != "0478982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB521F054FAD982AF4CC1933AFD1F1B563EA779A6AA6CCE36A30B947DD653E63E44"
|| btcKey.getPubPoint().compressed != false) {
return false;
}
return true;
},
testWifToPubKeyHexCompressed: function () {
var key = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var btcKey = new Bitcoin.ECKey(key);
btcKey.setCompressed(true);
if (btcKey.getPubKeyHex() != "0278982F40FA0C0B7A55717583AFC99A4EDFD301A2729DC59B0B8EB9E18692BCB5"
|| btcKey.getPubPoint().compressed != true) {
return false;
}
return true;
},
testBase64ToECKey: function () {
var key = "KSZlw4ckGK3x2n/6OmRvLwYCJG2mCYqR0inDIVDycYs=";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinBase64Format() != "KSZlw4ckGK3x2n/6OmRvLwYCJG2mCYqR0inDIVDycYs=") {
return false;
}
return true;
},
testHexToECKey: function () {
var key = "292665C3872418ADF1DA7FFA3A646F2F0602246DA6098A91D229C32150F2718B";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinHexFormat() != "292665C3872418ADF1DA7FFA3A646F2F0602246DA6098A91D229C32150F2718B") {
return false;
}
return true;
},
testCompressedWifToECKey: function () {
var key = "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinWalletImportFormat() != "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S"
|| btcKey.getPubPoint().compressed != true) {
return false;
}
return true;
},
testWifToECKey: function () {
var key = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinWalletImportFormat() != "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb") {
return false;
}
return true;
},
testBrainToECKey: function () {
var key = "bitaddress.org unit test";
var bytes = Crypto.SHA256(key, { asBytes: true });
var btcKey = new Bitcoin.ECKey(bytes);
if (btcKey.getBitcoinWalletImportFormat() != "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb") {
return false;
}
return true;
},
testMini30CharsToECKey: function () {
var key = "SQE6yipP5oW8RBaStWoB47xsRQ8pat";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinWalletImportFormat() != "5JrBLQseeZdYw4jWEAHmNxGMr5fxh9NJU3fUwnv4khfKcg2rJVh") {
return false;
}
return true;
},
testGetECKeyFromAdding: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "SQE6yipP5oW8RBaStWoB47xsRQ8pat";
var ecKey = ninja.privateKey.getECKeyFromAdding(key1, key2);
if (ecKey.getBitcoinWalletImportFormat() != "5KAJTSqSjpsZ11KyEE3qu5PrJVjR4ZCbNxK3Nb1F637oe41m1c2") {
return false;
}
return true;
},
testGetECKeyFromAddingCompressed: function () {
var key1 = "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S";
var key2 = "L1n4cgNZAo2KwdUc15zzstvo1dcxpBw26NkrLqfDZtU9AEbPkLWu";
var ecKey = ninja.privateKey.getECKeyFromAdding(key1, key2);
if (ecKey.getBitcoinWalletImportFormat() != "L3A43j2pc2J8F2SjBNbYprPrcDpDCh8Aju8dUH65BEM2r7RFSLv4") {
return false;
}
return true;
},
testGetECKeyFromAddingUncompressedAndCompressed: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "L1n4cgNZAo2KwdUc15zzstvo1dcxpBw26NkrLqfDZtU9AEbPkLWu";
var ecKey = ninja.privateKey.getECKeyFromAdding(key1, key2);
if (ecKey.getBitcoinWalletImportFormat() != "5KAJTSqSjpsZ11KyEE3qu5PrJVjR4ZCbNxK3Nb1F637oe41m1c2") {
return false;
}
return true;
},
testGetECKeyFromAddingShouldReturnNullWhenSameKey1: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var ecKey = ninja.privateKey.getECKeyFromAdding(key1, key2);
if (ecKey != null) {
return false;
}
return true;
},
testGetECKeyFromAddingShouldReturnNullWhenSameKey2: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S";
var ecKey = ninja.privateKey.getECKeyFromAdding(key1, key2);
if (ecKey != null) {
return false;
}
return true;
},
testGetECKeyFromMultiplying: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "SQE6yipP5oW8RBaStWoB47xsRQ8pat";
var ecKey = ninja.privateKey.getECKeyFromMultiplying(key1, key2);
if (ecKey.getBitcoinWalletImportFormat() != "5KetpZ5mCGagCeJnMmvo18n4iVrtPSqrpnW5RP92Gv2BQy7GPCk") {
return false;
}
return true;
},
testGetECKeyFromMultiplyingCompressed: function () {
var key1 = "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S";
var key2 = "L1n4cgNZAo2KwdUc15zzstvo1dcxpBw26NkrLqfDZtU9AEbPkLWu";
var ecKey = ninja.privateKey.getECKeyFromMultiplying(key1, key2);
if (ecKey.getBitcoinWalletImportFormat() != "L5LFitc24jme2PfVChJS3bKuQAPBp54euuqLWciQdF2CxnaU3M8t") {
return false;
}
return true;
},
testGetECKeyFromMultiplyingUncompressedAndCompressed: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "L1n4cgNZAo2KwdUc15zzstvo1dcxpBw26NkrLqfDZtU9AEbPkLWu";
var ecKey = ninja.privateKey.getECKeyFromMultiplying(key1, key2);
if (ecKey.getBitcoinWalletImportFormat() != "5KetpZ5mCGagCeJnMmvo18n4iVrtPSqrpnW5RP92Gv2BQy7GPCk") {
return false;
}
return true;
},
testGetECKeyFromMultiplyingShouldReturnNullWhenSameKey1: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var ecKey = ninja.privateKey.getECKeyFromMultiplying(key1, key2);
if (ecKey != null) {
return false;
}
return true;
},
testGetECKeyFromMultiplyingShouldReturnNullWhenSameKey2: function () {
var key1 = "5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb";
var key2 = "KxbhchnQquYQ2dfSxz7rrEaQTCukF4uCV57TkamyTbLzjFWcdi3S";
var ecKey = ninja.privateKey.getECKeyFromMultiplying(key1, key2);
if (ecKey != null) {
return false;
}
return true;
},
testGetECKeyFromBase6Key: function () {
var base = 6;
var baseKey = "100531114202410255230521444145414341221420541210522412225005202300434134213212540304311321323051431";
var hexKey = "292665C3872418ADF1DA7FFA3A646F2F0602246DA6098A91D229C32150F2718B";
var bigInt = new BigInteger(baseKey, base);
var ecKey = new Bitcoin.ECKey(bigInt);
if (ecKey.getBitcoinHexFormat() != hexKey) {
return false;
}
return true;
},
// EllipticCurve tests
testDecodePointEqualsDecodeFrom: function () {
var key = "04F04BF260DCCC46061B5868F60FE962C77B5379698658C98A93C3129F5F98938020F36EBBDE6F1BEAF98E5BD0E425747E68B0F2FB7A2A59EDE93F43C0D78156FF";
var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
var ecPoint1 = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), Crypto.util.hexToBytes(key));
var ecPoint2 = ecparams.getCurve().decodePointHex(key);
if (!ecPoint1.equals(ecPoint2)) {
return false;
}
return true;
},
testDecodePointHexForCompressedPublicKey: function () {
var key = "03F04BF260DCCC46061B5868F60FE962C77B5379698658C98A93C3129F5F989380";
var pubHexUncompressed = ninja.publicKey.getDecompressedPubKeyHex(key);
if (pubHexUncompressed != "04F04BF260DCCC46061B5868F60FE962C77B5379698658C98A93C3129F5F98938020F36EBBDE6F1BEAF98E5BD0E425747E68B0F2FB7A2A59EDE93F43C0D78156FF") {
return false;
}
return true;
},
// old bugs
testBugWithLeadingZeroBytePublicKey: function () {
var key = "5Je7CkWTzgdo1RpwjYhwnVKxQXt8EPRq17WZFtWcq5umQdsDtTP";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinAddress() != "1M6dsMZUjFxjdwsyVk8nJytWcfr9tfUa9E") {
return false;
}
return true;
},
testBugWithLeadingZeroBytePrivateKey: function () {
var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da";
var btcKey = new Bitcoin.ECKey(key);
if (btcKey.getBitcoinAddress() != "1NAjZjF81YGfiJ3rTKc7jf1nmZ26KN7Gkn") {
return false;
}
return true;
}
},
asynchronousTests: {
//https://en.bitcoin.it/wiki/BIP_0038
testBip38: function (done) {
var tests = [
//No compression, no EC multiply
["6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg", "TestingOneTwoThree", "5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR"],
["6PRNFFkZc2NZ6dJqFfhRoFNMR9Lnyj7dYGrzdgXXVMXcxoKTePPX1dWByq", "Satoshi", "5HtasZ6ofTHP6HCwTqTkLDuLQisYPah7aUnSKfC7h4hMUVw2gi5"],
//Compression, no EC multiply
["6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo", "TestingOneTwoThree", "L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP"],
["6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7", "Satoshi", "KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7"],
//EC multiply, no compression, no lot/sequence numbers
["6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX", "TestingOneTwoThree", "5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2"],
["6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd", "Satoshi", "5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH"],
//EC multiply, no compression, lot/sequence numbers
["6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j", "MOLON LABE", "5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8"],
["6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH", Crypto.charenc.UTF8.bytesToString([206, 156, 206, 159, 206, 155, 206, 169, 206, 157, 32, 206, 155, 206, 145, 206, 146, 206, 149])/*UTF-8 characters, encoded in source so they don't get corrupted*/, "5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D"]];
// running each test uses a lot of memory, which isn't freed
// immediately, so give the VM a little time to reclaim memory
function waitThenCall(callback) {
return function () { setTimeout(callback, 10000); }
}
var decryptTest = function (test, i, onComplete) {
ninja.privateKey.BIP38EncryptedKeyToByteArrayAsync(test[0], test[1], function (privBytes) {
if (privBytes.constructor == Error) {
document.getElementById("asyncunittestresults").innerHTML += "fail testDecryptBip38 #" + i + ", error: " + privBytes.message + "<br/>";
} else {
var btcKey = new Bitcoin.ECKey(privBytes);
var wif = !test[2].substr(0, 1).match(/[LK]/) ? btcKey.setCompressed(false).getBitcoinWalletImportFormat() : btcKey.setCompressed(true).getBitcoinWalletImportFormat();
if (wif != test[2]) {
document.getElementById("asyncunittestresults").innerHTML += "fail testDecryptBip38 #" + i + "<br/>";
} else {
document.getElementById("asyncunittestresults").innerHTML += "pass testDecryptBip38 #" + i + "<br/>";
}
}
onComplete();
});
};
var encryptTest = function (test, compressed, i, onComplete) {
ninja.privateKey.BIP38PrivateKeyToEncryptedKeyAsync(test[2], test[1], compressed, function (encryptedKey) {
if (encryptedKey === test[0]) {
document.getElementById("asyncunittestresults").innerHTML += "pass testBip38Encrypt #" + i + "<br/>";
} else {
document.getElementById("asyncunittestresults").innerHTML += "fail testBip38Encrypt #" + i + "<br/>";
document.getElementById("asyncunittestresults").innerHTML += "expected " + test[0] + "<br/>received " + encryptedKey + "<br/>";
}
onComplete();
});
};
// test randomly generated encryption-decryption cycle
var cycleTest = function (i, compress, onComplete) {
// create new private key
var privKey = (new Bitcoin.ECKey(false)).getBitcoinWalletImportFormat();
// encrypt private key
ninja.privateKey.BIP38PrivateKeyToEncryptedKeyAsync(privKey, 'testing', compress, function (encryptedKey) {
// decrypt encryptedKey
ninja.privateKey.BIP38EncryptedKeyToByteArrayAsync(encryptedKey, 'testing', function (decryptedBytes) {
var decryptedKey = (new Bitcoin.ECKey(decryptedBytes)).getBitcoinWalletImportFormat();
if (decryptedKey === privKey) {
document.getElementById("asyncunittestresults").innerHTML += "pass cycleBip38 test #" + i + "<br/>";
}
else {
document.getElementById("asyncunittestresults").innerHTML += "fail cycleBip38 test #" + i + " " + privKey + "<br/>";
document.getElementById("asyncunittestresults").innerHTML += "encrypted key: " + encryptedKey + "<br/>decrypted key: " + decryptedKey;
}
onComplete();
});
});
};
// intermediate test - create some encrypted keys from an intermediate
// then decrypt them to check that the private keys are recoverable
var intermediateTest = function (i, onComplete) {
var pass = Math.random().toString(36).substr(2);
ninja.privateKey.BIP38GenerateIntermediatePointAsync(pass, null, null, function (intermediatePoint) {
ninja.privateKey.BIP38GenerateECAddressAsync(intermediatePoint, false, function (address, encryptedKey) {
ninja.privateKey.BIP38EncryptedKeyToByteArrayAsync(encryptedKey, pass, function (privBytes) {
if (privBytes.constructor == Error) {
document.getElementById("asyncunittestresults").innerHTML += "fail testBip38Intermediate #" + i + ", error: " + privBytes.message + "<br/>";
} else {
var btcKey = new Bitcoin.ECKey(privBytes);
var btcAddress = btcKey.getBitcoinAddress();
if (address !== btcKey.getBitcoinAddress()) {
document.getElementById("asyncunittestresults").innerHTML += "fail testBip38Intermediate #" + i + "<br/>";
} else {
document.getElementById("asyncunittestresults").innerHTML += "pass testBip38Intermediate #" + i + "<br/>";
}
}
onComplete();
});
});
});
}
document.getElementById("asyncunittestresults").innerHTML += "running " + tests.length + " tests named testDecryptBip38<br/>";
document.getElementById("asyncunittestresults").innerHTML += "running 4 tests named testBip38Encrypt<br/>";
document.getElementById("asyncunittestresults").innerHTML += "running 2 tests named cycleBip38<br/>";
document.getElementById("asyncunittestresults").innerHTML += "running 5 tests named testBip38Intermediate<br/>";
ninja.runSerialized([
function (cb) {
ninja.forSerialized(0, tests.length, function (i, callback) {
decryptTest(tests[i], i, waitThenCall(callback));
}, waitThenCall(cb));
},
function (cb) {
ninja.forSerialized(0, 4, function (i, callback) {
// only first 4 test vectors are not EC-multiply,
// compression param false for i = 1,2 and true for i = 3,4
encryptTest(tests[i], i >= 2, i, waitThenCall(callback));
}, waitThenCall(cb));
},
function (cb) {
ninja.forSerialized(0, 2, function (i, callback) {
cycleTest(i, i % 2 ? true : false, waitThenCall(callback));
}, waitThenCall(cb));
},
function (cb) {
ninja.forSerialized(0, 5, function (i, callback) {
intermediateTest(i, waitThenCall(callback));
}, cb);
}
], done);
}
}
};
})(ninja);
</script>
<script type="text/javascript">
// run unit tests
if (ninja.getQueryString()["unittests"] == "true" || ninja.getQueryString()["unittests"] == "1") {
ninja.unitTests.runSynchronousTests();
ninja.translator.showEnglishJson();
}
// run async unit tests
if (ninja.getQueryString()["asyncunittests"] == "true" || ninja.getQueryString()["asyncunittests"] == "1") {
ninja.unitTests.runAsynchronousTests();
}
// change language
if (ninja.getQueryString()["culture"] != undefined) {
ninja.translator.translate(ninja.getQueryString()["culture"]);
}
// testnet, check if testnet edition should be activated
if (ninja.getQueryString()["testnet"] == "true" || ninja.getQueryString()["testnet"] == "1") {
document.getElementById("testnet").innerHTML = ninja.translator.get("testneteditionactivated");
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.seeder.forceGenerate, ninja.seeder.seedLimit * 20);
</script>
<div class="extLives"></div></body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment