Merge b7535c2239
into 37c86c23e0
commit
7577f9a2d2
@ -1,4 +1,5 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
coverage
|
||||
.vscode
|
||||
.vscode
|
||||
yarn-error.log
|
@ -1,97 +0,0 @@
|
||||
// Copyright (c) 2014-2018, MyMonero.com
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
(function(exports)
|
||||
{
|
||||
var crc32 = (function () {
|
||||
'use strict';
|
||||
var crc32 = {};
|
||||
|
||||
crc32.Utf8Encode = function (string) {
|
||||
return unescape(encodeURIComponent(string));
|
||||
};
|
||||
|
||||
crc32.run = function (str) {
|
||||
var crc = new crc32.Type();
|
||||
crc.processString(str);
|
||||
return crc.checksum();
|
||||
};
|
||||
|
||||
crc32.table = [
|
||||
0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
|
||||
249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
|
||||
498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
|
||||
325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
|
||||
997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
|
||||
901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
|
||||
651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
|
||||
671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
|
||||
1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
|
||||
2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
|
||||
1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
|
||||
1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
|
||||
1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
|
||||
1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
|
||||
1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
|
||||
1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
|
||||
3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
|
||||
3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
|
||||
4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
|
||||
4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
|
||||
3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
|
||||
3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
|
||||
3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
|
||||
3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
|
||||
2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
|
||||
2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
|
||||
2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
|
||||
2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
|
||||
2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
|
||||
2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
|
||||
3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
|
||||
3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117
|
||||
];
|
||||
crc32.Type = function () {
|
||||
this.rem_ = 0xFFFFFFFF;
|
||||
this.checksum = function () {
|
||||
return ((this.rem_ ^ 0xFFFFFFFF) >>> 0);
|
||||
};
|
||||
this.processString = function (str) {
|
||||
str = crc32.Utf8Encode(str);
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
var byte_index = ((str.charCodeAt(i) ^ this.rem_) >>> 0) & 0xFF;
|
||||
this.rem_ = ((this.rem_ >>> 8) ^ crc32.table[byte_index]) >>> 0;
|
||||
}
|
||||
};
|
||||
return this;
|
||||
};
|
||||
|
||||
return crc32;
|
||||
})();
|
||||
exports.crc32 = crc32;
|
||||
})(typeof exports !== 'undefined' ? exports : this);
|
File diff suppressed because it is too large
Load Diff
@ -1,473 +0,0 @@
|
||||
/*
|
||||
* js-sha3 v0.5.1
|
||||
* https://github.com/emn178/js-sha3
|
||||
*
|
||||
* Copyright 2015, emn178@gmail.com
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
;(function(root, undefined) {
|
||||
'use strict';
|
||||
|
||||
var NODE_JS = typeof(module) != 'undefined';
|
||||
if(NODE_JS) {
|
||||
root = global;
|
||||
if(root.JS_SHA3_TEST) {
|
||||
root.navigator = { userAgent: 'Chrome'};
|
||||
}
|
||||
}
|
||||
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', '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 = {};
|
||||
|
||||
for(var i = 0;i < algorithms.length;++i) {
|
||||
var algorithm = algorithms[i];
|
||||
var bits = algorithm.bits;
|
||||
var createMethod = algorithm.createMethod;
|
||||
for(var j = 0;j < bits.length;++j) {
|
||||
var method = algorithm.createMethod(bits[j], algorithm.padding);
|
||||
methods[algorithm.name +'_' + bits[j]] = method;
|
||||
}
|
||||
}
|
||||
|
||||
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 == root.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);
|
||||
}
|
||||
}
|
||||
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.buffer = 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.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(!root.JS_SHA3_TEST && NODE_JS) {
|
||||
module.exports = methods;
|
||||
} else if(root) {
|
||||
for(var key in methods) {
|
||||
root[key] = methods[key];
|
||||
}
|
||||
}
|
||||
}(this));
|
@ -0,0 +1,19 @@
|
||||
declare module "keccakjs" {
|
||||
type Message = Buffer | string;
|
||||
|
||||
class Hasher {
|
||||
/**
|
||||
* Update hash
|
||||
*
|
||||
* @param message The message you want to hash.
|
||||
*/
|
||||
update(message: Message): Hasher;
|
||||
|
||||
/**
|
||||
* Return hash in integer array.
|
||||
*/
|
||||
digest(): number[];
|
||||
}
|
||||
|
||||
export = Hasher;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
// Copyright (c) 2014-2018, MyMonero.com
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
"use strict";
|
||||
//
|
||||
const monero_wallet_utils = require("./monero_wallet_utils");
|
||||
//
|
||||
function MnemonicWordsetNameWithLocale(
|
||||
currentLocale, // e.g. 'en'
|
||||
) {
|
||||
const mnemonicWordsetNamesByAppLocaleNames =
|
||||
monero_wallet_utils.MnemonicWordsetNamesByAppLocaleNames;
|
||||
if (currentLocale.indexOf("en") === 0) {
|
||||
return mnemonicWordsetNamesByAppLocaleNames.English;
|
||||
} else if (currentLocale.indexOf("es") === 0) {
|
||||
return mnemonicWordsetNamesByAppLocaleNames.Spanish;
|
||||
} else if (currentLocale.indexOf("pt") === 0) {
|
||||
return mnemonicWordsetNamesByAppLocaleNames.Portuguese;
|
||||
} else if (currentLocale.indexOf("ja") === 0) {
|
||||
return mnemonicWordsetNamesByAppLocaleNames.Japanese;
|
||||
}
|
||||
return monero_wallet_utils.DefaultWalletMnemonicWordsetName; // which would be .English
|
||||
}
|
||||
exports.MnemonicWordsetNameWithLocale = MnemonicWordsetNameWithLocale;
|
@ -1,377 +0,0 @@
|
||||
// Copyright (c) 2014-2018, MyMonero.com
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"use strict";
|
||||
//
|
||||
const mnemonic = require("../cryptonote_utils/mnemonic");
|
||||
const monero_utils = require("./monero_cryptonote_utils_instance");
|
||||
const monero_config = require("./monero_config");
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Mnemonic wordset utilities - Exposing available names
|
||||
//
|
||||
const wordsetNamesByWordsetName = {};
|
||||
const allWordsetNames = Object.keys(mnemonic.mn_words);
|
||||
for (let wordsetName of allWordsetNames) {
|
||||
wordsetNamesByWordsetName[wordsetName] = wordsetName;
|
||||
}
|
||||
exports.WordsetNamesByWordsetName = wordsetNamesByWordsetName;
|
||||
exports.AllWordsetNames = allWordsetNames;
|
||||
//
|
||||
//
|
||||
// Mnemonic wordset utilities - Comparison
|
||||
// TODO: perhaps move this to mnemonic.js
|
||||
function AreEqualMnemonics(a, b, a__wordsetName, b__wordsetName) {
|
||||
if (a__wordsetName !== b__wordsetName) {
|
||||
return false;
|
||||
}
|
||||
const wordsetName = a__wordsetName;
|
||||
const wordset = mnemonic.mn_words[wordsetName];
|
||||
const prefix_len = wordset.prefix_len;
|
||||
// since mnemonics can be entered with only the first N letters, we must check equality of mnemonics by prefix
|
||||
let a__mnemonicString_words = a.split(" ");
|
||||
let b__mnemonicString_words = b.split(" ");
|
||||
if (a__mnemonicString_words.length != b__mnemonicString_words.length) {
|
||||
return false;
|
||||
}
|
||||
let numberOf_mnemonicString_words = a__mnemonicString_words.length;
|
||||
for (var i = 0; i < numberOf_mnemonicString_words; i++) {
|
||||
let a__word = a__mnemonicString_words[i];
|
||||
let b__word = b__mnemonicString_words[i];
|
||||
// ... We're assuming that a and b are already valid mneminics
|
||||
const a_prefix = a__word.slice(0, prefix_len);
|
||||
const b_prefix = b__word.slice(0, prefix_len);
|
||||
if (a_prefix !== b_prefix) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.AreEqualMnemonics = AreEqualMnemonics;
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Mnemonic wordset utilities - Wordset name detection by mnemonic contents
|
||||
// TODO: perhaps move this to mnemonic.js
|
||||
function WordsetNameAccordingToMnemonicString(
|
||||
mnemonicString, // throws
|
||||
) {
|
||||
const mnemonicString_words = mnemonicString.split(" ");
|
||||
if (mnemonicString_words.length == 0) {
|
||||
throw "Invalid mnemonic";
|
||||
}
|
||||
var wholeMnemonicSuspectedAsWordsetNamed = null; // to derive
|
||||
for (let mnemonicString_word of mnemonicString_words) {
|
||||
var thisWordIsInWordsetNamed = null; // to derive
|
||||
for (let wordsetName of allWordsetNames) {
|
||||
if (wordsetName === "electrum") {
|
||||
continue; // skip because it conflicts with 'english'
|
||||
}
|
||||
const wordset = mnemonic.mn_words[wordsetName];
|
||||
const prefix_len = wordset.prefix_len;
|
||||
if (mnemonicString_word.length < prefix_len) {
|
||||
throw "Please enter more than " +
|
||||
(prefix_len - 1) +
|
||||
" letters per word";
|
||||
}
|
||||
const wordsetWords = wordset.words;
|
||||
for (let wordsetWord of wordsetWords) {
|
||||
if (wordsetWord.indexOf(mnemonicString_word) == 0) {
|
||||
// we can safely check prefix b/c we've checked mnemonicString_word is of at least min length
|
||||
thisWordIsInWordsetNamed = wordsetName;
|
||||
break; // done looking; exit interior then exterior loops
|
||||
}
|
||||
}
|
||||
if (thisWordIsInWordsetNamed != null) {
|
||||
// just found
|
||||
break; // also exit
|
||||
}
|
||||
// haven't found it yet; keep looking
|
||||
}
|
||||
if (thisWordIsInWordsetNamed === null) {
|
||||
// didn't find this word in any of the mnemonic wordsets
|
||||
throw "Unrecognized mnemonic language";
|
||||
}
|
||||
if (wholeMnemonicSuspectedAsWordsetNamed === null) {
|
||||
// haven't found it yet
|
||||
wholeMnemonicSuspectedAsWordsetNamed = thisWordIsInWordsetNamed;
|
||||
} else if (
|
||||
thisWordIsInWordsetNamed !== wholeMnemonicSuspectedAsWordsetNamed
|
||||
) {
|
||||
throw "Ambiguous mnemonic language"; // multiple wordset names detected
|
||||
} else {
|
||||
// nothing to do but keep verifying the rest of the words that it's the same suspsected wordset
|
||||
}
|
||||
}
|
||||
if (wholeMnemonicSuspectedAsWordsetNamed === null) {
|
||||
// this might be redundant, but for logical rigor……
|
||||
throw "Unrecognized mnemonic language";
|
||||
}
|
||||
//
|
||||
return wholeMnemonicSuspectedAsWordsetNamed;
|
||||
}
|
||||
exports.WordsetNameAccordingToMnemonicString = WordsetNameAccordingToMnemonicString;
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Mnemonic wordset utilities - By locale
|
||||
//
|
||||
const mnemonicWordsetNamesByAppLocaleNames = {
|
||||
English: "english",
|
||||
Japanese: "japanese",
|
||||
Spanish: "spanish",
|
||||
Portuguese: "portuguese",
|
||||
// NOTE: no support for 'electrum' wordset here
|
||||
};
|
||||
exports.MnemonicWordsetNamesByAppLocaleNames = mnemonicWordsetNamesByAppLocaleNames;
|
||||
//
|
||||
exports.DefaultWalletMnemonicWordsetName =
|
||||
mnemonicWordsetNamesByAppLocaleNames.English;
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Wallet creation:
|
||||
//
|
||||
function NewlyCreatedWallet(mnemonic_wordsetName, nettype) {
|
||||
const seed = monero_utils.random_scalar(); // to generate a 32-byte (25-word) but reduced seed
|
||||
const mnemonicString = mnemonic.mn_encode(seed, mnemonic_wordsetName);
|
||||
const keys = monero_utils.create_address(seed, nettype);
|
||||
//
|
||||
return {
|
||||
seed: seed,
|
||||
mnemonicString: mnemonicString,
|
||||
keys: keys,
|
||||
};
|
||||
}
|
||||
exports.NewlyCreatedWallet = NewlyCreatedWallet;
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Wallet login:
|
||||
//
|
||||
function MnemonicStringFromSeed(account_seed, mnemonic_wordsetName) {
|
||||
const mnemonicString = mnemonic.mn_encode(
|
||||
account_seed,
|
||||
mnemonic_wordsetName,
|
||||
);
|
||||
//
|
||||
return mnemonicString;
|
||||
}
|
||||
exports.MnemonicStringFromSeed = MnemonicStringFromSeed;
|
||||
//
|
||||
function SeedAndKeysFromMnemonic_sync(
|
||||
mnemonicString,
|
||||
mnemonic_wordsetName,
|
||||
nettype,
|
||||
) {
|
||||
// -> {err_str?, seed?, keys?}
|
||||
mnemonicString = mnemonicString.toLowerCase() || "";
|
||||
try {
|
||||
var seed = null;
|
||||
var keys = null;
|
||||
switch (mnemonic_wordsetName) {
|
||||
case "english":
|
||||
try {
|
||||
seed = mnemonic.mn_decode(mnemonicString);
|
||||
} catch (e) {
|
||||
// Try decoding as an electrum seed, on failure throw the original exception
|
||||
try {
|
||||
seed = mnemonic.mn_decode(mnemonicString, "electrum");
|
||||
} catch (ee) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
seed = mnemonic.mn_decode(mnemonicString, mnemonic_wordsetName);
|
||||
break;
|
||||
}
|
||||
if (seed === null) {
|
||||
return { err_str: "Unable to derive seed", seed: null, keys: null };
|
||||
}
|
||||
keys = monero_utils.create_address(seed, nettype);
|
||||
if (keys === null) {
|
||||
return {
|
||||
err_str: "Unable to derive keys from seed",
|
||||
seed: seed,
|
||||
keys: null,
|
||||
};
|
||||
}
|
||||
return { err_str: null, seed: seed, keys: keys };
|
||||
} catch (e) {
|
||||
console.error("Invalid mnemonic!");
|
||||
return {
|
||||
err_str: typeof e === "string" ? e : "" + e,
|
||||
seed: null,
|
||||
keys: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.SeedAndKeysFromMnemonic_sync = SeedAndKeysFromMnemonic_sync;
|
||||
|
||||
function SeedAndKeysFromMnemonic(
|
||||
mnemonicString,
|
||||
mnemonic_wordsetName,
|
||||
nettype,
|
||||
fn, // made available via callback not because it's async but for convenience
|
||||
) {
|
||||
// fn: (err?, seed?, keys?)
|
||||
const payload = SeedAndKeysFromMnemonic_sync(
|
||||
mnemonicString,
|
||||
mnemonic_wordsetName,
|
||||
nettype,
|
||||
);
|
||||
const err = payload.err_str ? new Error(payload.err_str) : null;
|
||||
const seed = payload.seed;
|
||||
const keys = payload.keys;
|
||||
fn(err, seed, keys);
|
||||
}
|
||||
exports.SeedAndKeysFromMnemonic = SeedAndKeysFromMnemonic;
|
||||
//
|
||||
function VerifiedComponentsForLogIn_sync(
|
||||
address,
|
||||
nettype,
|
||||
view_key,
|
||||
spend_key_orUndefinedForViewOnly,
|
||||
seed_orUndefined,
|
||||
wasAGeneratedWallet,
|
||||
) {
|
||||
var spend_key =
|
||||
typeof spend_key_orUndefinedForViewOnly !== "undefined" &&
|
||||
spend_key_orUndefinedForViewOnly != null &&
|
||||
spend_key_orUndefinedForViewOnly != ""
|
||||
? spend_key_orUndefinedForViewOnly
|
||||
: null;
|
||||
var isInViewOnlyMode = spend_key == null;
|
||||
if (
|
||||
!view_key ||
|
||||
view_key.length !== 64 ||
|
||||
(isInViewOnlyMode ? false : spend_key.length !== 64)
|
||||
) {
|
||||
return { err_str: "invalid secret key length" };
|
||||
}
|
||||
if (
|
||||
!monero_utils.valid_hex(view_key) ||
|
||||
(isInViewOnlyMode ? false : !monero_utils.valid_hex(spend_key))
|
||||
) {
|
||||
return { err_str: "invalid hex formatting" };
|
||||
}
|
||||
var public_keys;
|
||||
try {
|
||||
public_keys = monero_utils.decode_address(address, nettype);
|
||||
} catch (e) {
|
||||
return { err_str: "invalid address" };
|
||||
}
|
||||
var expected_view_pub;
|
||||
try {
|
||||
expected_view_pub = monero_utils.sec_key_to_pub(view_key);
|
||||
} catch (e) {
|
||||
return { err_str: "invalid view key" };
|
||||
}
|
||||
var expected_spend_pub;
|
||||
if (spend_key.length === 64) {
|
||||
try {
|
||||
expected_spend_pub = monero_utils.sec_key_to_pub(spend_key);
|
||||
} catch (e) {
|
||||
return { err_str: "invalid spend key" };
|
||||
}
|
||||
}
|
||||
if (public_keys.view !== expected_view_pub) {
|
||||
return { err_str: "invalid view key" };
|
||||
}
|
||||
if (!isInViewOnlyMode && public_keys.spend !== expected_spend_pub) {
|
||||
return { err_str: "invalid spend key" };
|
||||
}
|
||||
const private_keys = {
|
||||
view: view_key,
|
||||
spend: spend_key,
|
||||
};
|
||||
var account_seed = null; // default
|
||||
if (
|
||||
typeof seed_orUndefined !== "undefined" &&
|
||||
seed_orUndefined &&
|
||||
seed_orUndefined.length != 0
|
||||
) {
|
||||
var expected_account;
|
||||
try {
|
||||
expected_account = monero_utils.create_address(
|
||||
seed_orUndefined,
|
||||
nettype,
|
||||
);
|
||||
} catch (e) {
|
||||
return { err_str: "invalid seed" };
|
||||
}
|
||||
if (
|
||||
expected_account.view.sec !== view_key ||
|
||||
expected_account.spend.sec !== spend_key ||
|
||||
expected_account.public_addr !== address
|
||||
) {
|
||||
return { err_str: "invalid seed" };
|
||||
}
|
||||
account_seed = seed_orUndefined;
|
||||
}
|
||||
const payload = {
|
||||
err_str: null, // err
|
||||
address: address,
|
||||
account_seed: account_seed !== "" ? account_seed : null,
|
||||
public_keys: public_keys,
|
||||
private_keys: private_keys,
|
||||
isInViewOnlyMode: isInViewOnlyMode,
|
||||
};
|
||||
return payload;
|
||||
}
|
||||
exports.VerifiedComponentsForLogIn_sync = VerifiedComponentsForLogIn_sync;
|
||||
//
|
||||
function VerifiedComponentsForLogIn(
|
||||
address,
|
||||
nettype,
|
||||
view_key,
|
||||
spend_key_orUndefinedForViewOnly,
|
||||
seed_orUndefined,
|
||||
wasAGeneratedWallet,
|
||||
fn,
|
||||
) {
|
||||
// fn: (err?, address, account_seed, public_keys, private_keys, isInViewOnlyMode) -> Void
|
||||
const payload = VerifiedComponentsForLogIn_sync(
|
||||
address,
|
||||
nettype,
|
||||
view_key,
|
||||
spend_key_orUndefinedForViewOnly,
|
||||
seed_orUndefined,
|
||||
wasAGeneratedWallet,
|
||||
);
|
||||
fn(
|
||||
payload.err_str ? new Error(payload.err_str) : null,
|
||||
payload.address,
|
||||
payload.account_seed,
|
||||
payload.public_keys,
|
||||
payload.private_keys,
|
||||
payload.isInViewOnlyMode,
|
||||
);
|
||||
}
|
||||
exports.VerifiedComponentsForLogIn = VerifiedComponentsForLogIn;
|
Loading…
Reference in new issue