tera/Source/HTML/JS/sha3.js
2019-07-12 20:45:46 +08:00

804 lines
28 KiB
JavaScript

/*
* @project: TERA
* @version: Development (beta)
* @license: MIT (not for evil)
* @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com]
* Web: https://terafoundation.org
* Twitter: https://twitter.com/terafoundation
* Telegram: https://t.me/terafoundation
*/
(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.RUN_NW_CLIENT)
{
root = global;
}
if(root.RUN_CLIENT)
{
root = window;
}
var COMMON_JS = !root.JS_SHA3_NO_COMMON_JS && typeof module === 'object' && module.exports;
var ARRAY_BUFFER = !root.JS_SHA3_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
var HEX_CHARS = '0123456789abcdef'.split('');
var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
var CSHAKE_PADDING = [4, 1024, 262144, 67108864];
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 CSHAKE_BYTEPAD = {'128':168, '256':136};
if(root.JS_SHA3_NO_NODE_JS || !Array.isArray)
{
Array.isArray = function (obj)
{
return Object.prototype.toString.call(obj) === '[object 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 createCshakeOutputMethod = function (bits,padding,outputType)
{
return function (message,outputBits,n,s)
{
return methods['cshake' + bits].update(message, outputBits, n, s)[outputType]();
};
};
var createKmacOutputMethod = function (bits,padding,outputType)
{
return function (key,message,outputBits,s)
{
return methods['kmac' + bits].update(key, message, outputBits, s)[outputType]();
};
};
var createOutputMethods = function (method,createMethod,bits,padding)
{
for(var i = 0; i < OUTPUT_TYPES.length; ++i)
{
var type = OUTPUT_TYPES[i];
method[type] = createMethod(bits, padding, type);
}
return method;
};
var createMethod = function (bits,padding,outputs)
{
var method = createOutputMethod(bits, padding, outputs);
method.create = function ()
{
return new Keccak(bits, padding, bits);
};
method.update = function (message)
{
return method.create().update(message);
};
return createOutputMethods(method, createOutputMethod, bits, padding);
};
var createMethodArray = function (bits,padding)
{
var method = createOutputMethod(bits, padding, 'array');
method.create = function ()
{
return new Keccak(bits, padding, bits);
};
method.update = function (message)
{
return method.create().update(message);
};
return createOutputMethods(method, createOutputMethod, bits, padding);
};
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);
};
return createOutputMethods(method, createShakeOutputMethod, bits, padding);
};
var createCshakeMethod = function (bits,padding)
{
var w = CSHAKE_BYTEPAD[bits];
var method = createCshakeOutputMethod(bits, padding, 'hex');
method.create = function (outputBits,n,s)
{
if(!n && !s)
{
return methods['shake' + bits].create(outputBits);
}
else
{
return new Keccak(bits, padding, outputBits).bytepad([n, s], w);
}
};
method.update = function (message,outputBits,n,s)
{
return method.create(outputBits, n, s).update(message);
};
return createOutputMethods(method, createCshakeOutputMethod, bits, padding);
};
var createKmacMethod = function (bits,padding)
{
var w = CSHAKE_BYTEPAD[bits];
var method = createKmacOutputMethod(bits, padding, 'hex');
method.create = function (key,outputBits,s)
{
return new Kmac(bits, padding, outputBits).bytepad(['KMAC', s], w).bytepad([key], w);
};
method.update = function (key,message,outputBits,s)
{
return method.create(key, outputBits, s).update(message);
};
return createOutputMethods(method, createKmacOutputMethod, bits, padding);
};
var algorithms = [{name:'keccak', padding:KECCAK_PADDING, bits:BITS, createMethod:createMethod}, {name:'sha3', padding:PADDING,
bits:BITS, createMethod:createMethod, outputs:'hex'}, {name:'sha3_array', padding:PADDING, bits:BITS, createMethod:createMethod,
outputs:'array'}, {name:'sha3_buf', padding:PADDING, bits:BITS, createMethod:createMethod, outputs:'buffer'}, {name:'shake',
padding:SHAKE_PADDING, bits:SHAKE_BITS, createMethod:createShakeMethod}, {name:'cshake', padding:CSHAKE_PADDING, bits:SHAKE_BITS,
createMethod:createCshakeMethod}, {name:'kmac', padding:CSHAKE_PADDING, bits:SHAKE_BITS, createMethod:createKmacMethod}];
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, algorithm.outputs);
if(algorithm.name !== 'sha3')
{
var newMethodName = algorithm.name + bits[j];
methodNames.push(newMethodName);
methods[newMethodName] = methods[methodName];
}
}
}
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)
{
TO_ERROR_LOG("SHA3", 10, 'ERROR: Error type ArrayBuffer, use Uint8Array instead!');
return [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 length = message.length;
if(notString)
{
if(typeof length !== 'number' || !Array.isArray(message) && !(ARRAY_BUFFER && ArrayBuffer.isView(message)))
{
TO_ERROR_LOG("SHA3", 20, 'ERROR: Input is invalid type, message=' + JSON.stringify(message));
return [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 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.encode = function (x,right)
{
var o = x & 255, n = 1;
var bytes = [o];
x = x >> 8;
o = x & 255;
while(o > 0)
{
bytes.unshift(o);
x = x >> 8;
o = x & 255;
++n;
}
if(right)
{
bytes.push(n);
}
else
{
bytes.unshift(n);
}
this.update(bytes);
return bytes.length;
};
Keccak.prototype.encodeString = function (str)
{
str = str || '';
var notString = typeof str !== 'string';
if(notString && str.constructor === root.ArrayBuffer)
{
str = new Uint8Array(str);
}
var length = str.length;
if(notString)
{
if(typeof length !== 'number' || !Array.isArray(str) && !(ARRAY_BUFFER && ArrayBuffer.isView(str)))
{
TO_ERROR_LOG("SHA3", 30, 'ERROR: Input is invalid type, str=' + JSON.stringify(str));
return [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 bytes = 0;
if(notString)
{
bytes = length;
}
else
{
for(var i = 0; i < str.length; ++i)
{
var code = str.charCodeAt(i);
if(code < 0x80)
{
bytes += 1;
}
else
if(code < 0x800)
{
bytes += 2;
}
else
if(code < 0xd800 || code >= 0xe000)
{
bytes += 3;
}
else
{
code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
bytes += 4;
}
}
}
bytes += this.encode(bytes * 8);
this.update(str);
return bytes;
};
Keccak.prototype.bytepad = function (strs,w)
{
var bytes = this.encode(w);
for(var i = 0; i < strs.length; ++i)
{
bytes += this.encodeString(strs[i]);
}
var paddingBytes = w - bytes % w;
var zeros = [];
zeros.length = paddingBytes;
this.update(zeros);
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;
};
function Kmac(bits,padding,outputBits)
{
Keccak.call(this, bits, padding, outputBits);
};
Kmac.prototype = new Keccak();
Kmac.prototype.finalize = function ()
{
this.encode(this.outputBits, true);
return Keccak.prototype.finalize.call(this);
};
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];
}
};
root.sha3_str = methods.sha3_256;
root.sha3_array_256 = methods.sha3_array_256;
root.sha3 = methods.sha3_array_256;
root.sha = function (data)
{
return meshhash(methods.sha3_256(data));
};
root.shaarr = function (data)
{
return meshhash(methods.sha3_array_256(data));
};
root.shabuf = function (data)
{
return Buffer.from(shaarr(data));
};
root.shabuf = function (data)
{
return Buffer.from(shaarr(data));
};
root.SHA3BUF = function (data,num)
{
return Buffer.from(SHA3ARR(data, num));
};
root.SHA3ARR = function (data,num)
{
if(!NEW_SIGN_TIME || !num || num >= NEW_SIGN_TIME)
return sha3(data);
else
return meshhash(methods.sha3_array_256(data));
};
root.shaarrblock = function (data,num)
{
return meshhash(methods.sha3_array_256(data), num);
};
})();
function meshhash(hash,num)
{
var regs = [hash[3], hash[2], hash[1], hash[0]];
var mem = [];
for(var i = 0; i < 16; i++)
{
mem[i] = hash[i * 2] + (hash[i * 2 + 1] << 8);
}
var WasGoto = 0;
var L = 0;
for(var i = 0; i < 64; i++)
{
var c = hash[L & 31];
L++;
var a = (c >> 4) & 0xF;
var b = c & 0xF;
var r = c & 0x3;
switch(a)
{
case 0:
regs[0] = regs[0] + regs[r];
break;
case 1:
regs[0] = regs[0] * regs[r];
break;
case 2:
regs[0] = regs[0] | regs[r];
break;
case 3:
regs[0] = regs[0] & regs[r];
break;
case 4:
case 5:
case 6:
case 7:
regs[0] = regs[0] + regs[1] + regs[2] + regs[3];
break;
case 8:
if((regs[0] & 0xFFFF) < 32768 && !WasGoto)
{
L = 32 + L - b;
WasGoto = 1;
}
break;
case 9:
if((regs[0] & 0xFFFF) > 32768 && !WasGoto)
{
L += b;
WasGoto = 1;
}
break;
default:
regs[a % 4] = mem[b];
}
var index1 = regs[0] & 0xF;
var index2 = (regs[0] >> 8) & 0xF;
if(index1 !== index2)
{
var temp = mem[index1];
mem[index1] = mem[index2];
mem[index2] = temp;
}
}
var ret = [];
for(var i = 0; i < 16; i++)
{
ret[i * 2] = mem[i] & 0xFF;
ret[i * 2 + 1] = mem[i] >> 8;
}
return sha3_array_256(ret);
};