UNPKG

@protontech/openpgp

Version:

OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.

1 lines 68.2 kB
{"version":3,"file":"noble_post_quantum.min.mjs","sources":["../../node_modules/@noble/post-quantum/esm/utils.js","../../node_modules/@noble/post-quantum/esm/_crystals.js","../../node_modules/@noble/post-quantum/esm/ml-kem.js","../../node_modules/@noble/post-quantum/esm/ml-dsa.js"],"sourcesContent":["/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { bytes as abytes } from '@noble/hashes/_assert';\nimport { randomBytes as randb, concatBytes } from '@noble/hashes/utils';\nexport const ensureBytes = abytes;\nexport const randomBytes = randb;\nexport { concatBytes };\n// Compares 2 u8a-s in kinda constant time\nexport function equalBytes(a, b) {\n if (a.length !== b.length)\n return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++)\n diff |= a[i] ^ b[i];\n return diff === 0;\n}\nexport function splitCoder(...lengths) {\n const getLength = (c) => (typeof c === 'number' ? c : c.bytesLen);\n const bytesLen = lengths.reduce((sum, a) => sum + getLength(a), 0);\n return {\n bytesLen,\n encode: (bufs) => {\n const res = new Uint8Array(bytesLen);\n for (let i = 0, pos = 0; i < lengths.length; i++) {\n const c = lengths[i];\n const l = getLength(c);\n const b = typeof c === 'number' ? bufs[i] : c.encode(bufs[i]);\n ensureBytes(b, l);\n res.set(b, pos);\n if (typeof c !== 'number')\n b.fill(0); // clean\n pos += l;\n }\n return res;\n },\n decode: (buf) => {\n ensureBytes(buf, bytesLen);\n const res = [];\n for (const c of lengths) {\n const l = getLength(c);\n const b = buf.subarray(0, l);\n res.push(typeof c === 'number' ? b : c.decode(b));\n buf = buf.subarray(l);\n }\n return res;\n },\n };\n}\n// nano-packed.array (fixed size)\nexport function vecCoder(c, vecLen) {\n const bytesLen = vecLen * c.bytesLen;\n return {\n bytesLen,\n encode: (u) => {\n if (u.length !== vecLen)\n throw new Error(`vecCoder.encode: wrong length=${u.length}. Expected: ${vecLen}`);\n const res = new Uint8Array(bytesLen);\n for (let i = 0, pos = 0; i < u.length; i++) {\n const b = c.encode(u[i]);\n res.set(b, pos);\n b.fill(0); // clean\n pos += b.length;\n }\n return res;\n },\n decode: (a) => {\n ensureBytes(a, bytesLen);\n const r = [];\n for (let i = 0; i < a.length; i += c.bytesLen)\n r.push(c.decode(a.subarray(i, i + c.bytesLen)));\n return r;\n },\n };\n}\n// cleanBytes(new Uint8Array(), [new Uint16Array(), new Uint32Array()])\nexport function cleanBytes(...list) {\n for (const t of list) {\n if (Array.isArray(t))\n for (const b of t)\n b.fill(0);\n else\n t.fill(0);\n }\n}\nexport function getMask(bits) {\n return (1 << bits) - 1; // 4 -> 0b1111\n}\n//# sourceMappingURL=utils.js.map","/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { shake128, shake256 } from '@noble/hashes/sha3';\nimport { getMask } from './utils.js';\n// TODO: benchmark\nfunction bitReversal(n, bits = 8) {\n const padded = n.toString(2).padStart(8, '0');\n const sliced = padded.slice(-bits).padStart(7, '0');\n const revrsd = sliced.split('').reverse().join('');\n return Number.parseInt(revrsd, 2);\n}\nexport const genCrystals = (opts) => {\n // isKyber: true means Kyber, false means Dilithium\n const { newPoly, N, Q, F, ROOT_OF_UNITY, brvBits, isKyber } = opts;\n const mod = (a, modulo = Q) => {\n const result = a % modulo | 0;\n return (result >= 0 ? result | 0 : (modulo + result) | 0) | 0;\n };\n // -(Q-1)/2 < a <= (Q-1)/2\n const smod = (a, modulo = Q) => {\n const r = mod(a, modulo) | 0;\n return (r > modulo >> 1 ? (r - modulo) | 0 : r) | 0;\n };\n // Generate zettas\n function getZettas() {\n const out = newPoly(N);\n for (let i = 0; i < N; i++) {\n const b = bitReversal(i, brvBits);\n const p = BigInt(ROOT_OF_UNITY) ** BigInt(b) % BigInt(Q);\n out[i] = Number(p) | 0;\n }\n return out;\n }\n const nttZetas = getZettas();\n // Number-Theoretic Transform\n // Explained: https://electricdusk.com/ntt.html\n // Kyber has slightly different params, since there is no 512th primitive root of unity mod q,\n // only 256th primitive root of unity mod. Which also complicates MultiplyNTT.\n // TODO: there should be less ugly way to define this.\n const LEN1 = isKyber ? 128 : N;\n const LEN2 = isKyber ? 1 : 0;\n const NTT = {\n encode: (r) => {\n for (let k = 1, len = 128; len > LEN2; len >>= 1) {\n for (let start = 0; start < N; start += 2 * len) {\n const zeta = nttZetas[k++];\n for (let j = start; j < start + len; j++) {\n const t = mod(zeta * r[j + len]);\n r[j + len] = mod(r[j] - t) | 0;\n r[j] = mod(r[j] + t) | 0;\n }\n }\n }\n return r;\n },\n decode: (r) => {\n for (let k = LEN1 - 1, len = 1 + LEN2; len < LEN1 + LEN2; len <<= 1) {\n for (let start = 0; start < N; start += 2 * len) {\n const zeta = nttZetas[k--];\n for (let j = start; j < start + len; j++) {\n const t = r[j];\n r[j] = mod(t + r[j + len]);\n r[j + len] = mod(zeta * (r[j + len] - t));\n }\n }\n }\n for (let i = 0; i < r.length; i++)\n r[i] = mod(F * r[i]);\n return r;\n },\n };\n // Encode polynominal as bits\n const bitsCoder = (d, c) => {\n const mask = getMask(d);\n const bytesLen = d * (N / 8);\n return {\n bytesLen,\n encode: (poly) => {\n const r = new Uint8Array(bytesLen);\n for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < poly.length; i++) {\n buf |= (c.encode(poly[i]) & mask) << bufLen;\n bufLen += d;\n for (; bufLen >= 8; bufLen -= 8, buf >>= 8)\n r[pos++] = buf & getMask(bufLen);\n }\n return r;\n },\n decode: (bytes) => {\n const r = newPoly(N);\n for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < bytes.length; i++) {\n buf |= bytes[i] << bufLen;\n bufLen += 8;\n for (; bufLen >= d; bufLen -= d, buf >>= d)\n r[pos++] = c.decode(buf & mask);\n }\n return r;\n },\n };\n };\n return { mod, smod, nttZetas, NTT, bitsCoder };\n};\nconst createXofShake = (shake) => (seed, blockLen) => {\n if (!blockLen)\n blockLen = shake.blockLen;\n // Optimizations that won't mater:\n // - cached seed update (two .update(), on start and on the end)\n // - another cache which cloned into working copy\n // Faster than multiple updates, since seed less than blockLen\n const _seed = new Uint8Array(seed.length + 2);\n _seed.set(seed);\n const seedLen = seed.length;\n const buf = new Uint8Array(blockLen); // == shake128.blockLen\n let h = shake.create({});\n let calls = 0;\n let xofs = 0;\n return {\n stats: () => ({ calls, xofs }),\n get: (x, y) => {\n _seed[seedLen + 0] = x;\n _seed[seedLen + 1] = y;\n h.destroy();\n h = shake.create({}).update(_seed);\n calls++;\n return () => {\n xofs++;\n return h.xofInto(buf);\n };\n },\n clean: () => {\n h.destroy();\n buf.fill(0);\n _seed.fill(0);\n },\n };\n};\nexport const XOF128 = /* @__PURE__ */ createXofShake(shake128);\nexport const XOF256 = /* @__PURE__ */ createXofShake(shake256);\n//# sourceMappingURL=_crystals.js.map","/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { sha3_256, sha3_512, shake256 } from '@noble/hashes/sha3';\nimport { u32 } from '@noble/hashes/utils';\nimport { genCrystals, XOF128 } from './_crystals.js';\nimport { cleanBytes, ensureBytes, equalBytes, randomBytes, splitCoder, vecCoder, } from './utils.js';\n/*\nLattice-based key encapsulation mechanism.\nSee [official site](https://www.pq-crystals.org/kyber/resources.shtml),\n[repo](https://github.com/pq-crystals/kyber),\n[spec](https://datatracker.ietf.org/doc/draft-cfrg-schwabe-kyber/).\n\nKey encapsulation is similar to DH / ECDH (think X25519), with important differences:\n\n- We can't verify if it was \"Bob\" who've sent the shared secret.\n In ECDH, it's always verified\n- Kyber is probabalistic and relies on quality of randomness (CSPRNG).\n ECDH doesn't (to this extent).\n- Kyber decapsulation never throws an error, even when shared secret was\n encrypted by a different public key. It will just return a different\n shared secret\n\nThere are some concerns with regards to security: see\n[djb blog](https://blog.cr.yp.to/20231003-countcorrectly.html) and\n[mailing list](https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/W2VOzy0wz_E).\n\n*/\nconst N = 256; // Kyber (not FIPS-203) supports different lengths, but all std modes were using 256\nconst Q = 3329; // 13*(2**8)+1, modulo prime\nconst F = 3303; // 3303 ≡ 128**(−1) mod q (FIPS-203)\nconst ROOT_OF_UNITY = 17; // ζ = 17 ∈ Zq is a primitive 256-th root of unity modulo Q. ζ**128 ≡−1\nconst { mod, nttZetas, NTT, bitsCoder } = genCrystals({\n N,\n Q,\n F,\n ROOT_OF_UNITY,\n newPoly: (n) => new Uint16Array(n),\n brvBits: 7,\n isKyber: true,\n});\n// prettier-ignore\nexport const PARAMS = {\n 512: { N, Q, K: 2, ETA1: 3, ETA2: 2, du: 10, dv: 4, RBGstrength: 128 },\n 768: { N, Q, K: 3, ETA1: 2, ETA2: 2, du: 10, dv: 4, RBGstrength: 192 },\n 1024: { N, Q, K: 4, ETA1: 2, ETA2: 2, du: 11, dv: 5, RBGstrength: 256 },\n};\n// FIPS-203: compress/decompress\nconst compress = (d) => {\n // Special case, no need to compress, pass as is, but strip high bytes on compression\n if (d >= 12)\n return { encode: (i) => i, decode: (i) => i };\n // NOTE: we don't use float arithmetic (forbidden by FIPS-203 and high chance of bugs).\n // Comments map to python implementation in RFC (draft-cfrg-schwabe-kyber)\n // const round = (i: number) => Math.floor(i + 0.5) | 0;\n const a = 2 ** (d - 1);\n return {\n // const compress = (i: number) => round((2 ** d / Q) * i) % 2 ** d;\n encode: (i) => ((i << d) + Q / 2) / Q,\n // const decompress = (i: number) => round((Q / 2 ** d) * i);\n decode: (i) => (i * Q + a) >>> d,\n };\n};\n// NOTE: we merge encoding and compress because it is faster, also both require same d param\n// Converts between bytes and d-bits compressed representation. Kinda like convertRadix2 from @scure/base\n// decode(encode(t)) == t, but there is loss of information on encode(decode(t))\nconst polyCoder = (d) => bitsCoder(d, compress(d));\nfunction polyAdd(a, b) {\n for (let i = 0; i < N; i++)\n a[i] = mod(a[i] + b[i]); // a += b\n}\nfunction polySub(a, b) {\n for (let i = 0; i < N; i++)\n a[i] = mod(a[i] - b[i]); // a -= b\n}\n// FIPS-203: Computes the product of two degree-one polynomials with respect to a quadratic modulus\nfunction BaseCaseMultiply(a0, a1, b0, b1, zeta) {\n const c0 = mod(a1 * b1 * zeta + a0 * b0);\n const c1 = mod(a0 * b1 + a1 * b0);\n return { c0, c1 };\n}\n// FIPS-203: Computes the product (in the ring Tq) of two NTT representations. NOTE: works inplace for f\n// NOTE: since multiply defined only for NTT representation, we need to convert to NTT, multiply and convert back\nfunction MultiplyNTTs(f, g) {\n for (let i = 0; i < N / 2; i++) {\n let z = nttZetas[64 + (i >> 1)];\n if (i & 1)\n z = -z;\n const { c0, c1 } = BaseCaseMultiply(f[2 * i + 0], f[2 * i + 1], g[2 * i + 0], g[2 * i + 1], z);\n f[2 * i + 0] = c0;\n f[2 * i + 1] = c1;\n }\n return f;\n}\n// Return poly in NTT representation\nfunction SampleNTT(xof) {\n const r = new Uint16Array(N);\n for (let j = 0; j < N;) {\n const b = xof();\n if (b.length % 3)\n throw new Error('SampleNTT: unaligned block');\n for (let i = 0; j < N && i + 3 <= b.length; i += 3) {\n const d1 = ((b[i + 0] >> 0) | (b[i + 1] << 8)) & 0xfff;\n const d2 = ((b[i + 1] >> 4) | (b[i + 2] << 4)) & 0xfff;\n if (d1 < Q)\n r[j++] = d1;\n if (j < N && d2 < Q)\n r[j++] = d2;\n }\n }\n return r;\n}\n// Sampling from the centered binomial distribution\n// Returns poly with small coefficients (noise/errors)\nfunction sampleCBD(PRF, seed, nonce, eta) {\n const buf = PRF((eta * N) / 4, seed, nonce);\n const r = new Uint16Array(N);\n const b32 = u32(buf);\n let len = 0;\n for (let i = 0, p = 0, bb = 0, t0 = 0; i < b32.length; i++) {\n let b = b32[i];\n for (let j = 0; j < 32; j++) {\n bb += b & 1;\n b >>= 1;\n len += 1;\n if (len === eta) {\n t0 = bb;\n bb = 0;\n }\n else if (len === 2 * eta) {\n r[p++] = mod(t0 - bb);\n bb = 0;\n len = 0;\n }\n }\n }\n if (len)\n throw new Error(`sampleCBD: leftover bits: ${len}`);\n return r;\n}\n// K-PKE\n// As per FIPS-203, it doesn't perform any input validation and can't be used in standalone fashion.\nconst genKPKE = (opts) => {\n const { K, PRF, XOF, HASH512, ETA1, ETA2, du, dv } = opts;\n const poly1 = polyCoder(1);\n const polyV = polyCoder(dv);\n const polyU = polyCoder(du);\n const publicCoder = splitCoder(vecCoder(polyCoder(12), K), 32);\n const secretCoder = vecCoder(polyCoder(12), K);\n const cipherCoder = splitCoder(vecCoder(polyU, K), polyV);\n const seedCoder = splitCoder(32, 32);\n return {\n secretCoder,\n secretKeyLen: secretCoder.bytesLen,\n publicKeyLen: publicCoder.bytesLen,\n cipherTextLen: cipherCoder.bytesLen,\n keygen: (seed) => {\n const seedDst = new Uint8Array(33);\n seedDst.set(seed);\n seedDst[32] = K;\n const seedHash = HASH512(seedDst);\n const [rho, sigma] = seedCoder.decode(seedHash);\n const sHat = [];\n const tHat = [];\n for (let i = 0; i < K; i++)\n sHat.push(NTT.encode(sampleCBD(PRF, sigma, i, ETA1)));\n const x = XOF(rho);\n for (let i = 0; i < K; i++) {\n const e = NTT.encode(sampleCBD(PRF, sigma, K + i, ETA1));\n for (let j = 0; j < K; j++) {\n const aji = SampleNTT(x.get(j, i)); // A[j][i], inplace\n polyAdd(e, MultiplyNTTs(aji, sHat[j]));\n }\n tHat.push(e); // t ← A ◦ s + e\n }\n x.clean();\n const res = {\n publicKey: publicCoder.encode([tHat, rho]),\n secretKey: secretCoder.encode(sHat),\n };\n cleanBytes(rho, sigma, sHat, tHat, seedDst, seedHash);\n return res;\n },\n encrypt: (publicKey, msg, seed) => {\n const [tHat, rho] = publicCoder.decode(publicKey);\n const rHat = [];\n for (let i = 0; i < K; i++)\n rHat.push(NTT.encode(sampleCBD(PRF, seed, i, ETA1)));\n const x = XOF(rho);\n const tmp2 = new Uint16Array(N);\n const u = [];\n for (let i = 0; i < K; i++) {\n const e1 = sampleCBD(PRF, seed, K + i, ETA2);\n const tmp = new Uint16Array(N);\n for (let j = 0; j < K; j++) {\n const aij = SampleNTT(x.get(i, j)); // A[i][j], inplace\n polyAdd(tmp, MultiplyNTTs(aij, rHat[j])); // t += aij * rHat[j]\n }\n polyAdd(e1, NTT.decode(tmp)); // e1 += tmp\n u.push(e1);\n polyAdd(tmp2, MultiplyNTTs(tHat[i], rHat[i])); // t2 += tHat[i] * rHat[i]\n tmp.fill(0);\n }\n x.clean();\n const e2 = sampleCBD(PRF, seed, 2 * K, ETA2);\n polyAdd(e2, NTT.decode(tmp2)); // e2 += tmp2\n const v = poly1.decode(msg); // encode plaintext m into polynomial v\n polyAdd(v, e2); // v += e2\n cleanBytes(tHat, rHat, tmp2, e2);\n return cipherCoder.encode([u, v]);\n },\n decrypt: (cipherText, privateKey) => {\n const [u, v] = cipherCoder.decode(cipherText);\n const sk = secretCoder.decode(privateKey); // s ← ByteDecode_12(dkPKE)\n const tmp = new Uint16Array(N);\n for (let i = 0; i < K; i++)\n polyAdd(tmp, MultiplyNTTs(sk[i], NTT.encode(u[i]))); // tmp += sk[i] * u[i]\n polySub(v, NTT.decode(tmp)); // v += tmp\n cleanBytes(tmp, sk, u);\n return poly1.encode(v);\n },\n };\n};\nfunction createKyber(opts) {\n const KPKE = genKPKE(opts);\n const { HASH256, HASH512, KDF } = opts;\n const { secretCoder: KPKESecretCoder, cipherTextLen } = KPKE;\n const publicKeyLen = KPKE.publicKeyLen; // 384*K+32\n const secretCoder = splitCoder(KPKE.secretKeyLen, KPKE.publicKeyLen, 32, 32);\n const secretKeyLen = secretCoder.bytesLen;\n const msgLen = 32;\n return {\n publicKeyLen,\n msgLen,\n keygen: (seed = randomBytes(64)) => {\n ensureBytes(seed, 64);\n const { publicKey, secretKey: sk } = KPKE.keygen(seed.subarray(0, 32));\n const publicKeyHash = HASH256(publicKey);\n // (dkPKE||ek||H(ek)||z)\n const secretKey = secretCoder.encode([sk, publicKey, publicKeyHash, seed.subarray(32)]);\n cleanBytes(sk, publicKeyHash);\n return { publicKey, secretKey };\n },\n encapsulate: (publicKey, msg = randomBytes(32)) => {\n ensureBytes(publicKey, publicKeyLen);\n ensureBytes(msg, msgLen);\n // FIPS-203 includes additional verification check for modulus\n const eke = publicKey.subarray(0, 384 * opts.K);\n const ek = KPKESecretCoder.encode(KPKESecretCoder.decode(eke.slice())); // Copy because of inplace encoding\n // (Modulus check.) Perform the computation ek ← ByteEncode12(ByteDecode12(eke)).\n // If ek = ̸ eke, the input is invalid. (See Section 4.2.1.)\n if (!equalBytes(ek, eke)) {\n cleanBytes(ek);\n throw new Error('ML-KEM.encapsulate: wrong publicKey modulus');\n }\n cleanBytes(ek);\n const kr = HASH512.create().update(msg).update(HASH256(publicKey)).digest(); // derive randomness\n const cipherText = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64));\n kr.subarray(32).fill(0);\n return { cipherText, sharedSecret: kr.subarray(0, 32) };\n },\n decapsulate: (cipherText, secretKey) => {\n ensureBytes(secretKey, secretKeyLen); // 768*k + 96\n ensureBytes(cipherText, cipherTextLen); // 32(du*k + dv)\n const [sk, publicKey, publicKeyHash, z] = secretCoder.decode(secretKey);\n const msg = KPKE.decrypt(cipherText, sk);\n const kr = HASH512.create().update(msg).update(publicKeyHash).digest(); // derive randomness, Khat, rHat = G(mHat || h)\n const Khat = kr.subarray(0, 32);\n const cipherText2 = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64)); // re-encrypt using the derived randomness\n const isValid = equalBytes(cipherText, cipherText2); // if ciphertexts do not match, “implicitly reject”\n const Kbar = KDF.create({ dkLen: 32 }).update(z).update(cipherText).digest();\n cleanBytes(msg, cipherText2, !isValid ? Khat : Kbar);\n return isValid ? Khat : Kbar;\n },\n };\n}\nfunction shakePRF(dkLen, key, nonce) {\n return shake256\n .create({ dkLen })\n .update(key)\n .update(new Uint8Array([nonce]))\n .digest();\n}\nconst opts = {\n HASH256: sha3_256,\n HASH512: sha3_512,\n KDF: shake256,\n XOF: XOF128,\n PRF: shakePRF,\n};\n/**\n * FIPS-203 ML-KEM.\n */\nexport const ml_kem512 = /* @__PURE__ */ createKyber({\n ...opts,\n ...PARAMS[512],\n});\nexport const ml_kem768 = /* @__PURE__ */ createKyber({\n ...opts,\n ...PARAMS[768],\n});\nexport const ml_kem1024 = /* @__PURE__ */ createKyber({\n ...opts,\n ...PARAMS[1024],\n});\n//# sourceMappingURL=ml-kem.js.map","/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { shake256 } from '@noble/hashes/sha3';\nimport { genCrystals, XOF128, XOF256 } from './_crystals.js';\nimport { cleanBytes, ensureBytes, equalBytes, randomBytes, splitCoder, vecCoder, concatBytes, } from './utils.js';\n/*\nLattice-based digital signature algorithm. See\n[official site](https://www.pq-crystals.org/dilithium/index.shtml),\n[repo](https://github.com/pq-crystals/dilithium).\nDilithium has similar internals to Kyber, but their keys and params are different.\n\n*/\n// Constants\nconst N = 256;\n// 2**23 − 2**13 + 1, 23 bits: multiply will be 46. We have enough precision in JS to avoid bigints\nconst Q = 8380417;\nconst ROOT_OF_UNITY = 1753;\n// f = 256**−1 mod q, pow(256, -1, q) = 8347681 (python3)\nconst F = 8347681;\nconst D = 13;\n// Dilithium is kinda parametrized over GAMMA2, but everything will break with any other value.\nconst GAMMA2_1 = Math.floor((Q - 1) / 88) | 0;\nconst GAMMA2_2 = Math.floor((Q - 1) / 32) | 0;\n// prettier-ignore\nexport const PARAMS = {\n 2: { K: 4, L: 4, D, GAMMA1: 2 ** 17, GAMMA2: GAMMA2_1, TAU: 39, ETA: 2, OMEGA: 80 },\n 3: { K: 6, L: 5, D, GAMMA1: 2 ** 19, GAMMA2: GAMMA2_2, TAU: 49, ETA: 4, OMEGA: 55 },\n 5: { K: 8, L: 7, D, GAMMA1: 2 ** 19, GAMMA2: GAMMA2_2, TAU: 60, ETA: 2, OMEGA: 75 },\n};\nconst newPoly = (n) => new Int32Array(n);\nconst { mod, smod, NTT, bitsCoder } = genCrystals({\n N,\n Q,\n F,\n ROOT_OF_UNITY,\n newPoly,\n isKyber: false,\n brvBits: 8,\n});\nconst id = (n) => n;\nconst polyCoder = (d, compress = id, verify = id) => bitsCoder(d, {\n encode: (i) => compress(verify(i)),\n decode: (i) => verify(compress(i)),\n});\nconst polyAdd = (a, b) => {\n for (let i = 0; i < a.length; i++)\n a[i] = mod(a[i] + b[i]);\n return a;\n};\nconst polySub = (a, b) => {\n for (let i = 0; i < a.length; i++)\n a[i] = mod(a[i] - b[i]);\n return a;\n};\nconst polyShiftl = (p) => {\n for (let i = 0; i < N; i++)\n p[i] <<= D;\n return p;\n};\nconst polyChknorm = (p, B) => {\n // Not very sure about this, but FIPS204 doesn't provide any function for that :(\n for (let i = 0; i < N; i++)\n if (Math.abs(smod(p[i])) >= B)\n return true;\n return false;\n};\nconst MultiplyNTTs = (a, b) => {\n // NOTE: we don't use montgomery reduction in code, since it requires 64 bit ints,\n // which is not available in JS. mod(a[i] * b[i]) is ok, since Q is 23 bit,\n // which means a[i] * b[i] is 46 bit, which is safe to use in JS. (number is 53 bits).\n // Barrett reduction is slower than mod :(\n const c = newPoly(N);\n for (let i = 0; i < a.length; i++)\n c[i] = mod(a[i] * b[i]);\n return c;\n};\n// Return poly in NTT representation\nfunction RejNTTPoly(xof) {\n // Samples a polynomial ∈ Tq.\n const r = newPoly(N);\n // NOTE: we can represent 3xu24 as 4xu32, but it doesn't improve perf :(\n for (let j = 0; j < N;) {\n const b = xof();\n if (b.length % 3)\n throw new Error('RejNTTPoly: unaligned block');\n for (let i = 0; j < N && i <= b.length - 3; i += 3) {\n const t = (b[i + 0] | (b[i + 1] << 8) | (b[i + 2] << 16)) & 0x7fffff; // 3 bytes\n if (t < Q)\n r[j++] = t;\n }\n }\n return r;\n}\nconst EMPTY = new Uint8Array(0);\nfunction getDilithium(opts) {\n const { K, L, GAMMA1, GAMMA2, TAU, ETA, OMEGA } = opts;\n const { CRH_BYTES, TR_BYTES, C_TILDE_BYTES, XOF128, XOF256 } = opts;\n if (![2, 4].includes(ETA))\n throw new Error('Wrong ETA');\n if (![1 << 17, 1 << 19].includes(GAMMA1))\n throw new Error('Wrong GAMMA1');\n if (![GAMMA2_1, GAMMA2_2].includes(GAMMA2))\n throw new Error('Wrong GAMMA2');\n const BETA = TAU * ETA;\n const decompose = (r) => {\n // Decomposes r into (r1, r0) such that r ≡ r1(2γ2) + r0 mod q.\n const rPlus = mod(r);\n const r0 = smod(rPlus, 2 * GAMMA2) | 0;\n if (rPlus - r0 === Q - 1)\n return { r1: 0 | 0, r0: (r0 - 1) | 0 };\n const r1 = Math.floor((rPlus - r0) / (2 * GAMMA2)) | 0;\n return { r1, r0 }; // r1 = HighBits, r0 = LowBits\n };\n const HighBits = (r) => decompose(r).r1;\n const LowBits = (r) => decompose(r).r0;\n const MakeHint = (z, r) => {\n // Compute hint bit indicating whether adding z to r alters the high bits of r.\n // From dilithium code\n const res0 = z <= GAMMA2 || z > Q - GAMMA2 || (z === Q - GAMMA2 && r === 0) ? 0 : 1;\n // from FIPS204:\n // // const r1 = HighBits(r);\n // // const v1 = HighBits(r + z);\n // // const res1 = +(r1 !== v1);\n // But they return different results! However, decompose is same.\n // So, either there is a bug in Dilithium ref implementation or in FIPS204.\n // For now, lets use dilithium one, so test vectors can be passed.\n // See\n // https://github.com/GiacomoPope/dilithium-py?tab=readme-ov-file#optimising-decomposition-and-making-hints\n return res0;\n };\n const UseHint = (h, r) => {\n // Returns the high bits of r adjusted according to hint h\n const m = Math.floor((Q - 1) / (2 * GAMMA2));\n const { r1, r0 } = decompose(r);\n // 3: if h = 1 and r0 > 0 return (r1 + 1) mod m\n // 4: if h = 1 and r0 ≤ 0 return (r1 − 1) mod m\n if (h === 1)\n return r0 > 0 ? mod(r1 + 1, m) | 0 : mod(r1 - 1, m) | 0;\n return r1 | 0;\n };\n const Power2Round = (r) => {\n // Decomposes r into (r1, r0) such that r ≡ r1*(2**d) + r0 mod q.\n const rPlus = mod(r);\n const r0 = smod(rPlus, 2 ** D) | 0;\n return { r1: Math.floor((rPlus - r0) / 2 ** D) | 0, r0 };\n };\n const hintCoder = {\n bytesLen: OMEGA + K,\n encode: (h) => {\n if (h === false)\n throw new Error('hint.encode: hint is false'); // should never happen\n const res = new Uint8Array(OMEGA + K);\n for (let i = 0, k = 0; i < K; i++) {\n for (let j = 0; j < N; j++)\n if (h[i][j] !== 0)\n res[k++] = j;\n res[OMEGA + i] = k;\n }\n return res;\n },\n decode: (buf) => {\n const h = [];\n let k = 0;\n for (let i = 0; i < K; i++) {\n const hi = newPoly(N);\n if (buf[OMEGA + i] < k || buf[OMEGA + i] > OMEGA)\n return false;\n for (let j = k; j < buf[OMEGA + i]; j++) {\n if (j > k && buf[j] <= buf[j - 1])\n return false;\n hi[buf[j]] = 1;\n }\n k = buf[OMEGA + i];\n h.push(hi);\n }\n for (let j = k; j < OMEGA; j++)\n if (buf[j] !== 0)\n return false;\n return h;\n },\n };\n const ETACoder = polyCoder(ETA === 2 ? 3 : 4, (i) => ETA - i, (i) => {\n if (!(-ETA <= i && i <= ETA))\n throw new Error(`malformed key s1/s3 ${i} outside of ETA range [${-ETA}, ${ETA}]`);\n return i;\n });\n const T0Coder = polyCoder(13, (i) => (1 << (D - 1)) - i);\n const T1Coder = polyCoder(10);\n // Requires smod. Need to fix!\n const ZCoder = polyCoder(GAMMA1 === 1 << 17 ? 18 : 20, (i) => smod(GAMMA1 - i));\n const W1Coder = polyCoder(GAMMA2 === GAMMA2_1 ? 6 : 4);\n const W1Vec = vecCoder(W1Coder, K);\n // Main structures\n const publicCoder = splitCoder(32, vecCoder(T1Coder, K));\n const secretCoder = splitCoder(32, 32, TR_BYTES, vecCoder(ETACoder, L), vecCoder(ETACoder, K), vecCoder(T0Coder, K));\n const sigCoder = splitCoder(C_TILDE_BYTES, vecCoder(ZCoder, L), hintCoder);\n const CoefFromHalfByte = ETA === 2\n ? (n) => (n < 15 ? 2 - (n % 5) : false)\n : (n) => (n < 9 ? 4 - n : false);\n // Return poly in NTT representation\n function RejBoundedPoly(xof) {\n // Samples an element a ∈ Rq with coeffcients in [−η, η] computed via rejection sampling from ρ.\n const r = newPoly(N);\n for (let j = 0; j < N;) {\n const b = xof();\n for (let i = 0; j < N && i < b.length; i += 1) {\n // half byte. Should be superfast with vector instructions. But very slow with js :(\n const d1 = CoefFromHalfByte(b[i] & 0x0f);\n const d2 = CoefFromHalfByte((b[i] >> 4) & 0x0f);\n if (d1 !== false)\n r[j++] = d1;\n if (j < N && d2 !== false)\n r[j++] = d2;\n }\n }\n return r;\n }\n const SampleInBall = (seed) => {\n // Samples a polynomial c ∈ Rq with coeffcients from {−1, 0, 1} and Hamming weight τ\n const pre = newPoly(N);\n const s = shake256.create({}).update(seed);\n const buf = new Uint8Array(shake256.blockLen);\n s.xofInto(buf);\n const masks = buf.slice(0, 8);\n for (let i = N - TAU, pos = 8, maskPos = 0, maskBit = 0; i < N; i++) {\n let b = i + 1;\n for (; b > i;) {\n b = buf[pos++];\n if (pos < shake256.blockLen)\n continue;\n s.xofInto(buf);\n pos = 0;\n }\n pre[i] = pre[b];\n pre[b] = 1 - (((masks[maskPos] >> maskBit++) & 1) << 1);\n if (maskBit >= 8) {\n maskPos++;\n maskBit = 0;\n }\n }\n return pre;\n };\n const polyPowerRound = (p) => {\n const res0 = newPoly(N);\n const res1 = newPoly(N);\n for (let i = 0; i < p.length; i++) {\n const { r0, r1 } = Power2Round(p[i]);\n res0[i] = r0;\n res1[i] = r1;\n }\n return { r0: res0, r1: res1 };\n };\n const polyUseHint = (u, h) => {\n for (let i = 0; i < N; i++)\n u[i] = UseHint(h[i], u[i]);\n return u;\n };\n const polyMakeHint = (a, b) => {\n const v = newPoly(N);\n let cnt = 0;\n for (let i = 0; i < N; i++) {\n const h = MakeHint(a[i], b[i]);\n v[i] = h;\n cnt += h;\n }\n return { v, cnt };\n };\n const signRandBytes = 32;\n const seedCoder = splitCoder(32, 64, 32);\n // API & argument positions are exactly as in FIPS204.\n const internal = {\n signRandBytes,\n keygen: (seed = randomBytes(32)) => {\n // H(𝜉||IntegerToBytes(𝑘, 1)||IntegerToBytes(ℓ, 1), 128) 2: ▷ expand seed\n const seedDst = new Uint8Array(32 + 2);\n seedDst.set(seed);\n seedDst[32] = K;\n seedDst[33] = L;\n const [rho, rhoPrime, K_] = seedCoder.decode(shake256(seedDst, { dkLen: seedCoder.bytesLen }));\n const xofPrime = XOF256(rhoPrime);\n const s1 = [];\n for (let i = 0; i < L; i++)\n s1.push(RejBoundedPoly(xofPrime.get(i & 0xff, (i >> 8) & 0xff)));\n const s2 = [];\n for (let i = L; i < L + K; i++)\n s2.push(RejBoundedPoly(xofPrime.get(i & 0xff, (i >> 8) & 0xff)));\n const s1Hat = s1.map((i) => NTT.encode(i.slice()));\n const t0 = [];\n const t1 = [];\n const xof = XOF128(rho);\n const t = newPoly(N);\n for (let i = 0; i < K; i++) {\n // t ← NTT−1(A*NTT(s1)) + s2\n t.fill(0); // don't-reallocate\n for (let j = 0; j < L; j++) {\n const aij = RejNTTPoly(xof.get(j, i)); // super slow!\n polyAdd(t, MultiplyNTTs(aij, s1Hat[j]));\n }\n NTT.decode(t);\n const { r0, r1 } = polyPowerRound(polyAdd(t, s2[i])); // (t1, t0) ← Power2Round(t, d)\n t0.push(r0);\n t1.push(r1);\n }\n const publicKey = publicCoder.encode([rho, t1]); // pk ← pkEncode(ρ, t1)\n const tr = shake256(publicKey, { dkLen: TR_BYTES }); // tr ← H(BytesToBits(pk), 512)\n const secretKey = secretCoder.encode([rho, K_, tr, s1, s2, t0]); // sk ← skEncode(ρ, K,tr, s1, s2, t0)\n xof.clean();\n xofPrime.clean();\n // STATS\n // Kyber512: { calls: 4, xofs: 12 }, Kyber768: { calls: 9, xofs: 27 }, Kyber1024: { calls: 16, xofs: 48 }\n // DSA44: { calls: 24, xofs: 24 }, DSA65: { calls: 41, xofs: 41 }, DSA87: { calls: 71, xofs: 71 }\n cleanBytes(rho, rhoPrime, K_, s1, s2, s1Hat, t, t0, t1, tr, seedDst);\n return { publicKey, secretKey };\n },\n // NOTE: random is optional.\n sign: (secretKey, msg, random) => {\n // This part can be pre-cached per secretKey, but there is only minor performance improvement,\n // since we re-use a lot of variables to computation.\n const [rho, _K, tr, s1, s2, t0] = secretCoder.decode(secretKey); // (ρ, K,tr, s1, s2, t0) ← skDecode(sk)\n // Cache matrix to avoid re-compute later\n const A = []; // A ← ExpandA(ρ)\n const xof = XOF128(rho);\n for (let i = 0; i < K; i++) {\n const pv = [];\n for (let j = 0; j < L; j++)\n pv.push(RejNTTPoly(xof.get(j, i)));\n A.push(pv);\n }\n xof.clean();\n for (let i = 0; i < L; i++)\n NTT.encode(s1[i]); // sˆ1 ← NTT(s1)\n for (let i = 0; i < K; i++) {\n NTT.encode(s2[i]); // sˆ2 ← NTT(s2)\n NTT.encode(t0[i]); // tˆ0 ← NTT(t0)\n }\n // This part is per msg\n const mu = shake256.create({ dkLen: CRH_BYTES }).update(tr).update(msg).digest(); // 6: µ ← H(tr||M, 512) ▷ Compute message representative µ\n // Compute private random seed\n const rnd = random ? random : new Uint8Array(32);\n ensureBytes(rnd);\n const rhoprime = shake256\n .create({ dkLen: CRH_BYTES })\n .update(_K)\n .update(rnd)\n .update(mu)\n .digest(); // ρ′← H(K||rnd||µ, 512)\n ensureBytes(rhoprime, CRH_BYTES);\n const x256 = XOF256(rhoprime, ZCoder.bytesLen);\n // Rejection sampling loop\n main_loop: for (let kappa = 0;;) {\n const y = [];\n // y ← ExpandMask(ρ , κ)\n for (let i = 0; i < L; i++, kappa++)\n y.push(ZCoder.decode(x256.get(kappa & 0xff, kappa >> 8)()));\n const z = y.map((i) => NTT.encode(i.slice()));\n const w = [];\n for (let i = 0; i < K; i++) {\n // w ← NTT−1(A ◦ NTT(y))\n const wi = newPoly(N);\n for (let j = 0; j < L; j++)\n polyAdd(wi, MultiplyNTTs(A[i][j], z[j]));\n NTT.decode(wi);\n w.push(wi);\n }\n const w1 = w.map((j) => j.map(HighBits)); // w1 ← HighBits(w)\n // Commitment hash: c˜ ∈{0, 1 2λ } ← H(µ||w1Encode(w1), 2λ)\n const cTilde = shake256\n .create({ dkLen: C_TILDE_BYTES })\n .update(mu)\n .update(W1Vec.encode(w1))\n .digest();\n // Verifer’s challenge\n const cHat = NTT.encode(SampleInBall(cTilde)); // c ← SampleInBall(c˜1); cˆ ← NTT(c)\n // ⟨⟨cs1⟩⟩ ← NTT−1(cˆ◦ sˆ1)\n const cs1 = s1.map((i) => MultiplyNTTs(i, cHat));\n for (let i = 0; i < L; i++) {\n polyAdd(NTT.decode(cs1[i]), y[i]); // z ← y + ⟨⟨cs1⟩⟩\n if (polyChknorm(cs1[i], GAMMA1 - BETA))\n continue main_loop; // ||z||∞ ≥ γ1 − β\n }\n // cs1 is now z (▷ Signer’s response)\n let cnt = 0;\n const h = [];\n for (let i = 0; i < K; i++) {\n const cs2 = NTT.decode(MultiplyNTTs(s2[i], cHat)); // ⟨⟨cs2⟩⟩ ← NTT−1(cˆ◦ sˆ2)\n const r0 = polySub(w[i], cs2).map(LowBits); // r0 ← LowBits(w − ⟨⟨cs2⟩⟩)\n if (polyChknorm(r0, GAMMA2 - BETA))\n continue main_loop; // ||r0||∞ ≥ γ2 − β\n const ct0 = NTT.decode(MultiplyNTTs(t0[i], cHat)); // ⟨⟨ct0⟩⟩ ← NTT−1(cˆ◦ tˆ0)\n if (polyChknorm(ct0, GAMMA2))\n continue main_loop;\n polyAdd(r0, ct0);\n // ▷ Signer’s hint\n const hint = polyMakeHint(r0, w1[i]); // h ← MakeHint(−⟨⟨ct0⟩⟩, w− ⟨⟨cs2⟩⟩ + ⟨⟨ct0⟩⟩)\n h.push(hint.v);\n cnt += hint.cnt;\n }\n if (cnt > OMEGA)\n continue; // the number of 1’s in h is greater than ω\n x256.clean();\n const res = sigCoder.encode([cTilde, cs1, h]); // σ ← sigEncode(c˜, z mod±q, h)\n // rho, _K, tr is subarray of secretKey, cannot clean.\n cleanBytes(cTilde, cs1, h, cHat, w1, w, z, y, rhoprime, mu, s1, s2, t0, ...A);\n return res;\n }\n // @ts-ignore\n throw new Error('Unreachable code path reached, report this error');\n },\n verify: (publicKey, msg, sig) => {\n // ML-DSA.Verify(pk, M, σ): Verifes a signature σ for a message M.\n const [rho, t1] = publicCoder.decode(publicKey); // (ρ, t1) ← pkDecode(pk)\n const tr = shake256(publicKey, { dkLen: TR_BYTES }); // 6: tr ← H(BytesToBits(pk), 512)\n if (sig.length !== sigCoder.bytesLen)\n return false; // return false instead of exception\n const [cTilde, z, h] = sigCoder.decode(sig); // (c˜, z, h) ← sigDecode(σ), ▷ Signer’s commitment hash c ˜, response z and hint\n if (h === false)\n return false; // if h = ⊥ then return false\n for (let i = 0; i < L; i++)\n if (polyChknorm(z[i], GAMMA1 - BETA))\n return false;\n const mu = shake256.create({ dkLen: CRH_BYTES }).update(tr).update(msg).digest(); // 7: µ ← H(tr||M, 512)\n // Compute verifer’s challenge from c˜\n const c = NTT.encode(SampleInBall(cTilde)); // c ← SampleInBall(c˜1)\n const zNtt = z.map((i) => i.slice()); // zNtt = NTT(z)\n for (let i = 0; i < L; i++)\n NTT.encode(zNtt[i]);\n const wTick1 = [];\n const xof = XOF128(rho);\n for (let i = 0; i < K; i++) {\n const ct12d = MultiplyNTTs(NTT.encode(polyShiftl(t1[i])), c); //c * t1 * (2**d)\n const Az = newPoly(N); // // A * z\n for (let j = 0; j < L; j++) {\n const aij = RejNTTPoly(xof.get(j, i)); // A[i][j] inplace\n polyAdd(Az, MultiplyNTTs(aij, zNtt[j]));\n }\n // wApprox = A*z - c*t1 * (2**d)\n const wApprox = NTT.decode(polySub(Az, ct12d));\n // Reconstruction of signer’s commitment\n wTick1.push(polyUseHint(wApprox, h[i])); // w ′ ← UseHint(h, w'approx )\n }\n xof.clean();\n // c˜′← H (µ||w1Encode(w′1), 2λ), Hash it; this should match c˜\n const c2 = shake256\n .create({ dkLen: C_TILDE_BYTES })\n .update(mu)\n .update(W1Vec.encode(wTick1))\n .digest();\n // Additional checks in FIPS-204:\n // [[ ||z||∞ < γ1 − β ]] and [[c ˜ = c˜′]] and [[number of 1’s in h is ≤ ω]]\n for (const t of h) {\n const sum = t.reduce((acc, i) => acc + i, 0);\n if (!(sum <= OMEGA))\n return false;\n }\n for (const t of z)\n if (polyChknorm(t, GAMMA1 - BETA))\n return false;\n return equalBytes(cTilde, c2);\n },\n };\n const getMessage = (msg, ctx = EMPTY) => {\n ensureBytes(msg);\n ensureBytes(ctx);\n if (ctx.length > 255)\n throw new Error('context should be less than 255 bytes');\n return concatBytes(new Uint8Array([0, ctx.length]), ctx, msg);\n };\n // TODO: no hash-dsa vectors for now, so we don't implement it yet\n return {\n internal,\n keygen: internal.keygen,\n signRandBytes: internal.signRandBytes,\n sign: (secretKey, msg, ctx = EMPTY, random) => {\n const M = getMessage(msg, ctx);\n const res = internal.sign(secretKey, M, random);\n M.fill(0);\n return res;\n },\n verify: (publicKey, msg, sig, ctx = EMPTY) => {\n return internal.verify(publicKey, getMessage(msg, ctx), sig);\n },\n };\n}\n// ML-DSA\nexport const ml_dsa44 = /* @__PURE__ */ getDilithium({\n ...PARAMS[2],\n CRH_BYTES: 64,\n TR_BYTES: 64,\n C_TILDE_BYTES: 32,\n XOF128,\n XOF256,\n});\nexport const ml_dsa65 = /* @__PURE__ */ getDilithium({\n ...PARAMS[3],\n CRH_BYTES: 64,\n TR_BYTES: 64,\n C_TILDE_BYTES: 48,\n XOF128,\n XOF256,\n});\nexport const ml_dsa87 = /* @__PURE__ */ getDilithium({\n ...PARAMS[5],\n CRH_BYTES: 64,\n TR_BYTES: 64,\n C_TILDE_BYTES: 64,\n XOF128,\n XOF256,\n});\n//# sourceMappingURL=ml-dsa.js.map"],"names":["ensureBytes","abytes","randomBytes","randb","equalBytes","a","b","length","diff","i","splitCoder","lengths","getLength","c","bytesLen","reduce","sum","encode","bufs","res","Uint8Array","pos","l","set","fill","decode","buf","subarray","push","vecCoder","vecLen","u","Error","r","cleanBytes","list","t","Array","isArray","getMask","bits","bitReversal","n","revrsd","toString","padStart","slice","split","reverse","join","Number","parseInt","genCrystals","opts","newPoly","N","Q","F","ROOT_OF_UNITY","brvBits","isKyber","mod","modulo","result","nttZetas","out","p","BigInt","getZettas","LEN1","LEN2","NTT","k","len","start","zeta","j","smod","bitsCoder","d","mask","poly","bufLen","bytes","createXofShake","shake","seed","blockLen","_seed","seedLen","h","create","calls","xofs","stats","get","x","y","destroy","update","xofInto","clean","XOF128","shake128","XOF256","shake256","Uint16Array","polyCoder","compress","polyAdd","MultiplyNTTs","f","g","z","c0","c1","a0","a1","b0","b1","SampleNTT","xof","d1","d2","sampleCBD","PRF","nonce","eta","b32","u32","bb","t0","genKPKE","K","XOF","HASH512","ETA1","ETA2","du","dv","poly1","polyV","polyU","publicCoder","secretCoder","cipherCoder","seedCoder","secretKeyLen","publicKeyLen","cipherTextLen","keygen","seedDst","seedHash","rho","sigma","sHat","tHat","e","publicKey","secretKey","encrypt","msg","rHat","tmp2","e1","tmp","e2","v","decrypt","cipherText","privateKey","sk","polySub","createKyber","KPKE","HASH256","KDF","KPKESecretCoder","msgLen","publicKeyHash","encapsulate","eke","ek","kr","digest","sharedSecret","decapsulate","Khat","cipherText2","isValid","Kbar","dkLen","ml_kem768","sha3_256","sha3_512","key","RBGstrength","D","GAMMA2_1","Math","floor","GAMMA2_2","PARAMS","L","GAMMA1","GAMMA2","TAU","ETA","OMEGA","Int32Array","id","verify","polyShiftl","polyChknorm","B","abs","RejNTTPoly","EMPTY","getDilithium","CRH_BYTES","TR_BYTES","C_TILDE_BYTES","includes","BETA","decompose","rPlus","r0","r1","HighBits","LowBits","UseHint","m","Power2Round","hintCoder","hi","ETACoder","T0Coder","T1Coder","ZCoder","W1Vec","sigCoder","CoefFromHalfByte","RejBoundedPoly","SampleInBall","pre","s","masks","maskPos","maskBit","polyPowerRound","res0","res1","polyUseHint","polyMakeHint","cnt","internal","signRandBytes","rhoPrime","K_","xofPrime","s1","s2","s1Hat","map","t1","aij","tr","sign","random","_K","A","pv","mu","rnd","rhoprime","x256","main_loop","kappa","w","wi","w1","cTilde","cHat","cs1","cs2","ct0","hint","sig","zNtt","wTick1","ct12d","Az","wApprox","c2","acc","getMessage","ctx","concatBytes","M","ml_dsa65"],"mappings":";;4EAGO,MAAMA,EAAcC,EACdC,EAAcC,EAGpB,SAASC,EAAWC,EAAGC,GAC1B,GAAID,EAAEE,SAAWD,EAAEC,OACf,OAAO,EACX,IAAIC,EAAO,EACX,IAAK,IAAIC,EAAI,EAAGA,EAAIJ,EAAEE,OAAQE,IAC1BD,GAAQH,EAAEI,GAAKH,EAAEG,GACrB,OAAgB,IAATD,CACX,CACO,SAASE,KAAcC,GAC1B,MAAMC,EAAaC,GAAoB,iBAANA,EAAiBA,EAAIA,EAAEC,SAClDA,EAAWH,EAAQI,QAAO,CAACC,EAAKX,IAAMW,EAAMJ,EAAUP,IAAI,GAChE,MAAO,CACHS,WACAG,OAASC,IACL,MAAMC,EAAM,IAAIC,WAAWN,GAC3B,IAAK,IAAIL,EAAI,EAAGY,EAAM,EAAGZ,EAAIE,EAAQJ,OAAQE,IAAK,CAC9C,MAAMI,EAAIF,EAAQF,GACZa,EAAIV,EAAUC,GACdP,EAAiB,iBAANO,EAAiBK,EAAKT,GAAKI,EAAEI,OAAOC,EAAKT,IAC1DT,EAAYM,EAAGgB,GACfH,EAAII,IAAIjB,EAAGe,GACM,iBAANR,GACPP,EAAEkB,KAAK,GACXH,GAAOC,CACvB,CACY,OAAOH,CAAG,EAEdM,OAASC,IACL1B,EAAY0B,EAAKZ,GACjB,MAAMK,EAAM,GACZ,IAAK,MAAMN,KAAKF,EAAS,CACrB,MAAMW,EAAIV,EAAUC,GACdP,EAAIoB,EAAIC,SAAS,EAAGL,GAC1BH,EAAIS,KAAkB,iBAANf,EAAiBP,EAAIO,EAAEY,OAAOnB,IAC9CoB,EAAMA,EAAIC,SAASL,EACnC,CACY,OAAOH,CAAG,EAGtB,CAEO,SAASU,EAAShB,EAAGiB,GACxB,MAAMhB,EAAWgB,EAASjB,EAAEC,SAC5B,MAAO,CACHA,WACAG,OAASc,IACL,GAAIA,EAAExB,SAAWuB,EACb,MAAUE,MAAM,iCAAiCD,EAAExB,qBAAqBuB,KAC5E,MAAMX,EAAM,IAAIC,WAAWN,GAC3B,IAAK,IAAIL,EAAI,EAAGY,EAAM,EAAGZ,EAAIsB,EAAExB,OAAQE,IAAK,CACxC,MAAMH,EAAIO,EAAEI,OAAOc,EAAEtB,IACrBU,EAAII,IAAIjB,EAAGe,GACXf,EAAEkB,KAAK,GACPH,GAAOf,EAAEC,MACzB,CACY,OAAOY,CAAG,EAEdM,OAASpB,IACLL,EAAYK,EAAGS,GACf,MAAMmB,EAAI,GACV,IAAK,IAAIxB,EAAI,EAAGA,EAAIJ,EAAEE,OAAQE,GAAKI,EAAEC,SACjCmB,EAAEL,KAAKf,EAAEY,OAAOpB,EAAEsB,SAASlB,EAAGA,EAAII,EAAEC,YACxC,OAAOmB,CAAC,EAGpB,CAEO,SAASC,KAAcC,GAC1B,IAAK,MAAMC,KAAKD,EACZ,GAAIE,MAAMC,QAAQF,GACd,IAAK,MAAM9B,KAAK8B,EACZ9B,EAAEkB,KAAK,QAEXY,EAAEZ,KAAK,EAEnB,CACO,SAASe,EAAQC,GACpB,OAAQ,GAAKA,GAAQ,CACzB;4ECjFA,SAASC,EAAYC,EAAGF,EAAO,GAC3B,MAEMG,EAFSD,EAAEE,SAAS,GAAGC,SAAS,EAAG,KACnBC,OAAON,GAAMK,SAAS,EAAG,KACzBE,MAAM,IAAIC,UAAUC,KAAK,IAC/C,OAAOC,OAAOC,SAASR,EAAQ,EACnC,CACO,MAAMS,EAAeC,IAExB,MAAMC,QAAEA,EAAOC,EAAEA,EAACC,EAAEA,EAACC,EAAEA,EAACC,cAAEA,EAAaC,QAAEA,EAAOC,QAAEA,GAAYP,EACxDQ,EAAM,CAACxD,EAAGyD,EAASN,KACrB,MAAMO,EAAS1D,EAAIyD,EAAS,EAC5B,OAA4D,GAApDC,GAAU,EAAIA,EAAcD,EAASC,EAAgB,EAiBjE,MAAMC,EATN,WACI,MAAMC,EAAMX,EAAQC,GACpB,IAAK,IAAI9C,EAAI,EAAGA,EAAI8C,EAAG9C,IAAK,CACxB,MAAMH,EAAImC,EAAYhC,EAAGkD,GACnBO,EAAIC,OAAOT,IAAkBS,OAAO7D,GAAK6D,OAAOX,GACtDS,EAAIxD,GAAiB,EAAZyC,OAAOgB,EAC5B,CACQ,OAAOD,CACf,CACqBG,GAMXC,EAAOT,EAAU,IAAML,EACvBe,EAAOV,EAAU,EAAI,EACrBW,EAAM,CACRtD,OAASgB,IACL,IAAK,IAAIuC,EAAI,EAAGC,EAAM,IAAKA,EAAMH,EAAMG,IAAQ,EAC3C,IAAK,IAAIC,EAAQ,EAAGA,EAAQnB,EAAGmB,GAAS,EAAID,EAAK,CAC7C,MAAME,EAAOX,EAASQ,KACtB,IAAK,IAAII,EAAIF,EAAOE,EAAIF,EAAQD,EAAKG,IAAK,CACtC,MAAMxC,EAAIyB,EAAIc,EAAO1C,EAAE2C,EAAIH,IAC3BxC,EAAE2C,EAAIH,GAAuB,EAAhBZ,EAAI5B,EAAE2C,GAAKxC,GACxBH,EAAE2C,GAAqB,EAAhBf,EAAI5B,EAAE2C,GAAKxC,EAC1C,CACA,CAEY,OAAOH,CAAC,EAEZR,OAASQ,IACL,IAAK,IAAIuC,EAAIH,EAAO,EAAGI,EAAM,EAAIH,EAAMG,EAAMJ,EAAOC,EAAMG,IAAQ,EAC9D,IAAK,IAAIC,EAAQ,EAAGA,EAAQnB,EAAGmB,GAAS,EAAID,EAAK,CAC7C,MAAME,EAAOX,EAASQ,KACtB,IAAK,IAAII,EAAIF,EAAOE,EAAIF,EAAQD,EAAKG,IAAK,CACtC,MAAMxC,EAAIH,EAAE2C,GACZ3C,EAAE2C,GAAKf,EAAIzB,EAAIH,EAAE2C,EAAIH,IACrBxC,EAAE2C,EAAIH,GAAOZ,EAAIc,GAAQ1C,EAAE2C,EAAIH,GAAOrC,GAC9D,CACA,CAEY,IAAK,IAAI3B,EAAI,EAAGA,EAAIwB,EAAE1B,OAAQE,IAC1BwB,EAAExB,GAAKoD,EAAIJ,EAAIxB,EAAExB,IACrB,OAAOwB,CAAC,GA+BhB,MAAO,CAAE4B,MAAKgB,KAhFD,CAACxE,EAAGyD,EAASN,KACtB,MAAMvB,EAAqB,EAAjB4B,EAAIxD,EAAGyD,GACjB,OAAkD,GAA1C7B,EAAI6B,GAAU,EAAK7B,EAAI6B,EAAc7B,EAAM,EA8EnC+B,WAAUO,MAAKO,UA3BjB,CAACC,EAAGlE,KAClB,MAAMmE,EAAOzC,EAAQwC,GACfjE,EAAWiE,GAAKxB,EAAI,GAC1B,MAAO,CACHzC,WACAG,OAASgE,IACL,MAAMhD,EAAI,IAAIb,WAAWN,GACzB,IAAK,IAAIL,EAAI,EAAGiB,EAAM,EAAGwD,EAAS,EAAG7D,EAAM,EAAGZ,EAAIwE,EAAK1E,OAAQE,IAG3D,IAFAiB,IAAQb,EAAEI,OAAOgE,EAAKxE,IAAMuE,IAASE,EACrCA,GAAUH,EACHG,GAAU,EAAGA,GAAU,EAAGxD,IAAQ,EACrCO,EAAEZ,KAASK,EAAMa,EAAQ2C,GAEjC,OAAOjD,CAAC,EAEZR,OAAS0D,IACL,MAAMlD,EAAIqB,EAAQC,GAClB,IAAK,IAAI9C,EAAI,EAAGiB,EAAM,EAAGwD,EAAS,EAAG7D,EAAM,EAAGZ,EAAI0E,EAAM5E,OAAQE,IAG5D,IAFAiB,GAAOyD,EAAM1E,IAAMyE,EACnBA,GAAU,EACHA,GAAUH,EAAGG,GAAUH,EAAGrD,IAAQqD,EACrC9C,EAAEZ,KAASR,EAAEY,OAAOC,EAAMsD,GAElC,OAAO/C,CAAC,EAEf,EAEyC,EAE5CmD,EAAkBC,GAAU,CAACC,EA