| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 | "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.shake256 = exports.shake128 = exports.keccak_512 = exports.keccak_384 = exports.keccak_256 = exports.keccak_224 = exports.sha3_512 = exports.sha3_384 = exports.sha3_256 = exports.sha3_224 = exports.Keccak = exports.keccakP = void 0;const _assert_js_1 = require("./_assert.js");const _u64_js_1 = require("./_u64.js");const utils_js_1 = require("./utils.js");// SHA3 (keccak) is based on a new design: basically, the internal state is bigger than output size.// It's called a sponge function.// Various per round constants calculationsconst SHA3_PI = [];const SHA3_ROTL = [];const _SHA3_IOTA = [];const _0n = /* @__PURE__ */ BigInt(0);const _1n = /* @__PURE__ */ BigInt(1);const _2n = /* @__PURE__ */ BigInt(2);const _7n = /* @__PURE__ */ BigInt(7);const _256n = /* @__PURE__ */ BigInt(256);const _0x71n = /* @__PURE__ */ BigInt(0x71);for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {    // Pi    [x, y] = [y, (2 * x + 3 * y) % 5];    SHA3_PI.push(2 * (5 * y + x));    // Rotational    SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);    // Iota    let t = _0n;    for (let j = 0; j < 7; j++) {        R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;        if (R & _2n)            t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n);    }    _SHA3_IOTA.push(t);}const [SHA3_IOTA_H, SHA3_IOTA_L] = /* @__PURE__ */ (0, _u64_js_1.split)(_SHA3_IOTA, true);// Left rotation (without 0, 32, 64)const rotlH = (h, l, s) => (s > 32 ? (0, _u64_js_1.rotlBH)(h, l, s) : (0, _u64_js_1.rotlSH)(h, l, s));const rotlL = (h, l, s) => (s > 32 ? (0, _u64_js_1.rotlBL)(h, l, s) : (0, _u64_js_1.rotlSL)(h, l, s));// Same as keccakf1600, but allows to skip some roundsfunction keccakP(s, rounds = 24) {    const B = new Uint32Array(5 * 2);    // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)    for (let round = 24 - rounds; round < 24; round++) {        // Theta θ        for (let x = 0; x < 10; x++)            B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];        for (let x = 0; x < 10; x += 2) {            const idx1 = (x + 8) % 10;            const idx0 = (x + 2) % 10;            const B0 = B[idx0];            const B1 = B[idx0 + 1];            const Th = rotlH(B0, B1, 1) ^ B[idx1];            const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];            for (let y = 0; y < 50; y += 10) {                s[x + y] ^= Th;                s[x + y + 1] ^= Tl;            }        }        // Rho (ρ) and Pi (π)        let curH = s[2];        let curL = s[3];        for (let t = 0; t < 24; t++) {            const shift = SHA3_ROTL[t];            const Th = rotlH(curH, curL, shift);            const Tl = rotlL(curH, curL, shift);            const PI = SHA3_PI[t];            curH = s[PI];            curL = s[PI + 1];            s[PI] = Th;            s[PI + 1] = Tl;        }        // Chi (χ)        for (let y = 0; y < 50; y += 10) {            for (let x = 0; x < 10; x++)                B[x] = s[y + x];            for (let x = 0; x < 10; x++)                s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];        }        // Iota (ι)        s[0] ^= SHA3_IOTA_H[round];        s[1] ^= SHA3_IOTA_L[round];    }    B.fill(0);}exports.keccakP = keccakP;class Keccak extends utils_js_1.Hash {    // NOTE: we accept arguments in bytes instead of bits here.    constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {        super();        this.blockLen = blockLen;        this.suffix = suffix;        this.outputLen = outputLen;        this.enableXOF = enableXOF;        this.rounds = rounds;        this.pos = 0;        this.posOut = 0;        this.finished = false;        this.destroyed = false;        // Can be passed from user as dkLen        (0, _assert_js_1.number)(outputLen);        // 1600 = 5x5 matrix of 64bit.  1600 bits === 200 bytes        if (0 >= this.blockLen || this.blockLen >= 200)            throw new Error('Sha3 supports only keccak-f1600 function');        this.state = new Uint8Array(200);        this.state32 = (0, utils_js_1.u32)(this.state);    }    keccak() {        if (!utils_js_1.isLE)            (0, utils_js_1.byteSwap32)(this.state32);        keccakP(this.state32, this.rounds);        if (!utils_js_1.isLE)            (0, utils_js_1.byteSwap32)(this.state32);        this.posOut = 0;        this.pos = 0;    }    update(data) {        (0, _assert_js_1.exists)(this);        const { blockLen, state } = this;        data = (0, utils_js_1.toBytes)(data);        const len = data.length;        for (let pos = 0; pos < len;) {            const take = Math.min(blockLen - this.pos, len - pos);            for (let i = 0; i < take; i++)                state[this.pos++] ^= data[pos++];            if (this.pos === blockLen)                this.keccak();        }        return this;    }    finish() {        if (this.finished)            return;        this.finished = true;        const { state, suffix, pos, blockLen } = this;        // Do the padding        state[pos] ^= suffix;        if ((suffix & 0x80) !== 0 && pos === blockLen - 1)            this.keccak();        state[blockLen - 1] ^= 0x80;        this.keccak();    }    writeInto(out) {        (0, _assert_js_1.exists)(this, false);        (0, _assert_js_1.bytes)(out);        this.finish();        const bufferOut = this.state;        const { blockLen } = this;        for (let pos = 0, len = out.length; pos < len;) {            if (this.posOut >= blockLen)                this.keccak();            const take = Math.min(blockLen - this.posOut, len - pos);            out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);            this.posOut += take;            pos += take;        }        return out;    }    xofInto(out) {        // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF        if (!this.enableXOF)            throw new Error('XOF is not possible for this instance');        return this.writeInto(out);    }    xof(bytes) {        (0, _assert_js_1.number)(bytes);        return this.xofInto(new Uint8Array(bytes));    }    digestInto(out) {        (0, _assert_js_1.output)(out, this);        if (this.finished)            throw new Error('digest() was already called');        this.writeInto(out);        this.destroy();        return out;    }    digest() {        return this.digestInto(new Uint8Array(this.outputLen));    }    destroy() {        this.destroyed = true;        this.state.fill(0);    }    _cloneInto(to) {        const { blockLen, suffix, outputLen, rounds, enableXOF } = this;        to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));        to.state32.set(this.state32);        to.pos = this.pos;        to.posOut = this.posOut;        to.finished = this.finished;        to.rounds = rounds;        // Suffix can change in cSHAKE        to.suffix = suffix;        to.outputLen = outputLen;        to.enableXOF = enableXOF;        to.destroyed = this.destroyed;        return to;    }}exports.Keccak = Keccak;const gen = (suffix, blockLen, outputLen) => (0, utils_js_1.wrapConstructor)(() => new Keccak(blockLen, suffix, outputLen));exports.sha3_224 = gen(0x06, 144, 224 / 8);/** * SHA3-256 hash function * @param message - that would be hashed */exports.sha3_256 = gen(0x06, 136, 256 / 8);exports.sha3_384 = gen(0x06, 104, 384 / 8);exports.sha3_512 = gen(0x06, 72, 512 / 8);exports.keccak_224 = gen(0x01, 144, 224 / 8);/** * keccak-256 hash function. Different from SHA3-256. * @param message - that would be hashed */exports.keccak_256 = gen(0x01, 136, 256 / 8);exports.keccak_384 = gen(0x01, 104, 384 / 8);exports.keccak_512 = gen(0x01, 72, 512 / 8);const genShake = (suffix, blockLen, outputLen) => (0, utils_js_1.wrapXOFConstructorWithOpts)((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true));exports.shake128 = genShake(0x1f, 168, 128 / 8);exports.shake256 = genShake(0x1f, 136, 256 / 8);//# sourceMappingURL=sha3.js.map
 |