11425 lines
357 KiB
JavaScript
11425 lines
357 KiB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||
"use strict";
|
||
|
||
(function(root) {
|
||
|
||
function checkInt(value) {
|
||
return (parseInt(value) === value);
|
||
}
|
||
|
||
function checkInts(arrayish) {
|
||
if (!checkInt(arrayish.length)) { return false; }
|
||
|
||
for (var i = 0; i < arrayish.length; i++) {
|
||
if (!checkInt(arrayish[i]) || arrayish[i] < 0 || arrayish[i] > 255) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function coerceArray(arg, copy) {
|
||
|
||
// ArrayBuffer view
|
||
if (arg.buffer && ArrayBuffer.isView(arg) && arg.name === 'Uint8Array') {
|
||
|
||
if (copy) {
|
||
if (arg.slice) {
|
||
arg = arg.slice();
|
||
} else {
|
||
arg = Array.prototype.slice.call(arg);
|
||
}
|
||
}
|
||
|
||
return arg;
|
||
}
|
||
|
||
// It's an array; check it is a valid representation of a byte
|
||
if (Array.isArray(arg)) {
|
||
if (!checkInts(arg)) {
|
||
throw new Error('Array contains invalid value: ' + arg);
|
||
}
|
||
|
||
return new Uint8Array(arg);
|
||
}
|
||
|
||
// Something else, but behaves like an array (maybe a Buffer? Arguments?)
|
||
if (checkInt(arg.length) && checkInts(arg)) {
|
||
return new Uint8Array(arg);
|
||
}
|
||
|
||
throw new Error('unsupported array-like object');
|
||
}
|
||
|
||
function createArray(length) {
|
||
return new Uint8Array(length);
|
||
}
|
||
|
||
function copyArray(sourceArray, targetArray, targetStart, sourceStart, sourceEnd) {
|
||
if (sourceStart != null || sourceEnd != null) {
|
||
if (sourceArray.slice) {
|
||
sourceArray = sourceArray.slice(sourceStart, sourceEnd);
|
||
} else {
|
||
sourceArray = Array.prototype.slice.call(sourceArray, sourceStart, sourceEnd);
|
||
}
|
||
}
|
||
targetArray.set(sourceArray, targetStart);
|
||
}
|
||
|
||
|
||
|
||
var convertUtf8 = (function() {
|
||
function toBytes(text) {
|
||
var result = [], i = 0;
|
||
text = encodeURI(text);
|
||
while (i < text.length) {
|
||
var c = text.charCodeAt(i++);
|
||
|
||
// if it is a % sign, encode the following 2 bytes as a hex value
|
||
if (c === 37) {
|
||
result.push(parseInt(text.substr(i, 2), 16))
|
||
i += 2;
|
||
|
||
// otherwise, just the actual byte
|
||
} else {
|
||
result.push(c)
|
||
}
|
||
}
|
||
|
||
return coerceArray(result);
|
||
}
|
||
|
||
function fromBytes(bytes) {
|
||
var result = [], i = 0;
|
||
|
||
while (i < bytes.length) {
|
||
var c = bytes[i];
|
||
|
||
if (c < 128) {
|
||
result.push(String.fromCharCode(c));
|
||
i++;
|
||
} else if (c > 191 && c < 224) {
|
||
result.push(String.fromCharCode(((c & 0x1f) << 6) | (bytes[i + 1] & 0x3f)));
|
||
i += 2;
|
||
} else {
|
||
result.push(String.fromCharCode(((c & 0x0f) << 12) | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f)));
|
||
i += 3;
|
||
}
|
||
}
|
||
|
||
return result.join('');
|
||
}
|
||
|
||
return {
|
||
toBytes: toBytes,
|
||
fromBytes: fromBytes,
|
||
}
|
||
})();
|
||
|
||
var convertHex = (function() {
|
||
function toBytes(text) {
|
||
var result = [];
|
||
for (var i = 0; i < text.length; i += 2) {
|
||
result.push(parseInt(text.substr(i, 2), 16));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
// http://ixti.net/development/javascript/2011/11/11/base64-encodedecode-of-utf8-in-browser-with-js.html
|
||
var Hex = '0123456789abcdef';
|
||
|
||
function fromBytes(bytes) {
|
||
var result = [];
|
||
for (var i = 0; i < bytes.length; i++) {
|
||
var v = bytes[i];
|
||
result.push(Hex[(v & 0xf0) >> 4] + Hex[v & 0x0f]);
|
||
}
|
||
return result.join('');
|
||
}
|
||
|
||
return {
|
||
toBytes: toBytes,
|
||
fromBytes: fromBytes,
|
||
}
|
||
})();
|
||
|
||
|
||
// Number of rounds by keysize
|
||
var numberOfRounds = {16: 10, 24: 12, 32: 14}
|
||
|
||
// Round constant words
|
||
var rcon = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91];
|
||
|
||
// S-box and Inverse S-box (S is for Substitution)
|
||
var S = [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];
|
||
var Si =[0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d];
|
||
|
||
// Transformations for encryption
|
||
var T1 = [0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a];
|
||
var T2 = [0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616];
|
||
var T3 = [0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16];
|
||
var T4 = [0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c];
|
||
|
||
// Transformations for decryption
|
||
var T5 = [0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742];
|
||
var T6 = [0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10, 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95, 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857];
|
||
var T7 = [0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3, 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655, 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8];
|
||
var T8 = [0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff, 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0];
|
||
|
||
// Transformations for decryption key expansion
|
||
var U1 = [0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3];
|
||
var U2 = [0x00000000, 0x0b0e090d, 0x161c121a, 0x1d121b17, 0x2c382434, 0x27362d39, 0x3a24362e, 0x312a3f23, 0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f, 0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b, 0xb0e090d0, 0xbbee99dd, 0xa6fc82ca, 0xadf28bc7, 0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3, 0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af, 0xc4a8fc8c, 0xcfa6f581, 0xd2b4ee96, 0xd9bae79b, 0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac, 0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498, 0x23ab73d3, 0x28a57ade, 0x35b761c9, 0x3eb968c4, 0x0f9357e7, 0x049d5eea, 0x198f45fd, 0x12814cf0, 0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c, 0xe7038f5f, 0xec0d8652, 0xf11f9d45, 0xfa119448, 0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814, 0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20, 0xf6ad766d, 0xfda37f60, 0xe0b16477, 0xebbf6d7a, 0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e, 0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512, 0x82e51a31, 0x89eb133c, 0x94f9082b, 0x9ff70126, 0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa, 0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e, 0x1e3daed5, 0x1533a7d8, 0x0821bccf, 0x032fb5c2, 0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6, 0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1, 0xa14e69e2, 0xaa4060ef, 0xb7527bf8, 0xbc5c72f5, 0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9, 0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d, 0x3d96dd06, 0x3698d40b, 0x2b8acf1c, 0x2084c611, 0x11aef932, 0x1aa0f03f, 0x07b2eb28, 0x0cbce225, 0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79, 0x49deb15a, 0x42d0b857, 0x5fc2a340, 0x54ccaa4d, 0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd, 0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9, 0xaf31a4b2, 0xa43fadbf, 0xb92db6a8, 0xb223bfa5, 0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91, 0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d, 0x6b99583e, 0x60975133, 0x7d854a24, 0x768b4329, 0x1fd13462, 0x14df3d6f, 0x09cd2678, 0x02c32f75, 0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41, 0x8c9ad761, 0x8794de6c, 0x9a86c57b, 0x9188cc76, 0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842, 0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e, 0xf8d2bb3d, 0xf3dcb230, 0xeecea927, 0xe5c0a02a, 0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6, 0x10426385, 0x1b4c6a88, 0x065e719f, 0x0d507892, 0x640a0fd9, 0x6f0406d4, 0x72161dc3, 0x791814ce, 0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa, 0x01ec9ab7, 0x0ae293ba, 0x17f088ad, 0x1cfe81a0, 0x2dd4be83, 0x26dab78e, 0x3bc8ac99, 0x30c6a594, 0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8, 0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc, 0xb10c0a67, 0xba02036a, 0xa710187d, 0xac1e1170, 0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544, 0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918, 0xc544663b, 0xce4a6f36, 0xd3587421, 0xd8567d2c, 0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b, 0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f, 0x2247e964, 0x2949e069, 0x345bfb7e, 0x3f55f273, 0x0e7fcd50, 0x0571c45d, 0x1863df4a, 0x136dd647, 0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb, 0xe6ef15e8, 0xede11ce5, 0xf0f307f2, 0xfbfd0eff, 0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3, 0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697];
|
||
var U3 = [0x00000000, 0x0d0b0e09, 0x1a161c12, 0x171d121b, 0x342c3824, 0x3927362d, 0x2e3a2436, 0x23312a3f, 0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253, 0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77, 0xd0b0e090, 0xddbbee99, 0xcaa6fc82, 0xc7adf28b, 0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf, 0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3, 0x8cc4a8fc, 0x81cfa6f5, 0x96d2b4ee, 0x9bd9bae7, 0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920, 0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104, 0xd323ab73, 0xde28a57a, 0xc935b761, 0xc43eb968, 0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c, 0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0, 0x5fe7038f, 0x52ec0d86, 0x45f11f9d, 0x48fa1194, 0x03934be3, 0x0e9845ea, 0x198557f1, 0x148e59f8, 0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc, 0x6df6ad76, 0x60fda37f, 0x77e0b164, 0x7aebbf6d, 0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749, 0x05aedd3e, 0x08a5d337, 0x1fb8c12c, 0x12b3cf25, 0x3182e51a, 0x3c89eb13, 0x2b94f908, 0x269ff701, 0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd, 0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9, 0xd51e3dae, 0xd81533a7, 0xcf0821bc, 0xc2032fb5, 0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791, 0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456, 0xe2a14e69, 0xefaa4060, 0xf8b7527b, 0xf5bc5c72, 0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e, 0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a, 0x063d96dd, 0x0b3698d4, 0x1c2b8acf, 0x112084c6, 0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2, 0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e, 0x5a49deb1, 0x5742d0b8, 0x405fc2a3, 0x4d54ccaa, 0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7, 0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3, 0xb2af31a4, 0xbfa43fad, 0xa8b92db6, 0xa5b223bf, 0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b, 0x0a47a17c, 0x074caf75, 0x1051bd6e, 0x1d5ab367, 0x3e6b9958, 0x33609751, 0x247d854a, 0x29768b43, 0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f, 0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b, 0x618c9ad7, 0x6c8794de, 0x7b9a86c5, 0x769188cc, 0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8, 0x09d4ea9f, 0x04dfe496, 0x13c2f68d, 0x1ec9f884, 0x3df8d2bb, 0x30f3dcb2, 0x27eecea9, 0x2ae5c0a0, 0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c, 0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078, 0xd9640a0f, 0xd46f0406, 0xc372161d, 0xce791814, 0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030, 0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81, 0x832dd4be, 0x8e26dab7, 0x993bc8ac, 0x9430c6a5, 0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9, 0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed, 0x67b10c0a, 0x6aba0203, 0x7da71018, 0x70ac1e11, 0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635, 0x0fe97c42, 0x02e2724b, 0x15ff6050, 0x18f46e59, 0x3bc54466, 0x36ce4a6f, 0x21d35874, 0x2cd8567d, 0x0c7a37a1, 0x017139a8, 0x166c2bb3, 0x1b6725ba, 0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e, 0x642247e9, 0x692949e0, 0x7e345bfb, 0x733f55f2, 0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6, 0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a, 0xe8e6ef15, 0xe5ede11c, 0xf2f0f307, 0xfffbfd0e, 0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562, 0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46];
|
||
var U4 = [0x00000000, 0x090d0b0e, 0x121a161c, 0x1b171d12, 0x24342c38, 0x2d392736, 0x362e3a24, 0x3f23312a, 0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562, 0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a, 0x90d0b0e0, 0x99ddbbee, 0x82caa6fc, 0x8bc7adf2, 0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca, 0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582, 0xfc8cc4a8, 0xf581cfa6, 0xee96d2b4, 0xe79bd9ba, 0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9, 0x1f8f57e3, 0x16825ced, 0x0d9541ff, 0x04984af1, 0x73d323ab, 0x7ade28a5, 0x61c935b7, 0x68c43eb9, 0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281, 0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629, 0x8f5fe703, 0x8652ec0d, 0x9d45f11f, 0x9448fa11, 0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59, 0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261, 0x766df6ad, 0x7f60fda3, 0x6477e0b1, 0x6d7aebbf, 0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787, 0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf, 0x1a3182e5, 0x133c89eb, 0x082b94f9, 0x01269ff7, 0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f, 0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767, 0xaed51e3d, 0xa7d81533, 0xbccf0821, 0xb5c2032f, 0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17, 0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064, 0x69e2a14e, 0x60efaa40, 0x7bf8b752, 0x72f5bc5c, 0x05bed506, 0x0cb3de08, 0x17a4c31a, 0x1ea9c814, 0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c, 0xdd063d96, 0xd40b3698, 0xcf1c2b8a, 0xc6112084, 0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc, 0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4, 0xb15a49de, 0xb85742d0, 0xa3405fc2, 0xaa4d54cc, 0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53, 0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b, 0xa4b2af31, 0xadbfa43f, 0xb6a8b92d, 0xbfa5b223, 0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b, 0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3, 0x583e6b99, 0x51336097, 0x4a247d85, 0x4329768b, 0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3, 0x105633e9, 0x195b38e7, 0x024c25f5, 0x0b412efb, 0xd7618c9a, 0xde6c8794, 0xc57b9a86, 0xcc769188, 0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0, 0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8, 0xbb3df8d2, 0xb230f3dc, 0xa927eece, 0xa02ae5c0, 0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168, 0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50, 0x0fd9640a, 0x06d46f04, 0x1dc37216, 0x14ce7918, 0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520, 0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe, 0xbe832dd4, 0xb78e26da, 0xac993bc8, 0xa59430c6, 0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e, 0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6, 0x0a67b10c, 0x036aba02, 0x187da710, 0x1170ac1e, 0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026, 0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e, 0x663bc544, 0x6f36ce4a, 0x7421d358, 0x7d2cd856, 0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725, 0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d, 0xe9642247, 0xe0692949, 0xfb7e345b, 0xf2733f55, 0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d, 0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5, 0x15e8e6ef, 0x1ce5ede1, 0x07f2f0f3, 0x0efffbfd, 0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5, 0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d];
|
||
|
||
function convertToInt32(bytes) {
|
||
var result = [];
|
||
for (var i = 0; i < bytes.length; i += 4) {
|
||
result.push(
|
||
(bytes[i ] << 24) |
|
||
(bytes[i + 1] << 16) |
|
||
(bytes[i + 2] << 8) |
|
||
bytes[i + 3]
|
||
);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
var AES = function(key) {
|
||
if (!(this instanceof AES)) {
|
||
throw Error('AES must be instanitated with `new`');
|
||
}
|
||
|
||
Object.defineProperty(this, 'key', {
|
||
value: coerceArray(key, true)
|
||
});
|
||
|
||
this._prepare();
|
||
}
|
||
|
||
|
||
AES.prototype._prepare = function() {
|
||
|
||
var rounds = numberOfRounds[this.key.length];
|
||
if (rounds == null) {
|
||
throw new Error('invalid key size (must be 16, 24 or 32 bytes)');
|
||
}
|
||
|
||
// encryption round keys
|
||
this._Ke = [];
|
||
|
||
// decryption round keys
|
||
this._Kd = [];
|
||
|
||
for (var i = 0; i <= rounds; i++) {
|
||
this._Ke.push([0, 0, 0, 0]);
|
||
this._Kd.push([0, 0, 0, 0]);
|
||
}
|
||
|
||
var roundKeyCount = (rounds + 1) * 4;
|
||
var KC = this.key.length / 4;
|
||
|
||
// convert the key into ints
|
||
var tk = convertToInt32(this.key);
|
||
|
||
// copy values into round key arrays
|
||
var index;
|
||
for (var i = 0; i < KC; i++) {
|
||
index = i >> 2;
|
||
this._Ke[index][i % 4] = tk[i];
|
||
this._Kd[rounds - index][i % 4] = tk[i];
|
||
}
|
||
|
||
// key expansion (fips-197 section 5.2)
|
||
var rconpointer = 0;
|
||
var t = KC, tt;
|
||
while (t < roundKeyCount) {
|
||
tt = tk[KC - 1];
|
||
tk[0] ^= ((S[(tt >> 16) & 0xFF] << 24) ^
|
||
(S[(tt >> 8) & 0xFF] << 16) ^
|
||
(S[ tt & 0xFF] << 8) ^
|
||
S[(tt >> 24) & 0xFF] ^
|
||
(rcon[rconpointer] << 24));
|
||
rconpointer += 1;
|
||
|
||
// key expansion (for non-256 bit)
|
||
if (KC != 8) {
|
||
for (var i = 1; i < KC; i++) {
|
||
tk[i] ^= tk[i - 1];
|
||
}
|
||
|
||
// key expansion for 256-bit keys is "slightly different" (fips-197)
|
||
} else {
|
||
for (var i = 1; i < (KC / 2); i++) {
|
||
tk[i] ^= tk[i - 1];
|
||
}
|
||
tt = tk[(KC / 2) - 1];
|
||
|
||
tk[KC / 2] ^= (S[ tt & 0xFF] ^
|
||
(S[(tt >> 8) & 0xFF] << 8) ^
|
||
(S[(tt >> 16) & 0xFF] << 16) ^
|
||
(S[(tt >> 24) & 0xFF] << 24));
|
||
|
||
for (var i = (KC / 2) + 1; i < KC; i++) {
|
||
tk[i] ^= tk[i - 1];
|
||
}
|
||
}
|
||
|
||
// copy values into round key arrays
|
||
var i = 0, r, c;
|
||
while (i < KC && t < roundKeyCount) {
|
||
r = t >> 2;
|
||
c = t % 4;
|
||
this._Ke[r][c] = tk[i];
|
||
this._Kd[rounds - r][c] = tk[i++];
|
||
t++;
|
||
}
|
||
}
|
||
|
||
// inverse-cipher-ify the decryption round key (fips-197 section 5.3)
|
||
for (var r = 1; r < rounds; r++) {
|
||
for (var c = 0; c < 4; c++) {
|
||
tt = this._Kd[r][c];
|
||
this._Kd[r][c] = (U1[(tt >> 24) & 0xFF] ^
|
||
U2[(tt >> 16) & 0xFF] ^
|
||
U3[(tt >> 8) & 0xFF] ^
|
||
U4[ tt & 0xFF]);
|
||
}
|
||
}
|
||
}
|
||
|
||
AES.prototype.encrypt = function(plaintext) {
|
||
if (plaintext.length != 16) {
|
||
throw new Error('invalid plaintext size (must be 16 bytes)');
|
||
}
|
||
|
||
var rounds = this._Ke.length - 1;
|
||
var a = [0, 0, 0, 0];
|
||
|
||
// convert plaintext to (ints ^ key)
|
||
var t = convertToInt32(plaintext);
|
||
for (var i = 0; i < 4; i++) {
|
||
t[i] ^= this._Ke[0][i];
|
||
}
|
||
|
||
// apply round transforms
|
||
for (var r = 1; r < rounds; r++) {
|
||
for (var i = 0; i < 4; i++) {
|
||
a[i] = (T1[(t[ i ] >> 24) & 0xff] ^
|
||
T2[(t[(i + 1) % 4] >> 16) & 0xff] ^
|
||
T3[(t[(i + 2) % 4] >> 8) & 0xff] ^
|
||
T4[ t[(i + 3) % 4] & 0xff] ^
|
||
this._Ke[r][i]);
|
||
}
|
||
t = a.slice();
|
||
}
|
||
|
||
// the last round is special
|
||
var result = createArray(16), tt;
|
||
for (var i = 0; i < 4; i++) {
|
||
tt = this._Ke[rounds][i];
|
||
result[4 * i ] = (S[(t[ i ] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
|
||
result[4 * i + 1] = (S[(t[(i + 1) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
|
||
result[4 * i + 2] = (S[(t[(i + 2) % 4] >> 8) & 0xff] ^ (tt >> 8)) & 0xff;
|
||
result[4 * i + 3] = (S[ t[(i + 3) % 4] & 0xff] ^ tt ) & 0xff;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
AES.prototype.decrypt = function(ciphertext) {
|
||
if (ciphertext.length != 16) {
|
||
throw new Error('invalid ciphertext size (must be 16 bytes)');
|
||
}
|
||
|
||
var rounds = this._Kd.length - 1;
|
||
var a = [0, 0, 0, 0];
|
||
|
||
// convert plaintext to (ints ^ key)
|
||
var t = convertToInt32(ciphertext);
|
||
for (var i = 0; i < 4; i++) {
|
||
t[i] ^= this._Kd[0][i];
|
||
}
|
||
|
||
// apply round transforms
|
||
for (var r = 1; r < rounds; r++) {
|
||
for (var i = 0; i < 4; i++) {
|
||
a[i] = (T5[(t[ i ] >> 24) & 0xff] ^
|
||
T6[(t[(i + 3) % 4] >> 16) & 0xff] ^
|
||
T7[(t[(i + 2) % 4] >> 8) & 0xff] ^
|
||
T8[ t[(i + 1) % 4] & 0xff] ^
|
||
this._Kd[r][i]);
|
||
}
|
||
t = a.slice();
|
||
}
|
||
|
||
// the last round is special
|
||
var result = createArray(16), tt;
|
||
for (var i = 0; i < 4; i++) {
|
||
tt = this._Kd[rounds][i];
|
||
result[4 * i ] = (Si[(t[ i ] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
|
||
result[4 * i + 1] = (Si[(t[(i + 3) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
|
||
result[4 * i + 2] = (Si[(t[(i + 2) % 4] >> 8) & 0xff] ^ (tt >> 8)) & 0xff;
|
||
result[4 * i + 3] = (Si[ t[(i + 1) % 4] & 0xff] ^ tt ) & 0xff;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
/**
|
||
* Mode Of Operation - Electonic Codebook (ECB)
|
||
*/
|
||
var ModeOfOperationECB = function(key) {
|
||
if (!(this instanceof ModeOfOperationECB)) {
|
||
throw Error('AES must be instanitated with `new`');
|
||
}
|
||
|
||
this.description = "Electronic Code Block";
|
||
this.name = "ecb";
|
||
|
||
this._aes = new AES(key);
|
||
}
|
||
|
||
ModeOfOperationECB.prototype.encrypt = function(plaintext) {
|
||
plaintext = coerceArray(plaintext);
|
||
|
||
if ((plaintext.length % 16) !== 0) {
|
||
throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
|
||
}
|
||
|
||
var ciphertext = createArray(plaintext.length);
|
||
var block = createArray(16);
|
||
|
||
for (var i = 0; i < plaintext.length; i += 16) {
|
||
copyArray(plaintext, block, 0, i, i + 16);
|
||
block = this._aes.encrypt(block);
|
||
copyArray(block, ciphertext, i);
|
||
}
|
||
|
||
return ciphertext;
|
||
}
|
||
|
||
ModeOfOperationECB.prototype.decrypt = function(ciphertext) {
|
||
ciphertext = coerceArray(ciphertext);
|
||
|
||
if ((ciphertext.length % 16) !== 0) {
|
||
throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
|
||
}
|
||
|
||
var plaintext = createArray(ciphertext.length);
|
||
var block = createArray(16);
|
||
|
||
for (var i = 0; i < ciphertext.length; i += 16) {
|
||
copyArray(ciphertext, block, 0, i, i + 16);
|
||
block = this._aes.decrypt(block);
|
||
copyArray(block, plaintext, i);
|
||
}
|
||
|
||
return plaintext;
|
||
}
|
||
|
||
|
||
/**
|
||
* Mode Of Operation - Cipher Block Chaining (CBC)
|
||
*/
|
||
var ModeOfOperationCBC = function(key, iv) {
|
||
if (!(this instanceof ModeOfOperationCBC)) {
|
||
throw Error('AES must be instanitated with `new`');
|
||
}
|
||
|
||
this.description = "Cipher Block Chaining";
|
||
this.name = "cbc";
|
||
|
||
if (!iv) {
|
||
iv = createArray(16);
|
||
|
||
} else if (iv.length != 16) {
|
||
throw new Error('invalid initialation vector size (must be 16 bytes)');
|
||
}
|
||
|
||
this._lastCipherblock = coerceArray(iv, true);
|
||
|
||
this._aes = new AES(key);
|
||
}
|
||
|
||
ModeOfOperationCBC.prototype.encrypt = function(plaintext) {
|
||
plaintext = coerceArray(plaintext);
|
||
|
||
if ((plaintext.length % 16) !== 0) {
|
||
throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
|
||
}
|
||
|
||
var ciphertext = createArray(plaintext.length);
|
||
var block = createArray(16);
|
||
|
||
for (var i = 0; i < plaintext.length; i += 16) {
|
||
copyArray(plaintext, block, 0, i, i + 16);
|
||
|
||
for (var j = 0; j < 16; j++) {
|
||
block[j] ^= this._lastCipherblock[j];
|
||
}
|
||
|
||
this._lastCipherblock = this._aes.encrypt(block);
|
||
copyArray(this._lastCipherblock, ciphertext, i);
|
||
}
|
||
|
||
return ciphertext;
|
||
}
|
||
|
||
ModeOfOperationCBC.prototype.decrypt = function(ciphertext) {
|
||
ciphertext = coerceArray(ciphertext);
|
||
|
||
if ((ciphertext.length % 16) !== 0) {
|
||
throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
|
||
}
|
||
|
||
var plaintext = createArray(ciphertext.length);
|
||
var block = createArray(16);
|
||
|
||
for (var i = 0; i < ciphertext.length; i += 16) {
|
||
copyArray(ciphertext, block, 0, i, i + 16);
|
||
block = this._aes.decrypt(block);
|
||
|
||
for (var j = 0; j < 16; j++) {
|
||
plaintext[i + j] = block[j] ^ this._lastCipherblock[j];
|
||
}
|
||
|
||
copyArray(ciphertext, this._lastCipherblock, 0, i, i + 16);
|
||
}
|
||
|
||
return plaintext;
|
||
}
|
||
|
||
|
||
/**
|
||
* Mode Of Operation - Cipher Feedback (CFB)
|
||
*/
|
||
var ModeOfOperationCFB = function(key, iv, segmentSize) {
|
||
if (!(this instanceof ModeOfOperationCFB)) {
|
||
throw Error('AES must be instanitated with `new`');
|
||
}
|
||
|
||
this.description = "Cipher Feedback";
|
||
this.name = "cfb";
|
||
|
||
if (!iv) {
|
||
iv = createArray(16);
|
||
|
||
} else if (iv.length != 16) {
|
||
throw new Error('invalid initialation vector size (must be 16 size)');
|
||
}
|
||
|
||
if (!segmentSize) { segmentSize = 1; }
|
||
|
||
this.segmentSize = segmentSize;
|
||
|
||
this._shiftRegister = coerceArray(iv, true);
|
||
|
||
this._aes = new AES(key);
|
||
}
|
||
|
||
ModeOfOperationCFB.prototype.encrypt = function(plaintext) {
|
||
if ((plaintext.length % this.segmentSize) != 0) {
|
||
throw new Error('invalid plaintext size (must be segmentSize bytes)');
|
||
}
|
||
|
||
var encrypted = coerceArray(plaintext, true);
|
||
|
||
var xorSegment;
|
||
for (var i = 0; i < encrypted.length; i += this.segmentSize) {
|
||
xorSegment = this._aes.encrypt(this._shiftRegister);
|
||
for (var j = 0; j < this.segmentSize; j++) {
|
||
encrypted[i + j] ^= xorSegment[j];
|
||
}
|
||
|
||
// Shift the register
|
||
copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
|
||
copyArray(encrypted, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
|
||
}
|
||
|
||
return encrypted;
|
||
}
|
||
|
||
ModeOfOperationCFB.prototype.decrypt = function(ciphertext) {
|
||
if ((ciphertext.length % this.segmentSize) != 0) {
|
||
throw new Error('invalid ciphertext size (must be segmentSize bytes)');
|
||
}
|
||
|
||
var plaintext = coerceArray(ciphertext, true);
|
||
|
||
var xorSegment;
|
||
for (var i = 0; i < plaintext.length; i += this.segmentSize) {
|
||
xorSegment = this._aes.encrypt(this._shiftRegister);
|
||
|
||
for (var j = 0; j < this.segmentSize; j++) {
|
||
plaintext[i + j] ^= xorSegment[j];
|
||
}
|
||
|
||
// Shift the register
|
||
copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
|
||
copyArray(ciphertext, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
|
||
}
|
||
|
||
return plaintext;
|
||
}
|
||
|
||
/**
|
||
* Mode Of Operation - Output Feedback (OFB)
|
||
*/
|
||
var ModeOfOperationOFB = function(key, iv) {
|
||
if (!(this instanceof ModeOfOperationOFB)) {
|
||
throw Error('AES must be instanitated with `new`');
|
||
}
|
||
|
||
this.description = "Output Feedback";
|
||
this.name = "ofb";
|
||
|
||
if (!iv) {
|
||
iv = createArray(16);
|
||
|
||
} else if (iv.length != 16) {
|
||
throw new Error('invalid initialation vector size (must be 16 bytes)');
|
||
}
|
||
|
||
this._lastPrecipher = coerceArray(iv, true);
|
||
this._lastPrecipherIndex = 16;
|
||
|
||
this._aes = new AES(key);
|
||
}
|
||
|
||
ModeOfOperationOFB.prototype.encrypt = function(plaintext) {
|
||
var encrypted = coerceArray(plaintext, true);
|
||
|
||
for (var i = 0; i < encrypted.length; i++) {
|
||
if (this._lastPrecipherIndex === 16) {
|
||
this._lastPrecipher = this._aes.encrypt(this._lastPrecipher);
|
||
this._lastPrecipherIndex = 0;
|
||
}
|
||
encrypted[i] ^= this._lastPrecipher[this._lastPrecipherIndex++];
|
||
}
|
||
|
||
return encrypted;
|
||
}
|
||
|
||
// Decryption is symetric
|
||
ModeOfOperationOFB.prototype.decrypt = ModeOfOperationOFB.prototype.encrypt;
|
||
|
||
|
||
/**
|
||
* Counter object for CTR common mode of operation
|
||
*/
|
||
var Counter = function(initialValue) {
|
||
if (!(this instanceof Counter)) {
|
||
throw Error('Counter must be instanitated with `new`');
|
||
}
|
||
|
||
// We allow 0, but anything false-ish uses the default 1
|
||
if (initialValue !== 0 && !initialValue) { initialValue = 1; }
|
||
|
||
if (typeof(initialValue) === 'number') {
|
||
this._counter = createArray(16);
|
||
this.setValue(initialValue);
|
||
|
||
} else {
|
||
this.setBytes(initialValue);
|
||
}
|
||
}
|
||
|
||
Counter.prototype.setValue = function(value) {
|
||
if (typeof(value) !== 'number' || parseInt(value) != value) {
|
||
throw new Error('invalid counter value (must be an integer)');
|
||
}
|
||
|
||
for (var index = 15; index >= 0; --index) {
|
||
this._counter[index] = value % 256;
|
||
value = value >> 8;
|
||
}
|
||
}
|
||
|
||
Counter.prototype.setBytes = function(bytes) {
|
||
bytes = coerceArray(bytes, true);
|
||
|
||
if (bytes.length != 16) {
|
||
throw new Error('invalid counter bytes size (must be 16 bytes)');
|
||
}
|
||
|
||
this._counter = bytes;
|
||
};
|
||
|
||
Counter.prototype.increment = function() {
|
||
for (var i = 15; i >= 0; i--) {
|
||
if (this._counter[i] === 255) {
|
||
this._counter[i] = 0;
|
||
} else {
|
||
this._counter[i]++;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Mode Of Operation - Counter (CTR)
|
||
*/
|
||
var ModeOfOperationCTR = function(key, counter) {
|
||
if (!(this instanceof ModeOfOperationCTR)) {
|
||
throw Error('AES must be instanitated with `new`');
|
||
}
|
||
|
||
this.description = "Counter";
|
||
this.name = "ctr";
|
||
|
||
if (!(counter instanceof Counter)) {
|
||
counter = new Counter(counter)
|
||
}
|
||
|
||
this._counter = counter;
|
||
|
||
this._remainingCounter = null;
|
||
this._remainingCounterIndex = 16;
|
||
|
||
this._aes = new AES(key);
|
||
}
|
||
|
||
ModeOfOperationCTR.prototype.encrypt = function(plaintext) {
|
||
var encrypted = coerceArray(plaintext, true);
|
||
|
||
for (var i = 0; i < encrypted.length; i++) {
|
||
if (this._remainingCounterIndex === 16) {
|
||
this._remainingCounter = this._aes.encrypt(this._counter._counter);
|
||
this._remainingCounterIndex = 0;
|
||
this._counter.increment();
|
||
}
|
||
encrypted[i] ^= this._remainingCounter[this._remainingCounterIndex++];
|
||
}
|
||
|
||
return encrypted;
|
||
}
|
||
|
||
// Decryption is symetric
|
||
ModeOfOperationCTR.prototype.decrypt = ModeOfOperationCTR.prototype.encrypt;
|
||
|
||
|
||
///////////////////////
|
||
// Padding
|
||
|
||
// See:https://tools.ietf.org/html/rfc2315
|
||
function pkcs7pad(data) {
|
||
data = coerceArray(data, true);
|
||
var padder = 16 - (data.length % 16);
|
||
var result = createArray(data.length + padder);
|
||
copyArray(data, result);
|
||
for (var i = data.length; i < result.length; i++) {
|
||
result[i] = padder;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
function pkcs7strip(data) {
|
||
data = coerceArray(data, true);
|
||
if (data.length < 16) { throw new Error('PKCS#7 invalid length'); }
|
||
|
||
var padder = data[data.length - 1];
|
||
if (padder > 16) { throw new Error('PKCS#7 padding byte out of range'); }
|
||
|
||
var length = data.length - padder;
|
||
for (var i = 0; i < padder; i++) {
|
||
if (data[length + i] !== padder) {
|
||
throw new Error('PKCS#7 invalid padding byte');
|
||
}
|
||
}
|
||
|
||
var result = createArray(length);
|
||
copyArray(data, result, 0, 0, length);
|
||
return result;
|
||
}
|
||
|
||
///////////////////////
|
||
// Exporting
|
||
|
||
|
||
// The block cipher
|
||
var aesjs = {
|
||
AES: AES,
|
||
Counter: Counter,
|
||
|
||
ModeOfOperation: {
|
||
ecb: ModeOfOperationECB,
|
||
cbc: ModeOfOperationCBC,
|
||
cfb: ModeOfOperationCFB,
|
||
ofb: ModeOfOperationOFB,
|
||
ctr: ModeOfOperationCTR
|
||
},
|
||
|
||
utils: {
|
||
hex: convertHex,
|
||
utf8: convertUtf8
|
||
},
|
||
|
||
padding: {
|
||
pkcs7: {
|
||
pad: pkcs7pad,
|
||
strip: pkcs7strip
|
||
}
|
||
},
|
||
|
||
_arrayTest: {
|
||
coerceArray: coerceArray,
|
||
createArray: createArray,
|
||
copyArray: copyArray,
|
||
}
|
||
};
|
||
|
||
|
||
// node.js
|
||
if (typeof exports !== 'undefined') {
|
||
module.exports = aesjs
|
||
|
||
// RequireJS/AMD
|
||
// http://www.requirejs.org/docs/api.html
|
||
// https://github.com/amdjs/amdjs-api/wiki/AMD
|
||
} else if (typeof(define) === 'function' && define.amd) {
|
||
define(aesjs);
|
||
|
||
// Web Browsers
|
||
} else {
|
||
|
||
// If there was an existing library at "aesjs" make sure it's still available
|
||
if (root.aesjs) {
|
||
aesjs._aesjs = root.aesjs;
|
||
}
|
||
|
||
root.aesjs = aesjs;
|
||
}
|
||
|
||
|
||
})(this);
|
||
|
||
},{}],2:[function(require,module,exports){
|
||
(function (module, exports) {
|
||
'use strict';
|
||
|
||
// Utils
|
||
function assert (val, msg) {
|
||
if (!val) throw new Error(msg || 'Assertion failed');
|
||
}
|
||
|
||
// Could use `inherits` module, but don't want to move from single file
|
||
// architecture yet.
|
||
function inherits (ctor, superCtor) {
|
||
ctor.super_ = superCtor;
|
||
var TempCtor = function () {};
|
||
TempCtor.prototype = superCtor.prototype;
|
||
ctor.prototype = new TempCtor();
|
||
ctor.prototype.constructor = ctor;
|
||
}
|
||
|
||
// BN
|
||
|
||
function BN (number, base, endian) {
|
||
if (BN.isBN(number)) {
|
||
return number;
|
||
}
|
||
|
||
this.negative = 0;
|
||
this.words = null;
|
||
this.length = 0;
|
||
|
||
// Reduction context
|
||
this.red = null;
|
||
|
||
if (number !== null) {
|
||
if (base === 'le' || base === 'be') {
|
||
endian = base;
|
||
base = 10;
|
||
}
|
||
|
||
this._init(number || 0, base || 10, endian || 'be');
|
||
}
|
||
}
|
||
if (typeof module === 'object') {
|
||
module.exports = BN;
|
||
} else {
|
||
exports.BN = BN;
|
||
}
|
||
|
||
BN.BN = BN;
|
||
BN.wordSize = 26;
|
||
|
||
var Buffer;
|
||
try {
|
||
Buffer = require('buffer').Buffer;
|
||
} catch (e) {
|
||
}
|
||
|
||
BN.isBN = function isBN (num) {
|
||
if (num instanceof BN) {
|
||
return true;
|
||
}
|
||
|
||
return num !== null && typeof num === 'object' &&
|
||
num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
|
||
};
|
||
|
||
BN.max = function max (left, right) {
|
||
if (left.cmp(right) > 0) return left;
|
||
return right;
|
||
};
|
||
|
||
BN.min = function min (left, right) {
|
||
if (left.cmp(right) < 0) return left;
|
||
return right;
|
||
};
|
||
|
||
BN.prototype._init = function init (number, base, endian) {
|
||
if (typeof number === 'number') {
|
||
return this._initNumber(number, base, endian);
|
||
}
|
||
|
||
if (typeof number === 'object') {
|
||
return this._initArray(number, base, endian);
|
||
}
|
||
|
||
if (base === 'hex') {
|
||
base = 16;
|
||
}
|
||
assert(base === (base | 0) && base >= 2 && base <= 36);
|
||
|
||
number = number.toString().replace(/\s+/g, '');
|
||
var start = 0;
|
||
if (number[0] === '-') {
|
||
start++;
|
||
}
|
||
|
||
if (base === 16) {
|
||
this._parseHex(number, start);
|
||
} else {
|
||
this._parseBase(number, base, start);
|
||
}
|
||
|
||
if (number[0] === '-') {
|
||
this.negative = 1;
|
||
}
|
||
|
||
this.strip();
|
||
|
||
if (endian !== 'le') return;
|
||
|
||
this._initArray(this.toArray(), base, endian);
|
||
};
|
||
|
||
BN.prototype._initNumber = function _initNumber (number, base, endian) {
|
||
if (number < 0) {
|
||
this.negative = 1;
|
||
number = -number;
|
||
}
|
||
if (number < 0x4000000) {
|
||
this.words = [ number & 0x3ffffff ];
|
||
this.length = 1;
|
||
} else if (number < 0x10000000000000) {
|
||
this.words = [
|
||
number & 0x3ffffff,
|
||
(number / 0x4000000) & 0x3ffffff
|
||
];
|
||
this.length = 2;
|
||
} else {
|
||
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
|
||
this.words = [
|
||
number & 0x3ffffff,
|
||
(number / 0x4000000) & 0x3ffffff,
|
||
1
|
||
];
|
||
this.length = 3;
|
||
}
|
||
|
||
if (endian !== 'le') return;
|
||
|
||
// Reverse the bytes
|
||
this._initArray(this.toArray(), base, endian);
|
||
};
|
||
|
||
BN.prototype._initArray = function _initArray (number, base, endian) {
|
||
// Perhaps a Uint8Array
|
||
assert(typeof number.length === 'number');
|
||
if (number.length <= 0) {
|
||
this.words = [ 0 ];
|
||
this.length = 1;
|
||
return this;
|
||
}
|
||
|
||
this.length = Math.ceil(number.length / 3);
|
||
this.words = new Array(this.length);
|
||
for (var i = 0; i < this.length; i++) {
|
||
this.words[i] = 0;
|
||
}
|
||
|
||
var j, w;
|
||
var off = 0;
|
||
if (endian === 'be') {
|
||
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
|
||
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
||
off += 24;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
j++;
|
||
}
|
||
}
|
||
} else if (endian === 'le') {
|
||
for (i = 0, j = 0; i < number.length; i += 3) {
|
||
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
|
||
off += 24;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
j++;
|
||
}
|
||
}
|
||
}
|
||
return this.strip();
|
||
};
|
||
|
||
function parseHex (str, start, end) {
|
||
var r = 0;
|
||
var len = Math.min(str.length, end);
|
||
for (var i = start; i < len; i++) {
|
||
var c = str.charCodeAt(i) - 48;
|
||
|
||
r <<= 4;
|
||
|
||
// 'a' - 'f'
|
||
if (c >= 49 && c <= 54) {
|
||
r |= c - 49 + 0xa;
|
||
|
||
// 'A' - 'F'
|
||
} else if (c >= 17 && c <= 22) {
|
||
r |= c - 17 + 0xa;
|
||
|
||
// '0' - '9'
|
||
} else {
|
||
r |= c & 0xf;
|
||
}
|
||
}
|
||
return r;
|
||
}
|
||
|
||
BN.prototype._parseHex = function _parseHex (number, start) {
|
||
// Create possibly bigger array to ensure that it fits the number
|
||
this.length = Math.ceil((number.length - start) / 6);
|
||
this.words = new Array(this.length);
|
||
for (var i = 0; i < this.length; i++) {
|
||
this.words[i] = 0;
|
||
}
|
||
|
||
var j, w;
|
||
// Scan 24-bit chunks and add them to the number
|
||
var off = 0;
|
||
for (i = number.length - 6, j = 0; i >= start; i -= 6) {
|
||
w = parseHex(number, i, i + 6);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
// NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
|
||
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
||
off += 24;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
j++;
|
||
}
|
||
}
|
||
if (i + 6 !== start) {
|
||
w = parseHex(number, start, i + 6);
|
||
this.words[j] |= (w << off) & 0x3ffffff;
|
||
this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
|
||
}
|
||
this.strip();
|
||
};
|
||
|
||
function parseBase (str, start, end, mul) {
|
||
var r = 0;
|
||
var len = Math.min(str.length, end);
|
||
for (var i = start; i < len; i++) {
|
||
var c = str.charCodeAt(i) - 48;
|
||
|
||
r *= mul;
|
||
|
||
// 'a'
|
||
if (c >= 49) {
|
||
r += c - 49 + 0xa;
|
||
|
||
// 'A'
|
||
} else if (c >= 17) {
|
||
r += c - 17 + 0xa;
|
||
|
||
// '0' - '9'
|
||
} else {
|
||
r += c;
|
||
}
|
||
}
|
||
return r;
|
||
}
|
||
|
||
BN.prototype._parseBase = function _parseBase (number, base, start) {
|
||
// Initialize as zero
|
||
this.words = [ 0 ];
|
||
this.length = 1;
|
||
|
||
// Find length of limb in base
|
||
for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
|
||
limbLen++;
|
||
}
|
||
limbLen--;
|
||
limbPow = (limbPow / base) | 0;
|
||
|
||
var total = number.length - start;
|
||
var mod = total % limbLen;
|
||
var end = Math.min(total, total - mod) + start;
|
||
|
||
var word = 0;
|
||
for (var i = start; i < end; i += limbLen) {
|
||
word = parseBase(number, i, i + limbLen, base);
|
||
|
||
this.imuln(limbPow);
|
||
if (this.words[0] + word < 0x4000000) {
|
||
this.words[0] += word;
|
||
} else {
|
||
this._iaddn(word);
|
||
}
|
||
}
|
||
|
||
if (mod !== 0) {
|
||
var pow = 1;
|
||
word = parseBase(number, i, number.length, base);
|
||
|
||
for (i = 0; i < mod; i++) {
|
||
pow *= base;
|
||
}
|
||
|
||
this.imuln(pow);
|
||
if (this.words[0] + word < 0x4000000) {
|
||
this.words[0] += word;
|
||
} else {
|
||
this._iaddn(word);
|
||
}
|
||
}
|
||
};
|
||
|
||
BN.prototype.copy = function copy (dest) {
|
||
dest.words = new Array(this.length);
|
||
for (var i = 0; i < this.length; i++) {
|
||
dest.words[i] = this.words[i];
|
||
}
|
||
dest.length = this.length;
|
||
dest.negative = this.negative;
|
||
dest.red = this.red;
|
||
};
|
||
|
||
BN.prototype.clone = function clone () {
|
||
var r = new BN(null);
|
||
this.copy(r);
|
||
return r;
|
||
};
|
||
|
||
BN.prototype._expand = function _expand (size) {
|
||
while (this.length < size) {
|
||
this.words[this.length++] = 0;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
// Remove leading `0` from `this`
|
||
BN.prototype.strip = function strip () {
|
||
while (this.length > 1 && this.words[this.length - 1] === 0) {
|
||
this.length--;
|
||
}
|
||
return this._normSign();
|
||
};
|
||
|
||
BN.prototype._normSign = function _normSign () {
|
||
// -0 = 0
|
||
if (this.length === 1 && this.words[0] === 0) {
|
||
this.negative = 0;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.inspect = function inspect () {
|
||
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
|
||
};
|
||
|
||
/*
|
||
|
||
var zeros = [];
|
||
var groupSizes = [];
|
||
var groupBases = [];
|
||
|
||
var s = '';
|
||
var i = -1;
|
||
while (++i < BN.wordSize) {
|
||
zeros[i] = s;
|
||
s += '0';
|
||
}
|
||
groupSizes[0] = 0;
|
||
groupSizes[1] = 0;
|
||
groupBases[0] = 0;
|
||
groupBases[1] = 0;
|
||
var base = 2 - 1;
|
||
while (++base < 36 + 1) {
|
||
var groupSize = 0;
|
||
var groupBase = 1;
|
||
while (groupBase < (1 << BN.wordSize) / base) {
|
||
groupBase *= base;
|
||
groupSize += 1;
|
||
}
|
||
groupSizes[base] = groupSize;
|
||
groupBases[base] = groupBase;
|
||
}
|
||
|
||
*/
|
||
|
||
var zeros = [
|
||
'',
|
||
'0',
|
||
'00',
|
||
'000',
|
||
'0000',
|
||
'00000',
|
||
'000000',
|
||
'0000000',
|
||
'00000000',
|
||
'000000000',
|
||
'0000000000',
|
||
'00000000000',
|
||
'000000000000',
|
||
'0000000000000',
|
||
'00000000000000',
|
||
'000000000000000',
|
||
'0000000000000000',
|
||
'00000000000000000',
|
||
'000000000000000000',
|
||
'0000000000000000000',
|
||
'00000000000000000000',
|
||
'000000000000000000000',
|
||
'0000000000000000000000',
|
||
'00000000000000000000000',
|
||
'000000000000000000000000',
|
||
'0000000000000000000000000'
|
||
];
|
||
|
||
var groupSizes = [
|
||
0, 0,
|
||
25, 16, 12, 11, 10, 9, 8,
|
||
8, 7, 7, 7, 7, 6, 6,
|
||
6, 6, 6, 6, 6, 5, 5,
|
||
5, 5, 5, 5, 5, 5, 5,
|
||
5, 5, 5, 5, 5, 5, 5
|
||
];
|
||
|
||
var groupBases = [
|
||
0, 0,
|
||
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
|
||
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
|
||
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
|
||
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
|
||
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
|
||
];
|
||
|
||
BN.prototype.toString = function toString (base, padding) {
|
||
base = base || 10;
|
||
padding = padding | 0 || 1;
|
||
|
||
var out;
|
||
if (base === 16 || base === 'hex') {
|
||
out = '';
|
||
var off = 0;
|
||
var carry = 0;
|
||
for (var i = 0; i < this.length; i++) {
|
||
var w = this.words[i];
|
||
var word = (((w << off) | carry) & 0xffffff).toString(16);
|
||
carry = (w >>> (24 - off)) & 0xffffff;
|
||
if (carry !== 0 || i !== this.length - 1) {
|
||
out = zeros[6 - word.length] + word + out;
|
||
} else {
|
||
out = word + out;
|
||
}
|
||
off += 2;
|
||
if (off >= 26) {
|
||
off -= 26;
|
||
i--;
|
||
}
|
||
}
|
||
if (carry !== 0) {
|
||
out = carry.toString(16) + out;
|
||
}
|
||
while (out.length % padding !== 0) {
|
||
out = '0' + out;
|
||
}
|
||
if (this.negative !== 0) {
|
||
out = '-' + out;
|
||
}
|
||
return out;
|
||
}
|
||
|
||
if (base === (base | 0) && base >= 2 && base <= 36) {
|
||
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
|
||
var groupSize = groupSizes[base];
|
||
// var groupBase = Math.pow(base, groupSize);
|
||
var groupBase = groupBases[base];
|
||
out = '';
|
||
var c = this.clone();
|
||
c.negative = 0;
|
||
while (!c.isZero()) {
|
||
var r = c.modn(groupBase).toString(base);
|
||
c = c.idivn(groupBase);
|
||
|
||
if (!c.isZero()) {
|
||
out = zeros[groupSize - r.length] + r + out;
|
||
} else {
|
||
out = r + out;
|
||
}
|
||
}
|
||
if (this.isZero()) {
|
||
out = '0' + out;
|
||
}
|
||
while (out.length % padding !== 0) {
|
||
out = '0' + out;
|
||
}
|
||
if (this.negative !== 0) {
|
||
out = '-' + out;
|
||
}
|
||
return out;
|
||
}
|
||
|
||
assert(false, 'Base should be between 2 and 36');
|
||
};
|
||
|
||
BN.prototype.toNumber = function toNumber () {
|
||
var ret = this.words[0];
|
||
if (this.length === 2) {
|
||
ret += this.words[1] * 0x4000000;
|
||
} else if (this.length === 3 && this.words[2] === 0x01) {
|
||
// NOTE: at this stage it is known that the top bit is set
|
||
ret += 0x10000000000000 + (this.words[1] * 0x4000000);
|
||
} else if (this.length > 2) {
|
||
assert(false, 'Number can only safely store up to 53 bits');
|
||
}
|
||
return (this.negative !== 0) ? -ret : ret;
|
||
};
|
||
|
||
BN.prototype.toJSON = function toJSON () {
|
||
return this.toString(16);
|
||
};
|
||
|
||
BN.prototype.toBuffer = function toBuffer (endian, length) {
|
||
assert(typeof Buffer !== 'undefined');
|
||
return this.toArrayLike(Buffer, endian, length);
|
||
};
|
||
|
||
BN.prototype.toArray = function toArray (endian, length) {
|
||
return this.toArrayLike(Array, endian, length);
|
||
};
|
||
|
||
BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
|
||
var byteLength = this.byteLength();
|
||
var reqLength = length || Math.max(1, byteLength);
|
||
assert(byteLength <= reqLength, 'byte array longer than desired length');
|
||
assert(reqLength > 0, 'Requested array length <= 0');
|
||
|
||
this.strip();
|
||
var littleEndian = endian === 'le';
|
||
var res = new ArrayType(reqLength);
|
||
|
||
var b, i;
|
||
var q = this.clone();
|
||
if (!littleEndian) {
|
||
// Assume big-endian
|
||
for (i = 0; i < reqLength - byteLength; i++) {
|
||
res[i] = 0;
|
||
}
|
||
|
||
for (i = 0; !q.isZero(); i++) {
|
||
b = q.andln(0xff);
|
||
q.iushrn(8);
|
||
|
||
res[reqLength - i - 1] = b;
|
||
}
|
||
} else {
|
||
for (i = 0; !q.isZero(); i++) {
|
||
b = q.andln(0xff);
|
||
q.iushrn(8);
|
||
|
||
res[i] = b;
|
||
}
|
||
|
||
for (; i < reqLength; i++) {
|
||
res[i] = 0;
|
||
}
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
if (Math.clz32) {
|
||
BN.prototype._countBits = function _countBits (w) {
|
||
return 32 - Math.clz32(w);
|
||
};
|
||
} else {
|
||
BN.prototype._countBits = function _countBits (w) {
|
||
var t = w;
|
||
var r = 0;
|
||
if (t >= 0x1000) {
|
||
r += 13;
|
||
t >>>= 13;
|
||
}
|
||
if (t >= 0x40) {
|
||
r += 7;
|
||
t >>>= 7;
|
||
}
|
||
if (t >= 0x8) {
|
||
r += 4;
|
||
t >>>= 4;
|
||
}
|
||
if (t >= 0x02) {
|
||
r += 2;
|
||
t >>>= 2;
|
||
}
|
||
return r + t;
|
||
};
|
||
}
|
||
|
||
BN.prototype._zeroBits = function _zeroBits (w) {
|
||
// Short-cut
|
||
if (w === 0) return 26;
|
||
|
||
var t = w;
|
||
var r = 0;
|
||
if ((t & 0x1fff) === 0) {
|
||
r += 13;
|
||
t >>>= 13;
|
||
}
|
||
if ((t & 0x7f) === 0) {
|
||
r += 7;
|
||
t >>>= 7;
|
||
}
|
||
if ((t & 0xf) === 0) {
|
||
r += 4;
|
||
t >>>= 4;
|
||
}
|
||
if ((t & 0x3) === 0) {
|
||
r += 2;
|
||
t >>>= 2;
|
||
}
|
||
if ((t & 0x1) === 0) {
|
||
r++;
|
||
}
|
||
return r;
|
||
};
|
||
|
||
// Return number of used bits in a BN
|
||
BN.prototype.bitLength = function bitLength () {
|
||
var w = this.words[this.length - 1];
|
||
var hi = this._countBits(w);
|
||
return (this.length - 1) * 26 + hi;
|
||
};
|
||
|
||
function toBitArray (num) {
|
||
var w = new Array(num.bitLength());
|
||
|
||
for (var bit = 0; bit < w.length; bit++) {
|
||
var off = (bit / 26) | 0;
|
||
var wbit = bit % 26;
|
||
|
||
w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
|
||
}
|
||
|
||
return w;
|
||
}
|
||
|
||
// Number of trailing zero bits
|
||
BN.prototype.zeroBits = function zeroBits () {
|
||
if (this.isZero()) return 0;
|
||
|
||
var r = 0;
|
||
for (var i = 0; i < this.length; i++) {
|
||
var b = this._zeroBits(this.words[i]);
|
||
r += b;
|
||
if (b !== 26) break;
|
||
}
|
||
return r;
|
||
};
|
||
|
||
BN.prototype.byteLength = function byteLength () {
|
||
return Math.ceil(this.bitLength() / 8);
|
||
};
|
||
|
||
BN.prototype.toTwos = function toTwos (width) {
|
||
if (this.negative !== 0) {
|
||
return this.abs().inotn(width).iaddn(1);
|
||
}
|
||
return this.clone();
|
||
};
|
||
|
||
BN.prototype.fromTwos = function fromTwos (width) {
|
||
if (this.testn(width - 1)) {
|
||
return this.notn(width).iaddn(1).ineg();
|
||
}
|
||
return this.clone();
|
||
};
|
||
|
||
BN.prototype.isNeg = function isNeg () {
|
||
return this.negative !== 0;
|
||
};
|
||
|
||
// Return negative clone of `this`
|
||
BN.prototype.neg = function neg () {
|
||
return this.clone().ineg();
|
||
};
|
||
|
||
BN.prototype.ineg = function ineg () {
|
||
if (!this.isZero()) {
|
||
this.negative ^= 1;
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
// Or `num` with `this` in-place
|
||
BN.prototype.iuor = function iuor (num) {
|
||
while (this.length < num.length) {
|
||
this.words[this.length++] = 0;
|
||
}
|
||
|
||
for (var i = 0; i < num.length; i++) {
|
||
this.words[i] = this.words[i] | num.words[i];
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ior = function ior (num) {
|
||
assert((this.negative | num.negative) === 0);
|
||
return this.iuor(num);
|
||
};
|
||
|
||
// Or `num` with `this`
|
||
BN.prototype.or = function or (num) {
|
||
if (this.length > num.length) return this.clone().ior(num);
|
||
return num.clone().ior(this);
|
||
};
|
||
|
||
BN.prototype.uor = function uor (num) {
|
||
if (this.length > num.length) return this.clone().iuor(num);
|
||
return num.clone().iuor(this);
|
||
};
|
||
|
||
// And `num` with `this` in-place
|
||
BN.prototype.iuand = function iuand (num) {
|
||
// b = min-length(num, this)
|
||
var b;
|
||
if (this.length > num.length) {
|
||
b = num;
|
||
} else {
|
||
b = this;
|
||
}
|
||
|
||
for (var i = 0; i < b.length; i++) {
|
||
this.words[i] = this.words[i] & num.words[i];
|
||
}
|
||
|
||
this.length = b.length;
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.iand = function iand (num) {
|
||
assert((this.negative | num.negative) === 0);
|
||
return this.iuand(num);
|
||
};
|
||
|
||
// And `num` with `this`
|
||
BN.prototype.and = function and (num) {
|
||
if (this.length > num.length) return this.clone().iand(num);
|
||
return num.clone().iand(this);
|
||
};
|
||
|
||
BN.prototype.uand = function uand (num) {
|
||
if (this.length > num.length) return this.clone().iuand(num);
|
||
return num.clone().iuand(this);
|
||
};
|
||
|
||
// Xor `num` with `this` in-place
|
||
BN.prototype.iuxor = function iuxor (num) {
|
||
// a.length > b.length
|
||
var a;
|
||
var b;
|
||
if (this.length > num.length) {
|
||
a = this;
|
||
b = num;
|
||
} else {
|
||
a = num;
|
||
b = this;
|
||
}
|
||
|
||
for (var i = 0; i < b.length; i++) {
|
||
this.words[i] = a.words[i] ^ b.words[i];
|
||
}
|
||
|
||
if (this !== a) {
|
||
for (; i < a.length; i++) {
|
||
this.words[i] = a.words[i];
|
||
}
|
||
}
|
||
|
||
this.length = a.length;
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ixor = function ixor (num) {
|
||
assert((this.negative | num.negative) === 0);
|
||
return this.iuxor(num);
|
||
};
|
||
|
||
// Xor `num` with `this`
|
||
BN.prototype.xor = function xor (num) {
|
||
if (this.length > num.length) return this.clone().ixor(num);
|
||
return num.clone().ixor(this);
|
||
};
|
||
|
||
BN.prototype.uxor = function uxor (num) {
|
||
if (this.length > num.length) return this.clone().iuxor(num);
|
||
return num.clone().iuxor(this);
|
||
};
|
||
|
||
// Not ``this`` with ``width`` bitwidth
|
||
BN.prototype.inotn = function inotn (width) {
|
||
assert(typeof width === 'number' && width >= 0);
|
||
|
||
var bytesNeeded = Math.ceil(width / 26) | 0;
|
||
var bitsLeft = width % 26;
|
||
|
||
// Extend the buffer with leading zeroes
|
||
this._expand(bytesNeeded);
|
||
|
||
if (bitsLeft > 0) {
|
||
bytesNeeded--;
|
||
}
|
||
|
||
// Handle complete words
|
||
for (var i = 0; i < bytesNeeded; i++) {
|
||
this.words[i] = ~this.words[i] & 0x3ffffff;
|
||
}
|
||
|
||
// Handle the residue
|
||
if (bitsLeft > 0) {
|
||
this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
|
||
}
|
||
|
||
// And remove leading zeroes
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.notn = function notn (width) {
|
||
return this.clone().inotn(width);
|
||
};
|
||
|
||
// Set `bit` of `this`
|
||
BN.prototype.setn = function setn (bit, val) {
|
||
assert(typeof bit === 'number' && bit >= 0);
|
||
|
||
var off = (bit / 26) | 0;
|
||
var wbit = bit % 26;
|
||
|
||
this._expand(off + 1);
|
||
|
||
if (val) {
|
||
this.words[off] = this.words[off] | (1 << wbit);
|
||
} else {
|
||
this.words[off] = this.words[off] & ~(1 << wbit);
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
// Add `num` to `this` in-place
|
||
BN.prototype.iadd = function iadd (num) {
|
||
var r;
|
||
|
||
// negative + positive
|
||
if (this.negative !== 0 && num.negative === 0) {
|
||
this.negative = 0;
|
||
r = this.isub(num);
|
||
this.negative ^= 1;
|
||
return this._normSign();
|
||
|
||
// positive + negative
|
||
} else if (this.negative === 0 && num.negative !== 0) {
|
||
num.negative = 0;
|
||
r = this.isub(num);
|
||
num.negative = 1;
|
||
return r._normSign();
|
||
}
|
||
|
||
// a.length > b.length
|
||
var a, b;
|
||
if (this.length > num.length) {
|
||
a = this;
|
||
b = num;
|
||
} else {
|
||
a = num;
|
||
b = this;
|
||
}
|
||
|
||
var carry = 0;
|
||
for (var i = 0; i < b.length; i++) {
|
||
r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
|
||
this.words[i] = r & 0x3ffffff;
|
||
carry = r >>> 26;
|
||
}
|
||
for (; carry !== 0 && i < a.length; i++) {
|
||
r = (a.words[i] | 0) + carry;
|
||
this.words[i] = r & 0x3ffffff;
|
||
carry = r >>> 26;
|
||
}
|
||
|
||
this.length = a.length;
|
||
if (carry !== 0) {
|
||
this.words[this.length] = carry;
|
||
this.length++;
|
||
// Copy the rest of the words
|
||
} else if (a !== this) {
|
||
for (; i < a.length; i++) {
|
||
this.words[i] = a.words[i];
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
// Add `num` to `this`
|
||
BN.prototype.add = function add (num) {
|
||
var res;
|
||
if (num.negative !== 0 && this.negative === 0) {
|
||
num.negative = 0;
|
||
res = this.sub(num);
|
||
num.negative ^= 1;
|
||
return res;
|
||
} else if (num.negative === 0 && this.negative !== 0) {
|
||
this.negative = 0;
|
||
res = num.sub(this);
|
||
this.negative = 1;
|
||
return res;
|
||
}
|
||
|
||
if (this.length > num.length) return this.clone().iadd(num);
|
||
|
||
return num.clone().iadd(this);
|
||
};
|
||
|
||
// Subtract `num` from `this` in-place
|
||
BN.prototype.isub = function isub (num) {
|
||
// this - (-num) = this + num
|
||
if (num.negative !== 0) {
|
||
num.negative = 0;
|
||
var r = this.iadd(num);
|
||
num.negative = 1;
|
||
return r._normSign();
|
||
|
||
// -this - num = -(this + num)
|
||
} else if (this.negative !== 0) {
|
||
this.negative = 0;
|
||
this.iadd(num);
|
||
this.negative = 1;
|
||
return this._normSign();
|
||
}
|
||
|
||
// At this point both numbers are positive
|
||
var cmp = this.cmp(num);
|
||
|
||
// Optimization - zeroify
|
||
if (cmp === 0) {
|
||
this.negative = 0;
|
||
this.length = 1;
|
||
this.words[0] = 0;
|
||
return this;
|
||
}
|
||
|
||
// a > b
|
||
var a, b;
|
||
if (cmp > 0) {
|
||
a = this;
|
||
b = num;
|
||
} else {
|
||
a = num;
|
||
b = this;
|
||
}
|
||
|
||
var carry = 0;
|
||
for (var i = 0; i < b.length; i++) {
|
||
r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
|
||
carry = r >> 26;
|
||
this.words[i] = r & 0x3ffffff;
|
||
}
|
||
for (; carry !== 0 && i < a.length; i++) {
|
||
r = (a.words[i] | 0) + carry;
|
||
carry = r >> 26;
|
||
this.words[i] = r & 0x3ffffff;
|
||
}
|
||
|
||
// Copy rest of the words
|
||
if (carry === 0 && i < a.length && a !== this) {
|
||
for (; i < a.length; i++) {
|
||
this.words[i] = a.words[i];
|
||
}
|
||
}
|
||
|
||
this.length = Math.max(this.length, i);
|
||
|
||
if (a !== this) {
|
||
this.negative = 1;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
// Subtract `num` from `this`
|
||
BN.prototype.sub = function sub (num) {
|
||
return this.clone().isub(num);
|
||
};
|
||
|
||
function smallMulTo (self, num, out) {
|
||
out.negative = num.negative ^ self.negative;
|
||
var len = (self.length + num.length) | 0;
|
||
out.length = len;
|
||
len = (len - 1) | 0;
|
||
|
||
// Peel one iteration (compiler can't do it, because of code complexity)
|
||
var a = self.words[0] | 0;
|
||
var b = num.words[0] | 0;
|
||
var r = a * b;
|
||
|
||
var lo = r & 0x3ffffff;
|
||
var carry = (r / 0x4000000) | 0;
|
||
out.words[0] = lo;
|
||
|
||
for (var k = 1; k < len; k++) {
|
||
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
||
// note that ncarry could be >= 0x3ffffff
|
||
var ncarry = carry >>> 26;
|
||
var rword = carry & 0x3ffffff;
|
||
var maxJ = Math.min(k, num.length - 1);
|
||
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
||
var i = (k - j) | 0;
|
||
a = self.words[i] | 0;
|
||
b = num.words[j] | 0;
|
||
r = a * b + rword;
|
||
ncarry += (r / 0x4000000) | 0;
|
||
rword = r & 0x3ffffff;
|
||
}
|
||
out.words[k] = rword | 0;
|
||
carry = ncarry | 0;
|
||
}
|
||
if (carry !== 0) {
|
||
out.words[k] = carry | 0;
|
||
} else {
|
||
out.length--;
|
||
}
|
||
|
||
return out.strip();
|
||
}
|
||
|
||
// TODO(indutny): it may be reasonable to omit it for users who don't need
|
||
// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
|
||
// multiplication (like elliptic secp256k1).
|
||
var comb10MulTo = function comb10MulTo (self, num, out) {
|
||
var a = self.words;
|
||
var b = num.words;
|
||
var o = out.words;
|
||
var c = 0;
|
||
var lo;
|
||
var mid;
|
||
var hi;
|
||
var a0 = a[0] | 0;
|
||
var al0 = a0 & 0x1fff;
|
||
var ah0 = a0 >>> 13;
|
||
var a1 = a[1] | 0;
|
||
var al1 = a1 & 0x1fff;
|
||
var ah1 = a1 >>> 13;
|
||
var a2 = a[2] | 0;
|
||
var al2 = a2 & 0x1fff;
|
||
var ah2 = a2 >>> 13;
|
||
var a3 = a[3] | 0;
|
||
var al3 = a3 & 0x1fff;
|
||
var ah3 = a3 >>> 13;
|
||
var a4 = a[4] | 0;
|
||
var al4 = a4 & 0x1fff;
|
||
var ah4 = a4 >>> 13;
|
||
var a5 = a[5] | 0;
|
||
var al5 = a5 & 0x1fff;
|
||
var ah5 = a5 >>> 13;
|
||
var a6 = a[6] | 0;
|
||
var al6 = a6 & 0x1fff;
|
||
var ah6 = a6 >>> 13;
|
||
var a7 = a[7] | 0;
|
||
var al7 = a7 & 0x1fff;
|
||
var ah7 = a7 >>> 13;
|
||
var a8 = a[8] | 0;
|
||
var al8 = a8 & 0x1fff;
|
||
var ah8 = a8 >>> 13;
|
||
var a9 = a[9] | 0;
|
||
var al9 = a9 & 0x1fff;
|
||
var ah9 = a9 >>> 13;
|
||
var b0 = b[0] | 0;
|
||
var bl0 = b0 & 0x1fff;
|
||
var bh0 = b0 >>> 13;
|
||
var b1 = b[1] | 0;
|
||
var bl1 = b1 & 0x1fff;
|
||
var bh1 = b1 >>> 13;
|
||
var b2 = b[2] | 0;
|
||
var bl2 = b2 & 0x1fff;
|
||
var bh2 = b2 >>> 13;
|
||
var b3 = b[3] | 0;
|
||
var bl3 = b3 & 0x1fff;
|
||
var bh3 = b3 >>> 13;
|
||
var b4 = b[4] | 0;
|
||
var bl4 = b4 & 0x1fff;
|
||
var bh4 = b4 >>> 13;
|
||
var b5 = b[5] | 0;
|
||
var bl5 = b5 & 0x1fff;
|
||
var bh5 = b5 >>> 13;
|
||
var b6 = b[6] | 0;
|
||
var bl6 = b6 & 0x1fff;
|
||
var bh6 = b6 >>> 13;
|
||
var b7 = b[7] | 0;
|
||
var bl7 = b7 & 0x1fff;
|
||
var bh7 = b7 >>> 13;
|
||
var b8 = b[8] | 0;
|
||
var bl8 = b8 & 0x1fff;
|
||
var bh8 = b8 >>> 13;
|
||
var b9 = b[9] | 0;
|
||
var bl9 = b9 & 0x1fff;
|
||
var bh9 = b9 >>> 13;
|
||
|
||
out.negative = self.negative ^ num.negative;
|
||
out.length = 19;
|
||
/* k = 0 */
|
||
lo = Math.imul(al0, bl0);
|
||
mid = Math.imul(al0, bh0);
|
||
mid = (mid + Math.imul(ah0, bl0)) | 0;
|
||
hi = Math.imul(ah0, bh0);
|
||
var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
|
||
w0 &= 0x3ffffff;
|
||
/* k = 1 */
|
||
lo = Math.imul(al1, bl0);
|
||
mid = Math.imul(al1, bh0);
|
||
mid = (mid + Math.imul(ah1, bl0)) | 0;
|
||
hi = Math.imul(ah1, bh0);
|
||
lo = (lo + Math.imul(al0, bl1)) | 0;
|
||
mid = (mid + Math.imul(al0, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh1)) | 0;
|
||
var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
|
||
w1 &= 0x3ffffff;
|
||
/* k = 2 */
|
||
lo = Math.imul(al2, bl0);
|
||
mid = Math.imul(al2, bh0);
|
||
mid = (mid + Math.imul(ah2, bl0)) | 0;
|
||
hi = Math.imul(ah2, bh0);
|
||
lo = (lo + Math.imul(al1, bl1)) | 0;
|
||
mid = (mid + Math.imul(al1, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh1)) | 0;
|
||
lo = (lo + Math.imul(al0, bl2)) | 0;
|
||
mid = (mid + Math.imul(al0, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh2)) | 0;
|
||
var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
|
||
w2 &= 0x3ffffff;
|
||
/* k = 3 */
|
||
lo = Math.imul(al3, bl0);
|
||
mid = Math.imul(al3, bh0);
|
||
mid = (mid + Math.imul(ah3, bl0)) | 0;
|
||
hi = Math.imul(ah3, bh0);
|
||
lo = (lo + Math.imul(al2, bl1)) | 0;
|
||
mid = (mid + Math.imul(al2, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh1)) | 0;
|
||
lo = (lo + Math.imul(al1, bl2)) | 0;
|
||
mid = (mid + Math.imul(al1, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh2)) | 0;
|
||
lo = (lo + Math.imul(al0, bl3)) | 0;
|
||
mid = (mid + Math.imul(al0, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh3)) | 0;
|
||
var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
|
||
w3 &= 0x3ffffff;
|
||
/* k = 4 */
|
||
lo = Math.imul(al4, bl0);
|
||
mid = Math.imul(al4, bh0);
|
||
mid = (mid + Math.imul(ah4, bl0)) | 0;
|
||
hi = Math.imul(ah4, bh0);
|
||
lo = (lo + Math.imul(al3, bl1)) | 0;
|
||
mid = (mid + Math.imul(al3, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh1)) | 0;
|
||
lo = (lo + Math.imul(al2, bl2)) | 0;
|
||
mid = (mid + Math.imul(al2, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh2)) | 0;
|
||
lo = (lo + Math.imul(al1, bl3)) | 0;
|
||
mid = (mid + Math.imul(al1, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh3)) | 0;
|
||
lo = (lo + Math.imul(al0, bl4)) | 0;
|
||
mid = (mid + Math.imul(al0, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh4)) | 0;
|
||
var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
|
||
w4 &= 0x3ffffff;
|
||
/* k = 5 */
|
||
lo = Math.imul(al5, bl0);
|
||
mid = Math.imul(al5, bh0);
|
||
mid = (mid + Math.imul(ah5, bl0)) | 0;
|
||
hi = Math.imul(ah5, bh0);
|
||
lo = (lo + Math.imul(al4, bl1)) | 0;
|
||
mid = (mid + Math.imul(al4, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh1)) | 0;
|
||
lo = (lo + Math.imul(al3, bl2)) | 0;
|
||
mid = (mid + Math.imul(al3, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh2)) | 0;
|
||
lo = (lo + Math.imul(al2, bl3)) | 0;
|
||
mid = (mid + Math.imul(al2, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh3)) | 0;
|
||
lo = (lo + Math.imul(al1, bl4)) | 0;
|
||
mid = (mid + Math.imul(al1, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh4)) | 0;
|
||
lo = (lo + Math.imul(al0, bl5)) | 0;
|
||
mid = (mid + Math.imul(al0, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh5)) | 0;
|
||
var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
|
||
w5 &= 0x3ffffff;
|
||
/* k = 6 */
|
||
lo = Math.imul(al6, bl0);
|
||
mid = Math.imul(al6, bh0);
|
||
mid = (mid + Math.imul(ah6, bl0)) | 0;
|
||
hi = Math.imul(ah6, bh0);
|
||
lo = (lo + Math.imul(al5, bl1)) | 0;
|
||
mid = (mid + Math.imul(al5, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh1)) | 0;
|
||
lo = (lo + Math.imul(al4, bl2)) | 0;
|
||
mid = (mid + Math.imul(al4, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh2)) | 0;
|
||
lo = (lo + Math.imul(al3, bl3)) | 0;
|
||
mid = (mid + Math.imul(al3, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh3)) | 0;
|
||
lo = (lo + Math.imul(al2, bl4)) | 0;
|
||
mid = (mid + Math.imul(al2, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh4)) | 0;
|
||
lo = (lo + Math.imul(al1, bl5)) | 0;
|
||
mid = (mid + Math.imul(al1, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh5)) | 0;
|
||
lo = (lo + Math.imul(al0, bl6)) | 0;
|
||
mid = (mid + Math.imul(al0, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh6)) | 0;
|
||
var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
|
||
w6 &= 0x3ffffff;
|
||
/* k = 7 */
|
||
lo = Math.imul(al7, bl0);
|
||
mid = Math.imul(al7, bh0);
|
||
mid = (mid + Math.imul(ah7, bl0)) | 0;
|
||
hi = Math.imul(ah7, bh0);
|
||
lo = (lo + Math.imul(al6, bl1)) | 0;
|
||
mid = (mid + Math.imul(al6, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh1)) | 0;
|
||
lo = (lo + Math.imul(al5, bl2)) | 0;
|
||
mid = (mid + Math.imul(al5, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh2)) | 0;
|
||
lo = (lo + Math.imul(al4, bl3)) | 0;
|
||
mid = (mid + Math.imul(al4, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh3)) | 0;
|
||
lo = (lo + Math.imul(al3, bl4)) | 0;
|
||
mid = (mid + Math.imul(al3, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh4)) | 0;
|
||
lo = (lo + Math.imul(al2, bl5)) | 0;
|
||
mid = (mid + Math.imul(al2, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh5)) | 0;
|
||
lo = (lo + Math.imul(al1, bl6)) | 0;
|
||
mid = (mid + Math.imul(al1, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh6)) | 0;
|
||
lo = (lo + Math.imul(al0, bl7)) | 0;
|
||
mid = (mid + Math.imul(al0, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh7)) | 0;
|
||
var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
|
||
w7 &= 0x3ffffff;
|
||
/* k = 8 */
|
||
lo = Math.imul(al8, bl0);
|
||
mid = Math.imul(al8, bh0);
|
||
mid = (mid + Math.imul(ah8, bl0)) | 0;
|
||
hi = Math.imul(ah8, bh0);
|
||
lo = (lo + Math.imul(al7, bl1)) | 0;
|
||
mid = (mid + Math.imul(al7, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh1)) | 0;
|
||
lo = (lo + Math.imul(al6, bl2)) | 0;
|
||
mid = (mid + Math.imul(al6, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh2)) | 0;
|
||
lo = (lo + Math.imul(al5, bl3)) | 0;
|
||
mid = (mid + Math.imul(al5, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh3)) | 0;
|
||
lo = (lo + Math.imul(al4, bl4)) | 0;
|
||
mid = (mid + Math.imul(al4, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh4)) | 0;
|
||
lo = (lo + Math.imul(al3, bl5)) | 0;
|
||
mid = (mid + Math.imul(al3, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh5)) | 0;
|
||
lo = (lo + Math.imul(al2, bl6)) | 0;
|
||
mid = (mid + Math.imul(al2, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh6)) | 0;
|
||
lo = (lo + Math.imul(al1, bl7)) | 0;
|
||
mid = (mid + Math.imul(al1, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh7)) | 0;
|
||
lo = (lo + Math.imul(al0, bl8)) | 0;
|
||
mid = (mid + Math.imul(al0, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh8)) | 0;
|
||
var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
|
||
w8 &= 0x3ffffff;
|
||
/* k = 9 */
|
||
lo = Math.imul(al9, bl0);
|
||
mid = Math.imul(al9, bh0);
|
||
mid = (mid + Math.imul(ah9, bl0)) | 0;
|
||
hi = Math.imul(ah9, bh0);
|
||
lo = (lo + Math.imul(al8, bl1)) | 0;
|
||
mid = (mid + Math.imul(al8, bh1)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl1)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh1)) | 0;
|
||
lo = (lo + Math.imul(al7, bl2)) | 0;
|
||
mid = (mid + Math.imul(al7, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh2)) | 0;
|
||
lo = (lo + Math.imul(al6, bl3)) | 0;
|
||
mid = (mid + Math.imul(al6, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh3)) | 0;
|
||
lo = (lo + Math.imul(al5, bl4)) | 0;
|
||
mid = (mid + Math.imul(al5, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh4)) | 0;
|
||
lo = (lo + Math.imul(al4, bl5)) | 0;
|
||
mid = (mid + Math.imul(al4, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh5)) | 0;
|
||
lo = (lo + Math.imul(al3, bl6)) | 0;
|
||
mid = (mid + Math.imul(al3, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh6)) | 0;
|
||
lo = (lo + Math.imul(al2, bl7)) | 0;
|
||
mid = (mid + Math.imul(al2, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh7)) | 0;
|
||
lo = (lo + Math.imul(al1, bl8)) | 0;
|
||
mid = (mid + Math.imul(al1, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh8)) | 0;
|
||
lo = (lo + Math.imul(al0, bl9)) | 0;
|
||
mid = (mid + Math.imul(al0, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah0, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah0, bh9)) | 0;
|
||
var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
|
||
w9 &= 0x3ffffff;
|
||
/* k = 10 */
|
||
lo = Math.imul(al9, bl1);
|
||
mid = Math.imul(al9, bh1);
|
||
mid = (mid + Math.imul(ah9, bl1)) | 0;
|
||
hi = Math.imul(ah9, bh1);
|
||
lo = (lo + Math.imul(al8, bl2)) | 0;
|
||
mid = (mid + Math.imul(al8, bh2)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl2)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh2)) | 0;
|
||
lo = (lo + Math.imul(al7, bl3)) | 0;
|
||
mid = (mid + Math.imul(al7, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh3)) | 0;
|
||
lo = (lo + Math.imul(al6, bl4)) | 0;
|
||
mid = (mid + Math.imul(al6, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh4)) | 0;
|
||
lo = (lo + Math.imul(al5, bl5)) | 0;
|
||
mid = (mid + Math.imul(al5, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh5)) | 0;
|
||
lo = (lo + Math.imul(al4, bl6)) | 0;
|
||
mid = (mid + Math.imul(al4, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh6)) | 0;
|
||
lo = (lo + Math.imul(al3, bl7)) | 0;
|
||
mid = (mid + Math.imul(al3, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh7)) | 0;
|
||
lo = (lo + Math.imul(al2, bl8)) | 0;
|
||
mid = (mid + Math.imul(al2, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh8)) | 0;
|
||
lo = (lo + Math.imul(al1, bl9)) | 0;
|
||
mid = (mid + Math.imul(al1, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah1, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah1, bh9)) | 0;
|
||
var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
|
||
w10 &= 0x3ffffff;
|
||
/* k = 11 */
|
||
lo = Math.imul(al9, bl2);
|
||
mid = Math.imul(al9, bh2);
|
||
mid = (mid + Math.imul(ah9, bl2)) | 0;
|
||
hi = Math.imul(ah9, bh2);
|
||
lo = (lo + Math.imul(al8, bl3)) | 0;
|
||
mid = (mid + Math.imul(al8, bh3)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl3)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh3)) | 0;
|
||
lo = (lo + Math.imul(al7, bl4)) | 0;
|
||
mid = (mid + Math.imul(al7, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh4)) | 0;
|
||
lo = (lo + Math.imul(al6, bl5)) | 0;
|
||
mid = (mid + Math.imul(al6, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh5)) | 0;
|
||
lo = (lo + Math.imul(al5, bl6)) | 0;
|
||
mid = (mid + Math.imul(al5, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh6)) | 0;
|
||
lo = (lo + Math.imul(al4, bl7)) | 0;
|
||
mid = (mid + Math.imul(al4, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh7)) | 0;
|
||
lo = (lo + Math.imul(al3, bl8)) | 0;
|
||
mid = (mid + Math.imul(al3, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh8)) | 0;
|
||
lo = (lo + Math.imul(al2, bl9)) | 0;
|
||
mid = (mid + Math.imul(al2, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah2, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah2, bh9)) | 0;
|
||
var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
|
||
w11 &= 0x3ffffff;
|
||
/* k = 12 */
|
||
lo = Math.imul(al9, bl3);
|
||
mid = Math.imul(al9, bh3);
|
||
mid = (mid + Math.imul(ah9, bl3)) | 0;
|
||
hi = Math.imul(ah9, bh3);
|
||
lo = (lo + Math.imul(al8, bl4)) | 0;
|
||
mid = (mid + Math.imul(al8, bh4)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl4)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh4)) | 0;
|
||
lo = (lo + Math.imul(al7, bl5)) | 0;
|
||
mid = (mid + Math.imul(al7, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh5)) | 0;
|
||
lo = (lo + Math.imul(al6, bl6)) | 0;
|
||
mid = (mid + Math.imul(al6, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh6)) | 0;
|
||
lo = (lo + Math.imul(al5, bl7)) | 0;
|
||
mid = (mid + Math.imul(al5, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh7)) | 0;
|
||
lo = (lo + Math.imul(al4, bl8)) | 0;
|
||
mid = (mid + Math.imul(al4, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh8)) | 0;
|
||
lo = (lo + Math.imul(al3, bl9)) | 0;
|
||
mid = (mid + Math.imul(al3, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah3, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah3, bh9)) | 0;
|
||
var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
|
||
w12 &= 0x3ffffff;
|
||
/* k = 13 */
|
||
lo = Math.imul(al9, bl4);
|
||
mid = Math.imul(al9, bh4);
|
||
mid = (mid + Math.imul(ah9, bl4)) | 0;
|
||
hi = Math.imul(ah9, bh4);
|
||
lo = (lo + Math.imul(al8, bl5)) | 0;
|
||
mid = (mid + Math.imul(al8, bh5)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl5)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh5)) | 0;
|
||
lo = (lo + Math.imul(al7, bl6)) | 0;
|
||
mid = (mid + Math.imul(al7, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh6)) | 0;
|
||
lo = (lo + Math.imul(al6, bl7)) | 0;
|
||
mid = (mid + Math.imul(al6, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh7)) | 0;
|
||
lo = (lo + Math.imul(al5, bl8)) | 0;
|
||
mid = (mid + Math.imul(al5, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh8)) | 0;
|
||
lo = (lo + Math.imul(al4, bl9)) | 0;
|
||
mid = (mid + Math.imul(al4, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah4, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah4, bh9)) | 0;
|
||
var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
|
||
w13 &= 0x3ffffff;
|
||
/* k = 14 */
|
||
lo = Math.imul(al9, bl5);
|
||
mid = Math.imul(al9, bh5);
|
||
mid = (mid + Math.imul(ah9, bl5)) | 0;
|
||
hi = Math.imul(ah9, bh5);
|
||
lo = (lo + Math.imul(al8, bl6)) | 0;
|
||
mid = (mid + Math.imul(al8, bh6)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl6)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh6)) | 0;
|
||
lo = (lo + Math.imul(al7, bl7)) | 0;
|
||
mid = (mid + Math.imul(al7, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh7)) | 0;
|
||
lo = (lo + Math.imul(al6, bl8)) | 0;
|
||
mid = (mid + Math.imul(al6, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh8)) | 0;
|
||
lo = (lo + Math.imul(al5, bl9)) | 0;
|
||
mid = (mid + Math.imul(al5, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah5, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah5, bh9)) | 0;
|
||
var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
|
||
w14 &= 0x3ffffff;
|
||
/* k = 15 */
|
||
lo = Math.imul(al9, bl6);
|
||
mid = Math.imul(al9, bh6);
|
||
mid = (mid + Math.imul(ah9, bl6)) | 0;
|
||
hi = Math.imul(ah9, bh6);
|
||
lo = (lo + Math.imul(al8, bl7)) | 0;
|
||
mid = (mid + Math.imul(al8, bh7)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl7)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh7)) | 0;
|
||
lo = (lo + Math.imul(al7, bl8)) | 0;
|
||
mid = (mid + Math.imul(al7, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh8)) | 0;
|
||
lo = (lo + Math.imul(al6, bl9)) | 0;
|
||
mid = (mid + Math.imul(al6, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah6, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah6, bh9)) | 0;
|
||
var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
|
||
w15 &= 0x3ffffff;
|
||
/* k = 16 */
|
||
lo = Math.imul(al9, bl7);
|
||
mid = Math.imul(al9, bh7);
|
||
mid = (mid + Math.imul(ah9, bl7)) | 0;
|
||
hi = Math.imul(ah9, bh7);
|
||
lo = (lo + Math.imul(al8, bl8)) | 0;
|
||
mid = (mid + Math.imul(al8, bh8)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl8)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh8)) | 0;
|
||
lo = (lo + Math.imul(al7, bl9)) | 0;
|
||
mid = (mid + Math.imul(al7, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah7, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah7, bh9)) | 0;
|
||
var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
|
||
w16 &= 0x3ffffff;
|
||
/* k = 17 */
|
||
lo = Math.imul(al9, bl8);
|
||
mid = Math.imul(al9, bh8);
|
||
mid = (mid + Math.imul(ah9, bl8)) | 0;
|
||
hi = Math.imul(ah9, bh8);
|
||
lo = (lo + Math.imul(al8, bl9)) | 0;
|
||
mid = (mid + Math.imul(al8, bh9)) | 0;
|
||
mid = (mid + Math.imul(ah8, bl9)) | 0;
|
||
hi = (hi + Math.imul(ah8, bh9)) | 0;
|
||
var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
|
||
w17 &= 0x3ffffff;
|
||
/* k = 18 */
|
||
lo = Math.imul(al9, bl9);
|
||
mid = Math.imul(al9, bh9);
|
||
mid = (mid + Math.imul(ah9, bl9)) | 0;
|
||
hi = Math.imul(ah9, bh9);
|
||
var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
|
||
c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
|
||
w18 &= 0x3ffffff;
|
||
o[0] = w0;
|
||
o[1] = w1;
|
||
o[2] = w2;
|
||
o[3] = w3;
|
||
o[4] = w4;
|
||
o[5] = w5;
|
||
o[6] = w6;
|
||
o[7] = w7;
|
||
o[8] = w8;
|
||
o[9] = w9;
|
||
o[10] = w10;
|
||
o[11] = w11;
|
||
o[12] = w12;
|
||
o[13] = w13;
|
||
o[14] = w14;
|
||
o[15] = w15;
|
||
o[16] = w16;
|
||
o[17] = w17;
|
||
o[18] = w18;
|
||
if (c !== 0) {
|
||
o[19] = c;
|
||
out.length++;
|
||
}
|
||
return out;
|
||
};
|
||
|
||
// Polyfill comb
|
||
if (!Math.imul) {
|
||
comb10MulTo = smallMulTo;
|
||
}
|
||
|
||
function bigMulTo (self, num, out) {
|
||
out.negative = num.negative ^ self.negative;
|
||
out.length = self.length + num.length;
|
||
|
||
var carry = 0;
|
||
var hncarry = 0;
|
||
for (var k = 0; k < out.length - 1; k++) {
|
||
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
|
||
// note that ncarry could be >= 0x3ffffff
|
||
var ncarry = hncarry;
|
||
hncarry = 0;
|
||
var rword = carry & 0x3ffffff;
|
||
var maxJ = Math.min(k, num.length - 1);
|
||
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
||
var i = k - j;
|
||
var a = self.words[i] | 0;
|
||
var b = num.words[j] | 0;
|
||
var r = a * b;
|
||
|
||
var lo = r & 0x3ffffff;
|
||
ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
|
||
lo = (lo + rword) | 0;
|
||
rword = lo & 0x3ffffff;
|
||
ncarry = (ncarry + (lo >>> 26)) | 0;
|
||
|
||
hncarry += ncarry >>> 26;
|
||
ncarry &= 0x3ffffff;
|
||
}
|
||
out.words[k] = rword;
|
||
carry = ncarry;
|
||
ncarry = hncarry;
|
||
}
|
||
if (carry !== 0) {
|
||
out.words[k] = carry;
|
||
} else {
|
||
out.length--;
|
||
}
|
||
|
||
return out.strip();
|
||
}
|
||
|
||
function jumboMulTo (self, num, out) {
|
||
var fftm = new FFTM();
|
||
return fftm.mulp(self, num, out);
|
||
}
|
||
|
||
BN.prototype.mulTo = function mulTo (num, out) {
|
||
var res;
|
||
var len = this.length + num.length;
|
||
if (this.length === 10 && num.length === 10) {
|
||
res = comb10MulTo(this, num, out);
|
||
} else if (len < 63) {
|
||
res = smallMulTo(this, num, out);
|
||
} else if (len < 1024) {
|
||
res = bigMulTo(this, num, out);
|
||
} else {
|
||
res = jumboMulTo(this, num, out);
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
// Cooley-Tukey algorithm for FFT
|
||
// slightly revisited to rely on looping instead of recursion
|
||
|
||
function FFTM (x, y) {
|
||
this.x = x;
|
||
this.y = y;
|
||
}
|
||
|
||
FFTM.prototype.makeRBT = function makeRBT (N) {
|
||
var t = new Array(N);
|
||
var l = BN.prototype._countBits(N) - 1;
|
||
for (var i = 0; i < N; i++) {
|
||
t[i] = this.revBin(i, l, N);
|
||
}
|
||
|
||
return t;
|
||
};
|
||
|
||
// Returns binary-reversed representation of `x`
|
||
FFTM.prototype.revBin = function revBin (x, l, N) {
|
||
if (x === 0 || x === N - 1) return x;
|
||
|
||
var rb = 0;
|
||
for (var i = 0; i < l; i++) {
|
||
rb |= (x & 1) << (l - i - 1);
|
||
x >>= 1;
|
||
}
|
||
|
||
return rb;
|
||
};
|
||
|
||
// Performs "tweedling" phase, therefore 'emulating'
|
||
// behaviour of the recursive algorithm
|
||
FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
|
||
for (var i = 0; i < N; i++) {
|
||
rtws[i] = rws[rbt[i]];
|
||
itws[i] = iws[rbt[i]];
|
||
}
|
||
};
|
||
|
||
FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
|
||
this.permute(rbt, rws, iws, rtws, itws, N);
|
||
|
||
for (var s = 1; s < N; s <<= 1) {
|
||
var l = s << 1;
|
||
|
||
var rtwdf = Math.cos(2 * Math.PI / l);
|
||
var itwdf = Math.sin(2 * Math.PI / l);
|
||
|
||
for (var p = 0; p < N; p += l) {
|
||
var rtwdf_ = rtwdf;
|
||
var itwdf_ = itwdf;
|
||
|
||
for (var j = 0; j < s; j++) {
|
||
var re = rtws[p + j];
|
||
var ie = itws[p + j];
|
||
|
||
var ro = rtws[p + j + s];
|
||
var io = itws[p + j + s];
|
||
|
||
var rx = rtwdf_ * ro - itwdf_ * io;
|
||
|
||
io = rtwdf_ * io + itwdf_ * ro;
|
||
ro = rx;
|
||
|
||
rtws[p + j] = re + ro;
|
||
itws[p + j] = ie + io;
|
||
|
||
rtws[p + j + s] = re - ro;
|
||
itws[p + j + s] = ie - io;
|
||
|
||
/* jshint maxdepth : false */
|
||
if (j !== l) {
|
||
rx = rtwdf * rtwdf_ - itwdf * itwdf_;
|
||
|
||
itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
|
||
rtwdf_ = rx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
|
||
var N = Math.max(m, n) | 1;
|
||
var odd = N & 1;
|
||
var i = 0;
|
||
for (N = N / 2 | 0; N; N = N >>> 1) {
|
||
i++;
|
||
}
|
||
|
||
return 1 << i + 1 + odd;
|
||
};
|
||
|
||
FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
|
||
if (N <= 1) return;
|
||
|
||
for (var i = 0; i < N / 2; i++) {
|
||
var t = rws[i];
|
||
|
||
rws[i] = rws[N - i - 1];
|
||
rws[N - i - 1] = t;
|
||
|
||
t = iws[i];
|
||
|
||
iws[i] = -iws[N - i - 1];
|
||
iws[N - i - 1] = -t;
|
||
}
|
||
};
|
||
|
||
FFTM.prototype.normalize13b = function normalize13b (ws, N) {
|
||
var carry = 0;
|
||
for (var i = 0; i < N / 2; i++) {
|
||
var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
|
||
Math.round(ws[2 * i] / N) +
|
||
carry;
|
||
|
||
ws[i] = w & 0x3ffffff;
|
||
|
||
if (w < 0x4000000) {
|
||
carry = 0;
|
||
} else {
|
||
carry = w / 0x4000000 | 0;
|
||
}
|
||
}
|
||
|
||
return ws;
|
||
};
|
||
|
||
FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
|
||
var carry = 0;
|
||
for (var i = 0; i < len; i++) {
|
||
carry = carry + (ws[i] | 0);
|
||
|
||
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
|
||
rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
|
||
}
|
||
|
||
// Pad with zeroes
|
||
for (i = 2 * len; i < N; ++i) {
|
||
rws[i] = 0;
|
||
}
|
||
|
||
assert(carry === 0);
|
||
assert((carry & ~0x1fff) === 0);
|
||
};
|
||
|
||
FFTM.prototype.stub = function stub (N) {
|
||
var ph = new Array(N);
|
||
for (var i = 0; i < N; i++) {
|
||
ph[i] = 0;
|
||
}
|
||
|
||
return ph;
|
||
};
|
||
|
||
FFTM.prototype.mulp = function mulp (x, y, out) {
|
||
var N = 2 * this.guessLen13b(x.length, y.length);
|
||
|
||
var rbt = this.makeRBT(N);
|
||
|
||
var _ = this.stub(N);
|
||
|
||
var rws = new Array(N);
|
||
var rwst = new Array(N);
|
||
var iwst = new Array(N);
|
||
|
||
var nrws = new Array(N);
|
||
var nrwst = new Array(N);
|
||
var niwst = new Array(N);
|
||
|
||
var rmws = out.words;
|
||
rmws.length = N;
|
||
|
||
this.convert13b(x.words, x.length, rws, N);
|
||
this.convert13b(y.words, y.length, nrws, N);
|
||
|
||
this.transform(rws, _, rwst, iwst, N, rbt);
|
||
this.transform(nrws, _, nrwst, niwst, N, rbt);
|
||
|
||
for (var i = 0; i < N; i++) {
|
||
var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
|
||
iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
|
||
rwst[i] = rx;
|
||
}
|
||
|
||
this.conjugate(rwst, iwst, N);
|
||
this.transform(rwst, iwst, rmws, _, N, rbt);
|
||
this.conjugate(rmws, _, N);
|
||
this.normalize13b(rmws, N);
|
||
|
||
out.negative = x.negative ^ y.negative;
|
||
out.length = x.length + y.length;
|
||
return out.strip();
|
||
};
|
||
|
||
// Multiply `this` by `num`
|
||
BN.prototype.mul = function mul (num) {
|
||
var out = new BN(null);
|
||
out.words = new Array(this.length + num.length);
|
||
return this.mulTo(num, out);
|
||
};
|
||
|
||
// Multiply employing FFT
|
||
BN.prototype.mulf = function mulf (num) {
|
||
var out = new BN(null);
|
||
out.words = new Array(this.length + num.length);
|
||
return jumboMulTo(this, num, out);
|
||
};
|
||
|
||
// In-place Multiplication
|
||
BN.prototype.imul = function imul (num) {
|
||
return this.clone().mulTo(num, this);
|
||
};
|
||
|
||
BN.prototype.imuln = function imuln (num) {
|
||
assert(typeof num === 'number');
|
||
assert(num < 0x4000000);
|
||
|
||
// Carry
|
||
var carry = 0;
|
||
for (var i = 0; i < this.length; i++) {
|
||
var w = (this.words[i] | 0) * num;
|
||
var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
|
||
carry >>= 26;
|
||
carry += (w / 0x4000000) | 0;
|
||
// NOTE: lo is 27bit maximum
|
||
carry += lo >>> 26;
|
||
this.words[i] = lo & 0x3ffffff;
|
||
}
|
||
|
||
if (carry !== 0) {
|
||
this.words[i] = carry;
|
||
this.length++;
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.muln = function muln (num) {
|
||
return this.clone().imuln(num);
|
||
};
|
||
|
||
// `this` * `this`
|
||
BN.prototype.sqr = function sqr () {
|
||
return this.mul(this);
|
||
};
|
||
|
||
// `this` * `this` in-place
|
||
BN.prototype.isqr = function isqr () {
|
||
return this.imul(this.clone());
|
||
};
|
||
|
||
// Math.pow(`this`, `num`)
|
||
BN.prototype.pow = function pow (num) {
|
||
var w = toBitArray(num);
|
||
if (w.length === 0) return new BN(1);
|
||
|
||
// Skip leading zeroes
|
||
var res = this;
|
||
for (var i = 0; i < w.length; i++, res = res.sqr()) {
|
||
if (w[i] !== 0) break;
|
||
}
|
||
|
||
if (++i < w.length) {
|
||
for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
|
||
if (w[i] === 0) continue;
|
||
|
||
res = res.mul(q);
|
||
}
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
// Shift-left in-place
|
||
BN.prototype.iushln = function iushln (bits) {
|
||
assert(typeof bits === 'number' && bits >= 0);
|
||
var r = bits % 26;
|
||
var s = (bits - r) / 26;
|
||
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
|
||
var i;
|
||
|
||
if (r !== 0) {
|
||
var carry = 0;
|
||
|
||
for (i = 0; i < this.length; i++) {
|
||
var newCarry = this.words[i] & carryMask;
|
||
var c = ((this.words[i] | 0) - newCarry) << r;
|
||
this.words[i] = c | carry;
|
||
carry = newCarry >>> (26 - r);
|
||
}
|
||
|
||
if (carry) {
|
||
this.words[i] = carry;
|
||
this.length++;
|
||
}
|
||
}
|
||
|
||
if (s !== 0) {
|
||
for (i = this.length - 1; i >= 0; i--) {
|
||
this.words[i + s] = this.words[i];
|
||
}
|
||
|
||
for (i = 0; i < s; i++) {
|
||
this.words[i] = 0;
|
||
}
|
||
|
||
this.length += s;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ishln = function ishln (bits) {
|
||
// TODO(indutny): implement me
|
||
assert(this.negative === 0);
|
||
return this.iushln(bits);
|
||
};
|
||
|
||
// Shift-right in-place
|
||
// NOTE: `hint` is a lowest bit before trailing zeroes
|
||
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
||
BN.prototype.iushrn = function iushrn (bits, hint, extended) {
|
||
assert(typeof bits === 'number' && bits >= 0);
|
||
var h;
|
||
if (hint) {
|
||
h = (hint - (hint % 26)) / 26;
|
||
} else {
|
||
h = 0;
|
||
}
|
||
|
||
var r = bits % 26;
|
||
var s = Math.min((bits - r) / 26, this.length);
|
||
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
||
var maskedWords = extended;
|
||
|
||
h -= s;
|
||
h = Math.max(0, h);
|
||
|
||
// Extended mode, copy masked part
|
||
if (maskedWords) {
|
||
for (var i = 0; i < s; i++) {
|
||
maskedWords.words[i] = this.words[i];
|
||
}
|
||
maskedWords.length = s;
|
||
}
|
||
|
||
if (s === 0) {
|
||
// No-op, we should not move anything at all
|
||
} else if (this.length > s) {
|
||
this.length -= s;
|
||
for (i = 0; i < this.length; i++) {
|
||
this.words[i] = this.words[i + s];
|
||
}
|
||
} else {
|
||
this.words[0] = 0;
|
||
this.length = 1;
|
||
}
|
||
|
||
var carry = 0;
|
||
for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
|
||
var word = this.words[i] | 0;
|
||
this.words[i] = (carry << (26 - r)) | (word >>> r);
|
||
carry = word & mask;
|
||
}
|
||
|
||
// Push carried bits as a mask
|
||
if (maskedWords && carry !== 0) {
|
||
maskedWords.words[maskedWords.length++] = carry;
|
||
}
|
||
|
||
if (this.length === 0) {
|
||
this.words[0] = 0;
|
||
this.length = 1;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.ishrn = function ishrn (bits, hint, extended) {
|
||
// TODO(indutny): implement me
|
||
assert(this.negative === 0);
|
||
return this.iushrn(bits, hint, extended);
|
||
};
|
||
|
||
// Shift-left
|
||
BN.prototype.shln = function shln (bits) {
|
||
return this.clone().ishln(bits);
|
||
};
|
||
|
||
BN.prototype.ushln = function ushln (bits) {
|
||
return this.clone().iushln(bits);
|
||
};
|
||
|
||
// Shift-right
|
||
BN.prototype.shrn = function shrn (bits) {
|
||
return this.clone().ishrn(bits);
|
||
};
|
||
|
||
BN.prototype.ushrn = function ushrn (bits) {
|
||
return this.clone().iushrn(bits);
|
||
};
|
||
|
||
// Test if n bit is set
|
||
BN.prototype.testn = function testn (bit) {
|
||
assert(typeof bit === 'number' && bit >= 0);
|
||
var r = bit % 26;
|
||
var s = (bit - r) / 26;
|
||
var q = 1 << r;
|
||
|
||
// Fast case: bit is much higher than all existing words
|
||
if (this.length <= s) return false;
|
||
|
||
// Check bit and return
|
||
var w = this.words[s];
|
||
|
||
return !!(w & q);
|
||
};
|
||
|
||
// Return only lowers bits of number (in-place)
|
||
BN.prototype.imaskn = function imaskn (bits) {
|
||
assert(typeof bits === 'number' && bits >= 0);
|
||
var r = bits % 26;
|
||
var s = (bits - r) / 26;
|
||
|
||
assert(this.negative === 0, 'imaskn works only with positive numbers');
|
||
|
||
if (this.length <= s) {
|
||
return this;
|
||
}
|
||
|
||
if (r !== 0) {
|
||
s++;
|
||
}
|
||
this.length = Math.min(s, this.length);
|
||
|
||
if (r !== 0) {
|
||
var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
|
||
this.words[this.length - 1] &= mask;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
// Return only lowers bits of number
|
||
BN.prototype.maskn = function maskn (bits) {
|
||
return this.clone().imaskn(bits);
|
||
};
|
||
|
||
// Add plain number `num` to `this`
|
||
BN.prototype.iaddn = function iaddn (num) {
|
||
assert(typeof num === 'number');
|
||
assert(num < 0x4000000);
|
||
if (num < 0) return this.isubn(-num);
|
||
|
||
// Possible sign change
|
||
if (this.negative !== 0) {
|
||
if (this.length === 1 && (this.words[0] | 0) < num) {
|
||
this.words[0] = num - (this.words[0] | 0);
|
||
this.negative = 0;
|
||
return this;
|
||
}
|
||
|
||
this.negative = 0;
|
||
this.isubn(num);
|
||
this.negative = 1;
|
||
return this;
|
||
}
|
||
|
||
// Add without checks
|
||
return this._iaddn(num);
|
||
};
|
||
|
||
BN.prototype._iaddn = function _iaddn (num) {
|
||
this.words[0] += num;
|
||
|
||
// Carry
|
||
for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
|
||
this.words[i] -= 0x4000000;
|
||
if (i === this.length - 1) {
|
||
this.words[i + 1] = 1;
|
||
} else {
|
||
this.words[i + 1]++;
|
||
}
|
||
}
|
||
this.length = Math.max(this.length, i + 1);
|
||
|
||
return this;
|
||
};
|
||
|
||
// Subtract plain number `num` from `this`
|
||
BN.prototype.isubn = function isubn (num) {
|
||
assert(typeof num === 'number');
|
||
assert(num < 0x4000000);
|
||
if (num < 0) return this.iaddn(-num);
|
||
|
||
if (this.negative !== 0) {
|
||
this.negative = 0;
|
||
this.iaddn(num);
|
||
this.negative = 1;
|
||
return this;
|
||
}
|
||
|
||
this.words[0] -= num;
|
||
|
||
if (this.length === 1 && this.words[0] < 0) {
|
||
this.words[0] = -this.words[0];
|
||
this.negative = 1;
|
||
} else {
|
||
// Carry
|
||
for (var i = 0; i < this.length && this.words[i] < 0; i++) {
|
||
this.words[i] += 0x4000000;
|
||
this.words[i + 1] -= 1;
|
||
}
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.addn = function addn (num) {
|
||
return this.clone().iaddn(num);
|
||
};
|
||
|
||
BN.prototype.subn = function subn (num) {
|
||
return this.clone().isubn(num);
|
||
};
|
||
|
||
BN.prototype.iabs = function iabs () {
|
||
this.negative = 0;
|
||
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.abs = function abs () {
|
||
return this.clone().iabs();
|
||
};
|
||
|
||
BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
|
||
var len = num.length + shift;
|
||
var i;
|
||
|
||
this._expand(len);
|
||
|
||
var w;
|
||
var carry = 0;
|
||
for (i = 0; i < num.length; i++) {
|
||
w = (this.words[i + shift] | 0) + carry;
|
||
var right = (num.words[i] | 0) * mul;
|
||
w -= right & 0x3ffffff;
|
||
carry = (w >> 26) - ((right / 0x4000000) | 0);
|
||
this.words[i + shift] = w & 0x3ffffff;
|
||
}
|
||
for (; i < this.length - shift; i++) {
|
||
w = (this.words[i + shift] | 0) + carry;
|
||
carry = w >> 26;
|
||
this.words[i + shift] = w & 0x3ffffff;
|
||
}
|
||
|
||
if (carry === 0) return this.strip();
|
||
|
||
// Subtraction overflow
|
||
assert(carry === -1);
|
||
carry = 0;
|
||
for (i = 0; i < this.length; i++) {
|
||
w = -(this.words[i] | 0) + carry;
|
||
carry = w >> 26;
|
||
this.words[i] = w & 0x3ffffff;
|
||
}
|
||
this.negative = 1;
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype._wordDiv = function _wordDiv (num, mode) {
|
||
var shift = this.length - num.length;
|
||
|
||
var a = this.clone();
|
||
var b = num;
|
||
|
||
// Normalize
|
||
var bhi = b.words[b.length - 1] | 0;
|
||
var bhiBits = this._countBits(bhi);
|
||
shift = 26 - bhiBits;
|
||
if (shift !== 0) {
|
||
b = b.ushln(shift);
|
||
a.iushln(shift);
|
||
bhi = b.words[b.length - 1] | 0;
|
||
}
|
||
|
||
// Initialize quotient
|
||
var m = a.length - b.length;
|
||
var q;
|
||
|
||
if (mode !== 'mod') {
|
||
q = new BN(null);
|
||
q.length = m + 1;
|
||
q.words = new Array(q.length);
|
||
for (var i = 0; i < q.length; i++) {
|
||
q.words[i] = 0;
|
||
}
|
||
}
|
||
|
||
var diff = a.clone()._ishlnsubmul(b, 1, m);
|
||
if (diff.negative === 0) {
|
||
a = diff;
|
||
if (q) {
|
||
q.words[m] = 1;
|
||
}
|
||
}
|
||
|
||
for (var j = m - 1; j >= 0; j--) {
|
||
var qj = (a.words[b.length + j] | 0) * 0x4000000 +
|
||
(a.words[b.length + j - 1] | 0);
|
||
|
||
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
|
||
// (0x7ffffff)
|
||
qj = Math.min((qj / bhi) | 0, 0x3ffffff);
|
||
|
||
a._ishlnsubmul(b, qj, j);
|
||
while (a.negative !== 0) {
|
||
qj--;
|
||
a.negative = 0;
|
||
a._ishlnsubmul(b, 1, j);
|
||
if (!a.isZero()) {
|
||
a.negative ^= 1;
|
||
}
|
||
}
|
||
if (q) {
|
||
q.words[j] = qj;
|
||
}
|
||
}
|
||
if (q) {
|
||
q.strip();
|
||
}
|
||
a.strip();
|
||
|
||
// Denormalize
|
||
if (mode !== 'div' && shift !== 0) {
|
||
a.iushrn(shift);
|
||
}
|
||
|
||
return {
|
||
div: q || null,
|
||
mod: a
|
||
};
|
||
};
|
||
|
||
// NOTE: 1) `mode` can be set to `mod` to request mod only,
|
||
// to `div` to request div only, or be absent to
|
||
// request both div & mod
|
||
// 2) `positive` is true if unsigned mod is requested
|
||
BN.prototype.divmod = function divmod (num, mode, positive) {
|
||
assert(!num.isZero());
|
||
|
||
if (this.isZero()) {
|
||
return {
|
||
div: new BN(0),
|
||
mod: new BN(0)
|
||
};
|
||
}
|
||
|
||
var div, mod, res;
|
||
if (this.negative !== 0 && num.negative === 0) {
|
||
res = this.neg().divmod(num, mode);
|
||
|
||
if (mode !== 'mod') {
|
||
div = res.div.neg();
|
||
}
|
||
|
||
if (mode !== 'div') {
|
||
mod = res.mod.neg();
|
||
if (positive && mod.negative !== 0) {
|
||
mod.iadd(num);
|
||
}
|
||
}
|
||
|
||
return {
|
||
div: div,
|
||
mod: mod
|
||
};
|
||
}
|
||
|
||
if (this.negative === 0 && num.negative !== 0) {
|
||
res = this.divmod(num.neg(), mode);
|
||
|
||
if (mode !== 'mod') {
|
||
div = res.div.neg();
|
||
}
|
||
|
||
return {
|
||
div: div,
|
||
mod: res.mod
|
||
};
|
||
}
|
||
|
||
if ((this.negative & num.negative) !== 0) {
|
||
res = this.neg().divmod(num.neg(), mode);
|
||
|
||
if (mode !== 'div') {
|
||
mod = res.mod.neg();
|
||
if (positive && mod.negative !== 0) {
|
||
mod.isub(num);
|
||
}
|
||
}
|
||
|
||
return {
|
||
div: res.div,
|
||
mod: mod
|
||
};
|
||
}
|
||
|
||
// Both numbers are positive at this point
|
||
|
||
// Strip both numbers to approximate shift value
|
||
if (num.length > this.length || this.cmp(num) < 0) {
|
||
return {
|
||
div: new BN(0),
|
||
mod: this
|
||
};
|
||
}
|
||
|
||
// Very short reduction
|
||
if (num.length === 1) {
|
||
if (mode === 'div') {
|
||
return {
|
||
div: this.divn(num.words[0]),
|
||
mod: null
|
||
};
|
||
}
|
||
|
||
if (mode === 'mod') {
|
||
return {
|
||
div: null,
|
||
mod: new BN(this.modn(num.words[0]))
|
||
};
|
||
}
|
||
|
||
return {
|
||
div: this.divn(num.words[0]),
|
||
mod: new BN(this.modn(num.words[0]))
|
||
};
|
||
}
|
||
|
||
return this._wordDiv(num, mode);
|
||
};
|
||
|
||
// Find `this` / `num`
|
||
BN.prototype.div = function div (num) {
|
||
return this.divmod(num, 'div', false).div;
|
||
};
|
||
|
||
// Find `this` % `num`
|
||
BN.prototype.mod = function mod (num) {
|
||
return this.divmod(num, 'mod', false).mod;
|
||
};
|
||
|
||
BN.prototype.umod = function umod (num) {
|
||
return this.divmod(num, 'mod', true).mod;
|
||
};
|
||
|
||
// Find Round(`this` / `num`)
|
||
BN.prototype.divRound = function divRound (num) {
|
||
var dm = this.divmod(num);
|
||
|
||
// Fast case - exact division
|
||
if (dm.mod.isZero()) return dm.div;
|
||
|
||
var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
|
||
|
||
var half = num.ushrn(1);
|
||
var r2 = num.andln(1);
|
||
var cmp = mod.cmp(half);
|
||
|
||
// Round down
|
||
if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
|
||
|
||
// Round up
|
||
return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
|
||
};
|
||
|
||
BN.prototype.modn = function modn (num) {
|
||
assert(num <= 0x3ffffff);
|
||
var p = (1 << 26) % num;
|
||
|
||
var acc = 0;
|
||
for (var i = this.length - 1; i >= 0; i--) {
|
||
acc = (p * acc + (this.words[i] | 0)) % num;
|
||
}
|
||
|
||
return acc;
|
||
};
|
||
|
||
// In-place division by number
|
||
BN.prototype.idivn = function idivn (num) {
|
||
assert(num <= 0x3ffffff);
|
||
|
||
var carry = 0;
|
||
for (var i = this.length - 1; i >= 0; i--) {
|
||
var w = (this.words[i] | 0) + carry * 0x4000000;
|
||
this.words[i] = (w / num) | 0;
|
||
carry = w % num;
|
||
}
|
||
|
||
return this.strip();
|
||
};
|
||
|
||
BN.prototype.divn = function divn (num) {
|
||
return this.clone().idivn(num);
|
||
};
|
||
|
||
BN.prototype.egcd = function egcd (p) {
|
||
assert(p.negative === 0);
|
||
assert(!p.isZero());
|
||
|
||
var x = this;
|
||
var y = p.clone();
|
||
|
||
if (x.negative !== 0) {
|
||
x = x.umod(p);
|
||
} else {
|
||
x = x.clone();
|
||
}
|
||
|
||
// A * x + B * y = x
|
||
var A = new BN(1);
|
||
var B = new BN(0);
|
||
|
||
// C * x + D * y = y
|
||
var C = new BN(0);
|
||
var D = new BN(1);
|
||
|
||
var g = 0;
|
||
|
||
while (x.isEven() && y.isEven()) {
|
||
x.iushrn(1);
|
||
y.iushrn(1);
|
||
++g;
|
||
}
|
||
|
||
var yp = y.clone();
|
||
var xp = x.clone();
|
||
|
||
while (!x.isZero()) {
|
||
for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
||
if (i > 0) {
|
||
x.iushrn(i);
|
||
while (i-- > 0) {
|
||
if (A.isOdd() || B.isOdd()) {
|
||
A.iadd(yp);
|
||
B.isub(xp);
|
||
}
|
||
|
||
A.iushrn(1);
|
||
B.iushrn(1);
|
||
}
|
||
}
|
||
|
||
for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
||
if (j > 0) {
|
||
y.iushrn(j);
|
||
while (j-- > 0) {
|
||
if (C.isOdd() || D.isOdd()) {
|
||
C.iadd(yp);
|
||
D.isub(xp);
|
||
}
|
||
|
||
C.iushrn(1);
|
||
D.iushrn(1);
|
||
}
|
||
}
|
||
|
||
if (x.cmp(y) >= 0) {
|
||
x.isub(y);
|
||
A.isub(C);
|
||
B.isub(D);
|
||
} else {
|
||
y.isub(x);
|
||
C.isub(A);
|
||
D.isub(B);
|
||
}
|
||
}
|
||
|
||
return {
|
||
a: C,
|
||
b: D,
|
||
gcd: y.iushln(g)
|
||
};
|
||
};
|
||
|
||
// This is reduced incarnation of the binary EEA
|
||
// above, designated to invert members of the
|
||
// _prime_ fields F(p) at a maximal speed
|
||
BN.prototype._invmp = function _invmp (p) {
|
||
assert(p.negative === 0);
|
||
assert(!p.isZero());
|
||
|
||
var a = this;
|
||
var b = p.clone();
|
||
|
||
if (a.negative !== 0) {
|
||
a = a.umod(p);
|
||
} else {
|
||
a = a.clone();
|
||
}
|
||
|
||
var x1 = new BN(1);
|
||
var x2 = new BN(0);
|
||
|
||
var delta = b.clone();
|
||
|
||
while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
|
||
for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
|
||
if (i > 0) {
|
||
a.iushrn(i);
|
||
while (i-- > 0) {
|
||
if (x1.isOdd()) {
|
||
x1.iadd(delta);
|
||
}
|
||
|
||
x1.iushrn(1);
|
||
}
|
||
}
|
||
|
||
for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
|
||
if (j > 0) {
|
||
b.iushrn(j);
|
||
while (j-- > 0) {
|
||
if (x2.isOdd()) {
|
||
x2.iadd(delta);
|
||
}
|
||
|
||
x2.iushrn(1);
|
||
}
|
||
}
|
||
|
||
if (a.cmp(b) >= 0) {
|
||
a.isub(b);
|
||
x1.isub(x2);
|
||
} else {
|
||
b.isub(a);
|
||
x2.isub(x1);
|
||
}
|
||
}
|
||
|
||
var res;
|
||
if (a.cmpn(1) === 0) {
|
||
res = x1;
|
||
} else {
|
||
res = x2;
|
||
}
|
||
|
||
if (res.cmpn(0) < 0) {
|
||
res.iadd(p);
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
BN.prototype.gcd = function gcd (num) {
|
||
if (this.isZero()) return num.abs();
|
||
if (num.isZero()) return this.abs();
|
||
|
||
var a = this.clone();
|
||
var b = num.clone();
|
||
a.negative = 0;
|
||
b.negative = 0;
|
||
|
||
// Remove common factor of two
|
||
for (var shift = 0; a.isEven() && b.isEven(); shift++) {
|
||
a.iushrn(1);
|
||
b.iushrn(1);
|
||
}
|
||
|
||
do {
|
||
while (a.isEven()) {
|
||
a.iushrn(1);
|
||
}
|
||
while (b.isEven()) {
|
||
b.iushrn(1);
|
||
}
|
||
|
||
var r = a.cmp(b);
|
||
if (r < 0) {
|
||
// Swap `a` and `b` to make `a` always bigger than `b`
|
||
var t = a;
|
||
a = b;
|
||
b = t;
|
||
} else if (r === 0 || b.cmpn(1) === 0) {
|
||
break;
|
||
}
|
||
|
||
a.isub(b);
|
||
} while (true);
|
||
|
||
return b.iushln(shift);
|
||
};
|
||
|
||
// Invert number in the field F(num)
|
||
BN.prototype.invm = function invm (num) {
|
||
return this.egcd(num).a.umod(num);
|
||
};
|
||
|
||
BN.prototype.isEven = function isEven () {
|
||
return (this.words[0] & 1) === 0;
|
||
};
|
||
|
||
BN.prototype.isOdd = function isOdd () {
|
||
return (this.words[0] & 1) === 1;
|
||
};
|
||
|
||
// And first word and num
|
||
BN.prototype.andln = function andln (num) {
|
||
return this.words[0] & num;
|
||
};
|
||
|
||
// Increment at the bit position in-line
|
||
BN.prototype.bincn = function bincn (bit) {
|
||
assert(typeof bit === 'number');
|
||
var r = bit % 26;
|
||
var s = (bit - r) / 26;
|
||
var q = 1 << r;
|
||
|
||
// Fast case: bit is much higher than all existing words
|
||
if (this.length <= s) {
|
||
this._expand(s + 1);
|
||
this.words[s] |= q;
|
||
return this;
|
||
}
|
||
|
||
// Add bit and propagate, if needed
|
||
var carry = q;
|
||
for (var i = s; carry !== 0 && i < this.length; i++) {
|
||
var w = this.words[i] | 0;
|
||
w += carry;
|
||
carry = w >>> 26;
|
||
w &= 0x3ffffff;
|
||
this.words[i] = w;
|
||
}
|
||
if (carry !== 0) {
|
||
this.words[i] = carry;
|
||
this.length++;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.isZero = function isZero () {
|
||
return this.length === 1 && this.words[0] === 0;
|
||
};
|
||
|
||
BN.prototype.cmpn = function cmpn (num) {
|
||
var negative = num < 0;
|
||
|
||
if (this.negative !== 0 && !negative) return -1;
|
||
if (this.negative === 0 && negative) return 1;
|
||
|
||
this.strip();
|
||
|
||
var res;
|
||
if (this.length > 1) {
|
||
res = 1;
|
||
} else {
|
||
if (negative) {
|
||
num = -num;
|
||
}
|
||
|
||
assert(num <= 0x3ffffff, 'Number is too big');
|
||
|
||
var w = this.words[0] | 0;
|
||
res = w === num ? 0 : w < num ? -1 : 1;
|
||
}
|
||
if (this.negative !== 0) return -res | 0;
|
||
return res;
|
||
};
|
||
|
||
// Compare two numbers and return:
|
||
// 1 - if `this` > `num`
|
||
// 0 - if `this` == `num`
|
||
// -1 - if `this` < `num`
|
||
BN.prototype.cmp = function cmp (num) {
|
||
if (this.negative !== 0 && num.negative === 0) return -1;
|
||
if (this.negative === 0 && num.negative !== 0) return 1;
|
||
|
||
var res = this.ucmp(num);
|
||
if (this.negative !== 0) return -res | 0;
|
||
return res;
|
||
};
|
||
|
||
// Unsigned comparison
|
||
BN.prototype.ucmp = function ucmp (num) {
|
||
// At this point both numbers have the same sign
|
||
if (this.length > num.length) return 1;
|
||
if (this.length < num.length) return -1;
|
||
|
||
var res = 0;
|
||
for (var i = this.length - 1; i >= 0; i--) {
|
||
var a = this.words[i] | 0;
|
||
var b = num.words[i] | 0;
|
||
|
||
if (a === b) continue;
|
||
if (a < b) {
|
||
res = -1;
|
||
} else if (a > b) {
|
||
res = 1;
|
||
}
|
||
break;
|
||
}
|
||
return res;
|
||
};
|
||
|
||
BN.prototype.gtn = function gtn (num) {
|
||
return this.cmpn(num) === 1;
|
||
};
|
||
|
||
BN.prototype.gt = function gt (num) {
|
||
return this.cmp(num) === 1;
|
||
};
|
||
|
||
BN.prototype.gten = function gten (num) {
|
||
return this.cmpn(num) >= 0;
|
||
};
|
||
|
||
BN.prototype.gte = function gte (num) {
|
||
return this.cmp(num) >= 0;
|
||
};
|
||
|
||
BN.prototype.ltn = function ltn (num) {
|
||
return this.cmpn(num) === -1;
|
||
};
|
||
|
||
BN.prototype.lt = function lt (num) {
|
||
return this.cmp(num) === -1;
|
||
};
|
||
|
||
BN.prototype.lten = function lten (num) {
|
||
return this.cmpn(num) <= 0;
|
||
};
|
||
|
||
BN.prototype.lte = function lte (num) {
|
||
return this.cmp(num) <= 0;
|
||
};
|
||
|
||
BN.prototype.eqn = function eqn (num) {
|
||
return this.cmpn(num) === 0;
|
||
};
|
||
|
||
BN.prototype.eq = function eq (num) {
|
||
return this.cmp(num) === 0;
|
||
};
|
||
|
||
//
|
||
// A reduce context, could be using montgomery or something better, depending
|
||
// on the `m` itself.
|
||
//
|
||
BN.red = function red (num) {
|
||
return new Red(num);
|
||
};
|
||
|
||
BN.prototype.toRed = function toRed (ctx) {
|
||
assert(!this.red, 'Already a number in reduction context');
|
||
assert(this.negative === 0, 'red works only with positives');
|
||
return ctx.convertTo(this)._forceRed(ctx);
|
||
};
|
||
|
||
BN.prototype.fromRed = function fromRed () {
|
||
assert(this.red, 'fromRed works only with numbers in reduction context');
|
||
return this.red.convertFrom(this);
|
||
};
|
||
|
||
BN.prototype._forceRed = function _forceRed (ctx) {
|
||
this.red = ctx;
|
||
return this;
|
||
};
|
||
|
||
BN.prototype.forceRed = function forceRed (ctx) {
|
||
assert(!this.red, 'Already a number in reduction context');
|
||
return this._forceRed(ctx);
|
||
};
|
||
|
||
BN.prototype.redAdd = function redAdd (num) {
|
||
assert(this.red, 'redAdd works only with red numbers');
|
||
return this.red.add(this, num);
|
||
};
|
||
|
||
BN.prototype.redIAdd = function redIAdd (num) {
|
||
assert(this.red, 'redIAdd works only with red numbers');
|
||
return this.red.iadd(this, num);
|
||
};
|
||
|
||
BN.prototype.redSub = function redSub (num) {
|
||
assert(this.red, 'redSub works only with red numbers');
|
||
return this.red.sub(this, num);
|
||
};
|
||
|
||
BN.prototype.redISub = function redISub (num) {
|
||
assert(this.red, 'redISub works only with red numbers');
|
||
return this.red.isub(this, num);
|
||
};
|
||
|
||
BN.prototype.redShl = function redShl (num) {
|
||
assert(this.red, 'redShl works only with red numbers');
|
||
return this.red.shl(this, num);
|
||
};
|
||
|
||
BN.prototype.redMul = function redMul (num) {
|
||
assert(this.red, 'redMul works only with red numbers');
|
||
this.red._verify2(this, num);
|
||
return this.red.mul(this, num);
|
||
};
|
||
|
||
BN.prototype.redIMul = function redIMul (num) {
|
||
assert(this.red, 'redMul works only with red numbers');
|
||
this.red._verify2(this, num);
|
||
return this.red.imul(this, num);
|
||
};
|
||
|
||
BN.prototype.redSqr = function redSqr () {
|
||
assert(this.red, 'redSqr works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.sqr(this);
|
||
};
|
||
|
||
BN.prototype.redISqr = function redISqr () {
|
||
assert(this.red, 'redISqr works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.isqr(this);
|
||
};
|
||
|
||
// Square root over p
|
||
BN.prototype.redSqrt = function redSqrt () {
|
||
assert(this.red, 'redSqrt works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.sqrt(this);
|
||
};
|
||
|
||
BN.prototype.redInvm = function redInvm () {
|
||
assert(this.red, 'redInvm works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.invm(this);
|
||
};
|
||
|
||
// Return negative clone of `this` % `red modulo`
|
||
BN.prototype.redNeg = function redNeg () {
|
||
assert(this.red, 'redNeg works only with red numbers');
|
||
this.red._verify1(this);
|
||
return this.red.neg(this);
|
||
};
|
||
|
||
BN.prototype.redPow = function redPow (num) {
|
||
assert(this.red && !num.red, 'redPow(normalNum)');
|
||
this.red._verify1(this);
|
||
return this.red.pow(this, num);
|
||
};
|
||
|
||
// Prime numbers with efficient reduction
|
||
var primes = {
|
||
k256: null,
|
||
p224: null,
|
||
p192: null,
|
||
p25519: null
|
||
};
|
||
|
||
// Pseudo-Mersenne prime
|
||
function MPrime (name, p) {
|
||
// P = 2 ^ N - K
|
||
this.name = name;
|
||
this.p = new BN(p, 16);
|
||
this.n = this.p.bitLength();
|
||
this.k = new BN(1).iushln(this.n).isub(this.p);
|
||
|
||
this.tmp = this._tmp();
|
||
}
|
||
|
||
MPrime.prototype._tmp = function _tmp () {
|
||
var tmp = new BN(null);
|
||
tmp.words = new Array(Math.ceil(this.n / 13));
|
||
return tmp;
|
||
};
|
||
|
||
MPrime.prototype.ireduce = function ireduce (num) {
|
||
// Assumes that `num` is less than `P^2`
|
||
// num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
|
||
var r = num;
|
||
var rlen;
|
||
|
||
do {
|
||
this.split(r, this.tmp);
|
||
r = this.imulK(r);
|
||
r = r.iadd(this.tmp);
|
||
rlen = r.bitLength();
|
||
} while (rlen > this.n);
|
||
|
||
var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
|
||
if (cmp === 0) {
|
||
r.words[0] = 0;
|
||
r.length = 1;
|
||
} else if (cmp > 0) {
|
||
r.isub(this.p);
|
||
} else {
|
||
r.strip();
|
||
}
|
||
|
||
return r;
|
||
};
|
||
|
||
MPrime.prototype.split = function split (input, out) {
|
||
input.iushrn(this.n, 0, out);
|
||
};
|
||
|
||
MPrime.prototype.imulK = function imulK (num) {
|
||
return num.imul(this.k);
|
||
};
|
||
|
||
function K256 () {
|
||
MPrime.call(
|
||
this,
|
||
'k256',
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
|
||
}
|
||
inherits(K256, MPrime);
|
||
|
||
K256.prototype.split = function split (input, output) {
|
||
// 256 = 9 * 26 + 22
|
||
var mask = 0x3fffff;
|
||
|
||
var outLen = Math.min(input.length, 9);
|
||
for (var i = 0; i < outLen; i++) {
|
||
output.words[i] = input.words[i];
|
||
}
|
||
output.length = outLen;
|
||
|
||
if (input.length <= 9) {
|
||
input.words[0] = 0;
|
||
input.length = 1;
|
||
return;
|
||
}
|
||
|
||
// Shift by 9 limbs
|
||
var prev = input.words[9];
|
||
output.words[output.length++] = prev & mask;
|
||
|
||
for (i = 10; i < input.length; i++) {
|
||
var next = input.words[i] | 0;
|
||
input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
|
||
prev = next;
|
||
}
|
||
prev >>>= 22;
|
||
input.words[i - 10] = prev;
|
||
if (prev === 0 && input.length > 10) {
|
||
input.length -= 10;
|
||
} else {
|
||
input.length -= 9;
|
||
}
|
||
};
|
||
|
||
K256.prototype.imulK = function imulK (num) {
|
||
// K = 0x1000003d1 = [ 0x40, 0x3d1 ]
|
||
num.words[num.length] = 0;
|
||
num.words[num.length + 1] = 0;
|
||
num.length += 2;
|
||
|
||
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
|
||
var lo = 0;
|
||
for (var i = 0; i < num.length; i++) {
|
||
var w = num.words[i] | 0;
|
||
lo += w * 0x3d1;
|
||
num.words[i] = lo & 0x3ffffff;
|
||
lo = w * 0x40 + ((lo / 0x4000000) | 0);
|
||
}
|
||
|
||
// Fast length reduction
|
||
if (num.words[num.length - 1] === 0) {
|
||
num.length--;
|
||
if (num.words[num.length - 1] === 0) {
|
||
num.length--;
|
||
}
|
||
}
|
||
return num;
|
||
};
|
||
|
||
function P224 () {
|
||
MPrime.call(
|
||
this,
|
||
'p224',
|
||
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
|
||
}
|
||
inherits(P224, MPrime);
|
||
|
||
function P192 () {
|
||
MPrime.call(
|
||
this,
|
||
'p192',
|
||
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
|
||
}
|
||
inherits(P192, MPrime);
|
||
|
||
function P25519 () {
|
||
// 2 ^ 255 - 19
|
||
MPrime.call(
|
||
this,
|
||
'25519',
|
||
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
|
||
}
|
||
inherits(P25519, MPrime);
|
||
|
||
P25519.prototype.imulK = function imulK (num) {
|
||
// K = 0x13
|
||
var carry = 0;
|
||
for (var i = 0; i < num.length; i++) {
|
||
var hi = (num.words[i] | 0) * 0x13 + carry;
|
||
var lo = hi & 0x3ffffff;
|
||
hi >>>= 26;
|
||
|
||
num.words[i] = lo;
|
||
carry = hi;
|
||
}
|
||
if (carry !== 0) {
|
||
num.words[num.length++] = carry;
|
||
}
|
||
return num;
|
||
};
|
||
|
||
// Exported mostly for testing purposes, use plain name instead
|
||
BN._prime = function prime (name) {
|
||
// Cached version of prime
|
||
if (primes[name]) return primes[name];
|
||
|
||
var prime;
|
||
if (name === 'k256') {
|
||
prime = new K256();
|
||
} else if (name === 'p224') {
|
||
prime = new P224();
|
||
} else if (name === 'p192') {
|
||
prime = new P192();
|
||
} else if (name === 'p25519') {
|
||
prime = new P25519();
|
||
} else {
|
||
throw new Error('Unknown prime ' + name);
|
||
}
|
||
primes[name] = prime;
|
||
|
||
return prime;
|
||
};
|
||
|
||
//
|
||
// Base reduction engine
|
||
//
|
||
function Red (m) {
|
||
if (typeof m === 'string') {
|
||
var prime = BN._prime(m);
|
||
this.m = prime.p;
|
||
this.prime = prime;
|
||
} else {
|
||
assert(m.gtn(1), 'modulus must be greater than 1');
|
||
this.m = m;
|
||
this.prime = null;
|
||
}
|
||
}
|
||
|
||
Red.prototype._verify1 = function _verify1 (a) {
|
||
assert(a.negative === 0, 'red works only with positives');
|
||
assert(a.red, 'red works only with red numbers');
|
||
};
|
||
|
||
Red.prototype._verify2 = function _verify2 (a, b) {
|
||
assert((a.negative | b.negative) === 0, 'red works only with positives');
|
||
assert(a.red && a.red === b.red,
|
||
'red works only with red numbers');
|
||
};
|
||
|
||
Red.prototype.imod = function imod (a) {
|
||
if (this.prime) return this.prime.ireduce(a)._forceRed(this);
|
||
return a.umod(this.m)._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.neg = function neg (a) {
|
||
if (a.isZero()) {
|
||
return a.clone();
|
||
}
|
||
|
||
return this.m.sub(a)._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.add = function add (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.add(b);
|
||
if (res.cmp(this.m) >= 0) {
|
||
res.isub(this.m);
|
||
}
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.iadd = function iadd (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.iadd(b);
|
||
if (res.cmp(this.m) >= 0) {
|
||
res.isub(this.m);
|
||
}
|
||
return res;
|
||
};
|
||
|
||
Red.prototype.sub = function sub (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.sub(b);
|
||
if (res.cmpn(0) < 0) {
|
||
res.iadd(this.m);
|
||
}
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Red.prototype.isub = function isub (a, b) {
|
||
this._verify2(a, b);
|
||
|
||
var res = a.isub(b);
|
||
if (res.cmpn(0) < 0) {
|
||
res.iadd(this.m);
|
||
}
|
||
return res;
|
||
};
|
||
|
||
Red.prototype.shl = function shl (a, num) {
|
||
this._verify1(a);
|
||
return this.imod(a.ushln(num));
|
||
};
|
||
|
||
Red.prototype.imul = function imul (a, b) {
|
||
this._verify2(a, b);
|
||
return this.imod(a.imul(b));
|
||
};
|
||
|
||
Red.prototype.mul = function mul (a, b) {
|
||
this._verify2(a, b);
|
||
return this.imod(a.mul(b));
|
||
};
|
||
|
||
Red.prototype.isqr = function isqr (a) {
|
||
return this.imul(a, a.clone());
|
||
};
|
||
|
||
Red.prototype.sqr = function sqr (a) {
|
||
return this.mul(a, a);
|
||
};
|
||
|
||
Red.prototype.sqrt = function sqrt (a) {
|
||
if (a.isZero()) return a.clone();
|
||
|
||
var mod3 = this.m.andln(3);
|
||
assert(mod3 % 2 === 1);
|
||
|
||
// Fast case
|
||
if (mod3 === 3) {
|
||
var pow = this.m.add(new BN(1)).iushrn(2);
|
||
return this.pow(a, pow);
|
||
}
|
||
|
||
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
|
||
//
|
||
// Find Q and S, that Q * 2 ^ S = (P - 1)
|
||
var q = this.m.subn(1);
|
||
var s = 0;
|
||
while (!q.isZero() && q.andln(1) === 0) {
|
||
s++;
|
||
q.iushrn(1);
|
||
}
|
||
assert(!q.isZero());
|
||
|
||
var one = new BN(1).toRed(this);
|
||
var nOne = one.redNeg();
|
||
|
||
// Find quadratic non-residue
|
||
// NOTE: Max is such because of generalized Riemann hypothesis.
|
||
var lpow = this.m.subn(1).iushrn(1);
|
||
var z = this.m.bitLength();
|
||
z = new BN(2 * z * z).toRed(this);
|
||
|
||
while (this.pow(z, lpow).cmp(nOne) !== 0) {
|
||
z.redIAdd(nOne);
|
||
}
|
||
|
||
var c = this.pow(z, q);
|
||
var r = this.pow(a, q.addn(1).iushrn(1));
|
||
var t = this.pow(a, q);
|
||
var m = s;
|
||
while (t.cmp(one) !== 0) {
|
||
var tmp = t;
|
||
for (var i = 0; tmp.cmp(one) !== 0; i++) {
|
||
tmp = tmp.redSqr();
|
||
}
|
||
assert(i < m);
|
||
var b = this.pow(c, new BN(1).iushln(m - i - 1));
|
||
|
||
r = r.redMul(b);
|
||
c = b.redSqr();
|
||
t = t.redMul(c);
|
||
m = i;
|
||
}
|
||
|
||
return r;
|
||
};
|
||
|
||
Red.prototype.invm = function invm (a) {
|
||
var inv = a._invmp(this.m);
|
||
if (inv.negative !== 0) {
|
||
inv.negative = 0;
|
||
return this.imod(inv).redNeg();
|
||
} else {
|
||
return this.imod(inv);
|
||
}
|
||
};
|
||
|
||
Red.prototype.pow = function pow (a, num) {
|
||
if (num.isZero()) return new BN(1).toRed(this);
|
||
if (num.cmpn(1) === 0) return a.clone();
|
||
|
||
var windowSize = 4;
|
||
var wnd = new Array(1 << windowSize);
|
||
wnd[0] = new BN(1).toRed(this);
|
||
wnd[1] = a;
|
||
for (var i = 2; i < wnd.length; i++) {
|
||
wnd[i] = this.mul(wnd[i - 1], a);
|
||
}
|
||
|
||
var res = wnd[0];
|
||
var current = 0;
|
||
var currentLen = 0;
|
||
var start = num.bitLength() % 26;
|
||
if (start === 0) {
|
||
start = 26;
|
||
}
|
||
|
||
for (i = num.length - 1; i >= 0; i--) {
|
||
var word = num.words[i];
|
||
for (var j = start - 1; j >= 0; j--) {
|
||
var bit = (word >> j) & 1;
|
||
if (res !== wnd[0]) {
|
||
res = this.sqr(res);
|
||
}
|
||
|
||
if (bit === 0 && current === 0) {
|
||
currentLen = 0;
|
||
continue;
|
||
}
|
||
|
||
current <<= 1;
|
||
current |= bit;
|
||
currentLen++;
|
||
if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
|
||
|
||
res = this.mul(res, wnd[current]);
|
||
currentLen = 0;
|
||
current = 0;
|
||
}
|
||
start = 26;
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
Red.prototype.convertTo = function convertTo (num) {
|
||
var r = num.umod(this.m);
|
||
|
||
return r === num ? r.clone() : r;
|
||
};
|
||
|
||
Red.prototype.convertFrom = function convertFrom (num) {
|
||
var res = num.clone();
|
||
res.red = null;
|
||
return res;
|
||
};
|
||
|
||
//
|
||
// Montgomery method engine
|
||
//
|
||
|
||
BN.mont = function mont (num) {
|
||
return new Mont(num);
|
||
};
|
||
|
||
function Mont (m) {
|
||
Red.call(this, m);
|
||
|
||
this.shift = this.m.bitLength();
|
||
if (this.shift % 26 !== 0) {
|
||
this.shift += 26 - (this.shift % 26);
|
||
}
|
||
|
||
this.r = new BN(1).iushln(this.shift);
|
||
this.r2 = this.imod(this.r.sqr());
|
||
this.rinv = this.r._invmp(this.m);
|
||
|
||
this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
|
||
this.minv = this.minv.umod(this.r);
|
||
this.minv = this.r.sub(this.minv);
|
||
}
|
||
inherits(Mont, Red);
|
||
|
||
Mont.prototype.convertTo = function convertTo (num) {
|
||
return this.imod(num.ushln(this.shift));
|
||
};
|
||
|
||
Mont.prototype.convertFrom = function convertFrom (num) {
|
||
var r = this.imod(num.mul(this.rinv));
|
||
r.red = null;
|
||
return r;
|
||
};
|
||
|
||
Mont.prototype.imul = function imul (a, b) {
|
||
if (a.isZero() || b.isZero()) {
|
||
a.words[0] = 0;
|
||
a.length = 1;
|
||
return a;
|
||
}
|
||
|
||
var t = a.imul(b);
|
||
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
||
var u = t.isub(c).iushrn(this.shift);
|
||
var res = u;
|
||
|
||
if (u.cmp(this.m) >= 0) {
|
||
res = u.isub(this.m);
|
||
} else if (u.cmpn(0) < 0) {
|
||
res = u.iadd(this.m);
|
||
}
|
||
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Mont.prototype.mul = function mul (a, b) {
|
||
if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
|
||
|
||
var t = a.mul(b);
|
||
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
||
var u = t.isub(c).iushrn(this.shift);
|
||
var res = u;
|
||
if (u.cmp(this.m) >= 0) {
|
||
res = u.isub(this.m);
|
||
} else if (u.cmpn(0) < 0) {
|
||
res = u.iadd(this.m);
|
||
}
|
||
|
||
return res._forceRed(this);
|
||
};
|
||
|
||
Mont.prototype.invm = function invm (a) {
|
||
// (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
|
||
var res = this.imod(a._invmp(this.m).mul(this.r2));
|
||
return res._forceRed(this);
|
||
};
|
||
})(typeof module === 'undefined' || module, this);
|
||
|
||
},{"buffer":4}],3:[function(require,module,exports){
|
||
var randomBytes = require('ethers-utils').randomBytes; module.exports = function(length) { return randomBytes(length); };
|
||
},{"ethers-utils":27}],4:[function(require,module,exports){
|
||
|
||
},{}],5:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var elliptic = exports;
|
||
|
||
elliptic.version = require('../package.json').version;
|
||
elliptic.utils = require('./elliptic/utils');
|
||
elliptic.rand = require('brorand');
|
||
elliptic.hmacDRBG = require('./elliptic/hmac-drbg');
|
||
elliptic.curve = require('./elliptic/curve');
|
||
elliptic.curves = require('./elliptic/curves');
|
||
|
||
// Protocols
|
||
elliptic.ec = require('./elliptic/ec');
|
||
elliptic.eddsa = require('./elliptic/eddsa');
|
||
|
||
},{"../package.json":19,"./elliptic/curve":8,"./elliptic/curves":11,"./elliptic/ec":12,"./elliptic/eddsa":15,"./elliptic/hmac-drbg":16,"./elliptic/utils":18,"brorand":3}],6:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var BN = require('bn.js');
|
||
var elliptic = require('../../elliptic');
|
||
var utils = elliptic.utils;
|
||
var getNAF = utils.getNAF;
|
||
var getJSF = utils.getJSF;
|
||
var assert = utils.assert;
|
||
|
||
function BaseCurve(type, conf) {
|
||
this.type = type;
|
||
this.p = new BN(conf.p, 16);
|
||
|
||
// Use Montgomery, when there is no fast reduction for the prime
|
||
this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
|
||
|
||
// Useful for many curves
|
||
this.zero = new BN(0).toRed(this.red);
|
||
this.one = new BN(1).toRed(this.red);
|
||
this.two = new BN(2).toRed(this.red);
|
||
|
||
// Curve configuration, optional
|
||
this.n = conf.n && new BN(conf.n, 16);
|
||
this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
|
||
|
||
// Temporary arrays
|
||
this._wnafT1 = new Array(4);
|
||
this._wnafT2 = new Array(4);
|
||
this._wnafT3 = new Array(4);
|
||
this._wnafT4 = new Array(4);
|
||
|
||
// Generalized Greg Maxwell's trick
|
||
var adjustCount = this.n && this.p.div(this.n);
|
||
if (!adjustCount || adjustCount.cmpn(100) > 0) {
|
||
this.redN = null;
|
||
} else {
|
||
this._maxwellTrick = true;
|
||
this.redN = this.n.toRed(this.red);
|
||
}
|
||
}
|
||
module.exports = BaseCurve;
|
||
|
||
BaseCurve.prototype.point = function point() {
|
||
throw new Error('Not implemented');
|
||
};
|
||
|
||
BaseCurve.prototype.validate = function validate() {
|
||
throw new Error('Not implemented');
|
||
};
|
||
|
||
BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
|
||
assert(p.precomputed);
|
||
var doubles = p._getDoubles();
|
||
|
||
var naf = getNAF(k, 1);
|
||
var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
|
||
I /= 3;
|
||
|
||
// Translate into more windowed form
|
||
var repr = [];
|
||
for (var j = 0; j < naf.length; j += doubles.step) {
|
||
var nafW = 0;
|
||
for (var k = j + doubles.step - 1; k >= j; k--)
|
||
nafW = (nafW << 1) + naf[k];
|
||
repr.push(nafW);
|
||
}
|
||
|
||
var a = this.jpoint(null, null, null);
|
||
var b = this.jpoint(null, null, null);
|
||
for (var i = I; i > 0; i--) {
|
||
for (var j = 0; j < repr.length; j++) {
|
||
var nafW = repr[j];
|
||
if (nafW === i)
|
||
b = b.mixedAdd(doubles.points[j]);
|
||
else if (nafW === -i)
|
||
b = b.mixedAdd(doubles.points[j].neg());
|
||
}
|
||
a = a.add(b);
|
||
}
|
||
return a.toP();
|
||
};
|
||
|
||
BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
|
||
var w = 4;
|
||
|
||
// Precompute window
|
||
var nafPoints = p._getNAFPoints(w);
|
||
w = nafPoints.wnd;
|
||
var wnd = nafPoints.points;
|
||
|
||
// Get NAF form
|
||
var naf = getNAF(k, w);
|
||
|
||
// Add `this`*(N+1) for every w-NAF index
|
||
var acc = this.jpoint(null, null, null);
|
||
for (var i = naf.length - 1; i >= 0; i--) {
|
||
// Count zeroes
|
||
for (var k = 0; i >= 0 && naf[i] === 0; i--)
|
||
k++;
|
||
if (i >= 0)
|
||
k++;
|
||
acc = acc.dblp(k);
|
||
|
||
if (i < 0)
|
||
break;
|
||
var z = naf[i];
|
||
assert(z !== 0);
|
||
if (p.type === 'affine') {
|
||
// J +- P
|
||
if (z > 0)
|
||
acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
|
||
else
|
||
acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
|
||
} else {
|
||
// J +- J
|
||
if (z > 0)
|
||
acc = acc.add(wnd[(z - 1) >> 1]);
|
||
else
|
||
acc = acc.add(wnd[(-z - 1) >> 1].neg());
|
||
}
|
||
}
|
||
return p.type === 'affine' ? acc.toP() : acc;
|
||
};
|
||
|
||
BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
|
||
points,
|
||
coeffs,
|
||
len,
|
||
jacobianResult) {
|
||
var wndWidth = this._wnafT1;
|
||
var wnd = this._wnafT2;
|
||
var naf = this._wnafT3;
|
||
|
||
// Fill all arrays
|
||
var max = 0;
|
||
for (var i = 0; i < len; i++) {
|
||
var p = points[i];
|
||
var nafPoints = p._getNAFPoints(defW);
|
||
wndWidth[i] = nafPoints.wnd;
|
||
wnd[i] = nafPoints.points;
|
||
}
|
||
|
||
// Comb small window NAFs
|
||
for (var i = len - 1; i >= 1; i -= 2) {
|
||
var a = i - 1;
|
||
var b = i;
|
||
if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
|
||
naf[a] = getNAF(coeffs[a], wndWidth[a]);
|
||
naf[b] = getNAF(coeffs[b], wndWidth[b]);
|
||
max = Math.max(naf[a].length, max);
|
||
max = Math.max(naf[b].length, max);
|
||
continue;
|
||
}
|
||
|
||
var comb = [
|
||
points[a], /* 1 */
|
||
null, /* 3 */
|
||
null, /* 5 */
|
||
points[b] /* 7 */
|
||
];
|
||
|
||
// Try to avoid Projective points, if possible
|
||
if (points[a].y.cmp(points[b].y) === 0) {
|
||
comb[1] = points[a].add(points[b]);
|
||
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
||
} else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
|
||
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
||
comb[2] = points[a].add(points[b].neg());
|
||
} else {
|
||
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
||
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
||
}
|
||
|
||
var index = [
|
||
-3, /* -1 -1 */
|
||
-1, /* -1 0 */
|
||
-5, /* -1 1 */
|
||
-7, /* 0 -1 */
|
||
0, /* 0 0 */
|
||
7, /* 0 1 */
|
||
5, /* 1 -1 */
|
||
1, /* 1 0 */
|
||
3 /* 1 1 */
|
||
];
|
||
|
||
var jsf = getJSF(coeffs[a], coeffs[b]);
|
||
max = Math.max(jsf[0].length, max);
|
||
naf[a] = new Array(max);
|
||
naf[b] = new Array(max);
|
||
for (var j = 0; j < max; j++) {
|
||
var ja = jsf[0][j] | 0;
|
||
var jb = jsf[1][j] | 0;
|
||
|
||
naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
|
||
naf[b][j] = 0;
|
||
wnd[a] = comb;
|
||
}
|
||
}
|
||
|
||
var acc = this.jpoint(null, null, null);
|
||
var tmp = this._wnafT4;
|
||
for (var i = max; i >= 0; i--) {
|
||
var k = 0;
|
||
|
||
while (i >= 0) {
|
||
var zero = true;
|
||
for (var j = 0; j < len; j++) {
|
||
tmp[j] = naf[j][i] | 0;
|
||
if (tmp[j] !== 0)
|
||
zero = false;
|
||
}
|
||
if (!zero)
|
||
break;
|
||
k++;
|
||
i--;
|
||
}
|
||
if (i >= 0)
|
||
k++;
|
||
acc = acc.dblp(k);
|
||
if (i < 0)
|
||
break;
|
||
|
||
for (var j = 0; j < len; j++) {
|
||
var z = tmp[j];
|
||
var p;
|
||
if (z === 0)
|
||
continue;
|
||
else if (z > 0)
|
||
p = wnd[j][(z - 1) >> 1];
|
||
else if (z < 0)
|
||
p = wnd[j][(-z - 1) >> 1].neg();
|
||
|
||
if (p.type === 'affine')
|
||
acc = acc.mixedAdd(p);
|
||
else
|
||
acc = acc.add(p);
|
||
}
|
||
}
|
||
// Zeroify references
|
||
for (var i = 0; i < len; i++)
|
||
wnd[i] = null;
|
||
|
||
if (jacobianResult)
|
||
return acc;
|
||
else
|
||
return acc.toP();
|
||
};
|
||
|
||
function BasePoint(curve, type) {
|
||
this.curve = curve;
|
||
this.type = type;
|
||
this.precomputed = null;
|
||
}
|
||
BaseCurve.BasePoint = BasePoint;
|
||
|
||
BasePoint.prototype.eq = function eq(/*other*/) {
|
||
throw new Error('Not implemented');
|
||
};
|
||
|
||
BasePoint.prototype.validate = function validate() {
|
||
return this.curve.validate(this);
|
||
};
|
||
|
||
BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
|
||
bytes = utils.toArray(bytes, enc);
|
||
|
||
var len = this.p.byteLength();
|
||
|
||
// uncompressed, hybrid-odd, hybrid-even
|
||
if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
|
||
bytes.length - 1 === 2 * len) {
|
||
if (bytes[0] === 0x06)
|
||
assert(bytes[bytes.length - 1] % 2 === 0);
|
||
else if (bytes[0] === 0x07)
|
||
assert(bytes[bytes.length - 1] % 2 === 1);
|
||
|
||
var res = this.point(bytes.slice(1, 1 + len),
|
||
bytes.slice(1 + len, 1 + 2 * len));
|
||
|
||
return res;
|
||
} else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
|
||
bytes.length - 1 === len) {
|
||
return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
|
||
}
|
||
throw new Error('Unknown point format');
|
||
};
|
||
|
||
BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
|
||
return this.encode(enc, true);
|
||
};
|
||
|
||
BasePoint.prototype._encode = function _encode(compact) {
|
||
var len = this.curve.p.byteLength();
|
||
var x = this.getX().toArray('be', len);
|
||
|
||
if (compact)
|
||
return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
|
||
|
||
return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
|
||
};
|
||
|
||
BasePoint.prototype.encode = function encode(enc, compact) {
|
||
return utils.encode(this._encode(compact), enc);
|
||
};
|
||
|
||
BasePoint.prototype.precompute = function precompute(power) {
|
||
if (this.precomputed)
|
||
return this;
|
||
|
||
var precomputed = {
|
||
doubles: null,
|
||
naf: null,
|
||
beta: null
|
||
};
|
||
precomputed.naf = this._getNAFPoints(8);
|
||
precomputed.doubles = this._getDoubles(4, power);
|
||
precomputed.beta = this._getBeta();
|
||
this.precomputed = precomputed;
|
||
|
||
return this;
|
||
};
|
||
|
||
BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
|
||
if (!this.precomputed)
|
||
return false;
|
||
|
||
var doubles = this.precomputed.doubles;
|
||
if (!doubles)
|
||
return false;
|
||
|
||
return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
|
||
};
|
||
|
||
BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
|
||
if (this.precomputed && this.precomputed.doubles)
|
||
return this.precomputed.doubles;
|
||
|
||
var doubles = [ this ];
|
||
var acc = this;
|
||
for (var i = 0; i < power; i += step) {
|
||
for (var j = 0; j < step; j++)
|
||
acc = acc.dbl();
|
||
doubles.push(acc);
|
||
}
|
||
return {
|
||
step: step,
|
||
points: doubles
|
||
};
|
||
};
|
||
|
||
BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
|
||
if (this.precomputed && this.precomputed.naf)
|
||
return this.precomputed.naf;
|
||
|
||
var res = [ this ];
|
||
var max = (1 << wnd) - 1;
|
||
var dbl = max === 1 ? null : this.dbl();
|
||
for (var i = 1; i < max; i++)
|
||
res[i] = res[i - 1].add(dbl);
|
||
return {
|
||
wnd: wnd,
|
||
points: res
|
||
};
|
||
};
|
||
|
||
BasePoint.prototype._getBeta = function _getBeta() {
|
||
return null;
|
||
};
|
||
|
||
BasePoint.prototype.dblp = function dblp(k) {
|
||
var r = this;
|
||
for (var i = 0; i < k; i++)
|
||
r = r.dbl();
|
||
return r;
|
||
};
|
||
|
||
},{"../../elliptic":5,"bn.js":2}],7:[function(require,module,exports){
|
||
module.exports = {};
|
||
},{}],8:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var curve = exports;
|
||
|
||
curve.base = require('./base');
|
||
curve.short = require('./short');
|
||
curve.mont = require('./mont');
|
||
curve.edwards = require('./edwards');
|
||
|
||
},{"./base":6,"./edwards":7,"./mont":9,"./short":10}],9:[function(require,module,exports){
|
||
arguments[4][7][0].apply(exports,arguments)
|
||
},{"dup":7}],10:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var curve = require('../curve');
|
||
var elliptic = require('../../elliptic');
|
||
var BN = require('bn.js');
|
||
var inherits = require('inherits');
|
||
var Base = curve.base;
|
||
|
||
var assert = elliptic.utils.assert;
|
||
|
||
function ShortCurve(conf) {
|
||
Base.call(this, 'short', conf);
|
||
|
||
this.a = new BN(conf.a, 16).toRed(this.red);
|
||
this.b = new BN(conf.b, 16).toRed(this.red);
|
||
this.tinv = this.two.redInvm();
|
||
|
||
this.zeroA = this.a.fromRed().cmpn(0) === 0;
|
||
this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
|
||
|
||
// If the curve is endomorphic, precalculate beta and lambda
|
||
this.endo = this._getEndomorphism(conf);
|
||
this._endoWnafT1 = new Array(4);
|
||
this._endoWnafT2 = new Array(4);
|
||
}
|
||
inherits(ShortCurve, Base);
|
||
module.exports = ShortCurve;
|
||
|
||
ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
|
||
// No efficient endomorphism
|
||
if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
|
||
return;
|
||
|
||
// Compute beta and lambda, that lambda * P = (beta * Px; Py)
|
||
var beta;
|
||
var lambda;
|
||
if (conf.beta) {
|
||
beta = new BN(conf.beta, 16).toRed(this.red);
|
||
} else {
|
||
var betas = this._getEndoRoots(this.p);
|
||
// Choose the smallest beta
|
||
beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
|
||
beta = beta.toRed(this.red);
|
||
}
|
||
if (conf.lambda) {
|
||
lambda = new BN(conf.lambda, 16);
|
||
} else {
|
||
// Choose the lambda that is matching selected beta
|
||
var lambdas = this._getEndoRoots(this.n);
|
||
if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
|
||
lambda = lambdas[0];
|
||
} else {
|
||
lambda = lambdas[1];
|
||
assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
|
||
}
|
||
}
|
||
|
||
// Get basis vectors, used for balanced length-two representation
|
||
var basis;
|
||
if (conf.basis) {
|
||
basis = conf.basis.map(function(vec) {
|
||
return {
|
||
a: new BN(vec.a, 16),
|
||
b: new BN(vec.b, 16)
|
||
};
|
||
});
|
||
} else {
|
||
basis = this._getEndoBasis(lambda);
|
||
}
|
||
|
||
return {
|
||
beta: beta,
|
||
lambda: lambda,
|
||
basis: basis
|
||
};
|
||
};
|
||
|
||
ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
|
||
// Find roots of for x^2 + x + 1 in F
|
||
// Root = (-1 +- Sqrt(-3)) / 2
|
||
//
|
||
var red = num === this.p ? this.red : BN.mont(num);
|
||
var tinv = new BN(2).toRed(red).redInvm();
|
||
var ntinv = tinv.redNeg();
|
||
|
||
var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
|
||
|
||
var l1 = ntinv.redAdd(s).fromRed();
|
||
var l2 = ntinv.redSub(s).fromRed();
|
||
return [ l1, l2 ];
|
||
};
|
||
|
||
ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
|
||
// aprxSqrt >= sqrt(this.n)
|
||
var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
|
||
|
||
// 3.74
|
||
// Run EGCD, until r(L + 1) < aprxSqrt
|
||
var u = lambda;
|
||
var v = this.n.clone();
|
||
var x1 = new BN(1);
|
||
var y1 = new BN(0);
|
||
var x2 = new BN(0);
|
||
var y2 = new BN(1);
|
||
|
||
// NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
|
||
var a0;
|
||
var b0;
|
||
// First vector
|
||
var a1;
|
||
var b1;
|
||
// Second vector
|
||
var a2;
|
||
var b2;
|
||
|
||
var prevR;
|
||
var i = 0;
|
||
var r;
|
||
var x;
|
||
while (u.cmpn(0) !== 0) {
|
||
var q = v.div(u);
|
||
r = v.sub(q.mul(u));
|
||
x = x2.sub(q.mul(x1));
|
||
var y = y2.sub(q.mul(y1));
|
||
|
||
if (!a1 && r.cmp(aprxSqrt) < 0) {
|
||
a0 = prevR.neg();
|
||
b0 = x1;
|
||
a1 = r.neg();
|
||
b1 = x;
|
||
} else if (a1 && ++i === 2) {
|
||
break;
|
||
}
|
||
prevR = r;
|
||
|
||
v = u;
|
||
u = r;
|
||
x2 = x1;
|
||
x1 = x;
|
||
y2 = y1;
|
||
y1 = y;
|
||
}
|
||
a2 = r.neg();
|
||
b2 = x;
|
||
|
||
var len1 = a1.sqr().add(b1.sqr());
|
||
var len2 = a2.sqr().add(b2.sqr());
|
||
if (len2.cmp(len1) >= 0) {
|
||
a2 = a0;
|
||
b2 = b0;
|
||
}
|
||
|
||
// Normalize signs
|
||
if (a1.negative) {
|
||
a1 = a1.neg();
|
||
b1 = b1.neg();
|
||
}
|
||
if (a2.negative) {
|
||
a2 = a2.neg();
|
||
b2 = b2.neg();
|
||
}
|
||
|
||
return [
|
||
{ a: a1, b: b1 },
|
||
{ a: a2, b: b2 }
|
||
];
|
||
};
|
||
|
||
ShortCurve.prototype._endoSplit = function _endoSplit(k) {
|
||
var basis = this.endo.basis;
|
||
var v1 = basis[0];
|
||
var v2 = basis[1];
|
||
|
||
var c1 = v2.b.mul(k).divRound(this.n);
|
||
var c2 = v1.b.neg().mul(k).divRound(this.n);
|
||
|
||
var p1 = c1.mul(v1.a);
|
||
var p2 = c2.mul(v2.a);
|
||
var q1 = c1.mul(v1.b);
|
||
var q2 = c2.mul(v2.b);
|
||
|
||
// Calculate answer
|
||
var k1 = k.sub(p1).sub(p2);
|
||
var k2 = q1.add(q2).neg();
|
||
return { k1: k1, k2: k2 };
|
||
};
|
||
|
||
ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
|
||
x = new BN(x, 16);
|
||
if (!x.red)
|
||
x = x.toRed(this.red);
|
||
|
||
var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
|
||
var y = y2.redSqrt();
|
||
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
|
||
throw new Error('invalid point');
|
||
|
||
// XXX Is there any way to tell if the number is odd without converting it
|
||
// to non-red form?
|
||
var isOdd = y.fromRed().isOdd();
|
||
if (odd && !isOdd || !odd && isOdd)
|
||
y = y.redNeg();
|
||
|
||
return this.point(x, y);
|
||
};
|
||
|
||
ShortCurve.prototype.validate = function validate(point) {
|
||
if (point.inf)
|
||
return true;
|
||
|
||
var x = point.x;
|
||
var y = point.y;
|
||
|
||
var ax = this.a.redMul(x);
|
||
var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
|
||
return y.redSqr().redISub(rhs).cmpn(0) === 0;
|
||
};
|
||
|
||
ShortCurve.prototype._endoWnafMulAdd =
|
||
function _endoWnafMulAdd(points, coeffs, jacobianResult) {
|
||
var npoints = this._endoWnafT1;
|
||
var ncoeffs = this._endoWnafT2;
|
||
for (var i = 0; i < points.length; i++) {
|
||
var split = this._endoSplit(coeffs[i]);
|
||
var p = points[i];
|
||
var beta = p._getBeta();
|
||
|
||
if (split.k1.negative) {
|
||
split.k1.ineg();
|
||
p = p.neg(true);
|
||
}
|
||
if (split.k2.negative) {
|
||
split.k2.ineg();
|
||
beta = beta.neg(true);
|
||
}
|
||
|
||
npoints[i * 2] = p;
|
||
npoints[i * 2 + 1] = beta;
|
||
ncoeffs[i * 2] = split.k1;
|
||
ncoeffs[i * 2 + 1] = split.k2;
|
||
}
|
||
var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
|
||
|
||
// Clean-up references to points and coefficients
|
||
for (var j = 0; j < i * 2; j++) {
|
||
npoints[j] = null;
|
||
ncoeffs[j] = null;
|
||
}
|
||
return res;
|
||
};
|
||
|
||
function Point(curve, x, y, isRed) {
|
||
Base.BasePoint.call(this, curve, 'affine');
|
||
if (x === null && y === null) {
|
||
this.x = null;
|
||
this.y = null;
|
||
this.inf = true;
|
||
} else {
|
||
this.x = new BN(x, 16);
|
||
this.y = new BN(y, 16);
|
||
// Force redgomery representation when loading from JSON
|
||
if (isRed) {
|
||
this.x.forceRed(this.curve.red);
|
||
this.y.forceRed(this.curve.red);
|
||
}
|
||
if (!this.x.red)
|
||
this.x = this.x.toRed(this.curve.red);
|
||
if (!this.y.red)
|
||
this.y = this.y.toRed(this.curve.red);
|
||
this.inf = false;
|
||
}
|
||
}
|
||
inherits(Point, Base.BasePoint);
|
||
|
||
ShortCurve.prototype.point = function point(x, y, isRed) {
|
||
return new Point(this, x, y, isRed);
|
||
};
|
||
|
||
ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
|
||
return Point.fromJSON(this, obj, red);
|
||
};
|
||
|
||
Point.prototype._getBeta = function _getBeta() {
|
||
if (!this.curve.endo)
|
||
return;
|
||
|
||
var pre = this.precomputed;
|
||
if (pre && pre.beta)
|
||
return pre.beta;
|
||
|
||
var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
|
||
if (pre) {
|
||
var curve = this.curve;
|
||
var endoMul = function(p) {
|
||
return curve.point(p.x.redMul(curve.endo.beta), p.y);
|
||
};
|
||
pre.beta = beta;
|
||
beta.precomputed = {
|
||
beta: null,
|
||
naf: pre.naf && {
|
||
wnd: pre.naf.wnd,
|
||
points: pre.naf.points.map(endoMul)
|
||
},
|
||
doubles: pre.doubles && {
|
||
step: pre.doubles.step,
|
||
points: pre.doubles.points.map(endoMul)
|
||
}
|
||
};
|
||
}
|
||
return beta;
|
||
};
|
||
|
||
Point.prototype.toJSON = function toJSON() {
|
||
if (!this.precomputed)
|
||
return [ this.x, this.y ];
|
||
|
||
return [ this.x, this.y, this.precomputed && {
|
||
doubles: this.precomputed.doubles && {
|
||
step: this.precomputed.doubles.step,
|
||
points: this.precomputed.doubles.points.slice(1)
|
||
},
|
||
naf: this.precomputed.naf && {
|
||
wnd: this.precomputed.naf.wnd,
|
||
points: this.precomputed.naf.points.slice(1)
|
||
}
|
||
} ];
|
||
};
|
||
|
||
Point.fromJSON = function fromJSON(curve, obj, red) {
|
||
if (typeof obj === 'string')
|
||
obj = JSON.parse(obj);
|
||
var res = curve.point(obj[0], obj[1], red);
|
||
if (!obj[2])
|
||
return res;
|
||
|
||
function obj2point(obj) {
|
||
return curve.point(obj[0], obj[1], red);
|
||
}
|
||
|
||
var pre = obj[2];
|
||
res.precomputed = {
|
||
beta: null,
|
||
doubles: pre.doubles && {
|
||
step: pre.doubles.step,
|
||
points: [ res ].concat(pre.doubles.points.map(obj2point))
|
||
},
|
||
naf: pre.naf && {
|
||
wnd: pre.naf.wnd,
|
||
points: [ res ].concat(pre.naf.points.map(obj2point))
|
||
}
|
||
};
|
||
return res;
|
||
};
|
||
|
||
Point.prototype.inspect = function inspect() {
|
||
if (this.isInfinity())
|
||
return '<EC Point Infinity>';
|
||
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
||
' y: ' + this.y.fromRed().toString(16, 2) + '>';
|
||
};
|
||
|
||
Point.prototype.isInfinity = function isInfinity() {
|
||
return this.inf;
|
||
};
|
||
|
||
Point.prototype.add = function add(p) {
|
||
// O + P = P
|
||
if (this.inf)
|
||
return p;
|
||
|
||
// P + O = P
|
||
if (p.inf)
|
||
return this;
|
||
|
||
// P + P = 2P
|
||
if (this.eq(p))
|
||
return this.dbl();
|
||
|
||
// P + (-P) = O
|
||
if (this.neg().eq(p))
|
||
return this.curve.point(null, null);
|
||
|
||
// P + Q = O
|
||
if (this.x.cmp(p.x) === 0)
|
||
return this.curve.point(null, null);
|
||
|
||
var c = this.y.redSub(p.y);
|
||
if (c.cmpn(0) !== 0)
|
||
c = c.redMul(this.x.redSub(p.x).redInvm());
|
||
var nx = c.redSqr().redISub(this.x).redISub(p.x);
|
||
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
||
return this.curve.point(nx, ny);
|
||
};
|
||
|
||
Point.prototype.dbl = function dbl() {
|
||
if (this.inf)
|
||
return this;
|
||
|
||
// 2P = O
|
||
var ys1 = this.y.redAdd(this.y);
|
||
if (ys1.cmpn(0) === 0)
|
||
return this.curve.point(null, null);
|
||
|
||
var a = this.curve.a;
|
||
|
||
var x2 = this.x.redSqr();
|
||
var dyinv = ys1.redInvm();
|
||
var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
|
||
|
||
var nx = c.redSqr().redISub(this.x.redAdd(this.x));
|
||
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
||
return this.curve.point(nx, ny);
|
||
};
|
||
|
||
Point.prototype.getX = function getX() {
|
||
return this.x.fromRed();
|
||
};
|
||
|
||
Point.prototype.getY = function getY() {
|
||
return this.y.fromRed();
|
||
};
|
||
|
||
Point.prototype.mul = function mul(k) {
|
||
k = new BN(k, 16);
|
||
|
||
if (this._hasDoubles(k))
|
||
return this.curve._fixedNafMul(this, k);
|
||
else if (this.curve.endo)
|
||
return this.curve._endoWnafMulAdd([ this ], [ k ]);
|
||
else
|
||
return this.curve._wnafMul(this, k);
|
||
};
|
||
|
||
Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
|
||
var points = [ this, p2 ];
|
||
var coeffs = [ k1, k2 ];
|
||
if (this.curve.endo)
|
||
return this.curve._endoWnafMulAdd(points, coeffs);
|
||
else
|
||
return this.curve._wnafMulAdd(1, points, coeffs, 2);
|
||
};
|
||
|
||
Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
|
||
var points = [ this, p2 ];
|
||
var coeffs = [ k1, k2 ];
|
||
if (this.curve.endo)
|
||
return this.curve._endoWnafMulAdd(points, coeffs, true);
|
||
else
|
||
return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
|
||
};
|
||
|
||
Point.prototype.eq = function eq(p) {
|
||
return this === p ||
|
||
this.inf === p.inf &&
|
||
(this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
|
||
};
|
||
|
||
Point.prototype.neg = function neg(_precompute) {
|
||
if (this.inf)
|
||
return this;
|
||
|
||
var res = this.curve.point(this.x, this.y.redNeg());
|
||
if (_precompute && this.precomputed) {
|
||
var pre = this.precomputed;
|
||
var negate = function(p) {
|
||
return p.neg();
|
||
};
|
||
res.precomputed = {
|
||
naf: pre.naf && {
|
||
wnd: pre.naf.wnd,
|
||
points: pre.naf.points.map(negate)
|
||
},
|
||
doubles: pre.doubles && {
|
||
step: pre.doubles.step,
|
||
points: pre.doubles.points.map(negate)
|
||
}
|
||
};
|
||
}
|
||
return res;
|
||
};
|
||
|
||
Point.prototype.toJ = function toJ() {
|
||
if (this.inf)
|
||
return this.curve.jpoint(null, null, null);
|
||
|
||
var res = this.curve.jpoint(this.x, this.y, this.curve.one);
|
||
return res;
|
||
};
|
||
|
||
function JPoint(curve, x, y, z) {
|
||
Base.BasePoint.call(this, curve, 'jacobian');
|
||
if (x === null && y === null && z === null) {
|
||
this.x = this.curve.one;
|
||
this.y = this.curve.one;
|
||
this.z = new BN(0);
|
||
} else {
|
||
this.x = new BN(x, 16);
|
||
this.y = new BN(y, 16);
|
||
this.z = new BN(z, 16);
|
||
}
|
||
if (!this.x.red)
|
||
this.x = this.x.toRed(this.curve.red);
|
||
if (!this.y.red)
|
||
this.y = this.y.toRed(this.curve.red);
|
||
if (!this.z.red)
|
||
this.z = this.z.toRed(this.curve.red);
|
||
|
||
this.zOne = this.z === this.curve.one;
|
||
}
|
||
inherits(JPoint, Base.BasePoint);
|
||
|
||
ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
|
||
return new JPoint(this, x, y, z);
|
||
};
|
||
|
||
JPoint.prototype.toP = function toP() {
|
||
if (this.isInfinity())
|
||
return this.curve.point(null, null);
|
||
|
||
var zinv = this.z.redInvm();
|
||
var zinv2 = zinv.redSqr();
|
||
var ax = this.x.redMul(zinv2);
|
||
var ay = this.y.redMul(zinv2).redMul(zinv);
|
||
|
||
return this.curve.point(ax, ay);
|
||
};
|
||
|
||
JPoint.prototype.neg = function neg() {
|
||
return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
|
||
};
|
||
|
||
JPoint.prototype.add = function add(p) {
|
||
// O + P = P
|
||
if (this.isInfinity())
|
||
return p;
|
||
|
||
// P + O = P
|
||
if (p.isInfinity())
|
||
return this;
|
||
|
||
// 12M + 4S + 7A
|
||
var pz2 = p.z.redSqr();
|
||
var z2 = this.z.redSqr();
|
||
var u1 = this.x.redMul(pz2);
|
||
var u2 = p.x.redMul(z2);
|
||
var s1 = this.y.redMul(pz2.redMul(p.z));
|
||
var s2 = p.y.redMul(z2.redMul(this.z));
|
||
|
||
var h = u1.redSub(u2);
|
||
var r = s1.redSub(s2);
|
||
if (h.cmpn(0) === 0) {
|
||
if (r.cmpn(0) !== 0)
|
||
return this.curve.jpoint(null, null, null);
|
||
else
|
||
return this.dbl();
|
||
}
|
||
|
||
var h2 = h.redSqr();
|
||
var h3 = h2.redMul(h);
|
||
var v = u1.redMul(h2);
|
||
|
||
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
||
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
||
var nz = this.z.redMul(p.z).redMul(h);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.mixedAdd = function mixedAdd(p) {
|
||
// O + P = P
|
||
if (this.isInfinity())
|
||
return p.toJ();
|
||
|
||
// P + O = P
|
||
if (p.isInfinity())
|
||
return this;
|
||
|
||
// 8M + 3S + 7A
|
||
var z2 = this.z.redSqr();
|
||
var u1 = this.x;
|
||
var u2 = p.x.redMul(z2);
|
||
var s1 = this.y;
|
||
var s2 = p.y.redMul(z2).redMul(this.z);
|
||
|
||
var h = u1.redSub(u2);
|
||
var r = s1.redSub(s2);
|
||
if (h.cmpn(0) === 0) {
|
||
if (r.cmpn(0) !== 0)
|
||
return this.curve.jpoint(null, null, null);
|
||
else
|
||
return this.dbl();
|
||
}
|
||
|
||
var h2 = h.redSqr();
|
||
var h3 = h2.redMul(h);
|
||
var v = u1.redMul(h2);
|
||
|
||
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
||
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
||
var nz = this.z.redMul(h);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.dblp = function dblp(pow) {
|
||
if (pow === 0)
|
||
return this;
|
||
if (this.isInfinity())
|
||
return this;
|
||
if (!pow)
|
||
return this.dbl();
|
||
|
||
if (this.curve.zeroA || this.curve.threeA) {
|
||
var r = this;
|
||
for (var i = 0; i < pow; i++)
|
||
r = r.dbl();
|
||
return r;
|
||
}
|
||
|
||
// 1M + 2S + 1A + N * (4S + 5M + 8A)
|
||
// N = 1 => 6M + 6S + 9A
|
||
var a = this.curve.a;
|
||
var tinv = this.curve.tinv;
|
||
|
||
var jx = this.x;
|
||
var jy = this.y;
|
||
var jz = this.z;
|
||
var jz4 = jz.redSqr().redSqr();
|
||
|
||
// Reuse results
|
||
var jyd = jy.redAdd(jy);
|
||
for (var i = 0; i < pow; i++) {
|
||
var jx2 = jx.redSqr();
|
||
var jyd2 = jyd.redSqr();
|
||
var jyd4 = jyd2.redSqr();
|
||
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
||
|
||
var t1 = jx.redMul(jyd2);
|
||
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
||
var t2 = t1.redISub(nx);
|
||
var dny = c.redMul(t2);
|
||
dny = dny.redIAdd(dny).redISub(jyd4);
|
||
var nz = jyd.redMul(jz);
|
||
if (i + 1 < pow)
|
||
jz4 = jz4.redMul(jyd4);
|
||
|
||
jx = nx;
|
||
jz = nz;
|
||
jyd = dny;
|
||
}
|
||
|
||
return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
|
||
};
|
||
|
||
JPoint.prototype.dbl = function dbl() {
|
||
if (this.isInfinity())
|
||
return this;
|
||
|
||
if (this.curve.zeroA)
|
||
return this._zeroDbl();
|
||
else if (this.curve.threeA)
|
||
return this._threeDbl();
|
||
else
|
||
return this._dbl();
|
||
};
|
||
|
||
JPoint.prototype._zeroDbl = function _zeroDbl() {
|
||
var nx;
|
||
var ny;
|
||
var nz;
|
||
// Z = 1
|
||
if (this.zOne) {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||
// #doubling-mdbl-2007-bl
|
||
// 1M + 5S + 14A
|
||
|
||
// XX = X1^2
|
||
var xx = this.x.redSqr();
|
||
// YY = Y1^2
|
||
var yy = this.y.redSqr();
|
||
// YYYY = YY^2
|
||
var yyyy = yy.redSqr();
|
||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||
s = s.redIAdd(s);
|
||
// M = 3 * XX + a; a = 0
|
||
var m = xx.redAdd(xx).redIAdd(xx);
|
||
// T = M ^ 2 - 2*S
|
||
var t = m.redSqr().redISub(s).redISub(s);
|
||
|
||
// 8 * YYYY
|
||
var yyyy8 = yyyy.redIAdd(yyyy);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
|
||
// X3 = T
|
||
nx = t;
|
||
// Y3 = M * (S - T) - 8 * YYYY
|
||
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
||
// Z3 = 2*Y1
|
||
nz = this.y.redAdd(this.y);
|
||
} else {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||
// #doubling-dbl-2009-l
|
||
// 2M + 5S + 13A
|
||
|
||
// A = X1^2
|
||
var a = this.x.redSqr();
|
||
// B = Y1^2
|
||
var b = this.y.redSqr();
|
||
// C = B^2
|
||
var c = b.redSqr();
|
||
// D = 2 * ((X1 + B)^2 - A - C)
|
||
var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
|
||
d = d.redIAdd(d);
|
||
// E = 3 * A
|
||
var e = a.redAdd(a).redIAdd(a);
|
||
// F = E^2
|
||
var f = e.redSqr();
|
||
|
||
// 8 * C
|
||
var c8 = c.redIAdd(c);
|
||
c8 = c8.redIAdd(c8);
|
||
c8 = c8.redIAdd(c8);
|
||
|
||
// X3 = F - 2 * D
|
||
nx = f.redISub(d).redISub(d);
|
||
// Y3 = E * (D - X3) - 8 * C
|
||
ny = e.redMul(d.redISub(nx)).redISub(c8);
|
||
// Z3 = 2 * Y1 * Z1
|
||
nz = this.y.redMul(this.z);
|
||
nz = nz.redIAdd(nz);
|
||
}
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype._threeDbl = function _threeDbl() {
|
||
var nx;
|
||
var ny;
|
||
var nz;
|
||
// Z = 1
|
||
if (this.zOne) {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
|
||
// #doubling-mdbl-2007-bl
|
||
// 1M + 5S + 15A
|
||
|
||
// XX = X1^2
|
||
var xx = this.x.redSqr();
|
||
// YY = Y1^2
|
||
var yy = this.y.redSqr();
|
||
// YYYY = YY^2
|
||
var yyyy = yy.redSqr();
|
||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||
s = s.redIAdd(s);
|
||
// M = 3 * XX + a
|
||
var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
|
||
// T = M^2 - 2 * S
|
||
var t = m.redSqr().redISub(s).redISub(s);
|
||
// X3 = T
|
||
nx = t;
|
||
// Y3 = M * (S - T) - 8 * YYYY
|
||
var yyyy8 = yyyy.redIAdd(yyyy);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
||
// Z3 = 2 * Y1
|
||
nz = this.y.redAdd(this.y);
|
||
} else {
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
|
||
// 3M + 5S
|
||
|
||
// delta = Z1^2
|
||
var delta = this.z.redSqr();
|
||
// gamma = Y1^2
|
||
var gamma = this.y.redSqr();
|
||
// beta = X1 * gamma
|
||
var beta = this.x.redMul(gamma);
|
||
// alpha = 3 * (X1 - delta) * (X1 + delta)
|
||
var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
|
||
alpha = alpha.redAdd(alpha).redIAdd(alpha);
|
||
// X3 = alpha^2 - 8 * beta
|
||
var beta4 = beta.redIAdd(beta);
|
||
beta4 = beta4.redIAdd(beta4);
|
||
var beta8 = beta4.redAdd(beta4);
|
||
nx = alpha.redSqr().redISub(beta8);
|
||
// Z3 = (Y1 + Z1)^2 - gamma - delta
|
||
nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
|
||
// Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
|
||
var ggamma8 = gamma.redSqr();
|
||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||
ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
|
||
}
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype._dbl = function _dbl() {
|
||
var a = this.curve.a;
|
||
|
||
// 4M + 6S + 10A
|
||
var jx = this.x;
|
||
var jy = this.y;
|
||
var jz = this.z;
|
||
var jz4 = jz.redSqr().redSqr();
|
||
|
||
var jx2 = jx.redSqr();
|
||
var jy2 = jy.redSqr();
|
||
|
||
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
||
|
||
var jxd4 = jx.redAdd(jx);
|
||
jxd4 = jxd4.redIAdd(jxd4);
|
||
var t1 = jxd4.redMul(jy2);
|
||
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
||
var t2 = t1.redISub(nx);
|
||
|
||
var jyd8 = jy2.redSqr();
|
||
jyd8 = jyd8.redIAdd(jyd8);
|
||
jyd8 = jyd8.redIAdd(jyd8);
|
||
jyd8 = jyd8.redIAdd(jyd8);
|
||
var ny = c.redMul(t2).redISub(jyd8);
|
||
var nz = jy.redAdd(jy).redMul(jz);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.trpl = function trpl() {
|
||
if (!this.curve.zeroA)
|
||
return this.dbl().add(this);
|
||
|
||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
|
||
// 5M + 10S + ...
|
||
|
||
// XX = X1^2
|
||
var xx = this.x.redSqr();
|
||
// YY = Y1^2
|
||
var yy = this.y.redSqr();
|
||
// ZZ = Z1^2
|
||
var zz = this.z.redSqr();
|
||
// YYYY = YY^2
|
||
var yyyy = yy.redSqr();
|
||
// M = 3 * XX + a * ZZ2; a = 0
|
||
var m = xx.redAdd(xx).redIAdd(xx);
|
||
// MM = M^2
|
||
var mm = m.redSqr();
|
||
// E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
|
||
var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||
e = e.redIAdd(e);
|
||
e = e.redAdd(e).redIAdd(e);
|
||
e = e.redISub(mm);
|
||
// EE = E^2
|
||
var ee = e.redSqr();
|
||
// T = 16*YYYY
|
||
var t = yyyy.redIAdd(yyyy);
|
||
t = t.redIAdd(t);
|
||
t = t.redIAdd(t);
|
||
t = t.redIAdd(t);
|
||
// U = (M + E)^2 - MM - EE - T
|
||
var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
|
||
// X3 = 4 * (X1 * EE - 4 * YY * U)
|
||
var yyu4 = yy.redMul(u);
|
||
yyu4 = yyu4.redIAdd(yyu4);
|
||
yyu4 = yyu4.redIAdd(yyu4);
|
||
var nx = this.x.redMul(ee).redISub(yyu4);
|
||
nx = nx.redIAdd(nx);
|
||
nx = nx.redIAdd(nx);
|
||
// Y3 = 8 * Y1 * (U * (T - U) - E * EE)
|
||
var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
|
||
ny = ny.redIAdd(ny);
|
||
ny = ny.redIAdd(ny);
|
||
ny = ny.redIAdd(ny);
|
||
// Z3 = (Z1 + E)^2 - ZZ - EE
|
||
var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
|
||
|
||
return this.curve.jpoint(nx, ny, nz);
|
||
};
|
||
|
||
JPoint.prototype.mul = function mul(k, kbase) {
|
||
k = new BN(k, kbase);
|
||
|
||
return this.curve._wnafMul(this, k);
|
||
};
|
||
|
||
JPoint.prototype.eq = function eq(p) {
|
||
if (p.type === 'affine')
|
||
return this.eq(p.toJ());
|
||
|
||
if (this === p)
|
||
return true;
|
||
|
||
// x1 * z2^2 == x2 * z1^2
|
||
var z2 = this.z.redSqr();
|
||
var pz2 = p.z.redSqr();
|
||
if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
|
||
return false;
|
||
|
||
// y1 * z2^3 == y2 * z1^3
|
||
var z3 = z2.redMul(this.z);
|
||
var pz3 = pz2.redMul(p.z);
|
||
return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
|
||
};
|
||
|
||
JPoint.prototype.eqXToP = function eqXToP(x) {
|
||
var zs = this.z.redSqr();
|
||
var rx = x.toRed(this.curve.red).redMul(zs);
|
||
if (this.x.cmp(rx) === 0)
|
||
return true;
|
||
|
||
var xc = x.clone();
|
||
var t = this.curve.redN.redMul(zs);
|
||
for (;;) {
|
||
xc.iadd(this.curve.n);
|
||
if (xc.cmp(this.curve.p) >= 0)
|
||
return false;
|
||
|
||
rx.redIAdd(t);
|
||
if (this.x.cmp(rx) === 0)
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
JPoint.prototype.inspect = function inspect() {
|
||
if (this.isInfinity())
|
||
return '<EC JPoint Infinity>';
|
||
return '<EC JPoint x: ' + this.x.toString(16, 2) +
|
||
' y: ' + this.y.toString(16, 2) +
|
||
' z: ' + this.z.toString(16, 2) + '>';
|
||
};
|
||
|
||
JPoint.prototype.isInfinity = function isInfinity() {
|
||
// XXX This code assumes that zero is always zero in red
|
||
return this.z.cmpn(0) === 0;
|
||
};
|
||
|
||
},{"../../elliptic":5,"../curve":8,"bn.js":2,"inherits":51}],11:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var curves = exports;
|
||
|
||
var hash = require('hash.js');
|
||
var elliptic = require('../elliptic');
|
||
|
||
var assert = elliptic.utils.assert;
|
||
|
||
function PresetCurve(options) {
|
||
if (options.type === 'short')
|
||
this.curve = new elliptic.curve.short(options);
|
||
else if (options.type === 'edwards')
|
||
this.curve = new elliptic.curve.edwards(options);
|
||
else
|
||
this.curve = new elliptic.curve.mont(options);
|
||
this.g = this.curve.g;
|
||
this.n = this.curve.n;
|
||
this.hash = options.hash;
|
||
|
||
assert(this.g.validate(), 'Invalid curve');
|
||
assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
|
||
}
|
||
curves.PresetCurve = PresetCurve;
|
||
|
||
function defineCurve(name, options) {
|
||
Object.defineProperty(curves, name, {
|
||
configurable: true,
|
||
enumerable: true,
|
||
get: function() {
|
||
var curve = new PresetCurve(options);
|
||
Object.defineProperty(curves, name, {
|
||
configurable: true,
|
||
enumerable: true,
|
||
value: curve
|
||
});
|
||
return curve;
|
||
}
|
||
});
|
||
}
|
||
|
||
defineCurve('p192', {
|
||
type: 'short',
|
||
prime: 'p192',
|
||
p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
|
||
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
|
||
b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
|
||
n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
|
||
'07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
|
||
]
|
||
});
|
||
|
||
defineCurve('p224', {
|
||
type: 'short',
|
||
prime: 'p224',
|
||
p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
|
||
a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
|
||
b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
|
||
n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
|
||
'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
|
||
]
|
||
});
|
||
|
||
defineCurve('p256', {
|
||
type: 'short',
|
||
prime: null,
|
||
p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
|
||
a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
|
||
b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
|
||
n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
|
||
'4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
|
||
]
|
||
});
|
||
|
||
defineCurve('p384', {
|
||
type: 'short',
|
||
prime: null,
|
||
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'fffffffe ffffffff 00000000 00000000 ffffffff',
|
||
a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'fffffffe ffffffff 00000000 00000000 fffffffc',
|
||
b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
|
||
'5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
|
||
n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
|
||
'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
|
||
hash: hash.sha384,
|
||
gRed: false,
|
||
g: [
|
||
'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
|
||
'5502f25d bf55296c 3a545e38 72760ab7',
|
||
'3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
|
||
'0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
|
||
]
|
||
});
|
||
|
||
defineCurve('p521', {
|
||
type: 'short',
|
||
prime: null,
|
||
p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff',
|
||
a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff ffffffff ffffffff fffffffc',
|
||
b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
|
||
'99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
|
||
'3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
|
||
n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
|
||
'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
|
||
'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
|
||
hash: hash.sha512,
|
||
gRed: false,
|
||
g: [
|
||
'000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
|
||
'053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
|
||
'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
|
||
'00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
|
||
'579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
|
||
'3fad0761 353c7086 a272c240 88be9476 9fd16650'
|
||
]
|
||
});
|
||
|
||
defineCurve('curve25519', {
|
||
type: 'mont',
|
||
prime: 'p25519',
|
||
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
|
||
a: '76d06',
|
||
b: '1',
|
||
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'9'
|
||
]
|
||
});
|
||
|
||
defineCurve('ed25519', {
|
||
type: 'edwards',
|
||
prime: 'p25519',
|
||
p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
|
||
a: '-1',
|
||
c: '1',
|
||
// -121665 * (121666^(-1)) (mod P)
|
||
d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
|
||
n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
|
||
hash: hash.sha256,
|
||
gRed: false,
|
||
g: [
|
||
'216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
|
||
|
||
// 4/5
|
||
'6666666666666666666666666666666666666666666666666666666666666658'
|
||
]
|
||
});
|
||
|
||
var pre;
|
||
try {
|
||
pre = require('./precomputed/secp256k1');
|
||
} catch (e) {
|
||
pre = undefined;
|
||
}
|
||
|
||
defineCurve('secp256k1', {
|
||
type: 'short',
|
||
prime: 'k256',
|
||
p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
|
||
a: '0',
|
||
b: '7',
|
||
n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
|
||
h: '1',
|
||
hash: hash.sha256,
|
||
|
||
// Precomputed endomorphism
|
||
beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
|
||
lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
|
||
basis: [
|
||
{
|
||
a: '3086d221a7d46bcde86c90e49284eb15',
|
||
b: '-e4437ed6010e88286f547fa90abfe4c3'
|
||
},
|
||
{
|
||
a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
|
||
b: '3086d221a7d46bcde86c90e49284eb15'
|
||
}
|
||
],
|
||
|
||
gRed: false,
|
||
g: [
|
||
'79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
|
||
'483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
|
||
pre
|
||
]
|
||
});
|
||
|
||
},{"../elliptic":5,"./precomputed/secp256k1":17,"hash.js":39}],12:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var BN = require('bn.js');
|
||
var elliptic = require('../../elliptic');
|
||
var utils = elliptic.utils;
|
||
var assert = utils.assert;
|
||
|
||
var KeyPair = require('./key');
|
||
var Signature = require('./signature');
|
||
|
||
function EC(options) {
|
||
if (!(this instanceof EC))
|
||
return new EC(options);
|
||
|
||
// Shortcut `elliptic.ec(curve-name)`
|
||
if (typeof options === 'string') {
|
||
assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options);
|
||
|
||
options = elliptic.curves[options];
|
||
}
|
||
|
||
// Shortcut for `elliptic.ec(elliptic.curves.curveName)`
|
||
if (options instanceof elliptic.curves.PresetCurve)
|
||
options = { curve: options };
|
||
|
||
this.curve = options.curve.curve;
|
||
this.n = this.curve.n;
|
||
this.nh = this.n.ushrn(1);
|
||
this.g = this.curve.g;
|
||
|
||
// Point on curve
|
||
this.g = options.curve.g;
|
||
this.g.precompute(options.curve.n.bitLength() + 1);
|
||
|
||
// Hash for function for DRBG
|
||
this.hash = options.hash || options.curve.hash;
|
||
}
|
||
module.exports = EC;
|
||
|
||
EC.prototype.keyPair = function keyPair(options) {
|
||
return new KeyPair(this, options);
|
||
};
|
||
|
||
EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
|
||
return KeyPair.fromPrivate(this, priv, enc);
|
||
};
|
||
|
||
EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
|
||
return KeyPair.fromPublic(this, pub, enc);
|
||
};
|
||
|
||
EC.prototype.genKeyPair = function genKeyPair(options) {
|
||
if (!options)
|
||
options = {};
|
||
|
||
// Instantiate Hmac_DRBG
|
||
var drbg = new elliptic.hmacDRBG({
|
||
hash: this.hash,
|
||
pers: options.pers,
|
||
entropy: options.entropy || elliptic.rand(this.hash.hmacStrength),
|
||
nonce: this.n.toArray()
|
||
});
|
||
|
||
var bytes = this.n.byteLength();
|
||
var ns2 = this.n.sub(new BN(2));
|
||
do {
|
||
var priv = new BN(drbg.generate(bytes));
|
||
if (priv.cmp(ns2) > 0)
|
||
continue;
|
||
|
||
priv.iaddn(1);
|
||
return this.keyFromPrivate(priv);
|
||
} while (true);
|
||
};
|
||
|
||
EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
|
||
var delta = msg.byteLength() * 8 - this.n.bitLength();
|
||
if (delta > 0)
|
||
msg = msg.ushrn(delta);
|
||
if (!truncOnly && msg.cmp(this.n) >= 0)
|
||
return msg.sub(this.n);
|
||
else
|
||
return msg;
|
||
};
|
||
|
||
EC.prototype.sign = function sign(msg, key, enc, options) {
|
||
if (typeof enc === 'object') {
|
||
options = enc;
|
||
enc = null;
|
||
}
|
||
if (!options)
|
||
options = {};
|
||
|
||
key = this.keyFromPrivate(key, enc);
|
||
msg = this._truncateToN(new BN(msg, 16));
|
||
|
||
// Zero-extend key to provide enough entropy
|
||
var bytes = this.n.byteLength();
|
||
var bkey = key.getPrivate().toArray('be', bytes);
|
||
|
||
// Zero-extend nonce to have the same byte size as N
|
||
var nonce = msg.toArray('be', bytes);
|
||
|
||
// Instantiate Hmac_DRBG
|
||
var drbg = new elliptic.hmacDRBG({
|
||
hash: this.hash,
|
||
entropy: bkey,
|
||
nonce: nonce,
|
||
pers: options.pers,
|
||
persEnc: options.persEnc
|
||
});
|
||
|
||
// Number of bytes to generate
|
||
var ns1 = this.n.sub(new BN(1));
|
||
|
||
for (var iter = 0; true; iter++) {
|
||
var k = options.k ?
|
||
options.k(iter) :
|
||
new BN(drbg.generate(this.n.byteLength()));
|
||
k = this._truncateToN(k, true);
|
||
if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
|
||
continue;
|
||
|
||
var kp = this.g.mul(k);
|
||
if (kp.isInfinity())
|
||
continue;
|
||
|
||
var kpX = kp.getX();
|
||
var r = kpX.umod(this.n);
|
||
if (r.cmpn(0) === 0)
|
||
continue;
|
||
|
||
var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
|
||
s = s.umod(this.n);
|
||
if (s.cmpn(0) === 0)
|
||
continue;
|
||
|
||
var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
|
||
(kpX.cmp(r) !== 0 ? 2 : 0);
|
||
|
||
// Use complement of `s`, if it is > `n / 2`
|
||
if (options.canonical && s.cmp(this.nh) > 0) {
|
||
s = this.n.sub(s);
|
||
recoveryParam ^= 1;
|
||
}
|
||
|
||
return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
|
||
}
|
||
};
|
||
|
||
EC.prototype.verify = function verify(msg, signature, key, enc) {
|
||
msg = this._truncateToN(new BN(msg, 16));
|
||
key = this.keyFromPublic(key, enc);
|
||
signature = new Signature(signature, 'hex');
|
||
|
||
// Perform primitive values validation
|
||
var r = signature.r;
|
||
var s = signature.s;
|
||
if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
|
||
return false;
|
||
if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
|
||
return false;
|
||
|
||
// Validate signature
|
||
var sinv = s.invm(this.n);
|
||
var u1 = sinv.mul(msg).umod(this.n);
|
||
var u2 = sinv.mul(r).umod(this.n);
|
||
|
||
if (!this.curve._maxwellTrick) {
|
||
var p = this.g.mulAdd(u1, key.getPublic(), u2);
|
||
if (p.isInfinity())
|
||
return false;
|
||
|
||
return p.getX().umod(this.n).cmp(r) === 0;
|
||
}
|
||
|
||
// NOTE: Greg Maxwell's trick, inspired by:
|
||
// https://git.io/vad3K
|
||
|
||
var p = this.g.jmulAdd(u1, key.getPublic(), u2);
|
||
if (p.isInfinity())
|
||
return false;
|
||
|
||
// Compare `p.x` of Jacobian point with `r`,
|
||
// this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
|
||
// inverse of `p.z^2`
|
||
return p.eqXToP(r);
|
||
};
|
||
|
||
EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
|
||
assert((3 & j) === j, 'The recovery param is more than two bits');
|
||
signature = new Signature(signature, enc);
|
||
|
||
var n = this.n;
|
||
var e = new BN(msg);
|
||
var r = signature.r;
|
||
var s = signature.s;
|
||
|
||
// A set LSB signifies that the y-coordinate is odd
|
||
var isYOdd = j & 1;
|
||
var isSecondKey = j >> 1;
|
||
if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
|
||
throw new Error('Unable to find sencond key candinate');
|
||
|
||
// 1.1. Let x = r + jn.
|
||
if (isSecondKey)
|
||
r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
|
||
else
|
||
r = this.curve.pointFromX(r, isYOdd);
|
||
|
||
var rInv = signature.r.invm(n);
|
||
var s1 = n.sub(e).mul(rInv).umod(n);
|
||
var s2 = s.mul(rInv).umod(n);
|
||
|
||
// 1.6.1 Compute Q = r^-1 (sR - eG)
|
||
// Q = r^-1 (sR + -eG)
|
||
return this.g.mulAdd(s1, r, s2);
|
||
};
|
||
|
||
EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
|
||
signature = new Signature(signature, enc);
|
||
if (signature.recoveryParam !== null)
|
||
return signature.recoveryParam;
|
||
|
||
for (var i = 0; i < 4; i++) {
|
||
var Qprime;
|
||
try {
|
||
Qprime = this.recoverPubKey(e, signature, i);
|
||
} catch (e) {
|
||
continue;
|
||
}
|
||
|
||
if (Qprime.eq(Q))
|
||
return i;
|
||
}
|
||
throw new Error('Unable to find valid recovery factor');
|
||
};
|
||
|
||
},{"../../elliptic":5,"./key":13,"./signature":14,"bn.js":2}],13:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var BN = require('bn.js');
|
||
var elliptic = require('../../elliptic');
|
||
var utils = elliptic.utils;
|
||
var assert = utils.assert;
|
||
|
||
function KeyPair(ec, options) {
|
||
this.ec = ec;
|
||
this.priv = null;
|
||
this.pub = null;
|
||
|
||
// KeyPair(ec, { priv: ..., pub: ... })
|
||
if (options.priv)
|
||
this._importPrivate(options.priv, options.privEnc);
|
||
if (options.pub)
|
||
this._importPublic(options.pub, options.pubEnc);
|
||
}
|
||
module.exports = KeyPair;
|
||
|
||
KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
|
||
if (pub instanceof KeyPair)
|
||
return pub;
|
||
|
||
return new KeyPair(ec, {
|
||
pub: pub,
|
||
pubEnc: enc
|
||
});
|
||
};
|
||
|
||
KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
|
||
if (priv instanceof KeyPair)
|
||
return priv;
|
||
|
||
return new KeyPair(ec, {
|
||
priv: priv,
|
||
privEnc: enc
|
||
});
|
||
};
|
||
|
||
KeyPair.prototype.validate = function validate() {
|
||
var pub = this.getPublic();
|
||
|
||
if (pub.isInfinity())
|
||
return { result: false, reason: 'Invalid public key' };
|
||
if (!pub.validate())
|
||
return { result: false, reason: 'Public key is not a point' };
|
||
if (!pub.mul(this.ec.curve.n).isInfinity())
|
||
return { result: false, reason: 'Public key * N != O' };
|
||
|
||
return { result: true, reason: null };
|
||
};
|
||
|
||
KeyPair.prototype.getPublic = function getPublic(compact, enc) {
|
||
// compact is optional argument
|
||
if (typeof compact === 'string') {
|
||
enc = compact;
|
||
compact = null;
|
||
}
|
||
|
||
if (!this.pub)
|
||
this.pub = this.ec.g.mul(this.priv);
|
||
|
||
if (!enc)
|
||
return this.pub;
|
||
|
||
return this.pub.encode(enc, compact);
|
||
};
|
||
|
||
KeyPair.prototype.getPrivate = function getPrivate(enc) {
|
||
if (enc === 'hex')
|
||
return this.priv.toString(16, 2);
|
||
else
|
||
return this.priv;
|
||
};
|
||
|
||
KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
|
||
this.priv = new BN(key, enc || 16);
|
||
|
||
// Ensure that the priv won't be bigger than n, otherwise we may fail
|
||
// in fixed multiplication method
|
||
this.priv = this.priv.umod(this.ec.curve.n);
|
||
};
|
||
|
||
KeyPair.prototype._importPublic = function _importPublic(key, enc) {
|
||
if (key.x || key.y) {
|
||
// Montgomery points only have an `x` coordinate.
|
||
// Weierstrass/Edwards points on the other hand have both `x` and
|
||
// `y` coordinates.
|
||
if (this.ec.curve.type === 'mont') {
|
||
assert(key.x, 'Need x coordinate');
|
||
} else if (this.ec.curve.type === 'short' ||
|
||
this.ec.curve.type === 'edwards') {
|
||
assert(key.x && key.y, 'Need both x and y coordinate');
|
||
}
|
||
this.pub = this.ec.curve.point(key.x, key.y);
|
||
return;
|
||
}
|
||
this.pub = this.ec.curve.decodePoint(key, enc);
|
||
};
|
||
|
||
// ECDH
|
||
KeyPair.prototype.derive = function derive(pub) {
|
||
return pub.mul(this.priv).getX();
|
||
};
|
||
|
||
// ECDSA
|
||
KeyPair.prototype.sign = function sign(msg, enc, options) {
|
||
return this.ec.sign(msg, this, enc, options);
|
||
};
|
||
|
||
KeyPair.prototype.verify = function verify(msg, signature) {
|
||
return this.ec.verify(msg, signature, this);
|
||
};
|
||
|
||
KeyPair.prototype.inspect = function inspect() {
|
||
return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
|
||
' pub: ' + (this.pub && this.pub.inspect()) + ' >';
|
||
};
|
||
|
||
},{"../../elliptic":5,"bn.js":2}],14:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var BN = require('bn.js');
|
||
|
||
var elliptic = require('../../elliptic');
|
||
var utils = elliptic.utils;
|
||
var assert = utils.assert;
|
||
|
||
function Signature(options, enc) {
|
||
if (options instanceof Signature)
|
||
return options;
|
||
|
||
if (this._importDER(options, enc))
|
||
return;
|
||
|
||
assert(options.r && options.s, 'Signature without r or s');
|
||
this.r = new BN(options.r, 16);
|
||
this.s = new BN(options.s, 16);
|
||
if (options.recoveryParam === undefined)
|
||
this.recoveryParam = null;
|
||
else
|
||
this.recoveryParam = options.recoveryParam;
|
||
}
|
||
module.exports = Signature;
|
||
|
||
function Position() {
|
||
this.place = 0;
|
||
}
|
||
|
||
function getLength(buf, p) {
|
||
var initial = buf[p.place++];
|
||
if (!(initial & 0x80)) {
|
||
return initial;
|
||
}
|
||
var octetLen = initial & 0xf;
|
||
var val = 0;
|
||
for (var i = 0, off = p.place; i < octetLen; i++, off++) {
|
||
val <<= 8;
|
||
val |= buf[off];
|
||
}
|
||
p.place = off;
|
||
return val;
|
||
}
|
||
|
||
function rmPadding(buf) {
|
||
var i = 0;
|
||
var len = buf.length - 1;
|
||
while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
|
||
i++;
|
||
}
|
||
if (i === 0) {
|
||
return buf;
|
||
}
|
||
return buf.slice(i);
|
||
}
|
||
|
||
Signature.prototype._importDER = function _importDER(data, enc) {
|
||
data = utils.toArray(data, enc);
|
||
var p = new Position();
|
||
if (data[p.place++] !== 0x30) {
|
||
return false;
|
||
}
|
||
var len = getLength(data, p);
|
||
if ((len + p.place) !== data.length) {
|
||
return false;
|
||
}
|
||
if (data[p.place++] !== 0x02) {
|
||
return false;
|
||
}
|
||
var rlen = getLength(data, p);
|
||
var r = data.slice(p.place, rlen + p.place);
|
||
p.place += rlen;
|
||
if (data[p.place++] !== 0x02) {
|
||
return false;
|
||
}
|
||
var slen = getLength(data, p);
|
||
if (data.length !== slen + p.place) {
|
||
return false;
|
||
}
|
||
var s = data.slice(p.place, slen + p.place);
|
||
if (r[0] === 0 && (r[1] & 0x80)) {
|
||
r = r.slice(1);
|
||
}
|
||
if (s[0] === 0 && (s[1] & 0x80)) {
|
||
s = s.slice(1);
|
||
}
|
||
|
||
this.r = new BN(r);
|
||
this.s = new BN(s);
|
||
this.recoveryParam = null;
|
||
|
||
return true;
|
||
};
|
||
|
||
function constructLength(arr, len) {
|
||
if (len < 0x80) {
|
||
arr.push(len);
|
||
return;
|
||
}
|
||
var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
|
||
arr.push(octets | 0x80);
|
||
while (--octets) {
|
||
arr.push((len >>> (octets << 3)) & 0xff);
|
||
}
|
||
arr.push(len);
|
||
}
|
||
|
||
Signature.prototype.toDER = function toDER(enc) {
|
||
var r = this.r.toArray();
|
||
var s = this.s.toArray();
|
||
|
||
// Pad values
|
||
if (r[0] & 0x80)
|
||
r = [ 0 ].concat(r);
|
||
// Pad values
|
||
if (s[0] & 0x80)
|
||
s = [ 0 ].concat(s);
|
||
|
||
r = rmPadding(r);
|
||
s = rmPadding(s);
|
||
|
||
while (!s[0] && !(s[1] & 0x80)) {
|
||
s = s.slice(1);
|
||
}
|
||
var arr = [ 0x02 ];
|
||
constructLength(arr, r.length);
|
||
arr = arr.concat(r);
|
||
arr.push(0x02);
|
||
constructLength(arr, s.length);
|
||
var backHalf = arr.concat(s);
|
||
var res = [ 0x30 ];
|
||
constructLength(res, backHalf.length);
|
||
res = res.concat(backHalf);
|
||
return utils.encode(res, enc);
|
||
};
|
||
|
||
},{"../../elliptic":5,"bn.js":2}],15:[function(require,module,exports){
|
||
arguments[4][7][0].apply(exports,arguments)
|
||
},{"dup":7}],16:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var hash = require('hash.js');
|
||
var elliptic = require('../elliptic');
|
||
var utils = elliptic.utils;
|
||
var assert = utils.assert;
|
||
|
||
function HmacDRBG(options) {
|
||
if (!(this instanceof HmacDRBG))
|
||
return new HmacDRBG(options);
|
||
this.hash = options.hash;
|
||
this.predResist = !!options.predResist;
|
||
|
||
this.outLen = this.hash.outSize;
|
||
this.minEntropy = options.minEntropy || this.hash.hmacStrength;
|
||
|
||
this.reseed = null;
|
||
this.reseedInterval = null;
|
||
this.K = null;
|
||
this.V = null;
|
||
|
||
var entropy = utils.toArray(options.entropy, options.entropyEnc);
|
||
var nonce = utils.toArray(options.nonce, options.nonceEnc);
|
||
var pers = utils.toArray(options.pers, options.persEnc);
|
||
assert(entropy.length >= (this.minEntropy / 8),
|
||
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
|
||
this._init(entropy, nonce, pers);
|
||
}
|
||
module.exports = HmacDRBG;
|
||
|
||
HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
|
||
var seed = entropy.concat(nonce).concat(pers);
|
||
|
||
this.K = new Array(this.outLen / 8);
|
||
this.V = new Array(this.outLen / 8);
|
||
for (var i = 0; i < this.V.length; i++) {
|
||
this.K[i] = 0x00;
|
||
this.V[i] = 0x01;
|
||
}
|
||
|
||
this._update(seed);
|
||
this.reseed = 1;
|
||
this.reseedInterval = 0x1000000000000; // 2^48
|
||
};
|
||
|
||
HmacDRBG.prototype._hmac = function hmac() {
|
||
return new hash.hmac(this.hash, this.K);
|
||
};
|
||
|
||
HmacDRBG.prototype._update = function update(seed) {
|
||
var kmac = this._hmac()
|
||
.update(this.V)
|
||
.update([ 0x00 ]);
|
||
if (seed)
|
||
kmac = kmac.update(seed);
|
||
this.K = kmac.digest();
|
||
this.V = this._hmac().update(this.V).digest();
|
||
if (!seed)
|
||
return;
|
||
|
||
this.K = this._hmac()
|
||
.update(this.V)
|
||
.update([ 0x01 ])
|
||
.update(seed)
|
||
.digest();
|
||
this.V = this._hmac().update(this.V).digest();
|
||
};
|
||
|
||
HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
|
||
// Optional entropy enc
|
||
if (typeof entropyEnc !== 'string') {
|
||
addEnc = add;
|
||
add = entropyEnc;
|
||
entropyEnc = null;
|
||
}
|
||
|
||
entropy = utils.toBuffer(entropy, entropyEnc);
|
||
add = utils.toBuffer(add, addEnc);
|
||
|
||
assert(entropy.length >= (this.minEntropy / 8),
|
||
'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
|
||
|
||
this._update(entropy.concat(add || []));
|
||
this.reseed = 1;
|
||
};
|
||
|
||
HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
|
||
if (this.reseed > this.reseedInterval)
|
||
throw new Error('Reseed is required');
|
||
|
||
// Optional encoding
|
||
if (typeof enc !== 'string') {
|
||
addEnc = add;
|
||
add = enc;
|
||
enc = null;
|
||
}
|
||
|
||
// Optional additional data
|
||
if (add) {
|
||
add = utils.toArray(add, addEnc);
|
||
this._update(add);
|
||
}
|
||
|
||
var temp = [];
|
||
while (temp.length < len) {
|
||
this.V = this._hmac().update(this.V).digest();
|
||
temp = temp.concat(this.V);
|
||
}
|
||
|
||
var res = temp.slice(0, len);
|
||
this._update(add);
|
||
this.reseed++;
|
||
return utils.encode(res, enc);
|
||
};
|
||
|
||
},{"../elliptic":5,"hash.js":39}],17:[function(require,module,exports){
|
||
module.exports = undefined;
|
||
},{}],18:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = exports;
|
||
var BN = require('bn.js');
|
||
|
||
utils.assert = function assert(val, msg) {
|
||
if (!val)
|
||
throw new Error(msg || 'Assertion failed');
|
||
};
|
||
|
||
function toArray(msg, enc) {
|
||
if (Array.isArray(msg))
|
||
return msg.slice();
|
||
if (!msg)
|
||
return [];
|
||
var res = [];
|
||
if (typeof msg !== 'string') {
|
||
for (var i = 0; i < msg.length; i++)
|
||
res[i] = msg[i] | 0;
|
||
return res;
|
||
}
|
||
if (!enc) {
|
||
for (var i = 0; i < msg.length; i++) {
|
||
var c = msg.charCodeAt(i);
|
||
var hi = c >> 8;
|
||
var lo = c & 0xff;
|
||
if (hi)
|
||
res.push(hi, lo);
|
||
else
|
||
res.push(lo);
|
||
}
|
||
} else if (enc === 'hex') {
|
||
msg = msg.replace(/[^a-z0-9]+/ig, '');
|
||
if (msg.length % 2 !== 0)
|
||
msg = '0' + msg;
|
||
for (var i = 0; i < msg.length; i += 2)
|
||
res.push(parseInt(msg[i] + msg[i + 1], 16));
|
||
}
|
||
return res;
|
||
}
|
||
utils.toArray = toArray;
|
||
|
||
function zero2(word) {
|
||
if (word.length === 1)
|
||
return '0' + word;
|
||
else
|
||
return word;
|
||
}
|
||
utils.zero2 = zero2;
|
||
|
||
function toHex(msg) {
|
||
var res = '';
|
||
for (var i = 0; i < msg.length; i++)
|
||
res += zero2(msg[i].toString(16));
|
||
return res;
|
||
}
|
||
utils.toHex = toHex;
|
||
|
||
utils.encode = function encode(arr, enc) {
|
||
if (enc === 'hex')
|
||
return toHex(arr);
|
||
else
|
||
return arr;
|
||
};
|
||
|
||
// Represent num in a w-NAF form
|
||
function getNAF(num, w) {
|
||
var naf = [];
|
||
var ws = 1 << (w + 1);
|
||
var k = num.clone();
|
||
while (k.cmpn(1) >= 0) {
|
||
var z;
|
||
if (k.isOdd()) {
|
||
var mod = k.andln(ws - 1);
|
||
if (mod > (ws >> 1) - 1)
|
||
z = (ws >> 1) - mod;
|
||
else
|
||
z = mod;
|
||
k.isubn(z);
|
||
} else {
|
||
z = 0;
|
||
}
|
||
naf.push(z);
|
||
|
||
// Optimization, shift by word if possible
|
||
var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
|
||
for (var i = 1; i < shift; i++)
|
||
naf.push(0);
|
||
k.iushrn(shift);
|
||
}
|
||
|
||
return naf;
|
||
}
|
||
utils.getNAF = getNAF;
|
||
|
||
// Represent k1, k2 in a Joint Sparse Form
|
||
function getJSF(k1, k2) {
|
||
var jsf = [
|
||
[],
|
||
[]
|
||
];
|
||
|
||
k1 = k1.clone();
|
||
k2 = k2.clone();
|
||
var d1 = 0;
|
||
var d2 = 0;
|
||
while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
|
||
|
||
// First phase
|
||
var m14 = (k1.andln(3) + d1) & 3;
|
||
var m24 = (k2.andln(3) + d2) & 3;
|
||
if (m14 === 3)
|
||
m14 = -1;
|
||
if (m24 === 3)
|
||
m24 = -1;
|
||
var u1;
|
||
if ((m14 & 1) === 0) {
|
||
u1 = 0;
|
||
} else {
|
||
var m8 = (k1.andln(7) + d1) & 7;
|
||
if ((m8 === 3 || m8 === 5) && m24 === 2)
|
||
u1 = -m14;
|
||
else
|
||
u1 = m14;
|
||
}
|
||
jsf[0].push(u1);
|
||
|
||
var u2;
|
||
if ((m24 & 1) === 0) {
|
||
u2 = 0;
|
||
} else {
|
||
var m8 = (k2.andln(7) + d2) & 7;
|
||
if ((m8 === 3 || m8 === 5) && m14 === 2)
|
||
u2 = -m24;
|
||
else
|
||
u2 = m24;
|
||
}
|
||
jsf[1].push(u2);
|
||
|
||
// Second phase
|
||
if (2 * d1 === u1 + 1)
|
||
d1 = 1 - d1;
|
||
if (2 * d2 === u2 + 1)
|
||
d2 = 1 - d2;
|
||
k1.iushrn(1);
|
||
k2.iushrn(1);
|
||
}
|
||
|
||
return jsf;
|
||
}
|
||
utils.getJSF = getJSF;
|
||
|
||
function cachedProperty(obj, name, computer) {
|
||
var key = '_' + name;
|
||
obj.prototype[name] = function cachedProperty() {
|
||
return this[key] !== undefined ? this[key] :
|
||
this[key] = computer.call(this);
|
||
};
|
||
}
|
||
utils.cachedProperty = cachedProperty;
|
||
|
||
function parseBytes(bytes) {
|
||
return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
|
||
bytes;
|
||
}
|
||
utils.parseBytes = parseBytes;
|
||
|
||
function intFromLE(bytes) {
|
||
return new BN(bytes, 'hex', 'le');
|
||
}
|
||
utils.intFromLE = intFromLE;
|
||
|
||
|
||
},{"bn.js":2}],19:[function(require,module,exports){
|
||
module.exports={"version":"6.3.3"}
|
||
},{}],20:[function(require,module,exports){
|
||
|
||
var BN = require('bn.js');
|
||
|
||
var convert = require('./convert');
|
||
var throwError = require('./throw-error');
|
||
var keccak256 = require('./keccak256');
|
||
|
||
function getChecksumAddress(address) {
|
||
if (typeof(address) !== 'string' || !address.match(/^0x[0-9A-Fa-f]{40}$/)) {
|
||
throwError('invalid address', {input: address});
|
||
}
|
||
|
||
address = address.toLowerCase();
|
||
|
||
var hashed = address.substring(2).split('');
|
||
for (var i = 0; i < hashed.length; i++) {
|
||
hashed[i] = hashed[i].charCodeAt(0);
|
||
}
|
||
hashed = convert.arrayify(keccak256(hashed));
|
||
|
||
address = address.substring(2).split('');
|
||
for (var i = 0; i < 40; i += 2) {
|
||
if ((hashed[i >> 1] >> 4) >= 8) {
|
||
address[i] = address[i].toUpperCase();
|
||
}
|
||
if ((hashed[i >> 1] & 0x0f) >= 8) {
|
||
address[i + 1] = address[i + 1].toUpperCase();
|
||
}
|
||
}
|
||
|
||
return '0x' + address.join('');
|
||
}
|
||
|
||
// Shims for environments that are missing some required constants and functions
|
||
var MAX_SAFE_INTEGER = 0x1fffffffffffff;
|
||
|
||
function log10(x) {
|
||
if (Math.log10) { return Math.log10(x); }
|
||
return Math.log(x) / Math.LN10;
|
||
}
|
||
|
||
|
||
// See: https://en.wikipedia.org/wiki/International_Bank_Account_Number
|
||
var ibanChecksum = (function() {
|
||
|
||
// Create lookup table
|
||
var ibanLookup = {};
|
||
for (var i = 0; i < 10; i++) { ibanLookup[String(i)] = String(i); }
|
||
for (var i = 0; i < 26; i++) { ibanLookup[String.fromCharCode(65 + i)] = String(10 + i); }
|
||
|
||
// How many decimal digits can we process? (for 64-bit float, this is 15)
|
||
var safeDigits = Math.floor(log10(MAX_SAFE_INTEGER));
|
||
|
||
return function(address) {
|
||
address = address.toUpperCase();
|
||
address = address.substring(4) + address.substring(0, 2) + '00';
|
||
|
||
var expanded = address.split('');
|
||
for (var i = 0; i < expanded.length; i++) {
|
||
expanded[i] = ibanLookup[expanded[i]];
|
||
}
|
||
expanded = expanded.join('');
|
||
|
||
// Javascript can handle integers safely up to 15 (decimal) digits
|
||
while (expanded.length >= safeDigits){
|
||
var block = expanded.substring(0, safeDigits);
|
||
expanded = parseInt(block, 10) % 97 + expanded.substring(block.length);
|
||
}
|
||
|
||
var checksum = String(98 - (parseInt(expanded, 10) % 97));
|
||
while (checksum.length < 2) { checksum = '0' + checksum; }
|
||
|
||
return checksum;
|
||
};
|
||
})();
|
||
|
||
function getAddress(address, icapFormat) {
|
||
var result = null;
|
||
|
||
if (typeof(address) !== 'string') {
|
||
throwError('invalid address', {input: address});
|
||
}
|
||
|
||
if (address.match(/^(0x)?[0-9a-fA-F]{40}$/)) {
|
||
|
||
// Missing the 0x prefix
|
||
if (address.substring(0, 2) !== '0x') { address = '0x' + address; }
|
||
|
||
result = getChecksumAddress(address);
|
||
|
||
// It is a checksummed address with a bad checksum
|
||
if (address.match(/([A-F].*[a-f])|([a-f].*[A-F])/) && result !== address) {
|
||
throwError('invalid address checksum', { input: address, expected: result });
|
||
}
|
||
|
||
// Maybe ICAP? (we only support direct mode)
|
||
} else if (address.match(/^XE[0-9]{2}[0-9A-Za-z]{30,31}$/)) {
|
||
|
||
// It is an ICAP address with a bad checksum
|
||
if (address.substring(2, 4) !== ibanChecksum(address)) {
|
||
throwError('invalid address icap checksum', { input: address });
|
||
}
|
||
|
||
result = (new BN(address.substring(4), 36)).toString(16);
|
||
while (result.length < 40) { result = '0' + result; }
|
||
result = getChecksumAddress('0x' + result);
|
||
|
||
} else {
|
||
throwError('invalid address', { input: address });
|
||
}
|
||
|
||
if (icapFormat) {
|
||
var base36 = (new BN(result.substring(2), 16)).toString(36).toUpperCase();
|
||
while (base36.length < 30) { base36 = '0' + base36; }
|
||
return 'XE' + ibanChecksum('XE00' + base36) + base36;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
module.exports = {
|
||
getAddress: getAddress,
|
||
}
|
||
|
||
},{"./convert":24,"./keccak256":28,"./throw-error":36,"bn.js":2}],21:[function(require,module,exports){
|
||
/**
|
||
* BigNumber
|
||
*
|
||
* A wrapper around the BN.js object. In the future we can swap out
|
||
* the underlying BN.js library for something smaller.
|
||
*/
|
||
|
||
var BN = require('bn.js');
|
||
|
||
var defineProperty = require('./properties').defineProperty;
|
||
var convert = require('./convert');
|
||
var throwError = require('./throw-error');
|
||
|
||
function BigNumber(value) {
|
||
if (!(this instanceof BigNumber)) { throw new Error('missing new'); }
|
||
|
||
if (convert.isHexString(value)) {
|
||
if (value == '0x') { value = '0x0'; }
|
||
value = new BN(value.substring(2), 16);
|
||
} else if (typeof(value) === 'string' && value[0] === '-' && convert.isHexString(value.substring(1))) {
|
||
value = (new BN(value.substring(3), 16)).mul(BigNumber.constantNegativeOne._bn);
|
||
|
||
} else if (typeof(value) === 'string' && value.match(/^-?[0-9]*$/)) {
|
||
if (value == '') { value = '0'; }
|
||
value = new BN(value);
|
||
|
||
} else if (typeof(value) === 'number' && parseInt(value) == value) {
|
||
value = new BN(value);
|
||
|
||
} else if (BN.isBN(value)) {
|
||
//value = value
|
||
|
||
} else if (isBigNumber(value)) {
|
||
value = value._bn;
|
||
|
||
} else if (convert.isArrayish(value)) {
|
||
value = new BN(convert.hexlify(value).substring(2), 16);
|
||
|
||
} else {
|
||
throwError('invalid BigNumber value', { input: value });
|
||
}
|
||
|
||
defineProperty(this, '_bn', value);
|
||
}
|
||
|
||
defineProperty(BigNumber, 'constantNegativeOne', bigNumberify(-1));
|
||
defineProperty(BigNumber, 'constantZero', bigNumberify(0));
|
||
defineProperty(BigNumber, 'constantOne', bigNumberify(1));
|
||
defineProperty(BigNumber, 'constantTwo', bigNumberify(2));
|
||
defineProperty(BigNumber, 'constantWeiPerEther', bigNumberify(new BN('1000000000000000000')));
|
||
|
||
|
||
defineProperty(BigNumber.prototype, 'fromTwos', function(value) {
|
||
return new BigNumber(this._bn.fromTwos(value));
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'toTwos', function(value) {
|
||
return new BigNumber(this._bn.toTwos(value));
|
||
});
|
||
|
||
|
||
defineProperty(BigNumber.prototype, 'add', function(other) {
|
||
return new BigNumber(this._bn.add(bigNumberify(other)._bn));
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'sub', function(other) {
|
||
return new BigNumber(this._bn.sub(bigNumberify(other)._bn));
|
||
});
|
||
|
||
|
||
defineProperty(BigNumber.prototype, 'div', function(other) {
|
||
return new BigNumber(this._bn.div(bigNumberify(other)._bn));
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'mul', function(other) {
|
||
return new BigNumber(this._bn.mul(bigNumberify(other)._bn));
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'mod', function(other) {
|
||
return new BigNumber(this._bn.mod(bigNumberify(other)._bn));
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'pow', function(other) {
|
||
return new BigNumber(this._bn.pow(bigNumberify(other)._bn));
|
||
});
|
||
|
||
|
||
defineProperty(BigNumber.prototype, 'maskn', function(value) {
|
||
return new BigNumber(this._bn.maskn(value));
|
||
});
|
||
|
||
|
||
|
||
defineProperty(BigNumber.prototype, 'eq', function(other) {
|
||
return this._bn.eq(bigNumberify(other)._bn);
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'lt', function(other) {
|
||
return this._bn.lt(bigNumberify(other)._bn);
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'lte', function(other) {
|
||
return this._bn.lte(bigNumberify(other)._bn);
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'gt', function(other) {
|
||
return this._bn.gt(bigNumberify(other)._bn);
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'gte', function(other) {
|
||
return this._bn.gte(bigNumberify(other)._bn);
|
||
});
|
||
|
||
|
||
defineProperty(BigNumber.prototype, 'isZero', function() {
|
||
return this._bn.isZero();
|
||
});
|
||
|
||
|
||
defineProperty(BigNumber.prototype, 'toNumber', function(base) {
|
||
return this._bn.toNumber();
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'toString', function() {
|
||
//return this._bn.toString(base || 10);
|
||
return this._bn.toString(10);
|
||
});
|
||
|
||
defineProperty(BigNumber.prototype, 'toHexString', function() {
|
||
var hex = this._bn.toString(16);
|
||
if (hex.length % 2) { hex = '0' + hex; }
|
||
return '0x' + hex;
|
||
});
|
||
|
||
|
||
function isBigNumber(value) {
|
||
return (value._bn && value._bn.mod);
|
||
}
|
||
|
||
function bigNumberify(value) {
|
||
if (isBigNumber(value)) { return value; }
|
||
return new BigNumber(value);
|
||
}
|
||
|
||
module.exports = {
|
||
isBigNumber: isBigNumber,
|
||
bigNumberify: bigNumberify,
|
||
BigNumber: BigNumber
|
||
};
|
||
|
||
},{"./convert":24,"./properties":31,"./throw-error":36,"bn.js":2}],22:[function(require,module,exports){
|
||
(function (global){
|
||
'use strict';
|
||
|
||
var convert = require('./convert');
|
||
var defineProperty = require('./properties').defineProperty;
|
||
|
||
var crypto = global.crypto || global.msCrypto;
|
||
if (!crypto || !crypto.getRandomValues) {
|
||
|
||
console.log('WARNING: Missing strong random number source; using weak randomBytes');
|
||
|
||
crypto = {
|
||
getRandomValues: function(buffer) {
|
||
for (var round = 0; round < 20; round++) {
|
||
for (var i = 0; i < buffer.length; i++) {
|
||
if (round) {
|
||
buffer[i] ^= parseInt(256 * Math.random());
|
||
} else {
|
||
buffer[i] = parseInt(256 * Math.random());
|
||
}
|
||
}
|
||
}
|
||
|
||
return buffer;
|
||
},
|
||
_weakCrypto: true
|
||
};
|
||
}
|
||
|
||
function randomBytes(length) {
|
||
if (length <= 0 || length > 1024 || parseInt(length) != length) {
|
||
throw new Error('invalid length');
|
||
}
|
||
|
||
var result = new Uint8Array(length);
|
||
crypto.getRandomValues(result);
|
||
return convert.arrayify(result);
|
||
};
|
||
|
||
if (crypto._weakCrypto === true) {
|
||
defineProperty(randomBytes, '_weakCrypto', true);
|
||
}
|
||
|
||
module.exports = randomBytes;
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"./convert":24,"./properties":31}],23:[function(require,module,exports){
|
||
|
||
var getAddress = require('./address').getAddress;
|
||
var convert = require('./convert');
|
||
var keccak256 = require('./keccak256');
|
||
var RLP = require('./rlp');
|
||
|
||
// http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed
|
||
function getContractAddress(transaction) {
|
||
if (!transaction.from) { throw new Error('missing from address'); }
|
||
var nonce = transaction.nonce;
|
||
|
||
return getAddress('0x' + keccak256(RLP.encode([
|
||
getAddress(transaction.from),
|
||
convert.stripZeros(convert.hexlify(nonce, 'nonce'))
|
||
])).substring(26));
|
||
}
|
||
|
||
module.exports = {
|
||
getContractAddress: getContractAddress,
|
||
}
|
||
|
||
},{"./address":20,"./convert":24,"./keccak256":28,"./rlp":32}],24:[function(require,module,exports){
|
||
/**
|
||
* Conversion Utilities
|
||
*
|
||
*/
|
||
|
||
var defineProperty = require('./properties.js').defineProperty;
|
||
var throwError = require('./throw-error');
|
||
|
||
function addSlice(array) {
|
||
if (array.slice) { return array; }
|
||
|
||
array.slice = function() {
|
||
var args = Array.prototype.slice.call(arguments);
|
||
return new Uint8Array(Array.prototype.slice.apply(array, args));
|
||
}
|
||
|
||
return array;
|
||
}
|
||
|
||
function isArrayish(value) {
|
||
if (!value || parseInt(value.length) != value.length || typeof(value) === 'string') {
|
||
return false;
|
||
}
|
||
|
||
for (var i = 0; i < value.length; i++) {
|
||
var v = value[i];
|
||
if (v < 0 || v >= 256 || parseInt(v) != v) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function arrayify(value, name) {
|
||
|
||
if (value && value.toHexString) {
|
||
value = value.toHexString();
|
||
}
|
||
|
||
if (isHexString(value)) {
|
||
value = value.substring(2);
|
||
if (value.length % 2) { value = '0' + value; }
|
||
|
||
var result = [];
|
||
for (var i = 0; i < value.length; i += 2) {
|
||
result.push(parseInt(value.substr(i, 2), 16));
|
||
}
|
||
|
||
return addSlice(new Uint8Array(result));
|
||
}
|
||
|
||
if (isArrayish(value)) {
|
||
return addSlice(new Uint8Array(value));
|
||
}
|
||
|
||
throwError('invalid arrayify value', { name: name, input: value });
|
||
}
|
||
|
||
function concat(objects) {
|
||
var arrays = [];
|
||
var length = 0;
|
||
for (var i = 0; i < objects.length; i++) {
|
||
var object = arrayify(objects[i])
|
||
arrays.push(object);
|
||
length += object.length;
|
||
}
|
||
|
||
var result = new Uint8Array(length);
|
||
var offset = 0;
|
||
for (var i = 0; i < arrays.length; i++) {
|
||
result.set(arrays[i], offset);
|
||
offset += arrays[i].length;
|
||
}
|
||
|
||
return addSlice(result);
|
||
}
|
||
function stripZeros(value) {
|
||
value = arrayify(value);
|
||
|
||
if (value.length === 0) { return value; }
|
||
|
||
// Find the first non-zero entry
|
||
var start = 0;
|
||
while (value[start] === 0) { start++ }
|
||
|
||
// If we started with zeros, strip them
|
||
if (start) {
|
||
value = value.slice(start);
|
||
}
|
||
|
||
return value;
|
||
}
|
||
|
||
function padZeros(value, length) {
|
||
value = arrayify(value);
|
||
|
||
if (length < value.length) { throw new Error('cannot pad'); }
|
||
|
||
var result = new Uint8Array(length);
|
||
result.set(value, length - value.length);
|
||
return addSlice(result);
|
||
}
|
||
|
||
|
||
function isHexString(value, length) {
|
||
if (typeof(value) !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) {
|
||
return false
|
||
}
|
||
if (length && value.length !== 2 + 2 * length) { return false; }
|
||
return true;
|
||
}
|
||
|
||
var HexCharacters = '0123456789abcdef';
|
||
|
||
function hexlify(value, name) {
|
||
|
||
if (value && value.toHexString) {
|
||
return value.toHexString();
|
||
}
|
||
|
||
if (typeof(value) === 'number') {
|
||
if (value < 0) {
|
||
throwError('cannot hexlify negative value', { name: name, input: value });
|
||
}
|
||
|
||
var hex = '';
|
||
while (value) {
|
||
hex = HexCharacters[value & 0x0f] + hex;
|
||
value = parseInt(value / 16);
|
||
}
|
||
|
||
if (hex.length) {
|
||
if (hex.length % 2) { hex = '0' + hex; }
|
||
return '0x' + hex;
|
||
}
|
||
|
||
return '0x00';
|
||
}
|
||
|
||
if (isHexString(value)) {
|
||
if (value.length % 2) {
|
||
value = '0x0' + value.substring(2);
|
||
}
|
||
return value;
|
||
}
|
||
|
||
if (isArrayish(value)) {
|
||
var result = [];
|
||
for (var i = 0; i < value.length; i++) {
|
||
var v = value[i];
|
||
result.push(HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f]);
|
||
}
|
||
return '0x' + result.join('');
|
||
}
|
||
|
||
throwError('invalid hexlify value', { name: name, input: value });
|
||
}
|
||
|
||
|
||
module.exports = {
|
||
arrayify: arrayify,
|
||
isArrayish: isArrayish,
|
||
|
||
concat: concat,
|
||
|
||
padZeros: padZeros,
|
||
stripZeros: stripZeros,
|
||
|
||
hexlify: hexlify,
|
||
isHexString: isHexString,
|
||
};
|
||
|
||
},{"./properties.js":31,"./throw-error":36}],25:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var hash = require('hash.js');
|
||
|
||
var sha2 = require('./sha2.js');
|
||
|
||
var convert = require('./convert.js');
|
||
|
||
// @TODO: Make this use create-hmac in node
|
||
|
||
function createSha256Hmac(key) {
|
||
if (!key.buffer) { key = convert.arrayify(key); }
|
||
return new hash.hmac(sha2.createSha256, key);
|
||
}
|
||
|
||
function createSha512Hmac(key) {
|
||
if (!key.buffer) { key = convert.arrayify(key); }
|
||
return new hash.hmac(sha2.createSha512, key);
|
||
}
|
||
|
||
module.exports = {
|
||
createSha256Hmac: createSha256Hmac,
|
||
createSha512Hmac: createSha512Hmac,
|
||
};
|
||
|
||
},{"./convert.js":24,"./sha2.js":33,"hash.js":39}],26:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var keccak256 = require('./keccak256');
|
||
var utf8 = require('./utf8');
|
||
|
||
function id(text) {
|
||
return keccak256(utf8.toUtf8Bytes(text));
|
||
}
|
||
|
||
module.exports = id;
|
||
|
||
},{"./keccak256":28,"./utf8":38}],27:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
// This is SUPER useful, but adds 140kb (even zipped, adds 40kb)
|
||
//var unorm = require('unorm');
|
||
|
||
var address = require('./address');
|
||
var bigNumber = require('./bignumber');
|
||
var contractAddress = require('./contract-address');
|
||
var convert = require('./convert');
|
||
var id = require('./id');
|
||
var keccak256 = require('./keccak256');
|
||
var namehash = require('./namehash');
|
||
var sha256 = require('./sha2').sha256;
|
||
var solidity = require('./solidity');
|
||
var randomBytes = require('./random-bytes');
|
||
var properties = require('./properties');
|
||
var RLP = require('./rlp');
|
||
var utf8 = require('./utf8');
|
||
var units = require('./units');
|
||
|
||
|
||
module.exports = {
|
||
RLP: RLP,
|
||
|
||
defineProperty: properties.defineProperty,
|
||
|
||
// NFKD (decomposed)
|
||
//etherSymbol: '\uD835\uDF63',
|
||
|
||
// NFKC (composed)
|
||
etherSymbol: '\u039e',
|
||
|
||
arrayify: convert.arrayify,
|
||
|
||
concat: convert.concat,
|
||
padZeros: convert.padZeros,
|
||
stripZeros: convert.stripZeros,
|
||
|
||
bigNumberify: bigNumber.bigNumberify,
|
||
BigNumber: bigNumber.BigNumber,
|
||
|
||
hexlify: convert.hexlify,
|
||
|
||
toUtf8Bytes: utf8.toUtf8Bytes,
|
||
toUtf8String: utf8.toUtf8String,
|
||
|
||
namehash: namehash,
|
||
id: id,
|
||
|
||
getAddress: address.getAddress,
|
||
getContractAddress: contractAddress.getContractAddress,
|
||
|
||
formatEther: units.formatEther,
|
||
parseEther: units.parseEther,
|
||
|
||
keccak256: keccak256,
|
||
sha256: sha256,
|
||
|
||
randomBytes: randomBytes,
|
||
|
||
solidityPack: solidity.pack,
|
||
solidityKeccak256: solidity.keccak256,
|
||
soliditySha256: solidity.sha256,
|
||
}
|
||
|
||
require('./standalone')({
|
||
utils: module.exports
|
||
});
|
||
|
||
|
||
},{"./address":20,"./bignumber":21,"./contract-address":23,"./convert":24,"./id":26,"./keccak256":28,"./namehash":29,"./properties":31,"./random-bytes":22,"./rlp":32,"./sha2":33,"./solidity":34,"./standalone":35,"./units":37,"./utf8":38}],28:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var sha3 = require('js-sha3');
|
||
|
||
var convert = require('./convert.js');
|
||
|
||
function keccak256(data) {
|
||
data = convert.arrayify(data);
|
||
return '0x' + sha3.keccak_256(data);
|
||
}
|
||
|
||
module.exports = keccak256;
|
||
|
||
},{"./convert.js":24,"js-sha3":52}],29:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var convert = require('./convert');
|
||
var utf8 = require('./utf8');
|
||
var keccak256 = require('./keccak256');
|
||
|
||
var Zeros = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||
var Partition = new RegExp("^((.*)\\.)?([^.]+)$");
|
||
var UseSTD3ASCIIRules = new RegExp("^[a-z0-9.-]*$");
|
||
|
||
function namehash(name, depth) {
|
||
name = name.toLowerCase();
|
||
|
||
// Supporting the full UTF-8 space requires additional (and large)
|
||
// libraries, so for now we simply do not support them.
|
||
// It should be fairly easy in the future to support systems with
|
||
// String.normalize, but that is future work.
|
||
if (!name.match(UseSTD3ASCIIRules)) {
|
||
throw new Error('contains invalid UseSTD3ASCIIRules characters');
|
||
}
|
||
|
||
var result = Zeros;
|
||
var processed = 0;
|
||
while (name.length && (!depth || processed < depth)) {
|
||
var partition = name.match(Partition);
|
||
var label = utf8.toUtf8Bytes(partition[3]);
|
||
result = keccak256(convert.concat([result, keccak256(label)]));
|
||
|
||
name = partition[2] || '';
|
||
|
||
processed++;
|
||
}
|
||
|
||
return convert.hexlify(result);
|
||
}
|
||
|
||
module.exports = namehash;
|
||
|
||
|
||
},{"./convert":24,"./keccak256":28,"./utf8":38}],30:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var convert = require('./convert');
|
||
|
||
function pbkdf2(password, salt, iterations, keylen, createHmac) {
|
||
var hLen
|
||
var l = 1
|
||
var DK = new Uint8Array(keylen)
|
||
var block1 = new Uint8Array(salt.length + 4)
|
||
block1.set(salt);
|
||
//salt.copy(block1, 0, 0, salt.length)
|
||
|
||
var r
|
||
var T
|
||
|
||
for (var i = 1; i <= l; i++) {
|
||
//block1.writeUInt32BE(i, salt.length)
|
||
block1[salt.length] = (i >> 24) & 0xff;
|
||
block1[salt.length + 1] = (i >> 16) & 0xff;
|
||
block1[salt.length + 2] = (i >> 8) & 0xff;
|
||
block1[salt.length + 3] = i & 0xff;
|
||
|
||
var U = createHmac(password).update(block1).digest();
|
||
|
||
if (!hLen) {
|
||
hLen = U.length
|
||
T = new Uint8Array(hLen)
|
||
l = Math.ceil(keylen / hLen)
|
||
r = keylen - (l - 1) * hLen
|
||
}
|
||
|
||
//U.copy(T, 0, 0, hLen)
|
||
T.set(U);
|
||
|
||
|
||
for (var j = 1; j < iterations; j++) {
|
||
U = createHmac(password).update(U).digest()
|
||
for (var k = 0; k < hLen; k++) T[k] ^= U[k]
|
||
}
|
||
|
||
|
||
var destPos = (i - 1) * hLen
|
||
var len = (i === l ? r : hLen)
|
||
//T.copy(DK, destPos, 0, len)
|
||
DK.set(convert.arrayify(T).slice(0, len), destPos);
|
||
}
|
||
|
||
return convert.arrayify(DK)
|
||
}
|
||
|
||
module.exports = pbkdf2;
|
||
|
||
},{"./convert":24}],31:[function(require,module,exports){
|
||
function defineProperty(object, name, value) {
|
||
Object.defineProperty(object, name, {
|
||
enumerable: true,
|
||
value: value,
|
||
writable: false,
|
||
});
|
||
}
|
||
|
||
module.exports = {
|
||
defineProperty: defineProperty,
|
||
};
|
||
|
||
},{}],32:[function(require,module,exports){
|
||
//See: https://github.com/ethereum/wiki/wiki/RLP
|
||
|
||
var convert = require('./convert.js');
|
||
|
||
function arrayifyInteger(value) {
|
||
var result = [];
|
||
while (value) {
|
||
result.unshift(value & 0xff);
|
||
value >>= 8;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
function unarrayifyInteger(data, offset, length) {
|
||
var result = 0;
|
||
for (var i = 0; i < length; i++) {
|
||
result = (result * 256) + data[offset + i];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
function _encode(object) {
|
||
if (Array.isArray(object)) {
|
||
var payload = [];
|
||
object.forEach(function(child) {
|
||
payload = payload.concat(_encode(child));
|
||
});
|
||
|
||
if (payload.length <= 55) {
|
||
payload.unshift(0xc0 + payload.length)
|
||
return payload;
|
||
}
|
||
|
||
var length = arrayifyInteger(payload.length);
|
||
length.unshift(0xf7 + length.length);
|
||
|
||
return length.concat(payload);
|
||
|
||
} else {
|
||
object = [].slice.call(convert.arrayify(object));
|
||
|
||
if (object.length === 1 && object[0] <= 0x7f) {
|
||
return object;
|
||
|
||
} else if (object.length <= 55) {
|
||
object.unshift(0x80 + object.length);
|
||
return object
|
||
}
|
||
|
||
var length = arrayifyInteger(object.length);
|
||
length.unshift(0xb7 + length.length);
|
||
|
||
return length.concat(object);
|
||
}
|
||
}
|
||
|
||
function encode(object) {
|
||
return convert.hexlify(_encode(object));
|
||
}
|
||
|
||
function _decodeChildren(data, offset, childOffset, length) {
|
||
var result = [];
|
||
|
||
while (childOffset < offset + 1 + length) {
|
||
var decoded = _decode(data, childOffset);
|
||
|
||
result.push(decoded.result);
|
||
|
||
childOffset += decoded.consumed;
|
||
if (childOffset > offset + 1 + length) {
|
||
throw new Error('invalid rlp');
|
||
}
|
||
}
|
||
|
||
return {consumed: (1 + length), result: result};
|
||
}
|
||
|
||
// returns { consumed: number, result: Object }
|
||
function _decode(data, offset) {
|
||
if (data.length === 0) { throw new Error('invalid rlp data'); }
|
||
|
||
// Array with extra length prefix
|
||
if (data[offset] >= 0xf8) {
|
||
var lengthLength = data[offset] - 0xf7;
|
||
if (offset + 1 + lengthLength > data.length) {
|
||
throw new Error('too short');
|
||
}
|
||
|
||
var length = unarrayifyInteger(data, offset + 1, lengthLength);
|
||
if (offset + 1 + lengthLength + length > data.length) {
|
||
throw new Error('to short');
|
||
}
|
||
|
||
return _decodeChildren(data, offset, offset + 1 + lengthLength, lengthLength + length);
|
||
|
||
} else if (data[offset] >= 0xc0) {
|
||
var length = data[offset] - 0xc0;
|
||
if (offset + 1 + length > data.length) {
|
||
throw new Error('invalid rlp data');
|
||
}
|
||
|
||
return _decodeChildren(data, offset, offset + 1, length);
|
||
|
||
} else if (data[offset] >= 0xb8) {
|
||
var lengthLength = data[offset] - 0xb7;
|
||
if (offset + 1 + lengthLength > data.length) {
|
||
throw new Error('invalid rlp data');
|
||
}
|
||
|
||
var length = unarrayifyInteger(data, offset + 1, lengthLength);
|
||
if (offset + 1 + lengthLength + length > data.length) {
|
||
throw new Error('invalid rlp data');
|
||
}
|
||
|
||
var result = convert.hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));
|
||
return { consumed: (1 + lengthLength + length), result: result }
|
||
|
||
} else if (data[offset] >= 0x80) {
|
||
var length = data[offset] - 0x80;
|
||
if (offset + 1 + length > data.offset) {
|
||
throw new Error('invlaid rlp data');
|
||
}
|
||
|
||
var result = convert.hexlify(data.slice(offset + 1, offset + 1 + length));
|
||
return { consumed: (1 + length), result: result }
|
||
}
|
||
return { consumed: 1, result: convert.hexlify(data[offset]) };
|
||
}
|
||
|
||
function decode(data) {
|
||
data = convert.arrayify(data);
|
||
var decoded = _decode(data, 0);
|
||
if (decoded.consumed !== data.length) {
|
||
throw new Error('invalid rlp data');
|
||
}
|
||
return decoded.result;
|
||
}
|
||
|
||
module.exports = {
|
||
encode: encode,
|
||
decode: decode,
|
||
}
|
||
|
||
},{"./convert.js":24}],33:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var hash = require('hash.js');
|
||
|
||
var convert = require('./convert.js');
|
||
|
||
function sha256(data) {
|
||
data = convert.arrayify(data);
|
||
return '0x' + (hash.sha256().update(data).digest('hex'));
|
||
}
|
||
|
||
function sha512(data) {
|
||
data = convert.arrayify(data);
|
||
return '0x' + (hash.sha512().update(data).digest('hex'));
|
||
}
|
||
|
||
module.exports = {
|
||
sha256: sha256,
|
||
sha512: sha512,
|
||
|
||
createSha256: hash.sha256,
|
||
createSha512: hash.sha512,
|
||
}
|
||
|
||
},{"./convert.js":24,"hash.js":39}],34:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var bigNumberify = require('./bignumber').bigNumberify;
|
||
var convert = require('./convert');
|
||
var getAddress = require('./address').getAddress;
|
||
var utf8 = require('./utf8');
|
||
|
||
var hashKeccak256 = require('./keccak256');
|
||
var hashSha256 = require('./sha2').sha256;
|
||
|
||
var regexBytes = new RegExp("^bytes([0-9]+)$");
|
||
var regexNumber = new RegExp("^(u?int)([0-9]*)$");
|
||
var regexArray = new RegExp("^(.*)\\[([0-9]*)\\]$");
|
||
|
||
var Zeros = '0000000000000000000000000000000000000000000000000000000000000000';
|
||
|
||
function _pack(type, value, isArray) {
|
||
switch(type) {
|
||
case 'address':
|
||
if (isArray) { return convert.padZeros(value, 32); }
|
||
return convert.arrayify(value);
|
||
case 'string':
|
||
return utf8.toUtf8Bytes(value);
|
||
case 'bytes':
|
||
return convert.arrayify(value);
|
||
}
|
||
|
||
var match = type.match(regexNumber);
|
||
if (match) {
|
||
var signed = (match[1] === 'int')
|
||
var size = parseInt(match[2] || "256")
|
||
if ((size % 8 != 0) || size === 0 || size > 256) {
|
||
throw new Error('invalid number type - ' + type);
|
||
}
|
||
|
||
if (isArray) { size = 256; }
|
||
|
||
value = bigNumberify(value).toTwos(size);
|
||
|
||
return convert.padZeros(value, size / 8);
|
||
}
|
||
|
||
match = type.match(regexBytes);
|
||
if (match) {
|
||
var size = match[1];
|
||
if (size != parseInt(size) || size === 0 || size > 32) {
|
||
throw new Error('invalid number type - ' + type);
|
||
}
|
||
size = parseInt(size);
|
||
if (convert.arrayify(value).byteLength !== size) { throw new Error('invalid value for ' + type); }
|
||
if (isArray) { return (value + Zeros).substring(0, 66); }
|
||
return value;
|
||
}
|
||
|
||
match = type.match(regexArray);
|
||
if (match) {
|
||
var baseType = match[1];
|
||
var count = parseInt(match[2] || value.length);
|
||
if (count != value.length) { throw new Error('invalid value for ' + type); }
|
||
var result = [];
|
||
value.forEach(function(value) {
|
||
value = _pack(baseType, value, true);
|
||
result.push(value);
|
||
});
|
||
return convert.concat(result);
|
||
}
|
||
|
||
throw new Error('unknown type - ' + type);
|
||
}
|
||
|
||
function pack(types, values) {
|
||
if (types.length != values.length) { throw new Error('type/value count mismatch'); }
|
||
var tight = [];
|
||
types.forEach(function(type, index) {
|
||
tight.push(_pack(type, values[index]));
|
||
});
|
||
return convert.hexlify(convert.concat(tight));
|
||
}
|
||
|
||
function keccak256(types, values) {
|
||
return hashKeccak256(pack(types, values));
|
||
}
|
||
|
||
function sha256(types, values) {
|
||
return hashSha256(pack(types, values));
|
||
}
|
||
|
||
module.exports = {
|
||
pack: pack,
|
||
|
||
keccak256: keccak256,
|
||
sha256: sha256,
|
||
}
|
||
|
||
},{"./address":20,"./bignumber":21,"./convert":24,"./keccak256":28,"./sha2":33,"./utf8":38}],35:[function(require,module,exports){
|
||
(function (global){
|
||
var defineProperty = require('./properties.js').defineProperty;
|
||
|
||
function Ethers() { }
|
||
|
||
function defineEthersValues(values) {
|
||
|
||
// This is modified in the Gruntfile.js
|
||
if ("__STAND_ALONE_TRUE__" !== ("__STAND_ALONE_" + "TRUE__")) {
|
||
return;
|
||
}
|
||
|
||
if (global.ethers == null) {
|
||
defineProperty(global, 'ethers', new Ethers());
|
||
}
|
||
|
||
for (var key in values) {
|
||
if (global.ethers[key] == null) {
|
||
defineProperty(global.ethers, key, values[key]);
|
||
}
|
||
}
|
||
}
|
||
|
||
module.exports = defineEthersValues;
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"./properties.js":31}],36:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
function throwError(message, params) {
|
||
var error = new Error(message);
|
||
for (var key in params) {
|
||
error[key] = params[key];
|
||
}
|
||
throw error;
|
||
}
|
||
|
||
module.exports = throwError;
|
||
|
||
},{}],37:[function(require,module,exports){
|
||
var bigNumberify = require('./bignumber.js').bigNumberify;
|
||
var throwError = require('./throw-error');
|
||
|
||
var zero = new bigNumberify(0);
|
||
var negative1 = new bigNumberify(-1);
|
||
var tenPower18 = new bigNumberify('1000000000000000000');
|
||
|
||
function formatEther(wei, options) {
|
||
wei = bigNumberify(wei);
|
||
|
||
if (!options) { options = {}; }
|
||
|
||
var negative = wei.lt(zero);
|
||
if (negative) { wei = wei.mul(negative1); }
|
||
|
||
var fraction = wei.mod(tenPower18).toString(10);
|
||
while (fraction.length < 18) { fraction = '0' + fraction; }
|
||
|
||
if (!options.pad) {
|
||
fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1];
|
||
}
|
||
|
||
var whole = wei.div(tenPower18).toString(10);
|
||
|
||
if (options.commify) {
|
||
whole = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
|
||
}
|
||
|
||
var value = whole + '.' + fraction;
|
||
|
||
if (negative) { value = '-' + value; }
|
||
|
||
return value;
|
||
}
|
||
|
||
function parseEther(ether) {
|
||
if (typeof(ether) !== 'string' || !ether.match(/^-?[0-9.,]+$/)) {
|
||
throwError('invalid value', { input: ether });
|
||
}
|
||
|
||
var value = ether.replace(/,/g,'');
|
||
|
||
// Is it negative?
|
||
var negative = (value.substring(0, 1) === '-');
|
||
if (negative) { value = value.substring(1); }
|
||
|
||
if (value === '.') { throwError('invalid value', { input: ether }); }
|
||
|
||
// Split it into a whole and fractional part
|
||
var comps = value.split('.');
|
||
if (comps.length > 2) { throwError('too many decimal points', { input: ether }); }
|
||
|
||
var whole = comps[0], fraction = comps[1];
|
||
if (!whole) { whole = '0'; }
|
||
if (!fraction) { fraction = '0'; }
|
||
if (fraction.length > 18) { throwError('too many decimal places', { input: ether, decimals: fraction.length }); }
|
||
|
||
while (fraction.length < 18) { fraction += '0'; }
|
||
|
||
whole = bigNumberify(whole);
|
||
fraction = bigNumberify(fraction);
|
||
|
||
var wei = (whole.mul(tenPower18)).add(fraction);
|
||
|
||
if (negative) { wei = wei.mul(negative1); }
|
||
|
||
return wei;
|
||
}
|
||
|
||
module.exports = {
|
||
formatEther: formatEther,
|
||
parseEther: parseEther,
|
||
}
|
||
|
||
},{"./bignumber.js":21,"./throw-error":36}],38:[function(require,module,exports){
|
||
|
||
var convert = require('./convert.js');
|
||
|
||
// http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
|
||
function utf8ToBytes(str) {
|
||
var result = [];
|
||
var offset = 0;
|
||
for (var i = 0; i < str.length; i++) {
|
||
var c = str.charCodeAt(i);
|
||
if (c < 128) {
|
||
result[offset++] = c;
|
||
} else if (c < 2048) {
|
||
result[offset++] = (c >> 6) | 192;
|
||
result[offset++] = (c & 63) | 128;
|
||
} else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
|
||
// Surrogate Pair
|
||
c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
|
||
result[offset++] = (c >> 18) | 240;
|
||
result[offset++] = ((c >> 12) & 63) | 128;
|
||
result[offset++] = ((c >> 6) & 63) | 128;
|
||
result[offset++] = (c & 63) | 128;
|
||
} else {
|
||
result[offset++] = (c >> 12) | 224;
|
||
result[offset++] = ((c >> 6) & 63) | 128;
|
||
result[offset++] = (c & 63) | 128;
|
||
}
|
||
}
|
||
|
||
return convert.arrayify(result);
|
||
};
|
||
|
||
|
||
// http://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript#13691499
|
||
function bytesToUtf8(bytes) {
|
||
bytes = convert.arrayify(bytes);
|
||
|
||
var result = '';
|
||
var i = 0;
|
||
|
||
// Invalid bytes are ignored
|
||
while(i < bytes.length) {
|
||
var c = bytes[i++];
|
||
if (c >> 7 == 0) {
|
||
// 0xxx xxxx
|
||
result += String.fromCharCode(c);
|
||
continue;
|
||
}
|
||
|
||
// Invalid starting byte
|
||
if (c >> 6 == 0x02) { continue; }
|
||
|
||
// Multibyte; how many bytes left for thus character?
|
||
var extraLength = null;
|
||
if (c >> 5 == 0x06) {
|
||
extraLength = 1;
|
||
} else if (c >> 4 == 0x0e) {
|
||
extraLength = 2;
|
||
} else if (c >> 3 == 0x1e) {
|
||
extraLength = 3;
|
||
} else if (c >> 2 == 0x3e) {
|
||
extraLength = 4;
|
||
} else if (c >> 1 == 0x7e) {
|
||
extraLength = 5;
|
||
} else {
|
||
continue;
|
||
}
|
||
|
||
// Do we have enough bytes in our data?
|
||
if (i + extraLength > bytes.length) {
|
||
|
||
// If there is an invalid unprocessed byte, try to continue
|
||
for (; i < bytes.length; i++) {
|
||
if (bytes[i] >> 6 != 0x02) { break; }
|
||
}
|
||
if (i != bytes.length) continue;
|
||
|
||
// All leftover bytes are valid.
|
||
return result;
|
||
}
|
||
|
||
// Remove the UTF-8 prefix from the char (res)
|
||
var res = c & ((1 << (8 - extraLength - 1)) - 1);
|
||
|
||
var count;
|
||
for (count = 0; count < extraLength; count++) {
|
||
var nextChar = bytes[i++];
|
||
|
||
// Is the char valid multibyte part?
|
||
if (nextChar >> 6 != 0x02) {break;};
|
||
res = (res << 6) | (nextChar & 0x3f);
|
||
}
|
||
|
||
if (count != extraLength) {
|
||
i--;
|
||
continue;
|
||
}
|
||
|
||
if (res <= 0xffff) {
|
||
result += String.fromCharCode(res);
|
||
continue;
|
||
}
|
||
|
||
res -= 0x10000;
|
||
result += String.fromCharCode(((res >> 10) & 0x3ff) + 0xd800, (res & 0x3ff) + 0xdc00);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
module.exports = {
|
||
toUtf8Bytes: utf8ToBytes,
|
||
toUtf8String: bytesToUtf8,
|
||
};
|
||
|
||
},{"./convert.js":24}],39:[function(require,module,exports){
|
||
var hash = exports;
|
||
|
||
hash.utils = require('./hash/utils');
|
||
hash.common = require('./hash/common');
|
||
hash.sha = require('./hash/sha');
|
||
hash.ripemd = require('./hash/ripemd');
|
||
hash.hmac = require('./hash/hmac');
|
||
|
||
// Proxy hash functions to the main object
|
||
hash.sha1 = hash.sha.sha1;
|
||
hash.sha256 = hash.sha.sha256;
|
||
hash.sha224 = hash.sha.sha224;
|
||
hash.sha384 = hash.sha.sha384;
|
||
hash.sha512 = hash.sha.sha512;
|
||
hash.ripemd160 = hash.ripemd.ripemd160;
|
||
|
||
},{"./hash/common":40,"./hash/hmac":41,"./hash/ripemd":42,"./hash/sha":43,"./hash/utils":50}],40:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('./utils');
|
||
var assert = require('minimalistic-assert');
|
||
|
||
function BlockHash() {
|
||
this.pending = null;
|
||
this.pendingTotal = 0;
|
||
this.blockSize = this.constructor.blockSize;
|
||
this.outSize = this.constructor.outSize;
|
||
this.hmacStrength = this.constructor.hmacStrength;
|
||
this.padLength = this.constructor.padLength / 8;
|
||
this.endian = 'big';
|
||
|
||
this._delta8 = this.blockSize / 8;
|
||
this._delta32 = this.blockSize / 32;
|
||
}
|
||
exports.BlockHash = BlockHash;
|
||
|
||
BlockHash.prototype.update = function update(msg, enc) {
|
||
// Convert message to array, pad it, and join into 32bit blocks
|
||
msg = utils.toArray(msg, enc);
|
||
if (!this.pending)
|
||
this.pending = msg;
|
||
else
|
||
this.pending = this.pending.concat(msg);
|
||
this.pendingTotal += msg.length;
|
||
|
||
// Enough data, try updating
|
||
if (this.pending.length >= this._delta8) {
|
||
msg = this.pending;
|
||
|
||
// Process pending data in blocks
|
||
var r = msg.length % this._delta8;
|
||
this.pending = msg.slice(msg.length - r, msg.length);
|
||
if (this.pending.length === 0)
|
||
this.pending = null;
|
||
|
||
msg = utils.join32(msg, 0, msg.length - r, this.endian);
|
||
for (var i = 0; i < msg.length; i += this._delta32)
|
||
this._update(msg, i, i + this._delta32);
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
BlockHash.prototype.digest = function digest(enc) {
|
||
this.update(this._pad());
|
||
assert(this.pending === null);
|
||
|
||
return this._digest(enc);
|
||
};
|
||
|
||
BlockHash.prototype._pad = function pad() {
|
||
var len = this.pendingTotal;
|
||
var bytes = this._delta8;
|
||
var k = bytes - ((len + this.padLength) % bytes);
|
||
var res = new Array(k + this.padLength);
|
||
res[0] = 0x80;
|
||
for (var i = 1; i < k; i++)
|
||
res[i] = 0;
|
||
|
||
// Append length
|
||
len <<= 3;
|
||
if (this.endian === 'big') {
|
||
for (var t = 8; t < this.padLength; t++)
|
||
res[i++] = 0;
|
||
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = (len >>> 24) & 0xff;
|
||
res[i++] = (len >>> 16) & 0xff;
|
||
res[i++] = (len >>> 8) & 0xff;
|
||
res[i++] = len & 0xff;
|
||
} else {
|
||
res[i++] = len & 0xff;
|
||
res[i++] = (len >>> 8) & 0xff;
|
||
res[i++] = (len >>> 16) & 0xff;
|
||
res[i++] = (len >>> 24) & 0xff;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
res[i++] = 0;
|
||
|
||
for (t = 8; t < this.padLength; t++)
|
||
res[i++] = 0;
|
||
}
|
||
|
||
return res;
|
||
};
|
||
|
||
},{"./utils":50,"minimalistic-assert":53}],41:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('./utils');
|
||
var assert = require('minimalistic-assert');
|
||
|
||
function Hmac(hash, key, enc) {
|
||
if (!(this instanceof Hmac))
|
||
return new Hmac(hash, key, enc);
|
||
this.Hash = hash;
|
||
this.blockSize = hash.blockSize / 8;
|
||
this.outSize = hash.outSize / 8;
|
||
this.inner = null;
|
||
this.outer = null;
|
||
|
||
this._init(utils.toArray(key, enc));
|
||
}
|
||
module.exports = Hmac;
|
||
|
||
Hmac.prototype._init = function init(key) {
|
||
// Shorten key, if needed
|
||
if (key.length > this.blockSize)
|
||
key = new this.Hash().update(key).digest();
|
||
assert(key.length <= this.blockSize);
|
||
|
||
// Add padding to key
|
||
for (var i = key.length; i < this.blockSize; i++)
|
||
key.push(0);
|
||
|
||
for (i = 0; i < key.length; i++)
|
||
key[i] ^= 0x36;
|
||
this.inner = new this.Hash().update(key);
|
||
|
||
// 0x36 ^ 0x5c = 0x6a
|
||
for (i = 0; i < key.length; i++)
|
||
key[i] ^= 0x6a;
|
||
this.outer = new this.Hash().update(key);
|
||
};
|
||
|
||
Hmac.prototype.update = function update(msg, enc) {
|
||
this.inner.update(msg, enc);
|
||
return this;
|
||
};
|
||
|
||
Hmac.prototype.digest = function digest(enc) {
|
||
this.outer.update(this.inner.digest());
|
||
return this.outer.digest(enc);
|
||
};
|
||
|
||
},{"./utils":50,"minimalistic-assert":53}],42:[function(require,module,exports){
|
||
module.exports = {ripemd160: null}
|
||
},{}],43:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
exports.sha1 = require('./sha/1');
|
||
exports.sha224 = require('./sha/224');
|
||
exports.sha256 = require('./sha/256');
|
||
exports.sha384 = require('./sha/384');
|
||
exports.sha512 = require('./sha/512');
|
||
|
||
},{"./sha/1":44,"./sha/224":45,"./sha/256":46,"./sha/384":47,"./sha/512":48}],44:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('../utils');
|
||
var common = require('../common');
|
||
var shaCommon = require('./common');
|
||
|
||
var rotl32 = utils.rotl32;
|
||
var sum32 = utils.sum32;
|
||
var sum32_5 = utils.sum32_5;
|
||
var ft_1 = shaCommon.ft_1;
|
||
var BlockHash = common.BlockHash;
|
||
|
||
var sha1_K = [
|
||
0x5A827999, 0x6ED9EBA1,
|
||
0x8F1BBCDC, 0xCA62C1D6
|
||
];
|
||
|
||
function SHA1() {
|
||
if (!(this instanceof SHA1))
|
||
return new SHA1();
|
||
|
||
BlockHash.call(this);
|
||
this.h = [
|
||
0x67452301, 0xefcdab89, 0x98badcfe,
|
||
0x10325476, 0xc3d2e1f0 ];
|
||
this.W = new Array(80);
|
||
}
|
||
|
||
utils.inherits(SHA1, BlockHash);
|
||
module.exports = SHA1;
|
||
|
||
SHA1.blockSize = 512;
|
||
SHA1.outSize = 160;
|
||
SHA1.hmacStrength = 80;
|
||
SHA1.padLength = 64;
|
||
|
||
SHA1.prototype._update = function _update(msg, start) {
|
||
var W = this.W;
|
||
|
||
for (var i = 0; i < 16; i++)
|
||
W[i] = msg[start + i];
|
||
|
||
for(; i < W.length; i++)
|
||
W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
|
||
|
||
var a = this.h[0];
|
||
var b = this.h[1];
|
||
var c = this.h[2];
|
||
var d = this.h[3];
|
||
var e = this.h[4];
|
||
|
||
for (i = 0; i < W.length; i++) {
|
||
var s = ~~(i / 20);
|
||
var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
|
||
e = d;
|
||
d = c;
|
||
c = rotl32(b, 30);
|
||
b = a;
|
||
a = t;
|
||
}
|
||
|
||
this.h[0] = sum32(this.h[0], a);
|
||
this.h[1] = sum32(this.h[1], b);
|
||
this.h[2] = sum32(this.h[2], c);
|
||
this.h[3] = sum32(this.h[3], d);
|
||
this.h[4] = sum32(this.h[4], e);
|
||
};
|
||
|
||
SHA1.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h, 'big');
|
||
else
|
||
return utils.split32(this.h, 'big');
|
||
};
|
||
|
||
},{"../common":40,"../utils":50,"./common":49}],45:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('../utils');
|
||
var SHA256 = require('./256');
|
||
|
||
function SHA224() {
|
||
if (!(this instanceof SHA224))
|
||
return new SHA224();
|
||
|
||
SHA256.call(this);
|
||
this.h = [
|
||
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
|
||
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
|
||
}
|
||
utils.inherits(SHA224, SHA256);
|
||
module.exports = SHA224;
|
||
|
||
SHA224.blockSize = 512;
|
||
SHA224.outSize = 224;
|
||
SHA224.hmacStrength = 192;
|
||
SHA224.padLength = 64;
|
||
|
||
SHA224.prototype._digest = function digest(enc) {
|
||
// Just truncate output
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h.slice(0, 7), 'big');
|
||
else
|
||
return utils.split32(this.h.slice(0, 7), 'big');
|
||
};
|
||
|
||
|
||
},{"../utils":50,"./256":46}],46:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('../utils');
|
||
var common = require('../common');
|
||
var shaCommon = require('./common');
|
||
var assert = require('minimalistic-assert');
|
||
|
||
var sum32 = utils.sum32;
|
||
var sum32_4 = utils.sum32_4;
|
||
var sum32_5 = utils.sum32_5;
|
||
var ch32 = shaCommon.ch32;
|
||
var maj32 = shaCommon.maj32;
|
||
var s0_256 = shaCommon.s0_256;
|
||
var s1_256 = shaCommon.s1_256;
|
||
var g0_256 = shaCommon.g0_256;
|
||
var g1_256 = shaCommon.g1_256;
|
||
|
||
var BlockHash = common.BlockHash;
|
||
|
||
var sha256_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
|
||
];
|
||
|
||
function SHA256() {
|
||
if (!(this instanceof SHA256))
|
||
return new SHA256();
|
||
|
||
BlockHash.call(this);
|
||
this.h = [
|
||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||
];
|
||
this.k = sha256_K;
|
||
this.W = new Array(64);
|
||
}
|
||
utils.inherits(SHA256, BlockHash);
|
||
module.exports = SHA256;
|
||
|
||
SHA256.blockSize = 512;
|
||
SHA256.outSize = 256;
|
||
SHA256.hmacStrength = 192;
|
||
SHA256.padLength = 64;
|
||
|
||
SHA256.prototype._update = function _update(msg, start) {
|
||
var W = this.W;
|
||
|
||
for (var i = 0; i < 16; i++)
|
||
W[i] = msg[start + i];
|
||
for (; i < W.length; i++)
|
||
W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
|
||
|
||
var a = this.h[0];
|
||
var b = this.h[1];
|
||
var c = this.h[2];
|
||
var d = this.h[3];
|
||
var e = this.h[4];
|
||
var f = this.h[5];
|
||
var g = this.h[6];
|
||
var h = this.h[7];
|
||
|
||
assert(this.k.length === W.length);
|
||
for (i = 0; i < W.length; i++) {
|
||
var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
|
||
var T2 = sum32(s0_256(a), maj32(a, b, c));
|
||
h = g;
|
||
g = f;
|
||
f = e;
|
||
e = sum32(d, T1);
|
||
d = c;
|
||
c = b;
|
||
b = a;
|
||
a = sum32(T1, T2);
|
||
}
|
||
|
||
this.h[0] = sum32(this.h[0], a);
|
||
this.h[1] = sum32(this.h[1], b);
|
||
this.h[2] = sum32(this.h[2], c);
|
||
this.h[3] = sum32(this.h[3], d);
|
||
this.h[4] = sum32(this.h[4], e);
|
||
this.h[5] = sum32(this.h[5], f);
|
||
this.h[6] = sum32(this.h[6], g);
|
||
this.h[7] = sum32(this.h[7], h);
|
||
};
|
||
|
||
SHA256.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h, 'big');
|
||
else
|
||
return utils.split32(this.h, 'big');
|
||
};
|
||
|
||
},{"../common":40,"../utils":50,"./common":49,"minimalistic-assert":53}],47:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('../utils');
|
||
|
||
var SHA512 = require('./512');
|
||
|
||
function SHA384() {
|
||
if (!(this instanceof SHA384))
|
||
return new SHA384();
|
||
|
||
SHA512.call(this);
|
||
this.h = [
|
||
0xcbbb9d5d, 0xc1059ed8,
|
||
0x629a292a, 0x367cd507,
|
||
0x9159015a, 0x3070dd17,
|
||
0x152fecd8, 0xf70e5939,
|
||
0x67332667, 0xffc00b31,
|
||
0x8eb44a87, 0x68581511,
|
||
0xdb0c2e0d, 0x64f98fa7,
|
||
0x47b5481d, 0xbefa4fa4 ];
|
||
}
|
||
utils.inherits(SHA384, SHA512);
|
||
module.exports = SHA384;
|
||
|
||
SHA384.blockSize = 1024;
|
||
SHA384.outSize = 384;
|
||
SHA384.hmacStrength = 192;
|
||
SHA384.padLength = 128;
|
||
|
||
SHA384.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h.slice(0, 12), 'big');
|
||
else
|
||
return utils.split32(this.h.slice(0, 12), 'big');
|
||
};
|
||
|
||
},{"../utils":50,"./512":48}],48:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('../utils');
|
||
var common = require('../common');
|
||
var assert = require('minimalistic-assert');
|
||
|
||
var rotr64_hi = utils.rotr64_hi;
|
||
var rotr64_lo = utils.rotr64_lo;
|
||
var shr64_hi = utils.shr64_hi;
|
||
var shr64_lo = utils.shr64_lo;
|
||
var sum64 = utils.sum64;
|
||
var sum64_hi = utils.sum64_hi;
|
||
var sum64_lo = utils.sum64_lo;
|
||
var sum64_4_hi = utils.sum64_4_hi;
|
||
var sum64_4_lo = utils.sum64_4_lo;
|
||
var sum64_5_hi = utils.sum64_5_hi;
|
||
var sum64_5_lo = utils.sum64_5_lo;
|
||
|
||
var BlockHash = common.BlockHash;
|
||
|
||
var sha512_K = [
|
||
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
|
||
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
|
||
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
|
||
0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
|
||
0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
|
||
0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
|
||
0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
|
||
0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
|
||
0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
|
||
0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
|
||
0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
|
||
0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
|
||
0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
|
||
0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
|
||
0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
|
||
0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
|
||
0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
|
||
0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
|
||
0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
|
||
0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
|
||
0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
|
||
0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
|
||
0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
|
||
0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
|
||
0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
|
||
0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
|
||
0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
|
||
0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
|
||
0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
|
||
0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
|
||
0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
|
||
0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
|
||
0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
|
||
0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
|
||
0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
|
||
0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
|
||
0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
|
||
0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
|
||
0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
|
||
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
|
||
];
|
||
|
||
function SHA512() {
|
||
if (!(this instanceof SHA512))
|
||
return new SHA512();
|
||
|
||
BlockHash.call(this);
|
||
this.h = [
|
||
0x6a09e667, 0xf3bcc908,
|
||
0xbb67ae85, 0x84caa73b,
|
||
0x3c6ef372, 0xfe94f82b,
|
||
0xa54ff53a, 0x5f1d36f1,
|
||
0x510e527f, 0xade682d1,
|
||
0x9b05688c, 0x2b3e6c1f,
|
||
0x1f83d9ab, 0xfb41bd6b,
|
||
0x5be0cd19, 0x137e2179 ];
|
||
this.k = sha512_K;
|
||
this.W = new Array(160);
|
||
}
|
||
utils.inherits(SHA512, BlockHash);
|
||
module.exports = SHA512;
|
||
|
||
SHA512.blockSize = 1024;
|
||
SHA512.outSize = 512;
|
||
SHA512.hmacStrength = 192;
|
||
SHA512.padLength = 128;
|
||
|
||
SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
|
||
var W = this.W;
|
||
|
||
// 32 x 32bit words
|
||
for (var i = 0; i < 32; i++)
|
||
W[i] = msg[start + i];
|
||
for (; i < W.length; i += 2) {
|
||
var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
|
||
var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
|
||
var c1_hi = W[i - 14]; // i - 7
|
||
var c1_lo = W[i - 13];
|
||
var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
|
||
var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
|
||
var c3_hi = W[i - 32]; // i - 16
|
||
var c3_lo = W[i - 31];
|
||
|
||
W[i] = sum64_4_hi(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo);
|
||
W[i + 1] = sum64_4_lo(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo);
|
||
}
|
||
};
|
||
|
||
SHA512.prototype._update = function _update(msg, start) {
|
||
this._prepareBlock(msg, start);
|
||
|
||
var W = this.W;
|
||
|
||
var ah = this.h[0];
|
||
var al = this.h[1];
|
||
var bh = this.h[2];
|
||
var bl = this.h[3];
|
||
var ch = this.h[4];
|
||
var cl = this.h[5];
|
||
var dh = this.h[6];
|
||
var dl = this.h[7];
|
||
var eh = this.h[8];
|
||
var el = this.h[9];
|
||
var fh = this.h[10];
|
||
var fl = this.h[11];
|
||
var gh = this.h[12];
|
||
var gl = this.h[13];
|
||
var hh = this.h[14];
|
||
var hl = this.h[15];
|
||
|
||
assert(this.k.length === W.length);
|
||
for (var i = 0; i < W.length; i += 2) {
|
||
var c0_hi = hh;
|
||
var c0_lo = hl;
|
||
var c1_hi = s1_512_hi(eh, el);
|
||
var c1_lo = s1_512_lo(eh, el);
|
||
var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
|
||
var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
|
||
var c3_hi = this.k[i];
|
||
var c3_lo = this.k[i + 1];
|
||
var c4_hi = W[i];
|
||
var c4_lo = W[i + 1];
|
||
|
||
var T1_hi = sum64_5_hi(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo,
|
||
c4_hi, c4_lo);
|
||
var T1_lo = sum64_5_lo(
|
||
c0_hi, c0_lo,
|
||
c1_hi, c1_lo,
|
||
c2_hi, c2_lo,
|
||
c3_hi, c3_lo,
|
||
c4_hi, c4_lo);
|
||
|
||
c0_hi = s0_512_hi(ah, al);
|
||
c0_lo = s0_512_lo(ah, al);
|
||
c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
|
||
c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
|
||
|
||
var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
|
||
var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
|
||
|
||
hh = gh;
|
||
hl = gl;
|
||
|
||
gh = fh;
|
||
gl = fl;
|
||
|
||
fh = eh;
|
||
fl = el;
|
||
|
||
eh = sum64_hi(dh, dl, T1_hi, T1_lo);
|
||
el = sum64_lo(dl, dl, T1_hi, T1_lo);
|
||
|
||
dh = ch;
|
||
dl = cl;
|
||
|
||
ch = bh;
|
||
cl = bl;
|
||
|
||
bh = ah;
|
||
bl = al;
|
||
|
||
ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
|
||
al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
|
||
}
|
||
|
||
sum64(this.h, 0, ah, al);
|
||
sum64(this.h, 2, bh, bl);
|
||
sum64(this.h, 4, ch, cl);
|
||
sum64(this.h, 6, dh, dl);
|
||
sum64(this.h, 8, eh, el);
|
||
sum64(this.h, 10, fh, fl);
|
||
sum64(this.h, 12, gh, gl);
|
||
sum64(this.h, 14, hh, hl);
|
||
};
|
||
|
||
SHA512.prototype._digest = function digest(enc) {
|
||
if (enc === 'hex')
|
||
return utils.toHex32(this.h, 'big');
|
||
else
|
||
return utils.split32(this.h, 'big');
|
||
};
|
||
|
||
function ch64_hi(xh, xl, yh, yl, zh) {
|
||
var r = (xh & yh) ^ ((~xh) & zh);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function ch64_lo(xh, xl, yh, yl, zh, zl) {
|
||
var r = (xl & yl) ^ ((~xl) & zl);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function maj64_hi(xh, xl, yh, yl, zh) {
|
||
var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function maj64_lo(xh, xl, yh, yl, zh, zl) {
|
||
var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s0_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 28);
|
||
var c1_hi = rotr64_hi(xl, xh, 2); // 34
|
||
var c2_hi = rotr64_hi(xl, xh, 7); // 39
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s0_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 28);
|
||
var c1_lo = rotr64_lo(xl, xh, 2); // 34
|
||
var c2_lo = rotr64_lo(xl, xh, 7); // 39
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s1_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 14);
|
||
var c1_hi = rotr64_hi(xh, xl, 18);
|
||
var c2_hi = rotr64_hi(xl, xh, 9); // 41
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function s1_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 14);
|
||
var c1_lo = rotr64_lo(xh, xl, 18);
|
||
var c2_lo = rotr64_lo(xl, xh, 9); // 41
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g0_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 1);
|
||
var c1_hi = rotr64_hi(xh, xl, 8);
|
||
var c2_hi = shr64_hi(xh, xl, 7);
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g0_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 1);
|
||
var c1_lo = rotr64_lo(xh, xl, 8);
|
||
var c2_lo = shr64_lo(xh, xl, 7);
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g1_512_hi(xh, xl) {
|
||
var c0_hi = rotr64_hi(xh, xl, 19);
|
||
var c1_hi = rotr64_hi(xl, xh, 29); // 61
|
||
var c2_hi = shr64_hi(xh, xl, 6);
|
||
|
||
var r = c0_hi ^ c1_hi ^ c2_hi;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
function g1_512_lo(xh, xl) {
|
||
var c0_lo = rotr64_lo(xh, xl, 19);
|
||
var c1_lo = rotr64_lo(xl, xh, 29); // 61
|
||
var c2_lo = shr64_lo(xh, xl, 6);
|
||
|
||
var r = c0_lo ^ c1_lo ^ c2_lo;
|
||
if (r < 0)
|
||
r += 0x100000000;
|
||
return r;
|
||
}
|
||
|
||
},{"../common":40,"../utils":50,"minimalistic-assert":53}],49:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var utils = require('../utils');
|
||
var rotr32 = utils.rotr32;
|
||
|
||
function ft_1(s, x, y, z) {
|
||
if (s === 0)
|
||
return ch32(x, y, z);
|
||
if (s === 1 || s === 3)
|
||
return p32(x, y, z);
|
||
if (s === 2)
|
||
return maj32(x, y, z);
|
||
}
|
||
exports.ft_1 = ft_1;
|
||
|
||
function ch32(x, y, z) {
|
||
return (x & y) ^ ((~x) & z);
|
||
}
|
||
exports.ch32 = ch32;
|
||
|
||
function maj32(x, y, z) {
|
||
return (x & y) ^ (x & z) ^ (y & z);
|
||
}
|
||
exports.maj32 = maj32;
|
||
|
||
function p32(x, y, z) {
|
||
return x ^ y ^ z;
|
||
}
|
||
exports.p32 = p32;
|
||
|
||
function s0_256(x) {
|
||
return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
|
||
}
|
||
exports.s0_256 = s0_256;
|
||
|
||
function s1_256(x) {
|
||
return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
|
||
}
|
||
exports.s1_256 = s1_256;
|
||
|
||
function g0_256(x) {
|
||
return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
|
||
}
|
||
exports.g0_256 = g0_256;
|
||
|
||
function g1_256(x) {
|
||
return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
|
||
}
|
||
exports.g1_256 = g1_256;
|
||
|
||
},{"../utils":50}],50:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var assert = require('minimalistic-assert');
|
||
var inherits = require('inherits');
|
||
|
||
exports.inherits = inherits;
|
||
|
||
function toArray(msg, enc) {
|
||
if (Array.isArray(msg))
|
||
return msg.slice();
|
||
if (!msg)
|
||
return [];
|
||
var res = [];
|
||
if (typeof msg === 'string') {
|
||
if (!enc) {
|
||
for (var i = 0; i < msg.length; i++) {
|
||
var c = msg.charCodeAt(i);
|
||
var hi = c >> 8;
|
||
var lo = c & 0xff;
|
||
if (hi)
|
||
res.push(hi, lo);
|
||
else
|
||
res.push(lo);
|
||
}
|
||
} else if (enc === 'hex') {
|
||
msg = msg.replace(/[^a-z0-9]+/ig, '');
|
||
if (msg.length % 2 !== 0)
|
||
msg = '0' + msg;
|
||
for (i = 0; i < msg.length; i += 2)
|
||
res.push(parseInt(msg[i] + msg[i + 1], 16));
|
||
}
|
||
} else {
|
||
for (i = 0; i < msg.length; i++)
|
||
res[i] = msg[i] | 0;
|
||
}
|
||
return res;
|
||
}
|
||
exports.toArray = toArray;
|
||
|
||
function toHex(msg) {
|
||
var res = '';
|
||
for (var i = 0; i < msg.length; i++)
|
||
res += zero2(msg[i].toString(16));
|
||
return res;
|
||
}
|
||
exports.toHex = toHex;
|
||
|
||
function htonl(w) {
|
||
var res = (w >>> 24) |
|
||
((w >>> 8) & 0xff00) |
|
||
((w << 8) & 0xff0000) |
|
||
((w & 0xff) << 24);
|
||
return res >>> 0;
|
||
}
|
||
exports.htonl = htonl;
|
||
|
||
function toHex32(msg, endian) {
|
||
var res = '';
|
||
for (var i = 0; i < msg.length; i++) {
|
||
var w = msg[i];
|
||
if (endian === 'little')
|
||
w = htonl(w);
|
||
res += zero8(w.toString(16));
|
||
}
|
||
return res;
|
||
}
|
||
exports.toHex32 = toHex32;
|
||
|
||
function zero2(word) {
|
||
if (word.length === 1)
|
||
return '0' + word;
|
||
else
|
||
return word;
|
||
}
|
||
exports.zero2 = zero2;
|
||
|
||
function zero8(word) {
|
||
if (word.length === 7)
|
||
return '0' + word;
|
||
else if (word.length === 6)
|
||
return '00' + word;
|
||
else if (word.length === 5)
|
||
return '000' + word;
|
||
else if (word.length === 4)
|
||
return '0000' + word;
|
||
else if (word.length === 3)
|
||
return '00000' + word;
|
||
else if (word.length === 2)
|
||
return '000000' + word;
|
||
else if (word.length === 1)
|
||
return '0000000' + word;
|
||
else
|
||
return word;
|
||
}
|
||
exports.zero8 = zero8;
|
||
|
||
function join32(msg, start, end, endian) {
|
||
var len = end - start;
|
||
assert(len % 4 === 0);
|
||
var res = new Array(len / 4);
|
||
for (var i = 0, k = start; i < res.length; i++, k += 4) {
|
||
var w;
|
||
if (endian === 'big')
|
||
w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
|
||
else
|
||
w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
|
||
res[i] = w >>> 0;
|
||
}
|
||
return res;
|
||
}
|
||
exports.join32 = join32;
|
||
|
||
function split32(msg, endian) {
|
||
var res = new Array(msg.length * 4);
|
||
for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
|
||
var m = msg[i];
|
||
if (endian === 'big') {
|
||
res[k] = m >>> 24;
|
||
res[k + 1] = (m >>> 16) & 0xff;
|
||
res[k + 2] = (m >>> 8) & 0xff;
|
||
res[k + 3] = m & 0xff;
|
||
} else {
|
||
res[k + 3] = m >>> 24;
|
||
res[k + 2] = (m >>> 16) & 0xff;
|
||
res[k + 1] = (m >>> 8) & 0xff;
|
||
res[k] = m & 0xff;
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
exports.split32 = split32;
|
||
|
||
function rotr32(w, b) {
|
||
return (w >>> b) | (w << (32 - b));
|
||
}
|
||
exports.rotr32 = rotr32;
|
||
|
||
function rotl32(w, b) {
|
||
return (w << b) | (w >>> (32 - b));
|
||
}
|
||
exports.rotl32 = rotl32;
|
||
|
||
function sum32(a, b) {
|
||
return (a + b) >>> 0;
|
||
}
|
||
exports.sum32 = sum32;
|
||
|
||
function sum32_3(a, b, c) {
|
||
return (a + b + c) >>> 0;
|
||
}
|
||
exports.sum32_3 = sum32_3;
|
||
|
||
function sum32_4(a, b, c, d) {
|
||
return (a + b + c + d) >>> 0;
|
||
}
|
||
exports.sum32_4 = sum32_4;
|
||
|
||
function sum32_5(a, b, c, d, e) {
|
||
return (a + b + c + d + e) >>> 0;
|
||
}
|
||
exports.sum32_5 = sum32_5;
|
||
|
||
function sum64(buf, pos, ah, al) {
|
||
var bh = buf[pos];
|
||
var bl = buf[pos + 1];
|
||
|
||
var lo = (al + bl) >>> 0;
|
||
var hi = (lo < al ? 1 : 0) + ah + bh;
|
||
buf[pos] = hi >>> 0;
|
||
buf[pos + 1] = lo;
|
||
}
|
||
exports.sum64 = sum64;
|
||
|
||
function sum64_hi(ah, al, bh, bl) {
|
||
var lo = (al + bl) >>> 0;
|
||
var hi = (lo < al ? 1 : 0) + ah + bh;
|
||
return hi >>> 0;
|
||
}
|
||
exports.sum64_hi = sum64_hi;
|
||
|
||
function sum64_lo(ah, al, bh, bl) {
|
||
var lo = al + bl;
|
||
return lo >>> 0;
|
||
}
|
||
exports.sum64_lo = sum64_lo;
|
||
|
||
function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
|
||
var carry = 0;
|
||
var lo = al;
|
||
lo = (lo + bl) >>> 0;
|
||
carry += lo < al ? 1 : 0;
|
||
lo = (lo + cl) >>> 0;
|
||
carry += lo < cl ? 1 : 0;
|
||
lo = (lo + dl) >>> 0;
|
||
carry += lo < dl ? 1 : 0;
|
||
|
||
var hi = ah + bh + ch + dh + carry;
|
||
return hi >>> 0;
|
||
}
|
||
exports.sum64_4_hi = sum64_4_hi;
|
||
|
||
function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
|
||
var lo = al + bl + cl + dl;
|
||
return lo >>> 0;
|
||
}
|
||
exports.sum64_4_lo = sum64_4_lo;
|
||
|
||
function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
|
||
var carry = 0;
|
||
var lo = al;
|
||
lo = (lo + bl) >>> 0;
|
||
carry += lo < al ? 1 : 0;
|
||
lo = (lo + cl) >>> 0;
|
||
carry += lo < cl ? 1 : 0;
|
||
lo = (lo + dl) >>> 0;
|
||
carry += lo < dl ? 1 : 0;
|
||
lo = (lo + el) >>> 0;
|
||
carry += lo < el ? 1 : 0;
|
||
|
||
var hi = ah + bh + ch + dh + eh + carry;
|
||
return hi >>> 0;
|
||
}
|
||
exports.sum64_5_hi = sum64_5_hi;
|
||
|
||
function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
|
||
var lo = al + bl + cl + dl + el;
|
||
|
||
return lo >>> 0;
|
||
}
|
||
exports.sum64_5_lo = sum64_5_lo;
|
||
|
||
function rotr64_hi(ah, al, num) {
|
||
var r = (al << (32 - num)) | (ah >>> num);
|
||
return r >>> 0;
|
||
}
|
||
exports.rotr64_hi = rotr64_hi;
|
||
|
||
function rotr64_lo(ah, al, num) {
|
||
var r = (ah << (32 - num)) | (al >>> num);
|
||
return r >>> 0;
|
||
}
|
||
exports.rotr64_lo = rotr64_lo;
|
||
|
||
function shr64_hi(ah, al, num) {
|
||
return ah >>> num;
|
||
}
|
||
exports.shr64_hi = shr64_hi;
|
||
|
||
function shr64_lo(ah, al, num) {
|
||
var r = (ah << (32 - num)) | (al >>> num);
|
||
return r >>> 0;
|
||
}
|
||
exports.shr64_lo = shr64_lo;
|
||
|
||
},{"inherits":51,"minimalistic-assert":53}],51:[function(require,module,exports){
|
||
if (typeof Object.create === 'function') {
|
||
// implementation from standard node.js 'util' module
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
ctor.prototype = Object.create(superCtor.prototype, {
|
||
constructor: {
|
||
value: ctor,
|
||
enumerable: false,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
});
|
||
};
|
||
} else {
|
||
// old school shim for old browsers
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
var TempCtor = function () {}
|
||
TempCtor.prototype = superCtor.prototype
|
||
ctor.prototype = new TempCtor()
|
||
ctor.prototype.constructor = ctor
|
||
}
|
||
}
|
||
|
||
},{}],52:[function(require,module,exports){
|
||
(function (process,global){
|
||
/**
|
||
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
||
*
|
||
* @version 0.5.7
|
||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||
* @copyright Chen, Yi-Cyuan 2015-2016
|
||
* @license MIT
|
||
*/
|
||
/*jslint bitwise: true */
|
||
(function () {
|
||
'use strict';
|
||
|
||
var root = typeof window === 'object' ? window : {};
|
||
var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
|
||
if (NODE_JS) {
|
||
root = global;
|
||
}
|
||
var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && typeof module === 'object' && module.exports;
|
||
var HEX_CHARS = '0123456789abcdef'.split('');
|
||
var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
|
||
var KECCAK_PADDING = [1, 256, 65536, 16777216];
|
||
var PADDING = [6, 1536, 393216, 100663296];
|
||
var SHIFT = [0, 8, 16, 24];
|
||
var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649,
|
||
0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0,
|
||
2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771,
|
||
2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648,
|
||
2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
|
||
var BITS = [224, 256, 384, 512];
|
||
var SHAKE_BITS = [128, 256];
|
||
var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array'];
|
||
|
||
var createOutputMethod = function (bits, padding, outputType) {
|
||
return function (message) {
|
||
return new Keccak(bits, padding, bits).update(message)[outputType]();
|
||
};
|
||
};
|
||
|
||
var createShakeOutputMethod = function (bits, padding, outputType) {
|
||
return function (message, outputBits) {
|
||
return new Keccak(bits, padding, outputBits).update(message)[outputType]();
|
||
};
|
||
};
|
||
|
||
var createMethod = function (bits, padding) {
|
||
var method = createOutputMethod(bits, padding, 'hex');
|
||
method.create = function () {
|
||
return new Keccak(bits, padding, bits);
|
||
};
|
||
method.update = function (message) {
|
||
return method.create().update(message);
|
||
};
|
||
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
||
var type = OUTPUT_TYPES[i];
|
||
method[type] = createOutputMethod(bits, padding, type);
|
||
}
|
||
return method;
|
||
};
|
||
|
||
var createShakeMethod = function (bits, padding) {
|
||
var method = createShakeOutputMethod(bits, padding, 'hex');
|
||
method.create = function (outputBits) {
|
||
return new Keccak(bits, padding, outputBits);
|
||
};
|
||
method.update = function (message, outputBits) {
|
||
return method.create(outputBits).update(message);
|
||
};
|
||
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
||
var type = OUTPUT_TYPES[i];
|
||
method[type] = createShakeOutputMethod(bits, padding, type);
|
||
}
|
||
return method;
|
||
};
|
||
|
||
var algorithms = [
|
||
{name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod},
|
||
{name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod},
|
||
{name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod}
|
||
];
|
||
|
||
var methods = {}, methodNames = [];
|
||
|
||
for (var i = 0; i < algorithms.length; ++i) {
|
||
var algorithm = algorithms[i];
|
||
var bits = algorithm.bits;
|
||
for (var j = 0; j < bits.length; ++j) {
|
||
var methodName = algorithm.name +'_' + bits[j];
|
||
methodNames.push(methodName);
|
||
methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding);
|
||
}
|
||
}
|
||
|
||
function Keccak(bits, padding, outputBits) {
|
||
this.blocks = [];
|
||
this.s = [];
|
||
this.padding = padding;
|
||
this.outputBits = outputBits;
|
||
this.reset = true;
|
||
this.block = 0;
|
||
this.start = 0;
|
||
this.blockCount = (1600 - (bits << 1)) >> 5;
|
||
this.byteCount = this.blockCount << 2;
|
||
this.outputBlocks = outputBits >> 5;
|
||
this.extraBytes = (outputBits & 31) >> 3;
|
||
|
||
for (var i = 0; i < 50; ++i) {
|
||
this.s[i] = 0;
|
||
}
|
||
}
|
||
|
||
Keccak.prototype.update = function (message) {
|
||
var notString = typeof message !== 'string';
|
||
if (notString && message.constructor === ArrayBuffer) {
|
||
message = new Uint8Array(message);
|
||
}
|
||
var length = message.length, blocks = this.blocks, byteCount = this.byteCount,
|
||
blockCount = this.blockCount, index = 0, s = this.s, i, code;
|
||
|
||
while (index < length) {
|
||
if (this.reset) {
|
||
this.reset = false;
|
||
blocks[0] = this.block;
|
||
for (i = 1; i < blockCount + 1; ++i) {
|
||
blocks[i] = 0;
|
||
}
|
||
}
|
||
if (notString) {
|
||
for (i = this.start; index < length && i < byteCount; ++index) {
|
||
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
|
||
}
|
||
} else {
|
||
for (i = this.start; index < length && i < byteCount; ++index) {
|
||
code = message.charCodeAt(index);
|
||
if (code < 0x80) {
|
||
blocks[i >> 2] |= code << SHIFT[i++ & 3];
|
||
} else if (code < 0x800) {
|
||
blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
|
||
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
|
||
} else if (code < 0xd800 || code >= 0xe000) {
|
||
blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
|
||
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
|
||
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
|
||
} else {
|
||
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
|
||
blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
|
||
blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
|
||
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
|
||
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
|
||
}
|
||
}
|
||
}
|
||
this.lastByteIndex = i;
|
||
if (i >= byteCount) {
|
||
this.start = i - byteCount;
|
||
this.block = blocks[blockCount];
|
||
for (i = 0; i < blockCount; ++i) {
|
||
s[i] ^= blocks[i];
|
||
}
|
||
f(s);
|
||
this.reset = true;
|
||
} else {
|
||
this.start = i;
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
Keccak.prototype.finalize = function () {
|
||
var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s;
|
||
blocks[i >> 2] |= this.padding[i & 3];
|
||
if (this.lastByteIndex === this.byteCount) {
|
||
blocks[0] = blocks[blockCount];
|
||
for (i = 1; i < blockCount + 1; ++i) {
|
||
blocks[i] = 0;
|
||
}
|
||
}
|
||
blocks[blockCount - 1] |= 0x80000000;
|
||
for (i = 0; i < blockCount; ++i) {
|
||
s[i] ^= blocks[i];
|
||
}
|
||
f(s);
|
||
};
|
||
|
||
Keccak.prototype.toString = Keccak.prototype.hex = function () {
|
||
this.finalize();
|
||
|
||
var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
|
||
extraBytes = this.extraBytes, i = 0, j = 0;
|
||
var hex = '', block;
|
||
while (j < outputBlocks) {
|
||
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
|
||
block = s[i];
|
||
hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] +
|
||
HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] +
|
||
HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] +
|
||
HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F];
|
||
}
|
||
if (j % blockCount === 0) {
|
||
f(s);
|
||
i = 0;
|
||
}
|
||
}
|
||
if (extraBytes) {
|
||
block = s[i];
|
||
if (extraBytes > 0) {
|
||
hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F];
|
||
}
|
||
if (extraBytes > 1) {
|
||
hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F];
|
||
}
|
||
if (extraBytes > 2) {
|
||
hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F];
|
||
}
|
||
}
|
||
return hex;
|
||
};
|
||
|
||
Keccak.prototype.arrayBuffer = function () {
|
||
this.finalize();
|
||
|
||
var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
|
||
extraBytes = this.extraBytes, i = 0, j = 0;
|
||
var bytes = this.outputBits >> 3;
|
||
var buffer;
|
||
if (extraBytes) {
|
||
buffer = new ArrayBuffer((outputBlocks + 1) << 2);
|
||
} else {
|
||
buffer = new ArrayBuffer(bytes);
|
||
}
|
||
var array = new Uint32Array(buffer);
|
||
while (j < outputBlocks) {
|
||
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
|
||
array[j] = s[i];
|
||
}
|
||
if (j % blockCount === 0) {
|
||
f(s);
|
||
}
|
||
}
|
||
if (extraBytes) {
|
||
array[i] = s[i];
|
||
buffer = buffer.slice(0, bytes);
|
||
}
|
||
return buffer;
|
||
};
|
||
|
||
Keccak.prototype.buffer = Keccak.prototype.arrayBuffer;
|
||
|
||
Keccak.prototype.digest = Keccak.prototype.array = function () {
|
||
this.finalize();
|
||
|
||
var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
|
||
extraBytes = this.extraBytes, i = 0, j = 0;
|
||
var array = [], offset, block;
|
||
while (j < outputBlocks) {
|
||
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
|
||
offset = j << 2;
|
||
block = s[i];
|
||
array[offset] = block & 0xFF;
|
||
array[offset + 1] = (block >> 8) & 0xFF;
|
||
array[offset + 2] = (block >> 16) & 0xFF;
|
||
array[offset + 3] = (block >> 24) & 0xFF;
|
||
}
|
||
if (j % blockCount === 0) {
|
||
f(s);
|
||
}
|
||
}
|
||
if (extraBytes) {
|
||
offset = j << 2;
|
||
block = s[i];
|
||
if (extraBytes > 0) {
|
||
array[offset] = block & 0xFF;
|
||
}
|
||
if (extraBytes > 1) {
|
||
array[offset + 1] = (block >> 8) & 0xFF;
|
||
}
|
||
if (extraBytes > 2) {
|
||
array[offset + 2] = (block >> 16) & 0xFF;
|
||
}
|
||
}
|
||
return array;
|
||
};
|
||
|
||
var f = function (s) {
|
||
var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
|
||
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17,
|
||
b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33,
|
||
b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49;
|
||
for (n = 0; n < 48; n += 2) {
|
||
c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40];
|
||
c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41];
|
||
c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42];
|
||
c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43];
|
||
c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44];
|
||
c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45];
|
||
c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46];
|
||
c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47];
|
||
c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48];
|
||
c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49];
|
||
|
||
h = c8 ^ ((c2 << 1) | (c3 >>> 31));
|
||
l = c9 ^ ((c3 << 1) | (c2 >>> 31));
|
||
s[0] ^= h;
|
||
s[1] ^= l;
|
||
s[10] ^= h;
|
||
s[11] ^= l;
|
||
s[20] ^= h;
|
||
s[21] ^= l;
|
||
s[30] ^= h;
|
||
s[31] ^= l;
|
||
s[40] ^= h;
|
||
s[41] ^= l;
|
||
h = c0 ^ ((c4 << 1) | (c5 >>> 31));
|
||
l = c1 ^ ((c5 << 1) | (c4 >>> 31));
|
||
s[2] ^= h;
|
||
s[3] ^= l;
|
||
s[12] ^= h;
|
||
s[13] ^= l;
|
||
s[22] ^= h;
|
||
s[23] ^= l;
|
||
s[32] ^= h;
|
||
s[33] ^= l;
|
||
s[42] ^= h;
|
||
s[43] ^= l;
|
||
h = c2 ^ ((c6 << 1) | (c7 >>> 31));
|
||
l = c3 ^ ((c7 << 1) | (c6 >>> 31));
|
||
s[4] ^= h;
|
||
s[5] ^= l;
|
||
s[14] ^= h;
|
||
s[15] ^= l;
|
||
s[24] ^= h;
|
||
s[25] ^= l;
|
||
s[34] ^= h;
|
||
s[35] ^= l;
|
||
s[44] ^= h;
|
||
s[45] ^= l;
|
||
h = c4 ^ ((c8 << 1) | (c9 >>> 31));
|
||
l = c5 ^ ((c9 << 1) | (c8 >>> 31));
|
||
s[6] ^= h;
|
||
s[7] ^= l;
|
||
s[16] ^= h;
|
||
s[17] ^= l;
|
||
s[26] ^= h;
|
||
s[27] ^= l;
|
||
s[36] ^= h;
|
||
s[37] ^= l;
|
||
s[46] ^= h;
|
||
s[47] ^= l;
|
||
h = c6 ^ ((c0 << 1) | (c1 >>> 31));
|
||
l = c7 ^ ((c1 << 1) | (c0 >>> 31));
|
||
s[8] ^= h;
|
||
s[9] ^= l;
|
||
s[18] ^= h;
|
||
s[19] ^= l;
|
||
s[28] ^= h;
|
||
s[29] ^= l;
|
||
s[38] ^= h;
|
||
s[39] ^= l;
|
||
s[48] ^= h;
|
||
s[49] ^= l;
|
||
|
||
b0 = s[0];
|
||
b1 = s[1];
|
||
b32 = (s[11] << 4) | (s[10] >>> 28);
|
||
b33 = (s[10] << 4) | (s[11] >>> 28);
|
||
b14 = (s[20] << 3) | (s[21] >>> 29);
|
||
b15 = (s[21] << 3) | (s[20] >>> 29);
|
||
b46 = (s[31] << 9) | (s[30] >>> 23);
|
||
b47 = (s[30] << 9) | (s[31] >>> 23);
|
||
b28 = (s[40] << 18) | (s[41] >>> 14);
|
||
b29 = (s[41] << 18) | (s[40] >>> 14);
|
||
b20 = (s[2] << 1) | (s[3] >>> 31);
|
||
b21 = (s[3] << 1) | (s[2] >>> 31);
|
||
b2 = (s[13] << 12) | (s[12] >>> 20);
|
||
b3 = (s[12] << 12) | (s[13] >>> 20);
|
||
b34 = (s[22] << 10) | (s[23] >>> 22);
|
||
b35 = (s[23] << 10) | (s[22] >>> 22);
|
||
b16 = (s[33] << 13) | (s[32] >>> 19);
|
||
b17 = (s[32] << 13) | (s[33] >>> 19);
|
||
b48 = (s[42] << 2) | (s[43] >>> 30);
|
||
b49 = (s[43] << 2) | (s[42] >>> 30);
|
||
b40 = (s[5] << 30) | (s[4] >>> 2);
|
||
b41 = (s[4] << 30) | (s[5] >>> 2);
|
||
b22 = (s[14] << 6) | (s[15] >>> 26);
|
||
b23 = (s[15] << 6) | (s[14] >>> 26);
|
||
b4 = (s[25] << 11) | (s[24] >>> 21);
|
||
b5 = (s[24] << 11) | (s[25] >>> 21);
|
||
b36 = (s[34] << 15) | (s[35] >>> 17);
|
||
b37 = (s[35] << 15) | (s[34] >>> 17);
|
||
b18 = (s[45] << 29) | (s[44] >>> 3);
|
||
b19 = (s[44] << 29) | (s[45] >>> 3);
|
||
b10 = (s[6] << 28) | (s[7] >>> 4);
|
||
b11 = (s[7] << 28) | (s[6] >>> 4);
|
||
b42 = (s[17] << 23) | (s[16] >>> 9);
|
||
b43 = (s[16] << 23) | (s[17] >>> 9);
|
||
b24 = (s[26] << 25) | (s[27] >>> 7);
|
||
b25 = (s[27] << 25) | (s[26] >>> 7);
|
||
b6 = (s[36] << 21) | (s[37] >>> 11);
|
||
b7 = (s[37] << 21) | (s[36] >>> 11);
|
||
b38 = (s[47] << 24) | (s[46] >>> 8);
|
||
b39 = (s[46] << 24) | (s[47] >>> 8);
|
||
b30 = (s[8] << 27) | (s[9] >>> 5);
|
||
b31 = (s[9] << 27) | (s[8] >>> 5);
|
||
b12 = (s[18] << 20) | (s[19] >>> 12);
|
||
b13 = (s[19] << 20) | (s[18] >>> 12);
|
||
b44 = (s[29] << 7) | (s[28] >>> 25);
|
||
b45 = (s[28] << 7) | (s[29] >>> 25);
|
||
b26 = (s[38] << 8) | (s[39] >>> 24);
|
||
b27 = (s[39] << 8) | (s[38] >>> 24);
|
||
b8 = (s[48] << 14) | (s[49] >>> 18);
|
||
b9 = (s[49] << 14) | (s[48] >>> 18);
|
||
|
||
s[0] = b0 ^ (~b2 & b4);
|
||
s[1] = b1 ^ (~b3 & b5);
|
||
s[10] = b10 ^ (~b12 & b14);
|
||
s[11] = b11 ^ (~b13 & b15);
|
||
s[20] = b20 ^ (~b22 & b24);
|
||
s[21] = b21 ^ (~b23 & b25);
|
||
s[30] = b30 ^ (~b32 & b34);
|
||
s[31] = b31 ^ (~b33 & b35);
|
||
s[40] = b40 ^ (~b42 & b44);
|
||
s[41] = b41 ^ (~b43 & b45);
|
||
s[2] = b2 ^ (~b4 & b6);
|
||
s[3] = b3 ^ (~b5 & b7);
|
||
s[12] = b12 ^ (~b14 & b16);
|
||
s[13] = b13 ^ (~b15 & b17);
|
||
s[22] = b22 ^ (~b24 & b26);
|
||
s[23] = b23 ^ (~b25 & b27);
|
||
s[32] = b32 ^ (~b34 & b36);
|
||
s[33] = b33 ^ (~b35 & b37);
|
||
s[42] = b42 ^ (~b44 & b46);
|
||
s[43] = b43 ^ (~b45 & b47);
|
||
s[4] = b4 ^ (~b6 & b8);
|
||
s[5] = b5 ^ (~b7 & b9);
|
||
s[14] = b14 ^ (~b16 & b18);
|
||
s[15] = b15 ^ (~b17 & b19);
|
||
s[24] = b24 ^ (~b26 & b28);
|
||
s[25] = b25 ^ (~b27 & b29);
|
||
s[34] = b34 ^ (~b36 & b38);
|
||
s[35] = b35 ^ (~b37 & b39);
|
||
s[44] = b44 ^ (~b46 & b48);
|
||
s[45] = b45 ^ (~b47 & b49);
|
||
s[6] = b6 ^ (~b8 & b0);
|
||
s[7] = b7 ^ (~b9 & b1);
|
||
s[16] = b16 ^ (~b18 & b10);
|
||
s[17] = b17 ^ (~b19 & b11);
|
||
s[26] = b26 ^ (~b28 & b20);
|
||
s[27] = b27 ^ (~b29 & b21);
|
||
s[36] = b36 ^ (~b38 & b30);
|
||
s[37] = b37 ^ (~b39 & b31);
|
||
s[46] = b46 ^ (~b48 & b40);
|
||
s[47] = b47 ^ (~b49 & b41);
|
||
s[8] = b8 ^ (~b0 & b2);
|
||
s[9] = b9 ^ (~b1 & b3);
|
||
s[18] = b18 ^ (~b10 & b12);
|
||
s[19] = b19 ^ (~b11 & b13);
|
||
s[28] = b28 ^ (~b20 & b22);
|
||
s[29] = b29 ^ (~b21 & b23);
|
||
s[38] = b38 ^ (~b30 & b32);
|
||
s[39] = b39 ^ (~b31 & b33);
|
||
s[48] = b48 ^ (~b40 & b42);
|
||
s[49] = b49 ^ (~b41 & b43);
|
||
|
||
s[0] ^= RC[n];
|
||
s[1] ^= RC[n + 1];
|
||
}
|
||
};
|
||
|
||
if (COMMON_JS) {
|
||
module.exports = methods;
|
||
} else {
|
||
for (var i = 0; i < methodNames.length; ++i) {
|
||
root[methodNames[i]] = methods[methodNames[i]];
|
||
}
|
||
}
|
||
})();
|
||
|
||
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"_process":54}],53:[function(require,module,exports){
|
||
module.exports = assert;
|
||
|
||
function assert(val, msg) {
|
||
if (!val)
|
||
throw new Error(msg || 'Assertion failed');
|
||
}
|
||
|
||
assert.equal = function assertEqual(l, r, msg) {
|
||
if (l != r)
|
||
throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
|
||
};
|
||
|
||
},{}],54:[function(require,module,exports){
|
||
arguments[4][17][0].apply(exports,arguments)
|
||
},{"dup":17}],55:[function(require,module,exports){
|
||
"use strict";
|
||
|
||
(function(root) {
|
||
var MAX_VALUE = 0x7fffffff;
|
||
|
||
// The SHA256 and PBKDF2 implementation are from scrypt-async-js:
|
||
// See: https://github.com/dchest/scrypt-async-js
|
||
function SHA256(m) {
|
||
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
|
||
];
|
||
|
||
var h0 = 0x6a09e667, h1 = 0xbb67ae85, h2 = 0x3c6ef372, h3 = 0xa54ff53a;
|
||
var h4 = 0x510e527f, h5 = 0x9b05688c, h6 = 0x1f83d9ab, h7 = 0x5be0cd19;
|
||
var w = new Array(64);
|
||
|
||
function blocks(p) {
|
||
var off = 0, len = p.length;
|
||
while (len >= 64) {
|
||
var a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7, u, i, j, t1, t2;
|
||
|
||
for (i = 0; i < 16; i++) {
|
||
j = off + i*4;
|
||
w[i] = ((p[j] & 0xff)<<24) | ((p[j+1] & 0xff)<<16) |
|
||
((p[j+2] & 0xff)<<8) | (p[j+3] & 0xff);
|
||
}
|
||
|
||
for (i = 16; i < 64; i++) {
|
||
u = w[i-2];
|
||
t1 = ((u>>>17) | (u<<(32-17))) ^ ((u>>>19) | (u<<(32-19))) ^ (u>>>10);
|
||
|
||
u = w[i-15];
|
||
t2 = ((u>>>7) | (u<<(32-7))) ^ ((u>>>18) | (u<<(32-18))) ^ (u>>>3);
|
||
|
||
w[i] = (((t1 + w[i-7]) | 0) + ((t2 + w[i-16]) | 0)) | 0;
|
||
}
|
||
|
||
for (i = 0; i < 64; i++) {
|
||
t1 = ((((((e>>>6) | (e<<(32-6))) ^ ((e>>>11) | (e<<(32-11))) ^
|
||
((e>>>25) | (e<<(32-25)))) + ((e & f) ^ (~e & g))) | 0) +
|
||
((h + ((K[i] + w[i]) | 0)) | 0)) | 0;
|
||
|
||
t2 = ((((a>>>2) | (a<<(32-2))) ^ ((a>>>13) | (a<<(32-13))) ^
|
||
((a>>>22) | (a<<(32-22)))) + ((a & b) ^ (a & c) ^ (b & c))) | 0;
|
||
|
||
h = g;
|
||
g = f;
|
||
f = e;
|
||
e = (d + t1) | 0;
|
||
d = c;
|
||
c = b;
|
||
b = a;
|
||
a = (t1 + t2) | 0;
|
||
}
|
||
|
||
h0 = (h0 + a) | 0;
|
||
h1 = (h1 + b) | 0;
|
||
h2 = (h2 + c) | 0;
|
||
h3 = (h3 + d) | 0;
|
||
h4 = (h4 + e) | 0;
|
||
h5 = (h5 + f) | 0;
|
||
h6 = (h6 + g) | 0;
|
||
h7 = (h7 + h) | 0;
|
||
|
||
off += 64;
|
||
len -= 64;
|
||
}
|
||
}
|
||
|
||
blocks(m);
|
||
|
||
var i, bytesLeft = m.length % 64,
|
||
bitLenHi = (m.length / 0x20000000) | 0,
|
||
bitLenLo = m.length << 3,
|
||
numZeros = (bytesLeft < 56) ? 56 : 120,
|
||
p = m.slice(m.length - bytesLeft, m.length);
|
||
|
||
p.push(0x80);
|
||
for (i = bytesLeft + 1; i < numZeros; i++) { p.push(0); }
|
||
p.push((bitLenHi>>>24) & 0xff);
|
||
p.push((bitLenHi>>>16) & 0xff);
|
||
p.push((bitLenHi>>>8) & 0xff);
|
||
p.push((bitLenHi>>>0) & 0xff);
|
||
p.push((bitLenLo>>>24) & 0xff);
|
||
p.push((bitLenLo>>>16) & 0xff);
|
||
p.push((bitLenLo>>>8) & 0xff);
|
||
p.push((bitLenLo>>>0) & 0xff);
|
||
|
||
blocks(p);
|
||
|
||
return [
|
||
(h0>>>24) & 0xff, (h0>>>16) & 0xff, (h0>>>8) & 0xff, (h0>>>0) & 0xff,
|
||
(h1>>>24) & 0xff, (h1>>>16) & 0xff, (h1>>>8) & 0xff, (h1>>>0) & 0xff,
|
||
(h2>>>24) & 0xff, (h2>>>16) & 0xff, (h2>>>8) & 0xff, (h2>>>0) & 0xff,
|
||
(h3>>>24) & 0xff, (h3>>>16) & 0xff, (h3>>>8) & 0xff, (h3>>>0) & 0xff,
|
||
(h4>>>24) & 0xff, (h4>>>16) & 0xff, (h4>>>8) & 0xff, (h4>>>0) & 0xff,
|
||
(h5>>>24) & 0xff, (h5>>>16) & 0xff, (h5>>>8) & 0xff, (h5>>>0) & 0xff,
|
||
(h6>>>24) & 0xff, (h6>>>16) & 0xff, (h6>>>8) & 0xff, (h6>>>0) & 0xff,
|
||
(h7>>>24) & 0xff, (h7>>>16) & 0xff, (h7>>>8) & 0xff, (h7>>>0) & 0xff
|
||
];
|
||
}
|
||
|
||
function PBKDF2_HMAC_SHA256_OneIter(password, salt, dkLen) {
|
||
// compress password if it's longer than hash block length
|
||
password = password.length <= 64 ? password : SHA256(password);
|
||
|
||
var i;
|
||
var innerLen = 64 + salt.length + 4;
|
||
var inner = new Array(innerLen);
|
||
var outerKey = new Array(64);
|
||
var dk = [];
|
||
|
||
// inner = (password ^ ipad) || salt || counter
|
||
for (i = 0; i < 64; i++) inner[i] = 0x36;
|
||
for (i = 0; i < password.length; i++) inner[i] ^= password[i];
|
||
for (i = 0; i < salt.length; i++) inner[64+i] = salt[i];
|
||
for (i = innerLen - 4; i < innerLen; i++) inner[i] = 0;
|
||
|
||
// outerKey = password ^ opad
|
||
for (i = 0; i < 64; i++) outerKey[i] = 0x5c;
|
||
for (i = 0; i < password.length; i++) outerKey[i] ^= password[i];
|
||
|
||
// increments counter inside inner
|
||
function incrementCounter() {
|
||
for (var i = innerLen-1; i >= innerLen-4; i--) {
|
||
inner[i]++;
|
||
if (inner[i] <= 0xff) return;
|
||
inner[i] = 0;
|
||
}
|
||
}
|
||
|
||
// output blocks = SHA256(outerKey || SHA256(inner)) ...
|
||
while (dkLen >= 32) {
|
||
incrementCounter();
|
||
dk = dk.concat(SHA256(outerKey.concat(SHA256(inner))));
|
||
dkLen -= 32;
|
||
}
|
||
if (dkLen > 0) {
|
||
incrementCounter();
|
||
dk = dk.concat(SHA256(outerKey.concat(SHA256(inner))).slice(0, dkLen));
|
||
}
|
||
|
||
return dk;
|
||
}
|
||
|
||
// The following is an adaptation of scryptsy
|
||
// See: https://www.npmjs.com/package/scryptsy
|
||
function blockmix_salsa8(BY, Yi, r, x, _X) {
|
||
var i;
|
||
|
||
arraycopy(BY, (2 * r - 1) * 16, _X, 0, 16);
|
||
for (i = 0; i < 2 * r; i++) {
|
||
blockxor(BY, i * 16, _X, 16);
|
||
salsa20_8(_X, x);
|
||
arraycopy(_X, 0, BY, Yi + (i * 16), 16);
|
||
}
|
||
|
||
for (i = 0; i < r; i++) {
|
||
arraycopy(BY, Yi + (i * 2) * 16, BY, (i * 16), 16);
|
||
}
|
||
|
||
for (i = 0; i < r; i++) {
|
||
arraycopy(BY, Yi + (i * 2 + 1) * 16, BY, (i + r) * 16, 16);
|
||
}
|
||
}
|
||
|
||
function R(a, b) {
|
||
return (a << b) | (a >>> (32 - b));
|
||
}
|
||
|
||
function salsa20_8(B, x) {
|
||
arraycopy(B, 0, x, 0, 16);
|
||
|
||
for (var 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) {
|
||
B[i] += x[i];
|
||
}
|
||
}
|
||
|
||
// naive approach... going back to loop unrolling may yield additional performance
|
||
function blockxor(S, Si, D, len) {
|
||
for (var i = 0; i < len; i++) {
|
||
D[i] ^= S[Si + i]
|
||
}
|
||
}
|
||
|
||
function arraycopy(src, srcPos, dest, destPos, length) {
|
||
while (length--) {
|
||
dest[destPos++] = src[srcPos++];
|
||
}
|
||
}
|
||
|
||
function checkBufferish(o) {
|
||
if (!o || typeof(o.length) !== 'number') {
|
||
return false;
|
||
}
|
||
for (var i = 0; i < o.length; i++) {
|
||
if (typeof(o[i]) !== 'number') { return false; }
|
||
|
||
var v = parseInt(o[i]);
|
||
if (v != o[i] || v < 0 || v >= 256) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function ensureInteger(value, name) {
|
||
var intValue = parseInt(value);
|
||
if (value != intValue) { throw new Error('invalid ' + name); }
|
||
return intValue;
|
||
}
|
||
|
||
// N = Cpu cost, r = Memory cost, p = parallelization cost
|
||
// callback(error, progress, key)
|
||
function scrypt(password, salt, N, r, p, dkLen, callback) {
|
||
|
||
if (!callback) { throw new Error('missing callback'); }
|
||
|
||
N = ensureInteger(N, 'N');
|
||
r = ensureInteger(r, 'r');
|
||
p = ensureInteger(p, 'p');
|
||
|
||
dkLen = ensureInteger(dkLen, 'dkLen');
|
||
|
||
if (N === 0 || (N & (N - 1)) !== 0) { throw new Error('N must be power of 2'); }
|
||
|
||
if (N > MAX_VALUE / 128 / r) { throw new Error('N too large'); }
|
||
if (r > MAX_VALUE / 128 / p) { throw new Error('r too large'); }
|
||
|
||
if (!checkBufferish(password)) {
|
||
throw new Error('password must be an array or buffer');
|
||
}
|
||
|
||
if (!checkBufferish(salt)) {
|
||
throw new Error('salt must be an array or buffer');
|
||
}
|
||
|
||
var b = PBKDF2_HMAC_SHA256_OneIter(password, salt, p * 128 * r);
|
||
var B = new Uint32Array(p * 32 * r)
|
||
for (var i = 0; i < B.length; i++) {
|
||
var j = i * 4;
|
||
B[i] = ((b[j + 3] & 0xff) << 24) |
|
||
((b[j + 2] & 0xff) << 16) |
|
||
((b[j + 1] & 0xff) << 8) |
|
||
((b[j + 0] & 0xff) << 0);
|
||
}
|
||
|
||
var XY = new Uint32Array(64 * r);
|
||
var V = new Uint32Array(32 * r * N);
|
||
|
||
var Yi = 32 * r;
|
||
|
||
// scratch space
|
||
var x = new Uint32Array(16); // salsa20_8
|
||
var _X = new Uint32Array(16); // blockmix_salsa8
|
||
|
||
var totalOps = p * N * 2;
|
||
var currentOp = 0;
|
||
var lastPercent10 = null;
|
||
|
||
// Set this to true to abandon the scrypt on the next step
|
||
var stop = false;
|
||
|
||
// State information
|
||
var state = 0;
|
||
var i0 = 0, i1;
|
||
var Bi;
|
||
|
||
// How many blockmix_salsa8 can we do per step?
|
||
var limit = parseInt(1000 / r);
|
||
|
||
// Trick from scrypt-async; if there is a setImmediate shim in place, use it
|
||
var nextTick = (typeof(setImmediate) !== 'undefined') ? setImmediate : setTimeout;
|
||
|
||
// This is really all I changed; making scryptsy a state machine so we occasionally
|
||
// stop and give other evnts on the evnt loop a chance to run. ~RicMoo
|
||
var incrementalSMix = function() {
|
||
if (stop) {
|
||
return callback(new Error('cancelled'), currentOp / totalOps);
|
||
}
|
||
|
||
switch (state) {
|
||
case 0:
|
||
// for (var i = 0; i < p; i++)...
|
||
Bi = i0 * 32 * r;
|
||
|
||
arraycopy(B, Bi, XY, 0, Yi); // ROMix - 1
|
||
|
||
state = 1; // Move to ROMix 2
|
||
i1 = 0;
|
||
|
||
// Fall through
|
||
|
||
case 1:
|
||
|
||
// Run up to 1000 steps of the first inner smix loop
|
||
var steps = N - i1;
|
||
if (steps > limit) { steps = limit; }
|
||
for (var i = 0; i < steps; i++) { // ROMix - 2
|
||
arraycopy(XY, 0, V, (i1 + i) * Yi, Yi) // ROMix - 3
|
||
blockmix_salsa8(XY, Yi, r, x, _X); // ROMix - 4
|
||
}
|
||
|
||
// for (var i = 0; i < N; i++)
|
||
i1 += steps;
|
||
currentOp += steps;
|
||
|
||
// Call the callback with the progress (optionally stopping us)
|
||
var percent10 = parseInt(1000 * currentOp / totalOps);
|
||
if (percent10 !== lastPercent10) {
|
||
stop = callback(null, currentOp / totalOps);
|
||
if (stop) { break; }
|
||
lastPercent10 = percent10;
|
||
}
|
||
|
||
if (i1 < N) {
|
||
break;
|
||
}
|
||
|
||
i1 = 0; // Move to ROMix 6
|
||
state = 2;
|
||
|
||
// Fall through
|
||
|
||
case 2:
|
||
|
||
// Run up to 1000 steps of the second inner smix loop
|
||
var steps = N - i1;
|
||
if (steps > limit) { steps = limit; }
|
||
for (var i = 0; i < steps; i++) { // ROMix - 6
|
||
var offset = (2 * r - 1) * 16; // ROMix - 7
|
||
var j = XY[offset] & (N - 1);
|
||
blockxor(V, j * Yi, XY, Yi); // ROMix - 8 (inner)
|
||
blockmix_salsa8(XY, Yi, r, x, _X); // ROMix - 9 (outer)
|
||
}
|
||
|
||
// for (var i = 0; i < N; i++)...
|
||
i1 += steps;
|
||
currentOp += steps;
|
||
|
||
// Call the callback with the progress (optionally stopping us)
|
||
var percent10 = parseInt(1000 * currentOp / totalOps);
|
||
if (percent10 !== lastPercent10) {
|
||
stop = callback(null, currentOp / totalOps);
|
||
if (stop) { break; }
|
||
lastPercent10 = percent10;
|
||
}
|
||
|
||
if (i1 < N) {
|
||
break;
|
||
}
|
||
|
||
arraycopy(XY, 0, B, Bi, Yi); // ROMix - 10
|
||
|
||
// for (var i = 0; i < p; i++)...
|
||
i0++;
|
||
if (i0 < p) {
|
||
state = 0;
|
||
break;
|
||
}
|
||
|
||
b = [];
|
||
for (var i = 0; i < B.length; i++) {
|
||
b.push((B[i] >> 0) & 0xff);
|
||
b.push((B[i] >> 8) & 0xff);
|
||
b.push((B[i] >> 16) & 0xff);
|
||
b.push((B[i] >> 24) & 0xff);
|
||
}
|
||
|
||
var derivedKey = PBKDF2_HMAC_SHA256_OneIter(password, b, dkLen);
|
||
|
||
// Done; don't break (which would reschedule)
|
||
return callback(null, 1.0, derivedKey);
|
||
}
|
||
|
||
// Schedule the next steps
|
||
nextTick(incrementalSMix);
|
||
}
|
||
|
||
// Bootstrap the incremental smix
|
||
incrementalSMix();
|
||
}
|
||
|
||
// node.js
|
||
if (typeof(exports) !== 'undefined') {
|
||
module.exports = scrypt;
|
||
|
||
// RequireJS/AMD
|
||
// http://www.requirejs.org/docs/api.html
|
||
// https://github.com/amdjs/amdjs-api/wiki/AMD
|
||
} else if (typeof(define) === 'function' && define.amd) {
|
||
define(scrypt);
|
||
|
||
// Web Browsers
|
||
} else if (root) {
|
||
|
||
// If there was an existing library "scrypt", make sure it is still available
|
||
if (root.scrypt) {
|
||
root._scrypt = root.scrypt;
|
||
}
|
||
|
||
root.scrypt = scrypt;
|
||
}
|
||
|
||
})(this);
|
||
|
||
},{}],56:[function(require,module,exports){
|
||
(function (process,global){
|
||
(function (global, undefined) {
|
||
"use strict";
|
||
|
||
if (global.setImmediate) {
|
||
return;
|
||
}
|
||
|
||
var nextHandle = 1; // Spec says greater than zero
|
||
var tasksByHandle = {};
|
||
var currentlyRunningATask = false;
|
||
var doc = global.document;
|
||
var setImmediate;
|
||
|
||
function addFromSetImmediateArguments(args) {
|
||
tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args);
|
||
return nextHandle++;
|
||
}
|
||
|
||
// This function accepts the same arguments as setImmediate, but
|
||
// returns a function that requires no arguments.
|
||
function partiallyApplied(handler) {
|
||
var args = [].slice.call(arguments, 1);
|
||
return function() {
|
||
if (typeof handler === "function") {
|
||
handler.apply(undefined, args);
|
||
} else {
|
||
(new Function("" + handler))();
|
||
}
|
||
};
|
||
}
|
||
|
||
function runIfPresent(handle) {
|
||
// From the spec: "Wait until any invocations of this algorithm started before this one have completed."
|
||
// So if we're currently running a task, we'll need to delay this invocation.
|
||
if (currentlyRunningATask) {
|
||
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
|
||
// "too much recursion" error.
|
||
setTimeout(partiallyApplied(runIfPresent, handle), 0);
|
||
} else {
|
||
var task = tasksByHandle[handle];
|
||
if (task) {
|
||
currentlyRunningATask = true;
|
||
try {
|
||
task();
|
||
} finally {
|
||
clearImmediate(handle);
|
||
currentlyRunningATask = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function clearImmediate(handle) {
|
||
delete tasksByHandle[handle];
|
||
}
|
||
|
||
function installNextTickImplementation() {
|
||
setImmediate = function() {
|
||
var handle = addFromSetImmediateArguments(arguments);
|
||
process.nextTick(partiallyApplied(runIfPresent, handle));
|
||
return handle;
|
||
};
|
||
}
|
||
|
||
function canUsePostMessage() {
|
||
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
|
||
// where `global.postMessage` means something completely different and can't be used for this purpose.
|
||
if (global.postMessage && !global.importScripts) {
|
||
var postMessageIsAsynchronous = true;
|
||
var oldOnMessage = global.onmessage;
|
||
global.onmessage = function() {
|
||
postMessageIsAsynchronous = false;
|
||
};
|
||
global.postMessage("", "*");
|
||
global.onmessage = oldOnMessage;
|
||
return postMessageIsAsynchronous;
|
||
}
|
||
}
|
||
|
||
function installPostMessageImplementation() {
|
||
// Installs an event handler on `global` for the `message` event: see
|
||
// * https://developer.mozilla.org/en/DOM/window.postMessage
|
||
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
|
||
|
||
var messagePrefix = "setImmediate$" + Math.random() + "$";
|
||
var onGlobalMessage = function(event) {
|
||
if (event.source === global &&
|
||
typeof event.data === "string" &&
|
||
event.data.indexOf(messagePrefix) === 0) {
|
||
runIfPresent(+event.data.slice(messagePrefix.length));
|
||
}
|
||
};
|
||
|
||
if (global.addEventListener) {
|
||
global.addEventListener("message", onGlobalMessage, false);
|
||
} else {
|
||
global.attachEvent("onmessage", onGlobalMessage);
|
||
}
|
||
|
||
setImmediate = function() {
|
||
var handle = addFromSetImmediateArguments(arguments);
|
||
global.postMessage(messagePrefix + handle, "*");
|
||
return handle;
|
||
};
|
||
}
|
||
|
||
function installMessageChannelImplementation() {
|
||
var channel = new MessageChannel();
|
||
channel.port1.onmessage = function(event) {
|
||
var handle = event.data;
|
||
runIfPresent(handle);
|
||
};
|
||
|
||
setImmediate = function() {
|
||
var handle = addFromSetImmediateArguments(arguments);
|
||
channel.port2.postMessage(handle);
|
||
return handle;
|
||
};
|
||
}
|
||
|
||
function installReadyStateChangeImplementation() {
|
||
var html = doc.documentElement;
|
||
setImmediate = function() {
|
||
var handle = addFromSetImmediateArguments(arguments);
|
||
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
|
||
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
|
||
var script = doc.createElement("script");
|
||
script.onreadystatechange = function () {
|
||
runIfPresent(handle);
|
||
script.onreadystatechange = null;
|
||
html.removeChild(script);
|
||
script = null;
|
||
};
|
||
html.appendChild(script);
|
||
return handle;
|
||
};
|
||
}
|
||
|
||
function installSetTimeoutImplementation() {
|
||
setImmediate = function() {
|
||
var handle = addFromSetImmediateArguments(arguments);
|
||
setTimeout(partiallyApplied(runIfPresent, handle), 0);
|
||
return handle;
|
||
};
|
||
}
|
||
|
||
// If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
|
||
var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
|
||
attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
|
||
|
||
// Don't get fooled by e.g. browserify environments.
|
||
if ({}.toString.call(global.process) === "[object process]") {
|
||
// For Node.js before 0.9
|
||
installNextTickImplementation();
|
||
|
||
} else if (canUsePostMessage()) {
|
||
// For non-IE10 modern browsers
|
||
installPostMessageImplementation();
|
||
|
||
} else if (global.MessageChannel) {
|
||
// For web workers, where supported
|
||
installMessageChannelImplementation();
|
||
|
||
} else if (doc && "onreadystatechange" in doc.createElement("script")) {
|
||
// For IE 6–8
|
||
installReadyStateChangeImplementation();
|
||
|
||
} else {
|
||
// For older browsers
|
||
installSetTimeoutImplementation();
|
||
}
|
||
|
||
attachTo.setImmediate = setImmediate;
|
||
attachTo.clearImmediate = clearImmediate;
|
||
}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
|
||
|
||
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{"_process":54}],57:[function(require,module,exports){
|
||
(function (global){
|
||
|
||
var rng;
|
||
|
||
if (global.crypto && crypto.getRandomValues) {
|
||
// WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
|
||
// Moderately fast, high quality
|
||
var _rnds8 = new Uint8Array(16);
|
||
rng = function whatwgRNG() {
|
||
crypto.getRandomValues(_rnds8);
|
||
return _rnds8;
|
||
};
|
||
}
|
||
|
||
if (!rng) {
|
||
// Math.random()-based (RNG)
|
||
//
|
||
// If all else fails, use Math.random(). It's fast, but is of unspecified
|
||
// quality.
|
||
var _rnds = new Array(16);
|
||
rng = function() {
|
||
for (var i = 0, r; i < 16; i++) {
|
||
if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
|
||
_rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
|
||
}
|
||
|
||
return _rnds;
|
||
};
|
||
}
|
||
|
||
module.exports = rng;
|
||
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
},{}],58:[function(require,module,exports){
|
||
// uuid.js
|
||
//
|
||
// Copyright (c) 2010-2012 Robert Kieffer
|
||
// MIT License - http://opensource.org/licenses/mit-license.php
|
||
|
||
// Unique ID creation requires a high quality random # generator. We feature
|
||
// detect to determine the best RNG source, normalizing to a function that
|
||
// returns 128-bits of randomness, since that's what's usually required
|
||
var _rng = require('./rng');
|
||
|
||
// Maps for number <-> hex string conversion
|
||
var _byteToHex = [];
|
||
var _hexToByte = {};
|
||
for (var i = 0; i < 256; i++) {
|
||
_byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||
_hexToByte[_byteToHex[i]] = i;
|
||
}
|
||
|
||
// **`parse()` - Parse a UUID into it's component bytes**
|
||
function parse(s, buf, offset) {
|
||
var i = (buf && offset) || 0, ii = 0;
|
||
|
||
buf = buf || [];
|
||
s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
|
||
if (ii < 16) { // Don't overflow!
|
||
buf[i + ii++] = _hexToByte[oct];
|
||
}
|
||
});
|
||
|
||
// Zero out remaining bytes if string was short
|
||
while (ii < 16) {
|
||
buf[i + ii++] = 0;
|
||
}
|
||
|
||
return buf;
|
||
}
|
||
|
||
// **`unparse()` - Convert UUID byte array (ala parse()) into a string**
|
||
function unparse(buf, offset) {
|
||
var i = offset || 0, bth = _byteToHex;
|
||
return bth[buf[i++]] + bth[buf[i++]] +
|
||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||
bth[buf[i++]] + bth[buf[i++]] +
|
||
bth[buf[i++]] + bth[buf[i++]] +
|
||
bth[buf[i++]] + bth[buf[i++]];
|
||
}
|
||
|
||
// **`v1()` - Generate time-based UUID**
|
||
//
|
||
// Inspired by https://github.com/LiosK/UUID.js
|
||
// and http://docs.python.org/library/uuid.html
|
||
|
||
// random #'s we need to init node and clockseq
|
||
var _seedBytes = _rng();
|
||
|
||
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
|
||
var _nodeId = [
|
||
_seedBytes[0] | 0x01,
|
||
_seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
|
||
];
|
||
|
||
// Per 4.2.2, randomize (14 bit) clockseq
|
||
var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
|
||
|
||
// Previous uuid creation time
|
||
var _lastMSecs = 0, _lastNSecs = 0;
|
||
|
||
// See https://github.com/broofa/node-uuid for API details
|
||
function v1(options, buf, offset) {
|
||
var i = buf && offset || 0;
|
||
var b = buf || [];
|
||
|
||
options = options || {};
|
||
|
||
var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
|
||
|
||
// UUID timestamps are 100 nano-second units since the Gregorian epoch,
|
||
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
|
||
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
|
||
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
|
||
var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();
|
||
|
||
// Per 4.2.1.2, use count of uuid's generated during the current clock
|
||
// cycle to simulate higher resolution clock
|
||
var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;
|
||
|
||
// Time since last uuid creation (in msecs)
|
||
var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
|
||
|
||
// Per 4.2.1.2, Bump clockseq on clock regression
|
||
if (dt < 0 && options.clockseq === undefined) {
|
||
clockseq = clockseq + 1 & 0x3fff;
|
||
}
|
||
|
||
// Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
|
||
// time interval
|
||
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
|
||
nsecs = 0;
|
||
}
|
||
|
||
// Per 4.2.1.2 Throw error if too many uuids are requested
|
||
if (nsecs >= 10000) {
|
||
throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
|
||
}
|
||
|
||
_lastMSecs = msecs;
|
||
_lastNSecs = nsecs;
|
||
_clockseq = clockseq;
|
||
|
||
// Per 4.1.4 - Convert from unix epoch to Gregorian epoch
|
||
msecs += 12219292800000;
|
||
|
||
// `time_low`
|
||
var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
|
||
b[i++] = tl >>> 24 & 0xff;
|
||
b[i++] = tl >>> 16 & 0xff;
|
||
b[i++] = tl >>> 8 & 0xff;
|
||
b[i++] = tl & 0xff;
|
||
|
||
// `time_mid`
|
||
var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
|
||
b[i++] = tmh >>> 8 & 0xff;
|
||
b[i++] = tmh & 0xff;
|
||
|
||
// `time_high_and_version`
|
||
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
|
||
b[i++] = tmh >>> 16 & 0xff;
|
||
|
||
// `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
|
||
b[i++] = clockseq >>> 8 | 0x80;
|
||
|
||
// `clock_seq_low`
|
||
b[i++] = clockseq & 0xff;
|
||
|
||
// `node`
|
||
var node = options.node || _nodeId;
|
||
for (var n = 0; n < 6; n++) {
|
||
b[i + n] = node[n];
|
||
}
|
||
|
||
return buf ? buf : unparse(b);
|
||
}
|
||
|
||
// **`v4()` - Generate random UUID**
|
||
|
||
// See https://github.com/broofa/node-uuid for API details
|
||
function v4(options, buf, offset) {
|
||
// Deprecated - 'format' argument, as supported in v1.2
|
||
var i = buf && offset || 0;
|
||
|
||
if (typeof(options) == 'string') {
|
||
buf = options == 'binary' ? new Array(16) : null;
|
||
options = null;
|
||
}
|
||
options = options || {};
|
||
|
||
var rnds = options.random || (options.rng || _rng)();
|
||
|
||
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||
rnds[6] = (rnds[6] & 0x0f) | 0x40;
|
||
rnds[8] = (rnds[8] & 0x3f) | 0x80;
|
||
|
||
// Copy bytes to buffer, if provided
|
||
if (buf) {
|
||
for (var ii = 0; ii < 16; ii++) {
|
||
buf[i + ii] = rnds[ii];
|
||
}
|
||
}
|
||
|
||
return buf || unparse(rnds);
|
||
}
|
||
|
||
// Export public API
|
||
var uuid = v4;
|
||
uuid.v1 = v1;
|
||
uuid.v4 = v4;
|
||
uuid.parse = parse;
|
||
uuid.unparse = unparse;
|
||
|
||
module.exports = uuid;
|
||
|
||
},{"./rng":57}],59:[function(require,module,exports){
|
||
// See: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||
// See: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
||
|
||
var secp256k1 = new (require('elliptic')).ec('secp256k1');
|
||
|
||
var wordlist = (function() {
|
||
var words = require('./words.json');
|
||
return words.replace(/([A-Z])/g, ' $1').toLowerCase().substring(1).split(' ');
|
||
})();
|
||
|
||
var utils = (function() {
|
||
var convert = require('ethers-utils/convert.js');
|
||
|
||
var sha2 = require('ethers-utils/sha2');
|
||
|
||
var hmac = require('ethers-utils/hmac');
|
||
|
||
return {
|
||
defineProperty: require('ethers-utils/properties.js').defineProperty,
|
||
|
||
arrayify: convert.arrayify,
|
||
bigNumberify: require('ethers-utils/bignumber.js').bigNumberify,
|
||
hexlify: convert.hexlify,
|
||
|
||
toUtf8Bytes: require('ethers-utils/utf8.js').toUtf8Bytes,
|
||
|
||
sha256: sha2.sha256,
|
||
createSha512Hmac: hmac.createSha512Hmac,
|
||
|
||
pbkdf2: require('ethers-utils/pbkdf2.js'),
|
||
}
|
||
})();
|
||
|
||
// "Bitcoin seed"
|
||
var MasterSecret = utils.toUtf8Bytes('Bitcoin seed');
|
||
|
||
var HardenedBit = 0x80000000;
|
||
|
||
// Returns a byte with the MSB bits set
|
||
function getUpperMask(bits) {
|
||
return ((1 << bits) - 1) << (8 - bits);
|
||
}
|
||
|
||
// Returns a byte with the LSB bits set
|
||
function getLowerMask(bits) {
|
||
return (1 << bits) - 1;
|
||
}
|
||
|
||
function HDNode(keyPair, chainCode, index, depth) {
|
||
if (!(this instanceof HDNode)) { throw new Error('missing new'); }
|
||
|
||
utils.defineProperty(this, '_keyPair', keyPair);
|
||
|
||
utils.defineProperty(this, 'privateKey', utils.hexlify(keyPair.priv.toArray('be', 32)));
|
||
utils.defineProperty(this, 'publicKey', '0x' + keyPair.getPublic(true, 'hex'));
|
||
|
||
utils.defineProperty(this, 'chainCode', utils.hexlify(chainCode));
|
||
|
||
utils.defineProperty(this, 'index', index);
|
||
utils.defineProperty(this, 'depth', depth);
|
||
}
|
||
|
||
utils.defineProperty(HDNode.prototype, '_derive', function(index) {
|
||
|
||
// Public parent key -> public child key
|
||
if (!this.privateKey) {
|
||
if (index >= HardenedBit) { throw new Error('cannot derive child of neutered node'); }
|
||
throw new Error('not implemented');
|
||
}
|
||
|
||
var data = new Uint8Array(37);
|
||
|
||
if (index & HardenedBit) {
|
||
// Data = 0x00 || ser_256(k_par)
|
||
data.set(utils.arrayify(this.privateKey), 1);
|
||
|
||
} else {
|
||
// Data = ser_p(point(k_par))
|
||
data.set(this._keyPair.getPublic().encode(null, true));
|
||
}
|
||
|
||
// Data += ser_32(i)
|
||
for (var i = 24; i >= 0; i -= 8) { data[33 + (i >> 3)] = ((index >> (24 - i)) & 0xff); }
|
||
|
||
var I = utils.arrayify(utils.createSha512Hmac(this.chainCode).update(data).digest());
|
||
var IL = utils.bigNumberify(I.slice(0, 32));
|
||
var IR = I.slice(32);
|
||
|
||
var ki = IL.add('0x' + this._keyPair.getPrivate('hex')).mod('0x' + secp256k1.curve.n.toString(16));
|
||
|
||
return new HDNode(secp256k1.keyFromPrivate(utils.arrayify(ki)), I.slice(32), index, this.depth + 1);
|
||
});
|
||
|
||
utils.defineProperty(HDNode.prototype, 'derivePath', function(path) {
|
||
var components = path.split('/');
|
||
|
||
if (components.length === 0 || (components[0] === 'm' && this.depth !== 0)) {
|
||
throw new Error('invalid path');
|
||
}
|
||
|
||
if (components[0] === 'm') { components.shift(); }
|
||
|
||
var result = this;
|
||
for (var i = 0; i < components.length; i++) {
|
||
var component = components[i];
|
||
if (component.match(/^[0-9]+'$/)) {
|
||
var index = parseInt(component.substring(0, component.length - 1));
|
||
if (index >= HardenedBit) { throw new Error('invalid path index - ' + component); }
|
||
result = result._derive(HardenedBit + index);
|
||
} else if (component.match(/^[0-9]+$/)) {
|
||
var index = parseInt(component);
|
||
if (index >= HardenedBit) { throw new Error('invalid path index - ' + component); }
|
||
result = result._derive(index);
|
||
} else {
|
||
throw new Error('invlaid path component - ' + component);
|
||
}
|
||
}
|
||
|
||
return result;
|
||
});
|
||
|
||
utils.defineProperty(HDNode, 'fromMnemonic', function(mnemonic) {
|
||
// Check that the checksum s valid (will throw an error)
|
||
mnemonicToEntropy(mnemonic);
|
||
|
||
return HDNode.fromSeed(mnemonicToSeed(mnemonic));
|
||
});
|
||
|
||
utils.defineProperty(HDNode, 'fromSeed', function(seed) {
|
||
seed = utils.arrayify(seed);
|
||
if (seed.length < 16 || seed.length > 64) { throw new Error('invalid seed'); }
|
||
|
||
var I = utils.arrayify(utils.createSha512Hmac(MasterSecret).update(seed).digest());
|
||
|
||
return new HDNode(secp256k1.keyFromPrivate(I.slice(0, 32)), I.slice(32), 0, 0, 0);
|
||
});
|
||
|
||
function mnemonicToSeed(mnemonic, password) {
|
||
|
||
if (!password) {
|
||
password = '';
|
||
|
||
} else if (password.normalize) {
|
||
password = password.normalize('NFKD');
|
||
|
||
} else {
|
||
for (var i = 0; i < password.length; i++) {
|
||
var c = password.charCodeAt(i);
|
||
if (c < 32 || c > 127) { throw new Error('passwords with non-ASCII characters not supported in this environment'); }
|
||
}
|
||
}
|
||
|
||
mnemonic = utils.toUtf8Bytes(mnemonic, 'NFKD');
|
||
var salt = utils.toUtf8Bytes('mnemonic' + password, 'NFKD');
|
||
|
||
return utils.hexlify(utils.pbkdf2(mnemonic, salt, 2048, 64, utils.createSha512Hmac));
|
||
}
|
||
|
||
function mnemonicToEntropy(mnemonic) {
|
||
var words = mnemonic.toLowerCase().split(' ');
|
||
if ((words.length % 3) !== 0) { throw new Error('invalid mnemonic'); }
|
||
|
||
var entropy = utils.arrayify(new Uint8Array(Math.ceil(11 * words.length / 8)));
|
||
|
||
var offset = 0;
|
||
for (var i = 0; i < words.length; i++) {
|
||
var index = wordlist.indexOf(words[i]);
|
||
if (index === -1) { throw new Error('invalid mnemonic'); }
|
||
|
||
for (var bit = 0; bit < 11; bit++) {
|
||
if (index & (1 << (10 - bit))) {
|
||
entropy[offset >> 3] |= (1 << (7 - (offset % 8)));
|
||
}
|
||
offset++;
|
||
}
|
||
}
|
||
|
||
var entropyBits = 32 * words.length / 3;
|
||
|
||
var checksumBits = words.length / 3;
|
||
var checksumMask = getUpperMask(checksumBits);
|
||
|
||
var checksum = utils.arrayify(utils.sha256(entropy.slice(0, entropyBits / 8)))[0];
|
||
checksum &= checksumMask;
|
||
|
||
if (checksum !== (entropy[entropy.length - 1] & checksumMask)) {
|
||
throw new Error('invalid checksum');
|
||
}
|
||
|
||
return utils.hexlify(entropy.slice(0, entropyBits / 8));
|
||
}
|
||
|
||
function entropyToMnemonic(entropy) {
|
||
entropy = utils.arrayify(entropy);
|
||
|
||
if ((entropy.length % 4) !== 0 || entropy.length < 16 || entropy.length > 32) {
|
||
throw new Error('invalid entropy');
|
||
}
|
||
|
||
var words = [0];
|
||
|
||
var remainingBits = 11;
|
||
for (var i = 0; i < entropy.length; i++) {
|
||
|
||
// Consume the whole byte (with still more to go)
|
||
if (remainingBits > 8) {
|
||
words[words.length - 1] <<= 8;
|
||
words[words.length - 1] |= entropy[i];
|
||
|
||
remainingBits -= 8;
|
||
|
||
// This byte will complete an 11-bit index
|
||
} else {
|
||
words[words.length - 1] <<= remainingBits;
|
||
words[words.length - 1] |= entropy[i] >> (8 - remainingBits);
|
||
|
||
// Start the next word
|
||
words.push(entropy[i] & getLowerMask(8 - remainingBits));
|
||
|
||
remainingBits += 3;
|
||
}
|
||
}
|
||
|
||
// Compute the checksum bits
|
||
var checksum = utils.arrayify(utils.sha256(entropy))[0];
|
||
var checksumBits = entropy.length / 4;
|
||
checksum &= getUpperMask(checksumBits);
|
||
|
||
// Shift the checksum into the word indices
|
||
words[words.length - 1] <<= checksumBits;
|
||
words[words.length - 1] |= (checksum >> (8 - checksumBits));
|
||
|
||
// Convert indices into words
|
||
for (var i = 0; i < words.length; i++) {
|
||
words[i] = wordlist[words[i]];
|
||
}
|
||
|
||
return words.join(' ');
|
||
}
|
||
|
||
function isValidMnemonic(mnemonic) {
|
||
try {
|
||
mnemonicToEntropy(mnemonic);
|
||
return true;
|
||
} catch (error) { }
|
||
|
||
return false;
|
||
}
|
||
|
||
module.exports = {
|
||
fromMnemonic: HDNode.fromMnemonic,
|
||
fromSeed: HDNode.fromSeed,
|
||
|
||
mnemonicToEntropy: mnemonicToEntropy,
|
||
entropyToMnemonic: entropyToMnemonic,
|
||
mnemonicToSeed: mnemonicToSeed,
|
||
|
||
isValidMnemonic: isValidMnemonic,
|
||
};
|
||
|
||
},{"./words.json":64,"elliptic":5,"ethers-utils/bignumber.js":21,"ethers-utils/convert.js":24,"ethers-utils/hmac":25,"ethers-utils/pbkdf2.js":30,"ethers-utils/properties.js":31,"ethers-utils/sha2":33,"ethers-utils/utf8.js":38}],60:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var Wallet = require('./wallet');
|
||
var HDNode = require('./hdnode');
|
||
var SigningKey = require('./signing-key');
|
||
|
||
module.exports = {
|
||
HDNode: HDNode,
|
||
Wallet: Wallet,
|
||
|
||
SigningKey: SigningKey,
|
||
_SigningKey: SigningKey,
|
||
}
|
||
|
||
require('ethers-utils/standalone.js')(module.exports);
|
||
|
||
},{"./hdnode":59,"./signing-key":62,"./wallet":63,"ethers-utils/standalone.js":35}],61:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var aes = require('aes-js');
|
||
var scrypt = require('scrypt-js');
|
||
var uuid = require('uuid');
|
||
|
||
var hmac = require('ethers-utils/hmac');
|
||
var pbkdf2 = require('ethers-utils/pbkdf2');
|
||
var utils = require('ethers-utils');
|
||
|
||
var SigningKey = require('./signing-key.js');
|
||
|
||
function arrayify(hexString) {
|
||
if (typeof(hexString) === 'string' && hexString.substring(0, 2) !== '0x') {
|
||
hexString = '0x' + hexString;
|
||
}
|
||
return utils.arrayify(hexString);
|
||
}
|
||
|
||
function getPassword(password) {
|
||
if (typeof(password) === 'string') {
|
||
return utils.toUtf8Bytes(password, 'NFKC');
|
||
}
|
||
return utils.arrayify(password, 'password');
|
||
}
|
||
|
||
// Search an Object and its children recursively, caselessly.
|
||
function searchPath(object, path) {
|
||
var currentChild = object;
|
||
|
||
var comps = path.toLowerCase().split('/');
|
||
for (var i = 0; i < comps.length; i++) {
|
||
|
||
// Search for a child object with a case-insensitive matching key
|
||
var matchingChild = null;
|
||
for (var key in currentChild) {
|
||
if (key.toLowerCase() === comps[i]) {
|
||
matchingChild = currentChild[key];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Didn't find one. :'(
|
||
if (matchingChild === null) {
|
||
return null;
|
||
}
|
||
|
||
// Now check this child...
|
||
currentChild = matchingChild;
|
||
}
|
||
|
||
return currentChild;
|
||
}
|
||
|
||
var secretStorage = {};
|
||
|
||
|
||
utils.defineProperty(secretStorage, 'isCrowdsaleWallet', function(json) {
|
||
try {
|
||
var data = JSON.parse(json);
|
||
} catch (error) { return false; }
|
||
|
||
return (data.encseed && data.ethaddr);
|
||
});
|
||
|
||
utils.defineProperty(secretStorage, 'isValidWallet', function(json) {
|
||
try {
|
||
var data = JSON.parse(json);
|
||
} catch (error) { return false; }
|
||
|
||
if (!data.version || parseInt(data.version) !== data.version || parseInt(data.version) !== 3) {
|
||
return false;
|
||
}
|
||
|
||
// @TODO: Put more checks to make sure it has kdf, iv and all that good stuff
|
||
return true;
|
||
});
|
||
|
||
|
||
// See: https://github.com/ethereum/pyethsaletool
|
||
utils.defineProperty(secretStorage, 'decryptCrowdsale', function(json, password) {
|
||
var data = JSON.parse(json);
|
||
|
||
password = getPassword(password);
|
||
|
||
// Ethereum Address
|
||
var ethaddr = utils.getAddress(searchPath(data, 'ethaddr'));
|
||
|
||
// Encrypted Seed
|
||
var encseed = arrayify(searchPath(data, 'encseed'));
|
||
if (!encseed || (encseed.length % 16) !== 0) {
|
||
throw new Error('invalid encseed');
|
||
}
|
||
|
||
var key = pbkdf2(password, password, 2000, 32, hmac.createSha256Hmac).slice(0, 16);
|
||
|
||
var iv = encseed.slice(0, 16);
|
||
var encryptedSeed = encseed.slice(16);
|
||
|
||
// Decrypt the seed
|
||
var aesCbc = new aes.ModeOfOperation.cbc(key, iv);
|
||
var seed = utils.arrayify(aesCbc.decrypt(encryptedSeed));
|
||
seed = aes.padding.pkcs7.strip(seed);
|
||
|
||
// This wallet format is weird... Convert the binary encoded hex to a string.
|
||
var seedHex = '';
|
||
for (var i = 0; i < seed.length; i++) {
|
||
seedHex += String.fromCharCode(seed[i]);
|
||
}
|
||
|
||
var seedHexBytes = utils.toUtf8Bytes(seedHex);
|
||
|
||
var signingKey = new SigningKey(utils.keccak256(seedHexBytes));
|
||
|
||
if (signingKey.address !== ethaddr) {
|
||
throw new Error('corrupt crowdsale wallet');
|
||
}
|
||
|
||
return signingKey;
|
||
});
|
||
|
||
|
||
utils.defineProperty(secretStorage, 'decrypt', function(json, password, progressCallback) {
|
||
var data = JSON.parse(json);
|
||
|
||
password = getPassword(password);
|
||
|
||
var decrypt = function(key, ciphertext) {
|
||
var cipher = searchPath(data, 'crypto/cipher');
|
||
if (cipher === 'aes-128-ctr') {
|
||
var iv = arrayify(searchPath(data, 'crypto/cipherparams/iv'), 'crypto/cipherparams/iv')
|
||
var counter = new aes.Counter(iv);
|
||
|
||
var aesCtr = new aes.ModeOfOperation.ctr(key, counter);
|
||
|
||
return new arrayify(aesCtr.decrypt(ciphertext));
|
||
}
|
||
|
||
return null;
|
||
};
|
||
|
||
var computeMAC = function(derivedHalf, ciphertext) {
|
||
return utils.keccak256(utils.concat([derivedHalf, ciphertext]));
|
||
}
|
||
|
||
var getSigningKey = function(key, reject) {
|
||
var ciphertext = arrayify(searchPath(data, 'crypto/ciphertext'));
|
||
|
||
var computedMAC = utils.hexlify(computeMAC(key.slice(16, 32), ciphertext)).substring(2);
|
||
if (computedMAC !== searchPath(data, 'crypto/mac').toLowerCase()) {
|
||
reject(new Error('invalid password'));
|
||
return null;
|
||
}
|
||
|
||
var privateKey = decrypt(key.slice(0, 16), ciphertext);
|
||
|
||
if (!privateKey) {
|
||
reject(new Error('unsupported cipher'));
|
||
return null;
|
||
}
|
||
|
||
var signingKey = new SigningKey(privateKey);
|
||
if (signingKey.address !== utils.getAddress(data.address)) {
|
||
reject(new Error('address mismatch'));
|
||
return null;
|
||
}
|
||
|
||
return signingKey;
|
||
}
|
||
|
||
|
||
return new Promise(function(resolve, reject) {
|
||
var kdf = searchPath(data, 'crypto/kdf');
|
||
if (kdf && typeof(kdf) === 'string') {
|
||
if (kdf.toLowerCase() === 'scrypt') {
|
||
var salt = arrayify(searchPath(data, 'crypto/kdfparams/salt'), 'crypto/kdfparams/salt');
|
||
var N = parseInt(searchPath(data, 'crypto/kdfparams/n'));
|
||
var r = parseInt(searchPath(data, 'crypto/kdfparams/r'));
|
||
var p = parseInt(searchPath(data, 'crypto/kdfparams/p'));
|
||
if (!N || !r || !p) {
|
||
reject(new Error('unsupported key-derivation function parameters'));
|
||
return;
|
||
}
|
||
|
||
// Make sure N is a power of 2
|
||
if ((N & (N - 1)) !== 0) {
|
||
reject(new Error('unsupported key-derivation function parameter value for N'));
|
||
return;
|
||
}
|
||
|
||
var dkLen = parseInt(searchPath(data, 'crypto/kdfparams/dklen'));
|
||
if (dkLen !== 32) {
|
||
reject( new Error('unsupported key-derivation derived-key length'));
|
||
return;
|
||
}
|
||
|
||
scrypt(password, salt, N, r, p, dkLen, function(error, progress, key) {
|
||
if (error) {
|
||
error.progress = progress;
|
||
reject(error);
|
||
|
||
} else if (key) {
|
||
key = arrayify(key);
|
||
|
||
var signingKey = getSigningKey(key, reject);
|
||
if (!signingKey) { return; }
|
||
|
||
if (progressCallback) { progressCallback(1); }
|
||
resolve(signingKey);
|
||
|
||
} else if (progressCallback) {
|
||
return progressCallback(progress);
|
||
}
|
||
});
|
||
|
||
} else if (kdf.toLowerCase() === 'pbkdf2') {
|
||
var salt = arrayify(searchPath(data, 'crypto/kdfparams/salt'), 'crypto/kdfparams/salt');
|
||
|
||
var prfFunc = null;
|
||
var prf = searchPath(data, 'crypto/kdfparams/prf');
|
||
if (prf === 'hmac-sha256') {
|
||
prfFunc = hmac.createSha256Hmac;
|
||
} else if (prf === 'hmac-sha512') {
|
||
prfFunc = hmac.createSha512Hmac;
|
||
} else {
|
||
reject(new Error('unsupported prf'));
|
||
return;
|
||
}
|
||
|
||
var c = parseInt(searchPath(data, 'crypto/kdfparams/c'));
|
||
|
||
var dkLen = parseInt(searchPath(data, 'crypto/kdfparams/dklen'));
|
||
if (dkLen !== 32) {
|
||
reject( new Error('unsupported key-derivation derived-key length'));
|
||
return;
|
||
}
|
||
|
||
var key = pbkdf2(password, salt, c, dkLen, prfFunc);
|
||
|
||
var signingKey = getSigningKey(key, reject);
|
||
if (!signingKey) { return; }
|
||
|
||
resolve(signingKey);
|
||
|
||
} else {
|
||
reject(new Error('unsupported key-derivation function'));
|
||
}
|
||
|
||
} else {
|
||
reject(new Error('unsupported key-derivation function'));
|
||
}
|
||
});
|
||
});
|
||
|
||
utils.defineProperty(secretStorage, 'encrypt', function(privateKey, password, options, progressCallback) {
|
||
|
||
// the options are optional, so adjust the call as needed
|
||
if (typeof(options) === 'function' && !progressCallback) {
|
||
progressCallback = options;
|
||
options = {};
|
||
}
|
||
if (!options) { options = {}; }
|
||
|
||
// Check the private key
|
||
if (privateKey instanceof SigningKey) {
|
||
privateKey = privateKey.privateKey;
|
||
}
|
||
privateKey = utils.arrayify(privateKey, 'private key');
|
||
if (privateKey.length !== 32) { throw new Error('invalid private key'); }
|
||
|
||
password = getPassword(password);
|
||
|
||
// Check/generate the salt
|
||
var salt = options.salt;
|
||
if (salt) {
|
||
salt = arrayify(salt, 'salt');
|
||
} else {
|
||
salt = utils.randomBytes(32);;
|
||
}
|
||
|
||
// Override initialization vector
|
||
var iv = null;
|
||
if (options.iv) {
|
||
iv = arrayify(options.iv, 'iv');
|
||
if (iv.length !== 16) { throw new Error('invalid iv'); }
|
||
}
|
||
|
||
// Override the uuid
|
||
var uuidRandom = options.uuid;
|
||
if (uuidRandom) {
|
||
uuidRandom = utils.arrayify(uuidRandom, 'uuid');
|
||
if (uuidRandom.length !== 16) { throw new Error('invalid uuid'); }
|
||
}
|
||
|
||
// Override the scrypt password-based key derivation function parameters
|
||
var N = (1 << 17), r = 8, p = 1;
|
||
if (options.scrypt) {
|
||
if (options.scrypt.N) { N = options.scrypt.N; }
|
||
if (options.scrypt.r) { r = options.scrypt.r; }
|
||
if (options.scrypt.p) { p = options.scrypt.p; }
|
||
}
|
||
|
||
return new Promise(function(resolve, reject) {
|
||
|
||
// We take 64 bytes:
|
||
// - 32 bytes As normal for the Web3 secret storage (derivedKey, macPrefix)
|
||
// - 16 bytes The initialization vector
|
||
// - 16 bytes The UUID random bytes
|
||
scrypt(password, salt, N, r, p, 64, function(error, progress, key) {
|
||
if (error) {
|
||
error.progress = progress;
|
||
reject(error);
|
||
|
||
} else if (key) {
|
||
key = arrayify(key);
|
||
|
||
// These will be used to encrypt the wallet (as per Web3 secret storage)
|
||
var derivedKey = key.slice(0, 16);
|
||
var macPrefix = key.slice(16, 32);
|
||
|
||
// Get the initialization vector
|
||
if (!iv) { iv = key.slice(32, 48); }
|
||
|
||
// Get the UUID random data
|
||
if (!uuidRandom) { uuidRandom = key.slice(48, 64); }
|
||
|
||
// Get the address for this private key
|
||
var address = (new SigningKey(privateKey)).address;
|
||
|
||
// Encrypt the private key
|
||
var counter = new aes.Counter(iv);
|
||
var aesCtr = new aes.ModeOfOperation.ctr(derivedKey, counter);
|
||
var ciphertext = utils.arrayify(aesCtr.encrypt(privateKey));
|
||
|
||
// Compute the message authentication code, used to check the password
|
||
var mac = utils.keccak256(utils.concat([macPrefix, ciphertext]))
|
||
|
||
// See: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
|
||
var data = {
|
||
address: address.substring(2).toLowerCase(),
|
||
id: uuid.v4({random: uuidRandom}),
|
||
version: 3,
|
||
Crypto: {
|
||
cipher: 'aes-128-ctr',
|
||
cipherparams: {
|
||
iv: utils.hexlify(iv).substring(2),
|
||
},
|
||
ciphertext: utils.hexlify(ciphertext).substring(2),
|
||
kdf: 'scrypt',
|
||
kdfparams: {
|
||
salt: utils.hexlify(salt).substring(2),
|
||
n: N,
|
||
dklen: 32,
|
||
p: p,
|
||
r: r
|
||
},
|
||
mac: mac.substring(2)
|
||
}
|
||
};
|
||
|
||
if (progressCallback) { progressCallback(1); }
|
||
resolve(JSON.stringify(data));
|
||
|
||
} else if (progressCallback) {
|
||
return progressCallback(progress);
|
||
}
|
||
});
|
||
});
|
||
});
|
||
|
||
module.exports = secretStorage;
|
||
|
||
},{"./signing-key.js":62,"aes-js":1,"ethers-utils":27,"ethers-utils/hmac":25,"ethers-utils/pbkdf2":30,"scrypt-js":55,"uuid":58}],62:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
/**
|
||
* SigningKey
|
||
*
|
||
*
|
||
*/
|
||
|
||
var secp256k1 = new (require('elliptic')).ec('secp256k1');
|
||
var utils = require('ethers-utils');
|
||
|
||
|
||
|
||
function SigningKey(privateKey) {
|
||
if (!(this instanceof SigningKey)) { throw new Error('missing new'); }
|
||
|
||
privateKey = utils.arrayify(privateKey);
|
||
if (privateKey.length !== 32) {
|
||
throw new Error('invalid private key');
|
||
}
|
||
utils.defineProperty(this, 'privateKey', utils.hexlify(privateKey))
|
||
|
||
var keyPair = secp256k1.keyFromPrivate(privateKey);
|
||
|
||
utils.defineProperty(this, 'publicKey', '0x' + keyPair.getPublic(true, 'hex'))
|
||
|
||
var address = SigningKey.publicKeyToAddress('0x' + keyPair.getPublic(false, 'hex'));
|
||
utils.defineProperty(this, 'address', address)
|
||
|
||
utils.defineProperty(this, 'signDigest', function(digest) {
|
||
var signature = keyPair.sign(utils.arrayify(digest), {canonical: true});
|
||
return {
|
||
recoveryParam: signature.recoveryParam,
|
||
r: '0x' + signature.r.toString(16),
|
||
s: '0x' + signature.s.toString(16)
|
||
}
|
||
});
|
||
}
|
||
|
||
utils.defineProperty(SigningKey, 'recover', function(digest, r, s, recoveryParam) {
|
||
var signature = {
|
||
r: utils.arrayify(r),
|
||
s: utils.arrayify(s)
|
||
};
|
||
var publicKey = secp256k1.recoverPubKey(utils.arrayify(digest), signature, recoveryParam);
|
||
return SigningKey.publicKeyToAddress('0x' + publicKey.encode('hex', false));
|
||
});
|
||
|
||
|
||
utils.defineProperty(SigningKey, 'getPublicKey', function(value, compressed) {
|
||
value = utils.arrayify(value);
|
||
compressed = !!compressed;
|
||
|
||
if (value.length === 32) {
|
||
var keyPair = secp256k1.keyFromPrivate(value);
|
||
return '0x' + keyPair.getPublic(compressed, 'hex');
|
||
|
||
} else if (value.length === 33) {
|
||
var keyPair = secp256k1.keyFromPublic(value);
|
||
return '0x' + keyPair.getPublic(compressed, 'hex');
|
||
|
||
} else if (value.length === 65) {
|
||
var keyPair = secp256k1.keyFromPublic(value);
|
||
return '0x' + keyPair.getPublic(compressed, 'hex');
|
||
}
|
||
|
||
throw new Error('invalid value');
|
||
});
|
||
|
||
utils.defineProperty(SigningKey, 'publicKeyToAddress', function(publicKey) {
|
||
publicKey = '0x' + SigningKey.getPublicKey(publicKey, false).slice(4);
|
||
return utils.getAddress('0x' + utils.keccak256(publicKey).substring(26));
|
||
});
|
||
|
||
module.exports = SigningKey;
|
||
|
||
},{"elliptic":5,"ethers-utils":27}],63:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var scrypt = require('scrypt-js');
|
||
var utils = require('ethers-utils');
|
||
|
||
var HDNode = require('./hdnode');
|
||
|
||
var secretStorage = require('./secret-storage');
|
||
var SigningKey = require('./signing-key');
|
||
|
||
// This ensures we inject a setImmediate into the global space, which
|
||
// dramatically improves the performance of the scrypt PBKDF.
|
||
require('setimmediate');
|
||
|
||
var defaultPath = "m/44'/60'/0'/0/0";
|
||
|
||
var transactionFields = [
|
||
{name: 'nonce', maxLength: 32, },
|
||
{name: 'gasPrice', maxLength: 32, },
|
||
{name: 'gasLimit', maxLength: 32, },
|
||
{name: 'to', length: 20, },
|
||
{name: 'value', maxLength: 32, },
|
||
{name: 'data'},
|
||
];
|
||
|
||
function Wallet(privateKey, provider) {
|
||
if (!(this instanceof Wallet)) { throw new Error('missing new'); }
|
||
|
||
// Make sure we have a valid signing key
|
||
var signingKey = privateKey;
|
||
if (!(privateKey instanceof SigningKey)) {
|
||
signingKey = new SigningKey(privateKey);
|
||
}
|
||
utils.defineProperty(this, 'privateKey', signingKey.privateKey);
|
||
|
||
// Provider
|
||
Object.defineProperty(this, 'provider', {
|
||
enumerable: true,
|
||
get: function() { return provider; },
|
||
set: function(value) {
|
||
provider = value;
|
||
}
|
||
});
|
||
if (provider) { this.provider = provider; }
|
||
|
||
var defaultGasLimit = 1500000;
|
||
Object.defineProperty(this, 'defaultGasLimit', {
|
||
enumerable: true,
|
||
get: function() { return defaultGasLimit; },
|
||
set: function(value) {
|
||
if (typeof(value) !== 'number') { throw new Error('invalid defaultGasLimit'); }
|
||
defaultGasLimit = value;
|
||
}
|
||
});
|
||
|
||
utils.defineProperty(this, 'address', signingKey.address);
|
||
|
||
utils.defineProperty(this, 'sign', function(transaction) {
|
||
var chainId = transaction.chainId;
|
||
if (!chainId && this.provider) { chainId = this.provider.chainId; }
|
||
if (!chainId) { chainId = 0; }
|
||
|
||
var raw = [];
|
||
transactionFields.forEach(function(fieldInfo) {
|
||
var value = transaction[fieldInfo.name] || ([]);
|
||
value = utils.arrayify(utils.hexlify(value), fieldInfo.name);
|
||
|
||
// Fixed-width field
|
||
if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {
|
||
var error = new Error('invalid ' + fieldInfo.name);
|
||
error.reason = 'wrong length';
|
||
error.value = value;
|
||
throw error;
|
||
}
|
||
|
||
// Variable-width (with a maximum)
|
||
if (fieldInfo.maxLength) {
|
||
value = utils.stripZeros(value);
|
||
if (value.length > fieldInfo.maxLength) {
|
||
var error = new Error('invalid ' + fieldInfo.name);
|
||
error.reason = 'too long';
|
||
error.value = value;
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
raw.push(utils.hexlify(value));
|
||
});
|
||
|
||
if (chainId) {
|
||
raw.push(utils.hexlify(chainId));
|
||
raw.push('0x');
|
||
raw.push('0x');
|
||
}
|
||
|
||
var digest = utils.keccak256(utils.RLP.encode(raw));
|
||
|
||
var signature = signingKey.signDigest(digest);
|
||
|
||
var v = 27 + signature.recoveryParam
|
||
if (chainId) {
|
||
raw.pop();
|
||
raw.pop();
|
||
raw.pop();
|
||
v += chainId * 2 + 8;
|
||
}
|
||
|
||
raw.push(utils.hexlify(v));
|
||
raw.push(signature.r);
|
||
raw.push(signature.s);
|
||
|
||
return utils.RLP.encode(raw);
|
||
});
|
||
}
|
||
|
||
utils.defineProperty(Wallet, 'parseTransaction', function(rawTransaction) {
|
||
rawTransaction = utils.hexlify(rawTransaction, 'rawTransaction');
|
||
var signedTransaction = utils.RLP.decode(rawTransaction);
|
||
if (signedTransaction.length !== 9) { throw new Error('invalid transaction'); }
|
||
|
||
var raw = [];
|
||
|
||
var transaction = {};
|
||
transactionFields.forEach(function(fieldInfo, index) {
|
||
transaction[fieldInfo.name] = signedTransaction[index];
|
||
raw.push(signedTransaction[index]);
|
||
});
|
||
|
||
if (transaction.to) {
|
||
if (transaction.to == '0x') {
|
||
delete transaction.to;
|
||
} else {
|
||
transaction.to = utils.getAddress(transaction.to);
|
||
}
|
||
}
|
||
|
||
['gasPrice', 'gasLimit', 'nonce', 'value'].forEach(function(name) {
|
||
if (!transaction[name]) { return; }
|
||
if (transaction[name].length === 0) {
|
||
transaction[name] = utils.bigNumberify(0);
|
||
} else {
|
||
transaction[name] = utils.bigNumberify(transaction[name]);
|
||
}
|
||
});
|
||
|
||
if (transaction.nonce) {
|
||
transaction.nonce = transaction.nonce.toNumber();
|
||
} else {
|
||
transaction.nonce = 0;
|
||
}
|
||
|
||
var v = utils.arrayify(signedTransaction[6]);
|
||
var r = utils.arrayify(signedTransaction[7]);
|
||
var s = utils.arrayify(signedTransaction[8]);
|
||
|
||
if (v.length === 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) {
|
||
transaction.v = v[0];
|
||
transaction.r = signedTransaction[7];
|
||
transaction.s = signedTransaction[8];
|
||
|
||
var chainId = (transaction.v - 35) / 2;
|
||
if (chainId < 0) { chainId = 0; }
|
||
chainId = parseInt(chainId);
|
||
|
||
transaction.chainId = chainId;
|
||
|
||
var recoveryParam = transaction.v - 27;
|
||
|
||
if (chainId) {
|
||
raw.push(utils.hexlify(chainId));
|
||
raw.push('0x');
|
||
raw.push('0x');
|
||
recoveryParam -= chainId * 2 + 8;
|
||
}
|
||
|
||
var digest = utils.keccak256(utils.RLP.encode(raw));
|
||
try {
|
||
transaction.from = SigningKey.recover(digest, r, s, recoveryParam);
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
|
||
return transaction;
|
||
});
|
||
|
||
utils.defineProperty(Wallet.prototype, 'getAddress', function() {
|
||
return this.address;
|
||
});
|
||
|
||
utils.defineProperty(Wallet.prototype, 'getBalance', function(blockTag) {
|
||
if (!this.provider) { throw new Error('missing provider'); }
|
||
return this.provider.getBalance(this.address, blockTag);
|
||
});
|
||
|
||
utils.defineProperty(Wallet.prototype, 'getTransactionCount', function(blockTag) {
|
||
if (!this.provider) { throw new Error('missing provider'); }
|
||
return this.provider.getTransactionCount(this.address, blockTag);
|
||
});
|
||
|
||
utils.defineProperty(Wallet.prototype, 'estimateGas', function(transaction) {
|
||
if (!this.provider) { throw new Error('missing provider'); }
|
||
|
||
var calculate = {};
|
||
['from', 'to', 'data', 'value'].forEach(function(key) {
|
||
if (transaction[key] == null) { return; }
|
||
calculate[key] = transaction[key];
|
||
});
|
||
|
||
if (transaction.from == null) { calculate.from = this.address; }
|
||
|
||
return this.provider.estimateGas(calculate);
|
||
});
|
||
|
||
utils.defineProperty(Wallet.prototype, 'sendTransaction', function(transaction) {
|
||
if (!this.provider) { throw new Error('missing provider'); }
|
||
|
||
var gasLimit = transaction.gasLimit;
|
||
if (gasLimit == null) { gasLimit = this.defaultGasLimit; }
|
||
|
||
var self = this;
|
||
|
||
var gasPricePromise = null;
|
||
if (transaction.gasPrice) {
|
||
gasPricePromise = Promise.resolve(transaction.gasPrice);
|
||
} else {
|
||
gasPricePromise = this.provider.getGasPrice();
|
||
}
|
||
|
||
var noncePromise = null;
|
||
if (transaction.nonce) {
|
||
noncePromise = Promise.resolve(transaction.nonce);
|
||
} else {
|
||
noncePromise = this.provider.getTransactionCount(self.address, 'pending');
|
||
}
|
||
|
||
var chainId = this.provider.chainId;
|
||
|
||
var toPromise = null;
|
||
if (transaction.to) {
|
||
toPromise = this.provider.resolveName(transaction.to);
|
||
} else {
|
||
toPromise = Promise.resolve(undefined);
|
||
}
|
||
|
||
var data = utils.hexlify(transaction.data || '0x');
|
||
var value = utils.hexlify(transaction.value || 0);
|
||
|
||
return Promise.all([gasPricePromise, noncePromise, toPromise]).then(function(results) {
|
||
var signedTransaction = self.sign({
|
||
to: results[2],
|
||
data: data,
|
||
gasLimit: gasLimit,
|
||
gasPrice: results[0],
|
||
nonce: results[1],
|
||
value: value,
|
||
chainId: chainId
|
||
});
|
||
|
||
return self.provider.sendTransaction(signedTransaction).then(function(hash) {
|
||
var transaction = Wallet.parseTransaction(signedTransaction);
|
||
transaction.hash = hash;
|
||
return transaction;
|
||
});
|
||
});
|
||
});
|
||
|
||
utils.defineProperty(Wallet.prototype, 'send', function(addressOrName, amountWei, options) {
|
||
if (!options) { options = {}; }
|
||
|
||
return this.sendTransaction({
|
||
to: addressOrName,
|
||
gasLimit: options.gasLimit,
|
||
gasPrice: options.gasPrice,
|
||
nonce: options.nonce,
|
||
value: amountWei,
|
||
});
|
||
});
|
||
|
||
// @TODO: this is starting to get used various places; move to utils?
|
||
function hexPad(value, length) {
|
||
while (value.length < 2 * length + 2) {
|
||
value = '0x0' + value.substring(2);
|
||
}
|
||
return value;
|
||
}
|
||
|
||
function getHash(message) {
|
||
var payload = utils.concat([
|
||
utils.toUtf8Bytes('\x19Ethereum Signed Message:\n'),
|
||
utils.toUtf8Bytes(String(message.length)),
|
||
((typeof(message) === 'string') ? utils.toUtf8Bytes(message): message)
|
||
]);
|
||
return utils.keccak256(payload);
|
||
}
|
||
|
||
utils.defineProperty(Wallet.prototype, 'signMessage', function(message) {
|
||
var signingKey = new SigningKey(this.privateKey);
|
||
var sig = signingKey.signDigest(getHash(message));
|
||
|
||
return (hexPad(sig.r) + hexPad(sig.s).substring(2) + (sig.recoveryParam ? '1c': '1b'));
|
||
});
|
||
|
||
utils.defineProperty(Wallet, 'verifyMessage', function(message, signature) {
|
||
signature = utils.hexlify(signature);
|
||
if (signature.length != 132) { throw new Error('invalid signature'); }
|
||
var digest = getHash(message);
|
||
var recoveryParam = parseInt(signature.substring(130), 16) - 27;
|
||
if (recoveryParam < 0) { throw new Error('invalid signature'); }
|
||
return SigningKey.recover(
|
||
digest,
|
||
signature.substring(0, 66),
|
||
'0x' + signature.substring(66, 130),
|
||
parseInt(signature.substring(130), 16) - 27
|
||
);
|
||
});
|
||
|
||
utils.defineProperty(Wallet.prototype, 'encrypt', function(password, options, progressCallback) {
|
||
if (typeof(options) === 'function' && !progressCallback) {
|
||
progressCallback = options;
|
||
options = {};
|
||
}
|
||
|
||
if (progressCallback && typeof(progressCallback) !== 'function') {
|
||
throw new Error('invalid callback');
|
||
}
|
||
|
||
if (!options) { options = {}; }
|
||
|
||
return secretStorage.encrypt(this.privateKey, password, options, progressCallback);
|
||
});
|
||
|
||
|
||
utils.defineProperty(Wallet, 'isEncryptedWallet', function(json) {
|
||
return (secretStorage.isValidWallet(json) || secretStorage.isCrowdsaleWallet(json));
|
||
});
|
||
|
||
|
||
|
||
utils.defineProperty(Wallet, 'createRandom', function(options) {
|
||
var entropy = utils.randomBytes(16);
|
||
|
||
if (!options) { options = { }; }
|
||
|
||
if (options.extraEntropy) {
|
||
entropy = utils.keccak256(utils.concat([entropy, options.extraEntropy])).substring(0, 34);
|
||
}
|
||
var mnemonic = HDNode.entropyToMnemonic(entropy);
|
||
return Wallet.fromMnemonic(mnemonic, options.path);
|
||
});
|
||
|
||
|
||
utils.defineProperty(Wallet, 'fromEncryptedWallet', function(json, password, progressCallback) {
|
||
if (progressCallback && typeof(progressCallback) !== 'function') {
|
||
throw new Error('invalid callback');
|
||
}
|
||
|
||
return new Promise(function(resolve, reject) {
|
||
|
||
if (secretStorage.isCrowdsaleWallet(json)) {
|
||
try {
|
||
var privateKey = secretStorage.decryptCrowdsale(json, password);
|
||
resolve(new Wallet(privateKey));
|
||
} catch (error) {
|
||
reject(error);
|
||
}
|
||
|
||
} else if (secretStorage.isValidWallet(json)) {
|
||
|
||
secretStorage.decrypt(json, password, progressCallback).then(function(signingKey) {
|
||
resolve(new Wallet(signingKey));
|
||
}, function(error) {
|
||
reject(error);
|
||
});
|
||
|
||
} else {
|
||
reject('invalid wallet JSON');
|
||
}
|
||
});
|
||
});
|
||
|
||
utils.defineProperty(Wallet, 'fromMnemonic', function(mnemonic, path) {
|
||
if (!path) { path = defaultPath; }
|
||
|
||
var hdnode = HDNode.fromMnemonic(mnemonic).derivePath(path);
|
||
|
||
var wallet = new Wallet(hdnode.privateKey);
|
||
utils.defineProperty(wallet, 'mnemonic', mnemonic);
|
||
utils.defineProperty(wallet, 'path', path);
|
||
|
||
return wallet;
|
||
});
|
||
|
||
|
||
utils.defineProperty(Wallet, 'fromBrainWallet', function(username, password, progressCallback) {
|
||
if (progressCallback && typeof(progressCallback) !== 'function') {
|
||
throw new Error('invalid callback');
|
||
}
|
||
|
||
if (typeof(username) === 'string') {
|
||
username = utils.toUtf8Bytes(username, 'NFKC');
|
||
} else {
|
||
username = utils.arrayify(username, 'password');
|
||
}
|
||
|
||
if (typeof(password) === 'string') {
|
||
password = utils.toUtf8Bytes(password, 'NFKC');
|
||
} else {
|
||
password = utils.arrayify(password, 'password');
|
||
}
|
||
|
||
return new Promise(function(resolve, reject) {
|
||
scrypt(password, username, (1 << 18), 8, 1, 32, function(error, progress, key) {
|
||
if (error) {
|
||
reject(error);
|
||
|
||
} else if (key) {
|
||
resolve(new Wallet(utils.hexlify(key)));
|
||
|
||
} else if (progressCallback) {
|
||
return progressCallback(progress);
|
||
}
|
||
});
|
||
});
|
||
});
|
||
|
||
//utils.defineProperty(Wallet, 'isCrowdsaleWallet', secretStorage.isCrowdsaleWallet);
|
||
|
||
//utils.defineProperty(Wallet, 'decryptCrowdsale', function(json, password) {
|
||
// return new Wallet(secretStorage.decryptCrowdsale(json, password));
|
||
//});
|
||
|
||
module.exports = Wallet;
|
||
|
||
},{"./hdnode":59,"./secret-storage":61,"./signing-key":62,"ethers-utils":27,"scrypt-js":55,"setimmediate":56}],64:[function(require,module,exports){
|
||
module.exports="AbandonAbilityAbleAboutAboveAbsentAbsorbAbstractAbsurdAbuseAccessAccidentAccountAccuseAchieveAcidAcousticAcquireAcrossActActionActorActressActualAdaptAddAddictAddressAdjustAdmitAdultAdvanceAdviceAerobicAffairAffordAfraidAgainAgeAgentAgreeAheadAimAirAirportAisleAlarmAlbumAlcoholAlertAlienAllAlleyAllowAlmostAloneAlphaAlreadyAlsoAlterAlwaysAmateurAmazingAmongAmountAmusedAnalystAnchorAncientAngerAngleAngryAnimalAnkleAnnounceAnnualAnotherAnswerAntennaAntiqueAnxietyAnyApartApologyAppearAppleApproveAprilArchArcticAreaArenaArgueArmArmedArmorArmyAroundArrangeArrestArriveArrowArtArtefactArtistArtworkAskAspectAssaultAssetAssistAssumeAsthmaAthleteAtomAttackAttendAttitudeAttractAuctionAuditAugustAuntAuthorAutoAutumnAverageAvocadoAvoidAwakeAwareAwayAwesomeAwfulAwkwardAxisBabyBachelorBaconBadgeBagBalanceBalconyBallBambooBananaBannerBarBarelyBargainBarrelBaseBasicBasketBattleBeachBeanBeautyBecauseBecomeBeefBeforeBeginBehaveBehindBelieveBelowBeltBenchBenefitBestBetrayBetterBetweenBeyondBicycleBidBikeBindBiologyBirdBirthBitterBlackBladeBlameBlanketBlastBleakBlessBlindBloodBlossomBlouseBlueBlurBlushBoardBoatBodyBoilBombBoneBonusBookBoostBorderBoringBorrowBossBottomBounceBoxBoyBracketBrainBrandBrassBraveBreadBreezeBrickBridgeBriefBrightBringBriskBroccoliBrokenBronzeBroomBrotherBrownBrushBubbleBuddyBudgetBuffaloBuildBulbBulkBulletBundleBunkerBurdenBurgerBurstBusBusinessBusyButterBuyerBuzzCabbageCabinCableCactusCageCakeCallCalmCameraCampCanCanalCancelCandyCannonCanoeCanvasCanyonCapableCapitalCaptainCarCarbonCardCargoCarpetCarryCartCaseCashCasinoCastleCasualCatCatalogCatchCategoryCattleCaughtCauseCautionCaveCeilingCeleryCementCensusCenturyCerealCertainChairChalkChampionChangeChaosChapterChargeChaseChatCheapCheckCheeseChefCherryChestChickenChiefChildChimneyChoiceChooseChronicChuckleChunkChurnCigarCinnamonCircleCitizenCityCivilClaimClapClarifyClawClayCleanClerkCleverClickClientCliffClimbClinicClipClockClogCloseClothCloudClownClubClumpClusterClutchCoachCoastCoconutCodeCoffeeCoilCoinCollectColorColumnCombineComeComfortComicCommonCompanyConcertConductConfirmCongressConnectConsiderControlConvinceCookCoolCopperCopyCoralCoreCornCorrectCostCottonCouchCountryCoupleCourseCousinCoverCoyoteCrackCradleCraftCramCraneCrashCraterCrawlCrazyCreamCreditCreekCrewCricketCrimeCrispCriticCropCrossCrouchCrowdCrucialCruelCruiseCrumbleCrunchCrushCryCrystalCubeCultureCupCupboardCuriousCurrentCurtainCurveCushionCustomCuteCycleDadDamageDampDanceDangerDaringDashDaughterDawnDayDealDebateDebrisDecadeDecemberDecideDeclineDecorateDecreaseDeerDefenseDefineDefyDegreeDelayDeliverDemandDemiseDenialDentistDenyDepartDependDepositDepthDeputyDeriveDescribeDesertDesignDeskDespairDestroyDetailDetectDevelopDeviceDevoteDiagramDialDiamondDiaryDiceDieselDietDifferDigitalDignityDilemmaDinnerDinosaurDirectDirtDisagreeDiscoverDiseaseDishDismissDisorderDisplayDistanceDivertDivideDivorceDizzyDoctorDocumentDogDollDolphinDomainDonateDonkeyDonorDoorDoseDoubleDoveDraftDragonDramaDrasticDrawDreamDressDriftDrillDrinkDripDriveDropDrumDryDuckDumbDuneDuringDustDutchDutyDwarfDynamicEagerEagleEarlyEarnEarthEasilyEastEasyEchoEcologyEconomyEdgeEditEducateEffortEggEightEitherElbowElderElectricElegantElementElephantElevatorEliteElseEmbarkEmbodyEmbraceEmergeEmotionEmployEmpowerEmptyEnableEnactEndEndlessEndorseEnemyEnergyEnforceEngageEngineEnhanceEnjoyEnlistEnoughEnrichEnrollEnsureEnterEntireEntryEnvelopeEpisodeEqualEquipEraEraseErodeErosionErrorEruptEscapeEssayEssenceEstateEternalEthicsEvidenceEvilEvokeEvolveExactExampleExcessExchangeExciteExcludeExcuseExecuteExerciseExhaustExhibitExileExistExitExoticExpandExpectExpireExplainExposeExpressExtendExtraEyeEyebrowFabricFaceFacultyFadeFaintFaithFallFalseFameFamilyFamousFanFancyFantasyFarmFashionFatFatalFatherFatigueFaultFavoriteFeatureFebruaryFederalFeeFeedFeelFemaleFenceFestivalFetchFeverFewFiberFictionFieldFigureFileFilmFilterFinalFindFineFingerFinishFireFirmFirstFiscalFishFitFitnessFixFlagFlameFlashFlatFlavorFleeFlightFlipFloatFlockFloorFlowerFluidFlushFlyFoamFocusFogFoilFoldFollowFoodFootForceForestForgetForkFortuneForumForwardFossilFosterFoundFoxFragileFrameFrequentFreshFriendFringeFrogFrontFrostFrownFrozenFruitFuelFunFunnyFurnaceFuryFutureGadgetGainGalaxyGalleryGameGapGarageGarbageGardenGarlicGarmentGasGaspGateGatherGaugeGazeGeneralGeniusGenreGentleGenuineGestureGhostGiantGiftGiggleGingerGiraffeGirlGiveGladGlanceGlareGlassGlideGlimpseGlobeGloomGloryGloveGlowGlueGoatGoddessGoldGoodGooseGorillaGospelGossipGovernGownGrabGraceGrainGrantGrapeGrassGravityGreatGreenGridGriefGritGroceryGroupGrowGruntGuardGuessGuideGuiltGuitarGunGymHabitHairHalfHammerHamsterHandHappyHarborHardHarshHarvestHatHaveHawkHazardHeadHealthHeartHeavyHedgehogHeightHelloHelmetHelpHenHeroHiddenHighHillHintHipHireHistoryHobbyHockeyHoldHoleHolidayHollowHomeHoneyHoodHopeHornHorrorHorseHospitalHostHotelHourHoverHubHugeHumanHumbleHumorHundredHungryHuntHurdleHurryHurtHusbandHybridIceIconIdeaIdentifyIdleIgnoreIllIllegalIllnessImageImitateImmenseImmuneImpactImposeImproveImpulseInchIncludeIncomeIncreaseIndexIndicateIndoorIndustryInfantInflictInformInhaleInheritInitialInjectInjuryInmateInnerInnocentInputInquiryInsaneInsectInsideInspireInstallIntactInterestIntoInvestInviteInvolveIronIslandIsolateIssueItemIvoryJacketJaguarJarJazzJealousJeansJellyJewelJobJoinJokeJourneyJoyJudgeJuiceJumpJungleJuniorJunkJustKangarooKeenKeepKetchupKeyKickKidKidneyKindKingdomKissKitKitchenKiteKittenKiwiKneeKnifeKnockKnowLabLabelLaborLadderLadyLakeLampLanguageLaptopLargeLaterLatinLaughLaundryLavaLawLawnLawsuitLayerLazyLeaderLeafLearnLeaveLectureLeftLegLegalLegendLeisureLemonLendLengthLensLeopardLessonLetterLevelLiarLibertyLibraryLicenseLifeLiftLightLikeLimbLimitLinkLionLiquidListLittleLiveLizardLoadLoanLobsterLocalLockLogicLonelyLongLoopLotteryLoudLoungeLoveLoyalLuckyLuggageLumberLunarLunchLuxuryLyricsMachineMadMagicMagnetMaidMailMainMajorMakeMammalManManageMandateMangoMansionManualMapleMarbleMarchMarginMarineMarketMarriageMaskMassMasterMatchMaterialMathMatrixMatterMaximumMazeMeadowMeanMeasureMeatMechanicMedalMediaMelodyMeltMemberMemoryMentionMenuMercyMergeMeritMerryMeshMessageMetalMethodMiddleMidnightMilkMillionMimicMindMinimumMinorMinuteMiracleMirrorMiseryMissMistakeMixMixedMixtureMobileModelModifyMomMomentMonitorMonkeyMonsterMonthMoonMoralMoreMorningMosquitoMotherMotionMotorMountainMouseMoveMovieMuchMuffinMuleMultiplyMuscleMuseumMushroomMusicMustMutualMyselfMysteryMythNaiveNameNapkinNarrowNastyNationNatureNearNeckNeedNegativeNeglectNeitherNephewNerveNestNetNetworkNeutralNeverNewsNextNiceNightNobleNoiseNomineeNoodleNormalNorthNoseNotableNoteNothingNoticeNovelNowNuclearNumberNurseNutOakObeyObjectObligeObscureObserveObtainObviousOccurOceanOctoberOdorOffOfferOfficeOftenOilOkayOldOliveOlympicOmitOnceOneOnionOnlineOnlyOpenOperaOpinionOpposeOptionOrangeOrbitOrchardOrderOrdinaryOrganOrientOriginalOrphanOstrichOtherOutdoorOuterOutputOutsideOvalOvenOverOwnOwnerOxygenOysterOzonePactPaddlePagePairPalacePalmPandaPanelPanicPantherPaperParadeParentParkParrotPartyPassPatchPathPatientPatrolPatternPausePavePaymentPeacePeanutPearPeasantPelicanPenPenaltyPencilPeoplePepperPerfectPermitPersonPetPhonePhotoPhrasePhysicalPianoPicnicPicturePiecePigPigeonPillPilotPinkPioneerPipePistolPitchPizzaPlacePlanetPlasticPlatePlayPleasePledgePluckPlugPlungePoemPoetPointPolarPolePolicePondPonyPoolPopularPortionPositionPossiblePostPotatoPotteryPovertyPowderPowerPracticePraisePredictPreferPreparePresentPrettyPreventPricePridePrimaryPrintPriorityPrisonPrivatePrizeProblemProcessProduceProfitProgramProjectPromoteProofPropertyProsperProtectProudProvidePublicPuddingPullPulpPulsePumpkinPunchPupilPuppyPurchasePurityPurposePursePushPutPuzzlePyramidQualityQuantumQuarterQuestionQuickQuitQuizQuoteRabbitRaccoonRaceRackRadarRadioRailRainRaiseRallyRampRanchRandomRangeRapidRareRateRatherRavenRawRazorReadyRealReasonRebelRebuildRecallReceiveRecipeRecordRecycleReduceReflectReformRefuseRegionRegretRegularRejectRelaxReleaseReliefRelyRemainRememberRemindRemoveRenderRenewRentReopenRepairRepeatReplaceReportRequireRescueResembleResistResourceResponseResultRetireRetreatReturnReunionRevealReviewRewardRhythmRibRibbonRiceRichRideRidgeRifleRightRigidRingRiotRippleRiskRitualRivalRiverRoadRoastRobotRobustRocketRomanceRoofRookieRoomRoseRotateRoughRoundRouteRoyalRubberRudeRugRuleRunRunwayRuralSadSaddleSadnessSafeSailSaladSalmonSalonSaltSaluteSameSampleSandSatisfySatoshiSauceSausageSaveSayScaleScanScareScatterSceneSchemeSchoolScienceScissorsScorpionScoutScrapScreenScriptScrubSeaSearchSeasonSeatSecondSecretSectionSecuritySeedSeekSegmentSelectSellSeminarSeniorSenseSentenceSeriesServiceSessionSettleSetupSevenShadowShaftShallowShareShedShellSheriffShieldShiftShineShipShiverShockShoeShootShopShortShoulderShoveShrimpShrugShuffleShySiblingSickSideSiegeSightSignSilentSilkSillySilverSimilarSimpleSinceSingSirenSisterSituateSixSizeSkateSketchSkiSkillSkinSkirtSkullSlabSlamSleepSlenderSliceSlideSlightSlimSloganSlotSlowSlushSmallSmartSmileSmokeSmoothSnackSnakeSnapSniffSnowSoapSoccerSocialSockSodaSoftSolarSoldierSolidSolutionSolveSomeoneSongSoonSorrySortSoulSoundSoupSourceSouthSpaceSpareSpatialSpawnSpeakSpecialSpeedSpellSpendSphereSpiceSpiderSpikeSpinSpiritSplitSpoilSponsorSpoonSportSpotSpraySpreadSpringSpySquareSqueezeSquirrelStableStadiumStaffStageStairsStampStandStartStateStaySteakSteelStemStepStereoStickStillStingStockStomachStoneStoolStoryStoveStrategyStreetStrikeStrongStruggleStudentStuffStumbleStyleSubjectSubmitSubwaySuccessSuchSuddenSufferSugarSuggestSuitSummerSunSunnySunsetSuperSupplySupremeSureSurfaceSurgeSurpriseSurroundSurveySuspectSustainSwallowSwampSwapSwarmSwearSweetSwiftSwimSwingSwitchSwordSymbolSymptomSyrupSystemTableTackleTagTailTalentTalkTankTapeTargetTaskTasteTattooTaxiTeachTeamTellTenTenantTennisTentTermTestTextThankThatThemeThenTheoryThereTheyThingThisThoughtThreeThriveThrowThumbThunderTicketTideTigerTiltTimberTimeTinyTipTiredTissueTitleToastTobaccoTodayToddlerToeTogetherToiletTokenTomatoTomorrowToneTongueTonightToolToothTopTopicToppleTorchTornadoTortoiseTossTotalTouristTowardTowerTownToyTrackTradeTrafficTragicTrainTransferTrapTrashTravelTrayTreatTreeTrendTrialTribeTrickTriggerTrimTripTrophyTroubleTruckTrueTrulyTrumpetTrustTruthTryTubeTuitionTumbleTunaTunnelTurkeyTurnTurtleTwelveTwentyTwiceTwinTwistTwoTypeTypicalUglyUmbrellaUnableUnawareUncleUncoverUnderUndoUnfairUnfoldUnhappyUniformUniqueUnitUniverseUnknownUnlockUntilUnusualUnveilUpdateUpgradeUpholdUponUpperUpsetUrbanUrgeUsageUseUsedUsefulUselessUsualUtilityVacantVacuumVagueValidValleyValveVanVanishVaporVariousVastVaultVehicleVelvetVendorVentureVenueVerbVerifyVersionVeryVesselVeteranViableVibrantViciousVictoryVideoViewVillageVintageViolinVirtualVirusVisaVisitVisualVitalVividVocalVoiceVoidVolcanoVolumeVoteVoyageWageWagonWaitWalkWallWalnutWantWarfareWarmWarriorWashWaspWasteWaterWaveWayWealthWeaponWearWeaselWeatherWebWeddingWeekendWeirdWelcomeWestWetWhaleWhatWheatWheelWhenWhereWhipWhisperWideWidthWifeWildWillWinWindowWineWingWinkWinnerWinterWireWisdomWiseWishWitnessWolfWomanWonderWoodWoolWordWorkWorldWorryWorthWrapWreckWrestleWristWriteWrongYardYearYellowYouYoungYouthZebraZeroZoneZoo"
|
||
|
||
},{}]},{},[60]);
|