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,830 lines (1,820 loc) • 275 kB
JavaScript
'use strict';
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] ^