UNPKG

@dartess/multicoin-address-validator

Version:

Multicoin address validator for Bitcoin and other Altcoins ported to TypeScript.

233 lines 8.72 kB
"use strict"; /* eslint-disable no-param-reassign,@typescript-eslint/no-shadow,@typescript-eslint/no-use-before-define,no-underscore-dangle */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Blake2b = void 0; /** * Credits to https://github.com/emilbayes/blake2b * * Copyright (c) 2017, Emil Bay github@tixz.dk * * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ // Ported to TypeScript by Sergey Kozlov const v = new Uint32Array(32); const m = new Uint32Array(32); // 64-bit unsigned addition // Sets v[a,a+1] += v[b,b+1] // v should be a Uint32Array function ADD64AA(v, a, b) { const o0 = v[a] + v[b]; let o1 = v[a + 1] + v[b + 1]; if (o0 >= 0x100000000) { o1++; } v[a] = o0; v[a + 1] = o1; } // 64-bit unsigned addition // Sets v[a,a+1] += b // b0 is the low 32 bits of b, b1 represents the high 32 bits function ADD64AC(v, a, b0, b1) { let o0 = v[a] + b0; if (b0 < 0) { o0 += 0x100000000; } let o1 = v[a + 1] + b1; if (o0 >= 0x100000000) { o1++; } v[a] = o0; v[a + 1] = o1; } // Little-endian byte access function B2B_GET32(arr, i) { return (arr[i] ^ (arr[i + 1] << 8) ^ (arr[i + 2] << 16) ^ (arr[i + 3] << 24)); } // G Mixing function // The ROTRs are inlined for speed function B2B_G(a, b, c, d, ix, iy) { const x0 = m[ix]; const x1 = m[ix + 1]; const y0 = m[iy]; const y1 = m[iy + 1]; ADD64AA(v, a, b); // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s ADD64AC(v, a, x0, x1); // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits let xor0 = v[d] ^ v[a]; let xor1 = v[d + 1] ^ v[a + 1]; v[d] = xor1; v[d + 1] = xor0; ADD64AA(v, c, d); // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits xor0 = v[b] ^ v[c]; xor1 = v[b + 1] ^ v[c + 1]; v[b] = (xor0 >>> 24) ^ (xor1 << 8); v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8); ADD64AA(v, a, b); ADD64AC(v, a, y0, y1); // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits xor0 = v[d] ^ v[a]; xor1 = v[d + 1] ^ v[a + 1]; v[d] = (xor0 >>> 16) ^ (xor1 << 16); v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16); ADD64AA(v, c, d); // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits xor0 = v[b] ^ v[c]; xor1 = v[b + 1] ^ v[c + 1]; v[b] = (xor1 >>> 31) ^ (xor0 << 1); v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1); } // Initialization Vector const BLAKE2B_IV32 = new Uint32Array([ 0xF3BCC908, 0x6A09E667, 0x84CAA73B, 0xBB67AE85, 0xFE94F82B, 0x3C6EF372, 0x5F1D36F1, 0xA54FF53A, 0xADE682D1, 0x510E527F, 0x2B3E6C1F, 0x9B05688C, 0xFB41BD6B, 0x1F83D9AB, 0x137E2179, 0x5BE0CD19, ]); const SIGMA8 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, ]; // These are offsets into a uint64 buffer. // Multiply them all by 2 to make them offsets into a uint32 buffer, // because this is Javascript and we don't have uint64s const SIGMA82 = new Uint8Array(SIGMA8.map((x) => x * 2)); // reusable parameter_block const parameter_block = new Uint8Array([ 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, 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, // 60: personal ]); function hexSlice(buf) { let str = ''; for (let i = 0; i < buf.length; i++) str += toHex(buf[i]); return str; } function toHex(n) { if (n < 16) return `0${n.toString(16)}`; return n.toString(16); } class Blake2b { // Creates a BLAKE2b hashing context // Requires an output length between 1 and 64 bytes constructor(outlen) { this.outlen = outlen; this._b = new Uint8Array(128); this._h = new Uint32Array(16); this._t = 0; // input count this._c = 0; // pointer within buffer this.final = Blake2b.prototype.digest; // zero out parameter_block before usage parameter_block.fill(0); parameter_block[0] = outlen; parameter_block[2] = 1; // fanout parameter_block[3] = 1; // depth // initialize hash state for (let i = 0; i < 16; i++) { this._h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4); } } // Compression function. 'last' flag indicates last block. // Note we're representing 16 uint64s as 32 uint32s blake2bCompress(last) { let i; // init work variables for (i = 0; i < 16; i++) { v[i] = this._h[i]; v[i + 16] = BLAKE2B_IV32[i]; } // low 64 bits of offset v[24] ^= this._t; v[25] ^= (this._t / 0x100000000); // high 64 bits not supported, offset may not be higher than 2**53-1 // last block flag set ? if (last) { v[28] = ~v[28]; v[29] = ~v[29]; } // get little-endian words for (i = 0; i < 32; i++) { m[i] = B2B_GET32(this._b, 4 * i); } // twelve rounds of mixing for (i = 0; i < 12; i++) { B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]); B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]); B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]); B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]); B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]); B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]); B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]); B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]); } for (i = 0; i < 16; i++) { this._h[i] = this._h[i] ^ v[i] ^ v[i + 16]; } } // Updates a BLAKE2b streaming hash // Requires hash context and Uint8Array (byte array) blake2bUpdate(input) { for (let i = 0; i < input.length; i++) { if (this._c === 128) { // buffer full ? this._t += this._c; // add counters this.blake2bCompress(false); // compress (not last) this._c = 0; // counter to zero } this._b[this._c++] = input[i]; } } // Completes a BLAKE2b streaming hash // Returns a Uint8Array containing the message digest blake2bFinal(out) { this._t += this._c; // mark last block offset while (this._c < 128) { // fill up with zeros this._b[this._c++] = 0; } this.blake2bCompress(true); // final block flag = 1 for (let i = 0; i < this.outlen; i++) { out[i] = this._h[i >> 2] >> (8 * (i & 3)); } return out; } update(input) { this.blake2bUpdate(input); return this; } digest() { const buf = new Uint8Array(this.outlen); this.blake2bFinal(buf); return hexSlice(buf); } } exports.Blake2b = Blake2b; //# sourceMappingURL=blake2b.js.map