UNPKG

ibctminer

Version:

```js const IntMiner = require('./src'); const Debug = require('./src/log')(); const fs = require('fs'); const COMP = '[SIPC]';

428 lines (358 loc) 11.8 kB
/*! * keccak.js - Keccak/SHA3 implementation for bcrypto * Copyright (c) 2017-2019, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcrypto * * Parts of this software are based on emn178/js-sha3: * Copyright (c) 2015-2017, Chen, Yi-Cyuan (MIT License). * https://github.com/emn178/js-sha3 * * Parts of this software are based on rhash/RHash: * Copyright (c) 2005-2014, Aleksey Kravchenko * https://github.com/rhash/RHash * * Resources: * https://en.wikipedia.org/wiki/SHA-3 * https://keccak.team/specifications.html * https://csrc.nist.gov/projects/hash-functions/sha-3-project/sha-3-standardization * http://dx.doi.org/10.6028/NIST.FIPS.202 * https://github.com/rhash/RHash/blob/master/librhash/sha3.c * https://github.com/emn178/js-sha3/blob/master/src/sha3.js */ 'use strict'; const assert = require('./assert'); const HMAC = require('./hmac'); /* * Constants */ const FINALIZED = 0x80000000; const ROUND_CONST = new Uint32Array([ 0x00000001, 0x00000000, 0x00008082, 0x00000000, 0x0000808a, 0x80000000, 0x80008000, 0x80000000, 0x0000808b, 0x00000000, 0x80000001, 0x00000000, 0x80008081, 0x80000000, 0x00008009, 0x80000000, 0x0000008a, 0x00000000, 0x00000088, 0x00000000, 0x80008009, 0x00000000, 0x8000000a, 0x00000000, 0x8000808b, 0x00000000, 0x0000008b, 0x80000000, 0x00008089, 0x80000000, 0x00008003, 0x80000000, 0x00008002, 0x80000000, 0x00000080, 0x80000000, 0x0000800a, 0x00000000, 0x8000000a, 0x80000000, 0x80008081, 0x80000000, 0x00008080, 0x80000000, 0x80000001, 0x00000000, 0x80008008, 0x80000000 ]); /** * Keccak */ class Keccak { constructor() { this.state = new Uint32Array(50); this.block = Buffer.allocUnsafe(168); this.bs = 136; this.pos = FINALIZED; } init(bits) { if (bits == null) bits = 256; assert((bits & 0xffff) === bits); assert(bits >= 128); assert(bits <= 512); const rate = 1600 - bits * 2; assert(rate >= 0 && (rate & 63) === 0); this.bs = rate / 8; this.pos = 0; return this; } update(data) { assert(Buffer.isBuffer(data)); assert(!(this.pos & FINALIZED), 'Context is not initialized.'); let len = data.length; let pos = this.pos; let off = 0; this.pos = (this.pos + len) % this.bs; if (pos > 0) { let want = this.bs - pos; if (want > len) want = len; data.copy(this.block, pos, off, off + want); pos += want; len -= want; off += want; if (pos < this.bs) return this; this._transform(this.block, 0); } while (len >= this.bs) { this._transform(data, off); off += this.bs; len -= this.bs; } if (len > 0) data.copy(this.block, 0, off, off + len); return this; } final(pad, len) { if (pad == null) pad = 0x01; if (len == null || len === 0) len = 100 - this.bs / 2; assert((pad & 0xff) === pad); assert((len >>> 0) === len); assert(!(this.pos & FINALIZED), 'Context is not initialized.'); this.block.fill(0, this.pos, this.bs); this.block[this.pos] |= pad; this.block[this.bs - 1] |= 0x80; this._transform(this.block, 0); this.pos = FINALIZED; assert(len < this.bs); const out = Buffer.allocUnsafe(len); for (let i = 0; i < len; i++) out[i] = this.state[i >>> 2] >>> (8 * (i & 3)); for (let i = 0; i < 50; i++) this.state[i] = 0; for (let i = 0; i < this.bs; i++) this.block[i] = 0; return out; } _transform(block, off) { const count = this.bs / 4; const s = this.state; for (let i = 0; i < count; i++) s[i] ^= readU32(block, off + i * 4); for (let n = 0; n < 48; n += 2) { const c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; const c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; const c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42]; const c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43]; const c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44]; const c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45]; const c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46]; const c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47]; const c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48]; const c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49]; const h0 = c8 ^ ((c2 << 1) | (c3 >>> 31)); const l0 = c9 ^ ((c3 << 1) | (c2 >>> 31)); const h1 = c0 ^ ((c4 << 1) | (c5 >>> 31)); const l1 = c1 ^ ((c5 << 1) | (c4 >>> 31)); const h2 = c2 ^ ((c6 << 1) | (c7 >>> 31)); const l2 = c3 ^ ((c7 << 1) | (c6 >>> 31)); const h3 = c4 ^ ((c8 << 1) | (c9 >>> 31)); const l3 = c5 ^ ((c9 << 1) | (c8 >>> 31)); const h4 = c6 ^ ((c0 << 1) | (c1 >>> 31)); const l4 = c7 ^ ((c1 << 1) | (c0 >>> 31)); s[0] ^= h0; s[1] ^= l0; s[10] ^= h0; s[11] ^= l0; s[20] ^= h0; s[21] ^= l0; s[30] ^= h0; s[31] ^= l0; s[40] ^= h0; s[41] ^= l0; s[2] ^= h1; s[3] ^= l1; s[12] ^= h1; s[13] ^= l1; s[22] ^= h1; s[23] ^= l1; s[32] ^= h1; s[33] ^= l1; s[42] ^= h1; s[43] ^= l1; s[4] ^= h2; s[5] ^= l2; s[14] ^= h2; s[15] ^= l2; s[24] ^= h2; s[25] ^= l2; s[34] ^= h2; s[35] ^= l2; s[44] ^= h2; s[45] ^= l2; s[6] ^= h3; s[7] ^= l3; s[16] ^= h3; s[17] ^= l3; s[26] ^= h3; s[27] ^= l3; s[36] ^= h3; s[37] ^= l3; s[46] ^= h3; s[47] ^= l3; s[8] ^= h4; s[9] ^= l4; s[18] ^= h4; s[19] ^= l4; s[28] ^= h4; s[29] ^= l4; s[38] ^= h4; s[39] ^= l4; s[48] ^= h4; s[49] ^= l4; const b0 = s[0]; const b1 = s[1]; const b32 = (s[11] << 4) | (s[10] >>> 28); const b33 = (s[10] << 4) | (s[11] >>> 28); const b14 = (s[20] << 3) | (s[21] >>> 29); const b15 = (s[21] << 3) | (s[20] >>> 29); const b46 = (s[31] << 9) | (s[30] >>> 23); const b47 = (s[30] << 9) | (s[31] >>> 23); const b28 = (s[40] << 18) | (s[41] >>> 14); const b29 = (s[41] << 18) | (s[40] >>> 14); const b20 = (s[2] << 1) | (s[3] >>> 31); const b21 = (s[3] << 1) | (s[2] >>> 31); const b2 = (s[13] << 12) | (s[12] >>> 20); const b3 = (s[12] << 12) | (s[13] >>> 20); const b34 = (s[22] << 10) | (s[23] >>> 22); const b35 = (s[23] << 10) | (s[22] >>> 22); const b16 = (s[33] << 13) | (s[32] >>> 19); const b17 = (s[32] << 13) | (s[33] >>> 19); const b48 = (s[42] << 2) | (s[43] >>> 30); const b49 = (s[43] << 2) | (s[42] >>> 30); const b40 = (s[5] << 30) | (s[4] >>> 2); const b41 = (s[4] << 30) | (s[5] >>> 2); const b22 = (s[14] << 6) | (s[15] >>> 26); const b23 = (s[15] << 6) | (s[14] >>> 26); const b4 = (s[25] << 11) | (s[24] >>> 21); const b5 = (s[24] << 11) | (s[25] >>> 21); const b36 = (s[34] << 15) | (s[35] >>> 17); const b37 = (s[35] << 15) | (s[34] >>> 17); const b18 = (s[45] << 29) | (s[44] >>> 3); const b19 = (s[44] << 29) | (s[45] >>> 3); const b10 = (s[6] << 28) | (s[7] >>> 4); const b11 = (s[7] << 28) | (s[6] >>> 4); const b42 = (s[17] << 23) | (s[16] >>> 9); const b43 = (s[16] << 23) | (s[17] >>> 9); const b24 = (s[26] << 25) | (s[27] >>> 7); const b25 = (s[27] << 25) | (s[26] >>> 7); const b6 = (s[36] << 21) | (s[37] >>> 11); const b7 = (s[37] << 21) | (s[36] >>> 11); const b38 = (s[47] << 24) | (s[46] >>> 8); const b39 = (s[46] << 24) | (s[47] >>> 8); const b30 = (s[8] << 27) | (s[9] >>> 5); const b31 = (s[9] << 27) | (s[8] >>> 5); const b12 = (s[18] << 20) | (s[19] >>> 12); const b13 = (s[19] << 20) | (s[18] >>> 12); const b44 = (s[29] << 7) | (s[28] >>> 25); const b45 = (s[28] << 7) | (s[29] >>> 25); const b26 = (s[38] << 8) | (s[39] >>> 24); const b27 = (s[39] << 8) | (s[38] >>> 24); const b8 = (s[48] << 14) | (s[49] >>> 18); const 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] ^= ROUND_CONST[n + 0]; s[1] ^= ROUND_CONST[n + 1]; } } static hash() { return new Keccak(); } static hmac(bits, pad, len) { if (bits == null) bits = 256; assert((bits >>> 0) === bits); const rate = 1600 - bits * 2; return new HMAC(Keccak, rate / 8, [bits], [pad, len]); } static digest(data, bits, pad, len) { return Keccak.ctx.init(bits).update(data).final(pad, len); } static root(left, right, bits, pad, len) { if (bits == null) bits = 256; if (len == null) len = 0; if (len === 0) { assert((bits >>> 0) === bits); len = bits >>> 3; } assert((len >>> 0) === len); assert(Buffer.isBuffer(left) && left.length === len); assert(Buffer.isBuffer(right) && right.length === len); return Keccak.ctx.init(bits).update(left).update(right).final(pad, len); } static multi(x, y, z, bits, pad, len) { const { ctx } = Keccak; ctx.init(bits); ctx.update(x); ctx.update(y); if (z) ctx.update(z); return ctx.final(pad, len); } static mac(data, key, bits, pad, len) { return Keccak.hmac(bits, pad, len).init(key).update(data).final(); } } /* * Static */ Keccak.native = 0; Keccak.id = 'KECCAK256'; Keccak.size = 32; Keccak.bits = 256; Keccak.blockSize = 136; Keccak.zero = Buffer.alloc(32, 0x00); Keccak.ctx = new Keccak(); /* * Helpers */ function readU32(data, off) { return (data[off++] + data[off++] * 0x100 + data[off++] * 0x10000 + data[off] * 0x1000000); } /* * Expose */ module.exports = Keccak;