UNPKG

mima-kit

Version:

mima-kit is a cryptographic suite implemented in TypeScript. The goal is to provide an easy-to-use cryptographic library. mima-kit 是一个使用 TypeScript 实现的密码学套件。目标是提供一个简单易用的密码学库。

1,828 lines (1,819 loc) 272 kB
function rotateL32(x, n) { return (x << n | x >>> 32 - n) >>> 0; } function rotateR32(x, n) { return x >>> n | x << 32 - n >>> 0; } function rotateL(bit, x, n, mask) { bit = BigInt(bit); mask ??= genBitMask(bit); x = BigInt(x); n = BigInt(n); x &= mask; n %= bit; x = x << n | x >> bit - n; return x & mask; } function rotateR(bit, x, n, mask) { bit = BigInt(bit); mask ??= genBitMask(bit); x = BigInt(x); n = BigInt(n); x &= mask; n %= bit; x = x >> n | x << bit - n; return x & mask; } function genRandomBI(max, byte, max_attempts = 1e3) { if (max <= 1n) throw new KitError("Max must be greater than 1"); const buffer = new U8(byte); let result = 0n; let attempts = 0; while (attempts < max_attempts) { crypto.getRandomValues(buffer); result = buffer.toBI(); if (result < max) return { buffer, result }; attempts++; } throw new KitError("Failed to generate random bigint within max attempts"); } function getBIBits(n) { return n === 0n ? 0 : n.toString(2).length; } function genBitMask(w) { w = BigInt(w); let mask = 0x0n; for (let i = 0; i < w; i++) { mask = mask << 1n | 1n; } return mask; } function extendedEuclidean(a, b) { let [s0, s1, t0, t1, r0, r1] = [1n, 0n, 0n, 1n, a, b]; if (b === 0n) { return { gcd: a, x: 1n }; } while (r1 !== 0n) { const q = r0 / r1; [r0, r1] = [r1, r0 - q * r1]; [s0, s1] = [s1, s0 - q * s1]; [t0, t1] = [t1, t0 - q * t1]; } return { gcd: r0, x: s0 }; } function legendreSymbol(a, p) { return modPow(a, p - 1n >> 1n, p); } function tonelliShanks(a, p) { if (legendreSymbol(a, p) !== 1n) { throw new KitError("There is no square root"); } if (a === 0n) { return 0n; } if (p === 2n) { return a; } if (p % 4n === 3n) { return modPow(a, p + 1n >> 2n, p); } let q = p - 1n; let s = 0n; while (mod(q, 2n) === 0n) { q >>= 1n; s++; } let z = 2n; while (legendreSymbol(z, p) !== p - 1n) { z++; } let m = s; let c = modPow(z, q, p); let t = modPow(a, q, p); let r = modPow(a, q + 1n >> 1n, p); while (t !== 0n && t !== 1n) { let t2i = t; let i = 1n; for (; i < m; i++) { t2i = modPow(t2i, 2n, p); if (t2i === 1n) { break; } } const b = modPow(c, 1n << m - i - 1n, p); m = i; c = modPow(b, 2n, p); t = t * c % p; r = r * b % p; } return r; } function gcd(a, b) { return extendedEuclidean(a, b).gcd; } function lcm(a, b) { return a * b / gcd(a, b); } function mod(a, b) { const r = a % b; return r < 0n ? r + b : r; } function modPow(x, y, n) { x %= n; let r = 1n; while (y > 0n) { if (y & 1n) r = r * x % n; x = x * x % n; y >>= 1n; } return r; } function modInverse(x, n) { const { gcd: gcd2, x: _x } = extendedEuclidean(x, n); if (gcd2 !== 1n) throw new KitError("Modular inverse does not exist"); return mod(_x, n); } function modPrimeSquareRoot(n, p) { n = mod(n, p); if (n === 0n) return 0n; const r1 = tonelliShanks(n, p); const r2 = mod(p - r1, p); return r1 <= r2 ? r1 : r2; } class U8 extends Uint8Array { /** * 从 U8 中获取一个字 / Get a word from U8 * * @param {number} word_size - 字长 / word size (byte) * @param {number} index - 字索引 / word index * @param {boolean} [little_endian] - 是否为小端序 / little-endian (default: false) */ getWord(word_size, index, little_endian = false) { const offset = index * word_size; const buffer = this.subarray(offset, offset + word_size); return little_endian ? buffer.toBI(true) : buffer.toBI(); } /** * 将一个字写入 U8 / Set a word to U8 * * @param {number} word_size - 字长 / word size (byte) * @param {number} index - 字索引 / word index * @param {bigint | Uint8Array} word - 字 / word * @param {boolean} [little_endian] - 是否为小端序 / little-endian (default: false) */ setWord(word_size, index, word, little_endian = false) { const offset = index * word_size; const buffer = typeof word === "bigint" ? U8.fromBI(word, word_size) : word; this.set(little_endian ? buffer.toReversed() : buffer, offset); } /** * U8 视图 / U8 view * * @param {number} word_size - 字长 / word size (byte) */ view(word_size) { const length = Math.floor(this.length / word_size); const get = (index, little_endian = false) => this.getWord(word_size, index, little_endian); const set = (index, word, little_endian = false) => this.setWord(word_size, index, word, little_endian); return { get, set, length }; } /** * 将 U8 编码为字符串 / stringify U8 to encoded string */ to(codec) { return codec(this); } /** * 将 U8 转换为 BigInt / Convert U8 to BigInt * * @param {boolean} [little_endian] - 是否为小端序 / little-endian (default: false) */ toBI(little_endian = false) { const buffer = little_endian ? this.toReversed() : this; let bigint = 0n; buffer.forEach((byte) => { bigint = bigint << 8n | BigInt(byte); }); return bigint; } /** * Convert U8 to Uint8Array * * 将 U8 转换为 Uint8Array */ toUint8Array() { return new Uint8Array(this); } /** * Convert string to U8 * * 将 字符串 转换为 U8 */ static fromString(input, codec) { return codec(input); } /** * Convert BigInt to U8 * * 将 BigInt 转换为 U8 */ static fromBI(bigint, length, little_endian = false) { length = length || getBIBits(bigint) + 7 >> 3; const buffer = new U8(length); if (little_endian) { for (let i = 0; i < buffer.length; i++) { buffer[i] = Number(bigint & 0xffn); bigint >>= 8n; } } else { for (let i = buffer.length - 1; i >= 0; i--) { buffer[i] = Number(bigint & 0xffn); bigint >>= 8n; } } return buffer; } /** * Returns the elements of an array that meet the condition specified in a callback function. * @param predicate A function that accepts up to three arguments. The filter method calls * the predicate function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the predicate function. * If thisArg is omitted, undefined is used as the this value. */ filter(predicate, thisArg) { const _ = super.filter(predicate, thisArg); return new U8(_.buffer, _.byteOffset, _.byteLength); } /** * Returns a new array from a set of elements. * @param items A set of elements to include in the new array object. */ static of(...items) { const _ = Uint8Array.of(...items); return new U8(_.buffer, _.byteOffset, _.byteLength); } static from(array_like, mapfn, this_arg) { const _ = Uint8Array.from(array_like, mapfn, this_arg); return new U8(_.buffer, _.byteOffset, _.byteLength); } /** * Calls a defined callback function on each element of an array, and returns an array that * contains the results. * @param callbackfn A function that accepts up to three arguments. The map method calls the * callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn, thisArg) { const _ = super.map(callbackfn, thisArg); return new U8(_.buffer, _.byteOffset, _.byteLength); } /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'. */ slice(start, end) { const _ = super.slice(start, end); return new U8(_.buffer, _.byteOffset, _.byteLength); } /** * Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin, end) { const _ = super.subarray(begin, end); return new U8(_.buffer, _.byteOffset, _.byteLength); } /** * Copies the array and returns the copy with the elements in reverse order. */ toReversed() { const _ = super.toReversed(); return new U8(_.buffer, _.byteOffset, _.byteLength); } /** * Copies and sorts the array. * @param compareFn Function used to determine the order of the elements. It is expected to return * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive * value otherwise. If omitted, the elements are sorted in ascending order. * ```ts * const myNums = Uint8Array.from([11, 2, 22, 1]); * myNums.toSorted((a, b) => a - b) // Uint8Array(4) [1, 2, 11, 22] * ``` */ toSorted(compareFn) { const _ = super.toSorted(compareFn); return new U8(_.buffer, _.byteOffset, _.byteLength); } /** * Copies the array and inserts the given number at the provided index. * @param index The index of the value to overwrite. If the index is * negative, then it replaces from the end of the array. * @param value The value to insert into the copied array. * @returns A copy of the original array with the inserted value. */ with(index, value) { const _ = super.with(index, value); return new U8(_.buffer, _.byteOffset, _.byteLength); } } function u8(source) { return new U8(source.buffer, source.byteOffset, source.byteLength); } function u32(source) { return new Uint32Array(source.buffer, source.byteOffset, source.byteLength >> 2); } function joinBuffer(...buffers) { const byte_total = buffers.reduce((acc, cur) => acc + cur.byteLength, 0); const result = new U8(byte_total); let offset = 0; for (const buffer of buffers) { result.set(new U8(buffer), offset); offset += buffer.byteLength; } return result; } function resizeBuffer(buffer, size) { const b = new U8(size); b.set(buffer); return b; } class Counter extends U8 { /** * @param {number} offset - 计数器偏移 / counter offset * @param {number} length - 计数器长度 / counter length */ inc(offset, length, little_endian = false) { offset = offset || 0; if (offset < 0 || offset >= this.length) { throw new KitError("Invalid counter offset"); } length = length || this.length - offset; if (length < 0 || offset + length > this.length) { throw new KitError("Invalid counter length"); } if (little_endian) { for (let i = offset; i < offset + length; i++) { if (this[i] < 255) { this[i] += 1; break; } this[i] = 0; } } else { for (let i = offset + length - 1; i >= offset; i--) { if (this[i] < 255) { this[i] += 1; break; } this[i] = 0; } } } } function trying(fn) { try { const result = fn(); return [null, result]; } catch (error) { return error instanceof Error ? [error, null] : [new KitError("Unknown error"), null]; } } function wrap(...args) { return Object.assign(...args); } class KitError extends Error { constructor(message) { super(message); this.name = "mima-kit Error"; } } const T$1 = 40; const LOW_PRIMES = [ 2n, 3n, 5n, 7n, 11n, 13n, 17n, 19n, 23n, 29n, 31n, 37n, 41n, 43n, 47n, 53n, 59n, 61n, 67n, 71n, 73n, 79n, 83n, 89n, 97n, 101n, 103n, 107n, 109n, 113n, 127n, 131n, 137n, 139n, 149n, 151n, 157n, 163n, 167n, 173n, 179n, 181n, 191n, 193n, 197n, 199n, 211n, 223n, 227n, 229n, 233n, 239n, 241n, 251n, 257n, 263n, 269n, 271n, 277n, 281n, 283n, 293n, 307n, 311n, 313n, 317n, 331n, 337n, 347n, 349n, 353n, 359n, 367n, 373n, 379n, 383n, 389n, 397n, 401n, 409n, 419n, 421n, 431n, 433n, 439n, 443n, 449n, 457n, 461n, 463n, 467n, 479n, 487n, 491n, 499n, 503n, 509n, 521n, 523n, 541n, 547n, 557n, 563n, 569n, 571n, 577n, 587n, 593n, 599n, 601n, 607n, 613n, 617n, 619n, 631n, 641n, 643n, 647n, 653n, 659n, 661n, 673n, 677n, 683n, 691n, 701n, 709n, 719n, 727n, 733n, 739n, 743n, 751n, 757n, 761n, 769n, 773n, 787n, 797n, 809n, 811n, 821n, 823n, 827n, 829n, 839n, 853n, 857n, 859n, 863n, 877n, 881n, 883n, 887n, 907n, 911n, 919n, 929n, 937n, 941n, 947n, 953n, 967n, 971n, 977n, 983n, 991n, 997n ]; const LOW_PRIMES_LIMIT = (1n << 26n) / LOW_PRIMES[LOW_PRIMES.length - 1]; function MillerRabin(n, t) { const n_1 = n - 1n; let s = 0n; let d = n_1; while ((d & 1n) === 0n) { d >>= 1n; s++; } t = t + 1 >> 1; if (t > LOW_PRIMES.length) t = LOW_PRIMES.length; const tested = [2n]; for (let i = 0; i < t; ++i) { let base; do { base = LOW_PRIMES[Math.floor(Math.random() * LOW_PRIMES.length)]; } while (tested.includes(base)); tested.push(base); if (StrongPseudoPrime(n, n_1, s, d, base) === false) { return false; } } return true; } function StrongPseudoPrime(n, n_1, s, d, base) { let x = modPow(base, d, n); if (x === 1n || x === n_1) return true; let y = 0n; for (let i = 1; i < s; i++) { y = modPow(x, 2n, n); if (y === 1n && x !== 1n && x !== n_1) return false; x = y; } return y === 1n; } function _isProbablePrime(n, t = T$1) { for (let i = 1; i < LOW_PRIMES.length; ) { let m = LOW_PRIMES[i]; let j = i + 1; while (j < LOW_PRIMES.length && m < LOW_PRIMES_LIMIT) { m *= LOW_PRIMES[j++]; } m = n % m; while (i < j) { if (m % LOW_PRIMES[i++] === 0n) return false; } } return MillerRabin(n, t); } function genPrimeCandidate(buffer) { crypto.getRandomValues(buffer); buffer[0] |= 128; let n = buffer.toBI() | 1n; const n_mod_6 = n % 6n; if (n_mod_6 !== 1n && n_mod_6 !== 5n) n += 4n; return n; } const genPrime = (b) => { const buffer = new U8(b >> 3); let n; do { n = genPrimeCandidate(buffer); } while (!_isProbablePrime(n)); return n; }; function isProbablePrime(n, t = T$1) { if (t <= 0) return false; if ((n & 1n) === 0n) return false; const n_mod_6 = n % 6n; if (n_mod_6 !== 1n && n_mod_6 !== 5n) return false; if (n <= LOW_PRIMES[LOW_PRIMES.length - 1]) return LOW_PRIMES.includes(n); return _isProbablePrime(n, t); } function createCodec(parse, stringify, format) { function codec(input) { return typeof input === "string" ? parse(input) : stringify(input); } return wrap(codec, { FORMAT: format }); } function UTF8ToU8(input) { const [error, result] = trying(() => new TextEncoder().encode(input)); if (!error) return u8(result); const buffer = []; for (let i = 0; i < input.length; i++) { const char_code = input.codePointAt(i); if (char_code === void 0) ; else if (char_code < 128) { buffer.push(char_code); } else if (char_code < 2048) { buffer.push(192 | char_code >> 6); buffer.push(128 | char_code & 63); } else if (char_code < 65536) { buffer.push(224 | char_code >> 12); buffer.push(128 | char_code >> 6 & 63); buffer.push(128 | char_code & 63); } else if (char_code < 1114112) { buffer.push(240 | char_code >> 18); buffer.push(128 | char_code >> 12 & 63); buffer.push(128 | char_code >> 6 & 63); buffer.push(128 | char_code & 63); i++; } } return U8.from(buffer); } function U8ToUTF8(input) { const [error, result] = trying(() => new TextDecoder().decode(input)); if (!error) return result; const str = []; for (let i = 0; i < input.length; ) { const byte1 = input[i++]; if (byte1 < 128) { str.push(String.fromCharCode(byte1)); } else if (byte1 >= 192 && byte1 < 224) { const byte2 = input[i++]; const char_code = (byte1 & 31) << 6 | byte2 & 63; str.push(String.fromCharCode(char_code)); } else if (byte1 >= 224 && byte1 < 240) { const byte2 = input[i++]; const byte3 = input[i++]; const char_code = (byte1 & 15) << 12 | (byte2 & 63) << 6 | byte3 & 63; str.push(String.fromCharCode(char_code)); } else if (byte1 >= 240 && byte1 < 248) { const byte2 = input[i++]; const byte3 = input[i++]; const byte4 = input[i++]; const char_code = (byte1 & 7) << 18 | (byte2 & 63) << 12 | (byte3 & 63) << 6 | byte4 & 63; str.push(String.fromCodePoint(char_code)); } else { console.warn("Included an invalid UTF-8 byte"); } } return str.join(""); } const UTF8 = createCodec(UTF8ToU8, U8ToUTF8, "utf-8"); function HEXToU8(input) { input = input.replace(/^0x/, ""); const [error, result] = trying(() => Buffer.from(input.replace(/[^0-9a-f]/gi, ""), "hex")); if (!error) return u8(result); const arr = input.match(/[\da-f]{2}/gi); if (arr == null) { return new U8(); } return new U8(arr.map((h) => Number.parseInt(h, 16))); } function U8ToHEX(input) { const [error, result] = trying(() => Buffer.from(input).toString("hex")); if (!error) return result; let str = ""; for (let i = 0; i < input.length; i++) { str += input[i].toString(16).padStart(2, "0"); } return str; } const HEX = createCodec(HEXToU8, U8ToHEX, "hex"); function B64ToU8(input) { const [error, result] = trying(() => Buffer.from(input.replace(/[^A-Z0-9+/]/gi, ""), "base64")); if (!error) return u8(result); return B64CommonParse(input); } function U8ToB64(input) { const [error, result] = trying(() => Buffer.from(input).toString("base64")); if (!error) return result; return B64CommonStringify(input); } const B64 = createCodec(B64ToU8, U8ToB64, "base64"); function B64URLToU8(input) { const [error, result] = trying(() => Buffer.from(input.replace(/[^\w-]/g, ""), "base64url")); if (!error) return u8(result); return B64CommonParse(input); } function U8ToB64URL(input) { const [error, result] = trying(() => Buffer.from(input).toString("base64url")); if (!error) return result; return B64(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); } const B64URL = createCodec(B64URLToU8, U8ToB64URL, "base64url"); function B64CommonParse(input) { const map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; input = input.replace(/-/g, "+").replace(/_/g, "/").replace(/[^A-Z0-9+/]/gi, ""); const length = input.length * 0.75; const result = new U8(length); let i = 0; let j = 0; while (i < input.length) { const a = map.indexOf(input.charAt(i++)); const b = map.indexOf(input.charAt(i++)); const c = map.indexOf(input.charAt(i++)); const d = map.indexOf(input.charAt(i++)); const combined = a << 18 | b << 12 | c << 6 | d; result[j++] = combined >> 16 & 255; result[j++] = combined >> 8 & 255; result[j++] = combined & 255; } return result; } function B64CommonStringify(input, url) { let map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; map += "+/"; let result = ""; let i; for (i = 0; i < input.length - 2; i += 3) { result += map[input[i] >> 2]; result += map[(input[i] & 3) << 4 | input[i + 1] >> 4]; result += map[(input[i + 1] & 15) << 2 | input[i + 2] >> 6]; result += map[input[i + 2] & 63]; } if (i === input.length - 2) { result += map[input[i] >> 2]; result += map[(input[i] & 3) << 4 | input[i + 1] >> 4]; result += map[(input[i + 1] & 15) << 2]; result += "="; } else if (i === input.length - 1) { result += map[input[i] >> 2]; result += map[(input[i] & 3) << 4]; result += "=="; } return result; } function TheB32Codec(args) { const RFC4648_B32_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; if (typeof args === "string") { const input = args.toUpperCase().replace(/[^A-Z2-7]/g, ""); return B32CommonParse(input, RFC4648_B32_MAP); } else if (args instanceof Uint8Array) { return B32CommonStringify(args, RFC4648_B32_MAP, false); } const { variant = "rfc4648", padding = false } = args; if (variant === "rfc4648") { let B32ToU8 = function(input) { input = input.toUpperCase().replace(/[^A-Z2-7]/g, ""); return B32CommonParse(input, RFC4648_B32_MAP); }, U8ToB32 = function(input) { return B32CommonStringify(input, RFC4648_B32_MAP, padding); }; return createCodec(B32ToU8, U8ToB32, "base32"); } else if (variant === "rfc4648-hex") { let B32HexToU8 = function(input) { input = input.toUpperCase().replace(/[^0-9A-V]/g, ""); return B32CommonParse(input, RFC4648_B32_HEX_MAP); }, U8ToB32Hex = function(input) { return B32CommonStringify(input, RFC4648_B32_HEX_MAP, padding); }; const RFC4648_B32_HEX_MAP = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; return createCodec(B32HexToU8, U8ToB32Hex, "base32-hex"); } else if (variant === "crockford") { let B32CrockfordToU8 = function(input) { input = input.toUpperCase().replace(/O/g, "0").replace(/[IL]/g, "1").replace(/[^0-9A-HJKMNP-TV-Z]/g, ""); return B32CommonParse(input, RFC4648_B32_CROCKFORD_MAP); }, U8ToB32Crockford = function(input) { return B32CommonStringify(input, RFC4648_B32_CROCKFORD_MAP, padding); }; const RFC4648_B32_CROCKFORD_MAP = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; return createCodec(B32CrockfordToU8, U8ToB32Crockford, "base32-crockford"); } } const B32 = wrap(TheB32Codec, { FORMAT: "base32" }); function B32CommonParse(input, map) { const length = input.length * 0.625; const result = new U8(length); let i = 0; let j = 0; while (i < input.length) { const a = map.indexOf(input.charAt(i++)); const b = map.indexOf(input.charAt(i++)); const c = map.indexOf(input.charAt(i++)); const d = map.indexOf(input.charAt(i++)); const e = map.indexOf(input.charAt(i++)); const f = map.indexOf(input.charAt(i++)); const g = map.indexOf(input.charAt(i++)); const h = map.indexOf(input.charAt(i++)); result[j++] = a << 3 | b >> 2; result[j++] = (b & 3) << 6 | c << 1 | d >> 4; result[j++] = (d & 15) << 4 | e >> 1; result[j++] = (e & 1) << 7 | f << 2 | g >> 3; result[j++] = (g & 7) << 5 | h; } return result; } function B32CommonStringify(input, map, pad) { let result = ""; let i; for (i = 0; i < input.length - 4; i += 5) { const E0 = input[i]; const E1 = input[i + 1]; const E2 = input[i + 2]; const E3 = input[i + 3]; const E4 = input[i + 4]; result += map[E0 >> 3]; result += map[(E0 & 7) << 2 | E1 >> 6]; result += map[E1 >> 1 & 31]; result += map[(E1 & 1) << 4 | E2 >> 4]; result += map[(E2 & 15) << 1 | E3 >> 7]; result += map[E3 >> 2 & 31]; result += map[(E3 & 3) << 3 | E4 >> 5]; result += map[E4 & 31]; } if (i === input.length - 4) { const E0 = input[i]; const E1 = input[i + 1]; const E2 = input[i + 2]; const E3 = input[i + 3]; result += map[E0 >> 3]; result += map[(E0 & 7) << 2 | E1 >> 6]; result += map[E1 >> 1 & 31]; result += map[(E1 & 1) << 4 | E2 >> 4]; result += map[(E2 & 15) << 1 | E3 >> 7]; result += map[E3 >> 2 & 31]; result += map[(E3 & 3) << 3]; result += pad ? "=" : ""; } else if (i === input.length - 3) { const E0 = input[i]; const E1 = input[i + 1]; const E2 = input[i + 2]; result += map[E0 >> 3]; result += map[(E0 & 7) << 2 | E1 >> 6]; result += map[E1 >> 1 & 31]; result += map[(E1 & 1) << 4 | E2 >> 4]; result += map[(E2 & 15) << 1]; result += pad ? "===" : ""; } else if (i === input.length - 2) { const E0 = input[i]; const E1 = input[i + 1]; result += map[E0 >> 3]; result += map[(E0 & 7) << 2 | E1 >> 6]; result += map[E1 >> 1 & 31]; result += map[(E1 & 1) << 4]; result += pad ? "====" : ""; } else if (i === input.length - 1) { const E0 = input[i]; result += map[E0 >> 3]; result += map[(E0 & 7) << 2]; result += pad ? "======" : ""; } return result; } function CSVToU8(input) { const coreValueMap = /* @__PURE__ */ new Map(); coreValueMap.set("\u5BCC\u5F3A", 0); coreValueMap.set("\u6C11\u4E3B", 1); coreValueMap.set("\u6587\u660E", 2); coreValueMap.set("\u548C\u8C10", 3); coreValueMap.set("\u81EA\u7531", 4); coreValueMap.set("\u5E73\u7B49", 5); coreValueMap.set("\u516C\u6B63", 6); coreValueMap.set("\u6CD5\u6CBB", 7); coreValueMap.set("\u7231\u56FD", 8); coreValueMap.set("\u656C\u4E1A", 9); coreValueMap.set("\u8BDA\u4FE1", 10); coreValueMap.set("\u53CB\u5584", 11); const from = (value) => { const nibble = coreValueMap.get(value); if (nibble === void 0) { throw new KitError("\u4F60\u7ADF\u7136\u5728\u793E\u4F1A\u4E3B\u4E49\u6838\u5FC3\u4EF7\u503C\u89C2\u91CC\u5939\u5E26\u79C1\u8D27\uFF01"); } return nibble; }; const coreValues = input.match(/(\S){2}/g); if (coreValues == null) return new U8(); let h = 0; let l = 0; let count = 0; const result = []; for (let i = 0; i < coreValues.length; i++) { const isHigh = count % 2 === 0; let nibble = from(coreValues[i]); if (nibble === 10 || nibble === 11) { i++; if (i === coreValues.length) { throw new KitError("\u4F60\u7684\u793E\u4F1A\u4E3B\u4E49\u6838\u5FC3\u4EF7\u503C\u89C2\u7834\u788E\u4E86\uFF01"); } nibble = nibble === 10 ? 10 + from(coreValues[i]) : 6 + from(coreValues[i]); } if (isHigh) { h = nibble; } else { l = nibble; } if (!isHigh) { result.push((h << 4 | l) & 255); } count++; } return new U8(result); } function U8ToCSV(input) { const rand = () => Math.random() >= 0.5; const map = [ "\u5BCC\u5F3A", "\u6C11\u4E3B", "\u6587\u660E", "\u548C\u8C10", "\u81EA\u7531", "\u5E73\u7B49", "\u516C\u6B63", "\u6CD5\u6CBB", "\u7231\u56FD", "\u656C\u4E1A", "\u8BDA\u4FE1", "\u53CB\u5584" ]; let result = ""; input.forEach((byte) => { const h = byte >> 4 & 15; const l = byte & 15; if (h < 10) { result += map[h]; } else if (rand()) { result += map[11] + map[h - 6]; } else { result += map[11] + map[h - 6]; } if (l < 10) { result += map[l]; } else if (rand()) { result += map[10] + map[l - 10]; } else { result += map[11] + map[l - 6]; } }); return result; } const CSV = createCodec(CSVToU8, U8ToCSV, "core-socialist-values"); const createHash = (digest, description) => wrap(digest, description); const createTupleHash = (digest, description) => wrap(digest, description); const createKeyHash = (digest, description) => wrap(digest, description); const FF$1 = (X, Y, Z, j) => j < 16 ? X ^ Y ^ Z : X & Y | X & Z | Y & Z; const GG$1 = (X, Y, Z, j) => j < 16 ? X ^ Y ^ Z : X & Y | ~X & Z; const P0$1 = (X) => X ^ rotateL32(X, 9) ^ rotateL32(X, 17); const P1$1 = (X) => X ^ rotateL32(X, 15) ^ rotateL32(X, 23); function digest$4(message) { const state = new U8(32); const state_view = state.view(4); state_view.set(0, 0x7380166fn); state_view.set(1, 0x4914b2b9n); state_view.set(2, 0x172442d7n); state_view.set(3, 0xda8a0600n); state_view.set(4, 0xa96f30bcn); state_view.set(5, 0x163138aan); state_view.set(6, 0xe38dee4dn); state_view.set(7, 0xb0fb0e4en); const m_byte = message.length; const m_bit = BigInt(m_byte) << 3n; const block_size = 64; const block_total = m_byte + 9 + 63 >> 6; const p = new U8(block_total * block_size); p.set(message); p[m_byte] = 128; const p_view = new DataView(p.buffer, p.byteOffset, p.byteLength); p_view.setBigUint64(p.length - 8, m_bit, false); for (let offset = 0; offset < p.length; offset += block_size) { const H0 = Number(state_view.get(0)); const H1 = Number(state_view.get(1)); const H2 = Number(state_view.get(2)); const H3 = Number(state_view.get(3)); const H4 = Number(state_view.get(4)); const H5 = Number(state_view.get(5)); const H6 = Number(state_view.get(6)); const H7 = Number(state_view.get(7)); let A = H0; let B = H1; let C = H2; let D = H3; let E = H4; let F = H5; let G = H6; let H = H7; const W = new Uint32Array(68); const W1 = new Uint32Array(64); for (let i = 0; i < 68; i++) { if (i < 16) { W[i] = p_view.getUint32(offset + (i << 2), false); } else { W[i] = P1$1(W[i - 16] ^ W[i - 9] ^ rotateL32(W[i - 3], 15)) ^ rotateL32(W[i - 13], 7) ^ W[i - 6]; } if (i > 3) { const j = i - 4; W1[j] = W[j] ^ W[i]; const T = j < 16 ? 2043430169 : 2055708042; const SS1 = rotateL32(rotateL32(A, 12) + E + rotateL32(T, j), 7); const SS2 = SS1 ^ rotateL32(A, 12); const TT1 = FF$1(A, B, C, j) + D + SS2 + W1[j]; const TT2 = GG$1(E, F, G, j) + H + SS1 + W[j]; D = C; C = rotateL32(B, 9); B = A; A = TT1; H = G; G = rotateL32(F, 19); F = E; E = P0$1(TT2); } } state_view.set(0, BigInt(H0 ^ A)); state_view.set(1, BigInt(H1 ^ B)); state_view.set(2, BigInt(H2 ^ C)); state_view.set(3, BigInt(H3 ^ D)); state_view.set(4, BigInt(H4 ^ E)); state_view.set(5, BigInt(H5 ^ F)); state_view.set(6, BigInt(H6 ^ G)); state_view.set(7, BigInt(H7 ^ H)); } return state; } const sm3 = createHash(digest$4, { ALGORITHM: "SM3", BLOCK_SIZE: 64, DIGEST_SIZE: 32, OID: "1.2.156.10197.1.401" }); const K$3 = new Uint32Array([ 3614090360, 3905402710, 606105819, 3250441966, 4118548399, 1200080426, 2821735955, 4249261313, 1770035416, 2336552879, 4294925233, 2304563134, 1804603682, 4254626195, 2792965006, 1236535329, 4129170786, 3225465664, 643717713, 3921069994, 3593408605, 38016083, 3634488961, 3889429448, 568446438, 3275163606, 4107603335, 1163531501, 2850285829, 4243563512, 1735328473, 2368359562, 4294588738, 2272392833, 1839030562, 4259657740, 2763975236, 1272893353, 4139469664, 3200236656, 681279174, 3936430074, 3572445317, 76029189, 3654602809, 3873151461, 530742520, 3299628645, 4096336452, 1126891415, 2878612391, 4237533241, 1700485571, 2399980690, 4293915773, 2240044497, 1873313359, 4264355552, 2734768916, 1309151649, 4149444226, 3174756917, 718787259, 3951481745 ]); function FF(a, b, c, d, m, s, k) { const n = a + (b & c | ~b & d) + m + k; return rotateL32(n, s) + b; } function GG(a, b, c, d, m, s, k) { const n = a + (b & d | c & ~d) + m + k; return rotateL32(n, s) + b; } function HH(a, b, c, d, m, s, k) { const n = a + (b ^ c ^ d) + m + k; return rotateL32(n, s) + b; } function II(a, b, c, d, m, s, k) { const n = a + (c ^ (b | ~d)) + m + k; return rotateL32(n, s) + b; } function digest$3(message) { const state = new Uint32Array([1732584193, 4023233417, 2562383102, 271733878]); const m_byte = message.length; const m_bit = BigInt(m_byte) << 3n; const block_size = 64; const block_total = m_byte + 9 + 63 >> 6; const p = new U8(block_total * block_size); p.set(message); p[m_byte] = 128; const p_view = new DataView(p.buffer, p.byteOffset, p.byteLength); p_view.setBigUint64(p.length - 8, m_bit, true); for (let offset = 0; offset < p.length; ) { const end = offset + block_size; const M = new Uint32Array(p.buffer, p.byteOffset + offset, block_size >> 2); offset = end; const A = state[0]; const B = state[1]; const C = state[2]; const D = state[3]; let a = A; let b = B; let c = C; let d = D; a = FF(a, b, c, d, M[0], 7, K$3[0]); d = FF(d, a, b, c, M[1], 12, K$3[1]); c = FF(c, d, a, b, M[2], 17, K$3[2]); b = FF(b, c, d, a, M[3], 22, K$3[3]); a = FF(a, b, c, d, M[4], 7, K$3[4]); d = FF(d, a, b, c, M[5], 12, K$3[5]); c = FF(c, d, a, b, M[6], 17, K$3[6]); b = FF(b, c, d, a, M[7], 22, K$3[7]); a = FF(a, b, c, d, M[8], 7, K$3[8]); d = FF(d, a, b, c, M[9], 12, K$3[9]); c = FF(c, d, a, b, M[10], 17, K$3[10]); b = FF(b, c, d, a, M[11], 22, K$3[11]); a = FF(a, b, c, d, M[12], 7, K$3[12]); d = FF(d, a, b, c, M[13], 12, K$3[13]); c = FF(c, d, a, b, M[14], 17, K$3[14]); b = FF(b, c, d, a, M[15], 22, K$3[15]); a = GG(a, b, c, d, M[1], 5, K$3[16]); d = GG(d, a, b, c, M[6], 9, K$3[17]); c = GG(c, d, a, b, M[11], 14, K$3[18]); b = GG(b, c, d, a, M[0], 20, K$3[19]); a = GG(a, b, c, d, M[5], 5, K$3[20]); d = GG(d, a, b, c, M[10], 9, K$3[21]); c = GG(c, d, a, b, M[15], 14, K$3[22]); b = GG(b, c, d, a, M[4], 20, K$3[23]); a = GG(a, b, c, d, M[9], 5, K$3[24]); d = GG(d, a, b, c, M[14], 9, K$3[25]); c = GG(c, d, a, b, M[3], 14, K$3[26]); b = GG(b, c, d, a, M[8], 20, K$3[27]); a = GG(a, b, c, d, M[13], 5, K$3[28]); d = GG(d, a, b, c, M[2], 9, K$3[29]); c = GG(c, d, a, b, M[7], 14, K$3[30]); b = GG(b, c, d, a, M[12], 20, K$3[31]); a = HH(a, b, c, d, M[5], 4, K$3[32]); d = HH(d, a, b, c, M[8], 11, K$3[33]); c = HH(c, d, a, b, M[11], 16, K$3[34]); b = HH(b, c, d, a, M[14], 23, K$3[35]); a = HH(a, b, c, d, M[1], 4, K$3[36]); d = HH(d, a, b, c, M[4], 11, K$3[37]); c = HH(c, d, a, b, M[7], 16, K$3[38]); b = HH(b, c, d, a, M[10], 23, K$3[39]); a = HH(a, b, c, d, M[13], 4, K$3[40]); d = HH(d, a, b, c, M[0], 11, K$3[41]); c = HH(c, d, a, b, M[3], 16, K$3[42]); b = HH(b, c, d, a, M[6], 23, K$3[43]); a = HH(a, b, c, d, M[9], 4, K$3[44]); d = HH(d, a, b, c, M[12], 11, K$3[45]); c = HH(c, d, a, b, M[15], 16, K$3[46]); b = HH(b, c, d, a, M[2], 23, K$3[47]); a = II(a, b, c, d, M[0], 6, K$3[48]); d = II(d, a, b, c, M[7], 10, K$3[49]); c = II(c, d, a, b, M[14], 15, K$3[50]); b = II(b, c, d, a, M[5], 21, K$3[51]); a = II(a, b, c, d, M[12], 6, K$3[52]); d = II(d, a, b, c, M[3], 10, K$3[53]); c = II(c, d, a, b, M[10], 15, K$3[54]); b = II(b, c, d, a, M[1], 21, K$3[55]); a = II(a, b, c, d, M[8], 6, K$3[56]); d = II(d, a, b, c, M[15], 10, K$3[57]); c = II(c, d, a, b, M[6], 15, K$3[58]); b = II(b, c, d, a, M[13], 21, K$3[59]); a = II(a, b, c, d, M[4], 6, K$3[60]); d = II(d, a, b, c, M[11], 10, K$3[61]); c = II(c, d, a, b, M[2], 15, K$3[62]); b = II(b, c, d, a, M[9], 21, K$3[63]); state[0] = A + a; state[1] = B + b; state[2] = C + c; state[3] = D + d; } return new U8(state.buffer); } const md5 = createHash(digest$3, { ALGORITHM: "MD5", BLOCK_SIZE: 64, DIGEST_SIZE: 16, OID: "1.2.840.113549.2.5" }); function K$2(t) { if (t < 20) return 1518500249; if (t < 40) return 1859775393; if (t < 60) return 2400959708; return 3395469782; } const Ch$2 = (x, y, z) => x & y ^ ~x & z; const Parity = (x, y, z) => x ^ y ^ z; const Maj$2 = (x, y, z) => x & y ^ x & z ^ y & z; function ft(x, y, z, t) { if (t < 20) return Ch$2(x, y, z); if (t < 40) return Parity(x, y, z); if (t < 60) return Maj$2(x, y, z); return Parity(x, y, z); } function digest$2(message) { const state = new U8(20); const state_view = state.view(4); state_view.set(0, 0x67452301n); state_view.set(1, 0xefcdab89n); state_view.set(2, 0x98badcfen); state_view.set(3, 0x10325476n); state_view.set(4, 0xc3d2e1f0n); const m_byte = message.length; const m_bit = BigInt(m_byte) << 3n; const block_size = 64; const block_total = m_byte + 9 + 63 >> 6; const p = new U8(block_total * block_size); p.set(message); p[m_byte] = 128; const p_view = new DataView(p.buffer, p.byteOffset, p.byteLength); p_view.setBigUint64(p.length - 8, m_bit); for (let offset = 0; offset < p.length; offset += block_size) { const H0 = Number(state_view.get(0)); const H1 = Number(state_view.get(1)); const H2 = Number(state_view.get(2)); const H3 = Number(state_view.get(3)); const H4 = Number(state_view.get(4)); let a = H0; let b = H1; let c = H2; let d = H3; let e = H4; const W = new Uint32Array(80); for (let i = 0; i < 80; i++) { if (i < 16) W[i] = p_view.getUint32(offset + (i << 2)); else W[i] = rotateL32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); const T = rotateL32(a, 5) + ft(b, c, d, i) + K$2(i) + e + W[i]; e = d; d = c; c = rotateL32(b, 30); b = a; a = T; } state_view.set(0, BigInt(H0 + a)); state_view.set(1, BigInt(H1 + b)); state_view.set(2, BigInt(H2 + c)); state_view.set(3, BigInt(H3 + d)); state_view.set(4, BigInt(H4 + e)); } return state; } const sha1 = createHash(digest$2, { ALGORITHM: "SHA-1", BLOCK_SIZE: 64, DIGEST_SIZE: 20, OID: "1.3.14.3.2.26" }); const K$1 = new Uint32Array([ 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298 ]); const Ch$1 = (x, y, z) => x & y ^ ~x & z; const Maj$1 = (x, y, z) => x & y ^ x & z ^ y & z; const Sigma0$1 = (x) => rotateR32(x, 2) ^ rotateR32(x, 13) ^ rotateR32(x, 22); const Sigma1$1 = (x) => rotateR32(x, 6) ^ rotateR32(x, 11) ^ rotateR32(x, 25); const sigma0$1 = (x) => rotateR32(x, 7) ^ rotateR32(x, 18) ^ x >>> 3; const sigma1$1 = (x) => rotateR32(x, 17) ^ rotateR32(x, 19) ^ x >>> 10; function digest$1(state, message) { state = state.slice(0); const state_view = state.view(4); const m_byte = message.length; const m_bit = BigInt(m_byte) << 3n; const block_size = 64; const block_total = m_byte + 9 + 63 >> 6; const p = new U8(block_total * block_size); p.set(message); p[m_byte] = 128; const p_view = new DataView(p.buffer, p.byteOffset, p.byteLength); p_view.setBigUint64(p.length - 8, m_bit); for (let offset = 0; offset < p.length; offset += block_size) { const h0 = Number(state_view.get(0)); const h1 = Number(state_view.get(1)); const h2 = Number(state_view.get(2)); const h3 = Number(state_view.get(3)); const h4 = Number(state_view.get(4)); const h5 = Number(state_view.get(5)); const h6 = Number(state_view.get(6)); const h7 = Number(state_view.get(7)); let a = h0; let b = h1; let c = h2; let d = h3; let e = h4; let f = h5; let g = h6; let h = h7; const W = new Uint32Array(64); for (let i = 0; i < W.length; i++) { if (i < 16) W[i] = p_view.getUint32(offset + (i << 2)); else W[i] = sigma1$1(W[i - 2]) + W[i - 7] + sigma0$1(W[i - 15]) + W[i - 16]; const T1 = h + Sigma1$1(e) + Ch$1(e, f, g) + K$1[i] + W[i]; const T2 = Sigma0$1(a) + Maj$1(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } state_view.set(0, BigInt(h0 + a)); state_view.set(1, BigInt(h1 + b)); state_view.set(2, BigInt(h2 + c)); state_view.set(3, BigInt(h3 + d)); state_view.set(4, BigInt(h4 + e)); state_view.set(5, BigInt(h5 + f)); state_view.set(6, BigInt(h6 + g)); state_view.set(7, BigInt(h7 + h)); } return state; } function sha224Digest(M) { const state = new U8(32); const state_view = state.view(4); state_view.set(0, 0xc1059ed8n); state_view.set(1, 0x367cd507n); state_view.set(2, 0x3070dd17n); state_view.set(3, 0xf70e5939n); state_view.set(4, 0xffc00b31n); state_view.set(5, 0x68581511n); state_view.set(6, 0x64f98fa7n); state_view.set(7, 0xbefa4fa4n); return digest$1(state, M).slice(0, 28); } function sha256Digest(M) { const state = new U8(32); const state_view = state.view(4); state_view.set(0, 0x6a09e667n); state_view.set(1, 0xbb67ae85n); state_view.set(2, 0x3c6ef372n); state_view.set(3, 0xa54ff53an); state_view.set(4, 0x510e527fn); state_view.set(5, 0x9b05688cn); state_view.set(6, 0x1f83d9abn); state_view.set(7, 0x5be0cd19n); return digest$1(state, M); } const sha224 = createHash(sha224Digest, { ALGORITHM: "SHA-224", BLOCK_SIZE: 64, DIGEST_SIZE: 28, OID: "2.16.840.1.101.3.4.2.4" }); const sha256 = createHash(sha256Digest, { ALGORITHM: "SHA-256", BLOCK_SIZE: 64, DIGEST_SIZE: 32, OID: "2.16.840.1.101.3.4.2.1" }); const K = new BigUint64Array([ 0x428a2f98d728ae22n, 0x7137449123ef65cdn, 0xb5c0fbcfec4d3b2fn, 0xe9b5dba58189dbbcn, 0x3956c25bf348b538n, 0x59f111f1b605d019n, 0x923f82a4af194f9bn, 0xab1c5ed5da6d8118n, 0xd807aa98a3030242n, 0x12835b0145706fben, 0x243185be4ee4b28cn, 0x550c7dc3d5ffb4e2n, 0x72be5d74f27b896fn, 0x80deb1fe3b1696b1n, 0x9bdc06a725c71235n, 0xc19bf174cf692694n, 0xe49b69c19ef14ad2n, 0xefbe4786384f25e3n, 0x0fc19dc68b8cd5b5n, 0x240ca1cc77ac9c65n, 0x2de92c6f592b0275n, 0x4a7484aa6ea6e483n, 0x5cb0a9dcbd41fbd4n, 0x76f988da831153b5n, 0x983e5152ee66dfabn, 0xa831c66d2db43210n, 0xb00327c898fb213fn, 0xbf597fc7beef0ee4n, 0xc6e00bf33da88fc2n, 0xd5a79147930aa725n, 0x06ca6351e003826fn, 0x142929670a0e6e70n, 0x27b70a8546d22ffcn, 0x2e1b21385c26c926n, 0x4d2c6dfc5ac42aedn, 0x53380d139d95b3dfn, 0x650a73548baf63den, 0x766a0abb3c77b2a8n, 0x81c2c92e47edaee6n, 0x92722c851482353bn, 0xa2bfe8a14cf10364n, 0xa81a664bbc423001n, 0xc24b8b70d0f89791n, 0xc76c51a30654be30n, 0xd192e819d6ef5218n, 0xd69906245565a910n, 0xf40e35855771202an, 0x106aa07032bbd1b8n, 0x19a4c116b8d2d0c8n, 0x1e376c085141ab53n, 0x2748774cdf8eeb99n, 0x34b0bcb5e19b48a8n, 0x391c0cb3c5c95a63n, 0x4ed8aa4ae3418acbn, 0x5b9cca4f7763e373n, 0x682e6ff3d6b2b8a3n, 0x748f82ee5defb2fcn, 0x78a5636f43172f60n, 0x84c87814a1f0ab72n, 0x8cc702081a6439ecn, 0x90befffa23631e28n, 0xa4506cebde82bde9n, 0xbef9a3f7b2c67915n, 0xc67178f2e372532bn, 0xca273eceea26619cn, 0xd186b8c721c0c207n, 0xeada7dd6cde0eb1en, 0xf57d4f7fee6ed178n, 0x06f067aa72176fban, 0x0a637dc5a2c898a6n, 0x113f9804bef90daen, 0x1b710b35131c471bn, 0x28db77f523047d84n, 0x32caab7b40c72493n, 0x3c9ebe0a15c9bebcn, 0x431d67c49c100d4cn, 0x4cc5d4becb3e42b6n, 0x597f299cfc657e2an, 0x5fcb6fab3ad6faecn, 0x6c44198c4a475817n ]); const mask64$1 = genBitMask(64); const rotateR64 = (x, n) => rotateR(64, x, n, mask64$1); const Ch = (x, y, z) => x & y ^ ~x & z; const Maj = (x, y, z) => x & y ^ x & z ^ y & z; const Sigma0 = (x) => rotateR64(x, 28n) ^ rotateR64(x, 34n) ^ rotateR64(x, 39n); const Sigma1 = (x) => rotateR64(x, 14n) ^ rotateR64(x, 18n) ^ rotateR64(x, 41n); const sigma0 = (x) => rotateR64(x, 1n) ^ rotateR64(x, 8n) ^ x >> 7n; const sigma1 = (x) => rotateR64(x, 19n) ^ rotateR64(x, 61n) ^ x >> 6n; function IVGen(t) { if (t <= 0) { throw new KitError("SHA-512 truncation must be greater than 0"); } if (t >= 512) { throw new KitError("SHA-512 truncation must be less than 512"); } if (t === 384) { throw new KitError("SHA-512 truncation must not be 384"); } const state = new U8(64); const state_view = state.view(8); state_view.set(0, 0x6a09e667f3bcc908n ^ 0xa5a5a5a5a5a5a5a5n); state_view.set(1, 0xbb67ae8584caa73bn ^ 0xa5a5a5a5a5a5a5a5n); state_view.set(2, 0x3c6ef372fe94f82bn ^ 0xa5a5a5a5a5a5a5a5n); state_view.set(3, 0xa54ff53a5f1d36f1n ^ 0xa5a5a5a5a5a5a5a5n); state_view.set(4, 0x510e527fade682d1n ^ 0xa5a5a5a5a5a5a5a5n); state_view.set(5, 0x9b05688c2b3e6c1fn ^ 0xa5a5a5a5a5a5a5a5n); state_view.set(6, 0x1f83d9abfb41bd6bn ^ 0xa5a5a5a5a5a5a5a5n); state_view.set(7, 0x5be0cd19137e2179n ^ 0xa5a5a5a5a5a5a5a5n); return digest(state, UTF8(`SHA-512/${t}`)); } function digest(state, message) { state = state.slice(0); const state_view = state.view(8); const m_byte = message.byteLength; const m_bit = BigInt(m_byte) << 3n; const block_size = 128; const block_total = m_byte + 17 + 127 >> 7; const p = new U8(block_total * block_size); p.set(message); p[m_byte] = 128; const p_view = new DataView(p.buffer, p.byteOffset, p.byteLength); p_view.setBigUint64(p.byteLength - 16, m_bit >> 32n); p_view.setBigUint64(p.byteLength - 8, m_bit & 0xffffffffffffffffn); for (let offset = 0; offset < p.length; offset += block_size) { const H0 = state_view.get(0); const H1 = state_view.get(1); const H2 = state_view.get(2); const H3 = state_view.get(3); const H4 = state_view.get(4); const H5 = state_view.get(5); const H6 = state_view.get(6); const H7 = state_view.get(7); let a = H0; let b = H1; let c = H2; let d = H3; let e = H4; let f = H5; let g = H6; let h = H7; const W = new BigUint64Array(80); for (let i = 0; i < W.length; i++) { if (i < 16) W[i] = p_view.getBigUint64(offset + (i << 3)); else W[i] = sigma1(W[i - 2]) + W[i - 7] + sigma0(W[i - 15]) + W[i - 16]; const T1 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; const T2 = Sigma0(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1 & 0xffffffffffffffffn; d = c; c = b; b = a; a = T1 + T2 & 0xffffffffffffffffn; } state_view.set(0, H0 + a); state_view.set(1, H1 + b); state_view.set(2, H2 + c); state_view.set(3, H3 + d); state_view.set(4, H4 + e); state_view.set(5, H5 + f); state_view.set(6, H6 + g); state_view.set(7, H7 + h); } return state; } function sha384Digest(M) { const state = new U8(64); const state_view = state.view(8); state_view.set(0, 0xcbbb9d5dc1059ed8n); state_view.set(1, 0x629a292a367cd507n); state_view.set(2, 0x9159015a3070dd17n); state_view.set(3, 0x152fecd8f70e5939n); state_view.set(4, 0x67332667ffc00b31n); state_view.set(5, 0x8eb44a8768581511n); state_view.set(6, 0xdb0c2e0d64f98fa7n); state_view.set(7, 0x47b5481dbefa4fa4n); return digest(state, M).slice(0, 48); } function sha512Digest(M) { const state = new U8(64); const state_view = state.view(8); state_view.set(0, 0x6a09e667f3bcc908n); state_view.set(1, 0xbb67ae8584caa73bn); state_view.set(2, 0x3c6ef372fe94f82bn); state_view.set(3, 0xa54ff53a5f1d36f1n); state_view.set(4, 0x510e527fade682d1n); state_view.set(5, 0x9b05688c2b3e6c1fn); state_view.set(6, 0x1f83d9abfb41bd6bn); state_view.set(7, 0x5be0cd19137e2179n); return digest(state, M); } const sha384 = createHash(sha384Digest, { ALGORITHM: "SHA-384", BLOCK_SIZE: 128, DIGEST_SIZE: 48, OID: "2.16.840.1.101.3.4.2.2" }); const sha512 = createHash(sha512Digest, { ALGORITHM: "SHA-512", BLOCK_SIZE: 128, DIGEST_SIZE: 64, OID: "2.16.840.1.101.3.4.2.3" }); function sha512t(t) { const status = IVGen(t); let OID; if (t === 224) OID = "2.16.840.1.101.3.4.2.5"; if (t === 256) OID = "2.16.840.1.101.3.4.2.6"; return createHash((M) => digest(status, M).slice(0, t >> 3), { ALGORITHM: `SHA-512/${t}`, BLOCK_SIZE: 128, DIGEST_SIZE: t >> 3, OID }); } const R = [ [0n, 36n, 3n, 41n, 18n], [1n, 44n, 10n, 45n, 2n], [62n, 6n, 43n, 15n, 61n], [28n, 55n, 25n, 21n, 56n], [27n, 20n, 39n, 8n, 14n] ]; const RC12 = [ 0x000000008000808bn, 0x800000000000008bn, 0x8000000000008089n, 0x8000000000008003n, 0x8000000000008002n, 0x8000000000000080n, 0x000000000000800an, 0x800000008000000an, 0x8000000080008081n, 0x8000000000008080n, 0x0000000080000001n, 0x8000000080008008n ]; const RC24 = [ 0x0000000000000001n, 0x0000000000008082n, 0x800000000000808an, 0x8000000080008000n, 0x000000000000808bn, 0x0000000080000001n, 0x8000000080008081n, 0x8000000000008009n, 0x000000000000008an, 0x0000000000000088n, 0x0000000080008009n, 0x000000008000000an, 0x000000008000808bn, 0x800000000000008bn, 0x8000000000008089n, 0x8000000000008003n, 0x8000000000008002n, 0x8000000000000080n, 0x000000000000800an, 0x800000008000000an, 0x8000000080008081n, 0x8000000000008080n, 0x0000000080000001n, 0x8000000080008008n ]; const mask64 = genBitMask(64); const rotateL64 = (x, n) => rotateL(64, x, n, mask64); function RCGen(l = 6, nr = 24) { const RCTable = []; for (let ir = 0; ir < nr; ir++) { let RC = 0n; for (let j = 0; j <= l; j++) { const t = j + 7 * ir; let rc; if (t % 255 === 0) { rc = 1n; } else { let R2 = 0x80n; for (let i = 1; i <= t % 255; i++) { const b = R2 & 1n; R2 ^= b << 8n | b << 4n | b << 3n | b << 2n; R2 >>= 1n; } rc = R2 >> 7n; } RC |= rc << BigInt(2 ** j - 1); } RCTable.push(RC); } return RCTable; } function createStateArray() { return Array.from({ length: 5 }).map(() => new BigUint64Array(5)); } function toStateArray(S) { const A = createStateArray(); const view = new DataView(S.buffer, S.byteOffset, S.byteLength); for (let x = 0; x < 5; x++) { for (let y = 0; y < 5; y++) { A[x][y] = view.getBigUint64(y * 5 + x << 3, true); } } return A; } function toState(A) { const S = new Uint8Array(200); const view = new DataView(S.buffer, S.byteOffset, S.byteLength); for (let x = 0; x < 5; x++) { for (let y = 0; y < 5; y++) { view.setBigUint64(y * 5 + x << 3, A[x][y], true); } } return S; } function theta(A) { const C = new BigUint64Array(5); const D = new BigUint64Array(5); for (let x = 0; x < 5; x++) { C[x] = A[x][0] ^ A[x][1] ^ A[x][2] ^ A[x][3] ^ A[x][4]; } for (let x = 0; x < 5; x++) { D[x] = C[(x + 4) % 5] ^ rotateL64(C[(x