10235 lines
808 KiB
HTML
10235 lines
808 KiB
HTML
<!doctype html>
|
||
<html>
|
||
<head>
|
||
<!--
|
||
Donation Address: 1NiNja1bUmhSoTXozBRBEtR8LeF9TGbZBN
|
||
|
||
Notice of Copyrights and Licenses:
|
||
***********************************
|
||
The bitaddress.org project, software and embedded resources are copyright bitaddress.org (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>bitaddress.org</title>
|
||
<meta charset="utf-8">
|
||
|
||
<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;
|
||
sr.poolCopyOnInit;
|
||
|
||
// 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;
|
||
if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
|
||
try {
|
||
var rvBytes = new Uint8Array(ba.length);
|
||
window.crypto.getRandomValues(rvBytes);
|
||
for (i = 0; i < ba.length; ++i)
|
||
ba[i] = sr.getByte() ^ rvBytes[i];
|
||
return;
|
||
} catch (e) {
|
||
alert(e);
|
||
}
|
||
}
|
||
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);
|
||
sr.poolCopyOnInit = [];
|
||
for (sr.pptr = 0; sr.pptr < sr.pool.length; ++sr.pptr)
|
||
sr.poolCopyOnInit[sr.pptr] = sr.pool[sr.pptr];
|
||
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.seedInt8(x);
|
||
sr.seedInt8((x >> 8));
|
||
sr.seedInt8((x >> 16));
|
||
sr.seedInt8((x >> 24));
|
||
}
|
||
|
||
// Mix in a 16-bit integer into the pool
|
||
sr.seedInt16 = function (x) {
|
||
sr.seedInt8(x);
|
||
sr.seedInt8((x >> 8));
|
||
}
|
||
|
||
// Mix in a 8-bit integer into the pool
|
||
sr.seedInt8 = function (x) {
|
||
sr.pool[sr.pptr++] ^= x & 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 (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
|
||
try {
|
||
// Use webcrypto if available
|
||
var ua = new Uint8Array(sr.poolSize);
|
||
window.crypto.getRandomValues(ua);
|
||
for (t = 0; t < sr.poolSize; ++t)
|
||
sr.pool[sr.pptr++] = ua[t];
|
||
} catch (e) { alert(e); }
|
||
}
|
||
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 = Math.floor(sr.poolSize * Math.random());
|
||
sr.seedTime();
|
||
// entropy
|
||
var entropyStr = "";
|
||
// screen size and color depth: ~4.8 to ~5.4 bits
|
||
entropyStr += (window.screen.height * window.screen.width * window.screen.colorDepth);
|
||
entropyStr += (window.screen.availHeight * window.screen.availWidth * window.screen.pixelDepth);
|
||
// time zone offset: ~4 bits
|
||
var dateObj = new Date();
|
||
var timeZoneOffset = dateObj.getTimezoneOffset();
|
||
entropyStr += timeZoneOffset;
|
||
// user agent: ~8.3 to ~11.6 bits
|
||
entropyStr += navigator.userAgent;
|
||
// browser plugin details: ~16.2 to ~21.8 bits
|
||
var pluginsStr = "";
|
||
for (var i = 0; i < navigator.plugins.length; i++) {
|
||
pluginsStr += navigator.plugins[i].name + " " + navigator.plugins[i].filename + " " + navigator.plugins[i].description + " " + navigator.plugins[i].version + ", ";
|
||
}
|
||
var mimeTypesStr = "";
|
||
for (var i = 0; i < navigator.mimeTypes.length; i++) {
|
||
mimeTypesStr += navigator.mimeTypes[i].description + " " + navigator.mimeTypes[i].type + " " + navigator.mimeTypes[i].suffixes + ", ";
|
||
}
|
||
entropyStr += pluginsStr + mimeTypesStr;
|
||
// cookies and storage: 1 bit
|
||
entropyStr += navigator.cookieEnabled + typeof (sessionStorage) + typeof (localStorage);
|
||
// language: ~7 bit
|
||
entropyStr += navigator.language;
|
||
// history: ~2 bit
|
||
entropyStr += window.history.length;
|
||
// location
|
||
entropyStr += window.location;
|
||
|
||
var entropyBytes = Crypto.SHA256(entropyStr, { asBytes: true });
|
||
for (var i = 0 ; i < entropyBytes.length ; i++) {
|
||
sr.seedInt8(entropyBytes[i]);
|
||
}
|
||
}
|
||
})();
|
||
</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);
|
||
}
|
||
var r = this.x.toBigInteger().multiply(this.zinv);
|
||
this.curve.reduce(r);
|
||
return this.curve.fromBigInteger(r);
|
||
};
|
||
|
||
ec.PointFp.prototype.getY = function () {
|
||
if (this.zinv == null) {
|
||
this.zinv = this.z.modInverse(this.curve.q);
|
||
}
|
||
var r = this.y.toBigInteger().multiply(this.zinv);
|
||
this.curve.reduce(r);
|
||
return this.curve.fromBigInteger(r);
|
||
};
|
||
|
||
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);
|
||
//this.curve.reduce(w);
|
||
// 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);
|
||
this.reducer = new Barrett(this.q);
|
||
}
|
||
|
||
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);
|
||
};
|
||
|
||
ec.CurveFp.prototype.reduce = function (x) {
|
||
this.reducer.reduce(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;
|
||
}
|
||
};
|
||
|
||
ec.CurveFp.prototype.encodePointHex = function (p) {
|
||
if (p.isInfinity()) return "00";
|
||
var xHex = p.getX().toBigInteger().toString(16);
|
||
var yHex = p.getY().toBigInteger().toString(16);
|
||
var oLen = this.getQ().toString(16).length;
|
||
if ((oLen % 2) != 0) oLen++;
|
||
while (xHex.length < oLen) {
|
||
xHex = "0" + xHex;
|
||
}
|
||
while (yHex.length < oLen) {
|
||
yHex = "0" + yHex;
|
||
}
|
||
return "04" + xHex + yHex;
|
||
};
|
||
|
||
/*
|
||
* 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">
|
||
// secrets.js - by Alexander Stetsyuk - released under MIT License
|
||
(function(exports, global){
|
||
var defaults = {
|
||
bits: 8, // default number of bits
|
||
radix: 16, // work with HEX by default
|
||
minBits: 3,
|
||
maxBits: 20, // this permits 1,048,575 shares, though going this high is NOT recommended in JS!
|
||
|
||
bytesPerChar: 2,
|
||
maxBytesPerChar: 6, // Math.pow(256,7) > Math.pow(2,53)
|
||
|
||
// Primitive polynomials (in decimal form) for Galois Fields GF(2^n), for 2 <= n <= 30
|
||
// The index of each term in the array corresponds to the n for that polynomial
|
||
// i.e. to get the polynomial for n=16, use primitivePolynomials[16]
|
||
primitivePolynomials: [null,null,1,3,3,5,3,3,29,17,9,5,83,27,43,3,45,9,39,39,9,5,3,33,27,9,71,39,9,5,83],
|
||
|
||
// warning for insecure PRNG
|
||
warning: 'WARNING:\nA secure random number generator was not found.\nUsing Math.random(), which is NOT cryptographically strong!'
|
||
};
|
||
|
||
// Protected settings object
|
||
var config = {};
|
||
|
||
/** @expose **/
|
||
exports.getConfig = function(){
|
||
return {
|
||
'bits': config.bits,
|
||
'unsafePRNG': config.unsafePRNG
|
||
};
|
||
};
|
||
|
||
function init(bits){
|
||
if(bits && (typeof bits !== 'number' || bits%1 !== 0 || bits<defaults.minBits || bits>defaults.maxBits)){
|
||
throw new Error('Number of bits must be an integer between ' + defaults.minBits + ' and ' + defaults.maxBits + ', inclusive.')
|
||
}
|
||
|
||
config.radix = defaults.radix;
|
||
config.bits = bits || defaults.bits;
|
||
config.size = Math.pow(2, config.bits);
|
||
config.max = config.size - 1;
|
||
|
||
// Construct the exp and log tables for multiplication.
|
||
var logs = [], exps = [], x = 1, primitive = defaults.primitivePolynomials[config.bits];
|
||
for(var i=0; i<config.size; i++){
|
||
exps[i] = x;
|
||
logs[x] = i;
|
||
x <<= 1;
|
||
if(x >= config.size){
|
||
x ^= primitive;
|
||
x &= config.max;
|
||
}
|
||
}
|
||
|
||
config.logs = logs;
|
||
config.exps = exps;
|
||
};
|
||
|
||
/** @expose **/
|
||
exports.init = init;
|
||
|
||
function isInited(){
|
||
if(!config.bits || !config.size || !config.max || !config.logs || !config.exps || config.logs.length !== config.size || config.exps.length !== config.size){
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
// Returns a pseudo-random number generator of the form function(bits){}
|
||
// which should output a random string of 1's and 0's of length `bits`
|
||
function getRNG(){
|
||
var randomBits, crypto;
|
||
|
||
function construct(bits, arr, radix, size){
|
||
var str = '',
|
||
i = 0,
|
||
len = arr.length-1;
|
||
while( i<len || (str.length < bits) ){
|
||
str += padLeft(parseInt(arr[i], radix).toString(2), size);
|
||
i++;
|
||
}
|
||
str = str.substr(-bits);
|
||
if( (str.match(/0/g)||[]).length === str.length){ // all zeros?
|
||
return null;
|
||
}else{
|
||
return str;
|
||
}
|
||
}
|
||
|
||
// node.js crypto.randomBytes()
|
||
if(typeof require === 'function' && (crypto=require('crypto')) && (randomBits=crypto['randomBytes'])){
|
||
return function(bits){
|
||
var bytes = Math.ceil(bits/8),
|
||
str = null;
|
||
|
||
while( str === null ){
|
||
str = construct(bits, randomBits(bytes).toString('hex'), 16, 4);
|
||
}
|
||
return str;
|
||
}
|
||
}
|
||
|
||
// browsers with window.crypto.getRandomValues()
|
||
if(global['crypto'] && typeof global['crypto']['getRandomValues'] === 'function' && typeof global['Uint32Array'] === 'function'){
|
||
crypto = global['crypto'];
|
||
return function(bits){
|
||
var elems = Math.ceil(bits/32),
|
||
str = null,
|
||
arr = new global['Uint32Array'](elems);
|
||
|
||
while( str === null ){
|
||
crypto['getRandomValues'](arr);
|
||
str = construct(bits, arr, 10, 32);
|
||
}
|
||
|
||
return str;
|
||
}
|
||
}
|
||
|
||
// A totally insecure RNG!!! (except in Safari)
|
||
// Will produce a warning every time it is called.
|
||
config.unsafePRNG = true;
|
||
warn();
|
||
|
||
var bitsPerNum = 32;
|
||
var max = Math.pow(2,bitsPerNum)-1;
|
||
return function(bits){
|
||
var elems = Math.ceil(bits/bitsPerNum);
|
||
var arr = [], str=null;
|
||
while(str===null){
|
||
for(var i=0; i<elems; i++){
|
||
arr[i] = Math.floor(Math.random() * max + 1);
|
||
}
|
||
str = construct(bits, arr, 10, bitsPerNum);
|
||
}
|
||
return str;
|
||
};
|
||
};
|
||
|
||
// Warn about using insecure rng.
|
||
// Called when Math.random() is being used.
|
||
function warn(){
|
||
global['console']['warn'](defaults.warning);
|
||
if(typeof global['alert'] === 'function' && config.alert){
|
||
global['alert'](defaults.warning);
|
||
}
|
||
}
|
||
|
||
// Set the PRNG to use. If no RNG function is supplied, pick a default using getRNG()
|
||
/** @expose **/
|
||
exports.setRNG = function(rng, alert){
|
||
if(!isInited()){
|
||
this.init();
|
||
}
|
||
config.unsafePRNG=false;
|
||
rng = rng || getRNG();
|
||
|
||
// test the RNG (5 times)
|
||
if(typeof rng !== 'function' || typeof rng(config.bits) !== 'string' || !parseInt(rng(config.bits),2) || rng(config.bits).length > config.bits || rng(config.bits).length < config.bits){
|
||
throw new Error("Random number generator is invalid. Supply an RNG of the form function(bits){} that returns a string containing 'bits' number of random 1's and 0's.")
|
||
}else{
|
||
config.rng = rng;
|
||
}
|
||
config.alert = !!alert;
|
||
|
||
return !!config.unsafePRNG;
|
||
};
|
||
|
||
function isSetRNG(){
|
||
return typeof config.rng === 'function';
|
||
};
|
||
|
||
// Generates a random bits-length number string using the PRNG
|
||
/** @expose **/
|
||
exports.random = function(bits){
|
||
if(!isSetRNG()){
|
||
this.setRNG();
|
||
}
|
||
|
||
if(typeof bits !== 'number' || bits%1 !== 0 || bits < 2){
|
||
throw new Error('Number of bits must be an integer greater than 1.')
|
||
}
|
||
|
||
if(config.unsafePRNG){
|
||
warn();
|
||
}
|
||
return bin2hex(config.rng(bits));
|
||
}
|
||
|
||
// Divides a `secret` number String str expressed in radix `inputRadix` (optional, default 16)
|
||
// into `numShares` shares, each expressed in radix `outputRadix` (optional, default to `inputRadix`),
|
||
// requiring `threshold` number of shares to reconstruct the secret.
|
||
// Optionally, zero-pads the secret to a length that is a multiple of padLength before sharing.
|
||
/** @expose **/
|
||
exports.share = function(secret, numShares, threshold, padLength, withoutPrefix){
|
||
if(!isInited()){
|
||
this.init();
|
||
}
|
||
if(!isSetRNG()){
|
||
this.setRNG();
|
||
}
|
||
|
||
padLength = padLength || 0;
|
||
|
||
if(typeof secret !== 'string'){
|
||
throw new Error('Secret must be a string.');
|
||
}
|
||
if(typeof numShares !== 'number' || numShares%1 !== 0 || numShares < 2){
|
||
throw new Error('Number of shares must be an integer between 2 and 2^bits-1 (' + config.max + '), inclusive.')
|
||
}
|
||
if(numShares > config.max){
|
||
var neededBits = Math.ceil(Math.log(numShares +1)/Math.LN2);
|
||
throw new Error('Number of shares must be an integer between 2 and 2^bits-1 (' + config.max + '), inclusive. To create ' + numShares + ' shares, use at least ' + neededBits + ' bits.')
|
||
}
|
||
if(typeof threshold !== 'number' || threshold%1 !== 0 || threshold < 2){
|
||
throw new Error('Threshold number of shares must be an integer between 2 and 2^bits-1 (' + config.max + '), inclusive.');
|
||
}
|
||
if(threshold > config.max){
|
||
var neededBits = Math.ceil(Math.log(threshold +1)/Math.LN2);
|
||
throw new Error('Threshold number of shares must be an integer between 2 and 2^bits-1 (' + config.max + '), inclusive. To use a threshold of ' + threshold + ', use at least ' + neededBits + ' bits.');
|
||
}
|
||
if(typeof padLength !== 'number' || padLength%1 !== 0 ){
|
||
throw new Error('Zero-pad length must be an integer greater than 1.');
|
||
}
|
||
|
||
if(config.unsafePRNG){
|
||
warn();
|
||
}
|
||
|
||
secret = '1' + hex2bin(secret); // append a 1 so that we can preserve the correct number of leading zeros in our secret
|
||
secret = split(secret, padLength);
|
||
var x = new Array(numShares), y = new Array(numShares);
|
||
for(var i=0, len = secret.length; i<len; i++){
|
||
var subShares = this._getShares(secret[i], numShares, threshold);
|
||
for(var j=0; j<numShares; j++){
|
||
x[j] = x[j] || subShares[j].x.toString(config.radix);
|
||
y[j] = padLeft(subShares[j].y.toString(2)) + (y[j] ? y[j] : '');
|
||
}
|
||
}
|
||
var padding = config.max.toString(config.radix).length;
|
||
if(withoutPrefix){
|
||
for(var i=0; i<numShares; i++){
|
||
x[i] = bin2hex(y[i]);
|
||
}
|
||
}else{
|
||
for(var i=0; i<numShares; i++){
|
||
x[i] = config.bits.toString(36).toUpperCase() + padLeft(x[i],padding) + bin2hex(y[i]);
|
||
}
|
||
}
|
||
|
||
return x;
|
||
};
|
||
|
||
// This is the basic polynomial generation and evaluation function
|
||
// for a `config.bits`-length secret (NOT an arbitrary length)
|
||
// Note: no error-checking at this stage! If `secrets` is NOT
|
||
// a NUMBER less than 2^bits-1, the output will be incorrect!
|
||
/** @expose **/
|
||
exports._getShares = function(secret, numShares, threshold){
|
||
var shares = [];
|
||
var coeffs = [secret];
|
||
|
||
for(var i=1; i<threshold; i++){
|
||
coeffs[i] = parseInt(config.rng(config.bits),2);
|
||
}
|
||
for(var i=1, len = numShares+1; i<len; i++){
|
||
shares[i-1] = {
|
||
x: i,
|
||
y: horner(i, coeffs)
|
||
}
|
||
}
|
||
return shares;
|
||
};
|
||
|
||
// Polynomial evaluation at `x` using Horner's Method
|
||
// TODO: this can possibly be sped up using other methods
|
||
// NOTE: fx=fx * x + coeff[i] -> exp(log(fx) + log(x)) + coeff[i],
|
||
// so if fx===0, just set fx to coeff[i] because
|
||
// using the exp/log form will result in incorrect value
|
||
function horner(x, coeffs){
|
||
var logx = config.logs[x];
|
||
var fx = 0;
|
||
for(var i=coeffs.length-1; i>=0; i--){
|
||
if(fx === 0){
|
||
fx = coeffs[i];
|
||
continue;
|
||
}
|
||
fx = config.exps[ (logx + config.logs[fx]) % config.max ] ^ coeffs[i];
|
||
}
|
||
return fx;
|
||
};
|
||
|
||
function inArray(arr,val){
|
||
for(var i = 0,len=arr.length; i < len; i++) {
|
||
if(arr[i] === val){
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
function processShare(share){
|
||
|
||
var bits = parseInt(share[0], 36);
|
||
if(bits && (typeof bits !== 'number' || bits%1 !== 0 || bits<defaults.minBits || bits>defaults.maxBits)){
|
||
throw new Error('Number of bits must be an integer between ' + defaults.minBits + ' and ' + defaults.maxBits + ', inclusive.')
|
||
}
|
||
|
||
var max = Math.pow(2, bits) - 1;
|
||
var idLength = max.toString(config.radix).length;
|
||
|
||
var id = parseInt(share.substr(1, idLength), config.radix);
|
||
if(typeof id !== 'number' || id%1 !== 0 || id<1 || id>max){
|
||
throw new Error('Share id must be an integer between 1 and ' + config.max + ', inclusive.');
|
||
}
|
||
share = share.substr(idLength + 1);
|
||
if(!share.length){
|
||
throw new Error('Invalid share: zero-length share.')
|
||
}
|
||
return {
|
||
'bits': bits,
|
||
'id': id,
|
||
'value': share
|
||
};
|
||
};
|
||
|
||
/** @expose **/
|
||
exports._processShare = processShare;
|
||
|
||
// Protected method that evaluates the Lagrange interpolation
|
||
// polynomial at x=`at` for individual config.bits-length
|
||
// segments of each share in the `shares` Array.
|
||
// Each share is expressed in base `inputRadix`. The output
|
||
// is expressed in base `outputRadix'
|
||
function combine(at, shares){
|
||
var setBits, share, x = [], y = [], result = '', idx;
|
||
|
||
for(var i=0, len = shares.length; i<len; i++){
|
||
share = processShare(shares[i]);
|
||
if(typeof setBits === 'undefined'){
|
||
setBits = share['bits'];
|
||
}else if(share['bits'] !== setBits){
|
||
throw new Error('Mismatched shares: Different bit settings.')
|
||
}
|
||
|
||
if(config.bits !== setBits){
|
||
init(setBits);
|
||
}
|
||
|
||
if(inArray(x, share['id'])){ // repeated x value?
|
||
continue;
|
||
}
|
||
|
||
idx = x.push(share['id']) - 1;
|
||
share = split(hex2bin(share['value']));
|
||
for(var j=0, len2 = share.length; j<len2; j++){
|
||
y[j] = y[j] || [];
|
||
y[j][idx] = share[j];
|
||
}
|
||
}
|
||
|
||
for(var i=0, len=y.length; i<len; i++){
|
||
result = padLeft(lagrange(at, x, y[i]).toString(2)) + result;
|
||
}
|
||
|
||
if(at===0){// reconstructing the secret
|
||
var idx = result.indexOf('1'); //find the first 1
|
||
return bin2hex(result.slice(idx+1));
|
||
}else{// generating a new share
|
||
return bin2hex(result);
|
||
}
|
||
};
|
||
|
||
// Combine `shares` Array into the original secret
|
||
/** @expose **/
|
||
exports.combine = function(shares){
|
||
return combine(0, shares);
|
||
};
|
||
|
||
// Generate a new share with id `id` (a number between 1 and 2^bits-1)
|
||
// `id` can be a Number or a String in the default radix (16)
|
||
/** @expose **/
|
||
exports.newShare = function(id, shares){
|
||
if(typeof id === 'string'){
|
||
id = parseInt(id, config.radix);
|
||
}
|
||
|
||
var share = processShare(shares[0]);
|
||
var max = Math.pow(2, share['bits']) - 1;
|
||
|
||
if(typeof id !== 'number' || id%1 !== 0 || id<1 || id>max){
|
||
throw new Error('Share id must be an integer between 1 and ' + config.max + ', inclusive.');
|
||
}
|
||
|
||
var padding = max.toString(config.radix).length;
|
||
return config.bits.toString(36).toUpperCase() + padLeft(id.toString(config.radix), padding) + combine(id, shares);
|
||
};
|
||
|
||
// Evaluate the Lagrange interpolation polynomial at x = `at`
|
||
// using x and y Arrays that are of the same length, with
|
||
// corresponding elements constituting points on the polynomial.
|
||
function lagrange(at, x, y){
|
||
var sum = 0,
|
||
product,
|
||
i, j;
|
||
|
||
for(var i=0, len = x.length; i<len; i++){
|
||
if(!y[i]){
|
||
continue;
|
||
}
|
||
|
||
product = config.logs[y[i]];
|
||
for(var j=0; j<len; j++){
|
||
if(i === j){ continue; }
|
||
if(at === x[j]){ // happens when computing a share that is in the list of shares used to compute it
|
||
product = -1; // fix for a zero product term, after which the sum should be sum^0 = sum, not sum^1
|
||
break;
|
||
}
|
||
product = ( product + config.logs[at ^ x[j]] - config.logs[x[i] ^ x[j]] + config.max/* to make sure it's not negative */ ) % config.max;
|
||
}
|
||
|
||
sum = product === -1 ? sum : sum ^ config.exps[product]; // though exps[-1]= undefined and undefined ^ anything = anything in chrome, this behavior may not hold everywhere, so do the check
|
||
}
|
||
return sum;
|
||
};
|
||
|
||
/** @expose **/
|
||
exports._lagrange = lagrange;
|
||
|
||
// Splits a number string `bits`-length segments, after first
|
||
// optionally zero-padding it to a length that is a multiple of `padLength.
|
||
// Returns array of integers (each less than 2^bits-1), with each element
|
||
// representing a `bits`-length segment of the input string from right to left,
|
||
// i.e. parts[0] represents the right-most `bits`-length segment of the input string.
|
||
function split(str, padLength){
|
||
if(padLength){
|
||
str = padLeft(str, padLength)
|
||
}
|
||
var parts = [];
|
||
for(var i=str.length; i>config.bits; i-=config.bits){
|
||
parts.push(parseInt(str.slice(i-config.bits, i), 2));
|
||
}
|
||
parts.push(parseInt(str.slice(0, i), 2));
|
||
return parts;
|
||
};
|
||
|
||
// Pads a string `str` with zeros on the left so that its length is a multiple of `bits`
|
||
function padLeft(str, bits){
|
||
bits = bits || config.bits
|
||
var missing = str.length % bits;
|
||
return (missing ? new Array(bits - missing + 1).join('0') : '') + str;
|
||
};
|
||
|
||
function hex2bin(str){
|
||
var bin = '', num;
|
||
for(var i=str.length - 1; i>=0; i--){
|
||
num = parseInt(str[i], 16)
|
||
if(isNaN(num)){
|
||
throw new Error('Invalid hex character.')
|
||
}
|
||
bin = padLeft(num.toString(2), 4) + bin;
|
||
}
|
||
return bin;
|
||
}
|
||
|
||
function bin2hex(str){
|
||
var hex = '', num;
|
||
str = padLeft(str, 4);
|
||
for(var i=str.length; i>=4; i-=4){
|
||
num = parseInt(str.slice(i-4, i), 2);
|
||
if(isNaN(num)){
|
||
throw new Error('Invalid binary character.')
|
||
}
|
||
hex = num.toString(16) + hex;
|
||
}
|
||
return hex;
|
||
}
|
||
|
||
// Converts a given UTF16 character string to the HEX representation.
|
||
// Each character of the input string is represented by
|
||
// `bytesPerChar` bytes in the output string.
|
||
/** @expose **/
|
||
exports.str2hex = function(str, bytesPerChar){
|
||
if(typeof str !== 'string'){
|
||
throw new Error('Input must be a character string.');
|
||
}
|
||
bytesPerChar = bytesPerChar || defaults.bytesPerChar;
|
||
|
||
if(typeof bytesPerChar !== 'number' || bytesPerChar%1 !== 0 || bytesPerChar<1 || bytesPerChar > defaults.maxBytesPerChar){
|
||
throw new Error('Bytes per character must be an integer between 1 and ' + defaults.maxBytesPerChar + ', inclusive.')
|
||
}
|
||
|
||
var hexChars = 2*bytesPerChar;
|
||
var max = Math.pow(16, hexChars) - 1;
|
||
var out = '', num;
|
||
for(var i=0, len=str.length; i<len; i++){
|
||
num = str[i].charCodeAt();
|
||
if(isNaN(num)){
|
||
throw new Error('Invalid character: ' + str[i]);
|
||
}else if(num > max){
|
||
var neededBytes = Math.ceil(Math.log(num+1)/Math.log(256));
|
||
throw new Error('Invalid character code (' + num +'). Maximum allowable is 256^bytes-1 (' + max + '). To convert this character, use at least ' + neededBytes + ' bytes.')
|
||
}else{
|
||
out = padLeft(num.toString(16), hexChars) + out;
|
||
}
|
||
}
|
||
return out;
|
||
};
|
||
|
||
// Converts a given HEX number string to a UTF16 character string.
|
||
/** @expose **/
|
||
exports.hex2str = function(str, bytesPerChar){
|
||
if(typeof str !== 'string'){
|
||
throw new Error('Input must be a hexadecimal string.');
|
||
}
|
||
bytesPerChar = bytesPerChar || defaults.bytesPerChar;
|
||
|
||
if(typeof bytesPerChar !== 'number' || bytesPerChar%1 !== 0 || bytesPerChar<1 || bytesPerChar > defaults.maxBytesPerChar){
|
||
throw new Error('Bytes per character must be an integer between 1 and ' + defaults.maxBytesPerChar + ', inclusive.')
|
||
}
|
||
|
||
var hexChars = 2*bytesPerChar;
|
||
var out = '';
|
||
str = padLeft(str, hexChars);
|
||
for(var i=0, len = str.length; i<len; i+=hexChars){
|
||
out = String.fromCharCode(parseInt(str.slice(i, i+hexChars),16)) + out;
|
||
}
|
||
return out;
|
||
};
|
||
|
||
// by default, initialize without an RNG
|
||
exports.init();
|
||
})(typeof module !== 'undefined' && module['exports'] ? module['exports'] : (window['secrets'] = {}), typeof GLOBAL !== 'undefined' ? GLOBAL : window );
|
||
</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 + this.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
|
||
var Classic = window.Classic = 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
|
||
var Montgomery = window.Montgomery = 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
|
||
var NullExp = window.NullExp = 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
|
||
var Barrett = window.Barrett = 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 = 0x00; // 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 (ECKey.isBase6Format(input)) {
|
||
this.priv = new BigInteger(input, 6);
|
||
} else 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 = 0x80; // mainnet 0x80 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 '5'
|
||
ECKey.isWalletImportFormat = function (key) {
|
||
key = key.toString();
|
||
return (ECKey.privateKeyPrefix == 0x80) ?
|
||
(/^5[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key)) :
|
||
(/^9[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{50}$/.test(key));
|
||
};
|
||
|
||
// 52 characters base58
|
||
ECKey.isCompressedWalletImportFormat = function (key) {
|
||
key = key.toString();
|
||
return (ECKey.privateKeyPrefix == 0x80) ?
|
||
(/^[LK][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key)) :
|
||
(/^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(key));
|
||
};
|
||
|
||
// 44 characters
|
||
ECKey.isBase64Format = function (key) {
|
||
key = key.toString();
|
||
return (/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test(key));
|
||
};
|
||
|
||
// 99 characters, 1=1, if using dice convert 6 to 0
|
||
ECKey.isBase6Format = function (key) {
|
||
key = key.toString();
|
||
return (/^[012345]{99}$/.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; cursor: pointer; }
|
||
.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; }
|
||
a { position: relative; z-index: 20; }
|
||
.right { text-align: right; }
|
||
.walletarea { display: none; border: 2px solid #009900; }
|
||
hr { margin: 20px 0; border-top: 2px dashed #008000; }
|
||
.keyarea { 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 { font-weight: bold; }
|
||
.keyarea .output { display: block; font-family: monospace; font-size: 1.25em; }
|
||
.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; }
|
||
body { font-family: Arial; }
|
||
body, html { height: 99%; }
|
||
.faqs ol { padding: 0 0 0 25px; }
|
||
.faqs li { padding: 3px 0; }
|
||
.question { padding: 10px 15px; text-align: left; cursor: pointer; }
|
||
.question:hover, .expandable:hover { color: #77777A; }
|
||
.answer { padding: 0 15px 10px 25px; text-align: left; display: none; font-size: 80%; }
|
||
.faq { border: 0; border-top: 2px solid #009900; }
|
||
|
||
#wallets { clear: both; }
|
||
#btcaddress, #btcprivwif, #detailaddress, #detailaddresscomp, #detailprivwif, #detailprivwifcomp { font-family: monospace; font-size: 1.25em; }
|
||
#seedpoolarea { display: none; }
|
||
#seedpooldisplay { font-family: monospace; font-size: 1em; width: 640px; padding: 15px 5px; word-wrap: break-word; }
|
||
.seedpoint { width: 6px; height: 6px; display: block; border-radius: 3px; background-color: #009900; position: absolute; z-index: 10; }
|
||
#generate { font-family: monospace; font-size: 1.25em; height: 305px; text-align: left; position: relative; padding: 5px; border: 2px solid #009900; clear: both; }
|
||
#generate span { padding: 5px 5px 0 5px; }
|
||
#generatekeyinput { position: relative; z-index: 20; }
|
||
#keyarea { height: 250px; }
|
||
#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; padding: 13px 11px 11px 11px; }
|
||
#keyarea .qrcode_private { float: none; display: block; top: 0; text-align: right; padding: 13px 11px 11px 11px; }
|
||
#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: #009900; font-weight: bolder; font-size: 200%; }
|
||
#singlesafety { text-align: left; padding: 5px; border-top: 2px solid #009900; top: -25px; position: relative; }
|
||
|
||
#main { position: relative; text-align: center; margin: 0px auto; width: 808px; }
|
||
#logo { width: 578px; height: 80px; }
|
||
|
||
#paperarea { min-height: 120px; display: none; }
|
||
#paperarea .keyarea { border: 2px solid #009900; 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: 174px; left: 332px; z-index: 100; font-size: 8px; 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);
|
||
}
|
||
#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; }
|
||
#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%; padding: 1px 0; }
|
||
#detailarea .item.clear { clear: both; padding-top: 10px; }
|
||
#detailarea .label { display: block; font-weight: bold; }
|
||
#detailarea .output { display: block; font-family: monospace; font-size: 1.25em; }
|
||
#detailarea #detailqrcodepublic { position: relative; float: left; margin: 0 10px 0 0; padding: 13px 11px 11px 11px; }
|
||
#detailarea #detailqrcodepubliccomp { position: relative; float: right; margin: 0 0 0 10px; padding: 13px 11px 11px 11px; }
|
||
#detailarea #detailqrcodeprivate { position: relative; float: left; margin: 0 10px 0 0; padding: 13px 11px 11px 11px; }
|
||
#detailarea #detailqrcodeprivatecomp { position: relative; float: right; margin: 0 0 0 10px; padding: 13px 11px 11px 11px; }
|
||
#detailpubkey { width: 590px; }
|
||
#detailbip38commands { display: none; padding-top: 5px; }
|
||
#vanityarea { text-align: left; }
|
||
#vanityarea .label { text-decoration: underline; }
|
||
#vanityarea .output { font-family: monospace; font-size: 1.25em; 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 #009900; }
|
||
#vanitystep1label { padding-left: 5px; }
|
||
#vanitystep2area { border-top: 2px solid #009900; display: block; padding: 15px; }
|
||
#vanitystep2inputs { padding: 0 15px 10px 15px; }
|
||
#vanitycalc { margin-top: 5px; }
|
||
|
||
#splitarea { text-align: left; }
|
||
#splitarea span { padding: 0; }
|
||
#splitcommands { padding: 10px 15px; text-align: left; }
|
||
#combinecommands { padding: 10px 15px; }
|
||
#splitstep1area { display: none; text-align: left; position: relative; padding: 0; border-bottom: 2px solid #009900; }
|
||
.splitsharerow { border-bottom: 2px solid #009900; padding: 15px; }
|
||
.splitsharerow:last-child { border-bottom: 0; }
|
||
#combinelabelprivatekey { text-decoration: underline; }
|
||
#splitarea .output { display: block; font-family: monospace; font-size: 1.25em; }
|
||
#splitarea span.output { display: inline; }
|
||
#splitstep2area { padding: 10px 15px; }
|
||
|
||
.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 { 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; font-style: italic; }
|
||
.menu
|
||
{
|
||
text-align: left; margin: 0; padding: 0; display: block;
|
||
background-color: #009900; /* # 009900 # 53c100 */
|
||
border-top-left-radius: 5px; border-top-right-radius: 5px;
|
||
}
|
||
.menu .tab
|
||
{
|
||
position: relative; display: inline-block; border: 0px solid red;
|
||
margin: 0; list-style: none; z-index: 110; cursor: pointer;
|
||
top: 1px; padding: 10px 20px; width: 162px; text-align: center;
|
||
}
|
||
.menu .tab.selected
|
||
{
|
||
cursor: default;
|
||
background-color: #FFF; margin: 6px 16px; padding: 4px; border-radius: 5px;
|
||
}
|
||
.menu .tab:hover
|
||
{
|
||
background-color: #FFF; margin: 6px 16px; padding: 4px; border-radius: 5px;
|
||
}
|
||
.menu .tab.selected:hover { color: #000; }
|
||
|
||
.pagebreak { height: 50px; }
|
||
.commands { border-bottom: 2px solid #009900; 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; margin-bottom: 3px; }
|
||
#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 #009900; }
|
||
#bulkstartindex, #paperlimit, #paperlimitperpage { width: 35px; }
|
||
#bulklimit { width: 45px; }
|
||
|
||
.footer { 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 #009900; }
|
||
#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: 310px; word-wrap: break-word; text-align: right; }
|
||
#detailarea .privqr .item.right { width: 310px; }
|
||
#detailarea .privqr .item { width: 285px; }
|
||
#detailarea .notes { display: none; }
|
||
#seedpoolarea { display: none; }
|
||
.faq { display: none; }
|
||
}
|
||
|
||
</style>
|
||
</head>
|
||
<body onclick="SecureRandom.seedTime();" onmousemove="ninja.seeder.seed(event);">
|
||
<div id="busyblock"></div>
|
||
<div id="main">
|
||
<div id="culturemenu">
|
||
<span><a href="?culture=en" id="cultureen" class="selected">English</a></span> |
|
||
<span><a href="?culture=es" id="culturees">Español</a></span> |
|
||
<span><a href="?culture=fr" id="culturefr">Français</a></span> |
|
||
<span><a href="?culture=el" id="cultureel">ελληνικά</a></span> |
|
||
<span><a href="?culture=it" id="cultureit">italiano</a></span> |
|
||
<span><a href="?culture=de" id="culturede">Deutsch</a></span> |
|
||
<span><a href="?culture=cs" id="culturecs">Česky</a></span> |
|
||
<span><a href="?culture=hu" id="culturehu">Magyar</a></span> |
|
||
<span><a href="?culture=jp" id="culturejp">日本語</a></span>
|
||
</div>
|
||
<img alt="bitaddress.org" title="bitaddress.org" id="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkIAAABQCAYAAAD1Jhq5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABZ0RVh0Q3JlYXRpb24gVGltZQAwOS8xMi8xMXIwQl8AAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzVxteM2AAAgAElEQVR4nO29eZAk13nY+XuZWVVdfXfPhZnBYBoERPACMTxEyJTIKVqLlWwqhGF4Q75Wg4aDirYcq8AwLEsrrSU2lg5atrTLwW7sWmVzjZ6RbUm76+UMZVKUYZPVIgkRdzdO4prpnhNz9d1dR2a+t3+8zK7qo7Iyq6q7q4D8RVRMT73Kl19l5Xv5ve99h1BKUQshRM3PxMTEtBFZjgD9wBwjTOy0ODVpN3ljYmLaBhFGEWqI1//3bvZ88iPA/cjCx5HO+1FqH8g+UBYIEIaNkZrF6LhKouc1Uv3Pk9zzLCReAkpbKV6s5MW858hyBniw4p1p4FjLKhjtJm9MTExbsTWK0PTjB0gMfBbp/HWc5U9QmruD0vwu7DmBvQhOHpQNSnpSGCCSYKUh0QupXS4du2+Svm2ajn1PkT7wXTpu/wFws9mixopQzHuKLCeBRzZpmWeE/u0WpybtJm9MTEzb0TxFSAg4//jPYVjDlOYfIH9tF8uXoHgd7CWQjv4MhlZ8EOgzK62MKKUVI+UCCkQCEt3QuR+674Leu67Sfde36Dp0msSe7zdH6K1XhGZOMwwMAVPAmcHjzG3pCWNigsgSNOA/xwi57RIlFO0mb0xMTNvRuCIkBLyd/bso8QjFa/ezeA6WL4GzAsIEI+EpPhuPy5dKSCnpTKXYVB1RLkgblANmF/S8Dwbug4EPPkHnHSfpvOvbjQm/tYrQzOkNq9l5IDN4PDbpx+wA2s/mhYBPtJZi0W7yxsTEtCVWQ0f/+F9+lrf+j6+wfOmzzL8G+av6fTMFVkfFB+XGY6VLR/d+rSjlLwMK1qtDQoCZBJK6j/mXYe4luH7oAfbc/wADH/sWXXd8mc67nmvoe2wBM6fpZ6NJvw84g7YQxcRsN5ka7a2moGdqtLeavDExMW1IfYrQ93+xj30PfAW3+GvMPAfLF7T1x0ziKkXJtkknLAiyagsQ9i39B26NEwqKto1lJjBNA1YuwdQU3Hr+8+zLPED/rT+g/xNfwTALdX2freFIlfcPz5wmM3g8XsnGbDuZgLZJRlpu2zYT0NaK8sbExLQh0RWhiS/dz56f+ToLr36E+ZdASm0BAlAuhpEk1XOb9g2SrucX5CEEGEL/KwBs/b5paJ1J+n5ClSdUIAysrv0Iex5kAcwEkIClt2D5fJI9P/PbFG9l6D78K/R86NW6rkTzqaYIgZ7gc9sjRkzMKpmAttw2yRCFTEBbbptkiImJeZcTTRF6+XeOk+jNcuuvOli5CGYaLIvVrS8BggKieEUrNIYAS4BhgFQUSy5LyzaFgkOpZONKhUBgWYJk0iLdkaAnncBMmbo/V4KrAAfTuQU4IJR+AVhJfZ5rfwEr5z/NwQd/iFN4iIGPf7NZF6gB4oiWmNZB+9v0BXwit02ShKPd5I2JiWlbwitCk7/1myj795h/FuxlzwdIsen2l+FCwkLZinduLHP5+jyzcwuU8kvgljCFg2UoDMqGIEcJXCwMs4OOrm727urlwL5+Bvs6tPWo5O16rXduFujosuW34Pz/1c+BB89QuPKr7P+FbF1XpHlkdvj8kZg5zRBwDJgbPM7YzkoTswUEWSih9RSLdpM3JiamTQmnCE38+qPI/O8y/7yO5DI95+X1CAFJi+VlmzfffIcrV66jSvMMdEhu74TuXkha5d2xSqRSSGlTKNks5Be5ceEq59+2SHUPcOehvdx1qB/DMqDkbC6jmQZnAS7+sWDPf/OHrLyT5q4vnox2OZrKUEBby/g2eArQGHC04r3M4HGGm9R/BiD2idpxMgFtrehvkwloa0V5Y2Ji2pTaitBzv/YbqNLvsvC8tr4YppfrZx1Jk0JR8dKLl7l66Sp9iRXuGYDeTq30SKV3ufzXGmNShVKUSsG+NBzYDa7rMLN4g3Ov3+CNt3v5ibsO8v7DA/pAZxNFzEzocPvrfw67Pvs1Xn9shXse+dfRL0tjeBFjhwM+0hLRLp6cE2zcgnho5jRHgOF6Q/29vnPAfd7/54ETsbVpx8gEtJ3ZLiEikAloa0V5Y2Ji2pRNEvxU8PSv/D1k4V+w+BwIhe1KllfySOWiLUISDAkpg3MX53li/BUK197mEwdXuPcQ9HRqfcV2tbsPSus8q68Kv2n//6D9r21HK0+7++An74QPDC5w/vXX+M8/eJ2Z+QKkRFkGJBLJcn4F2/V8iGZ/APnpLK/9wee36uIFEGjWbyHryEmq+2HcB4w20PcJrw+fPuBxzwIVs51kGSJYMc9tjyAhaTd5Y2Ji2prqitAPj30CIb/O8kur2Z5FoptEz+0gLMAFCxwETz57kddffo179y3w4cMGVkJQcgVSVQSIqbWv1a0x/z1ZUXHD04yE0ApU0YXeNHzqTjiYusUPnnqN196ehaQBQmpZMEh2H8RI9encRIaApQmwb/4Rr3z1g1tz+aqSCWib3C4hgvAsNsdqfKwRh+/hKu+PNtBnTH1kAltbLylhJrC19eSNiYlpYzZXhHJ/rROz79+RfyuNXNIaiXKxDEnSkhiGA5ZiueDw3R++hchf5/570nR3pii5Bgix1gfItDA7BjA7+jE6+jHTAyAMDDOBkR7ESPnv9yMMfWDl4QK9nVZ0Yf8AfOqOApfePsfTL95AmQIMhSEUiYSJaVl6i8zq1cpQcXoAWTzFs7+T3LKruJFMQFtum2SoRYbgqBzQZUHqpdqKPtNAnzH1kQloG98uISKQCWhrRXljYmLamM19hBKHfg/n+gdwbuhiqEitDNnzUJqFZILFZal+8MwF7hg0xaF9+ygsL6GEgWGU0FU7pNafpMIQJgMf+SXMrr2Awlm+wewL/wZhphi87zhGsguEiT03xdxLf7QhwXQlJVenHfrEYZvX3pnmryZs7v/4IUyloHQLjBRYPWAk9UsoUIs/SWrgy8D/1PxLuClHA9py2yRDLWpF5cDWyBq05RGzNQRZ/nLbJUQE2k3emJiYNmajRSj3cz+FKv4aziUwrHLeHuHlBUpaaqUo1ZPPXVR3H9zL4aG7KDoWRrITw0ggzATCsBDCQAiBMEC5RXjnBYxrL2Bcex6uvYRSEuXk4Z1nMa5PYFx7HnXjVRSq7Du07oWXj1GhfY8+tN/FXL7IMxOXUaleSPVBsleH0yd6IdEPqd1aczLFP+HFR8M8/BvCj5IKILfVMoSkVtTNZOzY/C6g3fLxtJu8MTExbc9aRejfCwMj8Qe47wAO2hHZLb8MiaMUTz93kTt2pcX+/XtE0U1gpPrBSiMSaYSR8F4WQpieMiRQKF2BXnrV5fEKnipXF1WVDnhKkG6skMv3GVonvO3CPbeBmpvmpVevQNdeSPRBsh+SA5AahOQu6NgNHT0Jkl3/sulXcCOZgLbxFqo+P0Z1f6WzbN0WVkv4SL2HyAS2tp6/TSawtfXkjYmJaXPWKkL7PvMgaumnUXNotUOufVlCTb58g96kK27f3ysKyzMIVUJYXQirG2F2IKw0wkxqPx3DRBiGV33eBeGAcFFIT7nxvKRxy+9TEUlWkW9I4HXjh5h5bzoKPnAQZqdf5sKlOeg5AAlPAUruho69kNwHnbdDx64HePmf/fzWXtK28A/CU8gylH0u5oFTwOcGj3OsEYXNc8SuRq7efmPqIhPQ1or+NpmAtlaUNyYmps0p+wiNCYNDR38TNctqGFclSYNLl1dYmZ3ho3f3UcwvYVhpXfsLMBI9SCTKLWnrj3JQ0ka4ri4fpmwQXv4hZaNsUIaLUlo50smGvPdNwCgrPr7usyaHtack+UFn9+xXvD75l+w+9HE6u/uBJJhdYHWB0QXJPkgdBNf5HxHiO54j01YQ5B/UUvlPKpShZhPUZ0tdg/cADwa05bZLiAi0m7wxMTFtTlkR2nffUUT+fsgDeitrdStKCEpF1Llz1/mJ/Qjp2jq6S3oqipIo5dKx76OY6QGELCHdEkJJUC7SKWLkL2mlSYDR0UXvh/87kCWEfQ1UEZTE7NpD94f+Fqp4HWfhMu7CeaStMCxWNaGyTN7fXrLGdAfclpjj9ckf8bGf+0d638zq1q/koKcM7QKndJSXv/Jp4MlmX8yZ04FOnvP1JidsQzLVGlooh9K7n2zN9Ai57RAjNO0mb0xMzLuCsiIkjC9CEYSB7SSRCFKWA0pBwlTn31hU/daS6EolKbmlVSUEKUBIlBTIWz+m68CQjnWv9HJOGCAT4OQBSCRMEh225y9kah8hJUl2GCR7d0FiCKxuHNuheGOS/PknUHYRkdDiVG6X+X84LuzbBW9c+h63bh5n16H7QCVQZhel4jLJ7kGEtCHRAz13fZEtUISILSE+1R5o8dbG9pIJbG09f5tMYGvryRsTE/MuQCtC/9/u3XQP/Q0MG5SBlexEWL1QuAKmQSFvMHPjprh7txKOdDwn55LePfOVEkOg7DzM5dk0PZGwvL0uwF2BxQVPUTJZNe+UbsH1q97nE1jpPVh7P0pqz70svHgKd+kKRiLg2xiwr7PIxZe/za57fklnaHQKCPcGLL0O9qx+CfMXePPrA/zEF2ebcxlXyQS05Zp8rpbEyxxdLUQ+t32SxBAcht6KSmm7yRsTE/MuQCtCqduPYooBrY0kEe4KOMuACaaprlxcpMdaJpUAR7oIf59KeckPFSilQFlIM1l2bAavsBiUna7Rp+mw9PG+w7QfoCZ8TUdB4SpcvoQ18GH67/37zL3whyhncW2yRrH6aaSC/h6YufJt5q+/Rd/gAGL5Ikm1CEvXwJ4DZw5Eeg9Gz2eAbzbrQnoKwH0BH3mvWIQyAW25bZIhpt3KVLSbvDExO4UeK8coZ/6fACYYaSgB7nsarQglUj+LoUD5YVnm6gekY6q5W7Mc7MGQq/7F2ulZSKGNPwoShmDqHZfr566RTpr0din2DHaxb29Sh3b5GJAvwMTLeQwjj8DCsjo4tE8y0JvESgqwlS6TYXbpqvL2IkY6T/rgX2Pl3H+GCqvQhtyLFvSLGW5MZOn71Bdg8Tw4i2AvauXOXdBJIhMHH6CJihDtEza/1WSqNcT+QdtKu/nbbJ28WUbR9+UccDLeYquT8gP4GGzI9zSNzkR/BhhjZIvmu1aQYafI0o+uD/lQlfZx4AQjTfRFfY+MHYv/e1cHuz/yk4giUFGFQikwBfMLjjDdedXZofUZ4RcOU27ZgVmBa8Ntg0n2DZoI06LkJpm7tczeXRIhzIpK8wIcySAXSRgFXBdKeZP5Ky7T53vYPzTEwQN9IJPa0dnsBqsPzAFEag9GosJruqJ6veEZqJTSFe8vX/g27t3vx3RmwF7S23EyD27ek73rU0z88xRQbNK1zAS0vVesQVD9OpyN0okXgn+kor8p4MyWK5TZ1fMOeS+fOVgzwWQq3j/TgquxTGBr601omcDWeuXNMgx8ueKdB8nyBUZqjEntuJ2hnIF9Cv37t+JvvbXoJJcnCY6IPey9jgKjZDnBSBMTsraCDDuB/t7+vThEsNX0KPACWR5uyvdu17FTnsOPsLZepp7DN5lLhDr7wY/Rkf4ORmGv9tcxPG3HhERCTV2YwZ17g739CFeuDWEXApTQiRMRls4fZCSBBMJK4zqS3j6FmUx5FVV1aujCsktx7iqmUUJJFwMXJRX5AkzN93PfT3+WZHoQzF6dINEagK7D5C/8JYXX/jcQas32mKJc2FUBpoBLswkOfPJX6O9NQ2lBR6y5JZAlrRCl776Gte9viI/+zgvNuPYzp5mjekbcj70XIsa87cHzVZq/NHickzWO9RWfDJtvM84DRwaPb8Fg0oP+RJXzhqE5k08Y9Ko4Q3mw+0yhLSdngCD/t3FGtrHm207Km2WCjb/pNCNrlNzKzw+jCwMHPXDGgdEWVCabi36gjAKP1NnDnQ0/+FpBhp0gnOIXROPzUTuNnexqEfEwc/g8+tqe9K2GFob5KYo3dsEiYFaUfjegaLEyN8eudDlSfv1WlMBdDeVSsoSSCmEolCt0UJjoQu/AlVUohcJVSVAKpYTeaFOSVFpyyJmjVEyR3HcviDQkvMSI/R+hdPlN3JLC6lgrg6EFYXXrzoC0abN848f0d77PU4RKoLxINZkHe34PovdTQMOK0MzpwLIA07WUIM/6kWGjFutbIc40S5HyzjVMeStiAjjZJOUiE9CWq5DBt7j4ik+tsgo+fbA62JpDlgw6y3ajNdAeJ0tuyybdcAP9KNps/niN3nLNE6wKrSCvlmGzcx8my9Ca30o/eMaqfH49R4HvkeUxRjhRl2xBZKvOB6CvxRR6db111tHmjItjUH3x0xYy7AR6O+rLtT5Wg8fJMlH3Nlk7jZ0sJ9DPhDDPELzPfRk4RpYMI8xZGOKTKMNEJSlHe2mNwi45SrlFUkkMKsLWoXJnSjs7K+WglFcnTIFQBq4yvOyIifJRIgGGDeaCp3MJkKAMB9eWJFMGVu890H0vmD3QcUDnATK7WZqZJqnK9cbWUCmfgnQKVuavQGkvOCs6RB/XK+nhgrNsYC5+EsiGvHhBBPk35Ko1eHmHhglOIvcg8OWZ03r/txGFyLO65Fg7sRwFhmdON8XSEnQdTnjnr3eF49O8yb85E04lzZ909YR0wnuFHei1yDWpn420lrxHAtqGwLvf9Ur2JNHlfYQsc4w0STHXD5QTVPMB0fjj53GyPIZeXTdzTAyhH2qNjlMgMMN8a8uwE+jvfYb6rdLrOQNVrDe1af2xE00B24z70NcoYyHMe3T0l5+10EdQsl1hCqks00sN5O9Bef8KTxtRns+Qb5nRSRZLCGWiVq6Bm9JOz1aP9vkxXeAdfbB0UW4R6SisVJqOD34R685fgvR+7Szt5iF/Ebn4JvmL36Qn7Uu3KuZqkmhR4TeUTMJSaQ5KK3pLDOkpQZ4zkVsEd+WeOi/geoIUgA37qZ4CdJJoK52jQG7mNJkGlKHRKucMZWmpsCZtNrn0E6zQBU3uYZmnGf5W+mF9huZMtJU0d9Ktf5IJZqu2dFpP3qDJXKNlrmWRCuLLZDnTkIOqfgCOEn2MPAJkyHKsKZbI5v9+U20pw06grV9naO7YOUyW4Tq3yFp77Gg/pDEav15HyTJsKYz9QhnliDHhaRaGwHEkpqF0Emn/sEpdyfCUEKVzUSMc/a8CrR6ltDIjknqbiw4QHShRxOy7k2Q6iXKKCMPA6D5E4sDPI/YfA9EBxZuwOAmFaeyV67z25J+wT17GsEDKshjr5RKei5MFCHcZt1TANKT2UfLNSEqA66Ccwv4GL6KvHARppLmKzw7R2EqnD60MDdXpNJwJaAtzM26F8hCFEw1brZq/6qpkqim9NHdFvJ7m5+NpXXmDFdPGJ3KfE+gFQnSim/XX469qaz+4guUYJbx1dBo9r+XQ9/wQmysvubaTYSdo7D4cJ3jcjUJdilDrjh09Zr4W8tOT6O8SZHQYshxX9VsIBCYKcF2FZegkh650SJjlCK31leE9fWe15pculuolBFIKVAKSByDdpy1BiT5IDtLR20O6+zZEsh8SA5C+HTr2Ax2wfAGW3ob8JbBnsItLvPry03QsPUNPfzlpNbC2XJifyNr7r2GCIRxcx8VMaAFdV2EaAjBQSuGWVpqxgs8EtE36CsvM6YYnPJ8+WO0rNDUSHUKNCWPmNBl2RgnyrUAnG/aT0qbUHOF+g3HvvLnVFUuWHMHXINeQfPoczVrpVCPX1N7aTd4ywzTHSgm1Q/83oq2SYwRbUcNyXwMrf8gyRrhrMY52MN1olc2uOr37C4xTkaxUrSDDThDtob4e7WeTZYrqc/thz2LYuCW9zDA7NXbC3yen0NvGUyGUtjnLkSphedmdl4sl8sUSgz1dmJiAjelZWIwK5UdQtgQZnhP16raYUoCLUC5KSkjfCV17PCVoAJKDGB37oPOg9v9J9GofnoVzsPBjWJ6GwjWdZdpZwCjl+eDBFMn7/iH5d56DK08iLE8Jqwib9+XAE0EAhlA60SMWtqNYyBfpTneQMhOAwLELQXmqwxLoH+RZjE7SvBsH6nMYzgS0TYawMAUd30wm0dapHDDRtGi78EpQUC6OHNUVockmRMicJHp0zDR+QjXNMNuVmLDd5F1L0HicRo/ZSiV4gupWxGhKoFaCcgH91cMw9az8s6EeatPAcOAWpb73j3j9+Upe+8iwE0QfP5NURlqW55tRgh/0x2huCpedGTvhlKBJ9H1SOX+fIfj6TFiOC8pUCGXT2bOfrt39WhkRIMykX3m10iVH41tm1jlRV8axCwR0/wT0HoREP6T2QvogKn2bDrMv3YCbLyOW34biVSjc1K/irJf7J48pi5juCiydI33wKHmzA/vCdxEJgfA0njW+SZRD602/TblYiTSDfe+DwnWwF1HKwLFLNa5pKDIBbf4DPcyEN+59fg5WfXGq3SSHve2xqbBC0nieoyjnisI4ZRP3xJbkCSqvvoMG3TxwrAF/lLE6j6vHZ8mfbDbm5dCr4u9VPbIZ/kHtI+9QHcc8WsWB8wTV5ZwM3Xt4JWje+9wErEbg1cohEw29OKi1vREtuieqVaoVZNgJtLIWRgkqWzaqMcKYt61Y7f7IRBMOaLWxE04J2vw+GWGOLJNUH3MTlu1gK0OCITCcOVDLel/JTGIlTeF5/6zufalVHyAAgTBWPaa9t7SPkUKBMFB9H4CB90Nqnxf9ZTH/1nd46uxXSSaWschTtDvoTCru2GPT29VJb6cJThFcxyvIqkAuwtQ36Ljj53H770QunEcYRjnB4yp+5JtECMMr9aEQMg8rF7xkigqlXGy7aNe4sIF4YeBBk9NojXb/ATG2XgGYOc0owblVhoimnGQC2nK1Dh48zpj3fevN5wHlyT0H5LYxt1KO4AfPOFoJqqWEDdU4R3SiWQfC5OAI8hVp3D+oveSN4jczD2SqOm6OkPOitDa7/8M9pMNdu3n0NTu57tjREMdG5WRA2zx6Zd1MS0KryrC9hPOvqW0BW8toQJ+HydIfMbqwdcZONlQgQfW8SdVTAfjyzVm2NOekMHebplH2NDZSYKWxUh0IYXmh554jkBJlf6B18fTKtwIBKIUkAbvuh77D2tIz/yIULmFe+TM+2DdBuncPmGkcLGwbhFFg6uIUjpvmyF0dGKsOzmp1b05c/xFW9xClhakKK1BFKJuHlGCaKUzT0MoPCqT3PQQo6WKXCo1aHzI12qspQdPA6ODx6iuXwePMeSHzDfvl1FLYwpa+GDzOiZnTnKGchyiMWfNhvMyiO1JmRJufgx4epxgJ7aw3VOX9+TojH8IqFdPo7bowD4Qgv7dcOMGq0G7yhlcaJtETefD9qf0xzqAn7wfRD4AToR5W4a7dOPrhN7XJuee8czdHEdKWmKC5pRHraPvIsN2Es4CFXZiV0VahzZzFfXzXgLC0xtjZmN16PWEs+UHuK+MAVtE1r0ojdbcOs0rpLStDh7tbXQkhrC6kmkNVVJSvdEreLMWiH1qvMHV9r5vfh/lXYeUSODOolSm6u3tId6ZQIgGmgZHoQsp+9uzay4/ffIepqyu873YLnIquDQGlWzhOEiORQskSq0qQWiMUUoFhGghVYjVjtpL41iPXVZQKhasBFygM0Z0k4VG04+92KgWZgLZIpS88pSkHqwrWCapr62eDlL0tRzvyBlmwoihBUH2VlIvQRyVhHmyn0BNG2PslE9CWC9lHNdpH3mzoFW24idxnpHz/R6QZCvlQQFtU61nQ3HVqmxSQVpBh+yhvKQcRdU6qZIJmBLS0ytgpZ9euRrAlqsxwQNsUgFV0zNdtOj+TSpo6bN1IgdmhFaFEL2Z6L649h2H68enrfIL8N33fHN+LWYB0S3DlLDAH+atQmtVbXIXruK5EugUUCiUVrish0Y2UKe668zZuXJlG2fZaqxOABYXZd0gIhSkMTwfSlV/9PEdCCKRUJAwH8ue9Iqu9Xii/BQbYjk0+X3i9xgWsiucEHeWmGyd6QsSg/qP0kwloy0XoZw2Dx5nwotGqsXMm7WxNZ8mzkSacbGD261zofsr9naT2/VNPmvyhgLb6tyLbTd5wpn1/Nbm1i5JszSSJtR9++v4L6qOZ28zbb7ndSCvI0GzGCHaVaEQJaiY7P3Zq+3WGU4KyNaOdJwCMQkk8W1SdktSAjupKDUJqF6R2ITr3k+y/B9f1jxHlrS/v/2UzjP5beS+EgZI2avYZWJiA5dchPwXFyyh7HqSLkA5IGyFLCFkCexmkiyRJuqvHs/i4a19CUigWcF2plSTPECT80iCePK40SKUSIFxwl6BwWStFxSuglimVSjK/svJs4EUMJhPhs48OHo+WCNGztlRjOqJFKRPQlovQz2ZsbTh5/YxSfRDpyIJoZALacpF60oMzyFI1D3ysDsfTfqpPtPN1T1rtJq8mzGSe2fLwaq3ABIVHj4dUgnI1zjQWRSyCFadhz5q61bSCDNuD/i5BqRImm6AEDTV4vE8rjJ1Rgi2oYSxBfj9BTABYiyvO0wW37wbJXfsQHWB26pfVBalBOvffz9KNcYRcRBletLlabxJSKISXTFGtBo65pRKsnAOrAHYBsEE4KOkipUS5RW8PzSt74ZaQpWWsvZ+izyphrFzYKLaCQgm6UyZKyYqG1f047atkprQiJN2KbNc22DPgzrE0I27cml15OsSFrEYmxGemgWN1OgUH9Z8L24mX/6eqVt1gyY5MQPPklhRHDUM20Knbd8CM+pCt5tQXzT+otnk8rLl3M4ImsPp+53aTN1zfAF9qKBt0eMYC2qaptb0eLuHi2Tq+Sy6grQ/4BtmAnD3NoRVk0JRLwxyj/ACeRDuuN3bu7GoKlWpM02h6kuBFBUQbTzs7dmovvB4Odf7a1iDwLULX37n5ar5kTbvmIKT3Qcc+Xd4ifQBSe0jddj/WwEd1MVUqrS6VypDnP2SYGEYChYkyOhDJXkTpmlY+5AK4K6BKuLKE6zoI5XgOzCZYnRg9h+kY+m/p7EnQUXwFDIM11iDDpVByyTsGyaQJwkRheP5LYnF7HuYAABq7SURBVDU7tpSCRKoL05To3NP+SztdO65kYWFpeurC4qs1L2Z1aq1WxtGV0uu9YYYD2nIR+skEtDU6uQQNmFyDfTdC0KQzGnkQ6wFVbZLJReqr9kOtXqVCH1udqTr7HKW95PUJmgDPbojK2gqyNVe1myvkWYbIMuolyvsatdM+DEeWTZ+3ln/gUbQyMkWWE97Dtnm0ggzgL5ym0E65lb/Xfd65hxs8wwmClZRmbDFlAtqiWld3euyMBrQ9GsHyXOtz0/51sY599e3ii6c//3RBdn+qq/N2XQoj0evVBetEdB0meeffwZ79K0wlteOx8JyTK5QhA4VtK6w7f5HOvr2gTFIzz2At/AhkEi+xEEiXdFcfnXc/SKojhZ+ISCiJkEuw/AzMvODpWhZaCfJISs5fSNCZNDEMqUttKEFFoQ1A4ooO0qkOnQoAykFlAIZgZcllcUk+/fDjqvgPxjY4PNUkRJbmRweP119Mzus/aAKNosAEKWy5CP1sRiagbTtW2xsJXgWM1zmIg47Jhe5Fl6JofKVTnSDFdCpyb+0mr0828L7UYclbjb52QdEuZWdg/SAeQo+nDOEjdnxrXL0P0VHCZbY+jFbIvkY2RF6bdpJB3yvV81hpHidLrq7zlS1N1Xi0SdaVTEBbFIt1UD9bP3a00hk0f4+G7KeW8gkVc4wFsLK88sRi3vwfurqHQCWRogNldmF23g7JAVKHH8R5MwuLL4FleUqQqghYFwhhUCgqOt75L5glC+wSprPsWXUqQr+UojO5DAt/BnNCt8kiuAVWnZFML8rLP04ACcXFy4qZxR4+fncaxwGFgTBcrQd522JSgkj1kbJsvS2GIF9wSCUtHYFvCGbmbWYX7CdCXdDNCVIuHm5CpNRoQNupsP5BUeqg1cmWWoQ8P6lRtOPkiZDfezigLWhC2hw9oJp1DUcD2s42IRFcJqBtqo7+RgPaWlFen6D78sw2OEcPEaw8g86APEW0wsuVbJZBNxojTJDlYaLVjHoIeMjbsqqVI6q1ZQgXxeVzgnrmD31MNYuen0euGWQC2nIR+tnZsVN9zglv+SwXMa5Fzv/DAJi59vb3FxeXb6jEfuj5ELbRh0MKDAuW3sB0rmPu+yxSCl02QxewWN0q08YWgasMOsSsl715TvvkbOLsjCxA4QaUrkNpRofY4+pU0JbQDs6mDZYDloMrHd6+4HJh5gAfvvs2pNAh/sKwAHNNeLwrOkmluxBqBdAWrETvkM6RhIu0XW7OOjcuXnO+H+qibk6mWkOjSpBnDQqKDonSfyagbboRH54aVrH5JvkHjaFXiw8R5nvria3atTtVx5aYr4hVI7x/UDbwd61ve2Nt/0cI3kKZitjfEO0k71p2bstWr2jPU9vKcR/1K0GP0diWZBmtzD6M/k2jcBT4HlnGGt6u2jkZRglf4iGMA/FmDAeevxmKRbapOwg7OXYyVB8TJyNY5MYI97uujh8D4G+OXpidvfTyf1pcWIHUXlJdu0lZLsz8EGafgpkn6ei/HdV5J0JWJmMWnpO0QCoDJSSWqcDx/J8lKKnD4x1Hb53ZJYXjGXqUAtuBkgO2rXP7uI4iX4CbMwZvXUjw0lsGr0ylcKyP8NEPfYBksgtldKE8ZQgjgRIWChOpwOw8QIe55CWBVKBKWM5VDGywFLPzDjdn3P80cloFZW2uRabK+5Fy8lQhaIUwHjb5oUeQ5apR/6ChgLaGJ+iZ0xvyrjRqDRqtQ4wxggdULkJfwwFtJ7fYRwCihyMPB7S1oryV7MxkriODolg2ojKOjs6LkqepNloROUJ989dDwFSE3DOtJEMtP8/GyAaWRZlsYimQ4YC26YgK8076fQ5XeX+esJYzXYojbFqb1eti+X+888YPv9538D8+3DvYDfNv6qKn9qy27JRmMYVLct8nKU1fwUQCJlCus2oKxcVbSV65nKAzWcQwHGw3ie2m6O5weN++At0piRAwu2Tw9jWL/i7FgQGHjqTCNGDqpmD6uoHrprGdDvq6LQ7u7WB3fxedXT047gpuokf7PCcMpL2AMITeqnNtZGIfnZ0JROmWJ5/nO+Su4CdAuviOw7UZ9+shL9QGvO2aag/HhpSLmdM1QyxHI3aZCWjLRexr2/r2rsN635Qw13a4yvvjkff39YCq5auRi9DjcJX3ww/y+vrXRLceVOuvVeWtpNrvNrnFpv3RLehzHn3vn9zSSB09Po5VbCscI7y1pA/IkWWooeu7/TJEscjVc+2DFK3mbInV9kGKep6dGjtQ/XqFW3iFr0yvGVnnIwTw4O8vPvlf9/zF+IEDvUd7epKQvwHOgvdaBmeRjtQAzq5PoG7+CGHpQ5VXAsNVcMcusF2BaaQQIomSAiEEy0WThWWwvOCy5bxgVzqJIRSLK85qdLtdMnj/3i4GehMkEyaJhIUUJlK42KVFhNkJThEjNYAszSMsibSXELhIs5tE/x0k5StoB+xKB2rAUCzMw+Vr7vjw1+WTD/2b0JdrPVtiZfG2msYCPnIqijUohEN36L7qoO4B4ymaY+venh88XuPaBpuH1/cXTO0EeD65kP0dofpvMdbwBJON5GAbpr/2kndj39XIbck5yzTrO01TrjDeqOU2GvrhMOw9YI9BTR85nz60ctv4A74VZNhIPb9DtWfFfBOtQUE+SPNEmft2cuxkA9O8jIU4fowoStC6TOyripBSij/6R52/t+uFPz9630/dC/mb4C5ra4qbBzePKF2ga+BDLJc+jFp4Wecbwg/IMhjoVhgC1GpEmcIyXWYW4daS3vJSgJSC2/eYFGzF7KIgb3o9KOjvgnTCxVGCku3VBRMSYYKSKxgJgbRXEIkeXKeEYXUhpUT0vo9OcwpK8zqTNOsUIQveuiC5ekP+nlKKBshUef9svWUzPKfmMwTf0FEd9YIUtvEmlPjIBLTVtXL1rsMYG6/DWEPyRJl0tI9HUAI8nyj5g4YD2prxoBut0R7V92I4oK0V5a0kE9CWa6DfMMwT3oJRecxExau+6KRmo5XdMWDMe0iNUnvLoTFfoe2X4SzhItbGIztkNzsT/ebnqGUNiurcnAloy0Xopx6qnXuy5niIrgTBumeUVfmfX/4/V75z5rf2PHH7PvnArl0WFJe0Y7MsgrRBFjGcp+jc/zlWpI1aeB0SXQAYQiAlyHW1xxQCqRS2LSgUFUp5PkGOjvAqOYp8UX/WdsGVCukqwEUJoevAIlCuQJieEmSBWyhhpPqRhVlE/710pa4gFs6DSLAm5B4gATdvwLmL8okvPu5+J+IFW0+1gZirpzPv4Z+jRr6ROhSXTEBbLmJf28UZNr8OYVZ4mSrvh6/BFK4qtE8udL9B++6NRt1kQz0coiqm7SZvJTvt43CS4GLLY6tytEstLS1nxrOUhlkktIsMJ6mtCE1Sny9R0H3YrC3OUZq7eN7JsVPt3NXPW476q6e+2prfwFjfevHi7G+8NPG2TeEaOJ6PkLOoy1TIAthzmPPfJX3HpxG9HwB7EUOY+I7TmnLSRb8kR9HWFqFiSTtFC6HbXEdRKkGpBK7DatkM7WntoqSLUroUB6qEEC7SWcYUEllcxBj4MF2dS5iLL3jRY2rtSyiUUrz4umtfvCZ/o44LtkqNTMqRV8ohlaDHam4LbU4moC1XR39byszpqk5uj4aMQMtUeT8XSoBoSlD4fjXV82I0Qu3KzPXSbvJWUm1C3XofB72NlQv4xElGvHDvdlGCKtE5uB5918igf4OHAz5xlvrzNA0FtOXq6G8ttbMv1xPQsHNjp/r8vfl5tSP6FPUXma1uEQL4tX/nTPzbka7f3zfo/PYHPwCUvBB45WVnFgqKN7Fm/ozOu/4e+Yt9qFtPIRI9funV1YB6X88SQMnVfkRF2yRfSnBoDziu4NJMklRCIoSsOE4j/BIaUjs6K9f2drwMpHQxBj5KZ/I65sxf4is9OlKsopMUvPoqnLvI73/pT2SjmnimyvuRQ9E9X5gzBPvxjA8ej567IkRZjVzUPrcSTwnazLQZxTG32nWs/ZtHV4Igmn9Q86lP5jD9tpe8a8/RT/X7YLt8bYYC2prv7Fz2oxmCbVGwclRXZrf63M2XYYQxsuTQ1hP/3p9AbytF62stWzOOIEz+o8nQiQfX9rmTY6fa82pozf+yq7609SpAmpEaihDAU8/KR7u63Ad299k/uWeXjSophFDki5KlFRjoBSt/HfPqH5G+45fJJ/tRV/4rwkoiRKKcaFFo/cmyDPbvTqMQzC1aCCOJgYNpQldnHwnLxaBEwnKwDIGS2oqkAKGU7sRwwVUoWQCrD2PvR+lMXMO4OQ5CK1kzi5LOFHR1ePXGknD9HZh8XTzz/efFo19s6MoBjVodPGZOhzLv1muShe2xBgWtEELt03sWsZNU3989GWpLMNjJL/j4+kztUfyDmus3AX4l+KDVYCO0m7yV7KRp36f6BN1sJUVvM1Y6y55gK36/tVRbmM1vo5WruTJoH5TIC84abM3vkF3dRQjyRRuuo+dWGDub8RBZ5tDz+DHCOc1Pe5+v9tkNlu1NFaHsc/nS7//9vceffsV88nMfKw2kky52CbAG6dq1C6d4EUUBVm7B+X9Fx/5jlNJ/G+fSf0GUbiHMtJdRWnvrpJOCzmQHKDjYqzAMB8cRdCThM/c42oCjkiiS2K5aNeiUvY0kyinpZI6978faey+Jwou4117A9XbhJCm6Bg6BO0+pdINEApYX4YfPi9lzV3no1IRbCnEBa1Ftkgv1UPSsQCcD+vGZBDINODRnAtpydfa5ngmq768fo8YqoiI6rNrNOt1ImZKaZGsqYUHkmiRFtFVjtuY122paXd5M1ZZ23Iqqhlb8x9i4go/qqB3lnEMEr8THtuzcrSRDczhCPXNINpQrRb0lOzJVW7Zn7AQ5rkdZRE2iv0vQNcitf2ODj5DPP/n313984UbvL//ox7solrQjNG4Rw11ESRfbBluCXSxSOv+nGMVXSNz1C4i9n9GFUO0VkK5OtigFrjbo4EhByTVQQiCVoOgISo6g5Gpn6VX/Ir/CvbSRpSWU1Y9x+8+T2HsPxsxfYN94Ads7xrZBug7CXUS4BZTSvkjjzwnOXeKX/+l/lK9FuJCbUsM/KPDGmznNkLf98wJbrAR5VpagczTLzBn0nR/yFJ0NzJymf+Y0o9Qe0KN1S7aWjXJkVwdKUObk6YA+m7XF0Rd6K0qv/l+gPqViqo5jNqPV5a0mW2O+Tc0iG7htFub4fi9C5ntsvo0x2VD/m59v2Ns6Ok/wvBJ2C7v9ZGg+mchHhFOCzkbeEiuz02OnGb/dKUZWv0eQy8mG+XtTi5DPr/7h1Lf+7a9/6B+mzqf+8L47LoKzjJtf3lx9uvY8xuybmHt+Bu76W8j5C6i511CFm9r3x0yghIlYLc3hU1ER1d8G86rSKyMB6dsxBz8C6R5YfBF7+jmdu8gvTO/julC8hmVpN6InJwWvTzHyj/9UfivoO0YgU62hms+NpzwNE97qcIrwNbWqkQloa6isxjpyBIcLvzBzmscoK16+L8OxgGN8xiOWKglSTE54NZ3m0IP9GMGTqb8lOUYzKs6PkCMb+ImTBP1m2ikwKBIpDFOhP9lu8q4leuRJ8wkaEyeor95df8WxQWNnLERfGWCiatV7fQ2PQGDx4vU8FinkvxVk2HomqC77g2TJhLa06Ot1huDfXteeq5+dHTt63gmbzmA9OkKunCallktJbv0bgYoQwD/4g1ezf/xPP50WVufXPrDnDQwUrrPJBwVQWERN/TlmehBz1ycw7vg5hFOCpUvI5UuI0qwOxVcurHOMVsJACEvnJkrvQXQfQqRvQ1HCWXgV9+ok0rF1YBhsSBOkgISlQ/Ofeknw+jRf+tJ/kP+61veLQKbK+2ssB54lxH/gR1kNf2nweFO04kxAW64J/QMweJy5mdOcIVjJe4ToviHTRPWNGmHOK8C42cRzGPhGyJ5OMeJNJo2u3tcySfV74ShZJtB1h85UnPsYhKqg7CdNa6YPTrvJW8vZs/lOytUJegA+QpYpL/KpNvq6DlNbAQL9m43V6G8Mf7xmmaTsP9dP/duXZ4livW0FGbaHqRrtZ8hyLFAZKhfvDRPiX290WyuNnWFqW73WM44uPjxV8V4m4PObRsDVVIQA/u4/e/Lkn/7zz+fVbN+/el/3iyJhFHBk2SF6DQLclRnU4hOIhIXR8z4SPXdj7P80GEmEdBFuAWQJpVxtDxIJDDMFZgopBNJZxl25jHvpz5HLl7Xjs+mda12KID9ILJWApRV45lXU25fVr/7j/6CC17XRqboy8ZSfE0RLCe8zic4T1KwbLhPQlmvSOXxGqc/Hphr+tahnQI+itwzq5UvrHlCNWDTWc4bgwX0f8I0alpjNOIteCU2RDVQsot5b7SYvBPsvNWJhjcoZgq0YX/Mc9E+io7zK31U/kHxLSJSFlC6CG/QgzG6wTDfDb+vRSFsxrSDD9nGG4CCMPnTB2LPoedm/D/x7IOzv35gSpGmNsaMXtBnC+W5OoxdjY5u0BS2kc5u9GUoRAvjbv/Wt7DceO341PyNOHUq/2j+QXsSWfokNjQCkt7tlmqAcB26+QeH6GwgTRLIbIzmAkehGWGkwEqAkSpZQdh5lL+AWZ8Au6Ygxg9VtOKeo+xTrFC8hIJmAq7fgxbeYu3Sdh379j9U3w36vMNTwDzqM9oWIyjw6Kmq0Hpk2w/MPCho8uWadC2DwOFMzp/kSzUlwNg4cq3tbUJtWTxFdMdMWqI0PpOBzReMk4Vb1YZlGKxRh/b1yEftvN3mhHr+LrWGM2lXND+OPmcaXa+Po+7fWuBlu+ExlJtG/Zy7ica0gw/aglf1qVupKHqS+7SBojhIErTN2/Gziw2S9+nobF6Rn0WV+Np9LgjN6QxWraVVn6c34wiOnv3lppu+nX7xy6Mk3r/XhOgIUOF6maNsBR3XiJvdhuwaOA44CV4AjoZRfojB3keXrr7F0+XmWLz7F8uVnWL46ycrNNygsvINtl3DQhh9H6r4dx8Dovhtp9OHY5XOhtGvQK2/DD1/kyXNX+OlmK0FbxFngyBZERWUC2prpH7SKt513qsFuHh083lCUnEZva0WR5SxwZJMoi6AVUpAT9ebowR3dN2RzHkXLvH4iqObUGD0ZWrvJq2mdVe32bNPMo62YYR+EuSad82FGOFKnAtIKMmwno1vY9zjNUYKgVcZOJSOcYYQh4E7gc8DHGEEwwrEaC6rhgLaqaU8iKUIAw1/5i1effUX+7GsX+776/Lne0vU5Swd5eaUzXFeiJNiOKkd1eS9HeooRWjkqSMg73v/Rbc66Y2wXbEdir8xiFwvYrj6XIeD6LDz1MqXJN/jq0y/zs7/9/6hXo36fbWYc+NzgcY5thVLCFhWErcXgcYapL9vrJPCxpiqE4ZShSeBz3qCKOtBz9YjlmXAbyYh7CrjTy0y8mcxTVY4brets7SZvUN6Wrazavvn5mrE4COIUMBTa10hzkvqjyqbRGZiHGiwW2goybB9aUduK++CxCApwGFpn7Gw8/5SXiT2sHHU9A0UjBUj/l+E9n+hLrzx6W3/x8/sHJb1dupaY67ImqeJmKAXS6kUIE+HMI9Z7P69+sNyXvzW2sAJXbsCVm3zr1jxf/u3/Vz1X73cQ6/faqjBzmjmqm9wepfpWwjz6Bxjb6ozOM6fJUd0U+4U6S3VEOf8Q4fyGJtHbgmNbJkx2NWLP99uap1zRO/i8+thq/kafa2glml2NSAuz7eQ7Fp8MUXiwH30PZrx35ggyIYelXeStXnhxnpEtTzK4OdoXaJTmbDH688ho3dFR+pqPEs5RfXXeaqrlpRVk2G6ygfNyFKbRvmC5JvRVphXHTj3obbEgN5UvVJtfGlKEfP7X/z71N/s6nRO7+tQDu/sUvZ06gksqz2dos1MoSPYcAjNFaf4cG8LA0EqP4b1sRytAN+bg1jxPzC1y8tf/RH27UdkjKELDbF4i4OHB44x5/jnHKKcEnwMmtrOcRY2M1QNNqDgfVo5Kp0+fObwK29slR93oaI0JNj7AylFljfXv3yvH0NfJ3wevrETeaIr/5tEO8lZXXh9jpOlZg8NTjvwaJroD/jRaec811QqSXQ3uyFTINI220vnnyzXtfK0qw3ai82rVW2fPLzVUT/2w2rTq2IlKcBX6aW+rbVOaogj5/Iu/Y3ymr1Md7+vi873d7O9OQ2dKK0XCQFt3/JRBeOXLwKsw7/3t51OUWvlZKcJSHhaWuDq/zLfmVzj9m3+ivt8smcMqQrAmL9AQ+sF+spXqdgUUcR0fPN5CDnHtQHaDYvvumpjfjazNYaQrvbdSRFF2dXHQz+b+fDnvX61ctlZenJhG0UrxCfQzJIyVcBxtYT2z5UVPW33s1ELP11ME7doEfJ+mKkI+v/uLYvdALz/TmeKvd6a4vyPF4VSS3akEpmWAZWnnJF8HUWjLkeNoP6KijVsscbNQZHqlyFMrRb47u8AP/udvqpvNljWKItQOeMrQGcqm2Hl0puqd3euNiYmJidFopXiIjY7KU+D5xcSEp7bF7c6ghcWWKEKVfPYOkfz8T3FvKsknkwk+bpl80DTYbwgGECQAUNhSMetKrjour5Vsni+WePZbP+Klv7ygmlEjrCrvNkXIx/PXGaIdtqJiYmJiYmLqoborg09Nl4ZQitC7VVmIiYmJiYmJaWN0zqGgXEw1A1wih8/HxMTExMTExOw4Olt5kBI0HmabMVaEYmJiYmJiYtoL7WdVK5fWcJiuYkUoJiYmJiYmpn3IrkZIB0XfPRY28jJWhGJiYmJiYmLag3BK0DwRstTHilBMTExMTExM66PzHU0RXFwcdAbu0NHSoavPx8TExMTExMRsGzrrtZ+INEO4RJSPRS3VE4fPx8TExMTExLQG2dUakUHRYNWYZGRDksqaxBahmJiYmJiYmJ0lu6EqQlQm2bx0TU1iH6GYmJiYmJiYneYEjSpBddZkixWhmJiYmJiYmJ2m3kr3Z2lACYJ4aywmJiYmJiZmJ9HJEcM4QleiQ+RHaiZVrElsEYqJiYmJiYnZSYYifv4UcKQZShDEFqGYmJiYmJiYnWUqxGfm0c7Uo2EzRoclDp+PiYmJiYmJ2VmynEBng/a3yCaBOXQW6VyY4qn18v8DsSND1cPhyMEAAAAASUVORK5CYII=" />
|
||
<div id="tagline">Open Source JavaScript Client-Side Bitcoin Wallet Generator</div>
|
||
<div id="seedpoolarea"><textarea rows="16" cols="62" id="seedpool"></textarea></div>
|
||
<div id="testnet"></div>
|
||
<ul class="menu" id="menu">
|
||
<li class="tab selected" id="singlewallet" onclick="ninja.tabSwitch(this);">Single Wallet
|
||
<li class="tab" id="paperwallet" onclick="ninja.tabSwitch(this);">Paper Wallet
|
||
<li class="tab" id="bulkwallet" onclick="ninja.tabSwitch(this);">Bulk Wallet
|
||
<li class="tab" id="brainwallet" onclick="ninja.tabSwitch(this);">Brain Wallet
|
||
<li class="tab" id="vanitywallet" onclick="ninja.tabSwitch(this);">Vanity Wallet
|
||
<li class="tab" id="splitwallet" onclick="ninja.tabSwitch(this);">Split Wallet
|
||
<li class="tab" id="detailwallet" onclick="ninja.tabSwitch(this);">Wallet Details
|
||
</ul>
|
||
|
||
<div id="generate">
|
||
<span id="generatelabelbitcoinaddress">Generating Bitcoin Address...</span><br />
|
||
<span id="generatelabelmovemouse">MOVE your mouse around to add some extra randomness... </span><span id="mousemovelimit"></span><br />
|
||
<span id="generatelabelkeypress">OR type some random characters into this textbox</span> <input type="text" id="generatekeyinput" onkeydown="ninja.seeder.seedKeyPress(event);" /><br />
|
||
<div id="seedpooldisplay"></div>
|
||
</div>
|
||
|
||
<div id="wallets">
|
||
<div id="singlearea" class="walletarea">
|
||
<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">Bitcoin Address</span>
|
||
</div>
|
||
<div id="qrcode_public" class="qrcode_public"></div>
|
||
<div class="pubaddress">
|
||
<span class="output" id="btcaddress"></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"></div>
|
||
<div class="privwif">
|
||
<span class="output" id="btcprivwif"></span>
|
||
</div>
|
||
<div id="singlesecret">SECRET</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="singlesafety">
|
||
<p id="singletip1"><b>A Bitcoin wallet</b> is as simple as a single pairing of a Bitcoin address with its corresponding Bitcoin 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 Bitcoin 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 Bitcoin private key should be kept a secret. Whomever you share the private key with has access to spend all the bitcoins 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 bitcoins to your Bitcoin address.</p>
|
||
<p id="singletip4"><b>Check your balance</b> by going to blockchain.info or blockexplorer.com and entering your Bitcoin address.</p>
|
||
<p id="singletip5"><b>Spend your bitcoins</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 bitcoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a bitcoin 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 bitcoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining bitcoins 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" for="paperart">Hide Art?</label> <input type="checkbox" id="paperart" onchange="ninja.wallets.paperwallet.toggleArt(this);" /></span>
|
||
<span><label id="paperlabeladdressestogenerate" for="paperlimit">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('paperlimit').value * 1, document.getElementById('paperlimitperpage').value * 1, !document.getElementById('paperart').checked, document.getElementById('paperpassphrase').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" for="paperencrypt">BIP38 Encrypt?</label> <input type="checkbox" id="paperencrypt" onchange="ninja.wallets.paperwallet.toggleEncrypt(this);" /></span>
|
||
<span><label id="paperlabelBIPpassphrase" for="paperpassphrase">Passphrase:</label> <input type="text" id="paperpassphrase" /></span>
|
||
<span><label id="paperlabeladdressesperpage" for="paperlimitperpage">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" for="bulkstartindex">Start index:</label> <input type="text" id="bulkstartindex" value="1" /></span>
|
||
<span><label id="bulklabelrowstogenerate" for="bulklimit">Rows to generate:</label> <input type="text" id="bulklimit" value="3" /></span>
|
||
<span><label id="bulklabelcompressed" for="bulkcompressed">Compressed addresses?</label> <input type="checkbox" id="bulkcompressed" /></span>
|
||
<span><input type="button" id="bulkgenerate" value="Generate" onclick="ninja.wallets.bulkwallet.buildCSV(document.getElementById('bulklimit').value * 1, document.getElementById('bulkstartindex').value * 1, document.getElementById('bulkcompressed').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="faq">
|
||
<div id="bulkq1" class="question" onclick="ninja.wallets.bulkwallet.openCloseFaq(1);">
|
||
<span id="bulklabelq1">Why should I use a Bulk Wallet to accept bitcoins on my website?</span>
|
||
<div id="bulke1" class="more"></div>
|
||
</div>
|
||
<div id="bulka1" class="answer">The traditional approach to accepting bitcoins on your website requires that you install the official bitcoin client daemon ("bitcoind"). Many website hosting packages don't support installing the bitcoin daemon. Also, running the bitcoin daemon on your web server means your private keys are hosted on the server and could get stolen if your web server is hacked. When using a Bulk Wallet you can upload only the bitcoin addresses and not the private keys to your web server. Then you don't have to worry about your bitcoin wallet being stolen if your web server is hacked. </div>
|
||
</div>
|
||
<div id="bulkfaq2" class="faq">
|
||
<div id="bulkq2" class="question" onclick="ninja.wallets.bulkwallet.openCloseFaq(2);">
|
||
<span id="bulklabelq2">How do I use a Bulk Wallet to accept bitcoins on my website?</span>
|
||
<div id="bulke2" class="more"></div>
|
||
</div>
|
||
<div id="bulka2" class="answer">
|
||
<ol>
|
||
<li id="bulklabela2li1">Use the Bulk Wallet tab to pre-generate a large number of bitcoin addresses (10,000+). Copy and paste the generated comma separated values (CSV) list to a secure text file on your computer. Backup the file you just created to a secure location.</li>
|
||
<li id="bulklabela2li2">Import the bitcoin addresses into a database table on your web server. (Don't put the wallet/private keys on your web server, otherwise you risk hackers stealing your coins. Just the bitcoin addresses as they will be shown to customers.)</li>
|
||
<li id="bulklabela2li3">Provide an option on your website's shopping cart for your customer to pay in Bitcoin. When the customer chooses to pay in Bitcoin you will then display one of the addresses from your database to the customer as his "payment address" and save it with his shopping cart order.</li>
|
||
<li id="bulklabela2li4">You now need to be notified when the payment arrives. Google "bitcoin payment notification" and subscribe to at least one bitcoin payment notification service. There are various services that will notify you via Web Services, API, SMS, Email, etc. Once you receive this notification, which could be programmatically automated, you can process the customer's order. To manually check if a payment has arrived you can use Block Explorer. Replace THEADDRESSGOESHERE with the bitcoin address you are checking. It could take between 10 minutes to one hour for the transaction to be confirmed.<br />http://www.blockexplorer.com/address/THEADDRESSGOESHERE<br /><br />Unconfirmed transactions can be viewed at: http://blockchain.info/ <br />You should see the transaction there within 30 seconds.</li>
|
||
<li id="bulklabela2li5">Bitcoins will safely pile up on the block chain. Use the original wallet file you generated in step 1 to spend them.</li>
|
||
</ol>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="brainarea" class="walletarea">
|
||
<div id="braincommands" class="commands">
|
||
<div class="row">
|
||
<span id="brainlabelenterpassphrase" class="label"><label for="brainpassphrase">Enter Passphrase: </label></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" for="brainpassphraseshow">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"><label for="brainpassphraseconfirm">Confirm Passphrase: </label></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">Bitcoin Address:</span>
|
||
<span class="output" id="brainbtcaddress"></span>
|
||
</div>
|
||
</div>
|
||
<div class="private">
|
||
<div id="brainqrcodeprivate" class="qrcode_private"></div>
|
||
<div class="privwif">
|
||
<span class="label" 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 Bitcoin Private Key once the Pool has found your prefix.</div>
|
||
</div>
|
||
</div>
|
||
<div id="vanitystep2label" class="expandable" onclick="ninja.wallets.vanitywallet.openCloseStep(2);">
|
||
<span 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 Bitcoin 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="splitarea" class="walletarea">
|
||
<div id="splitcommands" class="commands " >
|
||
<label id="splitlabelthreshold">Minimum share threshold needed to combine</label>
|
||
<input type="text" id="splitthreshold" value="2" size="4"/>
|
||
<br/>
|
||
<label id="splitlabelshares">Number of shares</label>
|
||
<input type="text" id="splitshares" value="3" size="4"/>
|
||
<span><input type="button" id="splitview" value="Generate" onclick="ninja.wallets.splitwallet.splitKey();"></span>
|
||
<div id="splitstep1icon" class="more " onclick="ninja.wallets.splitwallet.openCloseStep(1);"></div>
|
||
</div>
|
||
<div id="splitstep1area"></div>
|
||
|
||
<div id="combinecommands" class="left commands">
|
||
<span>
|
||
<label id="combinelabelentershares">Enter Available Shares (whitespace separated)</label><br/>
|
||
<textarea id="combineinput" cols="60" rows="10"></textarea><br/>
|
||
</span>
|
||
<span><input type="button" id="combineview" value="Combine Shares" onclick="ninja.wallets.splitwallet.combineShares();"></span>
|
||
</div>
|
||
<div id="splitstep2area">
|
||
<div id="combineoutput">
|
||
<label id="combinelabelprivatekey">Combined Private Key</label>
|
||
<div id="combinedprivatekey" class="output"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="detailarea" class="walletarea">
|
||
<div id="detailcommands" class="commands">
|
||
<span><label id="detaillabelenterprivatekey" for="detailprivkey">Enter Private Key</label></span>
|
||
<input type="text" id="detailprivkey" value="" onfocus="this.select();" onkeypress="if (event.keyCode == 13) ninja.wallets.detailwallet.viewDetails();" />
|
||
<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 class="row extra">
|
||
<span><label id="detailkeyformats">Key Formats: WIF, WIFC, HEX, B64, B6, MINI, BIP38</label></span>
|
||
</div>
|
||
<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 Bitcoin Private Key is a unique secret number that only you know. It can be encoded in a number of different formats. Below we show the Bitcoin Address and Public Key that corresponds to your Private Key as well as your Private Key in the most popular encoding formats (WIF, WIFC, HEX, B64, MINI).</span>
|
||
<br /><br />
|
||
<span id="detaillabelnote2">Bitcoin v0.6+ stores public keys in compressed format. The client now also supports import and export of private keys with importprivkey/dumpprivkey. The format of the exported private key is determined by whether the address was generated in an old or new wallet.</span>
|
||
</div>
|
||
<div class="pubqr">
|
||
<div class="item">
|
||
<span class="label" id="detaillabelbitcoinaddress">Bitcoin 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">Bitcoin 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">'5'</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">'K' or 'L'</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 class="item" style="display: none;" id="detailb6">
|
||
<span class="label" id="detaillabelprivb6">Private Key Base6 Format (99 characters [0-5]):</span>
|
||
<span class="output" id="detailprivb6"></span>
|
||
</div>
|
||
<div class="item" style="display: none;" id="detailbip38">
|
||
<span class="label" id="detaillabelprivbip38">Private Key BIP38 Format (58 characters base58, starts with '6P'):</span>
|
||
<span class="output" id="detailprivbip38"></span>
|
||
</div>
|
||
</div>
|
||
<div class="faqs">
|
||
<div id="detailfaq1" class="faq">
|
||
<div id="detailq1" class="question" onclick="ninja.wallets.detailwallet.openCloseFaq(1);">
|
||
<span id="detaillabelq1">How do I make a wallet using dice? What is B6?</span>
|
||
<div id="detaile1" class="more"></div>
|
||
</div>
|
||
<div id="detaila1" class="answer">An important part of creating a Bitcoin wallet is ensuring the random numbers used to create the wallet are truly random. Physical randomness is better than computer generated pseudo-randomness. The easiest way to generate physical randomness is with dice. To create a Bitcoin private key you only need one six sided die which you roll 99 times. Stopping each time to record the value of the die. When recording the values follow these rules: 1=1, 2=2, 3=3, 4=4, 5=5, 6=0. By doing this you are recording the big random number, your private key, in B6 or base 6 format. You can then enter the 99 character base 6 private key into the text field above and click View Details. You will then see the Bitcoin address associated with your private key. You should also make note of your private key in WIF format since it is more widely used.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div id="footer" class="footer">
|
||
<div class="authorbtc">
|
||
<div>
|
||
<span class="item"><span id="footerlabeldonations">Donations:</span> <b>1NiNja</b>1bUmhSoTXozBRBEtR8LeF9TGbZBN</span>
|
||
<span class="item"></span>
|
||
<span class="item" id="footerlabeltranslatedby"></span>
|
||
</div>
|
||
</div>
|
||
<div class="authorpgp">
|
||
<span class="item">
|
||
<a href="pgpsignedmsg.txt" target="_blank"><span id="footerlabelversion">Version History</span> (v2.9.4)</a>
|
||
(<a href="ninja_bitaddress.org.txt" target="_blank" id="footerlabelpgp">PGP</a>)
|
||
</span>
|
||
<span class="item">527B 5C82 B1F6 B2DB 72A0<br />ECBF 8749 7B91 6397 4F5A</span>
|
||
<span class="item"><a href="https://github.com/pointbiz/bitaddress.org" target="_blank" id="footerlabelgithub">GitHub Repository</a></span>
|
||
</div>
|
||
<div class="copyright">
|
||
<span id="footerlabelcopyright1">Copyright bitaddress.org.</span>
|
||
<span id="footerlabelcopyright2">JavaScript copyrights are included in the source.</span>
|
||
<span id="footerlabelnowarranty">No warranty.</span>
|
||
</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 = {
|
||
init: (function () {
|
||
document.getElementById("generatekeyinput").value = "";
|
||
})(),
|
||
|
||
// number of mouse movements to wait for
|
||
seedLimit: (function () {
|
||
var num = Crypto.util.randomBytes(12)[11];
|
||
return 200 + Math.floor(num);
|
||
})(),
|
||
|
||
seedCount: 0, // counter
|
||
lastInputTime: new Date().getTime(),
|
||
seedPoints: [],
|
||
|
||
// 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;
|
||
var timeStamp = new Date().getTime();
|
||
// seeding is over now we generate and display the address
|
||
if (ninja.seeder.seedCount == ninja.seeder.seedLimit) {
|
||
ninja.seeder.seedCount++;
|
||
ninja.wallets.singlewallet.open();
|
||
document.getElementById("generate").style.display = "none";
|
||
document.getElementById("menu").style.visibility = "visible";
|
||
ninja.seeder.removePoints();
|
||
}
|
||
// seed mouse position X and Y when mouse movements are greater than 40ms apart.
|
||
else if ((ninja.seeder.seedCount < ninja.seeder.seedLimit) && evt && (timeStamp - ninja.seeder.lastInputTime) > 40) {
|
||
SecureRandom.seedTime();
|
||
SecureRandom.seedInt16((evt.clientX * evt.clientY));
|
||
ninja.seeder.showPoint(evt.clientX, evt.clientY);
|
||
ninja.seeder.seedCount++;
|
||
ninja.seeder.lastInputTime = new Date().getTime();
|
||
ninja.seeder.showPool();
|
||
}
|
||
},
|
||
|
||
// seed function exists to wait for mouse movement to add more entropy before generating an address
|
||
seedKeyPress: function (evt) {
|
||
if (!evt) var evt = window.event;
|
||
// seeding is over now we generate and display the address
|
||
if (ninja.seeder.seedCount == ninja.seeder.seedLimit) {
|
||
ninja.seeder.seedCount++;
|
||
ninja.wallets.singlewallet.open();
|
||
document.getElementById("generate").style.display = "none";
|
||
document.getElementById("menu").style.visibility = "visible";
|
||
ninja.seeder.removePoints();
|
||
}
|
||
// seed key press character
|
||
else if ((ninja.seeder.seedCount < ninja.seeder.seedLimit) && evt.which) {
|
||
var timeStamp = new Date().getTime();
|
||
// seed a bunch (minimum seedLimit) of times
|
||
SecureRandom.seedTime();
|
||
SecureRandom.seedInt8(evt.which);
|
||
var keyPressTimeDiff = timeStamp - ninja.seeder.lastInputTime;
|
||
SecureRandom.seedInt8(keyPressTimeDiff);
|
||
ninja.seeder.seedCount++;
|
||
ninja.seeder.lastInputTime = new Date().getTime();
|
||
ninja.seeder.showPool();
|
||
}
|
||
},
|
||
|
||
showPool: function () {
|
||
var poolHex;
|
||
if (SecureRandom.poolCopyOnInit != null) {
|
||
poolHex = Crypto.util.bytesToHex(SecureRandom.poolCopyOnInit);
|
||
document.getElementById("seedpool").innerHTML = poolHex;
|
||
document.getElementById("seedpooldisplay").innerHTML = poolHex;
|
||
}
|
||
else {
|
||
poolHex = Crypto.util.bytesToHex(SecureRandom.pool);
|
||
document.getElementById("seedpool").innerHTML = poolHex;
|
||
document.getElementById("seedpooldisplay").innerHTML = poolHex;
|
||
}
|
||
document.getElementById("mousemovelimit").innerHTML = (ninja.seeder.seedLimit - ninja.seeder.seedCount);
|
||
},
|
||
|
||
showPoint: function (x, y) {
|
||
var div = document.createElement("div");
|
||
div.setAttribute("class", "seedpoint");
|
||
div.style.top = y + "px";
|
||
div.style.left = x + "px";
|
||
document.body.appendChild(div);
|
||
ninja.seeder.seedPoints.push(div);
|
||
},
|
||
|
||
removePoints: function () {
|
||
for (var i = 0; i < ninja.seeder.seedPoints.length; i++) {
|
||
document.body.removeChild(ninja.seeder.seedPoints[i]);
|
||
}
|
||
ninja.seeder.seedPoints = [];
|
||
}
|
||
};
|
||
|
||
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",
|
||
|
||
autoDetectTranslation: function() {
|
||
// window.navigator.language for Firefox / Chrome / Opera Safari
|
||
// window.navigator.userLanguage for IE
|
||
var language = window.navigator.language || window.navigator.userLanguage;
|
||
if (!ninja.translator.translate(language)) {
|
||
// Try to remove part after dash, for example cs-CZ -> cs
|
||
language = language.substr(0, language.indexOf('-'));
|
||
ninja.translator.translate(language);
|
||
}
|
||
},
|
||
|
||
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];
|
||
}
|
||
}
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
},
|
||
|
||
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": "Bitcoin 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 bitcoins.",
|
||
"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 bitcoins.",
|
||
"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 bitcoin 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 Bitcoin:",
|
||
"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 bitcoins.",
|
||
"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 bitcoins.",
|
||
"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 bitcoin.",
|
||
"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 Bitcoin de código abierto en lado de cliente con Javascript",
|
||
"generatelabelbitcoinaddress": "Generando dirección Bitcoin...",
|
||
"generatelabelmovemouse": "Mueve un poco el ratón para crear entropía...",
|
||
"generatelabelkeypress": "OR type some random characters into this textbox", //TODO: please translate
|
||
"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 Bitcoin",
|
||
"singlelabelprivatekey": "Clave privada (formato para importar):",
|
||
"singletip1": "<b>A Bitcoin wallet</b> is as simple as a single pairing of a Bitcoin address with it's corresponding Bitcoin 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 Bitcoin 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 Bitcoin private key should be kept a secret. Whomever you share the private key with has access to spend all the bitcoins 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 bitcoins to your Bitcoin address.", //TODO: please translate
|
||
"singletip4": "<b>Check your balance</b> by going to blockchain.info or blockexplorer.com and entering your Bitcoin address.", //TODO: please translate
|
||
"singletip5": "<b>Spend your bitcoins</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 bitcoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a bitcoin 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 bitcoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining bitcoins will be stored there. Satoshi advised that one should never delete a wallet.", //TODO: please translate
|
||
"singleshare": "SHARE", //TODO: please translate
|
||
"singlesecret": "SECRET", //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 Bitcoins en mi web?",
|
||
"bulka1": "La forma tradicional de aceptar bitcoins en tu web requiere tener instalado el cliente oficial de bitcoin (\"bitcoind\"). 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 bitcoin 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 bitcoins 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 Bitcoin. Cuando el cliente elija pagar con Bitcoin, 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 bitcoin\" (o \"bitcoin 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 bitcoins 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 Bitcoin:",
|
||
"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 Bitcoin 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",
|
||
"detailkeyformats": "Key Formats: WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"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": "Bitcoin 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 Bitcoin:",
|
||
"detaillabelbitcoinaddresscomp": "Dirección Bitcoin (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 (51 caracteres en base58, empieza con un",
|
||
"detaillabelprivwifcomp": "Clave privada para importar (comprimida, 52 caracteres en base58, empieza con",
|
||
"detailcompwifprefix": "'K' o 'L'",
|
||
"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
|
||
"detaillabelq1": "How do I make a wallet using dice? What is B6?", //TODO: please translate
|
||
"detaila1": "An important part of creating a Bitcoin wallet is ensuring the random numbers used to create the wallet are truly random. Physical randomness is better than computer generated pseudo-randomness. The easiest way to generate physical randomness is with dice. To create a Bitcoin private key you only need one six sided die which you roll 99 times. Stopping each time to record the value of the die. When recording the values follow these rules: 1=1, 2=2, 3=3, 4=4, 5=5, 6=0. By doing this you are recording the big random number, your private key, in B6 or base 6 format. You can then enter the 99 character base 6 private key into the text field above and click View Details. You will then see the Bitcoin address associated with your private key. You should also make note of your private key in WIF format since it is more widely used." //TODO: please translate
|
||
},
|
||
|
||
"fr": {
|
||
// javascript alerts or messages
|
||
"testneteditionactivated": "ÉDITION TESTNET ACTIVÉE",
|
||
"paperlabelbitcoinaddress": "Adresse Bitcoin:",
|
||
"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 Bitcoins.",
|
||
"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 Bitcoins.",
|
||
"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 Bitcoin.",
|
||
"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 Bitcoin Javascript Hors-Ligne",
|
||
"generatelabelbitcoinaddress": "Création de l'adresse Bitcoin...",
|
||
"generatelabelmovemouse": "BOUGEZ votre souris pour ajouter de l'entropie...",
|
||
"generatelabelkeypress": "OR type some random characters into this textbox", //TODO: please translate
|
||
"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 Bitcoin:",
|
||
"singlelabelprivatekey": "Clé Privée (Format d'importation de porte-monnaie):",
|
||
"singletip1": "<b>A Bitcoin wallet</b> is as simple as a single pairing of a Bitcoin address with it's corresponding Bitcoin 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 Bitcoin 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 Bitcoin private key should be kept a secret. Whomever you share the private key with has access to spend all the bitcoins 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 bitcoins to your Bitcoin address.", //TODO: please translate
|
||
"singletip4": "<b>Check your balance</b> by going to blockchain.info or blockexplorer.com and entering your Bitcoin address.", //TODO: please translate
|
||
"singletip5": "<b>Spend your bitcoins</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 bitcoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a bitcoin 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 bitcoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining bitcoins will be stored there. Satoshi advised that one should never delete a wallet.", //TODO: please translate
|
||
"singleshare": "SHARE", //TODO: please translate
|
||
"singlesecret": "SECRET", //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 Bitcoins sur mon site web?",
|
||
"bulka1": "L'approche traditionnelle pour accepter des Bitcoins sur votre site web requière l'installation du logiciel Bitcoin officiel (\"bitcoind\"). Plusieurs hébergeurs ne supportent pas l'installation du logiciel Bitcoin. De plus, faire fonctionner le logiciel Bitcoin 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 Bitcoin 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 Bitcoin sur mon site web?",
|
||
"bulklabela2li1": "Utilisez le Porte-monnaie en vrac pour pré-générer une large quantité d'adresses Bitcoin (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 Bitcoin 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 Bitcoin qui seront visibles à vos visiteurs.)",
|
||
"bulklabela2li3": "Ajoutez une option dans votre panier en ligne pour que vos clients puissent vous payer en Bitcoin. Quand un client choisi de vous payer en Bitcoin, 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 \"bitcoin payment notification\" sur Google et inscrivez-vous à un service de notification de paiement Bitcoin. 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 Bitcoin 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 Bitcoins 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 Bitcoin:",
|
||
"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 Bitcoin 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",
|
||
"detailkeyformats": "Key Formats: WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"detailview": "Voir les détails",
|
||
"detailprint": "Imprimer",
|
||
"detaillabelnote1": "Votre Clé Privée Bitcoin 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 Bitcoin 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, WIFC, HEX, B64, MINI).",
|
||
"detaillabelnote2": "Bitcoin 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 Bitcoin.",
|
||
"detaillabelbitcoinaddress": "Adresse Bitcoin:",
|
||
"detaillabelbitcoinaddresscomp": "Adresse Bitcoin (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 (51 caractères base58, débute avec un a",
|
||
"detaillabelprivwifcomp": "Clé Privée WIF (compressée, 52 caractères base58, débute avec un a",
|
||
"detailcompwifprefix": "'K' ou 'L'",
|
||
"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
|
||
"detaillabelq1": "How do I make a wallet using dice? What is B6?", //TODO: please translate
|
||
"detaila1": "An important part of creating a Bitcoin wallet is ensuring the random numbers used to create the wallet are truly random. Physical randomness is better than computer generated pseudo-randomness. The easiest way to generate physical randomness is with dice. To create a Bitcoin private key you only need one six sided die which you roll 99 times. Stopping each time to record the value of the die. When recording the values follow these rules: 1=1, 2=2, 3=3, 4=4, 5=5, 6=0. By doing this you are recording the big random number, your private key, in B6 or base 6 format. You can then enter the 99 character base 6 private key into the text field above and click View Details. You will then see the Bitcoin address associated with your private key. You should also make note of your private key in WIF format since it is more widely used." //TODO: please translate
|
||
},
|
||
|
||
"el": {
|
||
// javascript alerts or messages
|
||
"testneteditionactivated": "ΕΝΕΡΓΗ ΕΚΔΟΣΗ TESTNET",
|
||
"paperlabelbitcoinaddress": "Διεύθυνση Bitcoin:",
|
||
"paperlabelprivatekey": "Προσωπικό Κλειδί (Μορφή εισαγωγής σε πορτοφόλι):",
|
||
"paperlabelencryptedkey": "Encrypted Private Key (Password required)", //TODO: please translate
|
||
"bulkgeneratingaddresses": "Δημιουργία διευθύνσεων... ",
|
||
"brainalertpassphrasetooshort": "Η φράση κωδικός που δώσατε είναι πολύ αδύναμη.\n\n",
|
||
"brainalertpassphrasewarning": "Προσοχή: Είναι σημαντικό να επιλέξετε μια ισχυρή φράση κωδικό που θα σας προφυλάξει από απόπειρες παραβίασής της τύπου brute force και κλοπή των bitcoins σας.",
|
||
"brainalertpassphrasedoesnotmatch": "Η φράση κωδικός και η επιβεβαίωση της δε συμφωνούν.",
|
||
"detailalertnotvalidprivatekey": "Το κείμενο που εισάγατε δεν αντιστοιχεί σε έγκυρο Προσωπικό Κλειδί",
|
||
"detailconfirmsha256": "Το κείμενο που εισάγατε δεν αντιστοιχεί σε έγκυρο Προσωπικό Κλειδί!\n\nΘα θέλατε να χρησιμοποιηθεί το κείμενο ως κωδικός για τη δημιουργία ενός Προσωπικού Κλειδιού που θα δημιουργηθεί από το SHA265 hash της φράσης κωδικού;\n\nΠροσοχή: Είναι σημαντικό να επιλέξετε έναν ισχυρό κωδικό ώστε να είναι δύσκολο να τον μαντέψει κάποιος και να κλέψει τα bitcoins σας.",
|
||
"bip38alertincorrectpassphrase": "Λάθος φράση κωδικός αποκρυπτογράφησης Προσωπικού Κλειδιού.",
|
||
"bip38alertpassphraserequired": "Απαιτείται η φράση κωδικός για το Κλειδί BIP38",
|
||
"vanityinvalidinputcouldnotcombinekeys": "Μη έγκυρη εισαγωγή. Ο συνδυασμός των κλειδιών είναι αδύνατος.",
|
||
"vanityalertinvalidinputpublickeysmatch": "Μη έγκυρη εισαγωγή. Τα Δημόσια Κλειδιά των δύο εγγραφών είναι όμοια. Πρέπει να εισάγετε δύο διαφορετικά Κλειδιά.",
|
||
"vanityalertinvalidinputcannotmultiple": "Μη έγκυρη εισαγωγή. Δεν είναι δυνατός ο πολλαπλασιασμός δύο Δημόσιων Κλειδιών. Επιλέξτε 'Πρόσθεση' για να προσθέσετε δύο Δημόσια Κλειδιά για δημιουργία μίας Διεύθυνσης Bitcoin.",
|
||
"vanityprivatekeyonlyavailable": "Διαθέσιμο μόνο κατά το συνδυασμό δύο Προσωπικών Κλειδιών",
|
||
"vanityalertinvalidinputprivatekeysmatch": "Μη έγκυρη εισαγωγή. Τα Προσωπικά Κλειδιά των δύο εγγραφών είναι όμοια. Πρέπει να εισάγετε δύο διαφορετικά Κλειδιά.",
|
||
|
||
// header and menu html
|
||
"tagline": "Δημιουργός Διευθύνσεων Bitcoin, ανοικτού κώδικα Javascript",
|
||
"generatelabelbitcoinaddress": "Δημιουργία Διεύθυνσης Bitcoin...",
|
||
"generatelabelmovemouse": "ΚΟΥΝΗΣΤΕ το ποντίκι τριγύρω για να προσθέσετε επιπλέον τυχαιότητα...",
|
||
"generatelabelkeypress": "OR type some random characters into this textbox", //TODO: please translate
|
||
"singlewallet": "Απλό Πορτοφόλι",
|
||
"paperwallet": "Χάρτινο Πορτοφόλι",
|
||
"bulkwallet": "Πολλαπλά Πορτοφόλια",
|
||
"brainwallet": "Μνημονικό Πορτοφόλι",
|
||
"vanitywallet": "Πορτοφόλι Vanity",
|
||
"detailwallet": "Λεπτομέρειες Πορτοφολιού",
|
||
|
||
// footer html
|
||
"footerlabeldonations": "Δωρεές:",
|
||
"footerlabeltranslatedby": "Μετάφραση: <a href='http://BitcoinX.gr/'><b>BitcoinX.gr</b></a> 1BitcoiNxkUPcTFxwMqxhRiPEiQRzYskf6",
|
||
"footerlabelpgp": "PGP",
|
||
"footerlabelversion": "ιστορικό εκδόσεων",
|
||
"footerlabelgithub": "Αποθετήριο GitHub",
|
||
"footerlabelcopyright1": "Copyright bitaddress.org.",
|
||
"footerlabelcopyright2": "Τα πνευματικά δικαιώματα της JavaScript περιλαμβάνονται στον κώδικα.",
|
||
"footerlabelnowarranty": "Καμία εγγύηση.",
|
||
|
||
// single wallet html
|
||
"newaddress": "Δημιουργία μιας νέας Διεύθυνσης",
|
||
"singleprint": "Εκτύπωση",
|
||
"singlelabelbitcoinaddress": "Διεύθυνση Bitcoin:",
|
||
"singlelabelprivatekey": "Προσωπικό Κλειδί (Μορφή εισαγωγής σε πορτοφόλι):",
|
||
"singletip1": "<b>A Bitcoin wallet</b> is as simple as a single pairing of a Bitcoin address with it's corresponding Bitcoin 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 Bitcoin 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 Bitcoin private key should be kept a secret. Whomever you share the private key with has access to spend all the bitcoins 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 bitcoins to your Bitcoin address.", //TODO: please translate
|
||
"singletip4": "<b>Check your balance</b> by going to blockchain.info or blockexplorer.com and entering your Bitcoin address.", //TODO: please translate
|
||
"singletip5": "<b>Spend your bitcoins</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 bitcoin p2p clients and importing your private key to the p2p client wallet. Keep in mind when you import your single key to a bitcoin 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 bitcoin address within the p2p client wallet. You must then backup the p2p client wallet and keep it safe as your remaining bitcoins will be stored there. Satoshi advised that one should never delete a wallet.", //TODO: please translate
|
||
"singleshare": "SHARE", //TODO: please translate
|
||
"singlesecret": "SECRET", //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": "Ο παραδοσιακός τρόπος για να δέχεστε bitcoins στην ιστοσελίδα σας, απαιτεί την εγκατάσταση και λειτουργία του επίσημου δαίμονα πελάτη bitcoin (\"bitcoind\"). Αρκετά πακέτα φιλοξενίας δεν υποστηρίζουν την εγκατάστασή του. Επιπλέον, η εκτέλεση του πελάτη bitcoin στον web server σας συνεπάγεται και τη φιλοξενία των προσωπικών σας κλειδιών στον ίδιο server, τα οποία μπορεί να υποκλαπούν αν ο server πέσει θύμα επίθεσης. Χρησιμοποιώντας τα Πολλαπλά Πορτοφόλια, ανεβάζετε στον server σας μόνο τις διευθύνσεις Bitcoin κι όχι τα προσωπικά κλειδιά. Με αυτό τον τρόπο δεν χρειάζεται να ανησυχείτε μήπως υποκλαπεί το πορτοφόλι σας.",
|
||
"bulklabelq2": "Πως χρησιμοποιώ τα Πολλαπλά Πορτοφόλια για να δέχομαι bitcoins στην ιστοσελίδα μου;",
|
||
"bulklabela2li1": "Χρησιμοποιήστε την καρτέλα Πολλαπλά Πορτοφόλια για να δημιουργήσετε έναν μεγάλο αριθμό διευθύνσεων Bitcoin (10.000+). Αντιγράψτε κι επικολλήστε τη λίστα των χωρισμένων με κόμμα τιμών (CSV) που δημιουργήθηκαν, σε ένα ασφαλές αρχείο στον υπολογιστή σας. Αντιγράψτε το αρχείο που δημιουργήσατε σε μια ασφαλή τοποθεσία.",
|
||
"bulklabela2li2": "Εισάγετε τις διευθύνσεις Bitcoin σε έναν πίνακα βάσης δεδομένων στον web server σας. (Μην αντιγράψετε τα προσωπικά κλειδιά ή το πορτοφόλι στον web server γιατί διακινδυνεύετε να σας τα κλέψουν. Μόνο τις διευθύνσεις Bitcoin που θα εμφανίζονται στους πελάτες.)",
|
||
"bulklabela2li3": "Παρέχετε στο καλάθι αγορών σας μια επιλογή για πληρωμή σε Bitcoin. Όταν ο πελάτης επιλέγει να πληρώσει με Bitcoin, θα εμφανίσετε σε αυτόν μια από τις διευθύνσεις από τη βάση δεδομένων, ως την «προσωπική του διεύθυνση πληρωμής» την οποία θα αποθηκεύσετε μαζί με την εντολή αγοράς.",
|
||
"bulklabela2li4": "Τώρα χρειάζεται να ειδοποιηθείτε μόλις γίνει η πληρωμή. Ψάξτε στο Google για «bitcoin payment notification» κι εγγραφείτε σε τουλάχιστο μία υπηρεσία ειδοποίησης πληρωμής. Υπάρχουν διάφορες υπηρεσίες που θα σας ειδοποιήσουν με Web υπηρεσίες, API, SMS, Email, κλπ. Όταν λάβετε την ειδοποίηση, η οποία μπορεί να αυτοματοποιηθεί προγραμματιστικά, εκτελείτε την εντολή του πελάτη. Για να ελέγξετε χειροκίνητα την πληρωμή μπορείτε να χρησιμοποιήσετε τον Block Explorer. Αντικαταστήστε το THEADDRESSGOESHERE με τη Bitcoin διεύθυνσή σας. Η επιβεβαίωση της πληρωμής ενδέχεται να διαρκέσει από δέκα λεπτά έως μία ώρα.<br />http://www.blockexplorer.com/address/THEADDRESSGOESHERE<br /><br />Μπορείτε να δείτε τις συναλλαγές που δεν έχουν επιβεβαιωθεί στο: http://blockchain.info/ <br />Θα πρέπει να δείτε τη συναλλαγή εκεί εντός 30 δευτερολέπτων.",
|
||
"bulklabela2li5": "Τα Bitcoins θα συσσωρεύονται με ασφάλεια στην αλυσίδα των μπλοκ. Χρησιμοποιήστε το αρχικό πορτοφόλι που δημιουργήσατε στο βήμα 1 για να τα ξοδέψετε.",
|
||
|
||
// brain wallet html
|
||
"brainlabelenterpassphrase": "Εισάγετε κωδικό: ",
|
||
"brainlabelshow": "Εμφάνιση;",
|
||
"brainprint": "Εκτύπωση",
|
||
"brainlabelconfirm": "Επιβεβαιώστε τον κωδικό: ",
|
||
"brainview": "Δημιουργία",
|
||
"brainalgorithm": "Αλγόριθμος: SHA256(κωδικός)",
|
||
"brainlabelbitcoinaddress": "Διεύθυνση Bitcoin:",
|
||
"brainlabelprivatekey": "Προσωπικό Κλειδί (Μορφή εισαγωγής σε πορτοφόλι):",
|
||
|
||
// vanity wallet html
|
||
"vanitylabelstep1": "Βήμα 1 - Δημιουργήστε το «Ζεύγος κλειδιών του Βήματος 1»",
|
||
"vanitynewkeypair": "Δημιουργία",
|
||
"vanitylabelstep1publickey": "Βήμα 1 Δημόσιο Κλειδί:",
|
||
"vanitylabelstep1pubnotes": "Αντιγράψτε κι επικολλήστε το παραπάνω στο πεδίο Your-Part-Public-Key στην ιστοσελίδα του Vanity Pool.",
|
||
"vanitylabelstep1privatekey": "Step 1 Προσωπικό Κλειδί:",
|
||
"vanitylabelstep1privnotes": "Αντιγράψτε κι επικολλήστε το παραπάνω Προσωπικό Κλειδί σε ένα αρχείο κειμένου. Ιδανικά, αποθηκεύστε το σε έναν κρυπτογραφημένο δίσκο. Θα το χρειαστείτε για να ανακτήσετε το Bitcoin Προσωπικό Κλειδί όταν βρεθεί το πρόθεμά σας από το Vanity Pool.",
|
||
"vanitylabelstep2calculateyourvanitywallet": "Βήμα 2 - Υπολογίστε το Vanity Πορτοφόλι σας.",
|
||
"vanitylabelenteryourpart": "Εισάγετε το Προσωπικό Κλειδί που δημιουργήσατε στο Βήμα 1 κι αποθηκεύσατε:",
|
||
"vanitylabelenteryourpoolpart": "Εισάγετε το Προσωπικό Κλειδί από το Vanity Pool:",
|
||
"vanitylabelnote1": "[ΣΗΜΕΙΩΣΗ: Το πεδίο αυτό μπορεί να δεχθεί είτε ένα Δημόσιο είτε ένα Προσωπικό Κλειδί.]",
|
||
"vanitylabelnote2": "[ΣΗΜΕΙΩΣΗ: Το πεδίο αυτό μπορεί να δεχθεί είτε ένα Δημόσιο είτε ένα Προσωπικό Κλειδί.]",
|
||
"vanitylabelradioadd": "Πρόσθεσε",
|
||
"vanitylabelradiomultiply": "Πολλαπλασίασε",
|
||
"vanitycalc": "Υπολογισμός του Πορτοφολιού Vanity",
|
||
"vanitylabelbitcoinaddress": "Vanity Διεύθυνση Bitcoin:",
|
||
"vanitylabelnotesbitcoinaddress": "Παραπάνω είναι η διεύθυνσή σας που θα πρέπει να περιλαμβάνει το επιθυμητό πρόθεμα.",
|
||
"vanitylabelpublickeyhex": "Vanity Δημόσιο Κλειδί (HEX):",
|
||
"vanitylabelnotespublickeyhex": "Παραπάνω είναι το Δημόσιο Κλειδί σε δεκαεξαδική μορφή. ",
|
||
"vanitylabelprivatekey": "Vanity Προσωπικό Κλειδί (WIF):",
|
||
"vanitylabelnotesprivatekey": "Παραπάνω είναι το Προσωπικό Κλειδί που θα φορτώσετε στο Πορτοφόλι σας. ",
|
||
|
||
// detail wallet html
|
||
"detaillabelenterprivatekey": "Εισάγετε το Προσωπικό Κλειδί",
|
||
"detailkeyformats": "Key Formats: WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"detailview": "Προβολή λεπτομερειών",
|
||
"detailprint": "Εκτύπωση",
|
||
"detaillabelnote1": "Το Bitcoin Προσωπικό Κλειδί είναι ένας μοναδικός και μυστικός αριθμός που μόνο εσείς πρέπει να γνωρίζετε, ο οποίος μπορεί να κωδικοποιηθεί σε πολλές διαφορετικές μορφές. Εμφανίζουμε παρακάτω τη διεύθυνση Bitcoin και το Δημόσιο Κλειδί, μαζί με το Προσωπικό Κλειδί, στις πιο δημοφιλείς μορφές (WIF, WIFC, HEX, B64, MINI).",
|
||
"detaillabelnote2": "Το Bitcoin v0.6+ αποθηκεύει τα Προσωπικά Κλειδιά σε συμπιεσμένη μορφή. Το πρόγραμμα υποστηρίζει επίσης εισαγωγή κι εξαγωγή των Προσωπικών Κλειδιών με τις εντολές importprivkey/dumpprivkey. Η μορφή του εξαγόμενου Προσωπικού Κλειδιού προσδιορίζεται από το αν η διεύθυνση δημιουργήθηκε σε ένα παλιό ή νέο πορτοφόλι.",
|
||
"detaillabelbitcoinaddress": "Διεύθυνση Bitcoin:",
|
||
"detaillabelbitcoinaddresscomp": "Συμπιεσμένη Διεύθυνση Bitcoin:",
|
||
"detaillabelpublickey": "Δημόσιο Κλειδί (130 χαρακτήρες [0-9A-F]):",
|
||
"detaillabelpublickeycomp": "Δημόσιο Κλειδί (Συμπιεσμένο, 66 χαρακτήρες [0-9A-F]):",
|
||
"detaillabelprivwif": "Προσωπικό Κλειδί WIF (51 χαρακτήρες base58, ξεκινάει με",
|
||
"detaillabelprivwifcomp": "Προσωπικό Κλειδί WIF (Συμπιεσμένο, 52 χαρακτήρες base58, ξεκινάει με",
|
||
"detailcompwifprefix": "'K' ή 'L'",
|
||
"detaillabelprivhex": "Προσωπικό Κλειδί Δεκαεξαδική Μορφή (64 χαρακτήρες [0-9A-F]):",
|
||
"detaillabelprivb64": "Προσωπικό Κλειδί Base64 (44 χαρακτήρες):",
|
||
"detaillabelprivmini": "Προσωπικό Κλειδί Μορφή Mini (22, 26 ή 30 χαρακτήρες, ξεκινάει με 'S'):",
|
||
"detaillabelpassphrase": "BIP38 Κωδικός",
|
||
"detaildecrypt": "Αποκωδικοποίηση BIP38",
|
||
"detaillabelq1": "How do I make a wallet using dice? What is B6?", //TODO: please translate
|
||
"detaila1": "An important part of creating a Bitcoin wallet is ensuring the random numbers used to create the wallet are truly random. Physical randomness is better than computer generated pseudo-randomness. The easiest way to generate physical randomness is with dice. To create a Bitcoin private key you only need one six sided die which you roll 99 times. Stopping each time to record the value of the die. When recording the values follow these rules: 1=1, 2=2, 3=3, 4=4, 5=5, 6=0. By doing this you are recording the big random number, your private key, in B6 or base 6 format. You can then enter the 99 character base 6 private key into the text field above and click View Details. You will then see the Bitcoin address associated with your private key. You should also make note of your private key in WIF format since it is more widely used." //TODO: please translate
|
||
},
|
||
|
||
"it": {
|
||
// javascript alerts or messages
|
||
"testneteditionactivated": "TESTNET EDITION ATTIVATO",
|
||
"paperlabelbitcoinaddress": "Indirizzo Bitcoin:",
|
||
"paperlabelprivatekey": "Chiave privata (Wallet Import Format):",
|
||
"paperlabelencryptedkey": "Chiave privata criptata (password richiesta)",
|
||
"bulkgeneratingaddresses": "Generazione indirizzi... ",
|
||
"brainalertpassphrasetooshort": "La passphrase inserita è troppo corta.\n\n",
|
||
"brainalertpassphrasewarning":"Attenzione: La scelta di una passphrase robusta è importante per evitare attacchi brute force in grado di indovinare la tua passphrase e rubare i tuoi Bitcoin",
|
||
"brainalertpassphrasedoesnotmatch": "La passphrase non combacia con quella data per la conferma.",
|
||
"detailalertnotvalidprivatekey": "Il testo inserito non rappresenta una Chiave Privata valida",
|
||
"detailconfirmsha256": "Il testo inserito non rappresenta una Chiave privata valida!\n\nVorresti usare il testo inserito come passphrase e creare da questa un hash SHA256 e generare così una Chiave Privata?\n\nAvvertenza: La scelta di una passphrase robusta è importante per evitare che attacchi di tipo \"brute force\" vadano a segno indovinando il testo segreto e di conseguenza far perdere i Bitcoin.",
|
||
"bip38alertincorrectpassphrase": "Passphrase non corretta per questa chiave privata criptata.",
|
||
"bip38alertpassphraserequired": "Passphrase richiesta per chiave BIP38",
|
||
"vanityinvalidinputcouldnotcombinekeys": "Dati inseriti non validi. Le chiavi non possono essere combinate.",
|
||
"vanityalertinvalidinputpublickeysmatch": "Dati inseriti non validi. Entrambe le chiavi pubbliche combaciano. Devi inserire due chiavi differenti.",
|
||
"vanityalertinvalidinputcannotmultiple": "Dati inseriti non validi. Impossibile moltiplicare due chiavi pubbliche. Seleziona 'Aggiungi' per inserire due chiavi pubbliche ed ottenere l'indirizzo Bitcoin.",
|
||
"vanityprivatekeyonlyavailable": "Non disponibile quando vengono combinate due chiavi private",
|
||
"vanityalertinvalidinputprivatekeysmatch": "Dati inseriti non validi. Entrambe le chiavi private combaciano. Devi inserire due chiavi differenti.",
|
||
|
||
// header and menu html
|
||
"tagline": "Open Source JavaScript Client-Side Bitcoin Wallet Generator",
|
||
"generatelabelbitcoinaddress": "Generazione Indirizzo Bitcoin...",
|
||
"generatelabelmovemouse": "MUOVI il tuo mouse per contribuire alla generazione dei numeri casuali...",
|
||
"generatelabelkeypress": "OR type some random characters into this textbox", //TODO: please translate
|
||
"singlewallet": "Singolo portafoglio",
|
||
"paperwallet": "Paper Wallet",
|
||
"bulkwallet": "Portafogli multipli",
|
||
"brainwallet": "Brain Wallet",
|
||
"vanitywallet": "Vanity Wallet",
|
||
"detailwallet": "Dettagli portafoglio",
|
||
|
||
// footer html
|
||
"footerlabeldonations": "Donazioni:",
|
||
"footerlabeltranslatedby": "",
|
||
"footerlabelpgp": "PGP",
|
||
"footerlabelversion": "Cronologia Versioni",
|
||
"footerlabelgithub": "Repository GitHub",
|
||
"footerlabelcopyright1": "Copyright bitaddress.org.",
|
||
"footerlabelcopyright2": "Le note di copyright dei file JavaScript sono inclusi nei sorgenti stessi.",
|
||
"footerlabelnowarranty": "Nessuna garanzia.",
|
||
|
||
// single wallet html
|
||
"newaddress": "Genera un Nuovo Indirizzo",
|
||
"singleprint": "Stampa",
|
||
"singlelabelbitcoinaddress": "Indirizzo Bitcoin:",
|
||
"singlelabelprivatekey": "Chiave privata (Wallet Import Format):",
|
||
"singletip1": "<b>Un portafogli bitcoin</b> è composto semplicemente da una coppia di valori: l'indirizzo e la sua chiave privata. Un portafogli è stato appena generato sul tuo browser e mostrato sopra.",
|
||
"singletip2": "<b>Per mettere in sicurezza questo portafogli</b> devi stampare o quantomeno salvare l'indirizzo bitcoin e la Chiave privata. È molto importante fare una copia di backup della chiave privata e conservarla in un posto sicuro. Questo sito non conosce la tua chiave privata. Se hai familiarità con PGP, puoi scaricare per intero questa pagina HTML e controllare la sua autentiticità. Puoi confrontare il codice SHA1 della pagina scaricata con il codice firmato dall'autore che trovi nella cronologia delle versioni (in fondo alla pagina). Se abbandoni/aggiorni la pagina web oppure premi il tasto Genera, un nuovo indirizzo sostituirà quello vecchio che non potrà più essere recuperato. La chiave privata dovrebbe essere tenuta segreta, chiunque conosca la chiave privata può avere accesso e spendere i tuoi bitcoin. Se stampi il tuo portafogli conservalo in una busta di plastica sigillata per tenerla al riparo dall'acqua. Tratta quanto stampato alla stregua di una banconota.",
|
||
"singletip3": "<b>Ricevi fondi</b> su questo portafogli mostrando l'indirizzo bitcoin per il versamento.",
|
||
"singletip4": "<b>Controlla il saldo</b> visitando blockchain.info o blockexplorer.com cercando il tuo indirizzo bitcoin.",
|
||
"singletip5": "<b>Spendi i tuoi bitcoin</b> aprendo un account su blockchain.info usando la chiave privata. Puoi anche spendere i tuoi bitcoin scaricando il popolare client p2p ed importando in esso il portafogli. Tieni presente che quando importi una chiave nel client p2p, nel momento in cui spendi le monete, la chiave viene raggruppata insieme alle altre presenti nel programma con i restanti bitcoin. Quando esegui una transazione gli spiccioli verranno invitati verso un altro indirizzo all'interno del tuo portafogli gestito dal client p2p. Quindi dovresti tenere un backup del portafogli contenuto nel client p2p e tenere questo in un posto sicuro fin tanto terrai dei bitcoin lì. Satoshi consiglia di non cancellare mai un portafogli. ",
|
||
"singleshare": "SHARE", //TODO: please translate
|
||
"singlesecret": "SECRET", //TODO: please translate
|
||
|
||
// paper wallet html
|
||
"paperlabelhideart": "Senza grafica?",
|
||
"paperlabeladdressesperpage": "Indirizzi per pagina:",
|
||
"paperlabeladdressestogenerate": "Indirizzi da generare:",
|
||
"papergenerate": "Genera",
|
||
"paperprint": "Stampa",
|
||
"paperlabelBIPpassphrase": "Passphrase:",
|
||
"paperlabelencrypt": "BIP38 criptato?",
|
||
|
||
// bulk wallet html
|
||
"bulklabelstartindex": "Indice iniziale:",
|
||
"bulklabelrowstogenerate": "Righe da generare:",
|
||
"bulklabelcompressed": "Indirizzo compresso?",
|
||
"bulkgenerate": "Genera",
|
||
"bulkprint": "Stampa",
|
||
"bulklabelcsv": "Valori Separati da virgola:",
|
||
"bulklabelformat": "Indice,Indirizzo,Chiave Privata (WIF)",
|
||
"bulklabelq1": "Perché dovrei usare tanti portafogli per accettare Bitcoin sul mio sito web?",
|
||
"bulka1": "Il tradizionale approcio per accettare i Bitcoin è quello di installare il demone ufficiale Bitcoin (\"bitcoind\"). Molti pacchetti di hosting web non supportano l'installazione di tale demone. Inoltre tenere in esecuzione il demone richiede che la chiave privata del portafogli sia custodita sul server, se questo viene violato tramite hacking puoi perdere tutti i Bitcoin. Usando portafogli multipli puoi caricare sul server solo l'indirizzo per il versamento e non la chiave privata. Quindi non devi preoccuparti del tuo portafogli nel caso in cui il server venga violato con un attacco di hacking.",
|
||
"bulklabelq2": "Come utilizzo tutti questi portafogli per accettare Bitcoin sul mio sito web?",
|
||
"bulklabela2li1": "Usa la funzione \"Portafogli multipli\" per generare una grande quantità di indirizzi Bitcoin (10,000+). Copia e incolla la lista generata in formato CSV (campi separati da virgola) su un file, al sicuro nel tuo computer. Fai una copia di backup di questo file e mettilo un posto sicuro.",
|
||
"bulklabela2li2": "Importa gli indirizzi Bitcoin in una tabella del database sul tuo web server. (Non importare i portafogli/chiavi private sul web server, altrimenti corri il rischio che rubino i tuoi Bitcoin con l'hacking. Usa gli indirizzi Bitcoin così come verranno mostrati ai tuoi clienti.)",
|
||
"bulklabela2li3": "Fornisci una opzione nel carrello del tuo sito web per pagare in Bitcoin. Quando il cliente sceglie di pagare in Bitcoin, gli mostrerai un indirizzo dal tuo database come \"indirizzo di pagamento\" e conserverai questo stesso indirizzo insieme ai dati dell'ordine.",
|
||
"bulklabela2li4": "Ora hai bisogno di notificare l'arrivo del pagamento. Cerca su Google \"notifiche pagamento Bitcoin\" ed iscriviti ad almeno un servizio di notifica. Esistono diversi servizi che possono notificare in vari modi come Web Services, API, SMS, Email, etc. Una volta ricevuta la notifica, la quale può essere automatizzata con la programmazione, puoi processare l'ordine del cliente. Per verificare manualmente se l'ordine è davvero arrivato puoi usare un block explorer. Sostituisci INDIRIZZODACONTROLLARE con l'indirizzo Bitcoin da controllare. Possono volerci dai 10 fino a 60 minuti per fare in modo che una transazione venga confermata.<br>http://www.blockexplorer.com/address/INDIRIZZODACONTROLLARE<br><br>Le transazioni non confermate possono essere visionate su: http://blockchain.info/ <br>Dovresti vedere la transazione entro 30 secondi.",
|
||
"bulklabela2li5": "In questo modo i Bitcoin transiteranno nella blockchain in tutta sicurezza. Usa il portafogli creato nel Passo 1 per spendere i Bitcoin.",
|
||
|
||
// brain wallet html
|
||
"brainlabelenterpassphrase": "Inserisci la Passphrase: ",
|
||
"brainlabelshow": "Mostra?",
|
||
"brainprint": "Stampa",
|
||
"brainlabelconfirm": "Conferma Passphrase: ",
|
||
"brainview": "Visiona",
|
||
"brainalgorithm": "Algoritmo: SHA256(passphrase)",
|
||
"brainlabelbitcoinaddress": "Indirizzo Bitcoin:",
|
||
"brainlabelprivatekey": "Chiave privata (Wallet Import Format):",
|
||
|
||
// vanity wallet html
|
||
"vanitylabelstep1": "Passo1 1 - Genera la tua Coppia di chiavi",
|
||
"vanitynewkeypair": "Genera",
|
||
"vanitylabelstep1publickey": "Passo 1 Chiave pubblica:",
|
||
"vanitylabelstep1pubnotes": "Copia e incolla il testo soprastante nel campo \"chiave-pubblica-parziale\" sul sito web del pool.",
|
||
"vanitylabelstep1privatekey": "Passo 1 Chiave pubblica:",
|
||
"vanitylabelstep1privnotes": "Copia & incolla la Chiave privata soprastante su un file di testo. Idealmente conservalo su un disco criptato. Ti servirà per recuperare la Chiave privata una volta che il Pool avrà trovato quella col prefisso scelto.",
|
||
"vanitylabelstep2calculateyourvanitywallet": "Passo 2 - Calcolo del Vanity Wallet",
|
||
"vanitylabelenteryourpart": "Inserisci la tua Chiave Privata parziale (Generata nel Passo 1 e precedentemente salvata):",
|
||
"vanitylabelenteryourpoolpart": "Inserisci la Chiave privata parziale generata dal pool (dal Vanity Pool):",
|
||
"vanitylabelnote1": "[NOTA: questo campo può accettare sia chiavi pubbliche che private]",
|
||
"vanitylabelnote2": "[NOTA: questo campo può accettare sia chiavi pubbliche che private]",
|
||
"vanitylabelradioadd": "Aggiungi",
|
||
"vanitylabelradiomultiply": "Moltiplica",
|
||
"vanitycalc": "Calcola Vanity Wallet",
|
||
"vanitylabelbitcoinaddress": "Indirizzo del Vanity Wallet:",
|
||
"vanitylabelnotesbitcoinaddress": "Sopra trovi il tuo nuovo indirizzo che dovrebbe includere il prefisso che hai scelto.",
|
||
"vanitylabelpublickeyhex": "Chiave pubblica del Vanity Wallet (HEX):",
|
||
"vanitylabelnotespublickeyhex": "Quella sopra è la Chiave Pubblica nel formato esadecimale. ",
|
||
"vanitylabelprivatekey": "Chiave privata del Vanity Wallet (WIF):",
|
||
"vanitylabelnotesprivatekey": "Quella sopra è la Chiave Privata nel formato esadecimale. ",
|
||
|
||
// detail wallet html
|
||
"detaillabelenterprivatekey": "Inserisci la Chiave Privata",
|
||
"detailkeyformats": "Key Formats: WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"detailview": "Mostra Dettagli",
|
||
"detailprint": "Stampa",
|
||
"detaillabelnote1": "La tua Chiave privata Bitcoin è rappresentata da un numero segreto, unico al mondo, che dovresti conoscere soltanto tu. Può essere codificato in molti formati differenti. Di seguito verrà mostrato l'indirizzo Bitcoin e la chiave pubblica, con la corrispondente chiave privata, nei più diffusi formati di codifica (WIF, WIFC, HEX, B64, MINI).",
|
||
"detaillabelnote2": "Il client Bitcoin, dalla versione v0.6, memorizza le chiavi pubbliche in formato compresso. Il programma ora supporta l'importazione e l'esportazione delle chiavi private attraverso importprivkey/dumpprivkey. Il formato con cui viene esportata la chiave privata dipende se l'indirizzo generato è stato creato con il nuovo o vecchio portafogli.",
|
||
"detaillabelbitcoinaddress": "Indirizzo Bitcoin",
|
||
"detaillabelbitcoinaddresscomp": "Indirizzo Bitcoin compresso",
|
||
"detaillabelpublickey": "Chiave pubblica (130 caratteri [0-9A-F]):",
|
||
"detaillabelpublickeycomp": "Chiave pubblica (compressa, 66 caratteri [0-9A-F]):",
|
||
"detaillabelprivwif": "Chiave privata WIF<br>51 caratteri base58, inizia per a",
|
||
"detaillabelprivwifcomp": "Chiave privata WIF compressa<br>52 caratteri base58, inizia per 'a'",
|
||
"detailcompwifprefix": "'K' o 'L'",
|
||
"detaillabelprivhex": "Chiave privata formato esadecimale (64 caratteri [0-9A-F]):",
|
||
"detaillabelprivb64": "Chiave privata Base64 (44 caratteri):",
|
||
"detaillabelprivmini": "Chiave privata formato mini (22, 26 or 30 caratteri, inizia per 'S'):",
|
||
"detaillabelpassphrase": "Inserisci passphrase BIP38",
|
||
"detaildecrypt": "Decripta BIP38",
|
||
"detaillabelq1": "How do I make a wallet using dice? What is B6?", //TODO: please translate
|
||
"detaila1": "An important part of creating a Bitcoin wallet is ensuring the random numbers used to create the wallet are truly random. Physical randomness is better than computer generated pseudo-randomness. The easiest way to generate physical randomness is with dice. To create a Bitcoin private key you only need one six sided die which you roll 99 times. Stopping each time to record the value of the die. When recording the values follow these rules: 1=1, 2=2, 3=3, 4=4, 5=5, 6=0. By doing this you are recording the big random number, your private key, in B6 or base 6 format. You can then enter the 99 character base 6 private key into the text field above and click View Details. You will then see the Bitcoin address associated with your private key. You should also make note of your private key in WIF format since it is more widely used." //TODO: please translate
|
||
},
|
||
|
||
"de": {
|
||
// javascript alerts or messages
|
||
"testneteditionactivated": "TESTNET AKTIVIERT",
|
||
"paperlabelbitcoinaddress": "Bitcoin-Adresse:",
|
||
"paperlabelprivatekey": "Privater Schlüssel (Wallet Import Format):",
|
||
"paperlabelencryptedkey": "Verschlüsselter privater Schlüssel (Passwort benötigt)",
|
||
"bulkgeneratingaddresses": "Adressen erstellen... ",
|
||
"brainalertpassphrasetooshort": "Die eingegebene Passphrase ist zu kurz.\n\n",
|
||
"brainalertpassphrasewarning": "Hinweis: Eine längere Passphrase schützt besser vor Brute-Force-Attacken, bei denen auf gut Glück Passphrasen probiert werden.",
|
||
"brainalertpassphrasedoesnotmatch": "Die beiden Passphrasen stimmen nicht überein.",
|
||
"detailalertnotvalidprivatekey": "Der eingegebene Text ist kein gültiger privater Schlüssel.",
|
||
"detailconfirmsha256": "Der eingegebene Text ist kein gültiger privater Schlüssel!\n\nMöchtest du den eingegebenen Text als Passphrase verwenden, um mithilfe dessen SHA256-Hash einen privaten Schlüssel zu erstellen?\n\nHinweis: Eine längere Passphrase schützt besser vor Brute-Force-Attacken, bei denen auf gut Glück Passphrasen probiert werden.",
|
||
"bip38alertincorrectpassphrase": "Falsches Passwort",
|
||
"bip38alertpassphraserequired": "Bitte Passwort eingeben.",
|
||
"vanityinvalidinputcouldnotcombinekeys": "Unzulässige Eingaben. Die Schlüssel konnten nicht kombiniert werden.",
|
||
"vanityalertinvalidinputpublickeysmatch": "Unzulässige Eingaben. Die eingegebenen öffentlichen Schlüssel stimmen überein. Bitte gib zwei unterschiedliche Schlüssel ein.",
|
||
"vanityalertinvalidinputcannotmultiple": "Unzulässige Eingaben. Zwei öffentliche Schlüssel können nicht miteinander multipliziert werden. Wähle \"Addieren\" aus, um aus zwei öffentlichen Schlüsseln eine Bitcoin-Adresse zu erstellen.",
|
||
"vanityprivatekeyonlyavailable": "Nur verfügbar, wenn zwei private Schlüssel kombiniert werden.",
|
||
"vanityalertinvalidinputprivatekeysmatch": "Unzulässige Eingaben. Die eingegebenen privaten Schlüssel stimmen überein. Bitte gib zwei unterschiedliche Schlüssel ein.",
|
||
|
||
// header and menu html
|
||
"tagline": "Offener, client-seitiger Bitcoin-Wallet-Generator in JavaScript",
|
||
"generatelabelbitcoinaddress": "Erstelle Bitcoin-Wallet...",
|
||
"generatelabelmovemouse": "Bewege deine Maus umher, um die Zufälligkeit zu erhöhen...",
|
||
"generatelabelkeypress": "OR type some random characters into this textbox", //TODO: please translate
|
||
"singlewallet": "Einzelnes Wallet",
|
||
"paperwallet": "Papier-Wallet",
|
||
"bulkwallet": "Massen-Wallet",
|
||
"brainwallet": "Kopf-Wallet",
|
||
"vanitywallet": "Personalisiertes Wallet",
|
||
"detailwallet": "Walletdetails",
|
||
|
||
// footer html
|
||
"footerlabeldonations": "Spenden:",
|
||
"footerlabeltranslatedby": "Übersetzung: 1EWPcmYmU8MamRUYMFWQa1r7A2Tskz78t5",
|
||
"footerlabelpgp": "PGP",
|
||
"footerlabelversion": "Versionsgeschichte",
|
||
"footerlabelgithub": "GitHub-Repository",
|
||
"footerlabelcopyright1": "Copyright bitaddress.org.",
|
||
"footerlabelcopyright2": "JavaScript-Copyrights sind im Quelltext enthalten.",
|
||
"footerlabelnowarranty": "Ohne Gewähr.",
|
||
|
||
// single wallet html
|
||
"newaddress": "Neues Wallet erstellen",
|
||
"singleprint": "Drucken",
|
||
"singlelabelbitcoinaddress": "Bitcoin-Adresse",
|
||
"singlelabelprivatekey": "Privater Schlüssel (WIF – zum Importieren geeignet):",
|
||
"singletip1": "<b>Ein Bitcoin-Wallet </b>(Geldbörse) ist nichts anderes als eine Bitcoin-Adresse (öffentlicher Schlüssel) und der zu ihr gehörende private Schlüssel. Oben findest du ein solches, gerade für dich erstelltes Wallet, bestehend aus den beiden Zeichenketten. Die QR-Codes dienen lediglich der Vereinfachung und enthalten kodiert die Adresse bzw. den privaten Schlüssel.",
|
||
"singletip2": "<b>Um dieses Wallet zu schützen,</b> musst du es entweder ausdrucken oder anderweitig die Bitcoin-Adresse und den privaten Schlüssel sichern. Fertige auf jeden Fall eine Kopie des privaten Schlüssels an und bewahre sie an einem sicheren Ort auf. Der private Schlüssel liegt nur lokal auf deinem Rechner vor und wurde nicht ins Internet übertragen. Falls du dich mit PGP auskennst, kannst du dir diese all-in-one HTML-Seite herunterladen. Um zu überprüfen, ob die heruntergeladene Version authentisch ist, kannst du den SHA1-Hash dieser Seite mit dem SHA1-Hash in der signierten Versionsgeschichte am unteren Ende dieser Seite abgleichen. Wenn du diese Seite verlässt, sie neulädst bzw. den \"Neues Wallet erstellen\"-Button drückst, wird ein neues Wallet erstellt und das vorherige wird nicht mehr abrufbar sein. Du solltest deinen privaten Schlüssel geheim halten. Wer den privaten Schlüssel hat, kann damit auf alle im Wallet befindlichen Bitcoin zugreifen und sie nach Belieben ausgeben. Behandle dein gedrucktes Wallet wie echtes Geld!",
|
||
"singletip3": "Du kannst <b>Guthaben</b> zu deinem Wallet <b>hinzufügen</b>, indem du genau wie bei anderen Überweisungen Bitcoins an die Bitcoin-Adresse deines Wallets schickst.",
|
||
"singletip4": "<b>Überprüfe dein Guthaben,</b> indem du deine Bitcoin-Adresse auf blockchain.info bzw. blockexplorer.com eingibst.",
|
||
"singletip5": "Du kannst deine <b>Bitcoins ausgeben</b>, indem du das gesamte mit deinem privaten Schlüssel verbundene Guthaben auf deinen Account bei blockchain.info überträgst. Alternativ kannst du dir ein Bitcoinprogramm herunterladen und deinen privaten Schlüssel in dieses importieren. Beachte dabei aber, dass, sobald du Bitcoins mit dem Programm sendest, dein privater Schlüssel mit den anderen privaten Schlüsseln, die vom Programm bereitgestellt werden, verbunden wird. Bei einer Überweisung wird etwas Rückgeld an eine der Bitcoin-Adressen des Programms geschickt. Deswegen musst du, um tatsächlich dein gesamtes Guthaben zu sichern, ein Backup vom gesamten Wallet des Programms, das nun auch deinen importierten privaten Schlüssel enthält, anfertigen. Satoshi rät, dass man unter keinen Umständen ein Wallet löschen sollte.",
|
||
"singleshare": "SHARE", //TODO: please translate
|
||
"singlesecret": "SECRET", //TODO: please translate
|
||
|
||
// paper wallet html
|
||
"paperlabelhideart": "Grafische Gestaltung ausblenden?",
|
||
"paperlabeladdressesperpage": "Adressen je Seite:",
|
||
"paperlabeladdressestogenerate": "Anzahl zu erstellender Adressen:",
|
||
"papergenerate": "Erstellen",
|
||
"paperprint": "Drucken",
|
||
"paperlabelBIPpassphrase": "Passwort:",
|
||
"paperlabelencrypt": "Mit BIP38 verschlüsseln?",
|
||
|
||
// bulk wallet html
|
||
"bulklabelstartindex": "Startindex:",
|
||
"bulklabelrowstogenerate": "Zu erstellende Adressen:",
|
||
"bulklabelcompressed": "Adressen komprimieren?",
|
||
"bulkgenerate": "Erstellen",
|
||
"bulkprint": "Drucken",
|
||
"bulklabelcsv": "Comma Separated Values (CSV):",
|
||
"bulklabelformat": "Index, Adresse, privater Schlüssel (WIF)",
|
||
"bulklabelq1": "Warum sollte ich ein Massen-Wallet auf meiner Webseite einsetzen?",
|
||
"bulka1": "Bisher musste immer der offizielle Bitcoin-Daemon, bitcoind, auf dem Server installiert sein, damit man Bitcoins auf seiner Webseite annehmen konnte. Viele Webhoster blockieren die Installation von bitcoind. Außerdem müssen die privaten Schlüssel auf dem Server liegen, damit bitcoind funktioniert, obwohl sie dort einfacher gestohlen werden können. Mit einem Massen-Wallet brauchst du nur noch die Bitcoin-Adressen und nicht mehr zusätzlich die privaten Schlüssel hochladen. Dadurch musst du dir keine Sorgen mehr machen, dass dein Bitcoin-Wallet gestohlen werden könnte, wenn unberechtigt in deinen Server eingedrungen wird.",
|
||
"bulklabelq2": "Wie kann ich ein Massen-Wallet in meine Webseite integrieren?",
|
||
"bulklabela2li1": "Erstelle mithilfe dieser Seite ganz viele Bitcoin-Adressen (10.000+). Kopiere die CSV-Liste in eine sichere Textdatei auf deinem Computer. Fertige ein Backup dieser Datei an und speichere sie an einem sicheren Ort.",
|
||
"bulklabela2li2": "Importiere die Bitcoin-Adressen in eine Datenbank auf deinem Server. (Lege nur die Bitcoin-Adressen, nicht aber die privaten Schlüssel auf deinem Server ab!)",
|
||
"bulklabela2li3": "Biete deinen Kunden auf deiner Webseite Bitcoin als Zahlungsmöglichkeit an. Wenn ein Kunde mit Bitcoin zahlen möchte, zeige ihm eine der Adressen aus deiner Datenbank als Zahlungsadresse an und speichere sie mit seiner Bestellung.",
|
||
"bulklabela2li4": "Jetzt musst du dir den Zahlungseingang bestätigen lassen. Google \"bitcoin payment notification\" und melde dich bei mindestens einem solchen Anbieter an. Es gibt verschiedene Anbieter, die dich via Web, API, SMS, E-Mail etc. über erfolgte Transaktionen informieren können. Sobald du die Eingangsbestätigung erhälst, kannst du automatisch die Bestellung abwickeln lassen. Um selber zu schauen, ob eine Zahlung erfolgt ist, kannst du Block Explorer nutzen. Ersetze BITCOINADRESSE durch die Bitcoin-Adresse, die du prüfen möchtest. Es dauert von zehn Minuten bis zu einer Stunde, um Transaktionen zu bestätigen. <br />http://www.blockexplorer.com/address/BITCOINADRESSE<br /> <br />Unbestätigte Transaktionen findest du hier: http://blockchain.info/ <br /> Sämtliche Transaktionen sollten dort innerhalb von 30 Sekunden auftauchen.",
|
||
"bulklabela2li5": "Deine Bitcoins werden sicher in die Block-Chain aufgenommen. Mithilfe des ursprünglichen Wallets vom ersten Schritt kannst du sie ausgeben.",
|
||
|
||
// brain wallet html
|
||
"brainlabelenterpassphrase": "Passphrase eingeben:",
|
||
"brainlabelshow": "Aufdecken?",
|
||
"brainprint": "Drucken",
|
||
"brainlabelconfirm": "Passphrase wiederholen:",
|
||
"brainview": "Zugehöriges Wallet anzeigen",
|
||
"brainalgorithm": "Algorithmus: SHA256 (Passphrase)",
|
||
"brainlabelbitcoinaddress": "Bitcoin-Adresse:",
|
||
"brainlabelprivatekey": "Privater Schlüssel (WIF):",
|
||
|
||
// vanity wallet html
|
||
"vanitylabelstep1": "Schritt 1 - Erstelle dein Schlüsselpaar",
|
||
"vanitynewkeypair": "Erstellen",
|
||
"vanitylabelstep1publickey": "Öffentlicher Schlüssel:",
|
||
"vanitylabelstep1pubnotes": "Kopiere den obigen öffentlichen Schlüssel in das \"Your public key\"-Feld auf der Webseite von Vanity Pool.",
|
||
"vanitylabelstep1privatekey": "Privater Schlüssel (Your Part Private Key):",
|
||
"vanitylabelstep1privnotes": "Speichere den obigen privaten Schlüssel in einer Textdatei, die du am besten auf einem verschlüsselten Laufwerk sicherst. Sobald der Vanity-Pool deine personalisierte Bitcoin-Adresse gefunden hat, kannst du den zu ihr gehörenden privaten Schlüssel nur mithilfe des vom Pools berechneten privaten Schlüssels (Pool Part Private Key) und des obigen privaten Schlüssels (Your Part Private Key) erhalten. Beide privaten Schlüssel (Pool und Your) werden zum Berechnen des privaten Schlüssels deiner personalisierten Bitcoin-Adresse benötigt, damit wirklich nur jemand, der beide besitzt, das personalisierte Wallet nutzen kann.",
|
||
"vanitylabelstep2calculateyourvanitywallet": "Schritt 2 - Berechne dein personalisiertes Wallet",
|
||
"vanitylabelenteryourpart": "Gib hier deinen privaten Schlüssel von oben ein (Your Part Private Key):",
|
||
"vanitylabelenteryourpoolpart": "Gib hier den von Vanity-Pool erhaltenen privaten Schlüssel ein (Pool Part Private Key):",
|
||
"vanitylabelnote1": "[HINWEIS: Dieses Eingabefeld nimmt sowohl öffentlich als auch private Schlüssel an.]",
|
||
"vanitylabelnote2": "[HINWEIS: Dieses Eingabefeld nimmt sowohl öffentlich als auch private Schlüssel an.]",
|
||
"vanitylabelradioadd": "Addieren",
|
||
"vanitylabelradiomultiply": "Multiplizieren",
|
||
"vanitycalc": "Personalisiertes Wallet berechnen",
|
||
"vanitylabelbitcoinaddress": "Personalisierte Bitcoin-Adresse:",
|
||
"vanitylabelnotesbitcoinaddress": "Die obige Bitcoin-Adresse sollte den gewünschten Präfix enthalten.",
|
||
"vanitylabelpublickeyhex": "Personalisierter öffentlicher Schlüssel (HEX):",
|
||
"vanitylabelnotespublickeyhex": "Die obige Zeichenfolge ist der öffentliche Schlüssel (Bitcoin-Adresse) im Hexadezimalformat.",
|
||
"vanitylabelprivatekey": "Personalisierter privater Schlüssel (WIF):",
|
||
"vanitylabelnotesprivatekey": "Der obige private Schlüssel ermöglicht das Importieren in andere Wallets.",
|
||
|
||
// detail wallet html
|
||
"detaillabelenterprivatekey": "Privaten Schlüssel eingeben:",
|
||
"detailkeyformats": "Unterstützte Formate: WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"detailview": "Details anzeigen",
|
||
"detailprint": "Drucken",
|
||
"detaillabelnote1": "Der private Schlüssel deines Wallets ist eine geheime, einzigartige Zeichenfolge, die nur du kennst. Er kann auf mehrer Arten dargestellt werden. Unten findest du die zugehörige Bitcoin-Adresse bzw. öffentlichen Schlüssel sowie den privaten Schlüssel in den verbreitetsten Formaten.",
|
||
"detaillabelnote2": "Ab Version 0.6 speichert Bitcoin-qt öffentliche Schlüssel komprimiert. Das Programm unterstützt nun auch den Import und Export von privaten Schlüsseln mit importprivkey/dumpprivkey. Das Format des exportierten privaten Schlüssels hängt davon ab, ob die Adresse in einem alten oder neuen Wallet erstellt wurde.",
|
||
"detaillabelbitcoinaddress": "Bitcoin-Adresse:",
|
||
"detaillabelbitcoinaddresscomp": "Komprimierte Bitcoin-Adresse:",
|
||
"detaillabelpublickey": "Öffentlicher Schlüssel (130 Zeichen [0-9A-F]):",
|
||
"detaillabelpublickeycomp": "Komprimierter öffentlicher Schlüssel (66 Zeichen [0-9A-F]):",
|
||
"detaillabelprivwif": "Privater Schlüssel WIF <br /> 51 Zeichen in base58, beginnt mit",
|
||
"detaillabelprivwifcomp": "Komprimierter privater Schlüssel WIF <br /> 52 Zeichen in base58, beginnt mit",
|
||
"detailcompwifprefix": "'K' oder 'L'",
|
||
"detaillabelprivhex": "Privater Schlüssel in Hexadezimal (64 Zeichen [0-9A-F]):",
|
||
"detaillabelprivb64": "Privater Schlüssel in base64 (44 Zeichen):",
|
||
"detaillabelprivmini": "Privater Schlüssel in mini (22, 26 oder 30 Zeichen, beginnt mit 'S'):",
|
||
"detaillabelpassphrase": "Passwort für BIP38 eingeben",
|
||
"detaildecrypt": "Entschlüsseln",
|
||
"detaillabelq1": "Wie erstelle ich ein Wallet mithilfe eines Würfels? Was versteht man unter B6?",
|
||
"detaila1": "Beim Erstellen eines Bitcoin-Wallets sollten die dafür genutzten Zufallszahlen auch tatsächlich zufällig sein. Ein echter Würfel liefert wesentlich zufälligere Zahlen als ein Computer. Um einen privaten Schlüssel zu erstellen, sind lediglich 99 Würfe mit einem normalen Würfel nötig. Nach jedem Wurf solltest du die Augenzahl nach folgendem Muster aufschreiben: 1-\>1, 2-\>2, 3-\>3, 4-\>4, 5-\>5, 6-\>0. Die so entstandene Zufallszahl stellt deinen privaten Schlüssel in B6 bzw. zur Basis 6 dar. Diesen 99 Zeichen langen Basis-6-Schlüssel kannst du im obigen Eingabefeld eingeben und dir dann die zugehörigen Details anzeigen lassen. U.a. wird dir die zu deinem privaten Schlüssel gehörende Bitcoin-Adresse angezeigt. Es wäre ratsam, sich die ebenfalls berechnete WIF-Version des privaten Schlüssels zu notieren, weil sie häufiger genutzt wird."
|
||
},
|
||
|
||
"cs": {
|
||
// javascript alerts or messages
|
||
"testneteditionactivated": "TESTNET aktivován",
|
||
"paperlabelbitcoinaddress": "Bitcoin adresa:",
|
||
"paperlabelprivatekey": "Soukromý klíč (WIF – Formát pro import do peněženky):",
|
||
"paperlabelencryptedkey": "Šifrovaný soukromý klíč (Vyžadováno heslo)",
|
||
"bulkgeneratingaddresses": "Generuji adresy... ",
|
||
"brainalertpassphrasetooshort": "Zadané heslo je příliš krátké.\n\n",
|
||
"brainalertpassphrasewarning": "Varování: Je důležité zvolit silné heslo, které je odolné proti útoku hrubou silou a krádeži vašich Bitcoinů.",
|
||
"brainalertpassphrasedoesnotmatch": "Heslo nejsou stejná.",
|
||
"detailalertnotvalidprivatekey": "Zadaný text není platým soukromým klíčem",
|
||
"detailconfirmsha256": "Zadaný text není platným soukromým klíčem!\n\nChcete použít zadaný text jako heslo a vytvořit soukromý klíč pomocí SHA256?\n\nVarování: Je důležité zvolit silné heslo, které je odolné proti útoku hrubou silou a krádeži vašich Bitcoinů.",
|
||
"bip38alertincorrectpassphrase": "Špatné heslo pro BIP38",
|
||
"bip38alertpassphraserequired": "Vyžadováno heslo pro BIP38 klíč",
|
||
"vanityinvalidinputcouldnotcombinekeys": "Špatný vstup. Kombinovat klíče není možné.",
|
||
"vanityalertinvalidinputpublickeysmatch": "Špatný vstup. Veřejný klíč obou položek je shodný. Musíte zadat dva různé klíče.",
|
||
"vanityalertinvalidinputcannotmultiple": "Špatný vstup. Dva veřejné klíče není možné násobit. Zvolte 'Přidat' pro přidání dvou veřejných klíčů a získání Bitcoin adresy.",
|
||
"vanityprivatekeyonlyavailable": "Dostupné pouze při kombinaci dvou soukromých klíčů",
|
||
"vanityalertinvalidinputprivatekeysmatch": "Špatný vstup. Soukromý klíč obou položek je shodný. Musíte zadat dva různé klíče.",
|
||
|
||
// header and menu html
|
||
"tagline": "Open Source generátor Bitcoin peněženky napsaný v JavaScript",
|
||
"generatelabelbitcoinaddress": "Generuji Bitcoin adresu",
|
||
"generatelabelmovemouse": "POHYBUJTE myší pro získání dostatku náhody...",
|
||
"generatelabelkeypress": "NEBO napište několik náhodných znaků do tohoto pole",
|
||
"singlewallet": "Jedna peněženka",
|
||
"paperwallet": "Papírová peněženka",
|
||
"bulkwallet": "Hromadná peněženka",
|
||
"brainwallet": "Myšlenková peněženka",
|
||
"vanitywallet": "Peněženka Vanity",
|
||
"detailwallet": "Detail peněženky",
|
||
|
||
// footer html
|
||
"footerlabeldonations": "Příspěvek:",
|
||
"footerlabeltranslatedby": "Překlad: 1LNF2anjkH3HyRKrhMzVYqYRKFeDe2TJWz",
|
||
"footerlabelpgp": "PGP",
|
||
"footerlabelversion": "Historie verzí",
|
||
"footerlabelgithub": "GitHub Repository",
|
||
"footerlabelcopyright1": "Copyright bitaddress.org.",
|
||
"footerlabelcopyright2": "Copyright JavaScriptu je uveden ve zdrojovém kódu.",
|
||
"footerlabelnowarranty": "Bez záruky.",
|
||
|
||
// single wallet html
|
||
"newaddress": "Vytvořit novou adresu",
|
||
"singleprint": "Tisk",
|
||
"singlelabelbitcoinaddress": "Bitcoin adresa",
|
||
"singlelabelprivatekey": "Soukromý klíč (WIF – Formát pro import do peněženky):",
|
||
"singletip1": "<b>Bitcoin peněženka</b> je jednoduchý pár Bitcoin adresy s přidruženým soukromým klíčem. Taková peněženka byla právě vytvořena ve vašem prohlížeči a zobrazena výše.",
|
||
"singletip2": "<b>Pro zabezpečení této peněženky</b> musíte tuto Bitcoin adresu a soukromý klíč vytisknout a nebo jinak poznamenat. Je důležité provést zálohu soukromého klíče a jeho uschování na bezpečném místě. Tato webová stránka nemá žádné informace o vašem soukromém klíči. Pokud ovládáte PGP, můžete celou tuto stránku stáhnout v jednom HTML souboru a ověřit její pravost srovnáním SHA1 hashe s podepsaným dokumentem historie verzí. Odkaz naleznete v patičce této stránky. Pokud opustíte či obnovíte tuto stránku nebo kliknete na 'Vytvořit novou adresu' dojde k vygenerování nového soukromého klíče a předtím zobrazený klíč bude ztracen. Váš soukromý klíč musíte uchovat v tajnosti. Každý kdo má tento klíč k dispozici může utratit všechny peníze v této peněžence. Pokud budete peněženku tisknout, uzavřete ji do nepropustného obalu nebo ji zalaminujte. Tím zabráníte jejímu poškození vodou. Chovejte se k této peněžence jako k normálním bankovkám.",
|
||
"singletip3": "<b>Pro vložení</b> peněz do této peněženky stačí zaslat peníze na Bitcoin adresu.",
|
||
"singletip4": "<b>Zkontrolovat zůstatek</b> můžete na webové stránce blockchain.info nebo blockexplorer.com po zadání Bitcoin adresy.",
|
||
"singletip5": "<b>Utratit Bitcoiny</b> můžete pomocí blockchain.info načtením celého zůstatku pomocí soukromého klíče do vašeho účtu. Utratit zůstatek můžete také pomocí jednoho z P2P Bitcoin klientů naimportováním soukromého klíče. Myslete na to, že importem klíče do klienta se stane součástí jeho peněženky. Pokud převedete někomu peníze, nespotřebovaný zůstatek se zašle na jinou Bitcoin adresu uvedenou v P2P klienta. Tuto novou adresu musíte vyzálohovat a udržovat v bezpečí. Satoshi doporučuje, že by nikdo nikdy neměl mazat peněženku.",
|
||
"singleshare": "SDÍLEJTE",
|
||
"singlesecret": "SOUKROMÉ",
|
||
|
||
// paper wallet html
|
||
"paperlabelhideart": "Skrýt grafiku?",
|
||
"paperlabeladdressesperpage": "Adres na stránku:",
|
||
"paperlabeladdressestogenerate": "Vytvořit adres:",
|
||
"papergenerate": "Vytvořit",
|
||
"paperprint": "Tisk",
|
||
"paperlabelBIPpassphrase": "Heslo:",
|
||
"paperlabelencrypt": "Šifrovat BIP38?",
|
||
|
||
// bulk wallet html
|
||
"bulklabelstartindex": "Počátek:",
|
||
"bulklabelrowstogenerate": "Počet řádku k vytvoření:",
|
||
"bulklabelcompressed": "Komprimované adresy?",
|
||
"bulkgenerate": "Vytvořit",
|
||
"bulkprint": "Tisk",
|
||
"bulklabelcsv": "Čárkou oddělené hodnoty (CSV):",
|
||
"bulklabelformat": "Index, Adresa, Soukromý klíč (WIF – Formát pro import do peněženky)",
|
||
"bulklabelq1": "Proč bych měl používat Hromadnou peněženku pro příjem Bitcoinů na mé stránce?",
|
||
"bulka1": "Tradiční způsob jak přijímat Bitcoiny na vaší webové stránce vyžaduje instalaci oficiálního bitcoin klienta (\"bitcoind\"). Mnoho webhostingových společností neumožňuje tuto instalaci provést. Také běh bitcoin démona na webovém serveru znamená, že soukromé klíče jsou uloženy na serveru a mohou být ukradeny. Pokud použijete Hromadnou peněženku, tak stačí na server nahrát pouze veřejnou bitcoin adresu a ne soukromé klíče. Poté se nemusíte bát, že vaše Bitcoiny budou ukradeny v případě napadení serveru.",
|
||
"bulklabelq2": "Jakým způsobem mohou přijímat Bitcoiny na mé stránce pomocí Hromadné peněženky?",
|
||
"bulklabela2li1": "Předgenerujte si velké množství Bitcoin adres (10 000+). Okopírujte si CSV seznam do souboru na bezpečné místo ve vašem počítači. Poté jej vyzálohujte na bezpečné místo.",
|
||
"bulklabela2li2": "Naimportujte Bitcoin adresy do databáze na vašem webovém serveru. Neimportujte soukromé klíče, abyste zabránili krádeži vašich peněz.",
|
||
"bulklabela2li3": "Umožněte na vaší stránce platbu pomocí Bitcoinu. Stačí vždy zobrazit jednu z vygenerovaných adres a uložit si ji u objednávky.",
|
||
"bulklabela2li4": "Nyní je již pouze potřeba zařídit notifikace o příchozí transakci. Zadejte do Google \"bitcoin payment notification\" a využijte jednu z existujících služeb. Existuje jich několik a podporují např. Web Services, API, SMS, Email, apod. Notifikaci můžete zpracovat automaticky. Pro ruční kontrolu, zda peníze přišly, stačí použít Block Explorer. Nahraďte SEMPATŘÍADRESA Bitcoin adresou, kterou chcete zkontrolovat. Potvrzení transkace může trvat od 10 minut do jedné hodiny.<br />http://www.blockexplorer.com/address/SEMPATŘÍADRESA<br /><br />Nepotvrzené tansakce je možné zkontrolovat na: http://blockchain.info/ <br />Většinou se zde zobrazí do 30 sekund.",
|
||
"bulklabela2li5": "Bitcoiny budou bezpečně převedeny v řetězci bloků. Pro spotřebování stačí kdykoliv naimportovat soubor vygenerovaný v prvním kroku.",
|
||
|
||
// brain wallet html
|
||
"brainlabelenterpassphrase": "Zadejte heslo:",
|
||
"brainlabelshow": "Zobrazit?",
|
||
"brainprint": "Tisk",
|
||
"brainlabelconfirm": "Heslo znovu:",
|
||
"brainview": "Zobrazit",
|
||
"brainalgorithm": "Algoritmus: SHA256 (Heslo)",
|
||
"brainlabelbitcoinaddress": "Bitcoin adresa:",
|
||
"brainlabelprivatekey": "Soukromý klíč (WIF – Formát pro import do peněženky):",
|
||
|
||
// vanity wallet html
|
||
"vanitylabelstep1": "Krok 1 – Vytvořte klíč pro první krok",
|
||
"vanitynewkeypair": "Vytvořit",
|
||
"vanitylabelstep1publickey": "Veřejný klíč 1. kroku",
|
||
"vanitylabelstep1pubnotes": "Zkopírujte a vložte výše uvedený klíč do pole Your-Part-Public-Key na Vanity Pool stránce.",
|
||
"vanitylabelstep1privatekey": "Soukromý klíč 1. kroku",
|
||
"vanitylabelstep1privnotes": "Zkopírujte a uschovejte uvedený soukromý klíč. Ideálně na šifrovaný disk. Budete ho potřebovat pro získání vašeho Bitcoin soukromého klíče poté, co pool nalezne začátek.",
|
||
"vanitylabelstep2calculateyourvanitywallet": "Krok 2 – Výpočet peněženky Vanity",
|
||
"vanitylabelenteryourpart": "Zadejte vaši část soukromého klíče (vygenerovaný a uložený v prvním kroku výše):",
|
||
"vanitylabelenteryourpoolpart": "Zadejte pool část soukromého klíče (z Vanity Poolu):",
|
||
"vanitylabelnote1": "[POZNÁMKA: do tohoto pole můžete zadat veřejný nebo soukromý klíč]",
|
||
"vanitylabelnote2": "[POZNÁMKA: do tohoto pole můžete zadat veřejný nebo soukromý klíč]",
|
||
"vanitylabelradioadd": "Sečíst",
|
||
"vanitylabelradiomultiply": "Násobit",
|
||
"vanitycalc": "Spočítát peněženku Vanity",
|
||
"vanitylabelbitcoinaddress": "Bitcoin adresa Vanity:",
|
||
"vanitylabelnotesbitcoinaddress": "Výše je vaše nová adresa, která by měla obsahovat požadovaný začátek.",
|
||
"vanitylabelpublickeyhex": "Veřejný klíč Vanity (HEX):",
|
||
"vanitylabelnotespublickeyhex": "Výše je veřejný klíč v hexadecimálním formátu.",
|
||
"vanitylabelprivatekey": "Soukromý klíč Vanity (WIF):",
|
||
"vanitylabelnotesprivatekey": "Výše je soukromý klíč pro načtení do vaší peněženky.",
|
||
|
||
// detail wallet html
|
||
"detaillabelenterprivatekey": "Zadejte soukromý klíč:",
|
||
"detailkeyformats": "Podporované formáty: WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"detailview": "Zobrazit detail",
|
||
"detailprint": "Tisk",
|
||
"detaillabelnote1": "",
|
||
"detaillabelnote2": "",
|
||
"detaillabelbitcoinaddress": "Bitcoin adresa:",
|
||
"detaillabelbitcoinaddresscomp": "Komprimovaná bitcoin adresa:",
|
||
"detaillabelpublickey": "Veřejný klíč (130 znaků [0-9A-F]):",
|
||
"detaillabelpublickeycomp": "Komprimovaný veřejný klíč (66 znaků [0-9A-F]):",
|
||
"detaillabelprivwif": "Soukromý klíč WIF <br />51 znaků v base58, začíná",
|
||
"detaillabelprivwifcomp": "Komprimovaný soukromý klíč WIF <br />52 znaků v base58, začíná",
|
||
"detailcompwifprefix": "'K' nebo 'L'",
|
||
"detaillabelprivhex": "Soukromý klíč v hexadecimálním formátů (64 znaků [0-9A-F]):",
|
||
"detaillabelprivb64": "Soukromý klíč v base64 (44 znaků):",
|
||
"detaillabelprivmini": "Soukromý klíč v mini formátů (22, 26 nebo 30 znaků, začíná 'S'):",
|
||
"detaillabelpassphrase": "Zadejte BIP38 heslo:",
|
||
"detaildecrypt": "Dešifrovat",
|
||
"detaillabelq1": "Jak si mohu vytvořit peněženku pomocí hrací kostky? Co je to B6?",
|
||
"detaila1": "Důležitá součást vytváření Bitcoin peněženky je jistota, že náhodná čísla použitá pro její tvorbu jsou opravdu náhodná. Fyzická náhoda je lepší než počítačem generovaná pseudonáhoda. Pomocí hrací kostky je možné jednoduše získat fyzicky náhodná čísla. Pro vytvoření soukromého klíče potřebujete pouze šestihrannou kostku, kterou 99x hodíte. Každý tento hod zaznamenejte. Při zapisování převeďte čísla takto: 1=1, 2=2, 3=3, 4=4, 5=5, 6=0. Pomocí této techniky zapisujete velké, opravdu náhodné číslo, svůj soukromý klíč v B6 nebo také base 6 formátu. Těchto 99 čísel napište do pole výše a klikněte na Zobrazit detail. Poté se vám zobrazí Bitcoin adresa přidružená k tomuto soukromému klíči. Soukromý klíč byste si měli zaznamenat také ve WIF formátu, který je široce používán."
|
||
},
|
||
|
||
"hu": { // 02-MAR-2014 16:57
|
||
// javascript alerts or messages
|
||
"testneteditionactivated": "TESTNET KIADÁS AKTIVÁLVA",
|
||
"paperlabelbitcoinaddress": "Bitcoin cím:",
|
||
"paperlabelprivatekey": "Privát kulcs (WIF, tárca import formátumban):",
|
||
"paperlabelencryptedkey": "Titkosított privát kulcs (Jelszó szükséges)",
|
||
"bulkgeneratingaddresses": "Cím generálás... ",
|
||
"brainalertpassphrasetooshort": "A megadott jelmondat túl rövid.\n\n",
|
||
"brainalertpassphrasewarning": "Figyelem: Fontos, hogy erős jelmondatot válasszon, mert különben a jelmondatot nyers erővel feltörhetik és a bitcoinjait ellophatják.",
|
||
"brainalertpassphrasedoesnotmatch": "A jelmondat és az ellenőrző jelmondat nem azonos.",
|
||
"detailalertnotvalidprivatekey": "A beadott szöveg nem érvénytelen Privát Kulcs",
|
||
"detailconfirmsha256": "Az ön által beadott szöveg érvénytelen Privát Kulcs!\n\nSzeretné a beadott szöveget jelmondatként kezelni, és annak SHA256 zanzájából egy Privát Kulcsot előállítani?\n\nFigyelem: Fontos, hogy erős jelmondatot válasszon, mert különben a jelmondatot nyers erővel feltörhetik és a bitcoinjait ellophatják.",
|
||
"bip38alertincorrectpassphrase": "Érvénytelen jelmondat a titkosított privát kulcshoz.",
|
||
"bip38alertpassphraserequired": "A BIP38 kulcshoz jelmondat szükséges",
|
||
"vanityinvalidinputcouldnotcombinekeys": "Érvénytelen bemenet. A kulcsok nem tartoznak össsze.",
|
||
"vanityalertinvalidinputpublickeysmatch": "Érvénytelen bemenet. A két megadott nyilvános kulcs azonos. Két különböző kulcs bevitelére van szükség.",
|
||
"vanityalertinvalidinputcannotmultiple": "Érvénytelen bemenet. Két nyilvános kulcs összeszorzása nem lehetséges. Válassza az 'Összeadás'-t, ha két nyilvános kulcsból szeretne egy bitcoin címet kapni.",
|
||
"vanityprivatekeyonlyavailable": "Csak két privát kulcs kombinálásakor lehetséges",
|
||
"vanityalertinvalidinputprivatekeysmatch": "Érvénytelen bemenet. A két megadott privát kulcs azonos. Két különböző kulcs bevitelére van szükség.",
|
||
|
||
// header and menu html
|
||
"tagline": "Nyílt forráskódú, kliens oldali JavaScript, Bitcoin pénztárca előállítására",
|
||
"generatelabelbitcoinaddress": "A bitcoin cím előállítása...",
|
||
"generatelabelmovemouse": "MOZGASSA az egeret, ha fokozni szeretné a véletlenszerűséget...",
|
||
"generatelabelkeypress": "VAGY gépeljen be néhány véletlenszerű karaktert ebbe a szövegdobozba",
|
||
"singlewallet": "Egyszerű pénztárca",
|
||
"paperwallet": "Papír pénztárca",
|
||
"bulkwallet": "Tömeges pénztárca",
|
||
"brainwallet": "Fejben tartott pénztárca",
|
||
"vanitywallet": "Kérkedő pénztárca",
|
||
"splitwallet": "Részekre bontott ~",
|
||
"detailwallet": "A pénztárca részletei",
|
||
|
||
// footer html
|
||
"footerlabeldonations": "Adományok:",
|
||
"footerlabeltranslatedby": "Fordította: 1GEBor11XtqDoamipB8nAV7o4fNW5JcrUD",
|
||
"footerlabelpgp": "PGP",
|
||
"footerlabelversion": "Változatok története",
|
||
"footerlabelgithub": "GitHub kódtár",
|
||
"footerlabelcopyright1": "Copyright bitaddress.org.",
|
||
"footerlabelcopyright2": "Az egyes JavaScript kódok szerzőinek jogai a forráskódon belül találhatók meg.",
|
||
"footerlabelnowarranty": "Garancia nincs.",
|
||
|
||
// single wallet html
|
||
"newaddress": "Új cím előállítása",
|
||
"singleprint": "Nyomtatás",
|
||
"singlelabelbitcoinaddress": "Bitcoin cím:",
|
||
"singlelabelprivatekey": "Privát kulcs (WIF, tárca import formátumban):",
|
||
"singletip1": "<b>Egy bitcoin pénztárca</b> nem más, mint egy bitcoin címből és a hozzá tartozó privát kulcsból álló számpár. Egy ilyen pénztárcát állítottunk elő és jelenítettünk meg fent az Ön számára a Web böngészőben.",
|
||
"singletip2": "<b>A pénztárca biztonságos megőrzése</b> érdekében nyomtassa ki vagy más módon rögzítse a bitcoin címet és privát kulcsot. Fontos, hogy a privát kulcsból készítsen másolatot, és tárolja biztonságos helyen. Ez a webhely nem tud az ön privát kulcsairól. Ha ismeri a PGP-t, akkor egyben letöltheti az egész web lapot, és ellenőrizheti, hogy a webhely szerzője álatal írt valódi változatot töltötte-e le. Ehhez össze kell hasonlítania a HTML-ből képzett SHA1 zanzát a webhely láblécében hivatkozott, aláírt verzió történetben lévő SHA1 zanzával. Ha elhagyja/megfrissíti a webhelyet vagy megnyomja az 'Új cím előállítása' gombot, akkor egy új privát kulcs áll elő, és az előzőleg megjelenített privát kulcs elvész. A bitcoin címhez tartozó privát kulcsot titokban kell tartani. Bárki, aki megszerzi ezt a kulcsot, el tudja költeni az ehhez a címhez tartozó összes bitcoint. Ha kinyomtatja a pénztárcát, akkor tárolja egy villámzáras vízhatlan nylon-zacskóban. A papír pénztárcát tekintse úgy, mintha pénz lenne.",
|
||
"singletip3": "<b>Pénzt úgy tehet</b> a pénztárcájába, hogy másokkal bitcoinokat küldet erre a Bitcoin címre.",
|
||
"singletip4": "<b>A pénztárca egyenlegét</b> úgy kérdezheti le, hogy elmegy a blockchain.info vagy a blockexplorer.com weblapokra, és ott beadja ezt a Bitcoin címet.",
|
||
"singletip5": "<b>Ha el akarja költeni a bitcoinjait,</b> akkor menjen a blockchain.info weblapra, és a privát kulcson lévő teljes egyenleget töltse át (sweep) a weblapon lévő számlájára. A pénzt úgy is elköltheti, hogy letölti valamelyik népszerű p2p bitcoin klienst, és beimportálja a privát kulcsot a p2p kliens pénztárcájába. Ne feledje, hogy miután beimportálta a kulcsot a p2p bitcoin kliensbe, a kulcsot a p2p kliens a pénztárcában lévő többi kulccsal együtt tárolja. Pénz küldésekor a visszajáró pénzt a p2p kliens pénztárcájában lévő másik bitcoin címre fogják küldeni. Ekkor biztonsági másolatot kell készítenie a p2p kliens pénztárcáról, és a másolatot biztos helyen kell őriznie, mivel a maradék bitcoinjait a pénztárca kulcsai tárolják. Satoshi tanácsa, hogy pénztárcát soha ne töröljünk.",
|
||
|
||
// paper wallet html
|
||
"paperlabelhideart": "A grafika elrejtése?",
|
||
"paperlabeladdressesperpage": "Címek száma egy oldalon:",
|
||
"paperlabeladdressestogenerate": "Előállítandó címek száma:",
|
||
"papergenerate": "Előállítás",
|
||
"paperprint": "Nyomtatás",
|
||
"paperlabelBIPpassphrase": "Jelmondat:",
|
||
"paperlabelencrypt": "BIP38 titkosítás?",
|
||
|
||
// bulk wallet html
|
||
"bulklabelstartindex": "Kezdő index:",
|
||
"bulklabelrowstogenerate": "Az előállítandó sorok száma:",
|
||
"bulklabelcompressed": "Tömörített címek használata?",
|
||
"bulkgenerate": "Előállítás",
|
||
"bulkprint": "Nyomtatás",
|
||
"bulklabelcsv": "Vesszővel elválasztott értékek (CSV):",
|
||
"bulklabelformat": "Index, Cím, Privát cím (WIF)",
|
||
"bulklabelq1": "Miért jó a Tömeges pénztárca használata, ha Ön bitcoint szeretne elfogadni a web-en?",
|
||
"bulka1": "Ha Ön bitcoint szeretne elfogadni a web-en, akkor a szokásos megoldás az, hogy installálja a hivatalos bitcoin kliens démont (\"bitcoind\"). Sok web szolgáltató nem támogatja a bitcoin démon installálását. Ráadásul, ha a bitcoin démont a web szerveren futtatja, akkor a privát kulcsai is a web szerveren lesznek tárolva, és a web szerver meghekkelésekor ellophatják őket. A Tömeges pénztárca használatakor csak a bitcoin címeket kell feltölteni a web szerverre, a privát kulcsokat nem. Így nem kell aggódnia, hogy ellopják a bitcoin pénztárcáját, ha betörnek a web szerverre.",
|
||
"bulklabelq2": "Hogyan használható a Tömeges pénztárca az Ön web helyén bitcoin elfogadásra?",
|
||
"bulklabela2li1": "A Tömeges pénztárcával állítson elő nagy mennyiségű (10,000+) bitcoin címet. Másolja át a vesszővel elválasztott adatokat (CSV) egy biztonságos szöveges állományba a számítógépére. A szöveges állományról készítsen mentést, és azt őrizze biztonságos környezetben.",
|
||
"bulklabela2li2": "Importálja be a Bitcoin címeket a web szerverén futó adatbázisba. (A pénztárca privát kulcsait ne importája be, mert ezzel azt kockáztatja, hogy a hackerek ellopják a pénzét. Csak a bitcoin címeket importálja be, úgy, ahogy azt a ügyfelei látják majd.)",
|
||
"bulklabela2li3": "Web helyének vásárlókosarába vegye fel a bitcoinnal történő fizetés lehetőségét. Ha egy ügyfél bitcoinnal kíván fizetni, akkor \"fizetési címként\" az adatbázis egyik címét jelenítse meg, és a megrendelés mellett ezt a címet tárolja.",
|
||
"bulklabela2li4": "Most szüksége van arra, hogy értesítést kapjon, ha megérkezett a pénz. A Google-on keressen rá a \"bitcoin payment notification\" kifejezésre, és iratkozzon föl valamelyik szolgáltatóhoz, amely értesítést küld, ha bizonyos címekre Bitcoint küldtek. Számos ilyen szolgáltató van, amelyik Web szervíz, API, SMS, Email, stb. segítségével értesítést küld. Amint megérkezik az értesítés, amelynek automatikus figyelése beprogramozható, máris megkezdheti az ügyfél megrendelésének feldolgozását. Ha manuálisan szeretné ellenőrizni, hogy érkezett-e valamelyik címre pénz, akkor a Block Explorer-t használhatja. A CÍM helyébe írja azt a Bitcoin címet, amelyet ellenőrizni szeretne. A tranzakció megerősítéséhez 10 és 60 perc közötti időre van szükség.<br />http://www.blockexplorer.com/address/CÍM<br /><br />A megerősítetlen tranzakciókat itt lehet megnézni: http://blockchain.info/ <br />A tranzakció 30 másodpercen belül megjelenik.",
|
||
"bulklabela2li5": "Az Ön bitcoinjai biztonságos módon gyűlnek a blokkláncon. Használja az 1. lépés során előállított eredeti pénztárcát, ha szeretné őket elkölteni.",
|
||
|
||
// brain wallet html
|
||
"brainlabelenterpassphrase": "Adja be a jelmondatot: ",
|
||
"brainlabelshow": "Jelmondat megjelenítése?",
|
||
"brainprint": "Nyomtatás",
|
||
"brainlabelconfirm": "Erősítse meg a jelmondatot: ",
|
||
"brainview": "Megjelenítés",
|
||
"brainalgorithm": "Algoritmus: SHA256(jelmondat)",
|
||
"brainlabelbitcoinaddress": "Bitcoin cím:",
|
||
"brainlabelprivatekey": "Privát kulcs (WIF, tárca import formátumban):",
|
||
|
||
// vanity wallet html
|
||
"vanitylabelstep1": "1. lépés - az \"1. lépéshez tartozó Kulcspár\" előállítása",
|
||
"vanitynewkeypair": "Előállítás",
|
||
"vanitylabelstep1publickey": "1. lépés, Publikus Kulcs:",
|
||
"vanitylabelstep1pubnotes": "Másolja a fentiekeket a Vanity Pool webhely Your-Part-Public-Key ('az ön publikus kulcsa') mezőjébe.",
|
||
"vanitylabelstep1privatekey": "1. lépés, Privát Kulcs:",
|
||
"vanitylabelstep1privnotes": "Másolás és beillesztés segítségével másolja a fenti Privát Kulcsot egy szöveges állományba. Ideális esetben a szöveges állomány egy titkosított meghajtón van. Ha a Vanity Pool megtalálta az Ön által megadott előtaghoz tartozó Privát Kulcsot, akkor lesz szüksége erre az állományra, hogy elő tudja állítani a Privát Kulcsot.",
|
||
"vanitylabelstep2calculateyourvanitywallet": "2. lépés - A Kérkedő Pénztárca Privát Kulcsának kiszámítása",
|
||
"vanitylabelenteryourpart": "Adja meg az Önhöz tartozó Privát Kulcsot (amelyet az 1. lépésben állított elő és mentett el):",
|
||
"vanitylabelenteryourpoolpart": "Adja meg a Pool-hoz tartozó Privát Kulcsot (amely a Vanity Pool-ból származik):",
|
||
"vanitylabelnote1": "[MEGJEGYZÉS: ebbe a szövegmezőbe publikus kulcs vagy privát kulcs egyaránt írható]",
|
||
"vanitylabelnote2": "[MEGJEGYZÉS: ebbe a szövegmezőbe publikus kulcs vagy privát kulcs egyaránt írható]",
|
||
"vanitylabelradioadd": "Összeadás",
|
||
"vanitylabelradiomultiply": "Szorzás",
|
||
"vanitycalc": "A Kérkedő pénztárca kiszámítása",
|
||
"vanitylabelbitcoinaddress": "Kérkedő Bitcoin cím:",
|
||
"vanitylabelnotesbitcoinaddress": "Fönt látható az ön új címe, mely magában foglalja a kívánt előtagot.",
|
||
"vanitylabelpublickeyhex": "Kérkedő Publikus Kulcs (HEX):",
|
||
"vanitylabelnotespublickeyhex": "A Publikus Kulcs hexadecimális alakban. ",
|
||
"vanitylabelprivatekey": "Kérkedő Privát Kulcs (WIF):",
|
||
"vanitylabelnotesprivatekey": "Ez az Ön Privát Kulcsa, mellyel elérheti a pénzét. ",
|
||
|
||
// split wallet html
|
||
"splitlabelthreshold": "A visszaállításhoz szükséges részek minimális száma",
|
||
"splitlabelshares": "Részek száma",
|
||
"splitview": "Előállítás",
|
||
"combinelabelentershares": "Adja be a meglévő részeket (Enter-rel, szóközzel vagy más whitespace karakterrel elválasztva)",
|
||
"combineview": "A részek összekombinálása",
|
||
"combinelabelprivatekey": "Visszaállított Privát Kulcs",
|
||
|
||
// detail wallet html
|
||
"detaillabelenterprivatekey": "Adja meg a Privát Kulcsot",
|
||
"detailkeyformats": "Kulcs formátumok: WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"detailview": "Részletek megjelenítése",
|
||
"detailprint": "Nyomtatás",
|
||
"detaillabelnote1": "A Bitcoin Privát Kulcs egy titkos szám, melyet csak Ön ismer. Számos különböző formátumban kódolható. Az alábbiakban megjelenítettük a a Privát Kulcshoz tartozó Bitcoin Címet és Publikus kulcsot, valamint a Privát Kulcsot a legnépszerűbb kódolási formátumokban (WIF, WIFC, HEX, B64, MINI).",
|
||
"detaillabelnote2": "A Bitcoin v0.6+ a publikus kulcsokat tömörített formátumban tárolja. A kliens az importprivkey/dumpprivkey parancsokkal a privát kulcsok importálását és exportálását is támogatja. Az exportált privát kulcsok formátumát csupán a Bitcoin pénztárca verziószáma határozza meg.",
|
||
"detaillabelbitcoinaddress": "Bitcoin cím:",
|
||
"detaillabelbitcoinaddresscomp": "Tömörített Bitcoin cím:",
|
||
"detaillabelpublickey": "Publikus Kulcs (130 karakter [0-9A-F]):",
|
||
"detaillabelpublickeycomp": "Tömörített Publikus Kulcs (66 karakter [0-9A-F]):",
|
||
"detaillabelprivwif": "WIF Privát Kulcs <br />51 db base58 karakter, melynek kezdete",
|
||
"detaillabelprivwifcomp": "Tömörített WIF Privát Kulcs <br />52 db base58 karakter, melynek kezdete",
|
||
"detailcompwifprefix": "'K' vagy 'L'",
|
||
"detaillabelprivhex": "Hexadecimális formátumú Privát Kulcs (64 karakter [0-9A-F]):",
|
||
"detaillabelprivb64": "Base64 formátumú Privát Kulcs (44 karakter):",
|
||
"detaillabelprivmini": "Mini formátumú Privát Kulcs (22, 26 vagy 30 karakter, amely egy 'S'-sel kezdődik):",
|
||
"detaillabelpassphrase": "BIP38 jelmondat",
|
||
"detaildecrypt": "BIP38 dekódolás",
|
||
"detaillabelq1": "Hogyan lehet dobókockával pénztárcát készíteni? Mit jelent a B6 formátum?",
|
||
"detaila1": "Egy Bitcoin pénztárca előállításakor nagyon fontos, hogy a felhasznált véletlen számok valóban véletlenek legyenek. A fizikai véletlen jobb, mint a számítógéppel előállított pszeudo-véletlen. Fizikai véletlen a legegyszerűbben egy dobókockával állítható elő. Ha szeretne egy Bitcoin privát címet előállítani, akkor csupán egy dobókockára van szüksége, mellyel 99-szer kell dobni. Jegyezze fel minden egyes dobása eredményét. Az eredmények feljegyzésekor a következő szabályokat kövesse: 1->1, 2->2, 3->3, 4->4, 5->5, 6->0. Ha így tesz, akkor a privát kulcshoz tartozó véletlen számot B6 formátumban, vagyis 6-os számrendszerben rögzíti. Írja be ezt a 99 karakterből álló 6-os számrendszerbeli privát kulcsot a fenti szövegmezőbe, majd nyomja meg a 'Részletek megjelenítése' gombot. Ekkor megjelenik az a Bitcoin cím, amely ehhez a privát kulcshoz tartozik. Érdemes felírni a WIF formátumú privát kulcsot is, mivel ezt szélesebb körben használják."
|
||
},
|
||
|
||
"jp": {
|
||
// javascript alerts or messages
|
||
"testneteditionactivated": "テストネット版が有効になりました。",
|
||
"paperlabelbitcoinaddress": "ビットコインアドレス",
|
||
"paperlabelprivatekey": "プライベートキー(WIF形式)",
|
||
"paperlabelencryptedkey": "暗号化されたプライベートキー(パスワード必須)",
|
||
"bulkgeneratingaddresses": "アドレス生成中...",
|
||
"brainalertpassphrasetooshort": "パスワードが短すぎます \n\n",
|
||
"brainalertpassphrasewarning": "注意:強いパスワードを選ばないとプライベートキーを安易に当てられてビットコインを盗まれてしまいます。<br>なお、<b>UTF-8の文字も使えるため、キーボードが半角か全角か今一度ご確認下さい。</b>",
|
||
"brainalertpassphrasedoesnotmatch": "パスワードが一致しません",
|
||
"detailalertnotvalidprivatekey": "入力された文字列は有効なプライベートキーではありません。",
|
||
"detailconfirmsha256": "入力された文字列は有効なプライベートキーではありません。\n\n代わりにこの文字列をパスワードとして、SHA256ハッシュを用いプライベートキーを生成しますか?\n\n注意: 強いパスワードを選ばないとプライベートキーを安易に当てられてビットコインを盗まれてしまいます。",
|
||
"bip38alertincorrectpassphrase": "暗号化されたプライベートキーに一致しないパスワードです。",
|
||
"bip38alertpassphraserequired": "BIP38キーを生成するにはパスワードをかける必要があります。",
|
||
"vanityinvalidinputcouldnotcombinekeys": "不正入力です。キーを結合できませんでした。",
|
||
"vanityalertinvalidinputpublickeysmatch": "不正入力です。両方のパブリックキーが同じです。2つの異なるキーをお使い下さい。",
|
||
"vanityalertinvalidinputcannotmultiple": "不正入力です。2つのパブリックキーを掛け合わせることはできません。「足し算」を選択し、2つのパブリックキーを足し合わせてアドレスを生成して下さい。",
|
||
"vanityprivatekeyonlyavailable": "2つのプライベートキーを掛け合わせた時だけ有効です。",
|
||
"vanityalertinvalidinputprivatekeysmatch": "不正入力両方のプライベートキーがチケットに一致します。2つの異なるキーをお使い下さい。",
|
||
|
||
// header and menu html
|
||
"tagline": "クライエント側ビットコインアドレス生成(JavaScript使用)",
|
||
"generatelabelbitcoinaddress": "ビットコインアドレスを生成中...",
|
||
"generatelabelmovemouse": "マウスを動かして、ランダム要素を追加してください。",
|
||
"generatelabelkeypress": "もしくはこちらの入力欄にランダムな文字を打って下さい。",
|
||
"singlewallet": "シングルウォレット",
|
||
"paperwallet": "ペーパーウォレット",
|
||
"bulkwallet": "大量ウォレット",
|
||
"brainwallet": "暗記ウォレット",
|
||
"vanitywallet": "カスタムウォレット",
|
||
"detailwallet": "ウォレットの詳細",
|
||
|
||
// footer html
|
||
"footerlabeldonations": "プロジェクト寄付先",
|
||
"footerlabeltranslatedby": "日本語訳寄付先 1o3EBhxPhGn8cGCL6Wzi5F5kTPuBofdMf",
|
||
"footerlabelpgp": "PGP",
|
||
"footerlabelversion": "バージョン履歴",
|
||
"footerlabelgithub": "GitHubリポジトリ",
|
||
"footerlabelcopyright1": "Copyright bitaddress.org.",
|
||
"footerlabelcopyright2": "JavaScriptのコピーライト情報はソースに含まれています。",
|
||
"footerlabelnowarranty": "保障はありません。",
|
||
|
||
// single wallet html
|
||
"newaddress": "新アドレス生成",
|
||
"singleprint": "印刷",
|
||
"singlelabelbitcoinaddress": "ビットコインアドレス",
|
||
"singlelabelprivatekey": "プライベートキー (WIF形式)",
|
||
"singletip1": "<b>ビットコインウォレットとは</b> ビットコインのアドレスと対応するプライベートキーを組み合わせたものです。新しいアドレスがブラウザー上で生成され、上記に表示されています。",
|
||
"singletip2": "<b>このウォレットを守るためには</b> ビットコインアドレスとビットコインプライベートキーを印刷するなどの手段で記録しなければいけません。プライベートキーが無いとペアになっているアドレスに送られたビットコインが使えないので、人に晒されないような方法でプライベートキーのコピーを取り、大事に保管して下さい。このサイトはこのプライベートキーの保存はしません。PGPをご存知の方は、このサイトを1つのhtmlファイルで落とすことができるので、このサイトのhtmlファイルのSHA1ハッシュとサイトのフッターにデジタル署名されたメッセージに入ったハッシュを比べて不正にいじられていないかをお確かめいただけます。このページを閉じたり、離れたり、”新アドレス生成”を押すと現在表示されているプライベートキーは消え、新規アドレスが生成されるので、ご使用の場合は必ず何らかの手段で記録しておいて下さい。プライベートキーは秘密にしてください。共有されますと、対応するビットコインアドレスに存在するコインが全て共有者間で利用可能となります。ウォレット情報を印刷したら、濡れないようにジップロックに入れましょう。紙幣と同様に扱うよう心がけてください。",
|
||
"singletip3": "<b>このウォレットにコインを追加 : </b> 他の人から自分のビットコインアドレスに送ってもらう。",
|
||
"singletip4": "<b>残高照会は</b> blockchain.infoやblockexplorer.comに行き、ビットコインアドレスを入力してお調べ下さい。",
|
||
"singletip5": "<b>ビットコインを使おう。</b> 送金するには、このページで生成したプライベートキーをblockchain.infoのウォレットや各種パソコン・スマホ端末にあるウォレットアプリなどに取り込んで使えます。しかし、その時点でそのアドレスが取り込んだウォレットの他のアドレスと融合してしまい、この一つのアドレスのバックアップだけじゃビットコインを保管することはできなくなります。取り込み先のウォレットを強いパスワードで暗号化し、バックアップして、安全に扱って下さい。ビットコインの考案者「サトシさん」曰く、「一度作ったウォレットを、空にしたとしても、削除しない方が良い。」(メールアドレスと同じく、いつ昔の友達や親戚から古いアドレス宛にビットコインを送ってくるかわかりませんから。)",
|
||
|
||
// paper wallet html
|
||
"paperlabelhideart": "デザイン非表示",
|
||
"paperlabeladdressesperpage": "1ページごとのアドレス数",
|
||
"paperlabeladdressestogenerate": "生成するアドレス数",
|
||
"papergenerate": "生成",
|
||
"paperprint": "印刷",
|
||
"paperlabelBIPpassphrase": "パスワード",
|
||
"paperlabelencrypt": "BIP38で暗号化?",
|
||
|
||
// bulk wallet html
|
||
"bulklabelstartindex": "開始番号",
|
||
"bulklabelrowstogenerate": "生成する行数",
|
||
"bulklabelcompressed": "アドレスを短縮?",
|
||
"bulkgenerate": "生成",
|
||
"bulkprint": "印刷",
|
||
"bulklabelcsv": "カンマ区切り値",
|
||
"bulklabelformat": "番号、アドレス、プライベートキー(WIF形式)",
|
||
"bulklabelq1": "ウェブサイトでビットコインを受け付ける時、何故大量のアドレスを生成しておいた方がいいのか?",
|
||
"bulka1": "以前はビットコインをサイトで受け付けたかったら、「bitcoind」というビットコインのシステムサービスをサーバーにアップロードし、サーバー上で実行しなければいけませんでした。しかし、このやり方だとサーバーがハッキングされてしまった場合、プライベートキーも全て持って行かれてしまいます。大量に生成しておいて、ビットコインアドレスだけをサーバーにアップしておけば、プライベートキーを安全な場所に保管できます。",
|
||
"bulklabelq2": "どうやって大量生成を使ってサイトでビットコインを受け付けられるようにできるのか?",
|
||
"bulklabela2li1": "大量生成タブで大量のビットコインを生成(10,000+でも可)。出てくるCSVテキストをコピーして、安全なテキストエディターで貼り付けて、安全な場所に保存しておいて下さい。一つバックアップを取り、別の場所で保管しておく(強いパスワードのかかったzipなどで)",
|
||
"bulklabela2li2": "ビットコインアドレスをウェブサーバーにアップロード。プライベートキーはアップロードしないで下さい。ユーザーに見せたい宛先用のアドレスのみをアップロードして下さい。",
|
||
"bulklabela2li3": "サイトのショッピングカート機能にビットコインのリンクを追加して下さい。クリックされた時、お値段と先ほどアップしたビットコインアドレスが順番に出てくるようにしておいて下さい(1取引1アドレス)。注文の情報と一緒に、このアドレスも一緒に保存して、後で紐付けられるようにしておいて下さい。",
|
||
"bulklabela2li4": "後は支払いの通知を受けないと注文を通すか否か分かりません。グーグルで「bitcoin payment notification」と検索したら、SMS、メール、APIなどでビットコインの支払いがあった際教えてくれます。これをコードの中に組み込んで、支払いがあったら注文を通すようにもできます。手動で送金があったかを見る場合、blockchain.infoに行き、宛先のアドレスを入力すれば、取引履歴から送金の事実を確認できます。大体送金の30秒後に表示され、10分~1時間の間に「確認」されます。",
|
||
"bulklabela2li5": "送られたビットコインはブロックチェーンにて安全に保管されます。送金するには1番で作成したウォレットを何らかのビットコインソフトに取り込んでご利用下さい。",
|
||
|
||
// brain wallet html
|
||
"brainlabelenterpassphrase": "パスワード",
|
||
"brainlabelshow": "表示",
|
||
"brainprint": "印刷",
|
||
"brainlabelconfirm": "パスワードをもう一度",
|
||
"brainview": "アドレスを見せる",
|
||
"brainalgorithm": "アルゴリズム SHA256 (パスワード)",
|
||
"brainlabelbitcoinaddress": "ビットコインアドレス",
|
||
"brainlabelprivatekey": "プライベートキー(WIF形式)",
|
||
|
||
// vanity wallet html
|
||
"vanitylabelstep1": "ステップ1「ステップ1キーペア」を生成",
|
||
"vanitynewkeypair": "生成",
|
||
"vanitylabelstep1publickey": "ステップ1パブリックキー",
|
||
"vanitylabelstep1pubnotes": "上記のものをカスタムアドレス生成業者の注文フォームに貼り付けて下さい。",
|
||
"vanitylabelstep1privatekey": "ステップ1プライベートキー",
|
||
"vanitylabelstep1privnotes": "上記のものを安全なテキストファイルに貼り付け、大事に保管しておいて下さい。パスワードで暗号化することをオススメします。カスタムアドレス生成業者からアドレスプレフィックスをもらった時にこれが必要となります。",
|
||
"vanitylabelstep2calculateyourvanitywallet": "ステップ2カスタムアドレスを計算",
|
||
"vanitylabelenteryourpart": "ステップ1で保存したプライベートキーを入力",
|
||
"vanitylabelenteryourpoolpart": "カスタムアドレス生成業者からもらったプライベートキーを入力",
|
||
"vanitylabelnote1": "[メモ: この欄はパブリックキーでもプライベートキーでも可能です。]",
|
||
"vanitylabelnote2": "[メモ: この欄はパブリックキーでもプライベートキーでも可能です。]",
|
||
"vanitylabelradioadd": "足し算",
|
||
"vanitylabelradiomultiply": "掛け算",
|
||
"vanitycalc": "カスタムアドレスを計算",
|
||
"vanitylabelbitcoinaddress": "カスタムビットコインアドレス",
|
||
"vanitylabelnotesbitcoinaddress": "ご希望された頭文字を持ったアドレスになっています。",
|
||
"vanitylabelpublickeyhex": "カスタムパブリックキー(HEX)",
|
||
"vanitylabelnotespublickeyhex": "パブリックキーを16進で表したものです。",
|
||
"vanitylabelprivatekey": "カスタムプライベートキー(WIF形式)",
|
||
"vanitylabelnotesprivatekey": "上記のアドレスに送られたビットコインを使うためのプライベートキーです。",
|
||
|
||
// split wallet html
|
||
"splitwallet": "分散ウォレット",
|
||
"splitlabelthreshold": "復元に必要なシェア数",
|
||
"splitlabelshares": "全シェア数",
|
||
"splitview": "生成",
|
||
"combinelabelentershares": "お持ちのシェアを入力 (空白区切り)",
|
||
"combineview": "シェア合わせて復元",
|
||
"combinelabelprivatekey": "復元された秘密鍵",
|
||
|
||
// detail wallet html
|
||
"detaillabelenterprivatekey": "プライベートキーを入力",
|
||
"detailkeyformats": "受け付けるキーの形式 WIF, WIFC, HEX, B64, B6, MINI, BIP38",
|
||
"detailview": "詳細を表示",
|
||
"detailprint": "印刷",
|
||
"detaillabelnote1": "ビットコインプライベートキーはあなたにしか分からない秘密の鍵。色々な形式で表示することができ、下記で表示しているのはビットコインアドレス、パブリックキー、プライベートキー、そして複数の形式でプライベートキーを表示します。(WIF, WIFC, HEX, B64, MINI)",
|
||
"detaillabelnote2": "ビットコイン v0.6より圧縮したパブリックキーを保存している。なお、importprivkey / dumpprivkeyのコマンドを用いてプライベートキーのインポートとエクスポートもできる。エクスポートされるプライベートキーの形式はウォレットの作成時期とバージョンによって異なってくる。",
|
||
"detaillabelbitcoinaddress": "ビットコインアドレス",
|
||
"detaillabelbitcoinaddresscomp": "ビットコインアドレス(圧縮)",
|
||
"detaillabelpublickey": "パブリックキー (130文字[0-9A-F])",
|
||
"detaillabelpublickeycomp": "パブリックキー (圧縮、66文字[0-9A-F])",
|
||
"detaillabelprivwif": "プライベートキー (WIF)<br>(base58コード51文字) 頭文字が",
|
||
"detaillabelprivwifcomp": "プライベートキー (WIF)<br>(圧縮、base58コード52文字) 頭文字が",
|
||
"detailwifprefix": "'5'",
|
||
"detailcompwifprefix": "'K' か 'L'",
|
||
"detaillabelprivhex": "プライベートキー(16進) (64文字[0-9A-F])",
|
||
"detaillabelprivb64": "プライベートキー(base64コード) (44文字)",
|
||
"detaillabelpassphrase": "BIP38パスワード",
|
||
"detaildecrypt": "BIP38暗号を解除",
|
||
"detaillabelq1": "サイコロを使ってどうやってアドレス作るのか?「B6」とは何か?",
|
||
"detaila1": "ビットコインのアドレスの生成には一番大事なことが、アドレス生成に使われている乱数が本当にランダムなのかというところです。自然界に起きる物理的なランダムさはパソコンが生成する(似非)ランダムさよりは優れている。物理的なランダムさを作る一番簡単な方法はサイコロを振ることです。ビットコインのプライベートキーを生成するには、6面のサイコロを99回振って、毎回結果を記載していきます。規則として1⇒1, 2⇒2, 3⇒3, 4⇒4, 5⇒5, 6⇒0というように、6が出る度に「0」と記載して下さい。99桁の6進数字列ができたら、上記の入力欄に入れて、「詳細を表示」ボタンを押して下さい。これでWIF形式のプライベートキーやそれと紐づくビットコインアドレスが表示されます。これらを記載し、通常生成されたビットコインアドレスと同じように保管しておいて下さい。",
|
||
}
|
||
}
|
||
};
|
||
|
||
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) {
|
||
if (passphrase == "") {
|
||
alert(ninja.translator.get("bip38alertpassphraserequired"));
|
||
return;
|
||
}
|
||
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;
|
||
if (ninja.wallets.paperwallet.encrypt) {
|
||
keyelement = 'btcencryptedkey'
|
||
image = 'data:image/png;base64,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';
|
||
}
|
||
else {
|
||
image = 'data:image/png;base64,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';
|
||
|
||
}
|
||
|
||
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 half = privateKey.length / 2;
|
||
document.getElementById("btcencryptedkey" + idPostFix).innerHTML = privateKey.slice(0, half) + '<br />' + privateKey.slice(half);
|
||
}
|
||
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";
|
||
},
|
||
|
||
openCloseFaq: function (faqNum) {
|
||
// do close
|
||
if (document.getElementById("detaila" + faqNum).style.display == "block") {
|
||
document.getElementById("detaila" + faqNum).style.display = "none";
|
||
document.getElementById("detaile" + faqNum).setAttribute("class", "more");
|
||
}
|
||
// do open
|
||
else {
|
||
document.getElementById("detaila" + faqNum).style.display = "block";
|
||
document.getElementById("detaile" + faqNum).setAttribute("class", "less");
|
||
}
|
||
},
|
||
|
||
viewDetails: function () {
|
||
var bip38 = false;
|
||
var key = document.getElementById("detailprivkey").value.toString().replace(/^\s+|\s+$/g, ""); // trim white space
|
||
document.getElementById("detailprivkey").value = key;
|
||
var bip38CommandDisplay = document.getElementById("detailbip38commands").style.display;
|
||
ninja.wallets.detailwallet.clear();
|
||
if (key == "") {
|
||
return;
|
||
}
|
||
if (ninja.privateKey.isBIP38Format(key)) {
|
||
document.getElementById("detailbip38commands").style.display = bip38CommandDisplay;
|
||
if (bip38CommandDisplay != "block") {
|
||
document.getElementById("detailbip38commands").style.display = "block";
|
||
document.getElementById("detailprivkeypassphrase").focus();
|
||
return;
|
||
}
|
||
var passphrase = document.getElementById("detailprivkeypassphrase").value.toString().replace(/^\s+|\s+$/g, ""); // trim white space
|
||
if (passphrase == "") {
|
||
alert(ninja.translator.get("bip38alertpassphraserequired"));
|
||
return;
|
||
}
|
||
document.getElementById("busyblock").className = "busy";
|
||
// show Private Key BIP38 Format
|
||
document.getElementById("detailprivbip38").innerHTML = key;
|
||
document.getElementById("detailbip38").style.display = "block";
|
||
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));
|
||
}
|
||
});
|
||
}
|
||
else {
|
||
if (Bitcoin.ECKey.isMiniFormat(key)) {
|
||
// show Private Key Mini Format
|
||
document.getElementById("detailprivmini").innerHTML = key;
|
||
document.getElementById("detailmini").style.display = "block";
|
||
}
|
||
else if (Bitcoin.ECKey.isBase6Format(key)) {
|
||
// show Private Key Base6 Format
|
||
document.getElementById("detailprivb6").innerHTML = key;
|
||
document.getElementById("detailb6").style.display = "block";
|
||
}
|
||
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("detailprivb6").innerHTML = "";
|
||
document.getElementById("detailprivmini").innerHTML = "";
|
||
document.getElementById("detailprivbip38").innerHTML = "";
|
||
document.getElementById("detailqrcodepublic").innerHTML = "";
|
||
document.getElementById("detailqrcodepubliccomp").innerHTML = "";
|
||
document.getElementById("detailqrcodeprivate").innerHTML = "";
|
||
document.getElementById("detailqrcodeprivatecomp").innerHTML = "";
|
||
document.getElementById("detailb6").style.display = "none";
|
||
document.getElementById("detailmini").style.display = "none";
|
||
document.getElementById("detailbip38commands").style.display = "none";
|
||
document.getElementById("detailbip38").style.display = "none";
|
||
}
|
||
};
|
||
</script>
|
||
<script type="text/javascript">
|
||
ninja.wallets.splitwallet = {
|
||
open: function () {
|
||
document.getElementById("splitarea").style.display = "block";
|
||
secrets.setRNG();
|
||
secrets.init(7); // 7 bits allows for up to 127 shares
|
||
},
|
||
|
||
close: function () {
|
||
document.getElementById("splitarea").style.display = "none";
|
||
},
|
||
|
||
mkOutputRow: function (s, id, lbltxt) {
|
||
var row = document.createElement("div");
|
||
var label = document.createElement("label");
|
||
label.innerHTML = lbltxt;
|
||
var qr = document.createElement("div");
|
||
var output = document.createElement("span");
|
||
output.setAttribute("class", "output");
|
||
output.innerHTML = s;
|
||
|
||
qr.setAttribute("id", id);
|
||
row.setAttribute("class", "splitsharerow");
|
||
row.appendChild(label);
|
||
row.appendChild(output);
|
||
row.appendChild(qr);
|
||
row.appendChild(document.createElement("br"));
|
||
|
||
return row;
|
||
},
|
||
|
||
stripLeadZeros: function (hex) { return hex.split(/^0+/).slice(-1)[0]; },
|
||
|
||
hexToBytes: function (hex) {
|
||
//if input has odd number of digits, pad it
|
||
if (hex.length % 2 == 1)
|
||
hex = "0" + hex;
|
||
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||
return bytes;
|
||
},
|
||
|
||
// Split a private key and update information in the HTML
|
||
splitKey: function () {
|
||
try {
|
||
var numshares = parseInt(document.getElementById('splitshares').value);
|
||
var threshold = parseInt(document.getElementById('splitthreshold').value);
|
||
var key = new Bitcoin.ECKey(false);
|
||
var bitcoinAddress = key.getBitcoinAddress();
|
||
var shares = ninja.wallets.splitwallet.getFormattedShares(key.getBitcoinHexFormat(), numshares, threshold);
|
||
|
||
var output = document.createElement("div");
|
||
output.setAttribute("id", "splitoutput");
|
||
var m = {};
|
||
output.appendChild(this.mkOutputRow(bitcoinAddress, "split_addr", "Bitcoin Address: "));
|
||
m["split_addr"] = bitcoinAddress;
|
||
|
||
for (var i = 0; i < shares.length; i++) {
|
||
var id = "split_qr_" + i;
|
||
output.appendChild(this.mkOutputRow(shares[i], id, "Share " + (i + 1) + ": "));
|
||
m[id] = shares[i];
|
||
}
|
||
|
||
document.getElementById("splitstep1area").innerHTML = output.innerHTML;
|
||
ninja.qrCode.showQrCode(m);
|
||
|
||
document.getElementById("splitstep1area").style.display = "block";
|
||
document.getElementById("splitstep1icon").setAttribute("class", "less");
|
||
}
|
||
catch (e) {
|
||
// browser does not have sufficient JavaScript support to generate a bitcoin address
|
||
alert(e);
|
||
}
|
||
},
|
||
|
||
// Combine shares of a private key to retrieve the key
|
||
combineShares: function () {
|
||
try {
|
||
document.getElementById("combinedprivatekey").innerHTML = "";
|
||
var shares = document.getElementById("combineinput").value.trim().split(/\W+/);
|
||
var combinedBytes = ninja.wallets.splitwallet.combineFormattedShares(shares);
|
||
var privkeyBase58 = new Bitcoin.ECKey(combinedBytes).getBitcoinWalletImportFormat();
|
||
document.getElementById("combinedprivatekey").innerHTML = privkeyBase58;
|
||
}
|
||
catch (e) {
|
||
alert(e);
|
||
}
|
||
},
|
||
|
||
// generate shares and format them in base58
|
||
getFormattedShares: function (key, numshares, threshold) {
|
||
var shares = secrets.share(key, numshares, threshold).map(ninja.wallets.splitwallet.hexToBytes).map(Bitcoin.Base58.encode);
|
||
return shares;
|
||
},
|
||
|
||
// combine base58 formatted shares and return a bitcoin byte array
|
||
combineFormattedShares: function (shares) {
|
||
var combined = secrets.combine(shares.map(Bitcoin.Base58.decode).map(Crypto.util.bytesToHex).map(ninja.wallets.splitwallet.stripLeadZeros));
|
||
return ninja.wallets.splitwallet.hexToBytes(combined);
|
||
},
|
||
|
||
openCloseStep: function (num) {
|
||
// do close
|
||
if (document.getElementById("splitstep" + num + "area").style.display == "block") {
|
||
document.getElementById("splitstep" + num + "area").style.display = "none";
|
||
document.getElementById("splitstep" + num + "icon").setAttribute("class", "more");
|
||
}
|
||
// do open
|
||
else {
|
||
document.getElementById("splitstep" + num + "area").style.display = "block";
|
||
document.getElementById("splitstep" + num + "icon").setAttribute("class", "less");
|
||
}
|
||
}
|
||
};
|
||
|
||
</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 baseKey = "100531114202410255230521444145414341221420541210522412225005202300434134213212540304311321323051431";
|
||
var hexKey = "292665C3872418ADF1DA7FFA3A646F2F0602246DA6098A91D229C32150F2718B";
|
||
var ecKey = new Bitcoin.ECKey(baseKey);
|
||
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;
|
||
},
|
||
|
||
// test split wallet
|
||
testSplitAndCombinePrivateKey2of2: function () {
|
||
// lowercase hex key
|
||
var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
|
||
var numshares = 2;
|
||
var threshold = 2;
|
||
secrets.setRNG();
|
||
secrets.init(7);
|
||
|
||
var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
|
||
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
|
||
var btcKey = new Bitcoin.ECKey(combined);
|
||
|
||
if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
// Example use case #1:
|
||
// Division of 3 shares:
|
||
// 1 share in a safety deposit box ("Box")
|
||
// 1 share at Home
|
||
// 1 share at Work
|
||
// Threshold of 2 can be redeemed in these permutations
|
||
// Home + Box
|
||
// Work + Box
|
||
// Home + Work
|
||
testSplitAndCombinePrivateKey2of3: function () {
|
||
// lowercase hex key
|
||
var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da"; //5HpJ4bpHFEMWYwCidjtZHwM2rsMh4PRfmZKV8Y21i7msiUkQKUW
|
||
var numshares = 3;
|
||
var threshold = 2;
|
||
secrets.setRNG();
|
||
secrets.init(7);
|
||
|
||
var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
|
||
shares.shift();
|
||
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
|
||
var btcKey = new Bitcoin.ECKey(combined);
|
||
|
||
if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
testSplitAndCombinePrivateKey2of4: function () {
|
||
// uppercase hex key
|
||
var key = "292665C3872418ADF1DA7FFA3A646F2F0602246DA6098A91D229C32150F2718B"; //5J8QhiQtAiozKwyk3GCycAscg1tNaYhNdiiLey8vaDK8Bzm4znb
|
||
var numshares = 4;
|
||
var threshold = 2;
|
||
secrets.setRNG();
|
||
secrets.init(7);
|
||
|
||
var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
|
||
shares.shift();
|
||
shares.shift();
|
||
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
|
||
var btcKey = new Bitcoin.ECKey(combined);
|
||
|
||
if (btcKey.getBitcoinHexFormat() != key) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
// Example use case #2:
|
||
// Division of 13 shares:
|
||
// 4 shares in a safety deposit box ("Box")
|
||
// 3 shares with good friend Angie
|
||
// 3 shares with good friend Fred
|
||
// 3 shares with Self at home or office
|
||
// Threshold of 7 can be redeemed in these permutations
|
||
// Self + Box (no trust to spend your coins but your friends are backing up your shares)
|
||
// Angie + Box (Angie will send btc to executor of your will)
|
||
// Fred + Box (if Angie hasn't already then Fred will send btc to executor of your will)
|
||
// Angie + Fred + Self (bank fire/theft then you with both your friends can spend the coins)
|
||
testSplitAndCombinePrivateKey7of13: function () {
|
||
var key = "0004d30da67214fa65a41a6493576944c7ea86713b14db437446c7a8df8e13da";
|
||
var numshares = 12;
|
||
var threshold = 7;
|
||
secrets.setRNG();
|
||
secrets.init(7);
|
||
|
||
var shares = ninja.wallets.splitwallet.getFormattedShares(key, numshares, threshold);
|
||
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
|
||
var btcKey = new Bitcoin.ECKey(combined);
|
||
|
||
if (btcKey.getBitcoinHexFormat() != key.toUpperCase()) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
testCombinePrivateKeyFromXofYShares: function () {
|
||
var key = "5K9nHKqbwc1xXpa6wV5p3AaCnubvxQDBukKaFkq7ThAkxgMTMEh";
|
||
// these are 4 of 6 shares
|
||
var shares = ["3XxjMASmrkk6eXMM9kAJA7qiqViNVBfiwA1GQDLvg4PVScL", "3Y2DkcPuNX8VKZwpnDdxw55wJtcnCvv2nALqe8nBLViHvck",
|
||
"3Y6qv7kyGwgRBKVHVbUNtzmLYAZWQtTPztPwR8wc7uf4MXR", "3YD4TowZn6jw5ss8U89vrcPHonFW4vSs9VKq8MupV5kevG4"]
|
||
secrets.setRNG();
|
||
secrets.init(7);
|
||
|
||
var combined = ninja.wallets.splitwallet.combineFormattedShares(shares);
|
||
var btcKey = new Bitcoin.ECKey(combined);
|
||
if (btcKey.getBitcoinWalletImportFormat() != key) {
|
||
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"]);
|
||
} else {
|
||
ninja.translator.autoDetectTranslation();
|
||
}
|
||
// 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 (ninja.getQueryString()["showseedpool"] == "true" || ninja.getQueryString()["showseedpool"] == "1") {
|
||
document.getElementById("seedpoolarea").style.display = "block";
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|