@unicitylabs/sphere-sdk 0.17.2 → 0.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/connect/index.cjs +1 -1
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +1 -1
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +32 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +25 -9
- package/dist/core/index.d.ts +25 -9
- package/dist/core/index.js +31 -1
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +1 -1
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +1 -1
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +32 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -9
- package/dist/index.d.ts +25 -9
- package/dist/index.js +31 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.d.cts +1 -1
- package/dist/token-engine/index.d.ts +1 -1
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../impl/wallet-api-v2/http.ts","../../../node_modules/@noble/hashes/src/utils.ts","../../../node_modules/@noble/hashes/src/_md.ts","../../../node_modules/@noble/hashes/src/sha2.ts","../../../impl/wallet-api-v2/client.ts","../../../core/logger.ts","../../../modules/payments-v2/stores.ts","../../../node_modules/@noble/curves/src/utils.ts","../../../node_modules/@noble/curves/src/abstract/modular.ts","../../../node_modules/@noble/curves/src/abstract/curve.ts","../../../node_modules/@noble/hashes/src/hmac.ts","../../../node_modules/@noble/curves/src/abstract/weierstrass.ts","../../../node_modules/@noble/curves/src/secp256k1.ts","../../../core/crypto.ts","../../../core/errors.ts","../../../core/wallet-api-protocol.ts","../../../impl/wallet-api-v2/session.ts","../../../impl/wallet-api-v2/storage.ts","../../../modules/payments-v2/async.ts","../../../node_modules/@noble/hashes/src/hkdf.ts","../../../node_modules/@noble/ciphers/src/utils.ts","../../../node_modules/@noble/ciphers/src/_arx.ts","../../../node_modules/@noble/ciphers/src/_poly1305.ts","../../../node_modules/@noble/ciphers/src/chacha.ts","../../../core/field-encryption.ts","../../../core/delivery-envelope.ts","../../../impl/wallet-api-v2/mailbox.ts","../../../token-engine/sdk.ts","../../../token-engine/identity.ts","../../../token-engine/errors.ts","../../../token-engine/nft-payload.ts","../../../token-engine/SphereTokenEngine.ts","../../../impl/wallet-api-v2/checkpoints.ts"],"sourcesContent":["// §5.1 http plumbing: fetch wrapper, https rule, typed error envelope.\n\nexport interface HttpResponseLike {\n readonly status: number;\n readonly ok: boolean;\n readonly headers?: { get(name: string): string | null };\n text(): Promise<string>;\n arrayBuffer(): Promise<ArrayBuffer>;\n}\n\nexport interface HttpRequestInit {\n method: string;\n headers?: Record<string, string>;\n body?: string | Uint8Array;\n}\n\nexport type FetchLike = (url: string, init?: HttpRequestInit) => Promise<HttpResponseLike>;\n\nexport class WalletApiHttpError extends Error {\n readonly status: number;\n readonly code: string;\n /** Milliseconds, parsed from a Retry-After header when present. */\n readonly retryAfter?: number;\n\n constructor(status: number, code: string, message: string, retryAfter?: number) {\n super(message);\n this.name = 'WalletApiHttpError';\n this.status = status;\n this.code = code;\n if (retryAfter !== undefined) this.retryAfter = retryAfter;\n }\n}\n\n/** Asking again may work; escalating will not. 0 is fetchRaw's NETWORK wrapper. */\nconst RETRYABLE_STATUSES = new Set([0, 408, 425, 429, 500, 502, 503, 504]);\n\nexport function isRetryableStatus(err: unknown): boolean {\n return err instanceof WalletApiHttpError && RETRYABLE_STATUSES.has(err.status);\n}\n\nexport function isWalletApiHttpError(err: unknown, status?: number): err is WalletApiHttpError {\n return err instanceof WalletApiHttpError && (status === undefined || err.status === status);\n}\n\nexport interface WalletApiHttpConfig {\n baseUrl: string;\n fetchFn: FetchLike;\n /** Bearer source; `null` sends the request unauthenticated. */\n getToken: () => string | null;\n}\n\nexport interface RequestOptions {\n /** Default true; auth endpoints opt out so a stale bearer is never attached. */\n auth?: boolean;\n}\n\nexport interface WalletApiHttp {\n readonly baseUrl: string;\n request(method: string, path: string, body?: unknown, opts?: RequestOptions): Promise<unknown>;\n /** Direct fetch for presigned S3 URLs — no base URL, no bearer. */\n fetchRaw(url: string, init: HttpRequestInit): Promise<HttpResponseLike>;\n}\n\nfunction isLoopbackHost(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname.endsWith('.localhost') ||\n /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname) ||\n hostname === '::1' ||\n hostname === '[::1]'\n );\n}\n\n/** ARCHITECTURE §4 transport rule: non-loopback MUST be https. Returns the URL without a trailing slash. */\nexport function assertSecureBaseUrl(baseUrl: string): string {\n let url: URL;\n try {\n url = new URL(baseUrl);\n } catch {\n throw new Error(`Invalid wallet-api base URL: ${baseUrl}`);\n }\n const httpLoopback = url.protocol === 'http:' && isLoopbackHost(url.hostname);\n if (url.protocol !== 'https:' && !httpLoopback) {\n throw new Error('wallet-api base URL must be https (plain http is allowed only on loopback)');\n }\n return url.toString().replace(/\\/$/, '');\n}\n\nfunction parseRetryAfter(res: HttpResponseLike): number | undefined {\n const raw = res.headers?.get('retry-after');\n if (!raw) return undefined;\n const seconds = Number(raw);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const when = Date.parse(raw);\n return Number.isNaN(when) ? undefined : Math.max(0, when - Date.now());\n}\n\nasync function readBodyText(res: HttpResponseLike): Promise<string> {\n try {\n return await res.text();\n } catch {\n return '';\n }\n}\n\n/** Parse the `{ error: { code, message } }` envelope into the typed error. */\nasync function toHttpError(res: HttpResponseLike, what: string): Promise<WalletApiHttpError> {\n let code = `HTTP_${res.status}`;\n let message = `${what} failed with status ${res.status}`;\n const text = await readBodyText(res);\n if (text !== '') {\n try {\n const parsed = JSON.parse(text) as { error?: { code?: string; message?: string } };\n if (parsed?.error?.code) code = parsed.error.code;\n if (parsed?.error?.message) message = `${what}: ${parsed.error.message}`;\n } catch {\n // non-JSON error body — keep the generic message\n }\n }\n return new WalletApiHttpError(res.status, code, message, parseRetryAfter(res));\n}\n\nfunction parseJsonBody(text: string, what: string, status: number): unknown {\n if (text === '') return null;\n try {\n return JSON.parse(text);\n } catch {\n throw new WalletApiHttpError(status, 'PROTOCOL', `${what}: response is not JSON`);\n }\n}\n\nexport function createWalletApiHttp(config: WalletApiHttpConfig): WalletApiHttp {\n const baseUrl = assertSecureBaseUrl(config.baseUrl);\n const { fetchFn, getToken } = config;\n\n const fetchRaw = async (url: string, init: HttpRequestInit): Promise<HttpResponseLike> => {\n try {\n return await fetchFn(url, init);\n } catch (err) {\n throw new WalletApiHttpError(\n 0,\n 'NETWORK',\n `wallet-api request failed: ${init.method} ${url}: ${String(err)}`\n );\n }\n };\n\n const request = async (\n method: string,\n path: string,\n body?: unknown,\n opts?: RequestOptions\n ): Promise<unknown> => {\n const headers: Record<string, string> = {};\n if (body !== undefined) headers['content-type'] = 'application/json';\n if (opts?.auth !== false) {\n const token = getToken();\n if (token !== null) headers['authorization'] = `Bearer ${token}`;\n }\n const res = await fetchRaw(`${baseUrl}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n const what = `${method} ${path}`;\n if (res.status === 204) return null;\n if (!res.ok) throw await toHttpError(res, what);\n return parseJsonBody(await readBodyText(res), what, res.status);\n };\n\n return { baseUrl, request, fetchRaw };\n}\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n/**\n * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.\n * @param a - value to test\n * @returns `true` when the value is a Uint8Array-compatible view.\n * @example\n * Check whether a value is a Uint8Array-compatible view.\n * ```ts\n * isBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.\n // The fallback still requires a real ArrayBuffer view, so plain\n // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and\n // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n\n/**\n * Asserts something is a non-negative integer.\n * @param n - number to validate\n * @param title - label included in thrown errors\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a non-negative integer option.\n * ```ts\n * anumber(32, 'length');\n * ```\n */\nexport function anumber(n: number, title: string = ''): void {\n if (typeof n !== 'number') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(`${prefix}expected number, got ${typeof n}`);\n }\n if (!Number.isSafeInteger(n) || n < 0) {\n const prefix = title && `\"${title}\" `;\n throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);\n }\n}\n\n/**\n * Asserts something is Uint8Array.\n * @param value - value to validate\n * @param length - optional exact length constraint\n * @param title - label included in thrown errors\n * @returns The validated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate that a value is a byte array.\n * ```ts\n * abytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function abytes(\n value: TArg<Uint8Array>,\n length?: number,\n title: string = ''\n): TRet<Uint8Array> {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n if (!bytes) throw new TypeError(message);\n throw new RangeError(message);\n }\n return value as TRet<Uint8Array>;\n}\n\n/**\n * Copies bytes into a fresh Uint8Array.\n * Buffer-style slices can alias the same backing store, so callers that need ownership should copy.\n * @param bytes - source bytes to clone\n * @returns Freshly allocated copy of `bytes`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Clone a byte array before mutating it.\n * ```ts\n * const copy = copyBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Asserts something is a wrapped hash constructor.\n * @param h - hash constructor to validate\n * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError}\n * @throws On invalid hash metadata ranges or values. {@link RangeError}\n * @throws If the hash metadata allows empty outputs or block sizes. {@link Error}\n * @example\n * Validate a callable hash wrapper.\n * ```ts\n * import { ahash } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * ahash(sha256);\n * ```\n */\nexport function ahash(h: TArg<CHash>): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new TypeError('Hash must wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass\n // validation and can produce empty outputs instead of failing fast.\n if (h.outputLen < 1) throw new Error('\"outputLen\" must be >= 1');\n if (h.blockLen < 1) throw new Error('\"blockLen\" must be >= 1');\n}\n\n/**\n * Asserts a hash instance has not been destroyed or finished.\n * @param instance - hash instance to validate\n * @param checkFinished - whether to reject finalized instances\n * @throws If the hash instance has already been destroyed or finalized. {@link Error}\n * @example\n * Validate that a hash instance is still usable.\n * ```ts\n * import { aexists } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aexists(hash);\n * ```\n */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/**\n * Asserts output is a sufficiently-sized byte array.\n * @param out - destination buffer\n * @param instance - hash instance providing output length\n * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a caller-provided digest buffer.\n * ```ts\n * import { aoutput } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aoutput(new Uint8Array(hash.outputLen), hash);\n * ```\n */\nexport function aoutput(out: any, instance: any): void {\n abytes(out, undefined, 'digestInto() output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new RangeError('\"digestInto() output\" expected to be of length >=' + min);\n }\n}\n\n/** Generic type encompassing 8/16/32-byte array views, but not 64-bit variants. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/**\n * Casts a typed array view to Uint8Array.\n * @param arr - source typed array\n * @returns Uint8Array view over the same buffer.\n * @example\n * Reinterpret a typed array as bytes.\n * ```ts\n * u8(new Uint32Array([1, 2]));\n * ```\n */\nexport function u8(arr: TArg<TypedArray>): TRet<Uint8Array> {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet<Uint8Array>;\n}\n\n/**\n * Casts a typed array view to Uint32Array.\n * `arr.byteOffset` must already be 4-byte aligned or the platform\n * Uint32Array constructor will throw.\n * @param arr - source typed array\n * @returns Uint32Array view over the same buffer.\n * @example\n * Reinterpret a byte array as 32-bit words.\n * ```ts\n * u32(new Uint8Array(8));\n * ```\n */\nexport function u32(arr: TArg<TypedArray>): TRet<Uint32Array> {\n return new Uint32Array(\n arr.buffer,\n arr.byteOffset,\n Math.floor(arr.byteLength / 4)\n ) as TRet<Uint32Array>;\n}\n\n/**\n * Zeroizes typed arrays in place. Warning: JS provides no guarantees.\n * @param arrays - arrays to overwrite with zeros\n * @example\n * Zeroize sensitive buffers in place.\n * ```ts\n * clean(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function clean(...arrays: TArg<TypedArray[]>): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/**\n * Creates a DataView for byte-level manipulation.\n * @param arr - source typed array\n * @returns DataView over the same buffer region.\n * @example\n * Create a DataView over an existing buffer.\n * ```ts\n * createView(new Uint8Array(4));\n * ```\n */\nexport function createView(arr: TArg<TypedArray>): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Rotate-right operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the right.\n * ```ts\n * rotr(0x12345678, 8);\n * ```\n */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n\n/**\n * Rotate-left operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the left.\n * ```ts\n * rotl(0x12345678, 8);\n * ```\n */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Whether the current platform is little-endian. */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/**\n * Byte-swap operation for uint32 values.\n * @param word - source word\n * @returns Word with reversed byte order.\n * @example\n * Reverse the byte order of a 32-bit word.\n * ```ts\n * byteSwap(0x11223344);\n * ```\n */\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/**\n * Conditionally byte-swaps one 32-bit word on big-endian platforms.\n * @param n - source word\n * @returns Original or byte-swapped word depending on platform endianness.\n * @example\n * Normalize a 32-bit word for host endianness.\n * ```ts\n * swap8IfBE(0x11223344);\n * ```\n */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n) >>> 0;\n\n/**\n * Byte-swaps every word of a Uint32Array in place.\n * @param arr - array to mutate\n * @returns The same array after mutation; callers pass live state arrays here.\n * @example\n * Reverse the byte order of every word in place.\n * ```ts\n * byteSwap32(new Uint32Array([0x11223344]));\n * ```\n */\nexport function byteSwap32(arr: TArg<Uint32Array>): TRet<Uint32Array> {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr as TRet<Uint32Array>;\n}\n\n/**\n * Conditionally byte-swaps a Uint32Array on big-endian platforms.\n * @param u - array to normalize for host endianness\n * @returns Original or byte-swapped array depending on platform endianness.\n * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`.\n * @example\n * Normalize a word array for host endianness.\n * ```ts\n * swap32IfBE(new Uint32Array([0x11223344]));\n * ```\n */\nexport const swap32IfBE: (u: TArg<Uint32Array>) => TRet<Uint32Array> = isLE\n ? (u: TArg<Uint32Array>) => u as TRet<Uint32Array>\n : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string.\n * Uses the built-in function when available and assumes it matches the tested\n * fallback semantics.\n * @param bytes - bytes to encode\n * @returns Lowercase hexadecimal string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Convert bytes to lowercase hexadecimal.\n * ```ts\n * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'\n * ```\n */\nexport function bytesToHex(bytes: TArg<Uint8Array>): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @param hex - hexadecimal string to decode\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Decode lowercase hexadecimal into bytes.\n * ```ts\n * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n * ```\n */\nexport function hexToBytes(hex: string): TRet<Uint8Array> {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n if (hasHexBuiltin) {\n try {\n return (Uint8Array as any).fromHex(hex);\n } catch (error) {\n if (error instanceof SyntaxError) throw new RangeError(error.message);\n throw error;\n }\n }\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new RangeError(\n 'hex string expected, got non-hex character \"' + char + '\" at index ' + hi\n );\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * This yields to the Promise/microtask scheduler queue, not to timers or the\n * full macrotask event loop.\n * @example\n * Yield to the next scheduler tick.\n * ```ts\n * await nextTick();\n * ```\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/**\n * Returns control to the Promise/microtask scheduler every `tick`\n * milliseconds to avoid blocking long loops.\n * @param iters - number of loop iterations to run\n * @param tick - maximum time slice in milliseconds\n * @param cb - callback executed on each iteration\n * @example\n * Run a loop that periodically yields back to the event loop.\n * ```ts\n * await asyncLoop(2, 0, () => {});\n * ```\n */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * Built-in doesn't validate input to be string: we do the check.\n * Non-ASCII details are delegated to the platform `TextEncoder`.\n * @param str - string to encode\n * @returns UTF-8 encoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encode a string as UTF-8 bytes.\n * ```ts\n * utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99])\n * ```\n */\nexport function utf8ToBytes(str: string): TRet<Uint8Array> {\n if (typeof str !== 'string') throw new TypeError('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n\n/**\n * Helper for KDFs: consumes Uint8Array or string.\n * String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer.\n * @param data - user-provided KDF input\n * @param errorTitle - label included in thrown errors\n * @returns Byte representation of the input.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Normalize KDF input to bytes.\n * ```ts\n * kdfInputToBytes('password');\n * ```\n */\nexport function kdfInputToBytes(data: TArg<KDFInput>, errorTitle = ''): TRet<Uint8Array> {\n if (typeof data === 'string') return utf8ToBytes(data);\n return abytes(data, undefined, errorTitle);\n}\n\n/**\n * Copies several Uint8Arrays into one.\n * @param arrays - arrays to concatenate\n * @returns Concatenated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Concatenate multiple byte arrays.\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nexport function concatBytes(...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\ntype EmptyObj = {};\n/**\n * Merges default options and passed options.\n * @param defaults - base option object\n * @param opts - user overrides\n * @returns Merged option object. The merge mutates `defaults` in place.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Merge user overrides onto default options.\n * ```ts\n * checkOpts({ dkLen: 32 }, { asyncTick: 10 });\n * ```\n */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new TypeError('options must be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Common interface for all hash instances. */\nexport interface Hash<T> {\n /** Bytes processed per compression block. */\n blockLen: number;\n /** Bytes produced by `digest()`. */\n outputLen: number;\n /** Whether the instance supports XOF-style variable-length output via `xof()` / `xofInto()`. */\n canXOF: boolean;\n /**\n * Absorbs more message bytes into the running hash state.\n * @param buf - message chunk to absorb\n * @returns The same hash instance for chaining.\n */\n update(buf: TArg<Uint8Array>): this;\n /**\n * Finalizes the hash into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Nothing. Implementations write into `buf` in place.\n */\n digestInto(buf: TArg<Uint8Array>): void;\n /**\n * Finalizes the hash and returns a freshly allocated digest.\n * @returns Digest bytes.\n */\n digest(): TRet<Uint8Array>;\n /** Wipes internal state and makes the instance unusable. */\n destroy(): void;\n /**\n * Copies the current hash state into an existing or new instance.\n * @param to - Optional destination instance to reuse.\n * @returns Cloned hash state.\n */\n _cloneInto(to?: T): T;\n /**\n * Creates an independent copy of the current hash state.\n * @returns Cloned hash instance.\n */\n clone(): T;\n}\n\n/** Pseudorandom generator interface. */\nexport interface PRG {\n /**\n * Mixes more entropy into the generator state.\n * @param seed - fresh entropy bytes\n * @returns Nothing. Implementations update internal state in place.\n */\n addEntropy(seed: TArg<Uint8Array>): void;\n /**\n * Generates pseudorandom output bytes.\n * @param length - number of bytes to generate\n * @returns Generated pseudorandom bytes.\n */\n randomBytes(length: number): TRet<Uint8Array>;\n /** Wipes generator state and makes the instance unusable. */\n clean(): void;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n /**\n * Reads more bytes from the XOF stream.\n * @param bytes - number of bytes to read\n * @returns Requested digest bytes.\n */\n xof(bytes: number): TRet<Uint8Array>;\n /**\n * Reads more bytes from the XOF stream into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Filled output buffer.\n */\n xofInto(buf: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/** Hash constructor or factory type. */\nexport type HasherCons<T, Opts = undefined> = Opts extends undefined ? () => T : (opts?: Opts) => T;\n/** Optional hash metadata. */\nexport type HashInfo = {\n /** DER-encoded object identifier bytes for the hash algorithm. */\n oid?: TRet<Uint8Array>;\n};\n/** Callable hash function type. */\nexport type CHash<T extends Hash<T> = Hash<any>, Opts = undefined> = {\n /** Digest size in bytes. */\n outputLen: number;\n /** Input block size in bytes. */\n blockLen: number;\n /** Whether `.create()` returns a hash instance that can be used as an XOF stream. */\n canXOF: boolean;\n} & HashInfo &\n (Opts extends undefined\n ? {\n (msg: TArg<Uint8Array>): TRet<Uint8Array>;\n create(): T;\n }\n : {\n (msg: TArg<Uint8Array>, opts?: TArg<Opts>): TRet<Uint8Array>;\n create(opts?: Opts): T;\n });\n/** Callable extendable-output hash function type. */\nexport type CHashXOF<T extends HashXOF<T> = HashXOF<any>, Opts = undefined> = CHash<T, Opts>;\n\n/**\n * Creates a callable hash function from a stateful class constructor.\n * @param hashCons - hash constructor or factory\n * @param info - optional metadata such as DER OID\n * @returns Frozen callable hash wrapper with `.create()`.\n * Wrapper construction eagerly calls `hashCons(undefined)` once to read\n * `outputLen` / `blockLen`, so constructor side effects happen at module\n * init time.\n * @example\n * Wrap a stateful hash constructor into a callable helper.\n * ```ts\n * import { createHasher } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const wrapped = createHasher(sha256.create, { oid: sha256.oid });\n * wrapped(new Uint8Array([1]));\n * ```\n */\nexport function createHasher<T extends Hash<T>, Opts = undefined>(\n hashCons: HasherCons<T, Opts>,\n info: TArg<HashInfo> = {}\n): TRet<CHash<T, Opts>> {\n const hashC: any = (msg: TArg<Uint8Array>, opts?: TArg<Opts>) =>\n hashCons(opts as Opts)\n .update(msg)\n .digest();\n const tmp = hashCons(undefined);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.canXOF = tmp.canXOF;\n hashC.create = (opts?: Opts) => hashCons(opts);\n Object.assign(hashC, info);\n return Object.freeze(hashC) as TRet<CHash<T, Opts>>;\n}\n\n/**\n * Cryptographically secure PRNG backed by `crypto.getRandomValues`.\n * @param bytesLength - number of random bytes to generate\n * @returns Random bytes.\n * The platform `getRandomValues()` implementation still defines any\n * single-call length cap, and this helper rejects oversize requests\n * with a stable library `RangeError` instead of host-specific errors.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error}\n * @example\n * Generate a fresh random key or nonce.\n * ```ts\n * const key = randomBytes(16);\n * ```\n */\nexport function randomBytes(bytesLength = 32): TRet<Uint8Array> {\n // Match the repo's other length-taking helpers instead of relying on Uint8Array coercion.\n anumber(bytesLength, 'bytesLength');\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n // Web Cryptography API Level 2 §10.1.1:\n // if `byteLength > 65536`, throw `QuotaExceededError`.\n // Keep the guard explicit so callers can see the quota in code\n // instead of discovering it by reading the spec or host errors.\n // This wrapper surfaces the same quota as a stable library RangeError.\n if (bytesLength > 65536)\n throw new RangeError(`\"bytesLength\" expected <= 65536, got ${bytesLength}`);\n return cr.getRandomValues(new Uint8Array(bytesLength));\n}\n\n/**\n * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.\n * @param suffix - final OID byte for the selected hash.\n * The helper accepts any byte even though only the documented NIST hash\n * suffixes are meaningful downstream.\n * @returns Object containing the DER-encoded OID.\n * @example\n * Build OID metadata for a NIST hash.\n * ```ts\n * oidNist(0x01);\n * ```\n */\nexport const oidNist = (suffix: number): TRet<Required<HashInfo>> => ({\n // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.\n // Larger suffix values would need base-128 OID encoding and a different length byte.\n oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),\n});\n","/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n createView,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`.\n * Returns bits from `b` when `a` is set, otherwise from `c`.\n * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never\n * set the same bit.\n * @param a - selector word\n * @param b - word chosen when selector bit is set\n * @param c - word chosen when selector bit is clear\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit choice primitive.\n * ```ts\n * Chi(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Chi(a: number, b: number, c: number): number {\n return (a & b) ^ (~a & c);\n}\n\n/**\n * Shared 32-bit majority primitive reused by SHA-256 and SHA-1.\n * Returns bits shared by at least two inputs.\n * @param a - first input word\n * @param b - second input word\n * @param c - third input word\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit majority primitive.\n * ```ts\n * Maj(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Maj(a: number, b: number, c: number): number {\n return (a & b) ^ (a & c) ^ (b & c);\n}\n\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit\n * strings with partial-byte tails.\n * @param blockLen - internal block size in bytes\n * @param outputLen - digest size in bytes\n * @param padOffset - trailing length field size in bytes\n * @param isLE - whether length and state words are encoded in little-endian\n * @example\n * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.\n * ```ts\n * import { _SHA1 } from '@noble/hashes/legacy.js';\n * const hash = new _SHA1();\n * hash.update(new Uint8Array([97, 98, 99]));\n * hash.digest();\n * ```\n */\nexport abstract class HashMD<T extends HashMD<T>> implements Hash<T> {\n // Subclasses must treat `buf` as read-only: `update()` may pass a direct view over caller input\n // when it can process whole blocks without buffering first.\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n\n readonly blockLen: number;\n readonly outputLen: number;\n readonly canXOF = false;\n readonly padOffset: number;\n readonly isLE: boolean;\n\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n const { view, buffer, blockLen } = this;\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path only when there is no buffered partial block: `take === blockLen` implies\n // `this.pos === 0`, so we can process full blocks directly from the input view.\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n clean(this.buffer.subarray(pos));\n // we have less than padOffset left in buffer, so we cannot put length in\n // current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from\n // the padding fill above, and JS will overflow before user input can make that half non-zero.\n // So we only need to write the low 64 bits here.\n view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen must be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return\n // fresh bytes to the caller.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.destroyed = destroyed;\n to.finished = finished;\n to.length = length;\n to.pos = pos;\n // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and\n // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.\n if (length % blockLen) to.buffer.set(buffer);\n return to as unknown as any;\n }\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n\n/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the\n * square roots of the first eight prime numbers. Exported as a shared table; callers must treat\n * it as read-only because constructors copy words from it by index. */\nexport const SHA256_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must\n * treat it as read-only because constructors copy words from it by index. */\nexport const SHA224_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n]);\n\n/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth\n * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only\n * because constructors copy halves from it by index. */\nexport const SHA384_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,\n]);\n\n/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first\n * eight prime numbers. Exported as a shared table; callers must treat it as read-only because\n * constructors copy halves from it by index. */\nexport const SHA512_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,\n]);\n","/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and\n * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.\n * @module\n */\nimport { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';\nimport * as u64 from './_u64.ts';\nimport { type CHash, clean, createHasher, oidNist, rotr, type TRet } from './utils.ts';\n\n/**\n * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits\n * of the cube roots of the first 64 primes (2..311).\n */\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\n\n/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */\nabstract class SHA2_32B<T extends SHA2_32B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected abstract A: number;\n protected abstract B: number;\n protected abstract C: number;\n protected abstract D: number;\n protected abstract E: number;\n protected abstract F: number;\n protected abstract G: number;\n protected abstract H: number;\n\n constructor(outputLen: number) {\n super(64, outputLen, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean(): void {\n clean(SHA256_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */\nexport class _SHA256 extends SHA2_32B<_SHA256> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected A: number = SHA256_IV[0] | 0;\n protected B: number = SHA256_IV[1] | 0;\n protected C: number = SHA256_IV[2] | 0;\n protected D: number = SHA256_IV[3] | 0;\n protected E: number = SHA256_IV[4] | 0;\n protected F: number = SHA256_IV[5] | 0;\n protected G: number = SHA256_IV[6] | 0;\n protected H: number = SHA256_IV[7] | 0;\n constructor() {\n super(32);\n }\n}\n\n/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */\nexport class _SHA224 extends SHA2_32B<_SHA224> {\n protected A: number = SHA224_IV[0] | 0;\n protected B: number = SHA224_IV[1] | 0;\n protected C: number = SHA224_IV[2] | 0;\n protected D: number = SHA224_IV[3] | 0;\n protected E: number = SHA224_IV[4] | 0;\n protected F: number = SHA224_IV[5] | 0;\n protected G: number = SHA224_IV[6] | 0;\n protected H: number = SHA224_IV[7] | 0;\n constructor() {\n super(28);\n }\n}\n\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n\n// SHA-384 / SHA-512 round constants from RFC 6234 §5.2:\n// 80 full 64-bit words split into high/low halves.\n// prettier-ignore\nconst K512 = /* @__PURE__ */ (() => u64.split([\n '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n\n// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\n// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n\n/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */\nabstract class SHA2_64B<T extends SHA2_64B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n // h -- high 32 bits, l -- low 32 bits\n protected abstract Ah: number;\n protected abstract Al: number;\n protected abstract Bh: number;\n protected abstract Bl: number;\n protected abstract Ch: number;\n protected abstract Cl: number;\n protected abstract Dh: number;\n protected abstract Dl: number;\n protected abstract Eh: number;\n protected abstract El: number;\n protected abstract Fh: number;\n protected abstract Fl: number;\n protected abstract Gh: number;\n protected abstract Gl: number;\n protected abstract Hh: number;\n protected abstract Hl: number;\n\n constructor(outputLen: number) {\n super(128, outputLen, 16, false);\n }\n // prettier-ignore\n protected get(): [\n number, number, number, number, number, number, number, number,\n number, number, number, number, number, number, number, number\n ] {\n const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n }\n // prettier-ignore\n protected set(\n Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number,\n Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number\n ): void {\n this.Ah = Ah | 0;\n this.Al = Al | 0;\n this.Bh = Bh | 0;\n this.Bl = Bl | 0;\n this.Ch = Ch | 0;\n this.Cl = Cl | 0;\n this.Dh = Dh | 0;\n this.Dl = Dl | 0;\n this.Eh = Eh | 0;\n this.El = El | 0;\n this.Fh = Fh | 0;\n this.Fl = Fl | 0;\n this.Gh = Gh | 0;\n this.Gl = Gl | 0;\n this.Hh = Hh | 0;\n this.Hl = Hl | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) {\n SHA512_W_H[i] = view.getUint32(offset);\n SHA512_W_L[i] = view.getUint32((offset += 4));\n }\n for (let i = 16; i < 80; i++) {\n // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n const W15h = SHA512_W_H[i - 15] | 0;\n const W15l = SHA512_W_L[i - 15] | 0;\n const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n const W2h = SHA512_W_H[i - 2] | 0;\n const W2l = SHA512_W_L[i - 2] | 0;\n const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16];\n const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n SHA512_W_H[i] = SUMh | 0;\n SHA512_W_L[i] = SUMl | 0;\n }\n let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n // Compression function main loop, 80 rounds\n for (let i = 0; i < 80; i++) {\n // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n const CHIl = (El & Fl) ^ (~El & Gl);\n // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n // prettier-ignore\n const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n const T1l = T1ll | 0;\n // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n Hh = Gh | 0;\n Hl = Gl | 0;\n Gh = Fh | 0;\n Gl = Fl | 0;\n Fh = Eh | 0;\n Fl = El | 0;\n ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n Dh = Ch | 0;\n Dl = Cl | 0;\n Ch = Bh | 0;\n Cl = Bl | 0;\n Bh = Ah | 0;\n Bl = Al | 0;\n const All = u64.add3L(T1l, sigma0l, MAJl);\n Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n Al = All | 0;\n }\n // Add the compressed chunk to the current hash value\n ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n }\n protected roundClean(): void {\n clean(SHA512_W_H, SHA512_W_L);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n}\n\n/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA512 extends SHA2_64B<_SHA512> {\n protected Ah: number = SHA512_IV[0] | 0;\n protected Al: number = SHA512_IV[1] | 0;\n protected Bh: number = SHA512_IV[2] | 0;\n protected Bl: number = SHA512_IV[3] | 0;\n protected Ch: number = SHA512_IV[4] | 0;\n protected Cl: number = SHA512_IV[5] | 0;\n protected Dh: number = SHA512_IV[6] | 0;\n protected Dl: number = SHA512_IV[7] | 0;\n protected Eh: number = SHA512_IV[8] | 0;\n protected El: number = SHA512_IV[9] | 0;\n protected Fh: number = SHA512_IV[10] | 0;\n protected Fl: number = SHA512_IV[11] | 0;\n protected Gh: number = SHA512_IV[12] | 0;\n protected Gl: number = SHA512_IV[13] | 0;\n protected Hh: number = SHA512_IV[14] | 0;\n protected Hl: number = SHA512_IV[15] | 0;\n\n constructor() {\n super(64);\n }\n}\n\n/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA384 extends SHA2_64B<_SHA384> {\n protected Ah: number = SHA384_IV[0] | 0;\n protected Al: number = SHA384_IV[1] | 0;\n protected Bh: number = SHA384_IV[2] | 0;\n protected Bl: number = SHA384_IV[3] | 0;\n protected Ch: number = SHA384_IV[4] | 0;\n protected Cl: number = SHA384_IV[5] | 0;\n protected Dh: number = SHA384_IV[6] | 0;\n protected Dl: number = SHA384_IV[7] | 0;\n protected Eh: number = SHA384_IV[8] | 0;\n protected El: number = SHA384_IV[9] | 0;\n protected Fh: number = SHA384_IV[10] | 0;\n protected Fl: number = SHA384_IV[11] | 0;\n protected Gh: number = SHA384_IV[12] | 0;\n protected Gl: number = SHA384_IV[13] | 0;\n protected Hh: number = SHA384_IV[14] | 0;\n protected Hl: number = SHA384_IV[15] | 0;\n\n constructor() {\n super(48);\n }\n}\n\n/**\n * Truncated SHA512/256 and SHA512/224.\n * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as \"intermediary\" IV of SHA512/t.\n * Then t hashes string to produce result IV.\n * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`.\n * These IV literals are checked against that script rather than a dedicated\n * local RFC section.\n */\n\n/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T224_IV = /* @__PURE__ */ Uint32Array.from([\n 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf,\n 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1,\n]);\n\n/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T256_IV = /* @__PURE__ */ Uint32Array.from([\n 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd,\n 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2,\n]);\n\n/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_224 extends SHA2_64B<_SHA512_224> {\n protected Ah: number = T224_IV[0] | 0;\n protected Al: number = T224_IV[1] | 0;\n protected Bh: number = T224_IV[2] | 0;\n protected Bl: number = T224_IV[3] | 0;\n protected Ch: number = T224_IV[4] | 0;\n protected Cl: number = T224_IV[5] | 0;\n protected Dh: number = T224_IV[6] | 0;\n protected Dl: number = T224_IV[7] | 0;\n protected Eh: number = T224_IV[8] | 0;\n protected El: number = T224_IV[9] | 0;\n protected Fh: number = T224_IV[10] | 0;\n protected Fl: number = T224_IV[11] | 0;\n protected Gh: number = T224_IV[12] | 0;\n protected Gl: number = T224_IV[13] | 0;\n protected Hh: number = T224_IV[14] | 0;\n protected Hl: number = T224_IV[15] | 0;\n\n constructor() {\n super(28);\n }\n}\n\n/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_256 extends SHA2_64B<_SHA512_256> {\n protected Ah: number = T256_IV[0] | 0;\n protected Al: number = T256_IV[1] | 0;\n protected Bh: number = T256_IV[2] | 0;\n protected Bl: number = T256_IV[3] | 0;\n protected Ch: number = T256_IV[4] | 0;\n protected Cl: number = T256_IV[5] | 0;\n protected Dh: number = T256_IV[6] | 0;\n protected Dl: number = T256_IV[7] | 0;\n protected Eh: number = T256_IV[8] | 0;\n protected El: number = T256_IV[9] | 0;\n protected Fh: number = T256_IV[10] | 0;\n protected Fl: number = T256_IV[11] | 0;\n protected Gh: number = T256_IV[12] | 0;\n protected Gl: number = T256_IV[13] | 0;\n protected Hh: number = T256_IV[14] | 0;\n protected Hl: number = T256_IV[15] | 0;\n\n constructor() {\n super(32);\n }\n}\n\n/**\n * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:\n *\n * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.\n * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n * - Each sha256 hash is executing 2^18 bit operations.\n * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-256.\n * ```ts\n * sha256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha256: TRet<CHash<_SHA256>> = /* @__PURE__ */ createHasher(\n () => new _SHA256(),\n /* @__PURE__ */ oidNist(0x01)\n);\n/**\n * SHA2-224 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-224.\n * ```ts\n * sha224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha224: TRet<CHash<_SHA224>> = /* @__PURE__ */ createHasher(\n () => new _SHA224(),\n /* @__PURE__ */ oidNist(0x04)\n);\n\n/**\n * SHA2-512 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512.\n * ```ts\n * sha512(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512: TRet<CHash<_SHA512>> = /* @__PURE__ */ createHasher(\n () => new _SHA512(),\n /* @__PURE__ */ oidNist(0x03)\n);\n/**\n * SHA2-384 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-384.\n * ```ts\n * sha384(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha384: TRet<CHash<_SHA384>> = /* @__PURE__ */ createHasher(\n () => new _SHA384(),\n /* @__PURE__ */ oidNist(0x02)\n);\n\n/**\n * SHA2-512/256 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/256.\n * ```ts\n * sha512_256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_256: TRet<CHash<_SHA512_256>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_256(),\n /* @__PURE__ */ oidNist(0x06)\n);\n/**\n * SHA2-512/224 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/224.\n * ```ts\n * sha512_224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_224: TRet<CHash<_SHA512_224>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_224(),\n /* @__PURE__ */ oidNist(0x05)\n);\n","// §16 typed endpoints over http.ts. Amounts are decimal STRINGS end-to-end.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { WalletApiHttpError, type WalletApiHttp } from './http';\n\nexport interface AuthChallengeWire {\n nonce: string;\n challenge: string;\n expiresAt: string;\n}\n\nexport interface AuthTokensWire {\n jwt: string;\n refreshToken: string;\n}\n\nexport interface AssetWire {\n coinId: string;\n amount: string;\n}\n\nexport interface InventoryItemWire {\n tokenId: string;\n status: 'active' | 'removed';\n seq: number;\n stateHash: string;\n /**\n * Omitted for a tombstone AND for an ACTIVE COINLESS token (wallet-api#140),\n * so absence is never \"removed\" or \"not loaded\" — discriminate on `status`.\n */\n assets?: AssetWire[];\n /**\n * Genesis `TokenType`, lowercase hex (1-64 bytes ⇒ 2-128 chars). Names the\n * token's CLASS, not the instance (wallet-api#147). Absent on rows written\n * before wallet-api migration 0015. An unrecognised type is legitimate: never\n * reject or hide a token for it.\n */\n tokenType?: string;\n}\n\nexport interface InventoryPageWire {\n cursor: number;\n syncEpoch: number;\n more: boolean;\n items: InventoryItemWire[];\n}\n\nexport interface BalanceWire {\n coinId: string;\n total: string;\n tokenCount: number;\n}\n\nexport interface BlobUrlWire {\n tokenId: string;\n getUrl: string;\n}\n\nexport interface UploadUrlWire {\n sha256: string;\n key: string;\n putUrl: string;\n}\n\nexport interface ApplyDeltaWire {\n cursor: number;\n syncEpoch: number;\n}\n\nexport interface IntentWire {\n transferId: string;\n payload: string;\n status: 'open' | 'aborted';\n createdAt: string;\n}\n\nexport interface ProgressRecordWire {\n opIndex: number;\n payload: string;\n createdAt: string;\n}\n\nexport interface MailboxDepositEntry {\n recipientPubkey: string;\n key: string;\n transferId: string;\n tokenId: string;\n stateHash: string;\n memo?: string;\n}\n\nexport interface MailboxEntryWire {\n entryId: string;\n seq: number;\n status: string;\n transferId: string;\n tokenId: string;\n assets: AssetWire[];\n senderPubkey: string;\n memo?: string;\n createdAt: string;\n getUrl?: string;\n blobCollected?: boolean;\n}\n\nexport interface MailboxPageWire {\n readPointer: number;\n cursor: number;\n syncEpoch: number;\n more: boolean;\n entries: MailboxEntryWire[];\n}\n\nexport interface ClaimResultWire {\n claimed: string[];\n alreadyClaimed: { entryId: string; intoInventory: boolean }[];\n failed: { entryId: string; code: string }[];\n}\n\nexport type MailboxRejectReason = 'invalid' | 'not-owned' | 'storage-rejected' | 'other';\n\nexport interface HistoryRecordWire {\n dedupKey: string;\n id: string;\n type: 'SENT' | 'RECEIVED' | 'MINT';\n assets: AssetWire[];\n ts: string;\n transferId?: string;\n tokenId?: string;\n counterpartyPubkey?: string;\n counterpartyNametag?: string;\n memo?: string;\n}\n\nexport interface HistoryPageWire {\n records: HistoryRecordWire[];\n more: boolean;\n cursor: string | null;\n syncEpoch: number;\n}\n\nexport type PaymentRequestWireStatus = 'open' | 'paid' | 'declined' | 'expired';\n\nexport interface PaymentRequestWire {\n id: string;\n seq: number;\n fromPubkey: string;\n toPubkey: string;\n assets: AssetWire[];\n memo?: string;\n status: PaymentRequestWireStatus;\n transferId: string | null;\n createdAt: string;\n expiresAt?: string;\n}\n\nexport interface PaymentRequestsPageWire {\n requests: PaymentRequestWire[];\n more: boolean;\n cursor: number | string | null;\n syncEpoch: number;\n}\n\nexport type ListPaymentRequestsParams =\n | { role: 'incoming'; status?: PaymentRequestWireStatus; since?: number }\n | { role: 'outgoing'; status?: PaymentRequestWireStatus; before?: string };\n\nexport type RespondPaymentRequestInput =\n | { action: 'paid'; transferId: string }\n | { action: 'declined' };\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let bin = '';\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin);\n}\n\nexport class WalletApiV2Client {\n constructor(private readonly http: WalletApiHttp) {}\n\n get baseUrl(): string {\n return this.http.baseUrl;\n }\n\n // ── auth ─────────────────────────────────────────────────────────────────\n\n authChallenge(pubkey: string): Promise<AuthChallengeWire> {\n return this.http.request('POST', '/v1/auth/challenge', { pubkey }, { auth: false }) as Promise<AuthChallengeWire>;\n }\n\n authVerify(input: { nonce: string; signature: string; deviceId: string }): Promise<AuthTokensWire> {\n return this.http.request('POST', '/v1/auth/verify', input, { auth: false }) as Promise<AuthTokensWire>;\n }\n\n authRefresh(refreshToken: string): Promise<AuthTokensWire> {\n return this.http.request('POST', '/v1/auth/refresh', { refreshToken }, { auth: false }) as Promise<AuthTokensWire>;\n }\n\n async authLogout(): Promise<void> {\n await this.http.request('POST', '/v1/auth/logout', {});\n }\n\n // ── inventory / blobs ────────────────────────────────────────────────────\n\n listInventory(since?: number): Promise<InventoryPageWire> {\n const query = since !== undefined ? `?since=${since}` : '';\n return this.http.request('GET', `/v1/inventory${query}`) as Promise<InventoryPageWire>;\n }\n\n async balances(): Promise<BalanceWire[]> {\n const body = (await this.http.request('GET', '/v1/balances')) as { balances: BalanceWire[] };\n return body.balances;\n }\n\n async blobUrls(tokenIds: string[]): Promise<BlobUrlWire[]> {\n const body = (await this.http.request('POST', '/v1/tokens/blob-urls', { tokenIds })) as {\n urls: BlobUrlWire[];\n };\n return body.urls;\n }\n\n async uploadUrls(blobs: { sha256: string; size: number }[]): Promise<UploadUrlWire[]> {\n const body = (await this.http.request('POST', '/v1/tokens/upload-urls', { blobs })) as {\n urls: UploadUrlWire[];\n };\n return body.urls;\n }\n\n apply(delta: {\n transferId: string;\n spent: string[];\n added: { tokenId: string; key: string }[];\n }): Promise<ApplyDeltaWire> {\n return this.http.request('POST', '/v1/inventory/apply', delta) as Promise<ApplyDeltaWire>;\n }\n\n async fetchBlob(getUrl: string): Promise<Uint8Array> {\n const res = await this.http.fetchRaw(getUrl, { method: 'GET' });\n if (!res.ok) {\n throw new WalletApiHttpError(res.status, 'BLOB_DOWNLOAD', `blob download failed with status ${res.status}`);\n }\n return new Uint8Array(await res.arrayBuffer());\n }\n\n /**\n * PUT to a presigned S3 URL. `x-amz-checksum-sha256` (base64) and\n * `If-None-Match: *` are SIGNED headers — sent verbatim. S3 412 = the\n * identical blob already exists = success.\n */\n async uploadBlob(putUrl: string, bytes: Uint8Array): Promise<void> {\n const res = await this.http.fetchRaw(putUrl, {\n method: 'PUT',\n headers: {\n 'content-type': 'application/octet-stream',\n 'x-amz-checksum-sha256': bytesToBase64(sha256(bytes)),\n 'if-none-match': '*',\n },\n body: bytes,\n });\n if (res.ok || res.status === 412) return;\n throw new WalletApiHttpError(res.status, 'BLOB_UPLOAD', `blob upload failed with status ${res.status}`);\n }\n\n // ── intents ──────────────────────────────────────────────────────────────\n\n async putIntent(transferId: string, payloadEnvelope: string, requiresSeedClose = false): Promise<void> {\n const body = requiresSeedClose\n ? { payload: payloadEnvelope, requiresSeedClose: true }\n : { payload: payloadEnvelope };\n await this.http.request('PUT', `/v1/intents/${transferId}`, body);\n }\n\n async listIntents(status: 'open' | 'aborted' = 'open'): Promise<IntentWire[]> {\n const body = (await this.http.request('GET', `/v1/intents?status=${status}`)) as {\n intents: IntentWire[];\n };\n return body.intents;\n }\n\n async abortIntent(transferId: string): Promise<void> {\n await this.http.request('POST', `/v1/intents/${transferId}/abort`);\n }\n\n async completeIntent(transferId: string, signature?: string): Promise<void> {\n await this.http.request(\n 'POST',\n `/v1/intents/${transferId}/complete`,\n signature !== undefined ? { signature } : undefined\n );\n }\n\n async postProgress(\n transferId: string,\n opIndex: number,\n payloadEnvelope: string,\n signature: string\n ): Promise<ProgressRecordWire> {\n const body = (await this.http.request('POST', `/v1/intents/${transferId}/progress`, {\n opIndex,\n payload: payloadEnvelope,\n signature,\n })) as { record: ProgressRecordWire };\n return body.record;\n }\n\n async getProgress(transferId: string): Promise<ProgressRecordWire[]> {\n const body = (await this.http.request('GET', `/v1/intents/${transferId}/progress`)) as {\n records: ProgressRecordWire[];\n };\n return body.records;\n }\n\n // ── mailbox ──────────────────────────────────────────────────────────────\n\n async deposit(entry: MailboxDepositEntry): Promise<string> {\n const body = (await this.http.request('POST', '/v1/mailbox', entry)) as { entryId: string };\n return body.entryId;\n }\n\n async depositBatch(entries: MailboxDepositEntry[]): Promise<{ entryId: string; seq: number }[]> {\n const body = (await this.http.request('POST', '/v1/mailbox/batch', { entries })) as {\n entries: { entryId: string; seq: number }[];\n };\n return body.entries;\n }\n\n listMailbox(since?: number): Promise<MailboxPageWire> {\n const query = since !== undefined ? `?since=${since}` : '';\n return this.http.request('GET', `/v1/mailbox${query}`) as Promise<MailboxPageWire>;\n }\n\n claim(entryIds: string[], intoInventory: boolean): Promise<ClaimResultWire> {\n return this.http.request('POST', '/v1/mailbox/claim', { entryIds, intoInventory }) as Promise<ClaimResultWire>;\n }\n\n async reject(entryIds: string[], reason?: MailboxRejectReason, detail?: string): Promise<string[]> {\n const body = (await this.http.request('POST', '/v1/mailbox/reject', {\n entryIds,\n ...(reason !== undefined ? { reason } : {}),\n ...(detail !== undefined ? { detail } : {}),\n })) as { rejected: string[] };\n return body.rejected;\n }\n\n // ── history ──────────────────────────────────────────────────────────────\n\n async postHistory(records: HistoryRecordWire[]): Promise<{ inserted: number; deduped: number }> {\n return (await this.http.request('POST', '/v1/history', { records })) as {\n inserted: number;\n deduped: number;\n };\n }\n\n listHistory(options: { before?: string; limit?: number } = {}): Promise<HistoryPageWire> {\n const params = new URLSearchParams();\n if (options.before !== undefined) params.set('before', options.before);\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n const qs = params.toString();\n return this.http.request('GET', `/v1/history${qs ? `?${qs}` : ''}`) as Promise<HistoryPageWire>;\n }\n\n // ── payment requests ─────────────────────────────────────────────────────\n\n createPaymentRequest(input: {\n toPubkey: string;\n assets: AssetWire[];\n memo?: string;\n expiresAt?: string;\n }): Promise<PaymentRequestWire> {\n return this.http.request('POST', '/v1/payment-requests', input) as Promise<PaymentRequestWire>;\n }\n\n listPaymentRequests(params: ListPaymentRequestsParams): Promise<PaymentRequestsPageWire> {\n const query = new URLSearchParams();\n query.set('role', params.role);\n if (params.status !== undefined) query.set('status', params.status);\n if (params.role === 'incoming') {\n if (params.since !== undefined) query.set('since', String(params.since));\n } else if (params.before !== undefined) {\n query.set('before', params.before);\n }\n return this.http.request('GET', `/v1/payment-requests?${query.toString()}`) as Promise<PaymentRequestsPageWire>;\n }\n\n respondPaymentRequest(id: string, response: RespondPaymentRequestInput): Promise<PaymentRequestWire> {\n return this.http.request('POST', `/v1/payment-requests/${id}/respond`, response) as Promise<PaymentRequestWire>;\n }\n\n // ── realtime ─────────────────────────────────────────────────────────────\n\n async wsTicket(): Promise<string> {\n const body = (await this.http.request('POST', '/v1/ws-ticket')) as { ticket: string };\n return body.ticket;\n }\n}\n","/**\n * Centralized SDK Logger\n *\n * A lightweight singleton logger that works across all tsup bundles\n * by storing state on globalThis. Supports three log levels:\n * - debug: detailed messages (only shown when debug=true)\n * - warn: important warnings (ALWAYS shown regardless of debug flag)\n * - error: critical errors (ALWAYS shown regardless of debug flag)\n *\n * Global debug flag enables all logging. Per-tag overrides allow\n * granular control (e.g., only transport debug).\n *\n * @example\n * ```ts\n * import { logger } from '@unicitylabs/sphere-sdk';\n *\n * // Enable all debug logging\n * logger.configure({ debug: true });\n *\n * // Enable only specific tags\n * logger.setTagDebug('Nostr', true);\n *\n * // Usage in SDK classes\n * logger.debug('Payments', 'Transfer started', { amount, recipient });\n * logger.warn('Nostr', 'queryEvents timed out after 5s');\n * logger.error('Sphere', 'Critical failure', error);\n * ```\n */\n\nexport type LogLevel = 'debug' | 'warn' | 'error';\n\nexport type LogHandler = (level: LogLevel, tag: string, message: string, ...args: unknown[]) => void;\n\nexport interface LoggerConfig {\n /** Enable debug logging globally (default: false). When false, only warn and error messages are shown. */\n debug?: boolean;\n /** Custom log handler. If provided, replaces console output. Useful for tests or custom log sinks. */\n handler?: LogHandler | null;\n}\n\n// Use a unique symbol-like key on globalThis to share logger state across tsup bundles\nconst LOGGER_KEY = '__sphere_sdk_logger__';\n\ninterface LoggerState {\n debug: boolean;\n tags: Record<string, boolean>;\n handler: LogHandler | null;\n}\n\nfunction getState(): LoggerState {\n const g = globalThis as unknown as Record<string, unknown>;\n if (!g[LOGGER_KEY]) {\n g[LOGGER_KEY] = { debug: false, tags: {}, handler: null } satisfies LoggerState;\n }\n return g[LOGGER_KEY] as LoggerState;\n}\n\nfunction isEnabled(tag: string): boolean {\n const state = getState();\n // Per-tag override takes priority\n if (tag in state.tags) return state.tags[tag];\n // Fall back to global flag\n return state.debug;\n}\n\nexport const logger = {\n /**\n * Configure the logger. Can be called multiple times (last write wins).\n * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().\n */\n configure(config: LoggerConfig): void {\n const state = getState();\n if (config.debug !== undefined) state.debug = config.debug;\n if (config.handler !== undefined) state.handler = config.handler;\n },\n\n /**\n * Enable/disable debug logging for a specific tag.\n * Per-tag setting overrides the global debug flag.\n *\n * @example\n * ```ts\n * logger.setTagDebug('Nostr', true); // enable only Nostr logs\n * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true\n * ```\n */\n setTagDebug(tag: string, enabled: boolean): void {\n getState().tags[tag] = enabled;\n },\n\n /**\n * Clear per-tag override, falling back to global debug flag.\n */\n clearTagDebug(tag: string): void {\n delete getState().tags[tag];\n },\n\n /** Returns true if debug mode is enabled for the given tag (or globally). */\n isDebugEnabled(tag?: string): boolean {\n if (tag) return isEnabled(tag);\n return getState().debug;\n },\n\n /**\n * Debug-level log. Only shown when debug is enabled (globally or for this tag).\n * Use for detailed operational information.\n */\n debug(tag: string, message: string, ...args: unknown[]): void {\n if (!isEnabled(tag)) return;\n const state = getState();\n if (state.handler) {\n state.handler('debug', tag, message, ...args);\n } else {\n console.log(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Warning-level log. ALWAYS shown regardless of debug flag.\n * Use for important but non-critical issues (timeouts, retries, degraded state).\n */\n warn(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('warn', tag, message, ...args);\n } else {\n console.warn(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Error-level log. ALWAYS shown regardless of debug flag.\n * Use for critical failures that should never be silenced.\n */\n error(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('error', tag, message, ...args);\n } else {\n console.error(`[${tag}]`, message, ...args);\n }\n },\n\n /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */\n reset(): void {\n const g = globalThis as unknown as Record<string, unknown>;\n delete g[LOGGER_KEY];\n },\n};\n","// The complete §6 durable-state inventory. One writer per store.\n\nimport { logger } from '../../core/logger';\nimport type { StorageProvider } from '../../storage';\n\n/** Generation 2 of the durable client state; renaming IS the 3.x migration\n * (kv-generation.test.ts). Must not START with a superseded prefix — the sweep\n * below matches by `startsWith`. */\nconst KV_PREFIX = 'pv2g2:';\n\nconst SUPERSEDED_KV_PREFIXES = ['pv2:'] as const;\n\n/** Never `storage.clear()` — that takes the keys too. */\nexport async function sweepSupersededState(storage: StorageProvider): Promise<void> {\n for (const prefix of SUPERSEDED_KV_PREFIXES) {\n try {\n await storage.clear(prefix);\n } catch (err) {\n logger.warn('PaymentsV2', `could not clear superseded state under \"${prefix}\": ${String(err)}`);\n }\n }\n}\n\nexport interface ScopedKV {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T): Promise<void>;\n remove(key: string): Promise<void>;\n}\n\nexport function createScopedKV(\n storage: StorageProvider,\n network: string,\n chainPubkey: string\n): ScopedKV {\n const prefix = `${KV_PREFIX}${network}:${chainPubkey}:`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.get(prefix + key);\n if (raw === null || raw === undefined) return null;\n return typeof raw === 'string' ? (JSON.parse(raw) as T) : (raw as T);\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.set(prefix + key, JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.remove(prefix + key);\n },\n };\n}\n\n\nexport interface IntentBackstopEntry {\n transferId: string;\n payloadEnvelope: string;\n requiresSeedClose: boolean;\n // #676: a locally-aborted intent is NEVER resumed.\n disposition: 'open' | 'abortPending' | 'aborted';\n createdAt: number;\n}\n\n\n// #621 delivery journal.\nexport interface DeliveryJournalEntry {\n transferId: string;\n opIndex: number;\n recipientPubkey: string;\n blobHex: string;\n memo?: string;\n // Poison budget (#517); 429 deferrals do NOT count.\n attempts: number;\n deferredUntil?: number;\n undeliverable?: boolean;\n}\n\n// §5.9 mint journal.\nexport interface MintJournalEntry {\n mintId: string;\n coinId: string;\n amount: string;\n tokenId: string;\n createdAt: number;\n}\n\n// §5.9 NFT mint journal (#785). Its own store: an older client reading a coin\n// journal entry without coinId/amount would retry it every pass, forever.\n// Every field a byte-identical re-mint needs is journaled, so resume never re-signs.\nexport interface NftMintJournalEntry {\n mintId: string;\n tokenId: string;\n dataHex: string;\n saltHex: string;\n tokenTypeHex: string;\n createdAt: number;\n}\n\n// #690 shortfall record.\nexport interface ShortfallEntry {\n transferId: string;\n remainingAmount: string;\n coinId: string;\n recipient: string;\n // Already delivered — NEVER re-send these sources.\n committedTokenIds: string[];\n createdAt: number;\n}\n\n// #441 settling link.\nexport interface SettlingLink {\n requestId: string;\n transferId: string;\n committed: boolean;\n createdAt: number;\n}\n\nexport type StreamName = 'inventory' | 'mailbox' | 'payment_requests' | 'history';\n\n// Cursor+epoch persist as ONE record — never two keys (#692 F10).\nexport interface StreamCursor {\n cursor: number | string;\n syncEpoch: string;\n}\n\nexport const STORE_KEYS = {\n intentBackstop: 'intents',\n checkpointCache: 'checkpoints',\n deliveryJournal: 'delivery-journal',\n mintJournal: 'mint-journal',\n nftMintJournal: 'nft-mint-journal',\n shortfalls: 'shortfalls',\n settlingLinks: 'settling',\n streamCursor: (s: StreamName) => `cursor:${s}`,\n epochLatch: 'epoch-latch',\n // §5.2 InventoryView durable overlays (#625/#679).\n suspectedSpent: 'suspected-spent',\n knownSpends: 'known-spends',\n} as const;\n","/**\n * Hex, bytes and number utilities.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport {\n abytes as abytes_,\n anumber as anumber_,\n bytesToHex as bytesToHex_,\n concatBytes as concatBytes_,\n hexToBytes as hexToBytes_,\n isBytes as isBytes_,\n randomBytes as randomBytes_,\n} from '@noble/hashes/utils.js';\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n/**\n * Validates that a value is a byte array.\n * @param value - Value to validate.\n * @param length - Optional exact byte length.\n * @param title - Optional field name.\n * @returns Original byte array.\n * @example\n * Reject non-byte input before passing data into curve code.\n *\n * ```ts\n * abytes(new Uint8Array(1));\n * ```\n */\nexport const abytes = <T extends TArg<Uint8Array>>(value: T, length?: number, title?: string): T =>\n abytes_(value, length, title) as T;\n/**\n * Validates that a value is a non-negative safe integer.\n * @param n - Value to validate.\n * @param title - Optional field name.\n * @example\n * Validate a numeric length before allocating buffers.\n *\n * ```ts\n * anumber(1);\n * ```\n */\nexport const anumber: typeof anumber_ = anumber_;\n/**\n * Encodes bytes as lowercase hex.\n * @param bytes - Bytes to encode.\n * @returns Lowercase hex string.\n * @example\n * Serialize bytes as hex for logging or fixtures.\n *\n * ```ts\n * bytesToHex(Uint8Array.of(1, 2, 3));\n * ```\n */\nexport const bytesToHex: typeof bytesToHex_ = bytesToHex_;\n/**\n * Concatenates byte arrays.\n * @param arrays - Byte arrays to join.\n * @returns Concatenated bytes.\n * @example\n * Join domain-separated chunks into one buffer.\n *\n * ```ts\n * concatBytes(Uint8Array.of(1), Uint8Array.of(2));\n * ```\n */\nexport const concatBytes = (...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> =>\n concatBytes_(...arrays) as TRet<Uint8Array>;\n/**\n * Decodes lowercase or uppercase hex into bytes.\n * @param hex - Hex string to decode.\n * @returns Decoded bytes.\n * @example\n * Parse fixture hex into bytes before hashing.\n *\n * ```ts\n * hexToBytes('0102');\n * ```\n */\nexport const hexToBytes = (hex: string): TRet<Uint8Array> => hexToBytes_(hex) as TRet<Uint8Array>;\n/**\n * Checks whether a value is a Uint8Array.\n * @param a - Value to inspect.\n * @returns `true` when `a` is a Uint8Array.\n * @example\n * Branch on byte input before decoding it.\n *\n * ```ts\n * isBytes(new Uint8Array(1));\n * ```\n */\nexport const isBytes: typeof isBytes_ = isBytes_;\n/**\n * Reads random bytes from the platform CSPRNG.\n * @param bytesLength - Number of random bytes to read.\n * @returns Fresh random bytes.\n * @example\n * Generate a random seed for a keypair.\n *\n * ```ts\n * randomBytes(2);\n * ```\n */\nexport const randomBytes = (bytesLength?: number): TRet<Uint8Array> =>\n randomBytes_(bytesLength) as TRet<Uint8Array>;\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _1n = /* @__PURE__ */ BigInt(1);\n\n/** Callable hash interface with metadata and optional extendable output support. */\nexport type CHash = {\n /**\n * Hash one message.\n * @param message - Message bytes to hash.\n * @returns Digest bytes.\n */\n (message: TArg<Uint8Array>): TRet<Uint8Array>;\n /** Hash block length in bytes. */\n blockLen: number;\n /** Default output length in bytes. */\n outputLen: number;\n /** Whether `.create()` can be used as an XOF stream. */\n canXOF: boolean;\n /**\n * Create one stateful hash or XOF instance, for example SHAKE with a custom output length.\n * @param opts - Optional extendable-output configuration:\n * - `dkLen` (optional): Optional output length for XOF-style hashes.\n * @returns Hash instance.\n */\n create(opts?: { dkLen?: number }): any;\n};\n/** Plain callable hash interface. */\nexport type FHash = (message: TArg<Uint8Array>) => TRet<Uint8Array>;\n/** HMAC callback signature. */\nexport type HmacFn = (key: TArg<Uint8Array>, message: TArg<Uint8Array>) => TRet<Uint8Array>;\n/**\n * Validates that a flag is boolean.\n * @param value - Value to validate.\n * @param title - Optional field name.\n * @returns Original value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Reject non-boolean option flags early.\n *\n * ```ts\n * abool(true);\n * ```\n */\nexport function abool(value: boolean, title: string = ''): boolean {\n if (typeof value !== 'boolean') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(prefix + 'expected boolean, got type=' + typeof value);\n }\n return value;\n}\n\n/**\n * Validates that a value is a non-negative bigint or safe integer.\n * @param n - Value to validate.\n * @returns The same validated value.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate one integer-like value before serializing it.\n *\n * ```ts\n * abignumber(1n);\n * ```\n */\nexport function abignumber<T extends number | bigint>(n: T): T {\n if (typeof n === 'bigint') {\n if (!isPosBig(n)) throw new RangeError('positive bigint expected, got ' + n);\n } else anumber(n);\n return n;\n}\n\n/**\n * Validates that a value is a safe integer.\n * @param value - Integer to validate.\n * @param title - Optional field name.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a window size before scalar arithmetic uses it.\n *\n * ```ts\n * asafenumber(1);\n * ```\n */\nexport function asafenumber(value: number, title: string = ''): void {\n if (typeof value !== 'number') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(prefix + 'expected number, got type=' + typeof value);\n }\n if (!Number.isSafeInteger(value)) {\n const prefix = title && `\"${title}\" `;\n throw new RangeError(prefix + 'expected safe integer, got ' + value);\n }\n}\n\n/**\n * Encodes a bigint into even-length big-endian hex.\n * The historical \"unpadded\" name only means \"no fixed-width field padding\"; odd-length hex still\n * gets one leading zero nibble so the result always represents whole bytes.\n * @param num - Number to encode.\n * @returns Big-endian hex string.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Encode a scalar into hex without a `0x` prefix.\n *\n * ```ts\n * numberToHexUnpadded(255n);\n * ```\n */\nexport function numberToHexUnpadded(num: number | bigint): string {\n const hex = abignumber(num).toString(16);\n return hex.length & 1 ? '0' + hex : hex;\n}\n\n/**\n * Parses a big-endian hex string into bigint.\n * Accepts odd-length hex through the native `BigInt('0x' + hex)` parser and currently surfaces the\n * same native `SyntaxError` for malformed hex instead of wrapping it in a library-specific error.\n * @param hex - Hex string without `0x`.\n * @returns Parsed bigint value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Parse a scalar from fixture hex.\n *\n * ```ts\n * hexToNumber('ff');\n * ```\n */\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian\n}\n\n// BE: Big Endian, LE: Little Endian\n/**\n * Parses big-endian bytes into bigint.\n * @param bytes - Bytes in big-endian order.\n * @returns Parsed bigint value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Read a scalar encoded in network byte order.\n *\n * ```ts\n * bytesToNumberBE(Uint8Array.of(1, 0));\n * ```\n */\nexport function bytesToNumberBE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex_(bytes));\n}\n/**\n * Parses little-endian bytes into bigint.\n * @param bytes - Bytes in little-endian order.\n * @returns Parsed bigint value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Read a scalar encoded in little-endian form.\n *\n * ```ts\n * bytesToNumberLE(Uint8Array.of(1, 0));\n * ```\n */\nexport function bytesToNumberLE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex_(copyBytes(abytes_(bytes)).reverse()));\n}\n\n/**\n * Encodes a bigint into fixed-length big-endian bytes.\n * @param n - Number to encode.\n * @param len - Output length in bytes. Must be greater than zero.\n * @returns Big-endian byte array.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Serialize a scalar into a 32-byte field element.\n *\n * ```ts\n * numberToBytesBE(255n, 2);\n * ```\n */\nexport function numberToBytesBE(n: number | bigint, len: number): TRet<Uint8Array> {\n anumber_(len);\n if (len === 0) throw new RangeError('zero length');\n n = abignumber(n);\n const hex = n.toString(16);\n // Detect overflow before hex parsing so oversized values don't leak the shared odd-hex error.\n if (hex.length > len * 2) throw new RangeError('number too large');\n return hexToBytes_(hex.padStart(len * 2, '0')) as TRet<Uint8Array>;\n}\n/**\n * Encodes a bigint into fixed-length little-endian bytes.\n * @param n - Number to encode.\n * @param len - Output length in bytes.\n * @returns Little-endian byte array.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Serialize a scalar for little-endian protocols.\n *\n * ```ts\n * numberToBytesLE(255n, 2);\n * ```\n */\nexport function numberToBytesLE(n: number | bigint, len: number): TRet<Uint8Array> {\n return numberToBytesBE(n, len).reverse() as TRet<Uint8Array>;\n}\n// Unpadded, rarely used\n/**\n * Encodes a bigint into variable-length big-endian bytes.\n * @param n - Number to encode.\n * @returns Variable-length big-endian bytes.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Serialize a bigint without fixed-width padding.\n *\n * ```ts\n * numberToVarBytesBE(255n);\n * ```\n */\nexport function numberToVarBytesBE(n: number | bigint): TRet<Uint8Array> {\n return hexToBytes_(numberToHexUnpadded(abignumber(n))) as TRet<Uint8Array>;\n}\n\n// Compares 2 u8a-s in kinda constant time\n/**\n * Compares two byte arrays in constant-ish time.\n * @param a - Left byte array.\n * @param b - Right byte array.\n * @returns `true` when bytes match.\n * @example\n * Compare two encoded points without early exit.\n *\n * ```ts\n * equalBytes(Uint8Array.of(1), Uint8Array.of(1));\n * ```\n */\nexport function equalBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n a = abytes(a);\n b = abytes(b);\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n/**\n * Copies Uint8Array. We can't use u8a.slice(), because u8a can be Buffer,\n * and Buffer#slice creates mutable copy. Never use Buffers!\n * @param bytes - Bytes to copy.\n * @returns Detached copy.\n * @example\n * Make an isolated copy before mutating serialized bytes.\n *\n * ```ts\n * copyBytes(Uint8Array.of(1, 2, 3));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Decodes 7-bit ASCII string to Uint8Array, throws on non-ascii symbols\n * Should be safe to use for things expected to be ASCII.\n * Returns exact same result as `TextEncoder` for ASCII or throws.\n * @param ascii - ASCII input text.\n * @returns Encoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encode an ASCII domain-separation tag.\n *\n * ```ts\n * asciiToBytes('ABC');\n * ```\n */\nexport function asciiToBytes(ascii: string): TRet<Uint8Array> {\n if (typeof ascii !== 'string') throw new TypeError('ascii string expected, got ' + typeof ascii);\n return Uint8Array.from(ascii, (c, i) => {\n const charCode = c.charCodeAt(0);\n if (c.length !== 1 || charCode > 127) {\n throw new RangeError(\n `string contains non-ASCII character \"${ascii[i]}\" with code ${charCode} at position ${i}`\n );\n }\n return charCode;\n }) as TRet<Uint8Array>;\n}\n\n// Historical name: this accepts non-negative bigints, including zero.\nconst isPosBig = (n: bigint) => typeof n === 'bigint' && _0n <= n;\n\n/**\n * Checks whether a bigint lies inside a half-open range.\n * @param n - Candidate value.\n * @param min - Inclusive lower bound.\n * @param max - Exclusive upper bound.\n * @returns `true` when the value is inside the range.\n * @example\n * Check whether a candidate scalar fits the field order.\n *\n * ```ts\n * inRange(2n, 1n, 3n);\n * ```\n */\nexport function inRange(n: bigint, min: bigint, max: bigint): boolean {\n return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;\n}\n\n/**\n * Asserts `min <= n < max`. NOTE: upper bound is exclusive.\n * @param title - Value label for error messages.\n * @param n - Candidate value.\n * @param min - Inclusive lower bound.\n * @param max - Exclusive upper bound.\n * Wrong-type inputs are not separated from out-of-range values here: they still flow through the\n * shared `RangeError` path because this is only a throwing wrapper around `inRange(...)`.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Assert that a bigint stays within one half-open range.\n *\n * ```ts\n * aInRange('x', 2n, 1n, 256n);\n * ```\n */\nexport function aInRange(title: string, n: bigint, min: bigint, max: bigint): void {\n // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?\n // consider P=256n, min=0n, max=P\n // - a for min=0 would require -1: `inRange('x', x, -1n, P)`\n // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`\n // - our way is the cleanest: `inRange('x', x, 0n, P)\n if (!inRange(n, min, max))\n throw new RangeError('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);\n}\n\n// Bit operations\n\n/**\n * Calculates amount of bits in a bigint.\n * Same as `n.toString(2).length`\n * TODO: merge with nLength in modular\n * @param n - Value to inspect.\n * @returns Bit length.\n * @throws If the value is negative. {@link Error}\n * @example\n * Measure the bit length of a scalar before serialization.\n *\n * ```ts\n * bitLen(8n);\n * ```\n */\nexport function bitLen(n: bigint): number {\n // Size callers in this repo only use non-negative orders / scalars, so negative inputs are a\n // contract bug and must not silently collapse to zero bits.\n if (n < _0n) throw new Error('expected non-negative bigint, got ' + n);\n let len;\n for (len = 0; n > _0n; n >>= _1n, len += 1);\n return len;\n}\n\n/**\n * Gets single bit at position.\n * NOTE: first bit position is 0 (same as arrays)\n * Same as `!!+Array.from(n.toString(2)).reverse()[pos]`\n * @param n - Source value.\n * @param pos - Bit position. Negative positions are passed through to raw\n * bigint shift semantics; because the mask is built as `1n << pos`,\n * they currently collapse to `0n` and make the helper a no-op.\n * @returns Bit as bigint.\n * @example\n * Gets single bit at position.\n *\n * ```ts\n * bitGet(5n, 0);\n * ```\n */\nexport function bitGet(n: bigint, pos: number): bigint {\n return (n >> BigInt(pos)) & _1n;\n}\n\n/**\n * Sets single bit at position.\n * @param n - Source value.\n * @param pos - Bit position. Negative positions are passed through to raw bigint shift semantics,\n * so they currently behave like left shifts.\n * @param value - Whether the bit should be set.\n * @returns Updated bigint.\n * @example\n * Sets single bit at position.\n *\n * ```ts\n * bitSet(0n, 1, true);\n * ```\n */\nexport function bitSet(n: bigint, pos: number, value: boolean): bigint {\n const mask = _1n << BigInt(pos);\n // Clearing needs AND-not here; OR with zero leaves an already-set bit untouched.\n return value ? n | mask : n & ~mask;\n}\n\n/**\n * Calculate mask for N bits. Not using ** operator with bigints because of old engines.\n * Same as BigInt(`0b${Array(i).fill('1').join('')}`)\n * @param n - Number of bits. Negative widths are currently passed through to raw bigint shift\n * semantics and therefore produce `-1n`.\n * @returns Bitmask value.\n * @example\n * Calculate mask for N bits.\n *\n * ```ts\n * bitMask(4);\n * ```\n */\nexport const bitMask = (n: number): bigint => (_1n << BigInt(n)) - _1n;\n\n// DRBG\n\ntype Pred<T> = (v: TArg<Uint8Array>) => T | undefined;\n/**\n * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n * @param hashLen - Hash output size in bytes. Callers are expected to pass a positive length; `0`\n * is not rejected here and would make the internal generate loop non-progressing.\n * @param qByteLen - Requested output size in bytes. Callers are expected to pass a positive length.\n * @param hmacFn - HMAC implementation.\n * @returns Function that will call DRBG until the predicate returns anything\n * other than `undefined`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Build a deterministic nonce generator for RFC6979-style signing.\n *\n * ```ts\n * import { createHmacDrbg } from '@noble/curves/utils.js';\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const drbg = createHmacDrbg(32, 32, (key, msg) => hmac(sha256, key, msg));\n * const seed = new Uint8Array(32);\n * drbg(seed, (bytes) => bytes);\n * ```\n */\nexport function createHmacDrbg<T>(\n hashLen: number,\n qByteLen: number,\n hmacFn: TArg<HmacFn>\n): TRet<(seed: Uint8Array, predicate: Pred<T>) => T> {\n anumber_(hashLen, 'hashLen');\n anumber_(qByteLen, 'qByteLen');\n if (typeof hmacFn !== 'function') throw new TypeError('hmacFn must be a function');\n // creates Uint8Array\n const u8n = (len: number): TRet<Uint8Array> => new Uint8Array(len) as TRet<Uint8Array>;\n const NULL = Uint8Array.of();\n const byte0 = Uint8Array.of(0x00);\n const byte1 = Uint8Array.of(0x01);\n const _maxDrbgIters = 1000;\n\n // Step B, Step C: set hashLen to 8*ceil(hlen/8).\n // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 signatures.\n let v: Uint8Array = u8n(hashLen);\n // Steps B and C of RFC6979 3.2.\n let k: Uint8Array = u8n(hashLen);\n let i = 0; // Iterations counter, will throw when over 1000\n const reset = () => {\n v.fill(1);\n k.fill(0);\n i = 0;\n };\n // hmac(k)(v, ...values)\n const h = (...msgs: TArg<Uint8Array[]>) => (hmacFn as HmacFn)(k, concatBytes(v, ...msgs));\n const reseed = (seed: TArg<Uint8Array> = NULL) => {\n // HMAC-DRBG reseed() function. Steps D-G\n k = h(byte0, seed); // k = hmac(k || v || 0x00 || seed)\n v = h(); // v = hmac(k || v)\n if (seed.length === 0) return;\n k = h(byte1, seed); // k = hmac(k || v || 0x01 || seed)\n v = h(); // v = hmac(k || v)\n };\n const gen = () => {\n // HMAC-DRBG generate() function\n if (i++ >= _maxDrbgIters) throw new Error('drbg: tried max amount of iterations');\n let len = 0;\n const out: Uint8Array[] = [];\n while (len < qByteLen) {\n v = h();\n const sl = v.slice();\n out.push(sl);\n len += v.length;\n }\n return concatBytes(...out);\n };\n const genUntil = (seed: TArg<Uint8Array>, pred: TArg<Pred<T>>): T => {\n reset();\n reseed(seed); // Steps D-G\n let res: T | undefined = undefined; // Step H: grind until the predicate accepts a candidate.\n // Falsy values like 0 are valid outputs.\n while ((res = (pred as Pred<T>)(gen())) === undefined) reseed();\n reset();\n return res;\n };\n return genUntil as TRet<(seed: Uint8Array, predicate: Pred<T>) => T>;\n}\n\n/**\n * Validates declared required and optional field types on a plain object.\n * Extra keys are intentionally ignored because many callers validate only the subset they use from\n * richer option bags or runtime objects.\n * @param object - Object to validate.\n * @param fields - Required field types.\n * @param optFields - Optional field types.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Check user options before building a curve helper.\n *\n * ```ts\n * validateObject({ flag: true }, { flag: 'boolean' });\n * ```\n */\nexport function validateObject(\n object: Record<string, any>,\n fields: Record<string, string> = {},\n optFields: Record<string, string> = {}\n): void {\n if (Object.prototype.toString.call(object) !== '[object Object]')\n throw new TypeError('expected valid options object');\n type Item = keyof typeof object;\n function checkField(fieldName: Item, expectedType: string, isOpt: boolean) {\n // Config/data fields must be explicit own properties, but runtime objects such as Field\n // instances intentionally satisfy required method slots via their shared prototype.\n if (!isOpt && expectedType !== 'function' && !Object.hasOwn(object, fieldName))\n throw new TypeError(`param \"${fieldName}\" is invalid: expected own property`);\n const val = object[fieldName];\n if (isOpt && val === undefined) return;\n const current = typeof val;\n if (current !== expectedType || val === null)\n throw new TypeError(\n `param \"${fieldName}\" is invalid: expected ${expectedType}, got ${current}`\n );\n }\n const iter = (f: typeof fields, isOpt: boolean) =>\n Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));\n iter(fields, false);\n iter(optFields, true);\n}\n\n/**\n * Throws not implemented error.\n * @returns Never returns.\n * @throws If the unfinished code path is reached. {@link Error}\n * @example\n * Surface the placeholder error from an unfinished code path.\n *\n * ```ts\n * try {\n * notImplemented();\n * } catch {}\n * ```\n */\nexport const notImplemented = (): never => {\n throw new Error('not implemented');\n};\n\n/** Generic keygen/getPublicKey interface shared by curve helpers. */\nexport interface CryptoKeys {\n /** Public byte lengths for keys and optional seeds. */\n lengths: { seed?: number; public?: number; secret?: number };\n /**\n * Generate one secret/public keypair.\n * @param seed - Optional seed bytes for deterministic key generation.\n * @returns Fresh secret/public keypair.\n */\n keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };\n /**\n * Derive one public key from a secret key.\n * @param secretKey - Secret key bytes.\n * @returns Public key bytes.\n */\n getPublicKey: (secretKey: Uint8Array) => Uint8Array;\n}\n\n/** Generic interface for signatures. Has keygen, sign and verify. */\nexport interface Signer extends CryptoKeys {\n // Interfaces are fun. We cannot just add new fields without copying old ones.\n /** Public byte lengths for keys, signatures, and optional signing randomness. */\n lengths: {\n seed?: number;\n public?: number;\n secret?: number;\n signRand?: number;\n signature?: number;\n };\n /**\n * Sign one message.\n * @param msg - Message bytes to sign.\n * @param secretKey - Secret key bytes.\n * @returns Signature bytes.\n */\n sign: (msg: Uint8Array, secretKey: Uint8Array) => Uint8Array;\n /**\n * Verify one signature.\n * @param sig - Signature bytes.\n * @param msg - Signed message bytes.\n * @param publicKey - Public key bytes.\n * @returns `true` when the signature is valid.\n */\n verify: (sig: Uint8Array, msg: Uint8Array, publicKey: Uint8Array) => boolean;\n}\n","/**\n * Utils for modular division and fields.\n * Field over 11 is a finite (Galois) field is integer number operations `mod 11`.\n * There is no division: it is replaced by modular multiplicative inverse.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport {\n abool,\n abytes,\n anumber,\n asafenumber,\n bitLen,\n bytesToNumberBE,\n bytesToNumberLE,\n numberToBytesBE,\n numberToBytesLE,\n validateObject,\n type TArg,\n type TRet,\n} from '../utils.ts';\n\n// Numbers aren't used in x25519 / x448 builds\n// prettier-ignore\nconst _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2);\n// prettier-ignore\nconst _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _5n = /* @__PURE__ */ BigInt(5);\n// prettier-ignore\nconst _7n = /* @__PURE__ */ BigInt(7), _8n = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9);\nconst _16n = /* @__PURE__ */ BigInt(16);\n\n/**\n * @param a - Dividend value.\n * @param b - Positive modulus.\n * @returns Reduced value in `[0, b)` only when `b` is positive.\n * @throws If the modulus is not positive. {@link Error}\n * @example\n * Normalize a bigint into one field residue.\n *\n * ```ts\n * mod(-1n, 5n);\n * ```\n */\nexport function mod(a: bigint, b: bigint): bigint {\n if (b <= _0n) throw new Error('mod: expected positive modulus, got ' + b);\n const result = a % b;\n return result >= _0n ? result : b + result;\n}\n/**\n * Efficiently raise num to a power with modular reduction.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n * Low-level helper: callers that need canonical residues must pass a valid `num` for the chosen\n * modulus instead of relying on the `power===0/1` fast paths to normalize it.\n * @param num - Base value.\n * @param power - Exponent value.\n * @param modulo - Reduction modulus.\n * @returns Modular exponentiation result.\n * @throws If the modulus or exponent is invalid. {@link Error}\n * @example\n * Raise one bigint to a modular power.\n *\n * ```ts\n * pow(2n, 6n, 11n) // 64n % 11n == 9n\n * ```\n */\nexport function pow(num: bigint, power: bigint, modulo: bigint): bigint {\n return FpPow(Field(modulo), num, power);\n}\n\n/**\n * Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)`.\n * Low-level helper: callers that need canonical residues must pass a valid `x` for the chosen\n * modulus; the `power===0` fast path intentionally returns the input unchanged.\n * @param x - Base value.\n * @param power - Number of squarings.\n * @param modulo - Reduction modulus.\n * @returns Repeated-squaring result.\n * @throws If the exponent is negative. {@link Error}\n * @example\n * Apply repeated squaring inside one field.\n *\n * ```ts\n * pow2(3n, 2n, 11n);\n * ```\n */\nexport function pow2(x: bigint, power: bigint, modulo: bigint): bigint {\n if (power < _0n) throw new Error('pow2: expected non-negative exponent, got ' + power);\n let res = x;\n while (power-- > _0n) {\n res *= res;\n res %= modulo;\n }\n return res;\n}\n\n/**\n * Inverses number over modulo.\n * Implemented using the {@link https://brilliant.org/wiki/extended-euclidean-algorithm/ | extended Euclidean algorithm}.\n * @param number - Value to invert.\n * @param modulo - Positive modulus.\n * @returns Multiplicative inverse.\n * @throws If the modulus is invalid or the inverse does not exist. {@link Error}\n * @example\n * Compute one modular inverse with the extended Euclidean algorithm.\n *\n * ```ts\n * invert(3n, 11n);\n * ```\n */\nexport function invert(number: bigint, modulo: bigint): bigint {\n if (number === _0n) throw new Error('invert: expected non-zero number');\n if (modulo <= _0n) throw new Error('invert: expected positive modulus, got ' + modulo);\n // Fermat's little theorem \"CT-like\" version inv(n) = n^(m-2) mod m is 30x slower.\n let a = mod(number, modulo);\n let b = modulo;\n // prettier-ignore\n let x = _0n, y = _1n, u = _1n, v = _0n;\n while (a !== _0n) {\n const q = b / a;\n const r = b - a * q;\n const m = x - u * q;\n const n = y - v * q;\n // prettier-ignore\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n const gcd = b;\n if (gcd !== _1n) throw new Error('invert: does not exist');\n return mod(x, modulo);\n}\n\nfunction assertIsSquare<T>(Fp: TArg<IField<T>>, root: T, n: T): void {\n const F = Fp as IField<T>;\n if (!F.eql(F.sqr(root), n)) throw new Error('Cannot find square root');\n}\n\n// Not all roots are possible! Example which will throw:\n// const NUM =\n// n = 72057594037927816n;\n// Fp = Field(BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'));\nfunction sqrt3mod4<T>(Fp: TArg<IField<T>>, n: T) {\n const F = Fp as IField<T>;\n const p1div4 = (F.ORDER + _1n) / _4n;\n const root = F.pow(n, p1div4);\n assertIsSquare(F, root, n);\n return root;\n}\n\n// Equivalent `q = 5 (mod 8)` square-root formula (Atkin-style), not the RFC Appendix I.2 CMOV\n// pseudocode verbatim.\nfunction sqrt5mod8<T>(Fp: TArg<IField<T>>, n: T) {\n const F = Fp as IField<T>;\n const p5div8 = (F.ORDER - _5n) / _8n;\n const n2 = F.mul(n, _2n);\n const v = F.pow(n2, p5div8);\n const nv = F.mul(n, v);\n const i = F.mul(F.mul(nv, _2n), v);\n const root = F.mul(nv, F.sub(i, F.ONE));\n assertIsSquare(F, root, n);\n return root;\n}\n\n// Based on RFC9380, Kong algorithm\n// prettier-ignore\nfunction sqrt9mod16(P: bigint): TRet<<T>(Fp: IField<T>, n: T) => T> {\n const Fp_ = Field(P);\n const tn = tonelliShanks(P);\n const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));// 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F\n const c2 = tn(Fp_, c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F\n const c3 = tn(Fp_, Fp_.neg(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F\n const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic\n return (<T>(Fp: TArg<IField<T>>, n: T): T => {\n const F = Fp as IField<T>;\n let tv1 = F.pow(n, c4); // 1. tv1 = x^c4\n let tv2 = F.mul(tv1, c1); // 2. tv2 = c1 * tv1\n const tv3 = F.mul(tv1, c2); // 3. tv3 = c2 * tv1\n const tv4 = F.mul(tv1, c3); // 4. tv4 = c3 * tv1\n const e1 = F.eql(F.sqr(tv2), n); // 5. e1 = (tv2^2) == x\n const e2 = F.eql(F.sqr(tv3), n); // 6. e2 = (tv3^2) == x\n tv1 = F.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x\n tv2 = F.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x\n const e3 = F.eql(F.sqr(tv2), n); // 9. e3 = (tv2^2) == x\n const root = F.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select sqrt from tv1 & tv2\n assertIsSquare(F, root, n);\n return root;\n }) as TRet<<T>(Fp: IField<T>, n: T) => T>;\n}\n\n/**\n * Tonelli-Shanks square root search algorithm.\n * This implementation is variable-time: it searches data-dependently for the first non-residue `Z`\n * and for the smallest `i` in the main loop, unlike RFC 9380 Appendix I.4's constant-time shape.\n * 1. {@link https://eprint.iacr.org/2012/685.pdf | eprint 2012/685}, page 12\n * 2. Square Roots from 1; 24, 51, 10 to Dan Shanks\n * @param P - field order\n * @returns function that takes field Fp (created from P) and number n\n * @throws If the field is too small, non-prime, or the square root does not exist. {@link Error}\n * @example\n * Construct a square-root helper for primes that need Tonelli-Shanks.\n *\n * ```ts\n * import { Field, tonelliShanks } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const sqrt = tonelliShanks(17n)(Fp, 4n);\n * ```\n */\nexport function tonelliShanks(P: bigint): TRet<<T>(Fp: IField<T>, n: T) => T> {\n // Initialization (precomputation).\n // Caching initialization could boost perf by 7%.\n if (P < _3n) throw new Error('sqrt is not defined for small field');\n // Factor P - 1 = Q * 2^S, where Q is odd\n let Q = P - _1n;\n let S = 0;\n while (Q % _2n === _0n) {\n Q /= _2n;\n S++;\n }\n\n // Find the first quadratic non-residue Z >= 2\n let Z = _2n;\n const _Fp = Field(P);\n while (FpLegendre(_Fp, Z) === 1) {\n // Basic primality test for P. After x iterations, chance of\n // not finding quadratic non-residue is 2^x, so 2^1000.\n if (Z++ > 1000) throw new Error('Cannot find square root: probably non-prime P');\n }\n // Fast-path; usually done before Z, but we do \"primality test\".\n if (S === 1) return sqrt3mod4 as TRet<<T>(Fp: IField<T>, n: T) => T>;\n\n // Slow-path\n // TODO: test on Fp2 and others\n let cc = _Fp.pow(Z, Q); // c = z^Q\n const Q1div2 = (Q + _1n) / _2n;\n return function tonelliSlow<T>(Fp: TArg<IField<T>>, n: T): T {\n const F = Fp as IField<T>;\n if (F.is0(n)) return n;\n // Check if n is a quadratic residue using Legendre symbol\n if (FpLegendre(F, n) !== 1) throw new Error('Cannot find square root');\n\n // Initialize variables for the main loop\n let M = S;\n let c = F.mul(F.ONE, cc); // c = z^Q, move cc from field _Fp into field Fp\n let t = F.pow(n, Q); // t = n^Q, first guess at the fudge factor\n let R = F.pow(n, Q1div2); // R = n^((Q+1)/2), first guess at the square root\n\n // Main loop\n // while t != 1\n while (!F.eql(t, F.ONE)) {\n if (F.is0(t)) return F.ZERO; // if t=0 return R=0\n let i = 1;\n\n // Find the smallest i >= 1 such that t^(2^i) ≡ 1 (mod P)\n let t_tmp = F.sqr(t); // t^(2^1)\n while (!F.eql(t_tmp, F.ONE)) {\n i++;\n t_tmp = F.sqr(t_tmp); // t^(2^2)...\n if (i === M) throw new Error('Cannot find square root');\n }\n\n // Calculate the exponent for b: 2^(M - i - 1)\n const exponent = _1n << BigInt(M - i - 1); // bigint is important\n const b = F.pow(c, exponent); // b = 2^(M - i - 1)\n\n // Update variables\n M = i;\n c = F.sqr(b); // c = b^2\n t = F.mul(t, c); // t = (t * b^2)\n R = F.mul(R, b); // R = R*b\n }\n return R;\n } as TRet<<T>(Fp: IField<T>, n: T) => T>;\n}\n\n/**\n * Square root for a finite field. Will try optimized versions first:\n *\n * 1. P ≡ 3 (mod 4)\n * 2. P ≡ 5 (mod 8)\n * 3. P ≡ 9 (mod 16)\n * 4. Tonelli-Shanks algorithm\n *\n * Different algorithms can give different roots, it is up to user to decide which one they want.\n * For example there is FpSqrtOdd/FpSqrtEven to choose a root by oddness\n * (used for hash-to-curve).\n * @param P - Field order.\n * @returns Square-root helper. The generic fallback inherits Tonelli-Shanks' variable-time\n * behavior and this selector assumes prime-field-style integer moduli.\n * @throws If the field is unsupported or the square root does not exist. {@link Error}\n * @example\n * Choose the square-root helper appropriate for one field modulus.\n *\n * ```ts\n * import { Field, FpSqrt } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const sqrt = FpSqrt(17n)(Fp, 4n);\n * ```\n */\nexport function FpSqrt(P: bigint): TRet<<T>(Fp: IField<T>, n: T) => T> {\n // P ≡ 3 (mod 4) => √n = n^((P+1)/4)\n if (P % _4n === _3n) return sqrt3mod4 as TRet<<T>(Fp: IField<T>, n: T) => T>;\n // P ≡ 5 (mod 8) => Atkin algorithm, page 10 of https://eprint.iacr.org/2012/685.pdf\n if (P % _8n === _5n) return sqrt5mod8 as TRet<<T>(Fp: IField<T>, n: T) => T>;\n // P ≡ 9 (mod 16) => Kong algorithm, page 11 of https://eprint.iacr.org/2012/685.pdf (algorithm 4)\n if (P % _16n === _9n) return sqrt9mod16(P);\n // Tonelli-Shanks algorithm\n return tonelliShanks(P);\n}\n\n/**\n * @param num - Value to inspect.\n * @param modulo - Field modulus.\n * @returns `true` when the least-significant little-endian bit is set.\n * @throws If the modulus is invalid for `mod(...)`. {@link Error}\n * @example\n * Inspect the low bit used by little-endian sign conventions.\n *\n * ```ts\n * isNegativeLE(3n, 11n);\n * ```\n */\nexport const isNegativeLE = (num: bigint, modulo: bigint): boolean =>\n (mod(num, modulo) & _1n) === _1n;\n\n/** Generic field interface used by prime and extension fields alike.\n * Generic helpers treat field operations as pure functions: implementations MUST treat provided\n * values/byte buffers as read-only and return detached results instead of mutating arguments.\n */\nexport interface IField<T> {\n /** Field order `q`, which may be prime or a prime power. */\n ORDER: bigint;\n /** Canonical encoded byte length. */\n BYTES: number;\n /** Canonical encoded bit length. */\n BITS: number;\n /** Whether encoded field elements use little-endian bytes. */\n isLE: boolean;\n /** Additive identity. */\n ZERO: T;\n /** Multiplicative identity. */\n ONE: T;\n // 1-arg\n /**\n * Normalize one value into the field.\n * @param num - Input value.\n * @returns Normalized field value.\n */\n create: (num: T) => T;\n /**\n * Check whether one value already belongs to the field.\n * @param num - Input value.\n * Implementations may throw `TypeError` on malformed input types instead of returning `false`.\n * @returns Whether the value already belongs to the field.\n */\n isValid: (num: T) => boolean;\n /**\n * Check whether one value is zero.\n * @param num - Input value.\n * @returns Whether the value is zero.\n */\n is0: (num: T) => boolean;\n /**\n * Check whether one value is non-zero and belongs to the field.\n * @param num - Input value.\n * Implementations may throw `TypeError` on malformed input types instead of returning `false`.\n * @returns Whether the value is non-zero and valid.\n */\n isValidNot0: (num: T) => boolean;\n /**\n * Negate one value.\n * @param num - Input value.\n * @returns Negated value.\n */\n neg(num: T): T;\n /**\n * Invert one value multiplicatively.\n * @param num - Input value.\n * @returns Multiplicative inverse.\n */\n inv(num: T): T;\n /**\n * Compute one square root when it exists.\n * @param num - Input value.\n * @returns Square root.\n */\n sqrt(num: T): T;\n /**\n * Square one value.\n * @param num - Input value.\n * @returns Squared value.\n */\n sqr(num: T): T;\n // 2-args\n /**\n * Compare two field values.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Whether both values are equal.\n */\n eql(lhs: T, rhs: T): boolean;\n /**\n * Add two normalized field values.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Sum value.\n */\n add(lhs: T, rhs: T): T;\n /**\n * Subtract two normalized field values.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Difference value.\n */\n sub(lhs: T, rhs: T): T;\n /**\n * Multiply two field values.\n * @param lhs - Left value.\n * @param rhs - Right value or scalar.\n * @returns Product value.\n */\n mul(lhs: T, rhs: T | bigint): T;\n /**\n * Raise one field value to a power.\n * @param lhs - Base value.\n * @param power - Exponent.\n * @returns Power value.\n */\n pow(lhs: T, power: bigint): T;\n /**\n * Divide one field value by another.\n * @param lhs - Dividend.\n * @param rhs - Divisor or scalar.\n * @returns Quotient value.\n */\n div(lhs: T, rhs: T | bigint): T;\n // N for NonNormalized (for now)\n /**\n * Add two values without re-normalizing the result.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Non-normalized sum.\n */\n addN(lhs: T, rhs: T): T;\n /**\n * Subtract two values without re-normalizing the result.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Non-normalized difference.\n */\n subN(lhs: T, rhs: T): T;\n /**\n * Multiply two values without re-normalizing the result.\n * @param lhs - Left value.\n * @param rhs - Right value or scalar.\n * @returns Non-normalized product.\n */\n mulN(lhs: T, rhs: T | bigint): T;\n /**\n * Square one value without re-normalizing the result.\n * @param num - Input value.\n * @returns Non-normalized square.\n */\n sqrN(num: T): T;\n\n // Optional\n // Should be same as sgn0 function in\n // [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#section-4.1).\n // NOTE: sgn0 is \"negative in LE\", which is the same as odd.\n // Negative in LE is a somewhat strange definition anyway.\n /**\n * Return the RFC 9380 `sgn0`-style oddness bit when supported.\n * This uses oddness instead of evenness so extension fields like Fp2 can expose the same hook.\n * Returns whether the value is odd under the field encoding.\n */\n isOdd?(num: T): boolean;\n // legendre?(num: T): T;\n /**\n * Invert many field elements in one batch.\n * @param lst - Values to invert.\n * @returns Batch of inverses.\n */\n invertBatch: (lst: T[]) => T[];\n /**\n * Encode one field value into fixed-width bytes.\n * Callers that need canonical encodings MUST supply a valid field element.\n * Low-level protocols may also use this to serialize raw / non-canonical residues.\n * @param num - Input value.\n * @returns Fixed-width byte encoding.\n */\n toBytes(num: T): Uint8Array;\n /**\n * Decode one field value from fixed-width bytes.\n * @param bytes - Fixed-width byte encoding.\n * @param skipValidation - Whether to skip range validation.\n * Implementations MUST treat `bytes` as read-only.\n * @returns Decoded field value.\n */\n fromBytes(bytes: Uint8Array, skipValidation?: boolean): T;\n // If c is False, CMOV returns a, otherwise it returns b.\n /**\n * Constant-time conditional move.\n * @param a - Value used when the condition is false.\n * @param b - Value used when the condition is true.\n * @param c - Selection bit.\n * @returns Selected value.\n */\n cmov(a: T, b: T, c: boolean): T;\n}\n// prettier-ignore\n// Arithmetic-only subset checked by validateField(). This is intentionally not the full runtime\n// IField contract: helpers like `isValidNot0`, `invertBatch`, `toBytes`, `fromBytes`, `cmov`, and\n// field-specific extras like `isOdd` are left to the callers that actually need them.\nconst FIELD_FIELDS = [\n 'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',\n 'eql', 'add', 'sub', 'mul', 'pow', 'div',\n 'addN', 'subN', 'mulN', 'sqrN'\n] as const;\n/**\n * @param field - Field implementation.\n * @returns Validated field. This only checks the arithmetic subset needed by generic helpers; it\n * does not guarantee full runtime-method coverage for serialization, batching, `cmov`, or\n * field-specific extras beyond positive `BYTES` / `BITS`.\n * @throws If the field shape or numeric metadata are invalid. {@link Error}\n * @example\n * Check that a field implementation exposes the operations curve code expects.\n *\n * ```ts\n * import { Field, validateField } from '@noble/curves/abstract/modular.js';\n * const Fp = validateField(Field(17n));\n * ```\n */\nexport function validateField<T>(field: TArg<IField<T>>): TRet<IField<T>> {\n const initial = {\n ORDER: 'bigint',\n BYTES: 'number',\n BITS: 'number',\n } as Record<string, string>;\n const opts = FIELD_FIELDS.reduce((map, val: string) => {\n map[val] = 'function';\n return map;\n }, initial);\n validateObject(field, opts);\n // Runtime field implementations must expose real integer byte/bit sizes; fractional / NaN /\n // infinite metadata leaks through validateObject(type='number') but breaks encoders and caches.\n asafenumber(field.BYTES, 'BYTES');\n asafenumber(field.BITS, 'BITS');\n // Runtime field implementations must expose positive byte/bit sizes; zero leaks through the\n // numeric shape checks above but still breaks encoding helpers and cached-length assumptions.\n if (field.BYTES < 1 || field.BITS < 1) throw new Error('invalid field: expected BYTES/BITS > 0');\n if (field.ORDER <= _1n) throw new Error('invalid field: expected ORDER > 1, got ' + field.ORDER);\n return field as TRet<IField<T>>;\n}\n\n// Generic field functions\n\n/**\n * Same as `pow` but for Fp: non-constant-time.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n * @param Fp - Field implementation.\n * @param num - Base value.\n * @param power - Exponent value.\n * @returns Powered field element.\n * @throws If the exponent is negative. {@link Error}\n * @example\n * Raise one field element to a public exponent.\n *\n * ```ts\n * import { Field, FpPow } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const x = FpPow(Fp, 3n, 5n);\n * ```\n */\nexport function FpPow<T>(Fp: TArg<IField<T>>, num: T, power: bigint): T {\n const F = Fp as IField<T>;\n if (power < _0n) throw new Error('invalid exponent, negatives unsupported');\n if (power === _0n) return F.ONE;\n if (power === _1n) return num;\n let p = F.ONE;\n let d = num;\n while (power > _0n) {\n if (power & _1n) p = F.mul(p, d);\n d = F.sqr(d);\n power >>= _1n;\n }\n return p;\n}\n\n/**\n * Efficiently invert an array of Field elements.\n * Exception-free. Zero-valued field elements stay `undefined` unless `passZero` is enabled.\n * @param Fp - Field implementation.\n * @param nums - Values to invert.\n * @param passZero - map 0 to 0 (instead of undefined)\n * @returns Inverted values.\n * @example\n * Invert several field elements with one shared inversion.\n *\n * ```ts\n * import { Field, FpInvertBatch } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const inv = FpInvertBatch(Fp, [1n, 2n, 4n]);\n * ```\n */\nexport function FpInvertBatch<T>(Fp: TArg<IField<T>>, nums: T[], passZero = false): T[] {\n const F = Fp as IField<T>;\n const inverted = new Array(nums.length).fill(passZero ? F.ZERO : undefined) as T[];\n // Walk from first to last, multiply them by each other MOD p\n const multipliedAcc = nums.reduce((acc, num, i) => {\n if (F.is0(num)) return acc;\n inverted[i] = acc;\n return F.mul(acc, num);\n }, F.ONE);\n // Invert last element\n const invertedAcc = F.inv(multipliedAcc);\n // Walk from last to first, multiply them by inverted each other MOD p\n nums.reduceRight((acc, num, i) => {\n if (F.is0(num)) return acc;\n inverted[i] = F.mul(acc, inverted[i]);\n return F.mul(acc, num);\n }, invertedAcc);\n return inverted;\n}\n\n/**\n * @param Fp - Field implementation.\n * @param lhs - Dividend value.\n * @param rhs - Divisor value.\n * @returns Division result.\n * @throws If the divisor is non-invertible. {@link Error}\n * @example\n * Divide one field element by another.\n *\n * ```ts\n * import { Field, FpDiv } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const x = FpDiv(Fp, 6n, 3n);\n * ```\n */\nexport function FpDiv<T>(Fp: TArg<IField<T>>, lhs: T, rhs: T | bigint): T {\n const F = Fp as IField<T>;\n return F.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, F.ORDER) : F.inv(rhs));\n}\n\n/**\n * Legendre symbol.\n * Legendre constant is used to calculate Legendre symbol (a | p)\n * which denotes the value of a^((p-1)/2) (mod p).\n *\n * * (a | p) ≡ 1 if a is a square (mod p), quadratic residue\n * * (a | p) ≡ -1 if a is not a square (mod p), quadratic non residue\n * * (a | p) ≡ 0 if a ≡ 0 (mod p)\n * @param Fp - Field implementation.\n * @param n - Value to inspect.\n * @returns Legendre symbol.\n * @throws If the field returns an invalid Legendre symbol value. {@link Error}\n * @example\n * Compute the Legendre symbol of one field element.\n *\n * ```ts\n * import { Field, FpLegendre } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const symbol = FpLegendre(Fp, 4n);\n * ```\n */\nexport function FpLegendre<T>(Fp: TArg<IField<T>>, n: T): -1 | 0 | 1 {\n const F = Fp as IField<T>;\n // We can use 3rd argument as optional cache of this value\n // but seems unneeded for now. The operation is very fast.\n const p1mod2 = (F.ORDER - _1n) / _2n;\n const powered = F.pow(n, p1mod2);\n const yes = F.eql(powered, F.ONE);\n const zero = F.eql(powered, F.ZERO);\n const no = F.eql(powered, F.neg(F.ONE));\n if (!yes && !zero && !no) throw new Error('invalid Legendre symbol result');\n return yes ? 1 : zero ? 0 : -1;\n}\n\n/**\n * @param Fp - Field implementation.\n * @param n - Value to inspect.\n * @returns `true` when `Fp.sqrt(n)` exists. This includes `0`, even though strict \"quadratic\n * residue\" terminology often reserves that name for the non-zero square class.\n * @throws If the field returns an invalid Legendre symbol value. {@link Error}\n * @example\n * Check whether one field element has a square root in the field.\n *\n * ```ts\n * import { Field, FpIsSquare } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const isSquare = FpIsSquare(Fp, 4n);\n * ```\n */\nexport function FpIsSquare<T>(Fp: TArg<IField<T>>, n: T): boolean {\n const l = FpLegendre(Fp as IField<T>, n);\n // Zero is a square too: 0 = 0^2, and Fp.sqrt(0) already returns 0.\n return l !== -1;\n}\n\n/** Byte and bit lengths derived from one scalar order. */\nexport type NLength = {\n /** Canonical byte length. */\n nByteLength: number;\n /** Canonical bit length. */\n nBitLength: number;\n};\n/**\n * @param n - Curve order. Callers are expected to pass a positive order.\n * @param nBitLength - Optional cached bit length. Callers are expected to pass a positive cached\n * value when overriding the derived bit length.\n * @returns Byte and bit lengths.\n * @throws If the order or cached bit length is invalid. {@link Error}\n * @example\n * Measure the encoding sizes needed for one modulus.\n *\n * ```ts\n * nLength(255n);\n * ```\n */\nexport function nLength(n: bigint, nBitLength?: number): NLength {\n // Bit size, byte size of CURVE.n\n if (nBitLength !== undefined) anumber(nBitLength);\n if (n <= _0n) throw new Error('invalid n length: expected positive n, got ' + n);\n if (nBitLength !== undefined && nBitLength < 1)\n throw new Error('invalid n length: expected positive bit length, got ' + nBitLength);\n const bits = bitLen(n);\n // Cached bit lengths smaller than ORDER would truncate serialized scalars/elements and poison\n // any math that relies on the derived field metadata.\n if (nBitLength !== undefined && nBitLength < bits)\n throw new Error(`invalid n length: expected bit length (${bits}) >= n.length (${nBitLength})`);\n const _nBitLength = nBitLength !== undefined ? nBitLength : bits;\n const nByteLength = Math.ceil(_nBitLength / 8);\n return { nBitLength: _nBitLength, nByteLength };\n}\n\ntype FpField = IField<bigint> & Required<Pick<IField<bigint>, 'isOdd'>>;\ntype SqrtFn = (n: bigint) => bigint;\ntype FieldOpts = Partial<{\n isLE: boolean;\n BITS: number;\n sqrt: SqrtFn;\n allowedLengths?: readonly number[]; // for P521 (adds padding for smaller sizes); must stay > 0\n modFromBytes: boolean; // bls12-381 requires mod(n) instead of rejecting keys >= n\n}>;\n// Keep the lazy sqrt cache off-instance so Field(...) can return a frozen object. Otherwise the\n// cached helper write would keep the field surface externally mutable.\nconst FIELD_SQRT = new WeakMap<object, ReturnType<typeof FpSqrt>>();\nclass _Field implements IField<bigint> {\n readonly ORDER: bigint;\n readonly BITS: number;\n readonly BYTES: number;\n readonly isLE: boolean;\n readonly ZERO = _0n;\n readonly ONE = _1n;\n readonly _lengths?: readonly number[];\n private readonly _mod?: boolean;\n constructor(ORDER: bigint, opts: FieldOpts = {}) {\n // ORDER <= 1 is degenerate: ONE would not be a valid field element and helpers like pow/inv\n // would stop modeling field arithmetic.\n if (ORDER <= _1n) throw new Error('invalid field: expected ORDER > 1, got ' + ORDER);\n let _nbitLength: number | undefined = undefined;\n this.isLE = false;\n if (opts != null && typeof opts === 'object') {\n // Cached bit lengths are trusted here and should already be positive / consistent with ORDER.\n if (typeof opts.BITS === 'number') _nbitLength = opts.BITS;\n if (typeof opts.sqrt === 'function')\n // `_Field.prototype` is frozen below, so custom sqrt hooks must become own properties\n // explicitly instead of relying on writable prototype shadowing via assignment.\n Object.defineProperty(this, 'sqrt', { value: opts.sqrt, enumerable: true });\n if (typeof opts.isLE === 'boolean') this.isLE = opts.isLE;\n if (opts.allowedLengths) this._lengths = Object.freeze(opts.allowedLengths.slice());\n if (typeof opts.modFromBytes === 'boolean') this._mod = opts.modFromBytes;\n }\n const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);\n if (nByteLength > 2048) throw new Error('invalid field: expected ORDER of <= 2048 bytes');\n this.ORDER = ORDER;\n this.BITS = nBitLength;\n this.BYTES = nByteLength;\n Object.freeze(this);\n }\n\n create(num: bigint) {\n return mod(num, this.ORDER);\n }\n isValid(num: bigint) {\n if (typeof num !== 'bigint')\n throw new TypeError('invalid field element: expected bigint, got ' + typeof num);\n return _0n <= num && num < this.ORDER; // 0 is valid element, but it's not invertible\n }\n is0(num: bigint) {\n return num === _0n;\n }\n // is valid and invertible\n isValidNot0(num: bigint) {\n return !this.is0(num) && this.isValid(num);\n }\n isOdd(num: bigint) {\n return (num & _1n) === _1n;\n }\n neg(num: bigint) {\n return mod(-num, this.ORDER);\n }\n eql(lhs: bigint, rhs: bigint) {\n return lhs === rhs;\n }\n\n sqr(num: bigint) {\n return mod(num * num, this.ORDER);\n }\n add(lhs: bigint, rhs: bigint) {\n return mod(lhs + rhs, this.ORDER);\n }\n sub(lhs: bigint, rhs: bigint) {\n return mod(lhs - rhs, this.ORDER);\n }\n mul(lhs: bigint, rhs: bigint) {\n return mod(lhs * rhs, this.ORDER);\n }\n pow(num: bigint, power: bigint): bigint {\n return FpPow(this, num, power);\n }\n div(lhs: bigint, rhs: bigint) {\n return mod(lhs * invert(rhs, this.ORDER), this.ORDER);\n }\n\n // Same as above, but doesn't normalize\n sqrN(num: bigint) {\n return num * num;\n }\n addN(lhs: bigint, rhs: bigint) {\n return lhs + rhs;\n }\n subN(lhs: bigint, rhs: bigint) {\n return lhs - rhs;\n }\n mulN(lhs: bigint, rhs: bigint) {\n return lhs * rhs;\n }\n\n inv(num: bigint) {\n return invert(num, this.ORDER);\n }\n sqrt(num: bigint): bigint {\n // Caching sqrt helpers speeds up sqrt9mod16 by 5x and Tonelli-Shanks by about 10% without keeping\n // the field instance itself mutable.\n let sqrt = FIELD_SQRT.get(this);\n if (!sqrt) FIELD_SQRT.set(this, (sqrt = FpSqrt(this.ORDER)));\n return sqrt(this, num);\n }\n toBytes(num: bigint) {\n // Serialize fixed-width limbs without re-validating the field range. Callers that need a\n // canonical encoding must pass a valid element; some protocols intentionally serialize raw\n // residues here and reduce or validate them elsewhere.\n return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);\n }\n fromBytes(bytes: Uint8Array, skipValidation = false) {\n abytes(bytes);\n const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;\n if (allowedLengths) {\n // `allowedLengths` must list real positive byte lengths; otherwise empty input would get\n // padded into zero and silently decode as a field element.\n if (bytes.length < 1 || !allowedLengths.includes(bytes.length) || bytes.length > BYTES) {\n throw new Error(\n 'Field.fromBytes: expected ' + allowedLengths + ' bytes, got ' + bytes.length\n );\n }\n const padded = new Uint8Array(BYTES);\n // isLE add 0 to right, !isLE to the left.\n padded.set(bytes, isLE ? 0 : padded.length - bytes.length);\n bytes = padded;\n }\n if (bytes.length !== BYTES)\n throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);\n let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n if (modFromBytes) scalar = mod(scalar, ORDER);\n if (!skipValidation)\n if (!this.isValid(scalar))\n throw new Error('invalid field element: outside of range 0..ORDER');\n // Range validation is optional here because some protocols intentionally decode raw residues\n // and reduce or validate them elsewhere.\n return scalar;\n }\n // TODO: we don't need it here, move out to separate fn\n invertBatch(lst: bigint[]): bigint[] {\n return FpInvertBatch(this, lst);\n }\n // We can't move this out because Fp6, Fp12 implement it\n // and it's unclear what to return in there.\n cmov(a: bigint, b: bigint, condition: boolean) {\n // Field elements have `isValid(...)`; the CMOV branch bit is a direct runtime input, so reject\n // non-boolean selectors here instead of letting JS truthiness silently change arithmetic.\n abool(condition, 'condition');\n return condition ? b : a;\n }\n}\n// Freeze the shared method surface too; otherwise callers can still poison every Field instance by\n// monkey-patching `_Field.prototype` even if each instance is frozen.\nObject.freeze(_Field.prototype);\n\n/**\n * Creates a finite field. Major performance optimizations:\n * * 1. Denormalized operations like mulN instead of mul.\n * * 2. Identical object shape: never add or remove keys.\n * * 3. Frozen stable object shape; the lazy sqrt cache lives in a module-level `WeakMap`.\n * Fragile: always run a benchmark on a change.\n * Security note: operations and low-level serializers like `toBytes` don't check `isValid` for\n * all elements for performance and protocol-flexibility reasons; callers are responsible for\n * supplying valid elements when they need canonical field behavior.\n * This is low-level code, please make sure you know what you're doing.\n *\n * Note about field properties:\n * * CHARACTERISTIC p = prime number, number of elements in main subgroup.\n * * ORDER q = similar to cofactor in curves, may be composite `q = p^m`.\n *\n * @param ORDER - field order, probably prime, or could be composite\n * @param opts - Field options such as bit length or endianness. See {@link FieldOpts}.\n * @returns Frozen field instance with a stable object shape. This wrapper forwards `opts` straight\n * into `_Field`, so it inherits `_Field`'s assumptions about cached sizes and `allowedLengths`.\n * @example\n * Construct one prime field with optional overrides.\n *\n * ```ts\n * Field(11n);\n * ```\n */\nexport function Field(ORDER: bigint, opts: FieldOpts = {}): TRet<Readonly<FpField>> {\n return new _Field(ORDER, opts);\n}\n\n// Generic random scalar, we can do same for other fields if via Fp2.mul(Fp2.ONE, Fp2.random)?\n// This allows unsafe methods like ignore bias or zero. These unsafe, but often used in different protocols (if deterministic RNG).\n// which mean we cannot force this via opts.\n// Not sure what to do with randomBytes, we can accept it inside opts if wanted.\n// Probably need to export getMinHashLength somewhere?\n// random(bytes?: Uint8Array, unsafeAllowZero = false, unsafeAllowBias = false) {\n// const LEN = !unsafeAllowBias ? getMinHashLength(ORDER) : BYTES;\n// if (bytes === undefined) bytes = randomBytes(LEN); // _opts.randomBytes?\n// const num = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n// // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n// const reduced = unsafeAllowZero ? mod(num, ORDER) : mod(num, ORDER - _1n) + _1n;\n// return reduced;\n// },\n\n/**\n * @param Fp - Field implementation.\n * @param elm - Value to square-root.\n * @returns Odd square root when two roots exist. The special case `elm = 0` still returns `0`,\n * which is the only square root but is not odd.\n * @throws If the field lacks oddness checks or the square root does not exist. {@link Error}\n * @example\n * Select the odd square root when two roots exist.\n *\n * ```ts\n * import { Field, FpSqrtOdd } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const root = FpSqrtOdd(Fp, 4n);\n * ```\n */\nexport function FpSqrtOdd<T>(Fp: TArg<IField<T>>, elm: T): T {\n const F = Fp as IField<T>;\n if (!F.isOdd) throw new Error(\"Field doesn't have isOdd\");\n const root = F.sqrt(elm);\n return F.isOdd(root) ? root : F.neg(root);\n}\n\n/**\n * @param Fp - Field implementation.\n * @param elm - Value to square-root.\n * @returns Even square root.\n * @throws If the field lacks oddness checks or the square root does not exist. {@link Error}\n * @example\n * Select the even square root when two roots exist.\n *\n * ```ts\n * import { Field, FpSqrtEven } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const root = FpSqrtEven(Fp, 4n);\n * ```\n */\nexport function FpSqrtEven<T>(Fp: TArg<IField<T>>, elm: T): T {\n const F = Fp as IField<T>;\n if (!F.isOdd) throw new Error(\"Field doesn't have isOdd\");\n const root = F.sqrt(elm);\n return F.isOdd(root) ? F.neg(root) : root;\n}\n\n/**\n * Returns total number of bytes consumed by the field element.\n * For example, 32 bytes for usual 256-bit weierstrass curve.\n * @param fieldOrder - number of field elements, usually CURVE.n. Callers are expected to pass an\n * order greater than 1.\n * @returns byte length of field\n * @throws If the field order is not a bigint. {@link Error}\n * @example\n * Read the fixed-width byte length of one field.\n *\n * ```ts\n * getFieldBytesLength(255n);\n * ```\n */\nexport function getFieldBytesLength(fieldOrder: bigint): number {\n if (typeof fieldOrder !== 'bigint') throw new Error('field order must be bigint');\n // Valid field elements are in 0..ORDER-1, so ORDER <= 1 would make the encoded range degenerate.\n if (fieldOrder <= _1n) throw new Error('field order must be greater than 1');\n // Valid field elements are < ORDER, so the maximal encoded element is ORDER - 1.\n const bitLength = bitLen(fieldOrder - _1n);\n return Math.ceil(bitLength / 8);\n}\n\n/**\n * Returns minimal amount of bytes that can be safely reduced\n * by field order.\n * Should be 2^-128 for 128-bit curve such as P256.\n * This is the reduction / modulo-bias lower bound; higher-level helpers may still impose a larger\n * absolute floor for policy reasons.\n * @param fieldOrder - number of field elements greater than 1, usually CURVE.n.\n * @returns byte length of target hash\n * @throws If the field order is invalid. {@link Error}\n * @example\n * Compute the minimum hash length needed for field reduction.\n *\n * ```ts\n * getMinHashLength(255n);\n * ```\n */\nexport function getMinHashLength(fieldOrder: bigint): number {\n const length = getFieldBytesLength(fieldOrder);\n return length + Math.ceil(length / 2);\n}\n\n/**\n * \"Constant-time\" private key generation utility.\n * Can take (n + n/2) or more bytes of uniform input e.g. from CSPRNG or KDF\n * and convert them into private scalar, with the modulo bias being negligible.\n * Needs at least 48 bytes of input for 32-byte private key. The implementation also keeps a hard\n * 16-byte minimum even when `getMinHashLength(...)` is smaller, so toy-small inputs do not look\n * accidentally acceptable for real scalar derivation.\n * See {@link https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/ | Kudelski's modulo-bias guide},\n * {@link https://csrc.nist.gov/publications/detail/fips/186/5/final | FIPS 186-5 appendix A.2}, and\n * {@link https://www.rfc-editor.org/rfc/rfc9380#section-5 | RFC 9380 section 5}. Unlike RFC 9380\n * `hash_to_field`, this helper intentionally maps into the non-zero private-scalar range `1..n-1`.\n * @param key - Uniform input bytes.\n * @param fieldOrder - Size of subgroup.\n * @param isLE - interpret hash bytes as LE num\n * @returns valid private scalar\n * @throws If the hash length or field order is invalid for scalar reduction. {@link Error}\n * @example\n * Map hash output into a private scalar range.\n *\n * ```ts\n * mapHashToField(new Uint8Array(48).fill(1), 255n);\n * ```\n */\nexport function mapHashToField(\n key: TArg<Uint8Array>,\n fieldOrder: bigint,\n isLE = false\n): TRet<Uint8Array> {\n abytes(key);\n const len = key.length;\n const fieldLen = getFieldBytesLength(fieldOrder);\n const minLen = Math.max(getMinHashLength(fieldOrder), 16);\n // No toy-small inputs: the helper is for real scalar derivation, not tiny test curves. No huge\n // inputs: easier to reason about JS timing / allocation behavior.\n if (len < minLen || len > 1024)\n throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);\n const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);\n // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n const reduced = mod(num, fieldOrder - _1n) + _1n;\n return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);\n}\n","/**\n * Methods for elliptic curve multiplication by scalars.\n * Contains wNAF, pippenger.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { bitLen, bitMask, validateObject, type Signer, type TArg, type TRet } from '../utils.ts';\nimport { Field, FpInvertBatch, validateField, type IField } from './modular.ts';\n\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _1n = /* @__PURE__ */ BigInt(1);\n\n/** Affine point coordinates without projective fields. */\nexport type AffinePoint<T> = {\n /** Affine x coordinate. */\n x: T;\n /** Affine y coordinate. */\n y: T;\n} & { Z?: never };\n\n// We can't \"abstract out\" coordinates (X, Y, Z; and T in Edwards): argument names of constructor\n// are not accessible. See Typescript gh-56093, gh-41594.\n//\n// We have to use recursive types, so it will return actual point, not constained `CurvePoint`.\n// If, at any point, P is `any`, it will erase all types and replace it\n// with `any`, because of recursion, `any implements CurvePoint`,\n// but we lose all constrains on methods.\n\n/** Base interface for all elliptic-curve point instances. */\nexport interface CurvePoint<F, P extends CurvePoint<F, P>> {\n /** Affine x coordinate. Different from projective / extended X coordinate. */\n x: F;\n /** Affine y coordinate. Different from projective / extended Y coordinate. */\n y: F;\n /** Projective Z coordinate when the point keeps projective state. */\n Z?: F;\n /**\n * Double the point.\n * @returns Doubled point.\n */\n double(): P;\n /**\n * Negate the point.\n * @returns Negated point.\n */\n negate(): P;\n /**\n * Add another point from the same curve.\n * @param other - Point to add.\n * @returns Sum point.\n */\n add(other: P): P;\n /**\n * Subtract another point from the same curve.\n * @param other - Point to subtract.\n * @returns Difference point.\n */\n subtract(other: P): P;\n /**\n * Compare two points for equality.\n * @param other - Point to compare.\n * @returns Whether the points are equal.\n */\n equals(other: P): boolean;\n /**\n * Multiply the point by a scalar in constant time.\n * Implementations keep the subgroup-scalar contract strict and may reject\n * `0` instead of returning the identity point.\n * @param scalar - Scalar multiplier.\n * @returns Product point.\n */\n multiply(scalar: bigint): P;\n /** Assert that the point satisfies the curve equation and subgroup checks. */\n assertValidity(): void;\n /**\n * Map the point into the prime-order subgroup when the curve requires it.\n * @returns Prime-order point.\n */\n clearCofactor(): P;\n /**\n * Check whether the point is the point at infinity.\n * @returns Whether the point is zero.\n */\n is0(): boolean;\n /**\n * Check whether the point belongs to the prime-order subgroup.\n * @returns Whether the point is torsion-free.\n */\n isTorsionFree(): boolean;\n /**\n * Check whether the point lies in a small torsion subgroup.\n * @returns Whether the point has small order.\n */\n isSmallOrder(): boolean;\n /**\n * Multiply the point by a scalar without constant-time guarantees.\n * Public-scalar callers that need `0` should use this method instead of\n * relying on `multiply(...)` to return the identity point.\n * @param scalar - Scalar multiplier.\n * @returns Product point.\n */\n multiplyUnsafe(scalar: bigint): P;\n /**\n * Massively speeds up `p.multiply(n)` by using precompute tables (caching). See {@link wNAF}.\n * Cache state lives in internal WeakMaps keyed by point identity, not on the point object.\n * Repeating `precompute(...)` for the same point identity replaces the remembered window size\n * and forces table regeneration for that point.\n * @param windowSize - Precompute window size.\n * @param isLazy - calculate cache now. Default (true) ensures it's deferred to first `multiply()`\n * @returns Same point instance with precompute tables attached.\n */\n precompute(windowSize?: number, isLazy?: boolean): P;\n /**\n * Converts point to 2D xy affine coordinates.\n * @param invertedZ - Optional inverted Z coordinate for batch normalization.\n * @returns Affine x/y coordinates.\n */\n toAffine(invertedZ?: F): AffinePoint<F>;\n /**\n * Encode the point into the curve's canonical byte form.\n * @returns Encoded point bytes.\n */\n toBytes(): Uint8Array;\n /**\n * Encode the point into the curve's canonical hex form.\n * @returns Encoded point hex.\n */\n toHex(): string;\n}\n\n/** Base interface for elliptic-curve point constructors. */\nexport interface CurvePointCons<P extends CurvePoint<any, P>> {\n /**\n * Runtime brand check for points created by this constructor.\n * @param item - Value to test.\n * @returns Whether the value is a point from this constructor.\n */\n [Symbol.hasInstance]: (item: unknown) => boolean;\n /** Canonical subgroup generator. */\n BASE: P;\n /** Point at infinity. */\n ZERO: P;\n /** Field for basic curve math */\n Fp: IField<P_F<P>>;\n /** Scalar field, for scalars in multiply and others */\n Fn: IField<bigint>;\n /**\n * Create one point from affine coordinates.\n * Does NOT validate curve, subgroup, or wrapper invariants.\n * Use `.assertValidity()` on adversarial inputs.\n * @param p - Affine point coordinates.\n * @returns Point instance.\n */\n fromAffine(p: AffinePoint<P_F<P>>): P;\n /**\n * Decode a point from the canonical byte encoding.\n * @param bytes - Encoded point bytes.\n * Implementations MUST treat `bytes` as read-only.\n * @returns Point instance.\n */\n fromBytes(bytes: Uint8Array): P;\n /**\n * Decode a point from the canonical hex encoding.\n * @param hex - Encoded point hex.\n * @returns Point instance.\n */\n fromHex(hex: string): P;\n}\n\n// Type inference helpers: PC - PointConstructor, P - Point, Fp - Field element\n// Short names, because we use them a lot in result types:\n// * we can't do 'P = GetCurvePoint<PC>': this is default value and doesn't constrain anything\n// * we can't do 'type X = GetCurvePoint<PC>': it won't be accesible for arguments/return types\n// * `CurvePointCons<P extends CurvePoint<any, P>>` constraints from interface definition\n// won't propagate, if `PC extends CurvePointCons<any>`: the P would be 'any', which is incorrect\n// * PC could be super specific with super specific P, which implements CurvePoint<any, P>.\n// this means we need to do stuff like\n// `function test<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(`\n// if we want type safety around P, otherwise PC_P<PC> will be any\n\n/** Returns the affine field type for a point instance (`P_F<P> == P.F`). */\nexport type P_F<P extends CurvePoint<any, P>> = P extends CurvePoint<infer F, P> ? F : never;\n/** Returns the affine field type for a point constructor (`PC_F<PC> == PC.P.F`). */\nexport type PC_F<PC extends CurvePointCons<CurvePoint<any, any>>> = PC['Fp']['ZERO'];\n/** Returns the point instance type for a point constructor (`PC_P<PC> == PC.P`). */\nexport type PC_P<PC extends CurvePointCons<CurvePoint<any, any>>> = PC['ZERO'];\n\n// Ugly hack to get proper type inference, because in typescript fails to infer resursively.\n// The hack allows to do up to 10 chained operations without applying type erasure.\n//\n// Types which won't work:\n// * `CurvePointCons<CurvePoint<any, any>>`, will return `any` after 1 operation\n// * `CurvePointCons<any>: WeierstrassPointCons<bigint> extends CurvePointCons<any> = false`\n// * `P extends CurvePoint, PC extends CurvePointCons<P>`\n// * It can't infer P from PC alone\n// * Too many relations between F, P & PC\n// * It will infer P/F if `arg: CurvePointCons<F, P>`, but will fail if PC is generic\n// * It will work correctly if there is an additional argument of type P\n// * But generally, we don't want to parametrize `CurvePointCons` over `F`: it will complicate\n// types, making them un-inferable\n// prettier-ignore\n/** Wide point-constructor type used when the concrete curve is not important. */\nexport type PC_ANY = CurvePointCons<\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any, any>\n >>>>>>>>>\n>;\n\n/**\n * Validates the static surface of a point constructor.\n * This is only a cheap sanity check for the constructor hooks and fields consumed by generic\n * factories; it does not certify `BASE`/`ZERO` semantics or prove the curve implementation itself.\n * @param Point - Runtime point constructor.\n * @throws On missing constructor hooks or malformed field metadata. {@link TypeError}\n * @example\n * Check that one point constructor exposes the static hooks generic helpers need.\n *\n * ```ts\n * import { ed25519 } from '@noble/curves/ed25519.js';\n * import { validatePointCons } from '@noble/curves/abstract/curve.js';\n * validatePointCons(ed25519.Point);\n * ```\n */\nexport function validatePointCons<P extends CurvePoint<any, P>>(Point: CurvePointCons<P>): void {\n const pc = Point as unknown as CurvePointCons<any>;\n if (typeof (pc as unknown) !== 'function') throw new TypeError('Point must be a constructor');\n // validateObject only accepts plain objects, so copy the constructor statics into one bag first.\n validateObject(\n {\n Fp: pc.Fp,\n Fn: pc.Fn,\n fromAffine: pc.fromAffine,\n fromBytes: pc.fromBytes,\n fromHex: pc.fromHex,\n },\n {\n Fp: 'object',\n Fn: 'object',\n fromAffine: 'function',\n fromBytes: 'function',\n fromHex: 'function',\n }\n );\n validateField(pc.Fp);\n validateField(pc.Fn);\n}\n\n/** Byte lengths used by one curve implementation. */\nexport interface CurveLengths {\n /** Secret-key length in bytes. */\n secretKey?: number;\n /** Compressed public-key length in bytes. */\n publicKey?: number;\n /** Uncompressed public-key length in bytes. */\n publicKeyUncompressed?: number;\n /** Whether public-key encodings include a format prefix byte. */\n publicKeyHasPrefix?: boolean;\n /** Signature length in bytes. */\n signature?: number;\n /** Seed length in bytes when the curve exposes deterministic keygen from seed. */\n seed?: number;\n}\n\n/** Reorders or otherwise remaps a batch while preserving its element type. */\nexport type Mapper<T> = (i: T[]) => T[];\n\n/**\n * Computes both candidates first, but the final selection still branches on `condition`, so this\n * is not a strict constant-time CMOV primitive.\n * @param condition - Whether to negate the point.\n * @param item - Point-like value.\n * @returns Original or negated value.\n * @example\n * Keep the point or return its negation based on one boolean branch.\n *\n * ```ts\n * import { negateCt } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const maybeNegated = negateCt(true, p256.Point.BASE);\n * ```\n */\nexport function negateCt<T extends { negate: () => T }>(condition: boolean, item: T): T {\n const neg = item.negate();\n return condition ? neg : item;\n}\n\n/**\n * Takes a bunch of Projective Points but executes only one\n * inversion on all of them. Inversion is very slow operation,\n * so this improves performance massively.\n * Optimization: converts a list of projective points to a list of identical points with Z=1.\n * Input points are left unchanged; the normalized points are returned as fresh instances.\n * @param c - Point constructor.\n * @param points - Projective points.\n * @returns Fresh projective points reconstructed from normalized affine coordinates.\n * @example\n * Batch-normalize projective points with a single shared inversion.\n *\n * ```ts\n * import { normalizeZ } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const points = normalizeZ(p256.Point, [p256.Point.BASE, p256.Point.BASE.double()]);\n * ```\n */\nexport function normalizeZ<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n c: PC,\n points: P[]\n): P[] {\n const invertedZs = FpInvertBatch(\n c.Fp,\n points.map((p) => p.Z!)\n );\n return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));\n}\n\nfunction validateW(W: number, bits: number) {\n if (!Number.isSafeInteger(W) || W <= 0 || W > bits)\n throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);\n}\n\n/** Internal wNAF opts for specific W and scalarBits.\n * Zero digits are skipped, so tables store only the positive half-window and callers reserve one\n * extra carry window.\n */\ntype WOpts = {\n windows: number;\n windowSize: number;\n mask: bigint;\n maxNumber: number;\n shiftBy: bigint;\n};\n\nfunction calcWOpts(W: number, scalarBits: number): WOpts {\n validateW(W, scalarBits);\n const windows = Math.ceil(scalarBits / W) + 1; // W=8 33. Not 32, because we skip zero\n const windowSize = 2 ** (W - 1); // W=8 128. Not 256, because we skip zero\n const maxNumber = 2 ** W; // W=8 256\n const mask = bitMask(W); // W=8 255 == mask 0b11111111\n const shiftBy = BigInt(W); // W=8 8\n return { windows, windowSize, mask, maxNumber, shiftBy };\n}\n\nfunction calcOffsets(n: bigint, window: number, wOpts: WOpts) {\n const { windowSize, mask, maxNumber, shiftBy } = wOpts;\n let wbits = Number(n & mask); // extract W bits.\n let nextN = n >> shiftBy; // shift number by W bits.\n\n // What actually happens here:\n // const highestBit = Number(mask ^ (mask >> 1n));\n // let wbits2 = wbits - 1; // skip zero\n // if (wbits2 & highestBit) { wbits2 ^= Number(mask); // (~);\n\n // split if bits > max: +224 => 256-32\n if (wbits > windowSize) {\n // we skip zero, which means instead of `>= size-1`, we do `> size`\n wbits -= maxNumber; // -32, can be maxNumber - wbits, but then we need to set isNeg here.\n nextN += _1n; // +256 (carry)\n }\n const offsetStart = window * windowSize;\n const offset = offsetStart + Math.abs(wbits) - 1; // -1 because we skip zero; ignore when isZero\n const isZero = wbits === 0; // is current window slice a 0?\n const isNeg = wbits < 0; // is current window slice negative?\n const isNegF = window % 2 !== 0; // fake branch noise only\n const offsetF = offsetStart; // fake branch noise only\n return { nextN, offset, isZero, isNeg, isNegF, offsetF };\n}\n\nfunction validateMSMPoints(points: any[], c: any) {\n if (!Array.isArray(points)) throw new Error('array expected');\n points.forEach((p, i) => {\n if (!(p instanceof c)) throw new Error('invalid point at index ' + i);\n });\n}\nfunction validateMSMScalars(scalars: any[], field: any) {\n if (!Array.isArray(scalars)) throw new Error('array of scalars expected');\n scalars.forEach((s, i) => {\n if (!field.isValid(s)) throw new Error('invalid scalar at index ' + i);\n });\n}\n\n// Since points in different groups cannot be equal (different object constructor),\n// we can have single place to store precomputes.\n// Allows to make points frozen / immutable.\nconst pointPrecomputes = new WeakMap<any, any[]>();\nconst pointWindowSizes = new WeakMap<any, number>();\n\nfunction getW(P: any): number {\n // To disable precomputes:\n // return 1;\n // `1` is also the uncached sentinel: use the ladder / non-precomputed path.\n return pointWindowSizes.get(P) || 1;\n}\n\nfunction assert0(n: bigint): void {\n // Internal invariant: a non-zero remainder here means the wNAF window decomposition or loop\n // count is inconsistent, not that the original caller provided a bad scalar.\n if (n !== _0n) throw new Error('invalid wNAF');\n}\n\n/**\n * Elliptic curve multiplication of Point by scalar. Fragile.\n * Table generation takes **30MB of ram and 10ms on high-end CPU**,\n * but may take much longer on slow devices. Actual generation will happen on\n * first call of `multiply()`. By default, `BASE` point is precomputed.\n *\n * Scalars should always be less than curve order: this should be checked inside of a curve itself.\n * Creates precomputation tables for fast multiplication:\n * - private scalar is split by fixed size windows of W bits\n * - every window point is collected from window's table & added to accumulator\n * - since windows are different, same point inside tables won't be accessed more than once per calc\n * - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)\n * - +1 window is neccessary for wNAF\n * - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication\n *\n * TODO: research returning a 2d JS array of windows instead of a single window.\n * This would allow windows to be in different memory locations.\n * @param Point - Point constructor.\n * @param bits - Scalar bit length.\n * @example\n * Elliptic curve multiplication of Point by scalar.\n *\n * ```ts\n * import { wNAF } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const ladder = new wNAF(p256.Point, p256.Point.Fn.BITS);\n * ```\n */\nexport class wNAF<PC extends PC_ANY> {\n private readonly BASE: PC_P<PC>;\n private readonly ZERO: PC_P<PC>;\n private readonly Fn: PC['Fn'];\n readonly bits: number;\n\n // Parametrized with a given Point class (not individual point)\n constructor(Point: PC, bits: number) {\n this.BASE = Point.BASE;\n this.ZERO = Point.ZERO;\n this.Fn = Point.Fn;\n this.bits = bits;\n }\n\n // non-const time multiplication ladder\n _unsafeLadder(elm: PC_P<PC>, n: bigint, p: PC_P<PC> = this.ZERO): PC_P<PC> {\n let d: PC_P<PC> = elm;\n while (n > _0n) {\n if (n & _1n) p = p.add(d);\n d = d.double();\n n >>= _1n;\n }\n return p;\n }\n\n /**\n * Creates a wNAF precomputation window. Used for caching.\n * Default window size is set by `utils.precompute()` and is equal to 8.\n * Number of precomputed points depends on the curve size:\n * 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:\n * - 𝑊 is the window size\n * - 𝑛 is the bitlength of the curve order.\n * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.\n * @param point - Point instance\n * @param W - window size\n * @returns precomputed point tables flattened to a single array\n */\n private precomputeWindow(point: PC_P<PC>, W: number): PC_P<PC>[] {\n const { windows, windowSize } = calcWOpts(W, this.bits);\n const points: PC_P<PC>[] = [];\n let p: PC_P<PC> = point;\n let base = p;\n for (let window = 0; window < windows; window++) {\n base = p;\n points.push(base);\n // i=1, bc we skip 0\n for (let i = 1; i < windowSize; i++) {\n base = base.add(p);\n points.push(base);\n }\n p = base.double();\n }\n return points;\n }\n\n /**\n * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.\n * More compact implementation:\n * https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541\n * @returns real and fake (for const-time) points\n */\n private wNAF(W: number, precomputes: PC_P<PC>[], n: bigint): { p: PC_P<PC>; f: PC_P<PC> } {\n // Scalar should be smaller than field order\n if (!this.Fn.isValid(n)) throw new Error('invalid scalar');\n // Accumulators\n let p = this.ZERO;\n let f = this.BASE;\n // This code was first written with assumption that 'f' and 'p' will never be infinity point:\n // since each addition is multiplied by 2 ** W, it cannot cancel each other. However,\n // there is negate now: it is possible that negated element from low value\n // would be the same as high element, which will create carry into next window.\n // It's not obvious how this can fail, but still worth investigating later.\n const wo = calcWOpts(W, this.bits);\n for (let window = 0; window < wo.windows; window++) {\n // (n === _0n) is handled and not early-exited. isEven and offsetF are used for noise\n const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);\n n = nextN;\n if (isZero) {\n // bits are 0: add garbage to fake point\n // Important part for const-time getPublicKey: add random \"noise\" point to f.\n f = f.add(negateCt(isNegF, precomputes[offsetF]));\n } else {\n // bits are 1: add to result point\n p = p.add(negateCt(isNeg, precomputes[offset]));\n }\n }\n assert0(n);\n // Return both real and fake points so JIT keeps the noise path alive.\n // Known caveat: negate/carry interactions can still drive `f` to infinity even when `p` is not,\n // which weakens the noise path and leaves this only \"less const-time\" by about one bigint mul.\n return { p, f };\n }\n\n /**\n * Implements unsafe EC multiplication using precomputed tables\n * and w-ary non-adjacent form.\n * @param acc - accumulator point to add result of multiplication\n * @returns point\n */\n private wNAFUnsafe(\n W: number,\n precomputes: PC_P<PC>[],\n n: bigint,\n acc: PC_P<PC> = this.ZERO\n ): PC_P<PC> {\n const wo = calcWOpts(W, this.bits);\n for (let window = 0; window < wo.windows; window++) {\n if (n === _0n) break; // Early-exit, skip 0 value\n const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);\n n = nextN;\n if (isZero) {\n // Window bits are 0: skip processing.\n // Move to next window.\n continue;\n } else {\n const item = precomputes[offset];\n acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM\n }\n }\n assert0(n);\n return acc;\n }\n\n private getPrecomputes(W: number, point: PC_P<PC>, transform?: Mapper<PC_P<PC>>): PC_P<PC>[] {\n // Cache key is only point identity plus the remembered window size; callers must not reuse the\n // same point with incompatible `transform(...)` layouts and expect a separate cache entry.\n let comp = pointPrecomputes.get(point);\n if (!comp) {\n comp = this.precomputeWindow(point, W) as PC_P<PC>[];\n if (W !== 1) {\n // Doing transform outside of if brings 15% perf hit\n if (typeof transform === 'function') comp = transform(comp);\n pointPrecomputes.set(point, comp);\n }\n }\n return comp;\n }\n\n cached(\n point: PC_P<PC>,\n scalar: bigint,\n transform?: Mapper<PC_P<PC>>\n ): { p: PC_P<PC>; f: PC_P<PC> } {\n const W = getW(point);\n return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);\n }\n\n unsafe(point: PC_P<PC>, scalar: bigint, transform?: Mapper<PC_P<PC>>, prev?: PC_P<PC>): PC_P<PC> {\n const W = getW(point);\n if (W === 1) return this._unsafeLadder(point, scalar, prev); // For W=1 ladder is ~x2 faster\n return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);\n }\n\n // We calculate precomputes for elliptic curve point multiplication\n // using windowed method. This specifies window size and\n // stores precomputed values. Usually only base point would be precomputed.\n createCache(P: PC_P<PC>, W: number): void {\n validateW(W, this.bits);\n pointWindowSizes.set(P, W);\n pointPrecomputes.delete(P);\n }\n\n hasCache(elm: PC_P<PC>): boolean {\n return getW(elm) !== 1;\n }\n}\n\n/**\n * Endomorphism-specific multiplication for Koblitz curves.\n * Cost: 128 dbl, 0-256 adds.\n * @param Point - Point constructor.\n * @param point - Input point.\n * @param k1 - First non-negative absolute scalar chunk.\n * @param k2 - Second non-negative absolute scalar chunk.\n * @returns Partial multiplication results.\n * @example\n * Endomorphism-specific multiplication for Koblitz curves.\n *\n * ```ts\n * import { mulEndoUnsafe } from '@noble/curves/abstract/curve.js';\n * import { secp256k1 } from '@noble/curves/secp256k1.js';\n * const parts = mulEndoUnsafe(secp256k1.Point, secp256k1.Point.BASE, 3n, 5n);\n * ```\n */\nexport function mulEndoUnsafe<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n Point: PC,\n point: P,\n k1: bigint,\n k2: bigint\n): { p1: P; p2: P } {\n let acc = point;\n let p1 = Point.ZERO;\n let p2 = Point.ZERO;\n while (k1 > _0n || k2 > _0n) {\n if (k1 & _1n) p1 = p1.add(acc);\n if (k2 & _1n) p2 = p2.add(acc);\n acc = acc.double();\n k1 >>= _1n;\n k2 >>= _1n;\n }\n return { p1, p2 };\n}\n\n/**\n * Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n * 30x faster vs naive addition on L=4096, 10x faster than precomputes.\n * For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.\n * Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.\n * @param c - Curve Point constructor\n * @param points - array of L curve points\n * @param scalars - array of L scalars (aka secret keys / bigints)\n * @returns MSM result point. Empty input is accepted and returns the identity.\n * @throws If the point set, scalar set, or MSM sizing is invalid. {@link Error}\n * @example\n * Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n *\n * ```ts\n * import { pippenger } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const point = pippenger(p256.Point, [p256.Point.BASE, p256.Point.BASE.double()], [2n, 3n]);\n * ```\n */\nexport function pippenger<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n c: PC,\n points: P[],\n scalars: bigint[]\n): P {\n // If we split scalars by some window (let's say 8 bits), every chunk will only\n // take 256 buckets even if there are 4096 scalars, also re-uses double.\n // TODO:\n // - https://eprint.iacr.org/2024/750.pdf\n // - https://tches.iacr.org/index.php/TCHES/article/view/10287\n // 0 is accepted in scalars\n const fieldN = c.Fn;\n validateMSMPoints(points, c);\n validateMSMScalars(scalars, fieldN);\n const plength = points.length;\n const slength = scalars.length;\n if (plength !== slength) throw new Error('arrays of points and scalars must have equal length');\n // if (plength === 0) throw new Error('array must be of length >= 2');\n const zero = c.ZERO;\n const wbits = bitLen(BigInt(plength));\n let windowSize = 1; // bits\n if (wbits > 12) windowSize = wbits - 3;\n else if (wbits > 4) windowSize = wbits - 2;\n else if (wbits > 0) windowSize = 2;\n const MASK = bitMask(windowSize);\n const buckets = new Array(Number(MASK) + 1).fill(zero); // +1 for zero array\n const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;\n let sum = zero;\n for (let i = lastBits; i >= 0; i -= windowSize) {\n buckets.fill(zero);\n for (let j = 0; j < slength; j++) {\n const scalar = scalars[j];\n const wbits = Number((scalar >> BigInt(i)) & MASK);\n buckets[wbits] = buckets[wbits].add(points[j]);\n }\n let resI = zero; // not using this will do small speed-up, but will lose ct\n // Skip first bucket, because it is zero\n for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {\n sumI = sumI.add(buckets[j]);\n resI = resI.add(sumI);\n }\n sum = sum.add(resI);\n if (i !== 0) for (let j = 0; j < windowSize; j++) sum = sum.double();\n }\n return sum as P;\n}\n/**\n * Precomputed multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n * @param c - Curve Point constructor\n * @param points - array of L curve points\n * @param windowSize - Precompute window size.\n * @returns Function which multiplies points with scalars. The closure accepts\n * `scalars.length <= points.length`, and omitted trailing scalars are treated as zero.\n * @throws If the point set or precompute window is invalid. {@link Error}\n * @example\n * Precomputed multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n *\n * ```ts\n * import { precomputeMSMUnsafe } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const msm = precomputeMSMUnsafe(p256.Point, [p256.Point.BASE], 4);\n * const point = msm([3n]);\n * ```\n */\nexport function precomputeMSMUnsafe<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n c: PC,\n points: P[],\n windowSize: number\n): (scalars: bigint[]) => P {\n /**\n * Performance Analysis of Window-based Precomputation\n *\n * Base Case (256-bit scalar, 8-bit window):\n * - Standard precomputation requires:\n * - 31 additions per scalar × 256 scalars = 7,936 ops\n * - Plus 255 summary additions = 8,191 total ops\n * Note: Summary additions can be optimized via accumulator\n *\n * Chunked Precomputation Analysis:\n * - Using 32 chunks requires:\n * - 255 additions per chunk\n * - 256 doublings\n * - Total: (255 × 32) + 256 = 8,416 ops\n *\n * Memory Usage Comparison:\n * Window Size | Standard Points | Chunked Points\n * ------------|-----------------|---------------\n * 4-bit | 520 | 15\n * 8-bit | 4,224 | 255\n * 10-bit | 13,824 | 1,023\n * 16-bit | 557,056 | 65,535\n *\n * Key Advantages:\n * 1. Enables larger window sizes due to reduced memory overhead\n * 2. More efficient for smaller scalar counts:\n * - 16 chunks: (16 × 255) + 256 = 4,336 ops\n * - ~2x faster than standard 8,191 ops\n *\n * Limitations:\n * - Not suitable for plain precomputes (requires 256 constant doublings)\n * - Performance degrades with larger scalar counts:\n * - Optimal for ~256 scalars\n * - Less efficient for 4096+ scalars (Pippenger preferred)\n */\n const fieldN = c.Fn;\n validateW(windowSize, fieldN.BITS);\n validateMSMPoints(points, c);\n const zero = c.ZERO;\n const tableSize = 2 ** windowSize - 1; // table size (without zero)\n const chunks = Math.ceil(fieldN.BITS / windowSize); // chunks of item\n const MASK = bitMask(windowSize);\n const tables = points.map((p: P) => {\n const res = [];\n for (let i = 0, acc = p; i < tableSize; i++) {\n res.push(acc);\n acc = acc.add(p);\n }\n return res;\n });\n return (scalars: bigint[]): P => {\n validateMSMScalars(scalars, fieldN);\n if (scalars.length > points.length)\n throw new Error('array of scalars must be smaller than array of points');\n let res = zero;\n for (let i = 0; i < chunks; i++) {\n // No need to double if accumulator is still zero.\n if (res !== zero) for (let j = 0; j < windowSize; j++) res = res.double();\n const shiftBy = BigInt(chunks * windowSize - (i + 1) * windowSize);\n for (let j = 0; j < scalars.length; j++) {\n const n = scalars[j];\n const curr = Number((n >> shiftBy) & MASK);\n if (!curr) continue; // skip zero scalars chunks\n res = res.add(tables[j][curr - 1]);\n }\n }\n return res;\n };\n}\n\n/** Minimal curve parameters needed to construct a Weierstrass or Edwards curve. */\nexport type ValidCurveParams<T> = {\n /** Base-field modulus. */\n p: bigint;\n /** Prime subgroup order. */\n n: bigint;\n /** Cofactor. */\n h: bigint;\n /** Curve parameter `a`. */\n a: T;\n /** Weierstrass curve parameter `b`. */\n b?: T;\n /** Edwards curve parameter `d`. */\n d?: T;\n /** Generator x coordinate. */\n Gx: T;\n /** Generator y coordinate. */\n Gy: T;\n};\n\nfunction createField<T>(order: bigint, field?: TArg<IField<T>>, isLE?: boolean): TRet<IField<T>> {\n if (field) {\n // Reuse supplied field overrides as-is; `isLE` only affects freshly constructed fallback\n // fields, and validateField() below only checks the arithmetic subset, not full byte/cmov\n // behavior.\n if (field.ORDER !== order) throw new Error('Field.ORDER must match order: Fp == p, Fn == n');\n validateField(field);\n return field as TRet<IField<T>>;\n } else {\n return Field(order, { isLE }) as unknown as TRet<IField<T>>;\n }\n}\n/** Pair of fields used by curve constructors. */\nexport type FpFn<T> = {\n /** Base field used for curve coordinates. */\n Fp: IField<T>;\n /** Scalar field used for secret scalars and subgroup arithmetic. */\n Fn: IField<bigint>;\n};\n\n/**\n * Validates basic CURVE shape and field membership, then creates fields.\n * This does not prove that the generator is on-curve, that subgroup/order data are consistent, or\n * that the curve equation itself is otherwise sane.\n * @param type - Curve family.\n * @param CURVE - Curve parameters.\n * @param curveOpts - Optional field overrides:\n * - `Fp` (optional): Optional base-field override.\n * - `Fn` (optional): Optional scalar-field override.\n * @param FpFnLE - Whether field encoding is little-endian.\n * @returns Frozen curve parameters and fields.\n * @throws If the curve parameters or field overrides are invalid. {@link Error}\n * @example\n * Build curve fields from raw constants before constructing a curve instance.\n *\n * ```ts\n * const curve = createCurveFields('weierstrass', {\n * p: 17n,\n * n: 19n,\n * h: 1n,\n * a: 2n,\n * b: 2n,\n * Gx: 5n,\n * Gy: 1n,\n * });\n * ```\n */\nexport function createCurveFields<T>(\n type: 'weierstrass' | 'edwards',\n CURVE: ValidCurveParams<T>,\n curveOpts: TArg<Partial<FpFn<T>>> = {},\n FpFnLE?: boolean\n): TRet<FpFn<T> & { CURVE: ValidCurveParams<T> }> {\n if (FpFnLE === undefined) FpFnLE = type === 'edwards';\n if (!CURVE || typeof CURVE !== 'object') throw new Error(`expected valid ${type} CURVE object`);\n for (const p of ['p', 'n', 'h'] as const) {\n const val = CURVE[p];\n if (!(typeof val === 'bigint' && val > _0n))\n throw new Error(`CURVE.${p} must be positive bigint`);\n }\n const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);\n const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);\n const _b: 'b' | 'd' = type === 'weierstrass' ? 'b' : 'd';\n const params = ['Gx', 'Gy', 'a', _b] as const;\n for (const p of params) {\n // @ts-ignore\n if (!Fp.isValid(CURVE[p]))\n throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);\n }\n CURVE = Object.freeze(Object.assign({}, CURVE));\n return { CURVE, Fp, Fn } as TRet<FpFn<T> & { CURVE: ValidCurveParams<T> }>;\n}\n\ntype KeygenFn = (\n seed?: Uint8Array,\n isCompressed?: boolean\n) => { secretKey: Uint8Array; publicKey: Uint8Array };\n/**\n * @param randomSecretKey - Secret-key generator.\n * @param getPublicKey - Public-key derivation helper.\n * @returns Keypair generator.\n * @example\n * Build a `keygen()` helper from existing secret-key and public-key primitives.\n *\n * ```ts\n * import { createKeygen } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const keygen = createKeygen(p256.utils.randomSecretKey, p256.getPublicKey);\n * const pair = keygen();\n * ```\n */\nexport function createKeygen(\n randomSecretKey: Function,\n getPublicKey: TArg<Signer['getPublicKey']>\n): TRet<KeygenFn> {\n return function keygen(seed?: TArg<Uint8Array>) {\n const secretKey = randomSecretKey(seed) as TRet<Uint8Array>;\n return { secretKey, publicKey: getPublicKey(secretKey) as TRet<Uint8Array> };\n };\n}\n","/**\n * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport {\n abytes,\n aexists,\n ahash,\n aoutput,\n clean,\n type CHash,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Internal class for HMAC.\n * Accepts any byte key, although RFC 2104 §3 recommends keys at least\n * `HashLen` bytes long.\n */\nexport class _HMAC<T extends Hash<T>> implements Hash<_HMAC<T>> {\n oHash: T;\n iHash: T;\n blockLen: number;\n outputLen: number;\n canXOF = false;\n private finished = false;\n private destroyed = false;\n\n constructor(hash: TArg<CHash>, key: TArg<Uint8Array>) {\n ahash(hash);\n abytes(key, undefined, 'key');\n this.iHash = hash.create() as T;\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of the first block) of the outer hash here,\n // we can re-use it between multiple calls via clone.\n this.oHash = hash.create() as T;\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n clean(pad);\n }\n update(buf: TArg<Uint8Array>): this {\n aexists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const buf = out.subarray(0, this.outputLen);\n // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before\n // overwriting that same prefix with the final tag, leaving any oversized tail untouched.\n this.iHash.digestInto(buf);\n this.oHash.update(buf);\n this.oHash.digestInto(buf);\n this.destroy();\n }\n digest(): TRet<Uint8Array> {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out as TRet<Uint8Array>;\n }\n _cloneInto(to?: _HMAC<T>): _HMAC<T> {\n // Create new instance without calling constructor since the key\n // is already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to as this;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n clone(): _HMAC<T> {\n return this._cloneInto();\n }\n destroy(): void {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - authentication key bytes\n * @param message - message bytes to authenticate\n * @returns Authentication tag bytes.\n * @example\n * Compute an RFC 2104 HMAC.\n * ```ts\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\ntype HmacFn = {\n (hash: TArg<CHash>, key: TArg<Uint8Array>, message: TArg<Uint8Array>): TRet<Uint8Array>;\n create(hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>>;\n};\nexport const hmac: TRet<HmacFn> = /* @__PURE__ */ (() => {\n const hmac_ = ((\n hash: TArg<CHash>,\n key: TArg<Uint8Array>,\n message: TArg<Uint8Array>\n ): TRet<Uint8Array> => new _HMAC<any>(hash, key).update(message).digest()) as TRet<HmacFn>;\n hmac_.create = (hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>> =>\n new _HMAC<any>(hash, key) as TRet<_HMAC<any>>;\n return hmac_;\n})();\n","/**\n * Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.\n *\n * ### Design rationale for types\n *\n * * Interaction between classes from different curves should fail:\n * `k256.Point.BASE.add(p256.Point.BASE)`\n * * For this purpose we want to use `instanceof` operator, which is fast and works during runtime\n * * Different calls of `curve()` would return different classes -\n * `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,\n * it won't affect others\n *\n * TypeScript can't infer types for classes created inside a function. Classes is one instance\n * of nominative types in TypeScript and interfaces only check for shape, so it's hard to create\n * unique type for every function call.\n *\n * We can use generic types via some param, like curve opts, but that would:\n * 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)\n * which is hard to debug.\n * 2. Params can be generic and we can't enforce them to be constant value:\n * if somebody creates curve from non-constant params,\n * it would be allowed to interact with other curves with non-constant params\n *\n * @todo https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { hmac as nobleHmac } from '@noble/hashes/hmac.js';\nimport { ahash } from '@noble/hashes/utils.js';\nimport {\n abignumber,\n abool,\n abytes,\n aInRange,\n asafenumber,\n bitLen,\n bitMask,\n bytesToHex,\n bytesToNumberBE,\n concatBytes,\n createHmacDrbg,\n hexToBytes,\n isBytes,\n numberToHexUnpadded,\n validateObject,\n randomBytes as wcRandomBytes,\n type CHash,\n type HmacFn,\n type Signer,\n type TArg,\n type TRet,\n} from '../utils.ts';\nimport {\n createCurveFields,\n createKeygen,\n mulEndoUnsafe,\n negateCt,\n normalizeZ,\n wNAF,\n type AffinePoint,\n type CurveLengths,\n type CurvePoint,\n type CurvePointCons,\n} from './curve.ts';\nimport {\n FpInvertBatch,\n FpIsSquare,\n getMinHashLength,\n mapHashToField,\n validateField,\n type IField,\n} from './modular.ts';\n\n/** Shared affine point shape used by Weierstrass helpers. */\nexport type { AffinePoint };\n\ntype EndoBasis = [[bigint, bigint], [bigint, bigint]];\n/**\n * When Weierstrass curve has `a=0`, it becomes Koblitz curve.\n * Koblitz curves allow using **efficiently-computable GLV endomorphism ψ**.\n * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.\n * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.\n *\n * Endomorphism consists of beta, lambda and splitScalar:\n *\n * 1. GLV endomorphism ψ transforms a point: `P = (x, y) ↦ ψ(P) = (β·x mod p, y)`\n * 2. GLV scalar decomposition transforms a scalar: `k ≡ k₁ + k₂·λ (mod n)`\n * 3. Then these are combined: `k·P = k₁·P + k₂·ψ(P)`\n * 4. Two 128-bit point-by-scalar multiplications + one point addition is faster than\n * one 256-bit multiplication.\n *\n * where\n * * beta: β ∈ Fₚ with β³ = 1, β ≠ 1\n * * lambda: λ ∈ Fₙ with λ³ = 1, λ ≠ 1\n * * splitScalar decomposes k ↦ k₁, k₂, by using reduced basis vectors.\n * Gauss lattice reduction calculates them from initial basis vectors `(n, 0), (-λ, 0)`\n *\n * Check out `test/misc/endomorphism.js` and\n * {@link https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066 | this endomorphism gist}.\n */\nexport type EndomorphismOpts = {\n /** Cube root of unity used by the GLV endomorphism. */\n beta: bigint;\n /** Reduced lattice basis used for scalar splitting. */\n basises?: EndoBasis;\n /**\n * Optional custom scalar-splitting helper.\n * Receives one scalar and returns two half-sized scalar components.\n */\n splitScalar?: (k: bigint) => { k1neg: boolean; k1: bigint; k2neg: boolean; k2: bigint };\n};\n// We construct the basis so `den` is always positive and equals `n`,\n// but the `num` sign depends on the basis, not on the secret value.\n// Exact half-way cases round away from zero, which keeps the split symmetric\n// around the reduced-basis boundaries used by endomorphism decomposition.\nconst divNearest = (num: bigint, den: bigint) => (num + (num >= 0 ? den : -den) / _2n) / den;\n\n/** Two half-sized scalar components returned by endomorphism splitting. */\nexport type ScalarEndoParts = {\n /** Whether the first split scalar should be negated. */\n k1neg: boolean;\n /** Absolute value of the first split scalar. */\n k1: bigint;\n /** Whether the second split scalar should be negated. */\n k2neg: boolean;\n /** Absolute value of the second split scalar. */\n k2: bigint;\n};\n\n/** Splits scalar for GLV endomorphism. */\nexport function _splitEndoScalar(k: bigint, basis: EndoBasis, n: bigint): ScalarEndoParts {\n // Split scalar into two such that part is ~half bits: `abs(part) < sqrt(N)`\n // Since part can be negative, we need to do this on point.\n // Callers must provide a reduced GLV basis whose vectors satisfy\n // `a + b * lambda ≡ 0 (mod n)`; this helper only sees the basis and `n`.\n // Reject unreduced scalars instead of silently treating them mod n.\n aInRange('scalar', k, _0n, n);\n // TODO: verifyScalar function which consumes lambda\n const [[a1, b1], [a2, b2]] = basis;\n const c1 = divNearest(b2 * k, n);\n const c2 = divNearest(-b1 * k, n);\n // |k1|/|k2| is < sqrt(N), but can be negative.\n // If we do `k1 mod N`, we'll get big scalar (`> sqrt(N)`): so, we do cheaper negation instead.\n let k1 = k - c1 * a1 - c2 * a2;\n let k2 = -c1 * b1 - c2 * b2;\n const k1neg = k1 < _0n;\n const k2neg = k2 < _0n;\n if (k1neg) k1 = -k1;\n if (k2neg) k2 = -k2;\n // Double check that resulting scalar less than half bits of N: otherwise wNAF will fail.\n // This should only happen on wrong bases.\n // Also, the math inside is complex enough that this guard is worth keeping.\n const MAX_NUM = bitMask(Math.ceil(bitLen(n) / 2)) + _1n; // Half bits of N\n if (k1 < _0n || k1 >= MAX_NUM || k2 < _0n || k2 >= MAX_NUM) {\n throw new Error('splitScalar (endomorphism): failed for k');\n }\n return { k1neg, k1, k2neg, k2 };\n}\n\n/**\n * Option to enable hedged signatures with improved security.\n *\n * * Randomly generated k is bad, because broken CSPRNG would leak private keys.\n * * Deterministic k (RFC6979) is better; but is suspectible to fault attacks.\n *\n * We allow using technique described in RFC6979 3.6: additional k', a.k.a. adding randomness\n * to deterministic sig. If CSPRNG is broken & randomness is weak, it would STILL be as secure\n * as ordinary sig without ExtraEntropy.\n *\n * * `true` means \"fetch data, from CSPRNG, incorporate it into k generation\"\n * * `false` means \"disable extra entropy, use purely deterministic k\"\n * * `Uint8Array` passed means \"incorporate following data into k generation\"\n *\n * See {@link https://paulmillr.com/posts/deterministic-signatures/ | deterministic signatures}.\n */\nexport type ECDSAExtraEntropy = boolean | Uint8Array;\n/**\n * - `compact` is the default format\n * - `recovered` is the same as compact, but with an extra byte indicating recovery byte\n * - `der` is ASN.1 DER encoding\n */\nexport type ECDSASignatureFormat = 'compact' | 'recovered' | 'der';\n/**\n * - `prehash`: (default: true) indicates whether to do sha256(message).\n * When a custom hash is used, it must be set to `false`.\n */\nexport type ECDSARecoverOpts = {\n /** Whether to hash the message before signature recovery. */\n prehash?: boolean;\n};\n/**\n * - `prehash`: (default: true) indicates whether to do sha256(message).\n * When a custom hash is used, it must be set to `false`.\n * - `lowS`: (default: true) prohibits signatures with `sig.s >= CURVE.n/2n`.\n * Compatible with BTC/ETH. Setting `lowS: false` allows to create malleable signatures,\n * which is default openssl behavior.\n * Non-malleable signatures can still be successfully verified in openssl.\n * - `format`: (default: 'compact') 'compact' or 'recovered' with recovery byte\n */\nexport type ECDSAVerifyOpts = {\n /** Whether to hash the message before verification. */\n prehash?: boolean;\n /** Whether to reject high-S signatures. */\n lowS?: boolean;\n /** Signature encoding to accept. */\n format?: ECDSASignatureFormat;\n};\n/**\n * - `prehash`: (default: true) indicates whether to do sha256(message).\n * When a custom hash is used, it must be set to `false`.\n * - `lowS`: (default: true) prohibits signatures with `sig.s >= CURVE.n/2n`.\n * Compatible with BTC/ETH. Setting `lowS: false` allows to create malleable signatures,\n * which is default openssl behavior.\n * Non-malleable signatures can still be successfully verified in openssl.\n * - `format`: (default: 'compact') 'compact' or 'recovered' with recovery byte\n * - `extraEntropy`: (default: false) creates signatures with increased\n * security, see {@link ECDSAExtraEntropy}\n */\nexport type ECDSASignOpts = {\n /** Whether to hash the message before signing. */\n prehash?: boolean;\n /** Whether to normalize signatures into the low-S half-order. */\n lowS?: boolean;\n /** Signature encoding to produce. */\n format?: ECDSASignatureFormat;\n /** Optional hedging input for deterministic k generation. */\n extraEntropy?: ECDSAExtraEntropy;\n};\n\nfunction validateSigFormat(format: string): ECDSASignatureFormat {\n if (!['compact', 'recovered', 'der'].includes(format))\n throw new Error('Signature format must be \"compact\", \"recovered\", or \"der\"');\n return format as ECDSASignatureFormat;\n}\n\nfunction validateSigOpts<T extends ECDSASignOpts, D extends Required<ECDSASignOpts>>(\n opts: T,\n def: D\n): D {\n validateObject(opts);\n const optsn = {} as D;\n // Normalize only the declared option subset from `def`; unknown keys are\n // intentionally ignored so shared / superset option bags stay valid here too.\n // `extraEntropy` stays an opaque payload until the signing path consumes it.\n for (let optName of Object.keys(def) as (keyof D)[]) {\n // @ts-ignore\n optsn[optName] = opts[optName] === undefined ? def[optName] : opts[optName];\n }\n abool(optsn.lowS!, 'lowS');\n abool(optsn.prehash!, 'prehash');\n if (optsn.format !== undefined) validateSigFormat(optsn.format);\n return optsn;\n}\n\n/** Projective XYZ point used by short Weierstrass curves. */\nexport interface WeierstrassPoint<T> extends CurvePoint<T, WeierstrassPoint<T>> {\n /** projective X coordinate. Different from affine x. */\n readonly X: T;\n /** projective Y coordinate. Different from affine y. */\n readonly Y: T;\n /** projective z coordinate */\n readonly Z: T;\n /** affine x coordinate. Different from projective X. */\n get x(): T;\n /** affine y coordinate. Different from projective Y. */\n get y(): T;\n /**\n * Encode the point into compressed or uncompressed SEC1 bytes.\n * @param isCompressed - Whether to use the compressed form.\n * @returns Encoded point bytes.\n */\n toBytes(isCompressed?: boolean): TRet<Uint8Array>;\n /**\n * Encode the point into compressed or uncompressed SEC1 hex.\n * @param isCompressed - Whether to use the compressed form.\n * @returns Encoded point hex.\n */\n toHex(isCompressed?: boolean): string;\n}\n\n/** Constructor and metadata helpers for Weierstrass points. */\nexport interface WeierstrassPointCons<T> extends CurvePointCons<WeierstrassPoint<T>> {\n /** Does NOT validate if the point is valid. Use `.assertValidity()`. */\n new (X: T, Y: T, Z: T): WeierstrassPoint<T>;\n /**\n * Return the curve parameters captured by this point constructor.\n * @returns Curve parameters.\n */\n CURVE(): WeierstrassOpts<T>;\n}\n\n/**\n * Weierstrass curve options.\n *\n * * p: prime characteristic (order) of finite field, in which arithmetics is done\n * * n: order of prime subgroup a.k.a total amount of valid curve points\n * * h: cofactor, usually 1. h*n is group order; n is subgroup order\n * * a: formula param, must be in field of p\n * * b: formula param, must be in field of p\n * * Gx: x coordinate of generator point a.k.a. base point\n * * Gy: y coordinate of generator point\n */\nexport type WeierstrassOpts<T> = Readonly<{\n /** Base-field modulus. */\n p: bigint;\n /** Prime subgroup order. */\n n: bigint;\n /** Curve cofactor. */\n h: bigint;\n /** Weierstrass curve parameter `a`. */\n a: T;\n /** Weierstrass curve parameter `b`. */\n b: T;\n /** Generator x coordinate. */\n Gx: T;\n /** Generator y coordinate. */\n Gy: T;\n}>;\n\n/**\n * Optional helpers and overrides for a Weierstrass point constructor.\n *\n * When a cofactor != 1, there can be effective methods to:\n * 1. Determine whether a point is torsion-free\n * 2. Clear torsion component\n */\nexport type WeierstrassExtraOpts<T> = Partial<{\n /** Optional base-field override. */\n Fp: IField<T>;\n /** Optional scalar-field override. */\n Fn: IField<bigint>;\n /** Whether the point constructor accepts infinity points. */\n allowInfinityPoint: boolean;\n /** Optional GLV endomorphism data. */\n endo: EndomorphismOpts;\n /** Optional torsion-check override. */\n isTorsionFree: (c: WeierstrassPointCons<T>, point: WeierstrassPoint<T>) => boolean;\n /** Optional cofactor-clearing override. */\n clearCofactor: (c: WeierstrassPointCons<T>, point: WeierstrassPoint<T>) => WeierstrassPoint<T>;\n /** Optional custom point decoder. */\n fromBytes: (bytes: TArg<Uint8Array>) => AffinePoint<T>;\n /** Optional custom point encoder. */\n toBytes: (\n c: WeierstrassPointCons<T>,\n point: WeierstrassPoint<T>,\n isCompressed: boolean\n ) => TRet<Uint8Array>;\n}>;\n\n/**\n * Options for ECDSA signatures over a Weierstrass curve.\n *\n * * lowS: (default: true) whether produced or verified signatures occupy the\n * low half of `ecdsaOpts.n`. Prevents malleability.\n * * hmac: (default: noble-hashes hmac) function, would be used to init hmac-drbg for k generation.\n * * randomBytes: (default: webcrypto os-level CSPRNG) custom method for fetching secure randomness.\n * * bits2int, bits2int_modN: used in sigs, sometimes overridden by curves. Custom hooks are\n * treated as pure functions over validated bytes and MUST NOT mutate caller-owned buffers or\n * closure-captured option bags. `bits2int_modN` must also return a canonical scalar in\n * `[0..Point.Fn.ORDER-1]`.\n */\nexport type ECDSAOpts = Partial<{\n /** Default low-S policy for this ECDSA instance. */\n lowS: boolean;\n /** HMAC implementation used by RFC6979 DRBG. */\n hmac: HmacFn;\n /** RNG override used by helper constructors. */\n randomBytes: (bytesLength?: number) => TRet<Uint8Array>;\n /** Hash-to-integer conversion override. */\n bits2int: (bytes: TArg<Uint8Array>) => bigint;\n /** Hash-to-integer-mod-n conversion override. Returns a canonical scalar in `[0..Fn.ORDER-1]`. */\n bits2int_modN: (bytes: TArg<Uint8Array>) => bigint;\n}>;\n\n/** Elliptic Curve Diffie-Hellman helper namespace. */\nexport interface ECDH {\n /**\n * Generate a secret/public key pair.\n * @param seed - Optional seed material.\n * @returns Secret/public key pair.\n */\n keygen: (seed?: TArg<Uint8Array>) => { secretKey: TRet<Uint8Array>; publicKey: TRet<Uint8Array> };\n /**\n * Derive the public key from a secret key.\n * @param secretKey - Secret key bytes.\n * @param isCompressed - Whether to emit compressed SEC1 bytes.\n * @returns Encoded public key.\n */\n getPublicKey: (secretKey: TArg<Uint8Array>, isCompressed?: boolean) => TRet<Uint8Array>;\n /**\n * Compute the shared secret point from a secret key and peer public key.\n * @param secretKeyA - Local secret key bytes.\n * @param publicKeyB - Peer public key bytes.\n * @param isCompressed - Whether to emit compressed SEC1 bytes.\n * @returns Encoded shared point.\n */\n getSharedSecret: (\n secretKeyA: TArg<Uint8Array>,\n publicKeyB: TArg<Uint8Array>,\n isCompressed?: boolean\n ) => TRet<Uint8Array>;\n /** Point constructor used by this ECDH instance. */\n Point: WeierstrassPointCons<bigint>;\n /** Validation and random-key helpers. */\n utils: {\n /** Check whether a secret key has the expected encoding. */\n isValidSecretKey: (secretKey: TArg<Uint8Array>) => boolean;\n /** Check whether a public key decodes to a valid point. */\n isValidPublicKey: (publicKey: TArg<Uint8Array>, isCompressed?: boolean) => boolean;\n /** Generate a valid random secret key. */\n randomSecretKey: (seed?: TArg<Uint8Array>) => TRet<Uint8Array>;\n };\n /** Byte lengths for keys and signatures exposed by this curve. */\n lengths: CurveLengths;\n}\n\n/**\n * ECDSA interface.\n * Only supported for prime fields, not Fp2 (extension fields).\n */\nexport interface ECDSA extends ECDH {\n /**\n * Sign a message with the given secret key.\n * @param message - Message bytes.\n * @param secretKey - Secret key bytes.\n * @param opts - Optional signing tweaks. See {@link ECDSASignOpts}.\n * @returns Encoded signature bytes.\n */\n sign: (\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts?: TArg<ECDSASignOpts>\n ) => TRet<Uint8Array>;\n /**\n * Verify a signature against a message and public key.\n * @param signature - Encoded signature bytes.\n * @param message - Message bytes.\n * @param publicKey - Encoded public key.\n * @param opts - Optional verification tweaks. See {@link ECDSAVerifyOpts}.\n * @returns Whether the signature is valid.\n */\n verify: (\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>,\n opts?: TArg<ECDSAVerifyOpts>\n ) => boolean;\n /**\n * Recover the public key encoded into a recoverable signature.\n * @param signature - Recoverable signature bytes.\n * @param message - Message bytes.\n * @param opts - Optional recovery tweaks. See {@link ECDSARecoverOpts}.\n * @returns Encoded recovered public key.\n */\n recoverPublicKey(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n opts?: TArg<ECDSARecoverOpts>\n ): TRet<Uint8Array>;\n /** Signature constructor and parser helpers. */\n Signature: ECDSASignatureCons;\n}\n/**\n * @param m - Error message.\n * @example\n * Throw a DER-specific error when signature parsing encounters invalid bytes.\n *\n * ```ts\n * new DERErr('bad der');\n * ```\n */\nexport class DERErr extends Error {\n constructor(m = '') {\n super(m);\n }\n}\n/** DER helper namespace used by ECDSA signature parsing and encoding. */\nexport type IDER = {\n // asn.1 DER encoding utils\n /**\n * DER-specific error constructor.\n * @param m - Error message.\n * @returns DER-specific error instance.\n */\n Err: typeof DERErr;\n // Basic building block is TLV (Tag-Length-Value)\n /** Low-level tag-length-value helpers used by DER encoders. */\n _tlv: {\n /**\n * Encode one TLV record.\n * @param tag - ASN.1 tag byte.\n * @param data - Hex-encoded value payload.\n * @returns Encoded TLV string.\n */\n encode: (tag: number, data: string) => string;\n // v - value, l - left bytes (unparsed)\n /**\n * Decode one TLV record and return the value plus leftover bytes.\n * @param tag - Expected ASN.1 tag byte.\n * @param data - Remaining DER bytes.\n * @returns Parsed value plus leftover bytes.\n */\n decode(tag: number, data: TArg<Uint8Array>): TRet<{ v: Uint8Array; l: Uint8Array }>;\n };\n // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,\n // since we always use positive integers here. It must always be empty:\n // - add zero byte if exists\n // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)\n /** Positive-integer DER helpers used by ECDSA signature encoding. */\n _int: {\n /**\n * Encode one positive bigint as a DER INTEGER.\n * @param num - Positive integer to encode.\n * @returns Encoded DER INTEGER.\n */\n encode(num: bigint): string;\n /**\n * Decode one DER INTEGER into a bigint.\n * @param data - DER INTEGER bytes.\n * @returns Decoded bigint.\n */\n decode(data: TArg<Uint8Array>): bigint;\n };\n /**\n * Parse a DER signature into `{ r, s }`.\n * @param bytes - DER signature bytes.\n * @returns Parsed signature components.\n */\n toSig(bytes: TArg<Uint8Array>): { r: bigint; s: bigint };\n /**\n * Encode `{ r, s }` as a DER signature.\n * @param sig - Signature components.\n * @returns DER-encoded signature hex.\n */\n hexFromSig(sig: { r: bigint; s: bigint }): string;\n};\n/**\n * ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:\n *\n * [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]\n *\n * Docs: {@link https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/ | Let's Encrypt ASN.1 guide} and\n * {@link https://luca.ntop.org/Teaching/Appunti/asn1.html | Luca Deri's ASN.1 notes}.\n * @example\n * ASN.1 DER encoding utilities.\n *\n * ```ts\n * const der = DER.hexFromSig({ r: 1n, s: 2n });\n * ```\n */\nexport const DER: IDER = {\n // asn.1 DER encoding utils\n Err: DERErr,\n // Basic building block is TLV (Tag-Length-Value)\n _tlv: {\n encode: (tag: number, data: string): string => {\n const { Err: E } = DER;\n asafenumber(tag, 'tag');\n if (tag < 0 || tag > 255) throw new E('tlv.encode: wrong tag');\n if (typeof data !== 'string')\n throw new TypeError('\"data\" expected string, got type=' + typeof data);\n // Internal helper: callers hand this already-validated hex payload, so we only enforce\n // byte alignment here instead of re-validating every nibble.\n if (data.length & 1) throw new E('tlv.encode: unpadded data');\n const dataLen = data.length / 2;\n const len = numberToHexUnpadded(dataLen);\n if ((len.length / 2) & 0b1000_0000) throw new E('tlv.encode: long form length too big');\n // length of length with long form flag\n const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 0b1000_0000) : '';\n const t = numberToHexUnpadded(tag);\n return t + lenLen + len + data;\n },\n // v - value, l - left bytes (unparsed)\n decode(tag: number, data: TArg<Uint8Array>): TRet<{ v: Uint8Array; l: Uint8Array }> {\n const { Err: E } = DER;\n data = abytes(data, undefined, 'DER data');\n let pos = 0;\n if (tag < 0 || tag > 255) throw new E('tlv.encode: wrong tag');\n if (data.length < 2 || data[pos++] !== tag) throw new E('tlv.decode: wrong tlv');\n const first = data[pos++];\n // First bit of first length byte is the short/long form flag.\n const isLong = !!(first & 0b1000_0000);\n let length = 0;\n if (!isLong) length = first;\n else {\n // Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]\n const lenLen = first & 0b0111_1111;\n if (!lenLen) throw new E('tlv.decode(long): indefinite length not supported');\n // This would overflow u32 in JS.\n if (lenLen > 4) throw new E('tlv.decode(long): byte length is too big');\n const lengthBytes = data.subarray(pos, pos + lenLen);\n if (lengthBytes.length !== lenLen) throw new E('tlv.decode: length bytes not complete');\n if (lengthBytes[0] === 0) throw new E('tlv.decode(long): zero leftmost byte');\n for (const b of lengthBytes) length = (length << 8) | b;\n pos += lenLen;\n if (length < 128) throw new E('tlv.decode(long): not minimal encoding');\n }\n const v = data.subarray(pos, pos + length);\n if (v.length !== length) throw new E('tlv.decode: wrong value length');\n return { v, l: data.subarray(pos + length) } as TRet<{ v: Uint8Array; l: Uint8Array }>;\n },\n },\n // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,\n // since we always use positive integers here. It must always be empty:\n // - add zero byte if exists\n // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)\n _int: {\n encode(num: bigint): string {\n const { Err: E } = DER;\n abignumber(num);\n if (num < _0n) throw new E('integer: negative integers are not allowed');\n let hex = numberToHexUnpadded(num);\n // Pad with zero byte if negative flag is present\n if (Number.parseInt(hex[0], 16) & 0b1000) hex = '00' + hex;\n if (hex.length & 1) throw new E('unexpected DER parsing assertion: unpadded hex');\n return hex;\n },\n decode(data: TArg<Uint8Array>): bigint {\n const { Err: E } = DER;\n if (data.length < 1) throw new E('invalid signature integer: empty');\n if (data[0] & 0b1000_0000) throw new E('invalid signature integer: negative');\n // Single-byte zero `00` is the canonical DER INTEGER encoding for zero.\n if (data.length > 1 && data[0] === 0x00 && !(data[1] & 0b1000_0000))\n throw new E('invalid signature integer: unnecessary leading zero');\n return bytesToNumberBE(data);\n },\n },\n toSig(bytes: TArg<Uint8Array>): { r: bigint; s: bigint } {\n // parse DER signature\n const { Err: E, _int: int, _tlv: tlv } = DER;\n const data = abytes(bytes, undefined, 'signature');\n const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);\n if (seqLeftBytes.length) throw new E('invalid signature: left bytes after parsing');\n const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);\n const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);\n if (sLeftBytes.length) throw new E('invalid signature: left bytes after parsing');\n return { r: int.decode(rBytes), s: int.decode(sBytes) };\n },\n hexFromSig(sig: { r: bigint; s: bigint }): string {\n const { _tlv: tlv, _int: int } = DER;\n const rs = tlv.encode(0x02, int.encode(sig.r));\n const ss = tlv.encode(0x02, int.encode(sig.s));\n const seq = rs + ss;\n return tlv.encode(0x30, seq);\n },\n};\nObject.freeze(DER._tlv);\nObject.freeze(DER._int);\nObject.freeze(DER);\n\n// Be friendly to bad ECMAScript parsers by not using bigint literals\n// prettier-ignore\nconst _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2), _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4);\n\n/**\n * Creates weierstrass Point constructor, based on specified curve options.\n *\n * See {@link WeierstrassOpts}.\n * @param params - Curve parameters. See {@link WeierstrassOpts}.\n * @param extraOpts - Optional helpers and overrides. See {@link WeierstrassExtraOpts}.\n * @returns Weierstrass point constructor.\n * @throws If the curve parameters, overrides, or point codecs are invalid. {@link Error}\n *\n * @example\n * Construct a point type from explicit Weierstrass curve parameters.\n *\n * ```js\n * const opts = {\n * p: 0xfffffffffffffffffffffffffffffffeffffac73n,\n * n: 0x100000000000000000001b8fa16dfab9aca16b6b3n,\n * h: 1n,\n * a: 0n,\n * b: 7n,\n * Gx: 0x3b4c382ce37aa192a4019e763036f4f5dd4d7ebbn,\n * Gy: 0x938cf935318fdced6bc28286531733c3f03c4feen,\n * };\n * const secp160k1_Point = weierstrass(opts);\n * ```\n */\nexport function weierstrass<T>(\n params: WeierstrassOpts<T>,\n extraOpts: WeierstrassExtraOpts<T> = {}\n): WeierstrassPointCons<T> {\n const validated = createCurveFields('weierstrass', params, extraOpts);\n const Fp = validated.Fp as IField<T>;\n const Fn = validated.Fn as IField<bigint>;\n let CURVE = validated.CURVE as WeierstrassOpts<T>;\n const { h: cofactor, n: CURVE_ORDER } = CURVE;\n validateObject(\n extraOpts,\n {},\n {\n allowInfinityPoint: 'boolean',\n clearCofactor: 'function',\n isTorsionFree: 'function',\n fromBytes: 'function',\n toBytes: 'function',\n endo: 'object',\n }\n );\n\n // Snapshot constructor-time flags whose later mutation would otherwise change\n // validity semantics of an already-built point type.\n const { endo, allowInfinityPoint } = extraOpts;\n if (endo) {\n // validateObject(endo, { beta: 'bigint', splitScalar: 'function' });\n if (!Fp.is0(CURVE.a) || typeof endo.beta !== 'bigint' || !Array.isArray(endo.basises)) {\n throw new Error('invalid endo: expected \"beta\": bigint and \"basises\": array');\n }\n }\n\n const lengths = getWLengths(Fp as TArg<IField<T>>, Fn);\n\n function assertCompressionIsSupported() {\n if (!Fp.isOdd) throw new Error('compression is not supported: Field does not have .isOdd()');\n }\n\n // Implements IEEE P1363 point encoding\n function pointToBytes(\n _c: WeierstrassPointCons<T>,\n point: WeierstrassPoint<T>,\n isCompressed: boolean\n ): TRet<Uint8Array> {\n // SEC 1 v2.0 §2.3.3 encodes infinity as the single octet 0x00. Only curves\n // that opt into infinity as a public point value should expose that byte form.\n if (allowInfinityPoint && point.is0()) return Uint8Array.of(0) as TRet<Uint8Array>;\n const { x, y } = point.toAffine();\n const bx = Fp.toBytes(x);\n abool(isCompressed, 'isCompressed');\n if (isCompressed) {\n assertCompressionIsSupported();\n const hasEvenY = !Fp.isOdd!(y);\n return concatBytes(pprefix(hasEvenY), bx) as TRet<Uint8Array>;\n } else {\n return concatBytes(Uint8Array.of(0x04), bx, Fp.toBytes(y)) as TRet<Uint8Array>;\n }\n }\n function pointFromBytes(bytes: TArg<Uint8Array>) {\n abytes(bytes, undefined, 'Point');\n const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths; // e.g. for 32-byte: 33, 65\n const length = bytes.length;\n const head = bytes[0];\n const tail = bytes.subarray(1);\n if (allowInfinityPoint && length === 1 && head === 0x00) return { x: Fp.ZERO, y: Fp.ZERO };\n // SEC 1 v2.0 §2.3.4 decodes 0x00 as infinity, but §3.2.2 public-key validation\n // rejects infinity. We therefore keep 0x00 rejected by default because callers\n // reuse this parser as the strict public-key boundary, and only admit it when\n // the curve explicitly opts into infinity as a public point value. secp256k1\n // crosstests show OpenSSL raw point codecs accept 0x00 too.\n // No actual validation is done here: use .assertValidity()\n if (length === comp && (head === 0x02 || head === 0x03)) {\n const x = Fp.fromBytes(tail);\n if (!Fp.isValid(x)) throw new Error('bad point: is not on curve, wrong x');\n const y2 = weierstrassEquation(x); // y² = x³ + ax + b\n let y: T;\n try {\n y = Fp.sqrt(y2); // y = y² ^ (p+1)/4\n } catch (sqrtError) {\n const err = sqrtError instanceof Error ? ': ' + sqrtError.message : '';\n throw new Error('bad point: is not on curve, sqrt error' + err);\n }\n assertCompressionIsSupported();\n const evenY = Fp.isOdd!(y);\n const evenH = (head & 1) === 1; // ECDSA-specific\n if (evenH !== evenY) y = Fp.neg(y);\n return { x, y };\n } else if (length === uncomp && head === 0x04) {\n // TODO: more checks\n const L = Fp.BYTES;\n const x = Fp.fromBytes(tail.subarray(0, L));\n const y = Fp.fromBytes(tail.subarray(L, L * 2));\n if (!isValidXY(x, y)) throw new Error('bad point: is not on curve');\n return { x, y };\n } else {\n throw new Error(\n `bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`\n );\n }\n }\n\n const encodePoint = extraOpts.toBytes === undefined ? pointToBytes : extraOpts.toBytes;\n const decodePoint = extraOpts.fromBytes === undefined ? pointFromBytes : extraOpts.fromBytes;\n function weierstrassEquation(x: T): T {\n const x2 = Fp.sqr(x); // x * x\n const x3 = Fp.mul(x2, x); // x² * x\n return Fp.add(Fp.add(x3, Fp.mul(x, CURVE.a)), CURVE.b); // x³ + a * x + b\n }\n\n // TODO: move top-level\n /** Checks whether equation holds for given x, y: y² == x³ + ax + b */\n function isValidXY(x: T, y: T): boolean {\n const left = Fp.sqr(y); // y²\n const right = weierstrassEquation(x); // x³ + ax + b\n return Fp.eql(left, right);\n }\n\n // Keep constructor-time generator validation cheap: callers are responsible for supplying the\n // correct prime-order base point, while eager subgroup checks here would slow heavy module imports.\n // Test 1: equation y² = x³ + ax + b should work for generator point.\n if (!isValidXY(CURVE.Gx, CURVE.Gy)) throw new Error('bad curve params: generator point');\n\n // Test 2: discriminant Δ part should be non-zero: 4a³ + 27b² != 0.\n // Guarantees curve is genus-1, smooth (non-singular).\n const _4a3 = Fp.mul(Fp.pow(CURVE.a, _3n), _4n);\n const _27b2 = Fp.mul(Fp.sqr(CURVE.b), BigInt(27));\n if (Fp.is0(Fp.add(_4a3, _27b2))) throw new Error('bad curve params: a or b');\n\n /** Asserts coordinate is valid: 0 <= n < Fp.ORDER. */\n function acoord(title: string, n: T, banZero = false) {\n if (!Fp.isValid(n) || (banZero && Fp.is0(n))) throw new Error(`bad point coordinate ${title}`);\n return n;\n }\n\n function aprjpoint(other: unknown): asserts other is Point {\n if (!(other instanceof Point)) throw new Error('Weierstrass Point expected');\n }\n\n function splitEndoScalarN(k: bigint) {\n if (!endo || !endo.basises) throw new Error('no endo');\n return _splitEndoScalar(k, endo.basises, Fn.ORDER);\n }\n\n function finishEndo(\n endoBeta: EndomorphismOpts['beta'],\n k1p: Point,\n k2p: Point,\n k1neg: boolean,\n k2neg: boolean\n ) {\n k2p = new Point(Fp.mul(k2p.X, endoBeta), k2p.Y, k2p.Z);\n k1p = negateCt(k1neg, k1p);\n k2p = negateCt(k2neg, k2p);\n return k1p.add(k2p);\n }\n\n /**\n * Projective Point works in 3d / projective (homogeneous) coordinates:(X, Y, Z) ∋ (x=X/Z, y=Y/Z).\n * Default Point works in 2d / affine coordinates: (x, y).\n * We're doing calculations in projective, because its operations don't require costly inversion.\n */\n class Point implements WeierstrassPoint<T> {\n // base / generator point\n static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);\n // zero / infinity / identity point\n static readonly ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); // 0, 1, 0\n // math field\n static readonly Fp = Fp;\n // scalar field\n static readonly Fn = Fn;\n\n readonly X: T;\n readonly Y: T;\n readonly Z: T;\n\n /** Does NOT validate if the point is valid. Use `.assertValidity()`. */\n constructor(X: T, Y: T, Z: T) {\n this.X = acoord('x', X);\n // This is not just about ZERO / infinity: ambient curves can have real\n // finite points with y=0. Those points are 2-torsion, so they cannot lie\n // in the odd prime-order subgroups this point type is meant to represent.\n this.Y = acoord('y', Y, true);\n this.Z = acoord('z', Z);\n Object.freeze(this);\n }\n\n static CURVE(): WeierstrassOpts<T> {\n return CURVE;\n }\n\n /** Does NOT validate if the point is valid. Use `.assertValidity()`. */\n static fromAffine(p: AffinePoint<T>): Point {\n const { x, y } = p || {};\n if (!p || !Fp.isValid(x) || !Fp.isValid(y)) throw new Error('invalid affine point');\n if (p instanceof Point) throw new Error('projective point not allowed');\n // (0, 0) would've produced (0, 0, 1) - instead, we need (0, 1, 0)\n if (Fp.is0(x) && Fp.is0(y)) return Point.ZERO;\n return new Point(x, y, Fp.ONE);\n }\n\n static fromBytes(bytes: TArg<Uint8Array>): Point {\n const P = Point.fromAffine(decodePoint(abytes(bytes, undefined, 'point')));\n P.assertValidity();\n return P;\n }\n\n static fromHex(hex: string): Point {\n return Point.fromBytes(hexToBytes(hex));\n }\n\n get x(): T {\n return this.toAffine().x;\n }\n get y(): T {\n return this.toAffine().y;\n }\n\n /**\n *\n * @param windowSize\n * @param isLazy - true will defer table computation until the first multiplication\n * @returns\n */\n precompute(windowSize: number = 8, isLazy = true): Point {\n wnaf.createCache(this, windowSize);\n if (!isLazy) this.multiply(_3n); // random number\n return this;\n }\n\n // TODO: return `this`\n /** A point on curve is valid if it conforms to equation. */\n assertValidity(): void {\n const p = this;\n if (p.is0()) {\n // (0, 1, 0) aka ZERO is invalid in most contexts.\n // In BLS, ZERO can be serialized, so we allow it.\n // Keep the accepted infinity encoding canonical: projective-equivalent (X, Y, 0) points\n // like (1, 1, 0) compare equal to ZERO, but only (0, 1, 0) should pass this guard.\n if (extraOpts.allowInfinityPoint && Fp.is0(p.X) && Fp.eql(p.Y, Fp.ONE) && Fp.is0(p.Z))\n return;\n throw new Error('bad point: ZERO');\n }\n // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`\n const { x, y } = p.toAffine();\n if (!Fp.isValid(x) || !Fp.isValid(y)) throw new Error('bad point: x or y not field elements');\n if (!isValidXY(x, y)) throw new Error('bad point: equation left != right');\n if (!p.isTorsionFree()) throw new Error('bad point: not in prime-order subgroup');\n }\n\n hasEvenY(): boolean {\n const { y } = this.toAffine();\n if (!Fp.isOdd) throw new Error(\"Field doesn't support isOdd\");\n return !Fp.isOdd(y);\n }\n\n /** Compare one point to another. */\n equals(other: WeierstrassPoint<T>): boolean {\n aprjpoint(other);\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const { X: X2, Y: Y2, Z: Z2 } = other;\n const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));\n const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));\n return U1 && U2;\n }\n\n /** Flips point to one corresponding to (x, -y) in Affine coordinates. */\n negate(): Point {\n return new Point(this.X, Fp.neg(this.Y), this.Z);\n }\n\n // Renes-Costello-Batina exception-free doubling formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 3\n // Cost: 8M + 3S + 3*a + 2*b3 + 15add.\n double() {\n const { a, b } = CURVE;\n const b3 = Fp.mul(b, _3n);\n const { X: X1, Y: Y1, Z: Z1 } = this;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n let t0 = Fp.mul(X1, X1); // step 1\n let t1 = Fp.mul(Y1, Y1);\n let t2 = Fp.mul(Z1, Z1);\n let t3 = Fp.mul(X1, Y1);\n t3 = Fp.add(t3, t3); // step 5\n Z3 = Fp.mul(X1, Z1);\n Z3 = Fp.add(Z3, Z3);\n X3 = Fp.mul(a, Z3);\n Y3 = Fp.mul(b3, t2);\n Y3 = Fp.add(X3, Y3); // step 10\n X3 = Fp.sub(t1, Y3);\n Y3 = Fp.add(t1, Y3);\n Y3 = Fp.mul(X3, Y3);\n X3 = Fp.mul(t3, X3);\n Z3 = Fp.mul(b3, Z3); // step 15\n t2 = Fp.mul(a, t2);\n t3 = Fp.sub(t0, t2);\n t3 = Fp.mul(a, t3);\n t3 = Fp.add(t3, Z3);\n Z3 = Fp.add(t0, t0); // step 20\n t0 = Fp.add(Z3, t0);\n t0 = Fp.add(t0, t2);\n t0 = Fp.mul(t0, t3);\n Y3 = Fp.add(Y3, t0);\n t2 = Fp.mul(Y1, Z1); // step 25\n t2 = Fp.add(t2, t2);\n t0 = Fp.mul(t2, t3);\n X3 = Fp.sub(X3, t0);\n Z3 = Fp.mul(t2, t1);\n Z3 = Fp.add(Z3, Z3); // step 30\n Z3 = Fp.add(Z3, Z3);\n return new Point(X3, Y3, Z3);\n }\n\n // Renes-Costello-Batina exception-free addition formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 1\n // Cost: 12M + 0S + 3*a + 3*b3 + 23add.\n add(other: WeierstrassPoint<T>): Point {\n aprjpoint(other);\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const { X: X2, Y: Y2, Z: Z2 } = other;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n const a = CURVE.a;\n const b3 = Fp.mul(CURVE.b, _3n);\n let t0 = Fp.mul(X1, X2); // step 1\n let t1 = Fp.mul(Y1, Y2);\n let t2 = Fp.mul(Z1, Z2);\n let t3 = Fp.add(X1, Y1);\n let t4 = Fp.add(X2, Y2); // step 5\n t3 = Fp.mul(t3, t4);\n t4 = Fp.add(t0, t1);\n t3 = Fp.sub(t3, t4);\n t4 = Fp.add(X1, Z1);\n let t5 = Fp.add(X2, Z2); // step 10\n t4 = Fp.mul(t4, t5);\n t5 = Fp.add(t0, t2);\n t4 = Fp.sub(t4, t5);\n t5 = Fp.add(Y1, Z1);\n X3 = Fp.add(Y2, Z2); // step 15\n t5 = Fp.mul(t5, X3);\n X3 = Fp.add(t1, t2);\n t5 = Fp.sub(t5, X3);\n Z3 = Fp.mul(a, t4);\n X3 = Fp.mul(b3, t2); // step 20\n Z3 = Fp.add(X3, Z3);\n X3 = Fp.sub(t1, Z3);\n Z3 = Fp.add(t1, Z3);\n Y3 = Fp.mul(X3, Z3);\n t1 = Fp.add(t0, t0); // step 25\n t1 = Fp.add(t1, t0);\n t2 = Fp.mul(a, t2);\n t4 = Fp.mul(b3, t4);\n t1 = Fp.add(t1, t2);\n t2 = Fp.sub(t0, t2); // step 30\n t2 = Fp.mul(a, t2);\n t4 = Fp.add(t4, t2);\n t0 = Fp.mul(t1, t4);\n Y3 = Fp.add(Y3, t0);\n t0 = Fp.mul(t5, t4); // step 35\n X3 = Fp.mul(t3, X3);\n X3 = Fp.sub(X3, t0);\n t0 = Fp.mul(t3, t1);\n Z3 = Fp.mul(t5, Z3);\n Z3 = Fp.add(Z3, t0); // step 40\n return new Point(X3, Y3, Z3);\n }\n\n subtract(other: WeierstrassPoint<T>) {\n // Validate before calling `negate()` so wrong inputs fail with the point guard\n // instead of leaking a foreign `negate()` error.\n aprjpoint(other);\n return this.add(other.negate());\n }\n\n is0(): boolean {\n return this.equals(Point.ZERO);\n }\n\n /**\n * Constant time multiplication.\n * Uses wNAF method. Windowed method may be 10% faster,\n * but takes 2x longer to generate and consumes 2x memory.\n * Uses precomputes when available.\n * Uses endomorphism for Koblitz curves.\n * @param scalar - by which the point would be multiplied\n * @returns New point\n */\n multiply(scalar: bigint): Point {\n const { endo } = extraOpts;\n // Keep the subgroup-scalar contract strict instead of reducing 0 / n to ZERO.\n // In key/signature-style callers, those values usually mean broken hash/scalar plumbing,\n // and failing closed is safer than silently producing the identity point.\n if (!Fn.isValidNot0(scalar)) throw new RangeError('invalid scalar: out of range'); // 0 is invalid\n let point: Point, fake: Point; // Fake point is used to const-time mult\n const mul = (n: bigint) => wnaf.cached(this, n, (p) => normalizeZ(Point, p));\n /** See docs for {@link EndomorphismOpts} */\n if (endo) {\n const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar);\n const { p: k1p, f: k1f } = mul(k1);\n const { p: k2p, f: k2f } = mul(k2);\n fake = k1f.add(k2f);\n point = finishEndo(endo.beta, k1p, k2p, k1neg, k2neg);\n } else {\n const { p, f } = mul(scalar);\n point = p;\n fake = f;\n }\n // Normalize `z` for both points, but return only real one\n return normalizeZ(Point, [point, fake])[0];\n }\n\n /**\n * Non-constant-time multiplication. Uses double-and-add algorithm.\n * It's faster, but should only be used when you don't care about\n * an exposed secret key e.g. sig verification, which works over *public* keys.\n */\n multiplyUnsafe(scalar: bigint): Point {\n const { endo } = extraOpts;\n const p = this as Point;\n const sc = scalar;\n // Public-scalar callers may need 0, but n and larger values stay rejected here too.\n // Reducing them mod n would turn bad caller input into an accidental identity point.\n if (!Fn.isValid(sc)) throw new RangeError('invalid scalar: out of range'); // 0 is valid\n if (sc === _0n || p.is0()) return Point.ZERO; // 0\n if (sc === _1n) return p; // 1\n if (wnaf.hasCache(this)) return this.multiply(sc); // precomputes\n // We don't have method for double scalar multiplication (aP + bQ):\n // Even with using Strauss-Shamir trick, it's 35% slower than naïve mul+add.\n if (endo) {\n const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(sc);\n const { p1, p2 } = mulEndoUnsafe(Point, p, k1, k2); // 30% faster vs wnaf.unsafe\n return finishEndo(endo.beta, p1, p2, k1neg, k2neg);\n } else {\n return wnaf.unsafe(p, sc);\n }\n }\n\n /**\n * Converts Projective point to affine (x, y) coordinates.\n * (X, Y, Z) ∋ (x=X/Z, y=Y/Z).\n * @param invertedZ - Z^-1 (inverted zero) - optional, precomputation is useful for invertBatch\n */\n toAffine(invertedZ?: T): AffinePoint<T> {\n const p = this;\n let iz = invertedZ;\n const { X, Y, Z } = p;\n // Fast-path for normalized points\n if (Fp.eql(Z, Fp.ONE)) return { x: X, y: Y };\n const is0 = p.is0();\n // If invZ was 0, we return zero point. However we still want to execute\n // all operations, so we replace invZ with a random number, 1.\n if (iz == null) iz = is0 ? Fp.ONE : Fp.inv(Z);\n const x = Fp.mul(X, iz);\n const y = Fp.mul(Y, iz);\n const zz = Fp.mul(Z, iz);\n if (is0) return { x: Fp.ZERO, y: Fp.ZERO };\n if (!Fp.eql(zz, Fp.ONE)) throw new Error('invZ was invalid');\n return { x, y };\n }\n\n /**\n * Checks whether Point is free of torsion elements (is in prime subgroup).\n * Always torsion-free for cofactor=1 curves.\n */\n isTorsionFree(): boolean {\n const { isTorsionFree } = extraOpts;\n if (cofactor === _1n) return true;\n if (isTorsionFree) return isTorsionFree(Point, this);\n return wnaf.unsafe(this, CURVE_ORDER).is0();\n }\n\n clearCofactor(): Point {\n const { clearCofactor } = extraOpts;\n if (cofactor === _1n) return this; // Fast-path\n if (clearCofactor) return clearCofactor(Point, this) as Point;\n // Default fallback assumes the cofactor fits the usual subgroup-scalar\n // multiplyUnsafe() contract. Curves with larger / structured cofactors\n // should define a clearCofactor override anyway (e.g. psi/Frobenius maps).\n return this.multiplyUnsafe(cofactor);\n }\n\n isSmallOrder(): boolean {\n if (cofactor === _1n) return this.is0(); // Fast-path\n return this.clearCofactor().is0();\n }\n\n toBytes(isCompressed = true): TRet<Uint8Array> {\n abool(isCompressed, 'isCompressed');\n // Same policy as pointFromBytes(): keep ZERO out of the default byte surface because\n // callers use these encodings as public keys, where SEC 1 validation rejects infinity.\n this.assertValidity();\n return encodePoint(Point, this, isCompressed);\n }\n\n toHex(isCompressed = true): string {\n return bytesToHex(this.toBytes(isCompressed));\n }\n\n toString() {\n return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;\n }\n }\n const bits = Fn.BITS;\n const wnaf = new wNAF(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits);\n // Tiny toy curves can have scalar fields narrower than 8 bits. Skip the\n // eager W=8 cache there instead of rejecting an otherwise valid constructor.\n if (bits >= 8) Point.BASE.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.\n Object.freeze(Point.prototype);\n Object.freeze(Point);\n return Point;\n}\n\n/** Parsed ECDSA signature with helpers for recovery and re-encoding. */\nexport interface ECDSASignature {\n /** Signature component `r`. */\n readonly r: bigint;\n /** Signature component `s`. */\n readonly s: bigint;\n /** Optional recovery bit for recoverable signatures. */\n readonly recovery?: number;\n /**\n * Return a copy of the signature with a recovery bit attached.\n * @param recovery - Recovery bit to attach.\n * @returns Signature with an attached recovery bit.\n */\n addRecoveryBit(recovery: number): ECDSASignature & { readonly recovery: number };\n /**\n * Check whether the signature uses the high-S half-order.\n * @returns Whether the signature uses the high-S half-order.\n */\n hasHighS(): boolean;\n /**\n * Recover the public key from the hashed message and recovery bit.\n * @param messageHash - Hashed message bytes.\n * @returns Recovered public-key point.\n */\n recoverPublicKey(messageHash: TArg<Uint8Array>): WeierstrassPoint<bigint>;\n /**\n * Encode the signature into bytes.\n * @param format - Signature encoding to produce.\n * @returns Encoded signature bytes.\n */\n toBytes(format?: string): TRet<Uint8Array>;\n /**\n * Encode the signature into hex.\n * @param format - Signature encoding to produce.\n * @returns Encoded signature hex.\n */\n toHex(format?: string): string;\n}\n/** Constructor and decoding helpers for ECDSA signatures. */\nexport type ECDSASignatureCons = {\n /** Create a signature from `r`, `s`, and an optional recovery bit. */\n new (r: bigint, s: bigint, recovery?: number): ECDSASignature;\n /**\n * Decode a signature from bytes.\n * @param bytes - Encoded signature bytes.\n * @param format - Signature encoding to parse.\n * @returns Parsed signature.\n */\n fromBytes(bytes: TArg<Uint8Array>, format?: ECDSASignatureFormat): ECDSASignature;\n /**\n * Decode a signature from hex.\n * @param hex - Encoded signature hex.\n * @param format - Signature encoding to parse.\n * @returns Parsed signature.\n */\n fromHex(hex: string, format?: ECDSASignatureFormat): ECDSASignature;\n};\n\n// Points start with byte 0x02 when y is even; otherwise 0x03\nfunction pprefix(hasEvenY: boolean): TRet<Uint8Array> {\n return Uint8Array.of(hasEvenY ? 0x02 : 0x03) as TRet<Uint8Array>;\n}\n\n/**\n * Implementation of the Shallue and van de Woestijne method for any weierstrass curve.\n * TODO: check if there is a way to merge this with uvRatio in Edwards; move to modular.\n * b = True and y = sqrt(u / v) if (u / v) is square in F, and\n * b = False and y = sqrt(Z * (u / v)) otherwise.\n * RFC 9380 expects callers to provide `v != 0`; this helper does not enforce it.\n * @param Fp - Field implementation.\n * @param Z - Simplified SWU map parameter.\n * @returns Square-root ratio helper.\n * @example\n * Build the square-root ratio helper used by SWU map implementations.\n *\n * ```ts\n * import { SWUFpSqrtRatio } from '@noble/curves/abstract/weierstrass.js';\n * import { Field } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const sqrtRatio = SWUFpSqrtRatio(Fp, 3n);\n * const out = sqrtRatio(4n, 1n);\n * ```\n */\nexport function SWUFpSqrtRatio<T>(\n Fp: TArg<IField<T>>,\n Z: T\n): (u: T, v: T) => { isValid: boolean; value: T } {\n // Fail with the usual field-shape error before touching pow/cmov on malformed field shims.\n const F = validateField(Fp as IField<T>) as IField<T>;\n // Generic implementation\n const q = F.ORDER;\n let l = _0n;\n for (let o = q - _1n; o % _2n === _0n; o /= _2n) l += _1n;\n const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.\n // We need 2n ** c1 and 2n ** (c1-1). We can't use **; but we can use <<.\n // 2n ** c1 == 2n << (c1-1)\n const _2n_pow_c1_1 = _2n << (c1 - _1n - _1n);\n const _2n_pow_c1 = _2n_pow_c1_1 * _2n;\n const c2 = (q - _1n) / _2n_pow_c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic\n const c3 = (c2 - _1n) / _2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic\n const c4 = _2n_pow_c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic\n const c5 = _2n_pow_c1_1; // 5. c5 = 2^(c1 - 1) # Integer arithmetic\n const c6 = F.pow(Z, c2); // 6. c6 = Z^c2\n const c7 = F.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2)\n // RFC 9380 Appendix F.2.1.1 defines sqrt_ratio(u, v) only for v != 0.\n // We keep v=0 on the regular result path with isValid=false instead of\n // throwing so the helper stays closer to the RFC's fixed control flow.\n let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => {\n let tv1 = c6; // 1. tv1 = c6\n let tv2 = F.pow(v, c4); // 2. tv2 = v^c4\n let tv3 = F.sqr(tv2); // 3. tv3 = tv2^2\n tv3 = F.mul(tv3, v); // 4. tv3 = tv3 * v\n let tv5 = F.mul(u, tv3); // 5. tv5 = u * tv3\n tv5 = F.pow(tv5, c3); // 6. tv5 = tv5^c3\n tv5 = F.mul(tv5, tv2); // 7. tv5 = tv5 * tv2\n tv2 = F.mul(tv5, v); // 8. tv2 = tv5 * v\n tv3 = F.mul(tv5, u); // 9. tv3 = tv5 * u\n let tv4 = F.mul(tv3, tv2); // 10. tv4 = tv3 * tv2\n tv5 = F.pow(tv4, c5); // 11. tv5 = tv4^c5\n let isQR = F.eql(tv5, F.ONE); // 12. isQR = tv5 == 1\n tv2 = F.mul(tv3, c7); // 13. tv2 = tv3 * c7\n tv5 = F.mul(tv4, tv1); // 14. tv5 = tv4 * tv1\n tv3 = F.cmov(tv2, tv3, isQR); // 15. tv3 = CMOV(tv2, tv3, isQR)\n tv4 = F.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)\n // 17. for i in (c1, c1 - 1, ..., 2):\n for (let i = c1; i > _1n; i--) {\n let tv5 = i - _2n; // 18. tv5 = i - 2\n tv5 = _2n << (tv5 - _1n); // 19. tv5 = 2^tv5\n let tvv5 = F.pow(tv4, tv5); // 20. tv5 = tv4^tv5\n const e1 = F.eql(tvv5, F.ONE); // 21. e1 = tv5 == 1\n tv2 = F.mul(tv3, tv1); // 22. tv2 = tv3 * tv1\n tv1 = F.mul(tv1, tv1); // 23. tv1 = tv1 * tv1\n tvv5 = F.mul(tv4, tv1); // 24. tv5 = tv4 * tv1\n tv3 = F.cmov(tv2, tv3, e1); // 25. tv3 = CMOV(tv2, tv3, e1)\n tv4 = F.cmov(tvv5, tv4, e1); // 26. tv4 = CMOV(tv5, tv4, e1)\n }\n // RFC 9380 Appendix F.2.1.1 defines sqrt_ratio(u, v) for v != 0.\n // When u = 0 and v != 0, u / v = 0 is square and the computed root is\n // still 0, so widen only the final flag and keep the full control flow.\n return { isValid: !F.is0(v) && (isQR || F.is0(u)), value: tv3 };\n };\n if (F.ORDER % _4n === _3n) {\n // sqrt_ratio_3mod4(u, v)\n const c1 = (F.ORDER - _3n) / _4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic\n const c2 = F.sqrt(F.neg(Z)); // 2. c2 = sqrt(-Z)\n sqrtRatio = (u: T, v: T) => {\n let tv1 = F.sqr(v); // 1. tv1 = v^2\n const tv2 = F.mul(u, v); // 2. tv2 = u * v\n tv1 = F.mul(tv1, tv2); // 3. tv1 = tv1 * tv2\n let y1 = F.pow(tv1, c1); // 4. y1 = tv1^c1\n y1 = F.mul(y1, tv2); // 5. y1 = y1 * tv2\n const y2 = F.mul(y1, c2); // 6. y2 = y1 * c2\n const tv3 = F.mul(F.sqr(y1), v); // 7. tv3 = y1^2; 8. tv3 = tv3 * v\n const isQR = F.eql(tv3, u); // 9. isQR = tv3 == u\n let y = F.cmov(y2, y1, isQR); // 10. y = CMOV(y2, y1, isQR)\n return { isValid: !F.is0(v) && isQR, value: y }; // 11. return (isQR, y) isQR ? y : y*c2\n };\n }\n // No curves uses that\n // if (Fp.ORDER % _8n === _5n) // sqrt_ratio_5mod8\n return sqrtRatio;\n}\n/**\n * Simplified Shallue-van de Woestijne-Ulas Method\n * See {@link https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2 | RFC 9380 section 6.6.2}.\n * @param Fp - Field implementation.\n * @param opts - SWU parameters:\n * - `A`: Curve parameter `A`.\n * - `B`: Curve parameter `B`.\n * - `Z`: Simplified SWU map parameter.\n * @returns Deterministic map-to-curve function.\n * @throws If the SWU parameters are invalid or the field lacks the required helpers. {@link Error}\n * @example\n * Map one field element to a Weierstrass curve point with the SWU recipe.\n *\n * ```ts\n * import { mapToCurveSimpleSWU } from '@noble/curves/abstract/weierstrass.js';\n * import { Field } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const map = mapToCurveSimpleSWU(Fp, { A: 1n, B: 2n, Z: 3n });\n * const point = map(5n);\n * ```\n */\nexport function mapToCurveSimpleSWU<T>(\n Fp: TArg<IField<T>>,\n opts: {\n A: T;\n B: T;\n Z: T;\n }\n): (u: T) => { x: T; y: T } {\n const F = validateField(Fp as IField<T>) as IField<T>;\n const { A, B, Z } = opts;\n if (!F.isValidNot0(A) || !F.isValidNot0(B) || !F.isValid(Z))\n throw new Error('mapToCurveSimpleSWU: invalid opts');\n // RFC 9380 §6.6.2 and Appendix H.2 require:\n // 1. Z is non-square in F\n // 2. Z != -1 in F\n // 3. g(x) - Z is irreducible over F\n // 4. g(B / (Z * A)) is square in F\n // We can enforce 1, 2, and 4 with the current field API.\n // Criterion 3 is not checked here because generic `IField<T>` does not expose\n // polynomial-ring / irreducibility operations, and this helper is used for\n // both prime and extension fields.\n if (F.eql(Z, F.neg(F.ONE)) || FpIsSquare(F, Z))\n throw new Error('mapToCurveSimpleSWU: invalid opts');\n // RFC 9380 Appendix H.2 criterion 4: g(B / (Z * A)) is square in F.\n // x = B / (Z * A)\n const x = F.mul(B, F.inv(F.mul(Z, A)));\n // g(x) = x^3 + A*x + B\n const gx = F.add(F.add(F.mul(F.sqr(x), x), F.mul(A, x)), B);\n if (!FpIsSquare(F, gx)) throw new Error('mapToCurveSimpleSWU: invalid opts');\n const sqrtRatio = SWUFpSqrtRatio(F, Z);\n if (!F.isOdd) throw new Error('Field does not have .isOdd()');\n // Input: u, an element of F.\n // Output: (x, y), a point on E.\n return (u: T): { x: T; y: T } => {\n // prettier-ignore\n let tv1, tv2, tv3, tv4, tv5, tv6, x, y;\n tv1 = F.sqr(u); // 1. tv1 = u^2\n tv1 = F.mul(tv1, Z); // 2. tv1 = Z * tv1\n tv2 = F.sqr(tv1); // 3. tv2 = tv1^2\n tv2 = F.add(tv2, tv1); // 4. tv2 = tv2 + tv1\n tv3 = F.add(tv2, F.ONE); // 5. tv3 = tv2 + 1\n tv3 = F.mul(tv3, B); // 6. tv3 = B * tv3\n tv4 = F.cmov(Z, F.neg(tv2), !F.eql(tv2, F.ZERO)); // 7. tv4 = CMOV(Z, -tv2, tv2 != 0)\n tv4 = F.mul(tv4, A); // 8. tv4 = A * tv4\n tv2 = F.sqr(tv3); // 9. tv2 = tv3^2\n tv6 = F.sqr(tv4); // 10. tv6 = tv4^2\n tv5 = F.mul(tv6, A); // 11. tv5 = A * tv6\n tv2 = F.add(tv2, tv5); // 12. tv2 = tv2 + tv5\n tv2 = F.mul(tv2, tv3); // 13. tv2 = tv2 * tv3\n tv6 = F.mul(tv6, tv4); // 14. tv6 = tv6 * tv4\n tv5 = F.mul(tv6, B); // 15. tv5 = B * tv6\n tv2 = F.add(tv2, tv5); // 16. tv2 = tv2 + tv5\n x = F.mul(tv1, tv3); // 17. x = tv1 * tv3\n const { isValid, value } = sqrtRatio(tv2, tv6); // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)\n y = F.mul(tv1, u); // 19. y = tv1 * u -> Z * u^3 * y1\n y = F.mul(y, value); // 20. y = y * y1\n x = F.cmov(x, tv3, isValid); // 21. x = CMOV(x, tv3, is_gx1_square)\n y = F.cmov(y, value, isValid); // 22. y = CMOV(y, y1, is_gx1_square)\n const e1 = F.isOdd!(u) === F.isOdd!(y); // 23. e1 = sgn0(u) == sgn0(y)\n y = F.cmov(F.neg(y), y, e1); // 24. y = CMOV(-y, y, e1)\n const tv4_inv = FpInvertBatch(F, [tv4], true)[0];\n x = F.mul(x, tv4_inv); // 25. x = x / tv4\n return { x, y };\n };\n}\n\nfunction getWLengths<T>(Fp: TArg<IField<T>>, Fn: TArg<IField<bigint>>) {\n return {\n secretKey: Fn.BYTES,\n publicKey: 1 + Fp.BYTES,\n publicKeyUncompressed: 1 + 2 * Fp.BYTES,\n publicKeyHasPrefix: true,\n // Raw compact `(r || s)` signature width; DER and recovered signatures use\n // different lengths outside this helper.\n signature: 2 * Fn.BYTES,\n };\n}\n\n/**\n * Sometimes users only need getPublicKey, getSharedSecret, and secret key handling.\n * This helper ensures no signature functionality is present. Less code, smaller bundle size.\n * @param Point - Weierstrass point constructor.\n * @param ecdhOpts - Optional randomness helpers:\n * - `randomBytes` (optional): Optional RNG override.\n * @returns ECDH helper namespace.\n * @example\n * Sometimes users only need getPublicKey, getSharedSecret, and secret key handling.\n *\n * ```ts\n * import { ecdh } from '@noble/curves/abstract/weierstrass.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const dh = ecdh(p256.Point);\n * const alice = dh.keygen();\n * const shared = dh.getSharedSecret(alice.secretKey, alice.publicKey);\n * ```\n */\nexport function ecdh(\n Point: WeierstrassPointCons<bigint>,\n ecdhOpts: TArg<{ randomBytes?: (bytesLength?: number) => TRet<Uint8Array> }> = {}\n): ECDH {\n const { Fn } = Point;\n const randomBytes_ = ecdhOpts.randomBytes === undefined ? wcRandomBytes : ecdhOpts.randomBytes;\n // Keep the advertised seed length aligned with mapHashToField(), which keeps a hard 16-byte\n // minimum even on toy curves.\n const lengths = Object.assign(getWLengths(Point.Fp, Fn), {\n seed: Math.max(getMinHashLength(Fn.ORDER), 16),\n });\n\n function isValidSecretKey(secretKey: TArg<Uint8Array>) {\n try {\n const num = Fn.fromBytes(secretKey);\n return Fn.isValidNot0(num);\n } catch (error) {\n return false;\n }\n }\n\n function isValidPublicKey(publicKey: TArg<Uint8Array>, isCompressed?: boolean): boolean {\n const { publicKey: comp, publicKeyUncompressed } = lengths;\n try {\n const l = publicKey.length;\n if (isCompressed === true && l !== comp) return false;\n if (isCompressed === false && l !== publicKeyUncompressed) return false;\n return !!Point.fromBytes(publicKey);\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Produces cryptographically secure secret key from random of size\n * (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.\n */\n function randomSecretKey(seed?: TArg<Uint8Array>): TRet<Uint8Array> {\n seed = seed === undefined ? randomBytes_(lengths.seed) : seed;\n return mapHashToField(abytes(seed, lengths.seed, 'seed'), Fn.ORDER) as TRet<Uint8Array>;\n }\n\n /**\n * Computes public key for a secret key. Checks for validity of the secret key.\n * @param isCompressed - whether to return compact (default), or full key\n * @returns Public key, full when isCompressed=false; short when isCompressed=true\n */\n function getPublicKey(secretKey: TArg<Uint8Array>, isCompressed = true): TRet<Uint8Array> {\n return Point.BASE.multiply(Fn.fromBytes(secretKey)).toBytes(isCompressed);\n }\n\n /**\n * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.\n */\n function isProbPub(item: TArg<Uint8Array>): boolean | undefined {\n const { secretKey, publicKey, publicKeyUncompressed } = lengths;\n const allowedLengths = (Fn as { _lengths?: readonly number[] })._lengths;\n if (!isBytes(item)) return undefined;\n const l = abytes(item, undefined, 'key').length;\n const isPub = l === publicKey || l === publicKeyUncompressed;\n const isSec = l === secretKey || !!allowedLengths?.includes(l);\n // P-521 accepts both 65- and 66-byte secret keys, so overlapping lengths stay ambiguous.\n if (isPub && isSec) return undefined;\n return isPub;\n }\n\n /**\n * ECDH (Elliptic Curve Diffie Hellman).\n * Computes encoded shared point from secret key A and public key B.\n * Checks: 1) secret key validity 2) shared key is on-curve.\n * Does NOT hash the result or expose the SEC 1 x-coordinate-only `z`.\n * Returns the encoded shared point on purpose: callers that need `x_P`\n * can derive it from the encoded point, but `x_P` alone cannot recover the\n * point/parity back.\n * This helper only exposes the fully validated public-key path, not cofactor DH.\n * @param isCompressed - whether to return compact (default), or full key\n * @returns shared point encoding\n */\n function getSharedSecret(\n secretKeyA: TArg<Uint8Array>,\n publicKeyB: TArg<Uint8Array>,\n isCompressed = true\n ): TRet<Uint8Array> {\n if (isProbPub(secretKeyA) === true) throw new Error('first arg must be private key');\n if (isProbPub(publicKeyB) === false) throw new Error('second arg must be public key');\n const s = Fn.fromBytes(secretKeyA);\n const b = Point.fromBytes(publicKeyB); // checks for being on-curve\n return b.multiply(s).toBytes(isCompressed);\n }\n\n const utils = {\n isValidSecretKey,\n isValidPublicKey,\n randomSecretKey,\n };\n const keygen = createKeygen(randomSecretKey, getPublicKey);\n Object.freeze(utils);\n Object.freeze(lengths);\n\n return Object.freeze({ getPublicKey, getSharedSecret, keygen, Point, utils, lengths });\n}\n\n/**\n * Creates ECDSA signing interface for given elliptic curve `Point` and `hash` function.\n *\n * @param Point - created using {@link weierstrass} function\n * @param hash - used for 1) message prehash-ing 2) k generation in `sign`, using hmac_drbg(hash)\n * @param ecdsaOpts - rarely needed, see {@link ECDSAOpts}:\n * - `lowS`: Default low-S policy.\n * - `hmac`: HMAC implementation used by RFC6979 DRBG.\n * - `randomBytes`: Optional RNG override.\n * - `bits2int`: Optional hash-to-int conversion override.\n * - `bits2int_modN`: Optional hash-to-int-mod-n conversion override.\n *\n * @returns ECDSA helper namespace.\n * @example\n * Create an ECDSA signer/verifier bundle for one curve implementation.\n *\n * ```ts\n * import { ecdsa } from '@noble/curves/abstract/weierstrass.js';\n * import { p256 } from '@noble/curves/nist.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const p256ecdsa = ecdsa(p256.Point, sha256);\n * const { secretKey, publicKey } = p256ecdsa.keygen();\n * const msg = new TextEncoder().encode('hello noble');\n * const sig = p256ecdsa.sign(msg, secretKey);\n * const isValid = p256ecdsa.verify(sig, msg, publicKey);\n * ```\n */\nexport function ecdsa(\n Point: WeierstrassPointCons<bigint>,\n hash: TArg<CHash>,\n ecdsaOpts: TArg<ECDSAOpts> = {}\n): ECDSA {\n // Custom hash / bits2int hooks are treated as pure functions over validated caller-owned bytes.\n const hash_ = hash as CHash;\n ahash(hash_);\n validateObject(\n ecdsaOpts,\n {},\n {\n hmac: 'function',\n lowS: 'boolean',\n randomBytes: 'function',\n bits2int: 'function',\n bits2int_modN: 'function',\n }\n );\n ecdsaOpts = Object.assign({}, ecdsaOpts);\n const randomBytes = ecdsaOpts.randomBytes === undefined ? wcRandomBytes : ecdsaOpts.randomBytes;\n const hmac =\n ecdsaOpts.hmac === undefined\n ? (key: TArg<Uint8Array>, msg: TArg<Uint8Array>) => nobleHmac(hash_, key, msg)\n : (ecdsaOpts.hmac as HmacFn);\n\n const { Fp, Fn } = Point;\n const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;\n const { keygen, getPublicKey, getSharedSecret, utils, lengths } = ecdh(Point, ecdsaOpts);\n const defaultSigOpts: Required<ECDSASignOpts> = {\n prehash: true,\n lowS: typeof ecdsaOpts.lowS === 'boolean' ? ecdsaOpts.lowS : true,\n format: 'compact' as ECDSASignatureFormat,\n extraEntropy: false,\n };\n // SEC 1 4.1.6 public-key recovery tries x = r + jn for j = 0..h. Our recovered-signature\n // format only stores one overflow bit, so it can only distinguish q.x = r from q.x = r + n.\n // A third lift would have the form q.x = r + 2n. Since valid ECDSA r is in 1..n-1, the\n // smallest such lift is 1 + 2n, not 2n.\n const hasLargeRecoveryLifts = CURVE_ORDER * _2n + _1n < Fp.ORDER;\n\n function isBiggerThanHalfOrder(number: bigint) {\n const HALF = CURVE_ORDER >> _1n;\n return number > HALF;\n }\n function validateRS(title: string, num: bigint): bigint {\n if (!Fn.isValidNot0(num))\n throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);\n return num;\n }\n function assertRecoverableCurve(): void {\n // ECDSA recovery only supports curves where the current recovery id can distinguish\n // q.x = r and q.x = r + n; larger lifts may need additional `r + n*i` branches.\n // SEC 1 4.1.6 recovers candidates via x = r + jn, but this format only encodes j = 0 or 1.\n // The next possible candidate is q.x = r + 2n, and its smallest valid value is 1 + 2n.\n // To easily get i, we either need to:\n // a. increase amount of valid recid values (4, 5...); OR\n // b. prohibit recovered signatures for those curves.\n if (hasLargeRecoveryLifts)\n throw new Error('\"recovered\" sig type is not supported for cofactor >2 curves');\n }\n function validateSigLength(bytes: TArg<Uint8Array>, format: ECDSASignatureFormat) {\n validateSigFormat(format);\n const size = lengths.signature!;\n const sizer = format === 'compact' ? size : format === 'recovered' ? size + 1 : undefined;\n return abytes(bytes, sizer);\n }\n\n /**\n * ECDSA signature with its (r, s) properties. Supports compact, recovered & DER representations.\n */\n class Signature implements ECDSASignature {\n readonly r: bigint;\n readonly s: bigint;\n readonly recovery?: number;\n\n constructor(r: bigint, s: bigint, recovery?: number) {\n this.r = validateRS('r', r); // r in [1..N-1];\n this.s = validateRS('s', s); // s in [1..N-1];\n if (recovery != null) {\n assertRecoverableCurve();\n if (![0, 1, 2, 3].includes(recovery)) throw new Error('invalid recovery id');\n this.recovery = recovery;\n }\n Object.freeze(this);\n }\n\n static fromBytes(\n bytes: TArg<Uint8Array>,\n format: ECDSASignatureFormat = defaultSigOpts.format\n ): Signature {\n validateSigLength(bytes, format);\n let recid: number | undefined;\n if (format === 'der') {\n const { r, s } = DER.toSig(abytes(bytes));\n return new Signature(r, s);\n }\n if (format === 'recovered') {\n recid = bytes[0];\n format = 'compact';\n bytes = bytes.subarray(1);\n }\n const L = lengths.signature! / 2;\n const r = bytes.subarray(0, L);\n const s = bytes.subarray(L, L * 2);\n return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid);\n }\n\n static fromHex(hex: string, format?: ECDSASignatureFormat) {\n return this.fromBytes(hexToBytes(hex), format);\n }\n\n private assertRecovery(): number {\n const { recovery } = this;\n if (recovery == null) throw new Error('invalid recovery id: must be present');\n return recovery;\n }\n\n addRecoveryBit(recovery: number): RecoveredSignature {\n return new Signature(this.r, this.s, recovery) as RecoveredSignature;\n }\n\n // Unlike the top-level helper below, this method expects a digest that has\n // already been hashed to the curve's message representative.\n recoverPublicKey(messageHash: TArg<Uint8Array>): WeierstrassPoint<bigint> {\n const { r, s } = this;\n const recovery = this.assertRecovery();\n const radj = recovery === 2 || recovery === 3 ? r + CURVE_ORDER : r;\n if (!Fp.isValid(radj)) throw new Error('invalid recovery id: sig.r+curve.n != R.x');\n const x = Fp.toBytes(radj);\n const R = Point.fromBytes(concatBytes(pprefix((recovery & 1) === 0), x));\n const ir = Fn.inv(radj); // r^-1\n const h = bits2int_modN(abytes(messageHash, undefined, 'msgHash')); // Truncate hash\n const u1 = Fn.create(-h * ir); // -hr^-1\n const u2 = Fn.create(s * ir); // sr^-1\n // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1). unsafe is fine: there is no private data.\n const Q = Point.BASE.multiplyUnsafe(u1).add(R.multiplyUnsafe(u2));\n if (Q.is0()) throw new Error('invalid recovery: point at infinify');\n Q.assertValidity();\n return Q;\n }\n\n // Signatures should be low-s, to prevent malleability.\n hasHighS(): boolean {\n return isBiggerThanHalfOrder(this.s);\n }\n\n toBytes(format: ECDSASignatureFormat = defaultSigOpts.format): TRet<Uint8Array> {\n validateSigFormat(format);\n if (format === 'der') return hexToBytes(DER.hexFromSig(this)) as TRet<Uint8Array>;\n const { r, s } = this;\n const rb = Fn.toBytes(r);\n const sb = Fn.toBytes(s);\n if (format === 'recovered') {\n assertRecoverableCurve();\n return concatBytes(Uint8Array.of(this.assertRecovery()), rb, sb) as TRet<Uint8Array>;\n }\n return concatBytes(rb, sb) as TRet<Uint8Array>;\n }\n\n toHex(format?: ECDSASignatureFormat) {\n return bytesToHex(this.toBytes(format));\n }\n }\n type RecoveredSignature = Signature & { recovery: number };\n Object.freeze(Signature.prototype);\n Object.freeze(Signature);\n\n // RFC6979: ensure ECDSA msg is X bytes and < N. RFC suggests optional truncating via bits2octets.\n // FIPS 186-4 4.6 suggests the leftmost min(nBitLen, outLen) bits, which matches bits2int.\n // bits2int can produce res>N, we can do mod(res, N) since the bitLen is the same.\n // int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors\n const bits2int: (bytes: TArg<Uint8Array>) => bigint =\n ecdsaOpts.bits2int === undefined\n ? function bits2int_def(bytes: TArg<Uint8Array>): bigint {\n // Our custom check \"just in case\", for protection against DoS\n if (bytes.length > 8192) throw new Error('input is too large');\n // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)\n // for some cases, since bytes.length * 8 is not actual bitLength.\n const num = bytesToNumberBE(bytes); // check for == u8 done here\n const delta = bytes.length * 8 - fnBits; // truncate to nBitLength leftmost bits\n return delta > 0 ? num >> BigInt(delta) : num;\n }\n : (ecdsaOpts.bits2int as (bytes: TArg<Uint8Array>) => bigint);\n const bits2int_modN: (bytes: TArg<Uint8Array>) => bigint =\n ecdsaOpts.bits2int_modN === undefined\n ? function bits2int_modN_def(bytes: TArg<Uint8Array>): bigint {\n return Fn.create(bits2int(bytes)); // can't use bytesToNumberBE here\n }\n : (ecdsaOpts.bits2int_modN as (bytes: TArg<Uint8Array>) => bigint);\n const ORDER_MASK = bitMask(fnBits);\n // Pads output with zero as per spec.\n /** Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`. */\n function int2octets(num: bigint): TRet<Uint8Array> {\n aInRange('num < 2^' + fnBits, num, _0n, ORDER_MASK);\n return Fn.toBytes(num) as TRet<Uint8Array>;\n }\n\n function validateMsgAndHash(message: TArg<Uint8Array>, prehash: boolean): TRet<Uint8Array> {\n abytes(message, undefined, 'message');\n return (\n prehash ? abytes(hash_(message), undefined, 'prehashed message') : message\n ) as TRet<Uint8Array>;\n }\n\n /**\n * Steps A, D of RFC6979 3.2.\n * Creates RFC6979 seed; converts msg/privKey to numbers.\n * Used only in sign, not in verify.\n *\n * Warning: we cannot assume here that message has same amount of bytes as curve order,\n * this will be invalid at least for P521. Also it can be bigger for P224 + SHA256.\n */\n function prepSig(\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts: TArg<ECDSASignOpts>\n ) {\n const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts);\n message = validateMsgAndHash(message, prehash); // RFC6979 3.2 A: h1 = H(m)\n // We can't later call bits2octets, since nested bits2int is broken for curves\n // with fnBits % 8 !== 0. Because of that, we unwrap it here as int2octets call.\n // const bits2octets = (bits) => int2octets(bits2int_modN(bits))\n const h1int = bits2int_modN(message);\n const d = Fn.fromBytes(secretKey); // validate secret key, convert to bigint\n if (!Fn.isValidNot0(d)) throw new Error('invalid private key');\n const seedArgs: TArg<Uint8Array>[] = [int2octets(d), int2octets(h1int)];\n // extraEntropy. RFC6979 3.6: additional k' (optional).\n if (extraEntropy != null && extraEntropy !== false) {\n // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')\n // gen random bytes OR pass as-is\n const e = extraEntropy === true ? randomBytes(lengths.secretKey) : extraEntropy;\n seedArgs.push(abytes(e, undefined, 'extraEntropy')); // check for being bytes\n }\n const seed = concatBytes(...seedArgs) as TRet<Uint8Array>; // Step D of RFC6979 3.2\n const m = h1int; // no need to call bits2int second time here, it is inside truncateHash!\n // Converts signature params into point w r/s, checks result for validity.\n // To transform k => Signature:\n // q = k⋅G\n // r = q.x mod n\n // s = k^-1(m + rd) mod n\n // Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to\n // https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it:\n // a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT\n function k2sig(kBytes: TArg<Uint8Array>): Signature | undefined {\n // RFC 6979 Section 3.2, step 3: k = bits2int(T)\n // Important: all mod() calls here must be done over N\n const k = bits2int(kBytes); // Cannot use fields methods, since it is group element\n if (!Fn.isValidNot0(k)) return; // Valid scalars (including k) must be in 1..N-1\n const ik = Fn.inv(k); // k^-1 mod n\n const q = Point.BASE.multiply(k).toAffine(); // q = k⋅G\n const r = Fn.create(q.x); // r = q.x mod n\n if (r === _0n) return;\n const s = Fn.create(ik * Fn.create(m + r * d)); // s = k^-1(m + rd) mod n\n if (s === _0n) return;\n let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3 when q.x>n)\n let normS = s;\n if (lowS && isBiggerThanHalfOrder(s)) {\n normS = Fn.neg(s); // if lowS was passed, ensure s is always in the bottom half of N\n recovery ^= 1;\n }\n return new Signature(r, normS, hasLargeRecoveryLifts ? undefined : recovery);\n }\n return { seed, k2sig };\n }\n\n /**\n * Signs a message or message hash with a secret key.\n * With the default `prehash: true`, raw message bytes are hashed internally;\n * only `{ prehash: false }` expects a caller-supplied digest.\n *\n * ```\n * sign(m, d) where\n * k = rfc6979_hmac_drbg(m, d)\n * (x, y) = G × k\n * r = x mod n\n * s = (m + dr) / k mod n\n * ```\n */\n function sign(\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts: TArg<ECDSASignOpts> = {}\n ): TRet<Uint8Array> {\n const { seed, k2sig } = prepSig(message, secretKey, opts); // Steps A, D of RFC6979 3.2.\n const drbg = createHmacDrbg<Signature>(hash_.outputLen, Fn.BYTES, hmac);\n const sig = drbg(seed, k2sig); // Steps B, C, D, E, F, G\n return sig.toBytes(opts.format);\n }\n\n /**\n * Verifies a signature against message and public key.\n * Rejects lowS signatures by default: see {@link ECDSAVerifyOpts}.\n * Implements section 4.1.4 from https://www.secg.org/sec1-v2.pdf:\n *\n * ```\n * verify(r, s, h, P) where\n * u1 = hs^-1 mod n\n * u2 = rs^-1 mod n\n * R = u1⋅G + u2⋅P\n * mod(R.x, n) == r\n * ```\n */\n function verify(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>,\n opts: TArg<ECDSAVerifyOpts> = {}\n ): boolean {\n const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);\n publicKey = abytes(publicKey, undefined, 'publicKey');\n message = validateMsgAndHash(message, prehash);\n if (!isBytes(signature as any)) {\n const end = signature instanceof Signature ? ', use sig.toBytes()' : '';\n throw new Error('verify expects Uint8Array signature' + end);\n }\n validateSigLength(signature, format); // execute this twice because we want loud error\n try {\n const sig = Signature.fromBytes(signature, format);\n const P = Point.fromBytes(publicKey);\n if (lowS && sig.hasHighS()) return false;\n const { r, s } = sig;\n const h = bits2int_modN(message); // mod n, not mod p\n const is = Fn.inv(s); // s^-1 mod n\n const u1 = Fn.create(h * is); // u1 = hs^-1 mod n\n const u2 = Fn.create(r * is); // u2 = rs^-1 mod n\n const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2)); // u1⋅G + u2⋅P\n if (R.is0()) return false;\n const v = Fn.create(R.x); // v = r.x mod n\n return v === r;\n } catch (e) {\n return false;\n }\n }\n\n function recoverPublicKey(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n opts: TArg<ECDSARecoverOpts> = {}\n ): TRet<Uint8Array> {\n // Top-level recovery mirrors `sign()` / `verify()`: it hashes raw message\n // bytes first unless the caller passes `{ prehash: false }`.\n const { prehash } = validateSigOpts(opts, defaultSigOpts);\n message = validateMsgAndHash(message, prehash);\n return Signature.fromBytes(signature, 'recovered').recoverPublicKey(message).toBytes();\n }\n\n return Object.freeze({\n keygen,\n getPublicKey,\n getSharedSecret,\n utils,\n lengths,\n Point,\n sign,\n verify,\n recoverPublicKey,\n Signature,\n hash: hash_,\n }) satisfies Signer;\n}\n","/**\n * SECG secp256k1. See [pdf](https://www.secg.org/sec2-v2.pdf).\n *\n * Belongs to Koblitz curves: it has efficiently-computable GLV endomorphism ψ,\n * check out {@link EndomorphismOpts}. Seems to be rigid (not backdoored).\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { randomBytes } from '@noble/hashes/utils.js';\nimport { createKeygen, type CurveLengths } from './abstract/curve.ts';\nimport {\n createFROST,\n type FROST,\n type FrostPublic,\n type FrostSecret,\n type Nonces,\n} from './abstract/frost.ts';\nimport { createHasher, type H2CHasher, isogenyMap } from './abstract/hash-to-curve.ts';\nimport { Field, mapHashToField, pow2 } from './abstract/modular.ts';\nimport {\n type ECDSA,\n ecdsa,\n type EndomorphismOpts,\n mapToCurveSimpleSWU,\n type WeierstrassPoint as PointType,\n weierstrass,\n type WeierstrassOpts,\n type WeierstrassPointCons,\n} from './abstract/weierstrass.ts';\nimport {\n abytes,\n asciiToBytes,\n bytesToNumberBE,\n concatBytes,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n// Seems like generator was produced from some seed:\n// `Pointk1.BASE.multiply(Pointk1.Fn.inv(2n, N)).toAffine().x`\n// // gives short x 0x3b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63n\nconst secp256k1_CURVE: WeierstrassOpts<bigint> = {\n p: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),\n n: BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'),\n h: BigInt(1),\n a: BigInt(0),\n b: BigInt(7),\n Gx: BigInt('0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),\n Gy: BigInt('0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'),\n};\n\nconst secp256k1_ENDO: EndomorphismOpts = {\n beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),\n basises: [\n [BigInt('0x3086d221a7d46bcde86c90e49284eb15'), -BigInt('0xe4437ed6010e88286f547fa90abfe4c3')],\n [BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8'), BigInt('0x3086d221a7d46bcde86c90e49284eb15')],\n ],\n};\n\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _2n = /* @__PURE__ */ BigInt(2);\n\n/**\n * √n = n^((p+1)/4) for fields p = 3 mod 4. We unwrap the loop and multiply bit-by-bit.\n * (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]\n */\nfunction sqrtMod(y: bigint): bigint {\n const P = secp256k1_CURVE.p;\n // prettier-ignore\n const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);\n // prettier-ignore\n const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);\n const b2 = (y * y * y) % P; // x^3, 11\n const b3 = (b2 * b2 * y) % P; // x^7\n const b6 = (pow2(b3, _3n, P) * b3) % P;\n const b9 = (pow2(b6, _3n, P) * b3) % P;\n const b11 = (pow2(b9, _2n, P) * b2) % P;\n const b22 = (pow2(b11, _11n, P) * b11) % P;\n const b44 = (pow2(b22, _22n, P) * b22) % P;\n const b88 = (pow2(b44, _44n, P) * b44) % P;\n const b176 = (pow2(b88, _88n, P) * b88) % P;\n const b220 = (pow2(b176, _44n, P) * b44) % P;\n const b223 = (pow2(b220, _3n, P) * b3) % P;\n const t1 = (pow2(b223, _23n, P) * b22) % P;\n const t2 = (pow2(t1, _6n, P) * b2) % P;\n const root = pow2(t2, _2n, P);\n if (!Fpk1.eql(Fpk1.sqr(root), y)) throw new Error('Cannot find square root');\n return root;\n}\n\nconst Fpk1 = Field(secp256k1_CURVE.p, { sqrt: sqrtMod });\nconst Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, {\n Fp: Fpk1,\n endo: secp256k1_ENDO,\n});\n\n/**\n * secp256k1 curve: ECDSA and ECDH methods.\n *\n * Uses sha256 to hash messages. To use a different hash,\n * pass `{ prehash: false }` to sign / verify.\n *\n * @example\n * Generate one secp256k1 keypair, sign a message, and verify it.\n *\n * ```js\n * import { secp256k1 } from '@noble/curves/secp256k1.js';\n * const { secretKey, publicKey } = secp256k1.keygen();\n * // const publicKey = secp256k1.getPublicKey(secretKey);\n * const msg = new TextEncoder().encode('hello noble');\n * const sig = secp256k1.sign(msg, secretKey);\n * const isValid = secp256k1.verify(sig, msg, publicKey);\n * // const sigKeccak = secp256k1.sign(keccak256(msg), secretKey, { prehash: false });\n * ```\n */\nexport const secp256k1: ECDSA = /* @__PURE__ */ ecdsa(Pointk1, sha256);\n\n// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.\n// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki\n/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */\nconst TAGGED_HASH_PREFIXES: { [tag: string]: Uint8Array } = {};\n// BIP-340 phrases tags as UTF-8, but all current standardized names here are 7-bit ASCII.\nfunction taggedHash(tag: string, ...messages: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let tagP = TAGGED_HASH_PREFIXES[tag];\n if (tagP === undefined) {\n const tagH = sha256(asciiToBytes(tag));\n tagP = concatBytes(tagH, tagH);\n TAGGED_HASH_PREFIXES[tag] = tagP;\n }\n return sha256(concatBytes(tagP, ...messages)) as TRet<Uint8Array>;\n}\n\n// ECDSA compact points are 33-byte. Schnorr is 32: we strip first byte 0x02 or 0x03\nconst pointToBytes = (point: TArg<PointType<bigint>>): TRet<Uint8Array> =>\n point.toBytes(true).slice(1) as TRet<Uint8Array>;\nconst hasEven = (y: bigint) => y % _2n === _0n;\n\n// Calculate point, scalar and bytes\nfunction schnorrGetExtPubKey(priv: TArg<Uint8Array>) {\n const { Fn, BASE } = Pointk1;\n const d_ = Fn.fromBytes(priv);\n const p = BASE.multiply(d_); // P = d'⋅G; 0 < d' < n check is done inside\n const scalar = hasEven(p.y) ? d_ : Fn.neg(d_);\n return { scalar, bytes: pointToBytes(p) };\n}\n/**\n * lift_x from BIP340. Convert 32-byte x coordinate to elliptic curve point.\n * @returns valid point checked for being on-curve\n */\nfunction lift_x(x: bigint): PointType<bigint> {\n const Fp = Fpk1;\n if (!Fp.isValidNot0(x)) throw new Error('invalid x: Fail if x ≥ p');\n const xx = Fp.create(x * x);\n const c = Fp.create(xx * x + BigInt(7)); // Let c = x³ + 7 mod p.\n let y = Fp.sqrt(c); // Let y = c^(p+1)/4 mod p. Same as sqrt().\n // Return the unique point P such that x(P) = x and\n // y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.\n if (!hasEven(y)) y = Fp.neg(y);\n const p = Pointk1.fromAffine({ x, y });\n p.assertValidity();\n return p;\n}\n// BIP-340 callers still need to supply canonical 32-byte inputs where required; this alias only\n// parses big-endian bytes and does not enforce the fixed-width contract itself.\nconst num = bytesToNumberBE;\n/** Create tagged hash, convert it to bigint, reduce modulo-n. */\nfunction challenge(...args: TArg<Uint8Array[]>): bigint {\n return Pointk1.Fn.create(num(taggedHash('BIP0340/challenge', ...args)));\n}\n\n/** Schnorr public key is just `x` coordinate of Point as per BIP340. */\nfunction schnorrGetPublicKey(secretKey: TArg<Uint8Array>): TRet<Uint8Array> {\n return schnorrGetExtPubKey(secretKey).bytes; // d'=int(sk). Fail if d'=0 or d'≥n. Ret bytes(d'⋅G)\n}\n\n/**\n * Creates Schnorr signature as per BIP340. Verifies itself before returning anything.\n * `auxRand` is optional and is not the sole source of `k` generation: bad CSPRNG output will not\n * be catastrophic, but BIP-340 still recommends fresh auxiliary randomness when available to harden\n * deterministic signing against side-channel and fault-injection attacks.\n */\nfunction schnorrSign(\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n auxRand: TArg<Uint8Array> = randomBytes(32)\n): TRet<Uint8Array> {\n const { Fn, BASE } = Pointk1;\n const m = abytes(message, undefined, 'message');\n const { bytes: px, scalar: d } = schnorrGetExtPubKey(secretKey); // checks for isWithinCurveOrder\n const a = abytes(auxRand, 32, 'auxRand'); // Auxiliary random data a: a 32-byte array\n // Let t be the byte-wise xor of bytes(d) and hash/aux(a).\n const t = Fn.toBytes(d ^ num(taggedHash('BIP0340/aux', a)));\n const rand = taggedHash('BIP0340/nonce', t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)\n // BIP340 defines k' = int(rand) mod n. We can't reuse schnorrGetExtPubKey(rand)\n // here: that helper parses canonical secret keys and rejects rand >= n instead\n // of reducing the nonce hash modulo the group order.\n const k_ = Fn.create(num(rand));\n // BIP-340: \"Let k' = int(rand) mod n. Fail if k' = 0. Let R = k'⋅G.\"\n if (k_ === 0n) throw new Error('sign failed: k is zero');\n const p = BASE.multiply(k_); // Rejects zero; only the raw nonce hash needs reduction.\n const k = hasEven(p.y) ? k_ : Fn.neg(k_);\n const rx = pointToBytes(p);\n const e = challenge(rx, px, m); // Let e = int(hash/challenge(bytes(R) || bytes(P) || m)) mod n.\n const sig = new Uint8Array(64); // Let sig = bytes(R) || bytes((k + ed) mod n).\n sig.set(rx, 0);\n sig.set(Fn.toBytes(Fn.create(k + e * d)), 32);\n // If Verify(bytes(P), m, sig) (see below) returns failure, abort\n if (!schnorrVerify(sig, m, px)) throw new Error('sign: Invalid signature produced');\n return sig as TRet<Uint8Array>;\n}\n\n/**\n * Verifies Schnorr signature.\n * Will swallow errors & return false except for initial type validation of arguments.\n */\nfunction schnorrVerify(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>\n): boolean {\n const { Fp, Fn, BASE } = Pointk1;\n const sig = abytes(signature, 64, 'signature');\n const m = abytes(message, undefined, 'message');\n const pub = abytes(publicKey, 32, 'publicKey');\n try {\n const P = lift_x(num(pub)); // P = lift_x(int(pk)); fail if that fails\n const r = num(sig.subarray(0, 32)); // Let r = int(sig[0:32]); fail if r ≥ p.\n if (!Fp.isValidNot0(r)) return false;\n const s = num(sig.subarray(32, 64)); // Let s = int(sig[32:64]); fail if s ≥ n.\n // Stricter than BIP-340/libsecp256k1, which only reject s >= n. Honest signing reaches\n // s = 0 only with negligible probability (k + e*d ≡ 0 mod n), so treat zero-s inputs as\n // crafted edge cases and fail closed instead of carrying that extra verification surface.\n if (!Fn.isValidNot0(s)) return false;\n\n // int(challenge(bytes(r) || bytes(P) || m)) % n\n const e = challenge(Fn.toBytes(r), pointToBytes(P), m);\n // R = s⋅G - e⋅P, where -eP == (n-e)P\n const R = BASE.multiplyUnsafe(s).add(P.multiplyUnsafe(Fn.neg(e)));\n const { x, y } = R.toAffine();\n // Fail if is_infinite(R) / not has_even_y(R) / x(R) ≠ r.\n if (R.is0() || !hasEven(y) || x !== r) return false;\n return true;\n } catch (error) {\n return false;\n }\n}\n\nexport const __TEST: { lift_x: typeof lift_x } = /* @__PURE__ */ Object.freeze({ lift_x });\n\n/** Schnorr-specific secp256k1 API from BIP340. */\nexport type SecpSchnorr = {\n /**\n * Generate one Schnorr secret/public keypair.\n * @param seed - Optional seed for deterministic testing or custom randomness.\n * @returns Fresh secret/public keypair.\n */\n keygen: (seed?: TArg<Uint8Array>) => { secretKey: TRet<Uint8Array>; publicKey: TRet<Uint8Array> };\n /**\n * Derive the x-only public key from a secret key.\n * @param secretKey - Secret key bytes.\n * @returns X-only public key bytes.\n */\n getPublicKey: typeof schnorrGetPublicKey;\n /**\n * Create one BIP340 Schnorr signature.\n * @param message - Message bytes to sign.\n * @param secretKey - Secret key bytes.\n * @param auxRand - Optional auxiliary randomness.\n * @returns Compact Schnorr signature bytes.\n */\n sign: typeof schnorrSign;\n /**\n * Verify one BIP340 Schnorr signature.\n * @param signature - Compact signature bytes.\n * @param message - Signed message bytes.\n * @param publicKey - X-only public key bytes.\n * @returns `true` when the signature is valid.\n */\n verify: typeof schnorrVerify;\n /** Underlying secp256k1 point constructor. */\n Point: WeierstrassPointCons<bigint>;\n /** Helper utilities for Schnorr-specific key handling and tagged hashing. */\n utils: {\n /** Generate one Schnorr secret key. */\n randomSecretKey: (seed?: TArg<Uint8Array>) => TRet<Uint8Array>;\n /** Convert one point into its x-only BIP340 byte encoding. */\n pointToBytes: (point: TArg<PointType<bigint>>) => TRet<Uint8Array>;\n /** Lift one x coordinate into the unique even-Y point. */\n lift_x: typeof lift_x;\n /** Compute a BIP340 tagged hash. */\n taggedHash: typeof taggedHash;\n };\n /** Public byte lengths for keys, signatures, and seeds. */\n lengths: CurveLengths;\n};\n/**\n * Schnorr signatures over secp256k1.\n * See {@link https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki | BIP 340}.\n * @example\n * Generate one BIP340 Schnorr keypair, sign a message, and verify it.\n *\n * ```js\n * import { schnorr } from '@noble/curves/secp256k1.js';\n * const { secretKey, publicKey } = schnorr.keygen();\n * // const publicKey = schnorr.getPublicKey(secretKey);\n * const msg = new TextEncoder().encode('hello');\n * const sig = schnorr.sign(msg, secretKey);\n * const isValid = schnorr.verify(sig, msg, publicKey);\n * ```\n */\nexport const schnorr: SecpSchnorr = /* @__PURE__ */ (() => {\n const size = 32;\n const seedLength = 48;\n const randomSecretKey = (seed?: TArg<Uint8Array>): TRet<Uint8Array> => {\n seed = seed === undefined ? randomBytes(seedLength) : seed;\n return mapHashToField(seed, secp256k1_CURVE.n);\n };\n return Object.freeze({\n keygen: createKeygen(randomSecretKey, schnorrGetPublicKey),\n getPublicKey: schnorrGetPublicKey,\n sign: schnorrSign,\n verify: schnorrVerify,\n Point: Pointk1,\n utils: Object.freeze({\n randomSecretKey,\n taggedHash,\n lift_x,\n pointToBytes,\n }),\n lengths: Object.freeze({\n secretKey: size,\n publicKey: size,\n publicKeyHasPrefix: false,\n signature: size * 2,\n seed: seedLength,\n }),\n });\n})();\n\n// RFC 9380 Appendix E.1 3-isogeny coefficients for secp256k1, stored in ascending degree order.\n// The final `1` in each denominator array is the explicit monic leading term.\nconst isoMap = /* @__PURE__ */ (() =>\n isogenyMap(\n Fpk1,\n [\n // xNum\n [\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7',\n '0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581',\n '0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262',\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c',\n ],\n // xDen\n [\n '0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b',\n '0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n // yNum\n [\n '0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c',\n '0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3',\n '0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931',\n '0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84',\n ],\n // yDen\n [\n '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b',\n '0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573',\n '0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n ].map((i) => i.map((j) => BigInt(j))) as [bigint[], bigint[], bigint[], bigint[]]\n ))();\n// RFC 9380 §8.7 secp256k1 E' parameters for the SWU-to-isogeny pipeline below.\nlet mapSWU: ((u: bigint) => { x: bigint; y: bigint }) | undefined;\nconst getMapSWU = () =>\n mapSWU ||\n (mapSWU = mapToCurveSimpleSWU(Fpk1, {\n // Building the SWU sqrt-ratio helper eagerly adds noticeable `secp256k1.js` import cost, so\n // defer it to first use; after that the cached mapper is reused directly.\n A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),\n B: BigInt('1771'),\n Z: Fpk1.create(BigInt('-11')),\n }));\n\n/**\n * Hashing / encoding to secp256k1 points / field. RFC 9380 methods.\n * @example\n * Hash one message onto secp256k1.\n *\n * ```ts\n * const point = secp256k1_hasher.hashToCurve(new TextEncoder().encode('hello noble'));\n * ```\n */\nexport const secp256k1_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__ */ (() =>\n createHasher(\n Pointk1,\n (scalars: bigint[]) => {\n const { x, y } = getMapSWU()(Fpk1.create(scalars[0]));\n return isoMap(x, y);\n },\n {\n DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',\n encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_',\n p: Fpk1.ORDER,\n m: 1,\n k: 128,\n expand: 'xmd',\n hash: sha256,\n }\n ))();\n/**\n * FROST threshold signatures over secp256k1. RFC 9591.\n * @example\n * Create one trusted-dealer package for 2-of-3 secp256k1 signing.\n *\n * ```ts\n * const alice = secp256k1_FROST.Identifier.derive('alice@example.com');\n * const bob = secp256k1_FROST.Identifier.derive('bob@example.com');\n * const carol = secp256k1_FROST.Identifier.derive('carol@example.com');\n * const deal = secp256k1_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);\n * ```\n */\nexport const secp256k1_FROST: TRet<FROST> = /* @__PURE__ */ (() =>\n createFROST({\n name: 'FROST-secp256k1-SHA256-v1',\n Point: Pointk1,\n hashToScalar: secp256k1_hasher.hashToScalar,\n hash: sha256,\n }))();\n\n// Taproot utils\n// `undefined` means \"disable TapTweak entirely\"; callers that want the BIP-341/BIP-386 empty\n// merkle root must pass `new Uint8Array(0)` explicitly.\nfunction tweak(point: PointType<bigint>, merkleRoot?: TArg<Uint8Array>): bigint {\n if (merkleRoot === undefined) return _0n;\n const x = pointToBytes(point);\n const t = bytesToNumberBE(taggedHash('TapTweak', x, merkleRoot));\n // BIP-341 taproot_tweak_pubkey/taproot_tweak_seckey: \"if t >= SECP256K1_ORDER:\n // raise ValueError\". TapTweak must reject overflow instead of reducing modulo n.\n if (!Pointk1.Fn.isValid(t)) throw new Error('invalid TapTweak hash');\n return t;\n}\nfunction frostPubToEvenY(pub: TArg<FrostPublic>): TRet<FrostPublic> {\n const VK = Pointk1.fromBytes(pub.commitments[0]);\n // Keep aliasing on the already-even path so wrapper callers can skip unnecessary cloning.\n if (hasEven(VK.y)) return pub as TRet<FrostPublic>;\n return {\n signers: { min: pub.signers.min, max: pub.signers.max },\n commitments: pub.commitments.map((i) => Pointk1.fromBytes(i).negate().toBytes()),\n verifyingShares: Object.fromEntries(\n Object.entries(pub.verifyingShares).map(([k, v]) => [\n k,\n Pointk1.fromBytes(v).negate().toBytes(),\n ])\n ),\n } as TRet<FrostPublic>;\n}\nfunction frostSecretToEvenY(s: TArg<FrostSecret>, pub: TArg<FrostPublic>): TRet<FrostSecret> {\n const VK = Pointk1.fromBytes(pub.commitments[0]);\n // Keep aliasing on the already-even path so wrapper callers can preserve package identity.\n if (hasEven(VK.y)) return s as TRet<FrostSecret>;\n const Fn = Pointk1.Fn;\n return {\n ...s,\n signingShare: Fn.toBytes(Fn.neg(Fn.fromBytes(s.signingShare))),\n } as TRet<FrostSecret>;\n}\nfunction frostNoncesToEvenY(PK: PointType<bigint>, nonces: TArg<Nonces>): TRet<Nonces> {\n if (hasEven(PK.y)) return nonces as TRet<Nonces>;\n const Fn = Pointk1.Fn;\n return {\n binding: Fn.toBytes(Fn.neg(Fn.fromBytes(nonces.binding))),\n hiding: Fn.toBytes(Fn.neg(Fn.fromBytes(nonces.hiding))),\n } as TRet<Nonces>;\n}\n\nfunction frostTweakSecret(\n s: TArg<FrostSecret>,\n pub: TArg<FrostPublic>,\n merkleRoot?: TArg<Uint8Array>\n): TRet<FrostSecret> {\n const Fn = Pointk1.Fn;\n const keyPackage = frostSecretToEvenY(s, pub);\n const evenPub = frostPubToEvenY(pub);\n const t = tweak(Pointk1.fromBytes(evenPub.commitments[0]), merkleRoot);\n const signingShare = Fn.toBytes(Fn.add(Fn.fromBytes(keyPackage.signingShare), t));\n return {\n identifier: keyPackage.identifier,\n signingShare,\n } as TRet<FrostSecret>;\n}\n\nfunction frostTweakPublic(\n pub: TArg<FrostPublic>,\n merkleRoot?: TArg<Uint8Array>\n): TRet<FrostPublic> {\n const PKPackage = frostPubToEvenY(pub);\n const t = tweak(Pointk1.fromBytes(PKPackage.commitments[0]), merkleRoot);\n const tp = Pointk1.BASE.multiply(t);\n const commitments = PKPackage.commitments.map((c, i) =>\n (i === 0 ? Pointk1.fromBytes(c).add(tp) : Pointk1.fromBytes(c)).toBytes()\n );\n const verifyingShares: Record<string, Uint8Array> = {};\n for (const k in PKPackage.verifyingShares) {\n verifyingShares[k] = Pointk1.fromBytes(PKPackage.verifyingShares[k]).add(tp).toBytes();\n }\n return {\n signers: { min: PKPackage.signers.min, max: PKPackage.signers.max },\n commitments,\n verifyingShares,\n } as TRet<FrostPublic>;\n}\n\n/**\n * FROST threshold signatures over secp256k1-schnorr-taproot. RFC 9591.\n * DKG outputs are auto-tweaked with the empty Taproot merkle root for compatibility, while\n * `trustedDealer()` outputs stay untweaked unless callers apply the Taproot tweak themselves.\n * @example\n * Create one trusted-dealer package for Taproot-compatible FROST signing.\n *\n * ```ts\n * const alice = schnorr_FROST.Identifier.derive('alice@example.com');\n * const bob = schnorr_FROST.Identifier.derive('bob@example.com');\n * const carol = schnorr_FROST.Identifier.derive('carol@example.com');\n * const deal = schnorr_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);\n * ```\n */\nexport const schnorr_FROST: TRet<FROST> = /* @__PURE__ */ (() =>\n createFROST({\n name: 'FROST-secp256k1-SHA256-TR-v1',\n Point: Pointk1,\n hashToScalar: secp256k1_hasher.hashToScalar,\n hash: sha256,\n // Taproot related hacks\n parsePublicKey(publicKey) {\n // External Taproot keys are x-only, but local key packages still use compressed points.\n if (publicKey.length === 32) return lift_x(bytesToNumberBE(publicKey));\n if (publicKey.length === 33) return Pointk1.fromBytes(publicKey);\n throw new Error(`expected x-only or compressed public key, got length=${publicKey.length}`);\n },\n adjustScalar(n: bigint) {\n const PK = Pointk1.BASE.multiply(n);\n return hasEven(PK.y) ? n : Pointk1.Fn.neg(n);\n },\n adjustPoint: (p) => (hasEven(p.y) ? p : p.negate()),\n challenge(R, PK, msg) {\n return challenge(pointToBytes(R), pointToBytes(PK), msg);\n },\n adjustNonces: frostNoncesToEvenY,\n adjustGroupCommitmentShare: (GC, GCShare) => (!hasEven(GC.y) ? GCShare.negate() : GCShare),\n adjustPublic: frostPubToEvenY,\n adjustSecret: frostSecretToEvenY,\n adjustTx: {\n // Compat with official implementation\n encode: (tx) => tx.subarray(1) as TRet<Uint8Array>,\n decode: (tx) => concatBytes(Uint8Array.of(0x02), tx) as TRet<Uint8Array>,\n },\n adjustDKG: (k) => {\n // Compatibility with frost-secp256k1-tr: DKG output is auto-tweaked with the\n // empty Taproot merkle root, while dealer-generated keys stay untweaked.\n const merkleRoot = new Uint8Array(0);\n return {\n public: frostTweakPublic(k.public, merkleRoot),\n secret: frostTweakSecret(k.secret, k.public, merkleRoot),\n };\n },\n }))();\n","/**\n * Cryptographic utilities for SDK2\n *\n * Provides BIP39 mnemonic and BIP32 key derivation functions.\n * Platform-independent - no browser-specific APIs.\n */\n\nimport { secp256k1 } from '@noble/curves/secp256k1.js';\nimport * as bip39 from 'bip39';\nimport CryptoJS from 'crypto-js';\nimport { SphereError } from './errors';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** secp256k1 curve order */\nconst CURVE_ORDER = BigInt(\n '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'\n);\n\n/** A secp256k1 private key is exactly 32 bytes — 64 hex chars. */\nconst PRIVKEY_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\n/**\n * Reject a malformed private key BEFORE it reaches the curve (#674 review).\n * `hexToBytes` coerces any non-hex character to a zero byte\n * (`parseInt('gg', 16)` → NaN → 0), so a right-length string with a stray\n * non-hex char would otherwise derive/sign with a DIFFERENT valid key and no\n * error — silently signing with an unintended key. secp256k1 already rejects\n * wrong-*length* input; this closes the same-length-wrong-chars hole.\n */\nfunction assertPrivKeyHex(privateKeyHex: string): void {\n if (!PRIVKEY_HEX_RE.test(privateKeyHex)) {\n throw new SphereError(\n `Invalid private key: expected 64 hex chars, got ${privateKeyHex.length}`,\n 'VALIDATION_ERROR',\n );\n }\n}\n\n/** Default derivation path for Unicity (BIP44) */\nexport const DEFAULT_DERIVATION_PATH = \"m/44'/0'/0'\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MasterKey {\n privateKey: string;\n chainCode: string;\n}\n\nexport interface DerivedKey {\n privateKey: string;\n chainCode: string;\n}\n\nexport interface KeyPair {\n privateKey: string;\n publicKey: string;\n}\n\nexport interface AddressInfo extends KeyPair {\n path: string;\n index: number;\n}\n\n// =============================================================================\n// BIP39 Mnemonic Functions\n// =============================================================================\n\n/**\n * Generate a new BIP39 mnemonic phrase\n * @param strength - Entropy bits (128 = 12 words, 256 = 24 words)\n */\nexport function generateMnemonic(strength: 128 | 256 = 128): string {\n return bip39.generateMnemonic(strength);\n}\n\n/**\n * Validate a BIP39 mnemonic phrase\n */\nexport function validateMnemonic(mnemonic: string): boolean {\n return bip39.validateMnemonic(mnemonic);\n}\n\n/**\n * Convert mnemonic to seed (64-byte hex string)\n * @param mnemonic - BIP39 mnemonic phrase\n * @param passphrase - Optional passphrase for additional security\n */\nexport async function mnemonicToSeed(\n mnemonic: string,\n passphrase: string = ''\n): Promise<string> {\n const seedBuffer = await bip39.mnemonicToSeed(mnemonic, passphrase);\n return Buffer.from(seedBuffer).toString('hex');\n}\n\n/**\n * Synchronous version of mnemonicToSeed\n */\nexport function mnemonicToSeedSync(\n mnemonic: string,\n passphrase: string = ''\n): string {\n const seedBuffer = bip39.mnemonicToSeedSync(mnemonic, passphrase);\n return Buffer.from(seedBuffer).toString('hex');\n}\n\n/**\n * Convert mnemonic to entropy (for recovery purposes)\n */\nexport function mnemonicToEntropy(mnemonic: string): string {\n return bip39.mnemonicToEntropy(mnemonic);\n}\n\n/**\n * Convert entropy to mnemonic\n */\nexport function entropyToMnemonic(entropy: string): string {\n return bip39.entropyToMnemonic(entropy);\n}\n\n// =============================================================================\n// BIP32 Key Derivation\n// =============================================================================\n\n/**\n * Generate master key from seed (BIP32 standard)\n * Uses HMAC-SHA512 with key \"Bitcoin seed\"\n */\nexport function generateMasterKey(seedHex: string): MasterKey {\n const I = CryptoJS.HmacSHA512(\n CryptoJS.enc.Hex.parse(seedHex),\n CryptoJS.enc.Utf8.parse('Bitcoin seed')\n ).toString();\n\n const IL = I.substring(0, 64); // Left 32 bytes - master private key\n const IR = I.substring(64); // Right 32 bytes - master chain code\n\n // Validate master key\n const masterKeyBigInt = BigInt('0x' + IL);\n if (masterKeyBigInt === 0n || masterKeyBigInt >= CURVE_ORDER) {\n throw new SphereError('Invalid master key generated', 'VALIDATION_ERROR');\n }\n\n return {\n privateKey: IL,\n chainCode: IR,\n };\n}\n\n/**\n * Derive child key using BIP32 standard\n * @param parentPrivKey - Parent private key (64 hex chars)\n * @param parentChainCode - Parent chain code (64 hex chars)\n * @param index - Child index (>= 0x80000000 for hardened)\n */\nexport function deriveChildKey(\n parentPrivKey: string,\n parentChainCode: string,\n index: number\n): DerivedKey {\n const isHardened = index >= 0x80000000;\n let data: string;\n\n if (isHardened) {\n // Hardened derivation: 0x00 || parentPrivKey || index\n const indexHex = index.toString(16).padStart(8, '0');\n data = '00' + parentPrivKey + indexHex;\n } else {\n // Non-hardened derivation: compressedPubKey || index\n const compressedPubKey = getPublicKey(parentPrivKey, true);\n const indexHex = index.toString(16).padStart(8, '0');\n data = compressedPubKey + indexHex;\n }\n\n // HMAC-SHA512 with chain code as key\n const I = CryptoJS.HmacSHA512(\n CryptoJS.enc.Hex.parse(data),\n CryptoJS.enc.Hex.parse(parentChainCode)\n ).toString();\n\n const IL = I.substring(0, 64); // Left 32 bytes\n const IR = I.substring(64); // Right 32 bytes (new chain code)\n\n // Add IL to parent key mod n (curve order)\n const ilBigInt = BigInt('0x' + IL);\n const parentKeyBigInt = BigInt('0x' + parentPrivKey);\n\n // Check IL is valid (less than curve order)\n if (ilBigInt >= CURVE_ORDER) {\n throw new SphereError('Invalid key: IL >= curve order', 'VALIDATION_ERROR');\n }\n\n const childKeyBigInt = (ilBigInt + parentKeyBigInt) % CURVE_ORDER;\n\n // Check child key is valid (not zero)\n if (childKeyBigInt === 0n) {\n throw new SphereError('Invalid key: child key is zero', 'VALIDATION_ERROR');\n }\n\n const childPrivKey = childKeyBigInt.toString(16).padStart(64, '0');\n\n return {\n privateKey: childPrivKey,\n chainCode: IR,\n };\n}\n\n/**\n * Derive key at a full BIP32/BIP44 path\n * @param masterPrivKey - Master private key\n * @param masterChainCode - Master chain code\n * @param path - BIP44 path like \"m/44'/0'/0'/0/0\"\n */\nexport function deriveKeyAtPath(\n masterPrivKey: string,\n masterChainCode: string,\n path: string\n): DerivedKey {\n const pathParts = path.replace('m/', '').split('/');\n\n let currentKey = masterPrivKey;\n let currentChainCode = masterChainCode;\n\n for (const part of pathParts) {\n const isHardened = part.endsWith(\"'\") || part.endsWith('h');\n const indexStr = part.replace(/['h]$/, '');\n let index = parseInt(indexStr, 10);\n\n if (isHardened) {\n index += 0x80000000; // Add hardened offset\n }\n\n const derived = deriveChildKey(currentKey, currentChainCode, index);\n currentKey = derived.privateKey;\n currentChainCode = derived.chainCode;\n }\n\n return {\n privateKey: currentKey,\n chainCode: currentChainCode,\n };\n}\n\n// =============================================================================\n// Key Pair Operations\n// =============================================================================\n\n/**\n * Get public key from private key\n * @param privateKey - Private key as hex string\n * @param compressed - Return compressed public key (default: true)\n */\nexport function getPublicKey(privateKey: string, compressed: boolean = true): string {\n assertPrivKeyHex(privateKey);\n // SEC1 encoding: compressed = 02/03 prefix + x (33 bytes),\n // uncompressed = 04 prefix + x + y (65 bytes) — identical to elliptic's output.\n return bytesToHex(secp256k1.getPublicKey(hexToBytes(privateKey), compressed));\n}\n\n/**\n * Create key pair from private key\n */\nexport function createKeyPair(privateKey: string): KeyPair {\n return {\n privateKey,\n publicKey: getPublicKey(privateKey),\n };\n}\n\n// =============================================================================\n// Hash Functions\n// =============================================================================\n\n/**\n * Compute SHA256 hash\n */\nexport function sha256(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const parsed =\n inputEncoding === 'hex'\n ? CryptoJS.enc.Hex.parse(data)\n : CryptoJS.enc.Utf8.parse(data);\n return CryptoJS.SHA256(parsed).toString();\n}\n\n/**\n * Compute RIPEMD160 hash\n */\nexport function ripemd160(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const parsed =\n inputEncoding === 'hex'\n ? CryptoJS.enc.Hex.parse(data)\n : CryptoJS.enc.Utf8.parse(data);\n return CryptoJS.RIPEMD160(parsed).toString();\n}\n\n/**\n * Compute HASH160 (SHA256 -> RIPEMD160)\n */\nexport function hash160(data: string): string {\n const sha = sha256(data, 'hex');\n return ripemd160(sha, 'hex');\n}\n\n/**\n * Compute double SHA256\n */\nexport function doubleSha256(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const first = sha256(data, inputEncoding);\n return sha256(first, 'hex');\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Convert hex string to Uint8Array\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const matches = hex.match(/../g);\n if (!matches) {\n return new Uint8Array(0);\n }\n return Uint8Array.from(matches.map((x) => parseInt(x, 16)));\n}\n\n/**\n * Convert Uint8Array to hex string\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Generate random bytes as hex string\n */\nexport function randomBytes(length: number): string {\n const words = CryptoJS.lib.WordArray.random(length);\n return words.toString(CryptoJS.enc.Hex);\n}\n\n// =============================================================================\n// High-Level Functions\n// =============================================================================\n\n/**\n * Generate identity from mnemonic\n * Returns master key derived from mnemonic seed\n */\nexport async function identityFromMnemonic(\n mnemonic: string,\n passphrase: string = ''\n): Promise<MasterKey> {\n if (!validateMnemonic(mnemonic)) {\n throw new SphereError('Invalid mnemonic phrase', 'INVALID_IDENTITY');\n }\n const seedHex = await mnemonicToSeed(mnemonic, passphrase);\n return generateMasterKey(seedHex);\n}\n\n/**\n * Synchronous version of identityFromMnemonic\n */\nexport function identityFromMnemonicSync(\n mnemonic: string,\n passphrase: string = ''\n): MasterKey {\n if (!validateMnemonic(mnemonic)) {\n throw new SphereError('Invalid mnemonic phrase', 'INVALID_IDENTITY');\n }\n const seedHex = mnemonicToSeedSync(mnemonic, passphrase);\n return generateMasterKey(seedHex);\n}\n\n/**\n * Derive key info at a specific path\n * @param masterKey - Master key with privateKey and chainCode\n * @param basePath - Base derivation path (e.g., \"m/44'/0'/0'\")\n * @param index - Address index\n * @param isChange - Whether this is a change address (chain 1 vs 0)\n */\nexport function deriveAddressInfo(\n masterKey: MasterKey,\n basePath: string,\n index: number,\n isChange: boolean = false\n): AddressInfo {\n const chain = isChange ? 1 : 0;\n const fullPath = `${basePath}/${chain}/${index}`;\n\n const derived = deriveKeyAtPath(masterKey.privateKey, masterKey.chainCode, fullPath);\n const publicKey = getPublicKey(derived.privateKey);\n\n return {\n privateKey: derived.privateKey,\n publicKey,\n path: fullPath,\n index,\n };\n}\n\n/**\n * Generate full key info from private key with index and path\n */\nexport function generateAddressInfo(\n privateKey: string,\n index: number,\n path: string\n): AddressInfo {\n const publicKey = getPublicKey(privateKey);\n return {\n privateKey,\n publicKey,\n path,\n index,\n };\n}\n\n/**\n * Generate key info from master private key using HMAC-SHA512 derivation\n * This matches exactly the original index.html implementation\n * NOTE: This is NON-STANDARD derivation for legacy wallet compatibility.\n *\n * Dual-use: in `wif_hmac` derivation mode (legacy wallet import) this derives\n * the wallet's chainPubkey (used for L3 identity).\n *\n * @param masterPrivateKey - 32-byte hex private key (64 chars)\n * @param index - Address index\n */\nexport function generateAddressFromMasterKey(\n masterPrivateKey: string,\n index: number\n): AddressInfo {\n const derivationPath = `m/44'/0'/${index}'`;\n\n // HMAC-SHA512 with path as key (matching index.html exactly)\n const hmacInput = CryptoJS.enc.Hex.parse(masterPrivateKey);\n const hmacKey = CryptoJS.enc.Utf8.parse(derivationPath);\n const hmacOutput = CryptoJS.HmacSHA512(hmacInput, hmacKey).toString();\n\n // Use left 32 bytes for private key\n const childPrivateKey = hmacOutput.substring(0, 64);\n\n return generateAddressInfo(childPrivateKey, index, derivationPath);\n}\n\n// =============================================================================\n// Message Signing (secp256k1 ECDSA with recoverable signature)\n// =============================================================================\n\n/** Prefix prepended to all signed messages (Bitcoin-like signed message format) */\nexport const SIGN_MESSAGE_PREFIX = 'Sphere Signed Message:\\n';\n\n/** Encode an integer as a Bitcoin-style compact varint */\nfunction varint(n: number): Uint8Array {\n if (n < 253) return new Uint8Array([n]);\n const buf = new Uint8Array(3);\n buf[0] = 253;\n buf[1] = n & 0xff;\n buf[2] = (n >> 8) & 0xff;\n return buf;\n}\n\n/**\n * Hash a message for signing using the Bitcoin-like double-SHA256 scheme:\n * SHA256(SHA256(varint(prefix.length) + prefix + varint(msg.length) + msg))\n *\n * @returns 64-char lowercase hex hash\n */\nexport function hashSignMessage(message: string): string {\n const prefix = new TextEncoder().encode(SIGN_MESSAGE_PREFIX);\n const msg = new TextEncoder().encode(message);\n const prefixLen = varint(prefix.length);\n const msgLen = varint(msg.length);\n const full = new Uint8Array(prefixLen.length + prefix.length + msgLen.length + msg.length);\n let off = 0;\n full.set(prefixLen, off); off += prefixLen.length;\n full.set(prefix, off); off += prefix.length;\n full.set(msgLen, off); off += msgLen.length;\n full.set(msg, off);\n const hex = Array.from(full).map(b => b.toString(16).padStart(2, '0')).join('');\n const h1 = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(hex)).toString();\n return CryptoJS.SHA256(CryptoJS.enc.Hex.parse(h1)).toString();\n}\n\n/**\n * Sign a message with a secp256k1 private key.\n *\n * Returns a 130-character hex string: v (2 chars) + r (64 chars) + s (64 chars).\n * The recovery byte `v` is `31 + recoveryParam` (0-3).\n *\n * @param privateKeyHex - 64-char hex private key\n * @param message - plaintext message to sign\n */\nexport function signMessage(privateKeyHex: string, message: string): string {\n assertPrivKeyHex(privateKeyHex);\n const hashHex = hashSignMessage(message);\n // prehash:false — the message is already hashed (double-SHA256 above);\n // lowS:true — canonical low-S signatures (same as elliptic's {canonical:true});\n // format:'recovered' — recoveryId(1) || r(32) || s(32), RFC6979-deterministic.\n const sigBytes = secp256k1.sign(hexToBytes(hashHex), hexToBytes(privateKeyHex), {\n prehash: false,\n lowS: true,\n format: 'recovered',\n });\n\n const recoveryParam = sigBytes[0];\n const v = (31 + recoveryParam).toString(16).padStart(2, '0');\n // r and s are fixed-width 32-byte big-endian — already left-padded.\n return v + bytesToHex(sigBytes.subarray(1));\n}\n\n/**\n * Verify a signed message against a compressed secp256k1 public key.\n *\n * @param message - The original plaintext message\n * @param signature - 130-char hex signature (v + r + s)\n * @param expectedPubkey - 66-char compressed public key hex\n * @returns `true` if the signature is valid and matches the expected public key\n */\nexport function verifySignedMessage(\n message: string,\n signature: string,\n expectedPubkey: string,\n): boolean {\n if (signature.length !== 130) return false;\n\n const v = parseInt(signature.slice(0, 2), 16) - 31;\n const r = signature.slice(2, 66);\n const s = signature.slice(66, 130);\n\n if (v < 0 || v > 3) return false;\n\n const hashHex = hashSignMessage(message);\n\n try {\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true) === expectedPubkey; // compressed\n } catch {\n return false;\n }\n}\n\n/**\n * Recover the compressed secp256k1 public key from a signed message.\n *\n * Use this when the server needs to identify the signer (not just verify\n * a signature against a known pubkey). Combined with `sphere.resolve(pubkey)`\n * it gives a fully cryptographically-attributable identity for backend auth,\n * without trusting any client-supplied identifier claim.\n *\n * @param message - The plaintext that was signed\n * @param signature - 130-char hex (v + r + s) as produced by `signMessage`\n * @returns - Compressed 66-char hex pubkey\n * @throws - On malformed signature length or out-of-range recovery byte\n */\nexport function recoverPubkeyFromSignature(message: string, signature: string): string {\n if (signature.length !== 130) {\n throw new SphereError(\n `Invalid signature length: expected 130 hex chars, got ${signature.length}`,\n 'SIGNING_ERROR',\n );\n }\n\n const v = parseInt(signature.slice(0, 2), 16) - 31;\n const r = signature.slice(2, 66);\n const s = signature.slice(66, 130);\n\n if (v < 0 || v > 3) {\n throw new SphereError(\n `Invalid recovery byte: v=${v} out of range [0..3]`,\n 'SIGNING_ERROR',\n );\n }\n\n const hashHex = hashSignMessage(message);\n\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true); // compressed\n}\n","/**\n * SDK Error Types\n *\n * Structured error codes for programmatic error handling in UI.\n * UI can switch on error.code to show appropriate user-facing messages.\n *\n * @example\n * ```ts\n * import { SphereError } from '@unicitylabs/sphere-sdk';\n *\n * try {\n * await sphere.payments.send({ ... });\n * } catch (err) {\n * if (err instanceof SphereError) {\n * switch (err.code) {\n * case 'INSUFFICIENT_BALANCE': showToast('Not enough funds'); break;\n * case 'INVALID_RECIPIENT': showToast('Recipient not found'); break;\n * case 'TRANSPORT_ERROR': showToast('Network connection issue'); break;\n * case 'TIMEOUT': showToast('Request timed out, try again'); break;\n * default: showToast(err.message);\n * }\n * }\n * }\n * ```\n */\n\nexport type SphereErrorCode =\n | 'NOT_INITIALIZED'\n | 'ALREADY_INITIALIZED'\n | 'INVALID_CONFIG'\n | 'INVALID_IDENTITY'\n | 'INSUFFICIENT_BALANCE'\n | 'INVALID_RECIPIENT'\n | 'TRANSFER_FAILED'\n // The source state was consumed by a DIFFERENT transaction (lost race, not a\n // resume) — raised as TransferConflictError (token-engine/errors.ts, Part E.2).\n | 'TRANSFER_CONFLICT'\n // The op's certification is INDETERMINATE (submit accepted / proof fetch\n // inconclusive) — raised as ProofUnconfirmedError; keep the intent OPEN (#631).\n | 'CERTIFICATION_UNCONFIRMED'\n // Split burn checkpoint (sdk-changes E.4, sphere-sdk#501) — all keep-open (token-engine/errors.ts):\n // burn certified but the checkpoint could not be persisted (no mint submitted);\n | 'CHECKPOINT_PERSIST_FAILED'\n // a certified mint leaf has no reproducing stored bytes, or a stored checkpoint fails byte-binding;\n | 'SPLIT_CHECKPOINT_LOST'\n // a byte-bound checkpoint proof no longer verifies against the current trust base (validator rotation).\n | 'CHECKPOINT_TRUSTBASE_MISMATCH'\n | 'STORAGE_ERROR'\n // #665: the on-chain spend committed but the post-commit wallet-api mirror\n // sync (inventory apply / blob upload / save) failed. NOT a lost payment —\n // the intent is kept open and resume converges the mirror (idempotent apply,\n // #664). Surfaced distinctly so a UI can reassure (\"sent — wallet catching\n // up\") instead of showing a hard send failure.\n | 'SEND_SYNC_PENDING'\n // #677: a multi-leg send lost a source to a concurrent transfer AFTER ≥1\n // earlier leg had already certified on-chain AND been journaled/delivered.\n // The delivered value has irreversibly left the wallet, so this is NOT a\n // plain, re-sendable failure: surfacing a bare TransferConflictError makes\n // the caller re-send the FULL amount and pay the delivered leg twice. Raised\n // as PartialSendConflictError; the caller MUST re-plan ONLY the remainder\n // under a NEW transferId, never the whole amount.\n | 'SEND_PARTIALLY_COMPLETED'\n | 'TRANSPORT_ERROR'\n | 'AGGREGATOR_ERROR'\n | 'VALIDATION_ERROR'\n | 'INVALID_AMOUNT'\n | 'NETWORK_ERROR'\n | 'TIMEOUT'\n | 'DECRYPTION_ERROR'\n | 'MODULE_NOT_AVAILABLE'\n | 'SIGNING_ERROR'\n // Token Spend Queue error codes\n | 'SEND_QUEUE_TIMEOUT'\n | 'SEND_INSUFFICIENT_BALANCE'\n | 'SEND_RESERVATION_CANCELLED'\n | 'SEND_QUEUE_FULL'\n | 'MODULE_DESTROYED'\n | 'REENTRANT_GATE'\n // Invoice / Accounting error codes\n | 'INVOICE_NO_TARGETS'\n | 'INVOICE_INVALID_ADDRESS'\n | 'INVOICE_NO_ASSETS'\n | 'INVOICE_INVALID_ASSET'\n | 'INVOICE_INVALID_AMOUNT'\n | 'INVOICE_INVALID_COIN'\n | 'INVOICE_INVALID_NFT'\n | 'INVOICE_PAST_DUE_DATE'\n | 'INVOICE_DUPLICATE_ADDRESS'\n | 'INVOICE_DUPLICATE_COIN'\n | 'INVOICE_DUPLICATE_NFT'\n | 'INVOICE_MINT_FAILED'\n | 'INVOICE_INVALID_PROOF'\n | 'INVOICE_WRONG_TOKEN_TYPE'\n | 'INVOICE_INVALID_DATA'\n | 'INVOICE_ALREADY_EXISTS'\n | 'INVOICE_NOT_FOUND'\n | 'INVOICE_NOT_TARGET'\n | 'INVOICE_ALREADY_CLOSED'\n | 'INVOICE_ALREADY_CANCELLED'\n | 'INVOICE_ORACLE_REQUIRED'\n | 'INVOICE_TERMINATED'\n | 'INVOICE_INVALID_TARGET'\n | 'INVOICE_INVALID_ASSET_INDEX'\n | 'INVOICE_RETURN_EXCEEDS_BALANCE'\n | 'INVOICE_INVALID_DELIVERY_METHOD'\n | 'INVOICE_INVALID_REFUND_ADDRESS'\n | 'INVOICE_INVALID_CONTACT'\n | 'INVOICE_INVALID_ID'\n | 'INVOICE_TOO_MANY_TARGETS'\n | 'INVOICE_TOO_MANY_ASSETS'\n | 'INVOICE_MEMO_TOO_LONG'\n | 'INVOICE_TERMS_TOO_LARGE'\n | 'INVOICE_NOT_TERMINATED'\n | 'INVOICE_NOT_CANCELLED'\n | 'INVOICE_STORAGE_FAILED'\n | 'RATE_LIMITED'\n | 'COMMUNICATIONS_UNAVAILABLE'\n // Swap error codes\n | 'SWAP_INVALID_DEAL'\n | 'SWAP_INVALID_MANIFEST'\n | 'SWAP_NOT_FOUND'\n | 'SWAP_WRONG_STATE'\n | 'SWAP_RESOLVE_FAILED'\n | 'SWAP_DM_SEND_FAILED'\n | 'SWAP_ESCROW_REJECTED'\n | 'SWAP_DEPOSIT_FAILED'\n | 'SWAP_PAYOUT_VERIFICATION_FAILED'\n | 'SWAP_ALREADY_EXISTS'\n | 'SWAP_ALREADY_COMPLETED'\n | 'SWAP_ALREADY_CANCELLED'\n | 'SWAP_TIMEOUT'\n | 'SWAP_LIMIT_EXCEEDED'\n | 'SWAP_ALREADY_INITIALIZED'\n | 'SWAP_MODULE_DESTROYED'\n | 'SWAP_NOT_INITIALIZED';\n\nexport class SphereError extends Error {\n readonly code: SphereErrorCode;\n readonly cause?: unknown;\n /**\n * #441 deferred-paid linkage: the transferId of the possibly-committed send,\n * stamped by `sendOnce` before the error leaves so a payment-request consumer\n * can durably journal request→transfer and resolve 'paid' only when that\n * transfer actually completes (never optimistically). Present ONLY on\n * possibly-committed outcomes ({@link isPossiblyCommittedSendOutcome}).\n */\n transferId?: string;\n\n constructor(message: string, code: SphereErrorCode, cause?: unknown) {\n super(message);\n this.name = 'SphereError';\n this.code = code;\n this.cause = cause;\n }\n}\n\n/**\n * #677: a send that PARTIALLY completed before losing a source to a concurrent\n * transfer. At least one earlier leg certified on-chain and was journaled for\n * delivery (its {@link committedTokenIds}) — that value has irreversibly left\n * the wallet — but a LATER leg raised `TransferConflictError` (a lost race), and\n * `send()` could NOT COMPLETE the {@link remainingAmount} from the remaining live\n * sources. This is the fallback after the internal remainder re-plan gave up —\n * either insufficient funds OR a transient/transport error during the re-plan\n * (the underlying reason is on `cause`), not necessarily an \"out of funds\" state.\n *\n * Distinct from `TransferConflictError` on purpose: a bare conflict makes the\n * caller re-send the FULL amount, paying the already-delivered leg a second\n * time. Catching THIS type (or `code === 'SEND_PARTIALLY_COMPLETED'`) tells the\n * caller/UI: the delivered legs are final, the conflicted intent stays OPEN\n * (resume converges its certified legs), and only the REMAINDER\n * ({@link remainingAmount}) may be re-planned — under a NEW transferId, never\n * re-sending the whole amount.\n *\n * NOT a subclass of `TransferConflictError` by design: existing conflict\n * handlers that re-send in full must NOT treat this as an ordinary conflict.\n */\nexport class PartialSendConflictError extends SphereError {\n /**\n * The FIRST partial attempt's transferId — its intent stays open for resume,\n * and it is the §6 handoff anchor. NOTE: `send()` may re-plan the remainder across\n * SEVERAL internal attempts before giving up, so {@link committedTokenIds} can\n * span MULTIPLE transferIds — they do NOT all map to this single id.\n */\n readonly transferId: string;\n /**\n * Source token ids whose spend already certified on-chain (and whose finished\n * output blob is journaled for delivery). Their value has already been\n * delivered; NEVER re-send these. May accumulate across several internal\n * remainder-re-plan attempts (so not all are journaled under {@link transferId}).\n */\n readonly committedTokenIds: readonly string[];\n /**\n * The still-undelivered portion (base units, decimal string) — `send()` could\n * not COMPLETE it from the remaining live sources (insufficient funds or a\n * transient error; see `cause`). Re-plan ONLY this amount, under a new\n * transferId; the delivered legs converge via the recipient's §6 claim.\n */\n readonly remainingAmount: string;\n\n constructor(\n message: string,\n transferId: string,\n committedTokenIds: readonly string[],\n remainingAmount: string,\n cause?: unknown,\n ) {\n super(message, 'SEND_PARTIALLY_COMPLETED', cause);\n this.name = 'PartialSendConflictError';\n this.transferId = transferId;\n this.committedTokenIds = [...committedTokenIds];\n this.remainingAmount = remainingAmount;\n }\n}\n\n/**\n * Error codes for a send outcome where money has (or may have) already left the\n * wallet on-chain, so the send is NOT a clean, re-sendable failure. A consumer\n * that persists a \"paid\" flag (e.g. a payment request) must keep the request\n * NON-payable on any of these — reverting to a re-payable state would double-pay\n * (#441). Covers the post-commit mirror-sync-pending / keep-open certification\n * states AND the partial-conflict outcome.\n */\nconst POSSIBLY_COMMITTED_SEND_CODES: ReadonlySet<SphereErrorCode> = new Set([\n 'SEND_SYNC_PENDING',\n 'CERTIFICATION_UNCONFIRMED',\n 'CHECKPOINT_PERSIST_FAILED',\n 'SPLIT_CHECKPOINT_LOST',\n 'CHECKPOINT_TRUSTBASE_MISMATCH',\n 'SEND_PARTIALLY_COMPLETED',\n]);\n\n/**\n * #441: true when a send failed with an outcome where the payment has (or may\n * have) irreversibly left the wallet — a post-commit sync-pending / keep-open\n * certification state, or a `PartialSendConflictError`. Such a send completes (or\n * has already partially completed) via resume/claim and MUST NOT be re-sent, so\n * a persisted \"paid\" state must stay non-payable. A `false` result is a clean\n * pre-commit failure — nothing left the wallet, safe to re-pay.\n */\nexport function isPossiblyCommittedSendOutcome(err: unknown): boolean {\n return isSphereError(err) && POSSIBLY_COMMITTED_SEND_CODES.has(err.code);\n}\n\n/**\n * Type guard to check if an error is a SphereError\n */\nexport function isSphereError(err: unknown): err is SphereError {\n return err instanceof SphereError;\n}\n","/**\n * The ONE source for the wallet-api cross-repo contract strings (§4 auth\n * challenge, E.4/#87/§16 seed-holder messages) — never re-derive them.\n * Grammar + rationale (#662 device-clock ban): wallet-api ARCHITECTURE §4/§16.\n */\n\nimport { sha256 } from './crypto';\n\n/** The §16 progress-append message: signed over the EXACT stored-envelope bytes (E.4). */\nexport function progressSignMessage(transferId: string, opIndex: number, payloadEnvelope: string): string {\n return `wallet-api.progress.v1:${transferId}:${String(opIndex)}:${sha256(payloadEnvelope, 'utf8')}`;\n}\n\n/** The §16/#87 terminal-close message for a checkpoint-bearing intent. */\nexport function completeSignMessage(transferId: string): string {\n return `wallet-api.complete.v1:${transferId}`;\n}\n\n/** Fixed domain-separation prefix (ARCHITECTURE §4 step 1). */\nexport const AUTH_CHALLENGE_PREFIX = 'unicity:wallet-api:auth:v1\\n';\n\n/** Maximum plausible challenge validity window (server default: NONCE_TTL = 5 min). */\nconst MAX_VALIDITY_WINDOW_MS = 60 * 60 * 1000;\n\nexport class ChallengeTemplateError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ChallengeTemplateError';\n }\n}\n\nexport interface ChallengeExpectation {\n /** The client's own compressed pubkey hex — the challenge MUST embed it. */\n pubkey: string;\n nonce: string;\n /** The client's network — refused if the challenge names a different one. */\n network: string;\n}\n\nfunction parseFields(body: string): Map<string, string> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n throw new ChallengeTemplateError('Challenge body is not the single-line JSON object the backend emits');\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new ChallengeTemplateError('Challenge body must be a JSON object');\n }\n const fields = new Map<string, string>();\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value !== 'string' || value === '') {\n throw new ChallengeTemplateError(`Challenge field \"${key}\" must be a non-empty string`);\n }\n fields.set(key, value);\n }\n return fields;\n}\n\nfunction requireField(fields: Map<string, string>, key: string): string {\n const value = fields.get(key);\n if (value === undefined) {\n throw new ChallengeTemplateError(`Challenge is missing the \"${key}\" field`);\n }\n return value;\n}\n\nfunction parseTimestamp(value: string, key: string): number {\n const ms = Date.parse(value);\n if (Number.isNaN(ms)) {\n throw new ChallengeTemplateError(`Challenge \"${key}\" is not a parseable timestamp: ${value}`);\n }\n return ms;\n}\n\n/** The spend key never signs unverified server text — throws on ANY violation. */\nexport function verifyChallengeTemplate(challenge: string, expect: ChallengeExpectation): void {\n if (typeof challenge !== 'string' || !challenge.startsWith(AUTH_CHALLENGE_PREFIX)) {\n throw new ChallengeTemplateError('Challenge does not start with the unicity:wallet-api:auth:v1 domain prefix');\n }\n const fields = parseFields(challenge.slice(AUTH_CHALLENGE_PREFIX.length));\n\n const pubkey = requireField(fields, 'pubkey');\n if (pubkey.toLowerCase() !== expect.pubkey.toLowerCase()) {\n throw new ChallengeTemplateError('Challenge embeds a different pubkey than this wallet');\n }\n\n const nonce = requireField(fields, 'nonce');\n if (nonce !== expect.nonce) {\n throw new ChallengeTemplateError('Challenge nonce does not match the nonce issued with it');\n }\n\n const network = requireField(fields, 'network');\n if (network !== expect.network) {\n throw new ChallengeTemplateError(`Challenge is for network \"${network}\", expected \"${expect.network}\"`);\n }\n\n const issuedAt = parseTimestamp(requireField(fields, 'issuedAt'), 'issuedAt');\n const expiresAt = parseTimestamp(requireField(fields, 'expiresAt'), 'expiresAt');\n\n // Server timestamps only — no device-clock comparison (#662).\n if (expiresAt <= issuedAt || expiresAt - issuedAt > MAX_VALIDITY_WINDOW_MS) {\n throw new ChallengeTemplateError('Challenge validity window is implausible');\n }\n}\n","// §5.1 WalletApiSession: auth generation-cell, single-flight refresh,\n// challenge-template verification, wake-socket supervisor, epoch latch.\n\nimport { STORE_KEYS, type ScopedKV } from '../../modules/payments-v2/stores';\nimport { verifyChallengeTemplate } from '../../core/wallet-api-protocol';\nimport { WalletApiHttpError } from './http';\nimport type { AuthTokensWire, WalletApiV2Client } from './client';\n\n// The spend key never signs unverified server text (S1/§4) — the canonical\n// verifier is the ONE source; re-exported so existing importers keep working.\nexport {\n AUTH_CHALLENGE_PREFIX,\n ChallengeTemplateError,\n verifyChallengeTemplate,\n type ChallengeExpectation,\n} from '../../core/wallet-api-protocol';\n\n/**\n * The JWT generation cell (#692 F8/F14). Every write is a compare-and-swap on\n * a generation captured at operation start — the CAS lives INSIDE the setter,\n * so a continuation returning from an await can never clobber a newer session.\n */\nexport class JwtGenerationCell {\n private gen = 0;\n private jwt: string | null = null;\n\n get generation(): number {\n return this.gen;\n }\n\n token(): string | null {\n return this.jwt;\n }\n\n install(generation: number, jwt: string): boolean {\n if (generation !== this.gen) return false;\n this.jwt = jwt;\n return true;\n }\n\n /** authGone(G) is a no-op when the cell moved to G+1 (F14). */\n clearIfCurrent(generation: number): boolean {\n if (generation !== this.gen || this.jwt === null) return false;\n this.jwt = null;\n return true;\n }\n\n dropIfMatches(generation: number, jwt: string): void {\n if (generation === this.gen && this.jwt === jwt) this.jwt = null;\n }\n\n bump(): number {\n this.gen += 1;\n this.jwt = null;\n return this.gen;\n }\n}\n\nexport type WakeStream = 'inventory' | 'mailbox' | 'payment_requests';\nexport const WAKE_STREAMS: readonly WakeStream[] = ['inventory', 'mailbox', 'payment_requests'];\n\nexport type ConnectionStatus = 'connected' | 'degraded' | 'offline';\n\nexport interface SessionSigner {\n readonly pubkey: string;\n readonly network: string;\n sign(message: string): string | Promise<string>;\n}\n\nexport interface WebSocketLike {\n onopen: (() => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n onclose: ((ev: { code?: number }) => void) | null;\n onerror: ((err: unknown) => void) | null;\n close(code?: number, reason?: string): void;\n}\n\nexport type WebSocketFactory = (url: string) => WebSocketLike;\n\nexport interface SessionTimers {\n setTimeout(cb: () => void, ms: number): unknown;\n clearTimeout(handle: unknown): void;\n setInterval(cb: () => void, ms: number): unknown;\n clearInterval(handle: unknown): void;\n}\n\nexport interface SessionTiming {\n pullIntervalMs: number;\n reconnectBaseMs: number;\n reconnectCapMs: number;\n heartbeatTimeoutMs: number;\n offlineAfterFailures: number;\n}\n\nexport const DEFAULT_SESSION_TIMING: SessionTiming = {\n pullIntervalMs: 30_000,\n reconnectBaseMs: 1_000,\n reconnectCapMs: 30_000,\n heartbeatTimeoutMs: 120_000,\n offlineAfterFailures: 3,\n};\n\nexport interface WalletApiSessionDeps {\n client: WalletApiV2Client;\n cell: JwtGenerationCell;\n signer: SessionSigner;\n deviceId: string;\n kv: ScopedKV;\n webSocketFactory: WebSocketFactory;\n emitStatus: (status: ConnectionStatus) => void;\n timing?: Partial<SessionTiming>;\n timers?: SessionTimers;\n random?: () => number;\n}\n\nexport function refreshTokenKey(deviceId: string): string {\n return `auth:refresh:${deviceId}`;\n}\n\nconst WS_CLOSE_AUTH_GONE = 4401;\n\ninterface WakeFrame {\n stream: WakeStream;\n syncEpoch: string;\n}\n\nfunction parseWakeFrame(data: unknown): WakeFrame | null {\n if (typeof data !== 'string') return null;\n let json: unknown;\n try {\n json = JSON.parse(data);\n } catch {\n return null;\n }\n const frame = json as { type?: unknown; stream?: unknown; syncEpoch?: unknown };\n if (frame.type !== 'wake') return null;\n if (!WAKE_STREAMS.includes(frame.stream as WakeStream)) return null;\n if (typeof frame.syncEpoch !== 'number' && typeof frame.syncEpoch !== 'string') return null;\n return { stream: frame.stream as WakeStream, syncEpoch: String(frame.syncEpoch) };\n}\n\nconst GLOBAL_TIMERS: SessionTimers = {\n setTimeout: (cb, ms) => setTimeout(cb, ms),\n clearTimeout: (h) => clearTimeout(h as Parameters<typeof clearTimeout>[0]),\n setInterval: (cb, ms) => setInterval(cb, ms),\n clearInterval: (h) => clearInterval(h as Parameters<typeof clearInterval>[0]),\n};\n\nexport class WalletApiSession {\n private readonly timing: SessionTiming;\n private readonly timers: SessionTimers;\n private readonly random: () => number;\n private readonly refreshKey: string;\n\n private authFlight: Promise<void> | null = null;\n\n private epochLatch: string | null = null;\n private reseedChain: Promise<void> = Promise.resolve();\n private reseedsPending = 0;\n private readonly epochHandlers = new Set<(epoch: string) => Promise<void>>();\n\n private readonly handlers = new Map<WakeStream, Set<() => void>>();\n private readonly statusHandlers = new Set<(status: ConnectionStatus) => void>();\n private socket: WebSocketLike | null = null;\n private started = false;\n private stopped = false;\n private reconnectAttempts = 0;\n private reconnectTimer: unknown = null;\n private heartbeatTimer: unknown = null;\n private pullTimers: unknown[] = [];\n private lastStatus: ConnectionStatus | null = null;\n\n constructor(private readonly deps: WalletApiSessionDeps) {\n this.timing = { ...DEFAULT_SESSION_TIMING, ...deps.timing };\n this.timers = deps.timers ?? GLOBAL_TIMERS;\n this.random = deps.random ?? Math.random;\n this.refreshKey = refreshTokenKey(deps.deviceId);\n }\n\n // ── lifecycle ─────────────────────────────────────────────────────────────\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n this.epochLatch = await this.deps.kv.get<string>(STORE_KEYS.epochLatch);\n this.startPullTimers();\n void this.connect();\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n for (const t of this.pullTimers) this.timers.clearInterval(t);\n this.pullTimers = [];\n if (this.reconnectTimer !== null) this.timers.clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n this.clearHeartbeat();\n const ws = this.socket;\n this.socket = null;\n ws?.close();\n await this.reseedChain;\n }\n\n // ── auth cell (F8/F14) ────────────────────────────────────────────────────\n\n token(): string | null {\n return this.deps.cell.token();\n }\n\n /** Identity switch / lock / logout: supersede every in-flight auth continuation. */\n invalidate(): void {\n this.deps.cell.bump();\n this.authFlight = null;\n }\n\n async ensureAuthenticated(): Promise<string> {\n const existing = this.deps.cell.token();\n if (existing !== null) return existing;\n await this.runAuthSingleFlight();\n const fresh = this.deps.cell.token();\n if (fresh === null) {\n throw new WalletApiHttpError(401, 'AUTH_SUPERSEDED', 'authentication superseded before completion');\n }\n return fresh;\n }\n\n /** Run an authenticated op; one 401 → single-flight re-auth → one retry. */\n async withAuth<T>(op: (jwt: string) => Promise<T>): Promise<T> {\n const jwt = await this.ensureAuthenticated();\n const generation = this.deps.cell.generation;\n try {\n return await op(jwt);\n } catch (err) {\n if (!(err instanceof WalletApiHttpError && err.status === 401)) throw err;\n this.deps.cell.dropIfMatches(generation, jwt);\n return op(await this.ensureAuthenticated());\n }\n }\n\n private runAuthSingleFlight(): Promise<void> {\n if (this.authFlight !== null) return this.authFlight;\n const generation = this.deps.cell.generation;\n const flight = this.authenticate(generation).finally(() => {\n if (this.authFlight === flight) this.authFlight = null;\n });\n this.authFlight = flight;\n return flight;\n }\n\n private async authenticate(generation: number): Promise<void> {\n if (await this.tryRefresh(generation)) return;\n if (this.deps.cell.generation !== generation) return;\n await this.challengeSignIn(generation);\n }\n\n private async tryRefresh(generation: number): Promise<boolean> {\n const stored = await this.deps.kv.get<string>(this.refreshKey);\n if (stored === null) return false;\n let tokens: AuthTokensWire;\n try {\n tokens = await this.deps.client.authRefresh(stored);\n } catch (err) {\n if (err instanceof WalletApiHttpError && err.status >= 400 && err.status < 500) {\n if (this.deps.cell.generation === generation) await this.deps.kv.remove(this.refreshKey);\n return false;\n }\n throw err;\n }\n if (!this.deps.cell.install(generation, tokens.jwt)) return true;\n await this.deps.kv.set(this.refreshKey, tokens.refreshToken);\n return true;\n }\n\n private async challengeSignIn(generation: number): Promise<void> {\n const { pubkey, network } = this.deps.signer;\n const { nonce, challenge } = await this.deps.client.authChallenge(pubkey);\n verifyChallengeTemplate(challenge, { pubkey, nonce, network });\n const signature = await this.deps.signer.sign(challenge);\n const tokens = await this.deps.client.authVerify({ nonce, signature, deviceId: this.deps.deviceId });\n if (!this.deps.cell.install(generation, tokens.jwt)) return;\n await this.deps.kv.set(this.refreshKey, tokens.refreshToken);\n }\n\n // ── epoch latch (F12) ─────────────────────────────────────────────────────\n\n /** §5.1: the latched server syncEpoch ('' before first server contact). */\n currentEpoch(): string {\n return this.epochLatch ?? '';\n }\n\n /**\n * §5.1 restore hook (FacadeSession contract): handlers are AWAITED inside\n * the reseed chain, BEFORE any stream nudge resumes.\n */\n subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void {\n this.epochHandlers.add(handler);\n return () => this.epochHandlers.delete(handler);\n }\n\n noteEpoch(epoch: string): void {\n if (this.epochLatch === epoch) return;\n const previous = this.epochLatch;\n this.epochLatch = epoch;\n if (previous === null) {\n void this.deps.kv.set(STORE_KEYS.epochLatch, epoch).catch(() => undefined);\n return;\n }\n this.reseedsPending += 1;\n this.reseedChain = this.reseedChain.then(() => this.runReseed(epoch, previous));\n }\n\n private async runReseed(epoch: string, previous: string): Promise<void> {\n try {\n for (const handler of [...this.epochHandlers]) await handler(epoch);\n await this.deps.kv.set(STORE_KEYS.epochLatch, epoch);\n } catch {\n if (this.epochLatch === epoch) this.epochLatch = previous;\n } finally {\n this.reseedsPending -= 1;\n if (this.reseedsPending === 0) this.nudgeAllStreams();\n }\n }\n\n // ── streams ───────────────────────────────────────────────────────────────\n\n subscribeStream(stream: WakeStream, handler: () => void): () => void {\n let set = this.handlers.get(stream);\n if (!set) {\n set = new Set();\n this.handlers.set(stream, set);\n }\n set.add(handler);\n return () => set.delete(handler);\n }\n\n private dispatch(stream: WakeStream): void {\n if (this.reseedsPending > 0) return;\n const set = this.handlers.get(stream);\n if (!set) return;\n for (const handler of set) handler();\n }\n\n private nudgeAllStreams(): void {\n for (const stream of WAKE_STREAMS) this.dispatch(stream);\n }\n\n private startPullTimers(): void {\n for (const stream of WAKE_STREAMS) {\n this.pullTimers.push(this.timers.setInterval(() => this.dispatch(stream), this.timing.pullIntervalMs));\n }\n }\n\n // ── wake socket ───────────────────────────────────────────────────────────\n\n status(): ConnectionStatus {\n return this.lastStatus ?? 'offline';\n }\n\n /** Transition feed off the existing emitStatus point (FacadeSession.subscribeStatus). */\n subscribeStatus(handler: (status: ConnectionStatus) => void): () => void {\n this.statusHandlers.add(handler);\n return () => this.statusHandlers.delete(handler);\n }\n\n private emitStatus(status: ConnectionStatus): void {\n if (this.stopped || this.lastStatus === status) return;\n this.lastStatus = status;\n this.deps.emitStatus(status);\n for (const handler of this.statusHandlers) handler(status);\n }\n\n private async connect(): Promise<void> {\n if (this.stopped) return;\n try {\n const ticket = await this.withAuth(() => this.deps.client.wsTicket());\n if (this.stopped) return;\n this.openSocket(ticket, this.deps.cell.generation);\n } catch {\n this.scheduleReconnect();\n }\n }\n\n private openSocket(ticket: string, generation: number): void {\n const wsBase = this.deps.client.baseUrl.replace(/^http/, 'ws');\n const ws = this.deps.webSocketFactory(`${wsBase}/v1/ws?ticket=${encodeURIComponent(ticket)}`);\n this.socket = ws;\n ws.onopen = () => this.handleOpen(ws);\n ws.onmessage = (ev) => this.handleMessage(ws, ev.data);\n ws.onclose = (ev) => this.handleClose(ws, generation, ev?.code);\n ws.onerror = () => undefined;\n }\n\n private handleOpen(ws: WebSocketLike): void {\n if (ws !== this.socket) return;\n this.reconnectAttempts = 0;\n this.emitStatus('connected');\n this.armHeartbeat(ws);\n // Wakes before this instant are lost — one synthetic nudge per stream.\n this.nudgeAllStreams();\n }\n\n private handleMessage(ws: WebSocketLike, data: unknown): void {\n if (ws !== this.socket) return;\n this.armHeartbeat(ws);\n const frame = parseWakeFrame(data);\n if (frame === null) return;\n this.noteEpoch(frame.syncEpoch);\n this.dispatch(frame.stream);\n }\n\n private handleClose(ws: WebSocketLike, generation: number, code?: number): void {\n if (ws !== this.socket) return;\n this.socket = null;\n this.clearHeartbeat();\n if (this.stopped) return;\n if (code === WS_CLOSE_AUTH_GONE) {\n // CAS inside the cell: a stale socket's auth-gone never clears a newer JWT (F14).\n this.deps.cell.clearIfCurrent(generation);\n this.emitStatus('degraded');\n void this.connect();\n return;\n }\n this.scheduleReconnect();\n }\n\n private scheduleReconnect(): void {\n if (this.stopped) return;\n this.reconnectAttempts += 1;\n this.emitStatus(this.reconnectAttempts >= this.timing.offlineAfterFailures ? 'offline' : 'degraded');\n const capped = Math.min(\n this.timing.reconnectCapMs,\n this.timing.reconnectBaseMs * 2 ** (this.reconnectAttempts - 1)\n );\n const delay = Math.floor(this.random() * capped);\n this.reconnectTimer = this.timers.setTimeout(() => void this.connect(), delay);\n }\n\n private armHeartbeat(ws: WebSocketLike): void {\n this.clearHeartbeat();\n this.heartbeatTimer = this.timers.setTimeout(() => {\n if (ws === this.socket) ws.close();\n }, this.timing.heartbeatTimeoutMs);\n }\n\n private clearHeartbeat(): void {\n if (this.heartbeatTimer !== null) this.timers.clearTimeout(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n}\n","// P3b: WalletApiStoragePort — thin StoragePort over the §16 client\n// (InventoryView owns the mirror; this file owns wire mapping + fan-out only).\n\nimport type { ApplyDeltaResult, InventoryPage, StoragePort } from '../../modules/payments-v2/ports';\nimport { isWalletApiHttpError } from './http';\nimport type { WalletApiV2Client } from './client';\n\nexport const WALLET_API_V2_FANOUT_WIDTH = 8;\n\n/**\n * Unique ids per blob-urls request. wallet-api answers more than its PAGE_LIMIT\n * (1000 by default, set per deployment) with 429 QUOTA_EXCEEDED, and a small batch\n * keeps each presigned GET well inside its TTL.\n */\nexport const WALLET_API_V2_BLOB_URLS_BATCH = 100;\n\nexport type StoragePortClient = Pick<\n WalletApiV2Client,\n 'listInventory' | 'blobUrls' | 'uploadUrls' | 'apply' | 'fetchBlob' | 'uploadBlob'\n>;\n\n/** The presigned-upload protocol step shared by storage and delivery (§5.6). */\nexport type PresignedUploadClient = Pick<WalletApiV2Client, 'uploadUrls' | 'uploadBlob'>;\n\n/** 409 on applyDelta: the server refused the delta on lineage grounds. */\nexport class DeltaConflictError extends Error {\n readonly code = 'DELTA_CONFLICT';\n constructor(message: string, readonly cause?: unknown) {\n super(message);\n this.name = 'DeltaConflictError';\n }\n}\n\n/** 422 on applyDelta: the delta itself is invalid (bad blob, unknown spend, …). */\nexport class DeltaValidationError extends Error {\n readonly code = 'DELTA_VALIDATION';\n constructor(message: string, readonly cause?: unknown) {\n super(message);\n this.name = 'DeltaValidationError';\n }\n}\n\nexport class StoragePortProtocolError extends Error {\n readonly code = 'PROTOCOL';\n constructor(message: string) {\n super(message);\n this.name = 'StoragePortProtocolError';\n }\n}\n\n/** Bounded-parallel map: at most `width` in flight; stops claiming new work after a failure. */\nexport async function mapBounded<T, R>(\n items: readonly T[],\n width: number,\n fn: (item: T, index: number) => Promise<R>\n): Promise<R[]> {\n const out = new Array<R>(items.length);\n let next = 0;\n let failed = false;\n const worker = async (): Promise<void> => {\n for (;;) {\n if (failed) return;\n const index = next;\n next += 1;\n if (index >= items.length) return;\n try {\n out[index] = await fn(items[index] as T, index);\n } catch (err) {\n failed = true;\n throw err;\n }\n }\n };\n const workers = Array.from({ length: Math.max(1, Math.min(width, items.length)) }, worker);\n await Promise.all(workers);\n return out;\n}\n\n/** upload-urls → bounded PUTs → sha256→key map (S3 412 = exists = success). */\nexport async function uploadViaPresigned(\n client: PresignedUploadClient,\n blobs: readonly { sha256: string; bytes: Uint8Array }[]\n): Promise<Map<string, string>> {\n if (blobs.length === 0) return new Map();\n const urls = await client.uploadUrls(blobs.map((b) => ({ sha256: b.sha256, size: b.bytes.length })));\n const urlBySha = new Map(urls.map((u) => [u.sha256, u]));\n const uploads = blobs.map((blob) => {\n const url = urlBySha.get(blob.sha256);\n if (url === undefined) {\n throw new StoragePortProtocolError(`upload-urls response missing sha256 ${blob.sha256}`);\n }\n return { blob, url };\n });\n await mapBounded(uploads, WALLET_API_V2_FANOUT_WIDTH, ({ blob, url }) =>\n client.uploadBlob(url.putUrl, blob.bytes)\n );\n return new Map(uploads.map(({ blob, url }) => [blob.sha256, url.key]));\n}\n\nexport class WalletApiStoragePort implements StoragePort {\n constructor(private readonly client: StoragePortClient) {}\n\n async listInventory(since?: number): Promise<InventoryPage> {\n const page = await this.client.listInventory(since);\n return {\n cursor: page.cursor,\n syncEpoch: String(page.syncEpoch),\n more: page.more,\n items: page.items,\n };\n }\n\n /** One blob-urls request per batch of unique ids, each batch fetched before the next is presigned. */\n async getBlobs(tokenIds: string[]): Promise<Map<string, Uint8Array>> {\n const unique = [...new Set(tokenIds)];\n const result = new Map<string, Uint8Array>();\n for (let start = 0; start < unique.length; start += WALLET_API_V2_BLOB_URLS_BATCH) {\n const urls = await this.client.blobUrls(unique.slice(start, start + WALLET_API_V2_BLOB_URLS_BATCH));\n const bytes = await mapBounded(urls, WALLET_API_V2_FANOUT_WIDTH, (u) => this.client.fetchBlob(u.getUrl));\n for (const [i, url] of urls.entries()) {\n const blob = bytes[i];\n if (blob !== undefined) result.set(url.tokenId, blob);\n }\n }\n return result;\n }\n\n uploadBlobs(blobs: { sha256: string; bytes: Uint8Array }[]): Promise<Map<string, string>> {\n return uploadViaPresigned(this.client, blobs);\n }\n\n async applyDelta(delta: {\n transferId: string;\n spent: string[];\n added: { tokenId: string; key: string }[];\n }): Promise<ApplyDeltaResult> {\n try {\n const result = await this.client.apply(delta);\n return { cursor: result.cursor, syncEpoch: String(result.syncEpoch) };\n } catch (err) {\n if (isWalletApiHttpError(err, 409)) throw new DeltaConflictError(err.message, err);\n if (isWalletApiHttpError(err, 422)) throw new DeltaValidationError(err.message, err);\n throw err;\n }\n }\n}\n","// Shared concurrency primitives. Both advance on SETTLED, never fulfilled —\n// a rejection never bricks the next run (async.test.ts pins the recovery).\n\nexport class SingleFlight<T> {\n private flight: Promise<T> | null = null;\n\n run(fn: () => Promise<T>): Promise<T> {\n if (this.flight !== null) return this.flight;\n const current = fn().finally(() => {\n this.flight = null;\n });\n this.flight = current;\n return current;\n }\n}\n\nexport class SerialChain {\n private tail: Promise<unknown> = Promise.resolve();\n\n /** FIFO; starts after every prior fn settled; returns this fn's own outcome. */\n enqueue<T>(fn: () => Promise<T>): Promise<T> {\n const run = this.tail.then(fn, fn);\n this.tail = run.then(\n () => undefined,\n () => undefined\n );\n return run;\n }\n}\n\n/** Fire-and-forget sibling of {@link SingleFlight}: one in flight, one queued behind it. */\nexport function coalesced(\n run: () => Promise<unknown>,\n observe?: (op: Promise<unknown>) => void\n): () => void {\n let inFlight = false;\n let queued = false;\n const start = (): void => {\n inFlight = true;\n // A synchronous throw would escape before .catch attaches and strand\n // inFlight, wedging every later trigger. Started eagerly, not on a\n // microtask, so a caller can rely on the first run having begun.\n let running: Promise<unknown>;\n try {\n running = run();\n } catch {\n running = Promise.resolve();\n }\n observe?.(running);\n void running\n .catch(() => undefined)\n .finally(() => {\n inFlight = false;\n if (!queued) return;\n queued = false;\n start();\n });\n };\n return () => {\n if (inFlight) {\n queued = true;\n return;\n }\n start();\n };\n}\n","/**\n * HKDF (RFC 5869): extract + expand in one step.\n * See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}.\n * @module\n */\nimport { hmac } from './hmac.ts';\nimport { abytes, ahash, anumber, type CHash, clean, type TArg, type TRet } from './utils.ts';\n\n/**\n * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK`\n * Arguments position differs from spec (IKM is first one, since it is not optional)\n * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`.\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @returns Pseudorandom key derived from input keying material.\n * @example\n * Run the HKDF extract step.\n * ```ts\n * import { extract } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\nexport function extract(\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n ahash(hash);\n // NOTE: some libraries treat zero-length array as 'not provided';\n // we don't, since we have undefined as 'not provided'\n // https://github.com/RustCrypto/KDFs/issues/15\n if (salt === undefined) salt = new Uint8Array(hash.outputLen);\n return hmac(hash, salt, ikm);\n}\n\n// Shared mutable scratch byte for the RFC 5869 block counter `N`.\n// Safe to reuse because `expand()` is synchronous and resets it with `clean(...)` before returning.\nconst HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);\n// Shared RFC 5869 empty string for both `info === undefined` and the first-block `T(0)` input.\nconst EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();\n\n/**\n * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM`\n * @param hash - hash function that would be used (e.g. sha256)\n * @param prk - a pseudorandom key of at least HashLen octets\n * (usually, the output from the extract step)\n * @param info - optional context and application specific information (can be a zero-length string)\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material with the requested length.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * Run the HKDF expand step.\n * ```ts\n * import { expand } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16);\n * ```\n */\nexport function expand(\n hash: TArg<CHash>,\n prk: TArg<Uint8Array>,\n info?: TArg<Uint8Array>,\n length: number = 32\n): TRet<Uint8Array> {\n ahash(hash);\n anumber(length, 'length');\n abytes(prk, undefined, 'prk');\n const olen = hash.outputLen;\n // RFC 5869 §2.3: PRK is \"a pseudorandom key of at least HashLen octets\".\n if (prk.length < olen) throw new Error('\"prk\" must be at least HashLen octets');\n // RFC 5869 §2.3 only bounds `L` by `<= 255*HashLen`; `L=0` is valid and yields empty OKM.\n if (length > 255 * olen) throw new Error('Length must be <= 255*HashLen');\n const blocks = Math.ceil(length / olen);\n if (info === undefined) info = EMPTY_BUFFER;\n else abytes(info, undefined, 'info');\n // first L(ength) octets of T\n const okm = new Uint8Array(blocks * olen);\n // Re-use HMAC instance between blocks\n const HMAC = hmac.create(hash, prk);\n const HMACTmp = HMAC._cloneInto();\n const T = new Uint8Array(HMAC.outputLen);\n for (let counter = 0; counter < blocks; counter++) {\n HKDF_COUNTER[0] = counter + 1;\n // T(0) = empty string (zero length)\n // T(N) = HMAC-Hash(PRK, T(N-1) | info | N)\n HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T)\n .update(info)\n .update(HKDF_COUNTER)\n .digestInto(T);\n okm.set(T, olen * counter);\n HMAC._cloneInto(HMACTmp);\n }\n HMAC.destroy();\n HMACTmp.destroy();\n clean(T, HKDF_COUNTER);\n return okm.slice(0, length) as TRet<Uint8Array>;\n}\n\n/**\n * HKDF (RFC 5869): derive keys from an initial input.\n * Combines hkdf_extract + hkdf_expand in one step\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @param info - optional context and application specific information bytes\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material derived from the input key.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * HKDF (RFC 5869): derive keys from an initial input.\n * ```ts\n * import { hkdf } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';\n * const inputKey = randomBytes(32);\n * const salt = randomBytes(32);\n * const info = utf8ToBytes('application-key');\n * const okm = hkdf(sha256, inputKey, salt, info, 32);\n * ```\n */\nexport const hkdf = (\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt: TArg<Uint8Array | undefined>,\n info: TArg<Uint8Array | undefined>,\n length: number\n): TRet<Uint8Array> => expand(hash, extract(hash, ikm, salt), info, length);\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */\n\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n\n/**\n * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.\n * @param a - Value to inspect.\n * @returns `true` when the value is a Uint8Array view, including Node's `Buffer`.\n * @example\n * Guards a value before treating it as raw key material.\n *\n * ```ts\n * isBytes(new Uint8Array());\n * ```\n */\nexport function isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy /\n // cross-realm cases. The fallback still requires a real ArrayBuffer view\n // so plain JSON-deserialized `{ constructor: ... }`\n // spoofing is rejected, and `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n\n/**\n * Asserts something is boolean.\n * @param b - Value to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validates a boolean option before branching on it.\n *\n * ```ts\n * abool(true);\n * ```\n */\nexport function abool(b: boolean): void {\n if (typeof b !== 'boolean') throw new TypeError(`boolean expected, not ${b}`);\n}\n\n/**\n * Asserts something is a non-negative safe integer.\n * @param n - Value to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validates a non-negative length or counter.\n *\n * ```ts\n * anumber(1);\n * ```\n */\nexport function anumber(n: number): void {\n if (typeof n !== 'number') throw new TypeError('number expected, got ' + typeof n);\n if (!Number.isSafeInteger(n) || n < 0)\n throw new RangeError('positive integer expected, got ' + n);\n}\n\n/**\n * Asserts something is Uint8Array.\n * @param value - Value to validate.\n * @param length - Expected byte length.\n * @param title - Optional label used in error messages.\n * @returns The validated byte array.\n * On Node, `Buffer` is accepted too because it is a Uint8Array view.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument lengths. {@link RangeError}\n * @example\n * Validates a fixed-length nonce or key buffer.\n *\n * ```ts\n * abytes(new Uint8Array([1, 2]), 2);\n * ```\n */\nexport function abytes(\n value: TArg<Uint8Array>,\n length?: number,\n title: string = ''\n): TRet<Uint8Array> {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n if (!bytes) throw new TypeError(message);\n throw new RangeError(message);\n }\n return value as TRet<Uint8Array>;\n}\n\n/**\n * Asserts a hash- or MAC-like instance has not been destroyed or finished.\n * @param instance - Stateful instance to validate.\n * @param checkFinished - Whether to reject finished instances.\n * When `false`, only `destroyed` is checked.\n * @throws If the hash instance has already been destroyed or finalized. {@link Error}\n * @example\n * Guards against calling `update()` or `digest()` on a finished hash.\n *\n * ```ts\n * aexists({ destroyed: false, finished: false });\n * ```\n */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/**\n * Asserts output is a properly-sized byte array.\n * @param out - Output buffer to validate.\n * @param instance - Hash-like instance providing `outputLen`.\n * This is the relaxed `digestInto()`-style contract: output must be at least `outputLen`,\n * unlike one-shot cipher helpers elsewhere in the repo that often require exact lengths.\n * @throws On wrong argument types. {@link TypeError}\n * @param onlyAligned - Whether `out` must be 4-byte aligned for zero-allocation word views.\n * @throws On wrong output buffer lengths. {@link RangeError}\n * @throws On wrong output buffer alignment. {@link Error}\n * @example\n * Verifies that a caller-provided output buffer is large enough.\n *\n * ```ts\n * aoutput(new Uint8Array(16), { outputLen: 16 });\n * ```\n */\nexport function aoutput(out: any, instance: any, onlyAligned = false): void {\n abytes(out, undefined, 'output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new RangeError('digestInto() expects output buffer of length at least ' + min);\n }\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n}\n\n/** One-shot hash helper with `.create()`. */\nexport type IHash = {\n (data: string | TArg<Uint8Array>): TRet<Uint8Array>;\n /** Input block size in bytes. */\n blockLen: number;\n /** Digest size in bytes. */\n outputLen: number;\n /** Creates a fresh incremental hash instance of the same algorithm. */\n create: any;\n};\n\n/** One-shot MAC helper with `.create()`. */\nexport type CMac<H extends IHash2 = IHash2, A extends any[] = []> = {\n (msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array>;\n /** Input block size in bytes. */\n blockLen: number;\n /** Digest size in bytes. */\n outputLen: number;\n /**\n * Creates a fresh incremental MAC instance of the same algorithm.\n * @param key - MAC key bytes.\n * @param args - Additional constructor arguments, when the MAC wrapper needs them.\n * @returns Fresh incremental MAC instance.\n */\n create(key: TArg<Uint8Array>, ...args: A): H;\n};\n\n/** Generic type encompassing 8/16/32-bit typed arrays, but not 64-bit. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/**\n * Casts a typed-array view to Uint8Array.\n * @param arr - Typed-array view to reinterpret.\n * @returns Uint8Array view over the same bytes.\n * @example\n * Views 32-bit words as raw bytes without copying.\n *\n * ```ts\n * u8(new Uint32Array([1]));\n * ```\n */\nexport function u8(arr: TArg<TypedArray>): TRet<Uint8Array> {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet<Uint8Array>;\n}\n\n/**\n * Casts a typed-array view to Uint32Array.\n * @param arr - Typed-array view to reinterpret.\n * @returns Uint32Array view over the same bytes. Callers are expected to provide a\n * 4-byte-aligned offset; trailing `1..3` bytes are silently dropped.\n * @example\n * Views a byte buffer as 32-bit words for block processing.\n *\n * ```ts\n * u32(new Uint8Array(4));\n * ```\n */\nexport function u32(arr: TArg<TypedArray>): TRet<Uint32Array> {\n return new Uint32Array(\n arr.buffer,\n arr.byteOffset,\n Math.floor(arr.byteLength / 4)\n ) as TRet<Uint32Array>;\n}\n\n/**\n * Zeroizes typed arrays in place.\n * Warning: JS provides no guarantees.\n * @param arrays - Arrays to wipe.\n * @example\n * Wipes a temporary key buffer after use.\n *\n * ```ts\n * const bytes = new Uint8Array([1]);\n * clean(bytes);\n * ```\n */\nexport function clean(...arrays: TArg<TypedArray[]>): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/**\n * Creates a DataView for byte-level manipulation.\n * @param arr - Typed-array view to wrap.\n * @returns DataView over the same bytes.\n * @example\n * Creates an endian-aware view for length encoding.\n *\n * ```ts\n * createView(new Uint8Array(4));\n * ```\n */\nexport function createView(arr: TArg<TypedArray>): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Whether the current platform is little-endian.\n * Most are; some IBM systems are not.\n */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/**\n * Reverses byte order of one 32-bit word.\n * @param word - Unsigned 32-bit word to swap.\n * @returns The same word with bytes reversed.\n * @example\n * Swaps a big-endian word into little-endian byte order.\n *\n * ```ts\n * byteSwap(0x11223344);\n * ```\n */\nexport const byteSwap = (word: number): number =>\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff);\n\n/**\n * Normalizes one 32-bit word to the little-endian representation expected by cipher cores.\n * @param n - Unsigned 32-bit word to normalize.\n * @returns Little-endian normalized word on big-endian hosts, else the input word unchanged.\n * @example\n * Normalizes a host-endian word before passing it into an ARX/AES core.\n *\n * ```ts\n * swap8IfBE(0x11223344);\n * ```\n */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n) >>> 0;\n\n/**\n * Byte-swaps every word of a Uint32Array in place.\n * @param arr - Uint32Array whose words should be swapped.\n * @returns The same array after in-place byte swapping.\n * @example\n * Swaps every 32-bit word in a word-view buffer.\n *\n * ```ts\n * byteSwap32(new Uint32Array([0x11223344]));\n * ```\n */\nexport const byteSwap32 = (arr: TArg<Uint32Array>): TRet<Uint32Array> => {\n for (let i = 0; i < arr.length; i++) arr[i] = byteSwap(arr[i]);\n return arr as TRet<Uint32Array>;\n};\n\n/**\n * Normalizes a Uint32Array view to the little-endian representation expected by cipher cores.\n * @param u - Word view to normalize in place.\n * @returns Little-endian normalized word view.\n * @example\n * Normalizes a word-view buffer before block processing.\n *\n * ```ts\n * swap32IfBE(new Uint32Array([0x11223344]));\n * ```\n */\nexport const swap32IfBE: (u: TArg<Uint32Array>) => TRet<Uint32Array> = isLE\n ? (u: TArg<Uint32Array>) => u as TRet<Uint32Array>\n : byteSwap32;\n\n// Built-in hex conversion:\n// {@link https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex | caniuse entry}\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @param bytes - Bytes to encode.\n * @returns Lowercase hexadecimal string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Formats ciphertext bytes for logs or test vectors.\n *\n * ```ts\n * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'\n * ```\n */\nexport function bytesToHex(bytes: TArg<Uint8Array>): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @param hex - Hexadecimal string to decode.\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On malformed hexadecimal input. {@link RangeError}\n * @example\n * Parses a hex test vector into bytes.\n *\n * ```ts\n * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n * ```\n */\nexport function hexToBytes(hex: string): TRet<Uint8Array> {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n if (hasHexBuiltin) {\n try {\n return (Uint8Array as any).fromHex(hex);\n } catch (error) {\n if (error instanceof SyntaxError) throw new RangeError(error.message);\n throw error;\n }\n }\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new RangeError(\n 'hex string expected, got non-hex character \"' + char + '\" at index ' + hi\n );\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array as TRet<Uint8Array>;\n}\n\n// Used in micro\n/**\n * Converts a big-endian hex string into bigint.\n * @param hex - Hexadecimal string without `0x`.\n * @returns Parsed bigint value. The empty string is treated as `0n`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Parses a big-endian field element or counter from hex.\n *\n * ```ts\n * hexToNumber('ff');\n * ```\n */\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian\n}\n\n// Used in ff1\n// BE: Big Endian, LE: Little Endian\n/**\n * Converts big-endian bytes into bigint.\n * @param bytes - Big-endian bytes.\n * @returns Parsed bigint value. Empty input is treated as `0n`.\n * @throws On invalid byte input passed to the internal hex conversion. {@link TypeError}\n * @example\n * Reads a big-endian integer from serialized bytes.\n *\n * ```ts\n * bytesToNumberBE(new Uint8Array([1, 0]));\n * ```\n */\nexport function bytesToNumberBE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\n\n// Used in micro, ff1\n/**\n * Converts a number into big-endian bytes of fixed length.\n * @param n - Number to encode.\n * @param len - Output length in bytes.\n * @returns Big-endian bytes padded to `len`.\n * Validation is indirect through `hexToBytes(...)`, so negative values, `len = 0`,\n * and values that do not fit surface through the downstream hex parser instead of a\n * dedicated range guard here.\n * @throws On wrong argument types. {@link TypeError}\n * @throws If the requested output length cannot represent the encoded value. {@link RangeError}\n * @example\n * Encodes a counter as fixed-width big-endian bytes.\n *\n * ```ts\n * numberToBytesBE(1, 2);\n * ```\n */\nexport function numberToBytesBE(n: number | bigint, len: number): TRet<Uint8Array> {\n // Reject coercible non-numeric inputs before string/hex conversion changes behavior.\n if (typeof n === 'number') anumber(n);\n else if (typeof n !== 'bigint') throw new TypeError(`number or bigint expected, got ${typeof n}`);\n anumber(len);\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\n\n// Global symbols, but ts doesn't see them:\n// {@link https://github.com/microsoft/TypeScript/issues/31535 | TypeScript issue 31535}\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @param str - String to encode.\n * @returns UTF-8 bytes in a detached fresh Uint8Array copy.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encodes application text before encryption or MACing.\n *\n * ```ts\n * utf8ToBytes('abc'); // new Uint8Array([97, 98, 99])\n * ```\n */\nexport function utf8ToBytes(str: string): TRet<Uint8Array> {\n if (typeof str !== 'string') throw new TypeError('string expected');\n return new Uint8Array(new TextEncoder().encode(str)) as TRet<Uint8Array>; // {@link https://bugzil.la/1681809 | Firefox bug 1681809}\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @param bytes - UTF-8 bytes.\n * @returns Decoded string. Input validation is delegated to `TextDecoder`, and malformed\n * UTF-8 is replacement-decoded instead of rejected.\n * @example\n * Decodes UTF-8 plaintext back into a string.\n *\n * ```ts\n * bytesToUtf8(new Uint8Array([97, 98, 99])); // 'abc'\n * ```\n */\nexport function bytesToUtf8(bytes: TArg<Uint8Array>): string {\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Checks if two U8A use same underlying buffer and overlaps.\n * This is invalid and can corrupt data.\n * @param a - First byte view.\n * @param b - Second byte view.\n * @returns `true` when the views overlap in memory.\n * @example\n * Detects whether two slices alias the same backing buffer.\n *\n * ```ts\n * overlapBytes(new Uint8Array(4), new Uint8Array(4));\n * ```\n */\nexport function overlapBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n // Zero-length views cannot overwrite anything, even if their offset sits inside another range.\n if (!a.byteLength || !b.byteLength) return false;\n return (\n a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy\n a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end\n b.byteOffset < a.byteOffset + a.byteLength // b starts before a end\n );\n}\n\n/**\n * If input and output overlap and input starts before output, we will overwrite end of input before\n * we start processing it, so this is not supported for most ciphers\n * (except chacha/salsa, which were designed for this)\n * @param input - Input bytes.\n * @param output - Output bytes.\n * @throws If the output view would overwrite unread input bytes. {@link Error}\n * @example\n * Rejects an in-place layout that would overwrite unread input bytes.\n *\n * ```ts\n * complexOverlapBytes(new Uint8Array(4), new Uint8Array(4));\n * ```\n */\nexport function complexOverlapBytes(input: TArg<Uint8Array>, output: TArg<Uint8Array>): void {\n // This is very cursed. It works somehow, but I'm completely unsure,\n // reasoning about overlapping aligned windows is very hard.\n if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)\n throw new Error('complex overlap of input and output is not supported');\n}\n\n/**\n * Copies several Uint8Arrays into one.\n * @param arrays - Byte arrays to concatenate.\n * @returns Combined byte array.\n * @throws On wrong argument types inside the byte-array list. {@link TypeError}\n * @example\n * Builds a `nonce || ciphertext` style buffer.\n *\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nexport function concatBytes(...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res as TRet<Uint8Array>;\n}\n\n// Used in ARX only\ntype EmptyObj = {};\n/**\n * Merges user options into defaults.\n * @param defaults - Default option values.\n * @param opts - User-provided overrides.\n * @returns Combined options object.\n * The merge mutates `defaults` in place and returns the same object.\n * @throws If options are missing or not an object. {@link Error}\n * @example\n * Applies user overrides to the default cipher options.\n *\n * ```ts\n * checkOpts({ rounds: 20 }, { rounds: 8 });\n * ```\n */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts: T2\n): T1 & T2 {\n if (opts == null || typeof opts !== 'object') throw new Error('options must be defined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/**\n * Compares two byte arrays in kinda constant time once lengths already match.\n * @param a - First byte array.\n * @param b - Second byte array.\n * @returns `true` when the arrays contain the same bytes. Different lengths still return early.\n * @example\n * Compares an expected authentication tag with the received one.\n *\n * ```ts\n * equalBytes(new Uint8Array([1]), new Uint8Array([1]));\n * ```\n */\nexport function equalBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n// TODO: remove\n/** Incremental hash interface used internally. */\nexport interface IHash2 {\n /** Bytes processed per compression block. */\n blockLen: number;\n /** Bytes produced by the final digest. */\n outputLen: number;\n /**\n * Absorbs one more chunk into the hash state.\n * @param buf - Data chunk to hash.\n * @returns The same hash instance for chaining.\n */\n update(buf: string | TArg<Uint8Array>): this;\n /**\n * Writes the final digest into a caller-provided buffer.\n * @param buf - Destination buffer for the digest bytes.\n * @returns Nothing. Implementations write into `buf` in place.\n */\n digestInto(buf: TArg<Uint8Array>): void;\n /**\n * Finalizes the hash and returns a fresh digest buffer.\n * @returns Digest bytes.\n */\n digest(): TRet<Uint8Array>;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n destroy(): void;\n}\n\n/**\n * Wraps a keyed MAC constructor into a one-shot helper with `.create()`.\n * @param keyLen - Valid probe-key length used to read static metadata once.\n * The probe key is only used for `outputLen` / `blockLen`, so callers with several valid key sizes\n * can pass any representative size as long as those values stay fixed.\n * @param macCons - Keyed MAC constructor or factory.\n * @param fromMsg - Optional adapter that derives extra constructor args from the one-shot message.\n * @returns Callable MAC helper with `.create()`.\n */\nexport function wrapMacConstructor<H extends IHash2, A extends any[] = []>(\n keyLen: number,\n macCons: TArg<(key: Uint8Array, ...args: A) => H>,\n fromMsg?: TArg<(msg: Uint8Array) => A>\n): TRet<CMac<H, A>> {\n const mac = macCons as (key: TArg<Uint8Array>, ...args: A) => H;\n const getArgs = (fromMsg || (() => [] as unknown as A)) as (msg: TArg<Uint8Array>) => A;\n const macC: any = (msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array> =>\n mac(key, ...getArgs(msg))\n .update(msg)\n .digest();\n const tmp = mac(new Uint8Array(keyLen), ...getArgs(new Uint8Array(0)));\n macC.outputLen = tmp.outputLen;\n macC.blockLen = tmp.blockLen;\n macC.create = (key: TArg<Uint8Array>, ...args: A) => mac(key, ...args);\n return macC as TRet<CMac<H, A>>;\n}\n\n// This will allow to re-use with composable things like packed & base encoders\n// Also, we probably can make tags composable\n\n/** Sync cipher: takes byte array and returns byte array. */\nexport type Cipher = {\n /**\n * Encrypts plaintext bytes.\n * @param plaintext - Data to encrypt.\n * @returns Ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>): TRet<Uint8Array>;\n /**\n * Decrypts ciphertext bytes.\n * @param ciphertext - Data to decrypt.\n * @returns Plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/** Async cipher e.g. from built-in WebCrypto. */\nexport type AsyncCipher = {\n /**\n * Encrypts plaintext bytes.\n * @param plaintext - Data to encrypt.\n * @returns Promise resolving to ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>): Promise<TRet<Uint8Array>>;\n /**\n * Decrypts ciphertext bytes.\n * @param ciphertext - Data to decrypt.\n * @returns Promise resolving to plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>): Promise<TRet<Uint8Array>>;\n};\n\n/** Cipher with `output` argument which can optimize by doing 1 less allocation. */\nexport type CipherWithOutput = Cipher & {\n /**\n * Encrypts plaintext bytes into an optional caller-provided buffer.\n * @param plaintext - Data to encrypt.\n * @param output - Optional destination buffer.\n * @returns Ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array>;\n /**\n * Decrypts ciphertext bytes into an optional caller-provided buffer.\n * @param ciphertext - Data to decrypt.\n * @param output - Optional destination buffer.\n * @returns Plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/**\n * Params are outside of return type, so it is accessible before calling constructor.\n * If function support multiple nonceLength's, we return the best one.\n */\nexport type CipherParams = {\n /** Cipher block size in bytes. */\n blockSize: number;\n /** Nonce length in bytes when the cipher uses a fixed nonce size. */\n nonceLength?: number;\n /** Authentication-tag length in bytes for AEAD modes. */\n tagLength?: number;\n /** Whether nonce length is variable at runtime. */\n varSizeNonce?: boolean;\n};\n/**\n * ARX AEAD cipher, like salsa or chacha.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param AAD - Optional associated data.\n * @returns Cipher instance with caller-managed output buffers.\n */\nexport type ARXCipher = ((\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n};\n/**\n * Cipher constructor signature.\n * @param key - Secret key bytes.\n * @param args - Additional constructor arguments, such as nonce or IV.\n * @returns Cipher instance.\n */\nexport type CipherCons<T extends any[]> = (key: TArg<Uint8Array>, ...args: T) => Cipher;\n/**\n * Wraps a cipher: validates args, ensures encrypt() can only be called once.\n * Used internally by the exported cipher constructors.\n * Output-buffer support is inferred from the wrapped `encrypt` / `decrypt`\n * arity (`fn.length === 2`), and tag-bearing constructors are expected to use\n * `args[1]` for optional AAD.\n * @__NO_SIDE_EFFECTS__\n * @param params - Static cipher metadata. See {@link CipherParams}.\n * @param constructor - Cipher constructor.\n * @returns Wrapped constructor with validation.\n */\nexport const wrapCipher = <C extends CipherCons<any>, P extends CipherParams>(\n params: P,\n constructor: C\n): C & P => {\n function wrappedCipher(key: TArg<Uint8Array>, ...args: any[]): TRet<CipherWithOutput> {\n // Validate key\n abytes(key, undefined, 'key');\n\n // Validate nonce if nonceLength is present\n if (params.nonceLength !== undefined) {\n const nonce = args[0];\n abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce');\n }\n\n // Validate AAD if tagLength present\n const tagl = params.tagLength;\n if (tagl && args[1] !== undefined) abytes(args[1], undefined, 'AAD');\n\n const cipher = constructor(key, ...args);\n const checkOutput = (fnLength: number, output?: TArg<Uint8Array>) => {\n if (output !== undefined) {\n if (fnLength !== 2) throw new Error('cipher output not supported');\n abytes(output, undefined, 'output');\n }\n };\n // Create wrapped cipher with validation and single-use encryption\n let called = false;\n const wrCipher = {\n encrypt(data: TArg<Uint8Array>, output?: TArg<Uint8Array>) {\n if (called) throw new Error('cannot encrypt() twice with same key + nonce');\n called = true;\n abytes(data);\n checkOutput(cipher.encrypt.length, output);\n return (cipher as CipherWithOutput).encrypt(data, output);\n },\n decrypt(data: TArg<Uint8Array>, output?: TArg<Uint8Array>) {\n abytes(data);\n if (tagl && data.length < tagl)\n throw new Error('\"ciphertext\" expected length bigger than tagLength=' + tagl);\n checkOutput(cipher.decrypt.length, output);\n return (cipher as CipherWithOutput).decrypt(data, output);\n },\n };\n\n return wrCipher as TRet<CipherWithOutput>;\n }\n\n Object.assign(wrappedCipher, params);\n return wrappedCipher as C & P;\n};\n\n/**\n * Represents a Salsa or ChaCha xor stream.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Optional starting block counter.\n * @returns Output bytes.\n */\nexport type XorStream = (\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n data: TArg<Uint8Array>,\n output?: TArg<Uint8Array>,\n counter?: number\n) => TRet<Uint8Array>;\n\n/**\n * By default, returns u8a of length.\n * When out is available, it checks it for validity and uses it.\n * @param expectedLength - Required output length.\n * @param out - Optional destination buffer.\n * @param onlyAligned - Whether `out` must be 4-byte aligned.\n * @returns Output buffer ready for writing.\n * @throws On wrong argument types. {@link TypeError}\n * @throws If the provided output buffer has the wrong size or alignment. {@link Error}\n * @example\n * Reuses a caller-provided output buffer when lengths match.\n *\n * ```ts\n * getOutput(16, new Uint8Array(16));\n * ```\n */\nexport function getOutput(\n expectedLength: number,\n out?: TArg<Uint8Array>,\n onlyAligned = true\n): TRet<Uint8Array> {\n if (out === undefined) return new Uint8Array(expectedLength) as TRet<Uint8Array>;\n // Keep Buffer/cross-realm Uint8Array support here instead of trusting a shape-compatible object.\n abytes(out, undefined, 'output');\n if (out.length !== expectedLength)\n throw new Error(\n '\"output\" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length\n );\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n return out as TRet<Uint8Array>;\n}\n\n/**\n * Encodes data and AAD bit lengths into a 16-byte buffer.\n * @param dataLength - Data length in bits.\n * @param aadLength - AAD length in bits.\n * The serialized block is still `aadLength || dataLength`, matching GCM/Poly1305\n * conventions even though the helper parameter order is `(dataLength, aadLength)`.\n * @param isLE - Whether to encode lengths as little-endian.\n * @returns 16-byte length block.\n * @throws On wrong argument types passed to the endian validator. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Builds the length block appended by GCM and Poly1305.\n *\n * ```ts\n * u64Lengths(16, 8, true);\n * ```\n */\nexport function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): TRet<Uint8Array> {\n // Reject coercible non-number lengths like '10' and true before BigInt(...) accepts them.\n anumber(dataLength);\n anumber(aadLength);\n abool(isLE);\n const num = new Uint8Array(16);\n const view = createView(num);\n view.setBigUint64(0, BigInt(aadLength), isLE);\n view.setBigUint64(8, BigInt(dataLength), isLE);\n return num as TRet<Uint8Array>;\n}\n\n/**\n * Checks whether a byte array is aligned to a 4-byte offset.\n * @param bytes - Byte array to inspect.\n * @returns `true` when the view is 4-byte aligned.\n * @example\n * Checks whether a buffer can be safely viewed as Uint32Array.\n *\n * ```ts\n * isAligned32(new Uint8Array(4));\n * ```\n */\nexport function isAligned32(bytes: TArg<Uint8Array>): boolean {\n return bytes.byteOffset % 4 === 0;\n}\n\n/**\n * Copies bytes into a new Uint8Array.\n * @param bytes - Bytes to copy.\n * @returns Copied byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Copies input into an aligned Uint8Array before block processing.\n *\n * ```ts\n * copyBytes(new Uint8Array([1, 2]));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Cryptographically secure PRNG.\n * Uses internal OS-level `crypto.getRandomValues`.\n * @param bytesLength - Number of bytes to produce.\n * Validation is delegated to `Uint8Array(bytesLength)` and `getRandomValues`, so\n * non-integers, negative lengths, and oversize requests surface backend/runtime errors.\n * @returns Random byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @throws If the runtime does not expose `crypto.getRandomValues`. {@link Error}\n * @example\n * Generates a fresh nonce or key.\n *\n * ```ts\n * randomBytes(16);\n * ```\n */\nexport function randomBytes(bytesLength = 32): TRet<Uint8Array> {\n // Validate upfront so fractional / coercible lengths do not silently\n // truncate through Uint8Array().\n anumber(bytesLength);\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n return cr.getRandomValues(new Uint8Array(bytesLength)) as TRet<Uint8Array>;\n}\n\n/**\n * The pseudorandom number generator doesn't wipe current state:\n * instead, it generates new one based on previous state + entropy.\n * Not reseed/rekey, since AES CTR DRBG does rekey on each randomBytes,\n * which is in fact `reseed`, since it changes counter too.\n */\nexport interface PRG {\n /**\n * Mixes fresh entropy into the current generator state.\n * @param seed - Entropy bytes to absorb.\n */\n addEntropy(seed: TArg<Uint8Array>): void;\n /**\n * Produces a requested number of pseudorandom bytes.\n * @param bytesLength - Number of bytes to generate.\n * @returns Random byte array.\n */\n randomBytes(bytesLength: number): TRet<Uint8Array>;\n /** Destroys the generator state. */\n clean(): void;\n}\n\n/** Removes the nonce argument from a cipher constructor type. */\nexport type RemoveNonce<T extends (...args: any) => any> = T extends (\n arg0: any,\n arg1: any,\n ...rest: infer R\n) => infer Ret\n ? (key: TArg<Uint8Array>, ...args: R) => Ret\n : never;\n/**\n * Cipher constructor that requires a nonce argument.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param args - Additional cipher-specific arguments.\n * @returns Cipher instance.\n */\nexport type CipherWithNonce = ((\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n ...args: any[]\n) => Cipher | AsyncCipher) & {\n nonceLength: number;\n};\n\n/**\n * Uses CSPRNG for nonce, nonce injected in ciphertext.\n * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and\n * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext\n * are treated as nonce. The wrapper always allocates a fresh `nonce || ciphertext`\n * buffer on encrypt and intentionally does not support caller-provided destination buffers.\n * Too-short decrypt inputs are split into short/empty nonce views and then delegated\n * to the wrapped cipher instead of being rejected here first.\n *\n * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha\n * should be limited to `2**23` (8M) messages to get a collision chance of\n * `2**-50`. Stretching to `2**32` (4B) messages would raise that chance to\n * `2**-33`, still negligible but creeping up.\n * @param fn - Cipher constructor that expects a nonce.\n * @param randomBytes_ - Random-byte source used for nonce generation.\n * @returns Cipher constructor that prepends the nonce to ciphertext.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On invalid nonce lengths observed at wrapper construction or use. {@link RangeError}\n * @example\n * Prepends a fresh random nonce to every ciphertext.\n *\n * ```ts\n * import { gcm } from '@noble/ciphers/aes.js';\n * import { managedNonce, randomBytes } from '@noble/ciphers/utils.js';\n * const wrapped = managedNonce(gcm);\n * const key = randomBytes(16);\n * const ciphertext = wrapped(key).encrypt(new Uint8Array([1, 2, 3]));\n * wrapped(key).decrypt(ciphertext);\n * ```\n */\nexport function managedNonce<T extends CipherWithNonce>(\n fn: T,\n randomBytes_: typeof randomBytes = randomBytes\n): TRet<RemoveNonce<T>> {\n const { nonceLength } = fn;\n anumber(nonceLength);\n const addNonce = (\n nonce: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n plaintext: TArg<Uint8Array>\n ) => {\n const out = concatBytes(nonce, ciphertext);\n // Wrapped ciphers may alias caller plaintext on encrypt(); never zero\n // caller-owned buffers here.\n if (!overlapBytes(plaintext, ciphertext)) ciphertext.fill(0);\n return out;\n };\n // NOTE: we cannot support DST here, it would be mistake:\n // - we don't know how much dst length cipher requires\n // - nonce may unalign dst and break everything\n // - we create new u8a anyway (concatBytes)\n // - previously we passed all args to cipher, but that was mistake!\n const res = ((key: TArg<Uint8Array>, ...args: any[]): any => ({\n encrypt(plaintext: TArg<Uint8Array>) {\n abytes(plaintext);\n const nonce = randomBytes_(nonceLength);\n const encrypted = fn(key, nonce, ...args).encrypt(plaintext);\n // @ts-ignore\n if (encrypted instanceof Promise)\n return encrypted.then((ct) => addNonce(nonce, ct, plaintext));\n return addNonce(nonce, encrypted, plaintext);\n },\n decrypt(ciphertext: TArg<Uint8Array>) {\n abytes(ciphertext);\n const nonce = ciphertext.subarray(0, nonceLength);\n const decrypted = ciphertext.subarray(nonceLength);\n return fn(key, nonce, ...args).decrypt(decrypted);\n },\n })) as RemoveNonce<T> & { blockSize?: number; tagLength?: number };\n // Auto-nonce wrappers still preserve the wrapped payload geometry.\n if ('blockSize' in fn) res.blockSize = (fn as any).blockSize;\n if ('tagLength' in fn) res.tagLength = (fn as any).tagLength;\n return res as TRet<RemoveNonce<T>>;\n}\n\n/** `Uint8Array.of()` return type helper for TS 5.9. */\nexport type Uint8ArrayBuffer = TRet<Uint8Array>;\n","/**\n * Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.\n\nRFC8439 requires multi-step cipher stream, where\nauthKey starts with counter: 0, actual msg with counter: 1.\n\nFor this, we need a way to re-use nonce / counter:\n\n const counter = new Uint8Array(4);\n chacha(..., counter, ...); // counter is now 1\n chacha(..., counter, ...); // counter is now 2\n\nThis is complicated:\n\n- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB\n- Original papers don't allow mutating counters\n- Counter overflow is undefined [^1]\n- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it\n- Caveat: Cannot be re-used through all cases:\n- * chacha has (counter | nonce)\n- * xchacha has (nonce16 | counter | nonce16)\n- Idea B: separate nonce / counter and provide separate API for counter re-use\n- Caveat: there are different counter sizes depending on an algorithm.\n- salsa & chacha also differ in structures of key & sigma:\n salsa20: s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3]\n chacha: s(4) | k(8) | cnt(1) | nonce(3)\n chacha20orig: s(4) | k(8) | cnt(2) | nonce(2)\n- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`\n- Caveat: we can't re-use counter array\n\nxchacha uses the subkey and remaining 8 byte nonce with ChaCha20 as normal\n(prefixed by 4 NUL bytes, since RFC8439 specifies a 12-byte nonce).\nCounter overflow is undefined; see {@link https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/ | the CFRG thread}.\nCurrent noble policy is strict non-wrap for the shared 32-bit counter path:\nexported ARX ciphers reject initial `0xffffffff` and stop before any implicit\nwrap back to zero.\nSee {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2 | the XChaCha appendix} for the extended-nonce construction.\n\n * @module\n */\nimport {\n type PRG,\n type TArg,\n type TRet,\n type XorStream,\n abool,\n abytes,\n anumber,\n checkOpts,\n clean,\n copyBytes,\n getOutput,\n isAligned32,\n isLE,\n randomBytes,\n swap32IfBE,\n u32,\n} from './utils.ts';\n\n// Replaces `TextEncoder` for ASCII literals, which is enough for sigma constants.\n// Non-ASCII input would not match UTF-8 `TextEncoder` output.\nconst encodeStr = (str: string) => Uint8Array.from(str.split(''), (c) => c.charCodeAt(0));\n// Raw `createCipher(...)` exports consume these native-endian `u32(...)` views directly.\n// Public `wrapCipher(...)` APIs reject non-little-endian platforms before reaching this path.\n// RFC 8439 §2.3 / RFC 7539 §2.3 only define the 256-bit-key constants; this 16-byte sigma is\n// kept for legacy allowShortKeys Salsa/ChaCha variants.\nconst sigma16_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 16-byte k'))))();\n// RFC 8439 §2.3 / RFC 7539 §2.3 define words 0-3 as\n// `0x61707865 0x3320646e 0x79622d32 0x6b206574`, i.e. `expand 32-byte k`.\nconst sigma32_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 32-byte k'))))();\n\n/**\n * Rotates a 32-bit word left.\n * @param a - Input word.\n * @param b - Rotation count in bits.\n * @returns Rotated 32-bit word.\n * @example\n * Moves the top byte of `0x12345678` into the low byte position.\n * ```ts\n * rotl(0x12345678, 8);\n * ```\n */\nexport function rotl(a: number, b: number): number {\n return (a << b) | (a >>> (32 - b));\n}\n\n/**\n * ARX core function operating on 32-bit words. Ciphers must use u32 for efficiency.\n * @param sigma - Sigma constants for the selected cipher layout.\n * @param key - Expanded key words.\n * @param nonce - Nonce and counter words prepared for the round function.\n * @param output - Output block written in place.\n * @param counter - Block counter value.\n * @param rounds - Optional round count override.\n */\nexport type CipherCoreFn = (\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n nonce: TArg<Uint32Array>,\n output: TArg<Uint32Array>,\n counter: number,\n rounds?: number\n) => void;\n\n/**\n * Nonce-extension function used by XChaCha and XSalsa.\n * @param sigma - Sigma constants for the selected cipher layout.\n * @param key - Expanded key words.\n * @param input - Input nonce words used for subkey derivation.\n * @param output - Output buffer written with the derived nonce words.\n */\nexport type ExtendNonceFn = (\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n input: TArg<Uint32Array>,\n output: TArg<Uint32Array>\n) => void;\n\n/** ARX cipher options.\n * * `allowShortKeys` for 16-byte keys\n * * `counterLength` in bytes\n * * `counterRight`: right: `nonce|counter`; left: `counter|nonce`\n * */\nexport type CipherOpts = {\n /** Whether 16-byte keys are accepted for legacy Salsa and ChaCha variants. */\n allowShortKeys?: boolean;\n /** Optional nonce-expansion hook used by extended-nonce variants. */\n extendNonceFn?: ExtendNonceFn;\n /** Counter length in bytes inside the nonce/counter layout. */\n counterLength?: number;\n /** Whether the layout is `nonce|counter` instead of `counter|nonce`. */\n counterRight?: boolean;\n /** Number of core rounds to execute. */\n rounds?: number;\n};\n\n// Salsa and Chacha block length is always 512-bit\nconst BLOCK_LEN = 64;\n// RFC 8439 §2.2 / RFC 7539 §2.2: the ChaCha state has 16 32-bit words.\nconst BLOCK_LEN32 = 16;\n\n// Counter policy for the shared public `counter` argument:\n// - RFC/IETF ChaCha20 uses a 32-bit counter.\n// - OpenSSL/Node `chacha20` instead treat the full 16-byte IV as a 128-bit\n// counter state and carry into the next word.\n// - Raw `chacha20orig`, `salsa20`, `xsalsa20`, and `xchacha20` use 64-bit counters in libsodium\n// and libtomcrypt, while some libs (for example libtomcrypt's RFC/IETF path) reject the max\n// boundary instead of carrying.\n// - AEAD wrappers diverge too: libsodium `xchacha20poly1305` uses the IETF payload counter from\n// block 1, while `secretstream_xchacha20poly1305` is a different protocol with rekey/reset.\n// Noble intentionally throws instead of silently picking one wrap model for users. In the default\n// path, even a 32-bit boundary would take 2^32 blocks * 64 bytes = 256 GiB, which is practically\n// unreachable for normal JS callers; advanced users who pass `counter` explicitly can implement\n// whatever wider carry / wrap policy they need on top.\nconst MAX_COUNTER = /* @__PURE__ */ (() => 2 ** 32 - 1)();\nconst U32_EMPTY = /* @__PURE__ */ Uint32Array.of();\nfunction runCipher(\n core: TArg<CipherCoreFn>,\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n nonce: TArg<Uint32Array>,\n data: TArg<Uint8Array>,\n output: TArg<Uint8Array>,\n counter: number,\n rounds: number\n): void {\n const len = data.length;\n const block = new Uint8Array(BLOCK_LEN);\n const b32 = u32(block);\n // Make sure that buffers aligned to 4 bytes\n const isAligned = isLE && isAligned32(data) && isAligned32(output);\n const d32 = isAligned ? u32(data) : U32_EMPTY;\n const o32 = isAligned ? u32(output) : U32_EMPTY;\n // RFC 8439 §2.4.1 / RFC 7539 §2.4.1 allow XORing one keystream block at a time and\n // truncating the final partial block instead of materializing the whole keystream.\n if (!isLE) {\n for (let pos = 0; pos < len; counter++) {\n core(\n sigma as TRet<Uint32Array>,\n key as TRet<Uint32Array>,\n nonce as TRet<Uint32Array>,\n b32,\n counter,\n rounds\n );\n // RFC 8439 §2.4 / RFC 7539 §2.4 serialize keystream words in little-endian order.\n swap32IfBE(b32);\n if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const take = Math.min(BLOCK_LEN, len - pos);\n for (let j = 0, posj; j < take; j++) {\n posj = pos + j;\n output[posj] = data[posj] ^ block[j];\n }\n pos += take;\n }\n return;\n }\n for (let pos = 0; pos < len; counter++) {\n core(\n sigma as TRet<Uint32Array>,\n key as TRet<Uint32Array>,\n nonce as TRet<Uint32Array>,\n b32,\n counter,\n rounds\n );\n // See MAX_COUNTER policy note above: never silently wrap the shared public counter.\n if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const take = Math.min(BLOCK_LEN, len - pos);\n // aligned to 4 bytes\n if (isAligned && take === BLOCK_LEN) {\n const pos32 = pos / 4;\n if (pos % 4 !== 0) throw new Error('arx: invalid block position');\n for (let j = 0, posj: number; j < BLOCK_LEN32; j++) {\n posj = pos32 + j;\n o32[posj] = d32[posj] ^ b32[j];\n }\n pos += BLOCK_LEN;\n continue;\n }\n for (let j = 0, posj; j < take; j++) {\n posj = pos + j;\n output[posj] = data[posj] ^ block[j];\n }\n pos += take;\n }\n}\n\n/**\n * Creates an ARX stream cipher from a 32-bit core permutation.\n * Used internally to build the exported Salsa and ChaCha stream ciphers.\n * @param core - Core function that fills one keystream block.\n * @param opts - Cipher layout and nonce-extension options. See {@link CipherOpts}.\n * @returns Stream cipher function over byte arrays.\n * @throws If the core callback, key size, counter, or output sizing is invalid. {@link Error}\n */\nexport function createCipher(core: TArg<CipherCoreFn>, opts: TArg<CipherOpts>): TRet<XorStream> {\n const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts(\n { allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 },\n opts\n );\n if (typeof core !== 'function') throw new Error('core must be a function');\n anumber(counterLength);\n anumber(rounds);\n abool(counterRight);\n abool(allowShortKeys);\n return (\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n data: TArg<Uint8Array>,\n output?: TArg<Uint8Array>,\n counter = 0\n ): TRet<Uint8Array> => {\n abytes(key, undefined, 'key');\n abytes(nonce, undefined, 'nonce');\n abytes(data, undefined, 'data');\n const len = data.length;\n // Raw XorStream APIs return ciphertext/plaintext bytes directly, so caller-provided outputs\n // must match the logical result length exactly instead of returning an oversized workspace.\n output = getOutput(len, output, false);\n anumber(counter);\n // See MAX_COUNTER policy note above: reject advanced explicit-counter requests before any wrap.\n if (counter < 0 || counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const toClean = [];\n\n // Key & sigma\n // key=16 -> sigma16, k=key|key\n // key=32 -> sigma32, k=key\n let l = key.length;\n let k: Uint8Array;\n let sigma: Uint32Array;\n if (l === 32) {\n // Copy caller keys too: big-endian normalization, extended-nonce subkey derivation, and\n // final clean(...) all mutate or wipe the temporary buffer in place.\n toClean.push((k = copyBytes(key)));\n sigma = sigma32_32;\n } else if (l === 16 && allowShortKeys) {\n k = new Uint8Array(32);\n k.set(key);\n k.set(key, 16);\n sigma = sigma16_32;\n toClean.push(k);\n } else {\n abytes(key, 32, 'arx key');\n throw new Error('invalid key size');\n // throw new Error(`\"arx key\" expected Uint8Array of length 32, got length=${l}`);\n }\n\n // Nonce\n // salsa20: 8 (8-byte counter)\n // chacha20orig: 8 (8-byte counter)\n // chacha20: 12 (4-byte counter)\n // xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)\n // xchacha20: 24 (16 -> hchacha, 8 -> old nonce)\n // Copy before taking u32(...) views on misaligned inputs, and on big-endian so later\n // swap32IfBE(...) never mutates caller nonce bytes in place.\n if (!isLE || !isAligned32(nonce)) toClean.push((nonce = copyBytes(nonce)));\n\n let k32 = u32(k);\n // hsalsa & hchacha: handle extended nonce\n if (extendNonceFn) {\n if (nonce.length !== 24) throw new Error(`arx: extended nonce must be 24 bytes`);\n const n16 = nonce.subarray(0, 16);\n if (isLE) extendNonceFn(sigma as TRet<Uint32Array>, k32, u32(n16), k32);\n else {\n const sigmaRaw = swap32IfBE(Uint32Array.from(sigma));\n extendNonceFn(sigmaRaw, k32, u32(n16), k32);\n clean(sigmaRaw);\n swap32IfBE(k32);\n }\n nonce = nonce.subarray(16);\n } else if (!isLE) swap32IfBE(k32);\n\n // Handle nonce counter\n const nonceNcLen = 16 - counterLength;\n if (nonceNcLen !== nonce.length)\n throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);\n\n // Normalize 64-bit-nonce layouts to the 12-byte core input: ChaCha/XChaCha prefix 4 zero\n // counter bytes, while Salsa/XSalsa append them after the nonce words.\n if (nonceNcLen !== 12) {\n const nc = new Uint8Array(12);\n nc.set(nonce, counterRight ? 0 : 12 - nonce.length);\n nonce = nc;\n toClean.push(nonce);\n }\n const n32 = swap32IfBE(u32(nonce));\n // Ensure temporary key/nonce copies are wiped even if the remaining\n // runtime guard in runCipher(...) throws on counter overflow.\n try {\n runCipher(core, sigma, k32, n32, data, output, counter, rounds);\n return output as TRet<Uint8Array>;\n } finally {\n clean(...toClean);\n }\n };\n}\n\n/** Internal class which wraps chacha20 or chacha8 to create CSPRNG. */\nexport class _XorStreamPRG implements PRG {\n readonly blockLen: number;\n readonly keyLen: number;\n readonly nonceLen: number;\n private state: TRet<Uint8Array>;\n private buf: TRet<Uint8Array>;\n private key: TRet<Uint8Array>;\n private nonce: TRet<Uint8Array>;\n private pos: number;\n private ctr: number;\n private cipher: TArg<XorStream>;\n constructor(\n cipher: TArg<XorStream>,\n blockLen: number,\n keyLen: number,\n nonceLen: number,\n seed: TArg<Uint8Array>\n ) {\n this.cipher = cipher;\n this.blockLen = blockLen;\n this.keyLen = keyLen;\n this.nonceLen = nonceLen;\n this.state = new Uint8Array(this.keyLen + this.nonceLen) as TRet<Uint8Array>;\n this.reseed(seed);\n this.ctr = 0;\n this.pos = this.blockLen;\n this.buf = new Uint8Array(this.blockLen) as TRet<Uint8Array>;\n // Keep a single key||nonce backing buffer so reseed/addEntropy/clean update the live cipher\n // inputs in place through these subarray views.\n this.key = this.state.subarray(0, this.keyLen) as TRet<Uint8Array>;\n this.nonce = this.state.subarray(this.keyLen) as TRet<Uint8Array>;\n }\n private reseed(seed: TArg<Uint8Array>) {\n abytes(seed);\n if (!seed || seed.length === 0) throw new Error('entropy required');\n // Mix variable-length entropy cyclically across the whole key||nonce state, then restart the\n // keystream so buffered leftovers from the previous state are never reused.\n for (let i = 0; i < seed.length; i++) this.state[i % this.state.length] ^= seed[i];\n this.ctr = 0;\n this.pos = this.blockLen;\n }\n addEntropy(seed: TArg<Uint8Array>): void {\n // Reject empty entropy before re-keying, otherwise a throwing call would still advance state.\n abytes(seed);\n if (seed.length === 0) throw new Error('entropy required');\n // Re-key from the current stream first, then mix external entropy into the fresh key||nonce\n // state through reseed() so stale buffered bytes are discarded.\n this.state.set(this.randomBytes(this.state.length));\n this.reseed(seed);\n }\n randomBytes(len: number): TRet<Uint8Array> {\n anumber(len);\n if (len === 0) return new Uint8Array(0) as TRet<Uint8Array>;\n const avail = this.pos < this.blockLen ? this.blockLen - this.pos : 0;\n const blocks = Math.ceil(Math.max(0, len - avail) / this.blockLen);\n // Preflight overflow so failed reads don't partially consume keystream\n // and leave the PRG repeating blocks.\n if (blocks > 0 && this.ctr > MAX_COUNTER - blocks) throw new Error('arx: counter overflow');\n const out = new Uint8Array(len);\n let outPos = 0;\n // `out` starts zero-filled, and `buf.fill(0)` below does the same for leftovers: XOR-stream\n // ciphers then emit raw keystream bytes directly into those buffers.\n // Serve buffered leftovers first so split reads stay identical to one larger read.\n if (this.pos < this.blockLen) {\n const take = Math.min(len, this.blockLen - this.pos);\n out.set(this.buf.subarray(this.pos, this.pos + take), 0);\n this.pos += take;\n outPos += take;\n if (outPos === len) return out as TRet<Uint8Array>; // fast path\n }\n // Full blocks directly to out\n const full = Math.floor((len - outPos) / this.blockLen);\n if (full > 0) {\n const blockBytes = full * this.blockLen;\n const b = out.subarray(outPos, outPos + blockBytes);\n this.cipher(this.key, this.nonce, b as TRet<Uint8Array>, b as TRet<Uint8Array>, this.ctr);\n this.ctr += full;\n outPos += blockBytes;\n }\n // Save leftovers\n const left = len - outPos;\n if (left > 0) {\n this.buf.fill(0);\n // NOTE: cipher will handle overflow\n this.cipher(\n this.key,\n this.nonce,\n this.buf as TRet<Uint8Array>,\n this.buf as TRet<Uint8Array>,\n this.ctr++\n );\n out.set(this.buf.subarray(0, left), outPos);\n this.pos = left;\n }\n return out as TRet<Uint8Array>;\n }\n // Clone seeds the new instance from this stream, so the source PRG advances too.\n clone(): _XorStreamPRG {\n return new _XorStreamPRG(\n this.cipher,\n this.blockLen,\n this.keyLen,\n this.nonceLen,\n this.randomBytes(this.state.length)\n );\n }\n // Zeroes the current state and leftover buffer, but does not make the instance unusable:\n // Later reads first drain zeros from the cleared buffer and then continue\n // from zero key||nonce state.\n clean(): void {\n this.pos = 0;\n this.ctr = 0;\n this.buf.fill(0);\n this.state.fill(0);\n }\n}\n\n/**\n * PRG constructor backed by an ARX stream cipher.\n * @param seed - Optional seed bytes mixed into the initial state. When omitted, exactly 32\n * random bytes are mixed in by default: larger states keep a zero tail, while smaller states\n * wrap those bytes through `reseed()`'s XOR schedule.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n */\nexport type XorPRG = (seed?: TArg<Uint8Array>) => TRet<_XorStreamPRG>;\n\n/**\n * Creates a PRG constructor from a stream cipher.\n * @param cipher - Stream cipher used to fill output blocks.\n * @param blockLen - Keystream block length in bytes.\n * @param keyLen - Internal key length in bytes.\n * @param nonceLen - Internal nonce length in bytes.\n * @returns PRG factory for seeded concrete `_XorStreamPRG` instances.\n * @example\n * Builds a PRG from XChaCha20 and reads bytes from a randomly seeded instance.\n * ```ts\n * import { xchacha20 } from '@noble/ciphers/chacha.js';\n * import { createPRG } from '@noble/ciphers/_arx.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const init = createPRG(xchacha20, 64, 32, 24);\n * const prg = init(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const createPRG = (\n cipher: TArg<XorStream>,\n blockLen: number,\n keyLen: number,\n nonceLen: number\n): TRet<XorPRG> => {\n return ((seed: TArg<Uint8Array> = randomBytes(32)): TRet<_XorStreamPRG> =>\n new _XorStreamPRG(\n cipher,\n blockLen,\n keyLen,\n nonceLen,\n seed\n ) as TRet<_XorStreamPRG>) as TRet<XorPRG>;\n};\n","/**\n * Poly1305 ({@link https://cr.yp.to/mac/poly1305-20050329.pdf | PDF},\n * {@link https://en.wikipedia.org/wiki/Poly1305 | wiki})\n * is a fast and parallel secret-key message-authentication code suitable for\n * a wide variety of applications. It was standardized in\n * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and is now used in TLS 1.3.\n *\n * Polynomial MACs are not perfect for every situation:\n * they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes.\n * See {@link https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/ | the invisible salamanders attack writeup}.\n * To combat invisible salamanders, `hash(key)` can be included in ciphertext,\n * however, this would violate ciphertext indistinguishability:\n * an attacker would know which key was used - so `HKDF(key, i)`\n * could be used instead.\n *\n * Check out the {@link https://cr.yp.to/mac.html | original website}.\n * Based on public-domain {@link https://github.com/floodyberry/poly1305-donna | poly1305-donna}.\n * @module\n */\n// prettier-ignore\nimport {\n abytes, aexists, aoutput, bytesToHex,\n clean, concatBytes, copyBytes, hexToNumber, numberToBytesBE,\n wrapMacConstructor, type CMac, type IHash2, type TArg, type TRet\n} from './utils.ts';\n\n// Little-endian 2-byte load used by the Poly1305 limb decomposition.\nfunction u8to16(a: TArg<Uint8Array>, i: number) {\n return (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);\n}\n\nfunction bytesToNumberLE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));\n}\n\n/** Small version of `poly1305` without loop unrolling. Unused, provided for auditability. */\nfunction poly1305_small(msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array> {\n abytes(msg);\n abytes(key, 32, 'key');\n const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5); // 2^130-5\n const POW_2_128_1 = BigInt(2) ** BigInt(128) - BigInt(1); // 2^128-1\n const CLAMP_R = BigInt('0x0ffffffc0ffffffc0ffffffc0fffffff');\n const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R;\n const s = bytesToNumberLE(key.subarray(16));\n // Process by 16 byte chunks\n let acc = BigInt(0);\n for (let i = 0; i < msg.length; i += 16) {\n const m = msg.subarray(i, i + 16);\n // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 append [0x01] to each chunk before multiplying by r.\n const n = bytesToNumberLE(m) | (BigInt(1) << BigInt(8 * m.length));\n acc = ((acc + n) * r) % POW_2_130_5;\n }\n const res = (acc + s) & POW_2_128_1;\n // RFC 8439 §2.5 / RFC 7539 §2.5 serialize the low 128 bits in little-endian order.\n return numberToBytesBE(res, 16).reverse() as TRet<Uint8Array>; // LE\n}\n\n// Can be used to replace `computeTag` in chacha.ts. Unused, provided for auditability.\n// @ts-expect-error\nfunction poly1305_computeTag_small(\n authKey: TArg<Uint8Array>,\n // AEAD trailer must already be the 16-byte length block:\n // 8-byte little-endian AAD length || 8-byte little-endian ciphertext length.\n lengths: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n // RFC 8439 §2.8.1 / RFC 7539 §2.8.1 MAC input is\n // AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || lengths.\n const res = [];\n const updatePadded2 = (msg: TArg<Uint8Array>) => {\n res.push(msg);\n const leftover = msg.length % 16;\n // RFC 8439 §2.8.1 / RFC 7539 §2.8.1: pad16(x) is empty for aligned\n // inputs, else 16-(len%16) zero bytes.\n if (leftover) res.push(new Uint8Array(16).slice(leftover));\n };\n if (AAD) updatePadded2(AAD);\n updatePadded2(ciphertext);\n res.push(lengths);\n return poly1305_small(concatBytes(...res), authKey);\n}\n\n/**\n * Incremental Poly1305 MAC state.\n * Prefer `poly1305()` for one-shot use.\n * @param key - 32-byte Poly1305 one-time key.\n * @example\n * Feeds one chunk into an incremental Poly1305 state with a fresh one-time key.\n *\n * ```ts\n * import { Poly1305 } from '@noble/ciphers/_poly1305.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const mac = new Poly1305(key);\n * mac.update(new Uint8Array([1, 2, 3]));\n * mac.digest();\n * ```\n */\nexport class Poly1305 implements IHash2 {\n readonly blockLen = 16;\n readonly outputLen = 16;\n private buffer = new Uint8Array(16);\n private r = new Uint16Array(10); // Allocating 1 array with .subarray() here is slower than 3\n private h = new Uint16Array(10);\n private pad = new Uint16Array(8);\n private pos = 0;\n protected finished = false;\n protected destroyed = false;\n\n // Can be speed-up using BigUint64Array, at the cost of complexity\n constructor(key: TArg<Uint8Array>) {\n key = copyBytes(abytes(key, 32, 'key'));\n const t0 = u8to16(key, 0);\n const t1 = u8to16(key, 2);\n const t2 = u8to16(key, 4);\n const t3 = u8to16(key, 6);\n const t4 = u8to16(key, 8);\n const t5 = u8to16(key, 10);\n const t6 = u8to16(key, 12);\n const t7 = u8to16(key, 14);\n\n // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 clamp r before multiplication.\n // These masks unpack that clamped value into 13-bit limbs, while pad\n // keeps the raw s half for finalize().\n // {@link https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47 | poly1305-donna reference}\n this.r[0] = t0 & 0x1fff;\n this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;\n this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;\n this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;\n this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;\n this.r[5] = (t4 >>> 1) & 0x1ffe;\n this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;\n this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;\n this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;\n this.r[9] = (t7 >>> 5) & 0x007f;\n for (let i = 0; i < 8; i++) this.pad[i] = u8to16(key, 16 + 2 * i);\n }\n\n private process(data: TArg<Uint8Array>, offset: number, isLast = false) {\n // RFC 8439 §2.5 / §2.5.1 and RFC 7539 §2.5 / §2.5.1 add an extra high\n // bit to every full 16-byte block. The final partial block gets its\n // explicit `1` byte during digestInto(), so `hibit` stays zero there.\n const hibit = isLast ? 0 : 1 << 11;\n const { h, r } = this;\n const r0 = r[0];\n const r1 = r[1];\n const r2 = r[2];\n const r3 = r[3];\n const r4 = r[4];\n const r5 = r[5];\n const r6 = r[6];\n const r7 = r[7];\n const r8 = r[8];\n const r9 = r[9];\n\n const t0 = u8to16(data, offset + 0);\n const t1 = u8to16(data, offset + 2);\n const t2 = u8to16(data, offset + 4);\n const t3 = u8to16(data, offset + 6);\n const t4 = u8to16(data, offset + 8);\n const t5 = u8to16(data, offset + 10);\n const t6 = u8to16(data, offset + 12);\n const t7 = u8to16(data, offset + 14);\n\n let h0 = h[0] + (t0 & 0x1fff);\n let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);\n let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);\n let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);\n let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);\n let h5 = h[5] + ((t4 >>> 1) & 0x1fff);\n let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);\n let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);\n let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);\n let h9 = h[9] + ((t7 >>> 5) | hibit);\n\n let c = 0;\n\n let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6);\n c = d0 >>> 13;\n d0 &= 0x1fff;\n d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1);\n c += d0 >>> 13;\n d0 &= 0x1fff;\n\n let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7);\n c = d1 >>> 13;\n d1 &= 0x1fff;\n d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2);\n c += d1 >>> 13;\n d1 &= 0x1fff;\n\n let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);\n c = d2 >>> 13;\n d2 &= 0x1fff;\n d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3);\n c += d2 >>> 13;\n d2 &= 0x1fff;\n\n let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);\n c = d3 >>> 13;\n d3 &= 0x1fff;\n d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4);\n c += d3 >>> 13;\n d3 &= 0x1fff;\n\n let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;\n c = d4 >>> 13;\n d4 &= 0x1fff;\n d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5);\n c += d4 >>> 13;\n d4 &= 0x1fff;\n\n let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;\n c = d5 >>> 13;\n d5 &= 0x1fff;\n d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6);\n c += d5 >>> 13;\n d5 &= 0x1fff;\n\n let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;\n c = d6 >>> 13;\n d6 &= 0x1fff;\n d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);\n c += d6 >>> 13;\n d6 &= 0x1fff;\n\n let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;\n c = d7 >>> 13;\n d7 &= 0x1fff;\n d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);\n c += d7 >>> 13;\n d7 &= 0x1fff;\n\n let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;\n c = d8 >>> 13;\n d8 &= 0x1fff;\n d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);\n c += d8 >>> 13;\n d8 &= 0x1fff;\n\n let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;\n c = d9 >>> 13;\n d9 &= 0x1fff;\n d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;\n c += d9 >>> 13;\n d9 &= 0x1fff;\n\n c = ((c << 2) + c) | 0;\n c = (c + d0) | 0;\n d0 = c & 0x1fff;\n c = c >>> 13;\n d1 += c;\n\n h[0] = d0;\n h[1] = d1;\n h[2] = d2;\n h[3] = d3;\n h[4] = d4;\n h[5] = d5;\n h[6] = d6;\n h[7] = d7;\n h[8] = d8;\n h[9] = d9;\n }\n\n private finalize() {\n const { h, pad } = this;\n const g = new Uint16Array(10);\n let c = h[1] >>> 13;\n h[1] &= 0x1fff;\n for (let i = 2; i < 10; i++) {\n h[i] += c;\n c = h[i] >>> 13;\n h[i] &= 0x1fff;\n }\n h[0] += c * 5;\n c = h[0] >>> 13;\n h[0] &= 0x1fff;\n h[1] += c;\n c = h[1] >>> 13;\n h[1] &= 0x1fff;\n h[2] += c;\n\n // RFC 8439 §2.5 / RFC 7539 §2.5 reduce modulo 2^130-5 before repacking\n // to 16-bit words and adding the raw s half.\n g[0] = h[0] + 5;\n c = g[0] >>> 13;\n g[0] &= 0x1fff;\n for (let i = 1; i < 10; i++) {\n g[i] = h[i] + c;\n c = g[i] >>> 13;\n g[i] &= 0x1fff;\n }\n g[9] -= 1 << 13;\n\n let mask = (c ^ 1) - 1;\n for (let i = 0; i < 10; i++) g[i] &= mask;\n mask = ~mask;\n for (let i = 0; i < 10; i++) h[i] = (h[i] & mask) | g[i];\n h[0] = (h[0] | (h[1] << 13)) & 0xffff;\n h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;\n h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;\n h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;\n h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;\n h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;\n h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;\n h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;\n\n let f = h[0] + pad[0];\n h[0] = f & 0xffff;\n for (let i = 1; i < 8; i++) {\n f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;\n h[i] = f & 0xffff;\n }\n clean(g);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n data = copyBytes(data);\n const { buffer, blockLen } = this;\n const len = data.length;\n\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input\n if (take === blockLen) {\n for (; blockLen <= len - pos; pos += blockLen) this.process(data, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(buffer, 0, false);\n this.pos = 0;\n }\n }\n return this;\n }\n destroy(): void {\n // `aexists(this)` guards update/digest paths, so destroy must mark the instance unusable too.\n this.destroyed = true;\n clean(this.h, this.r, this.buffer, this.pad);\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const { buffer, h } = this;\n let { pos } = this;\n if (pos) {\n // RFC 8439 §2.5 / RFC 7539 §2.5: the final short block appends a\n // single `0x01` byte and zero-fills the remaining bytes before the\n // last multiplication step.\n buffer[pos++] = 1;\n for (; pos < 16; pos++) buffer[pos] = 0;\n this.process(buffer, 0, true);\n }\n this.finalize();\n let opos = 0;\n for (let i = 0; i < 8; i++) {\n out[opos++] = h[i] >>> 0;\n out[opos++] = h[i] >>> 8;\n }\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy out before destroy() zeroes the internal buffer.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n}\n\n/** One-shot keyed hash helper with `.create()`. */\nexport type CHash = CMac<Poly1305>;\n\n/**\n * Poly1305 MAC from RFC 8439.\n * @param msg - Message bytes to authenticate.\n * @param key - 32-byte Poly1305 one-time key.\n * @returns 16-byte authentication tag.\n * @example\n * Authenticates one message with a one-shot Poly1305 call and a fresh key.\n *\n * ```ts\n * import { poly1305 } from '@noble/ciphers/_poly1305.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * poly1305(new Uint8Array(), key);\n * ```\n */\nexport const poly1305: TRet<CHash> = /* @__PURE__ */ wrapMacConstructor(\n 32,\n (key: TArg<Uint8Array>) => new Poly1305(key)\n);\n","/**\n * ChaCha stream cipher, released\n * in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round.\n * It was standardized in\n * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and\n * is now used in TLS 1.3.\n *\n * {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | XChaCha20}\n * extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with\n * randomly-generated nonces.\n *\n * Check out\n * {@link http://cr.yp.to/chacha/chacha-20080128.pdf | PDF},\n * {@link https://en.wikipedia.org/wiki/Salsa20 | wiki}, and\n * {@link https://cr.yp.to/chacha.html | website}.\n *\n * @module\n */\nimport { type XorPRG, createCipher, createPRG, rotl } from './_arx.ts';\nimport { poly1305 } from './_poly1305.ts';\nimport {\n type ARXCipher,\n type CipherWithOutput,\n type TArg,\n type TRet,\n type XorStream,\n abytes,\n clean,\n equalBytes,\n getOutput,\n swap8IfBE,\n swap32IfBE,\n u64Lengths,\n wrapCipher,\n} from './utils.ts';\n\n/**\n * ChaCha core function. It is implemented twice:\n * 1. Simple loop (chachaCore_small, hchacha_small)\n * 2. Unrolled loop (chachaCore, hchacha) - 4x faster, but larger & harder to read\n * The specific implementation is selected in `createCipher` below.\n */\n\n/** RFC 8439 §2.1 quarter round on words a, b, c, d. */\n// prettier-ignore\nfunction chachaQR(x: TArg<Uint32Array>, a: number, b: number, c: number, d: number) {\n x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 16);\n x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 12);\n x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 8);\n x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 7);\n}\n\n/** Repeated ChaCha double rounds; callers are expected to pass an even round count. */\nfunction chachaRound(x: TArg<Uint32Array>, rounds = 20) {\n for (let r = 0; r < rounds; r += 2) {\n // RFC 8439 §2.3 / §2.3.1 inner_block: four column rounds, then four diagonal rounds.\n chachaQR(x, 0, 4, 8, 12);\n chachaQR(x, 1, 5, 9, 13);\n chachaQR(x, 2, 6, 10, 14);\n chachaQR(x, 3, 7, 11, 15);\n chachaQR(x, 0, 5, 10, 15);\n chachaQR(x, 1, 6, 11, 12);\n chachaQR(x, 2, 7, 8, 13);\n chachaQR(x, 3, 4, 9, 14);\n }\n}\n\n// Shared scratch for the auditability-only helper below; only the test-only\n// __TESTS.chachaCore_small hook reaches it, so production exports stay reentrant.\nconst ctmp = /* @__PURE__ */ new Uint32Array(16);\n\n/** Small version of chacha without loop unrolling. Unused, provided for auditability. */\n// prettier-ignore\nfunction chacha(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, i: TArg<Uint32Array>, out: TArg<Uint32Array>,\n isHChacha: boolean = true, rounds: number = 20\n): void {\n // `i` is either `[counter, nonce0, nonce1, nonce2]` for the ChaCha block\n // function or the full 128-bit nonce prefix for the HChaCha subkey path.\n // Create initial array using common pattern\n const y = Uint32Array.from([\n s[0], s[1], s[2], s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n k[0], k[1], k[2], k[3], // Key Key Key Key\n k[4], k[5], k[6], k[7], // Key Key Key Key\n i[0], i[1], i[2], i[3], // Counter Counter Nonce Nonce\n ]);\n const x = ctmp;\n x.set(y);\n chachaRound(x, rounds);\n\n // HChaCha writes words 0..3 and 12..15 after the rounds; the ChaCha\n // block path adds the original state word-by-word.\n if (isHChacha) {\n const xindexes = [0, 1, 2, 3, 12, 13, 14, 15];\n for (let i = 0; i < 8; i++) out[i] = x[xindexes[i]];\n } else {\n for (let i = 0; i < 16; i++) out[i] = (y[i] + x[i]) | 0;\n }\n}\n\n/** Identical to `chachaCore`. Reached only through the test-only `__TESTS` export. */\n// @ts-ignore\nconst chachaCore_small: typeof chachaCore = (s, k, n, out, cnt, rounds) =>\n // Keep the reference wrapper on the same [counter, nonce0, nonce1, nonce2] layout as chacha().\n chacha(s, k, Uint32Array.from([cnt, n[0], n[1], n[2]]), out, false, rounds);\n/** Identical to `hchacha`. Unused. */\n// @ts-ignore\nconst hchacha_small: typeof hchacha = chacha;\n\n/** RFC 8439 §2.3 block core for `state = constants | key | counter | nonce`. */\n// prettier-ignore\nfunction chachaCore(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, n: TArg<Uint32Array>, out: TArg<Uint32Array>, cnt: number, rounds = 20\n): void {\n let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key\n y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key\n y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Nonce Nonce Nonce\n // Save state to temporary variables\n let x00 = y00, x01 = y01, x02 = y02, x03 = y03,\n x04 = y04, x05 = y05, x06 = y06, x07 = y07,\n x08 = y08, x09 = y09, x10 = y10, x11 = y11,\n x12 = y12, x13 = y13, x14 = y14, x15 = y15;\n for (let r = 0; r < rounds; r += 2) {\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8)\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16)\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7);\n }\n // RFC 8439 §2.3 / §2.3.1: add the original state words back in state order.\n let oi = 0;\n out[oi++] = (y00 + x00) | 0; out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0; out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0; out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0; out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0; out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0; out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0; out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0; out[oi++] = (y15 + x15) | 0;\n}\n/**\n * hchacha hashes key and nonce into key' and nonce' for xchacha20.\n * Algorithmically identical to `hchacha_small`, but this exported path\n * normalizes word order on big-endian hosts.\n * Need to find a way to merge it with `chachaCore` without 25% performance hit.\n * @param s - Sigma constants as 32-bit words.\n * @param k - Key words.\n * @param i - Nonce-prefix words.\n * @param out - Output buffer for the derived subkey.\n * @example\n * Derives the XChaCha subkey from sigma, key, and nonce-prefix words.\n *\n * ```ts\n * const sigma = new Uint32Array(4);\n * const key = new Uint32Array(8);\n * const nonce = new Uint32Array(4);\n * const out = new Uint32Array(8);\n * hchacha(sigma, key, nonce, out);\n * ```\n */\n// prettier-ignore\nexport function hchacha(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, i: TArg<Uint32Array>, out: TArg<Uint32Array>\n): void {\n let x00 = swap8IfBE(s[0]), x01 = swap8IfBE(s[1]), x02 = swap8IfBE(s[2]), x03 = swap8IfBE(s[3]),\n x04 = swap8IfBE(k[0]), x05 = swap8IfBE(k[1]), x06 = swap8IfBE(k[2]), x07 = swap8IfBE(k[3]),\n x08 = swap8IfBE(k[4]), x09 = swap8IfBE(k[5]), x10 = swap8IfBE(k[6]), x11 = swap8IfBE(k[7]),\n x12 = swap8IfBE(i[0]), x13 = swap8IfBE(i[1]), x14 = swap8IfBE(i[2]), x15 = swap8IfBE(i[3]);\n for (let r = 0; r < 20; r += 2) {\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8)\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16)\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7);\n }\n // HChaCha derives the subkey from state words 0..3 and 12..15 after 20 rounds.\n let oi = 0;\n out[oi++] = x00; out[oi++] = x01;\n out[oi++] = x02; out[oi++] = x03;\n out[oi++] = x12; out[oi++] = x13;\n out[oi++] = x14; out[oi++] = x15;\n swap32IfBE(out);\n}\n\n/**\n * Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter.\n * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public\n * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts`\n * near `MAX_COUNTER` for the full counter-policy rationale.\n * @param key - 16-byte or 32-byte key.\n * @param nonce - 8-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with the original 8-byte-nonce ChaCha variant and a fresh key/nonce.\n *\n * ```ts\n * import { chacha20orig } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(8);\n * chacha20orig(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha20orig: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n allowShortKeys: true,\n});\n/**\n * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.\n * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with the RFC 8439 ChaCha20 stream cipher and a fresh key/nonce.\n *\n * ```ts\n * import { chacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha20(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha20: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n allowShortKeys: false,\n});\n\n/**\n * XChaCha eXtended-nonce ChaCha. With 24-byte nonce, it's safe to make it random (CSPRNG).\n * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}.\n * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public\n * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts`\n * near `MAX_COUNTER` for the full counter-policy rationale.\n * @param key - 32-byte key.\n * @param nonce - 24-byte extended nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with XChaCha20 using a fresh key and random 24-byte nonce.\n *\n * ```ts\n * import { xchacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(24);\n * xchacha20(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const xchacha20: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n extendNonceFn: hchacha,\n allowShortKeys: false,\n});\n\n/**\n * Reduced 8-round chacha, described in original paper.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Uses the reduced 8-round variant for non-critical workloads with a fresh key/nonce.\n *\n * ```ts\n * import { chacha8 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha8(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha8: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 8,\n});\n\n/**\n * Reduced 12-round chacha, described in original paper.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Uses the reduced 12-round variant for non-critical workloads with a fresh key/nonce.\n *\n * ```ts\n * import { chacha12 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha12(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha12: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 12,\n});\n\n// Test-only hooks for keeping the simple/reference core aligned with the unrolled production core.\nexport const __TESTS: {\n chachaCore_small: typeof chachaCore_small;\n chachaCore: typeof chachaCore;\n} = /* @__PURE__ */ Object.freeze({ chachaCore_small, chachaCore });\n\n// RFC 8439 §2.8.1 pad16(x): shared zero block for AAD/ciphertext padding.\nconst ZEROS16 = /* @__PURE__ */ new Uint8Array(16);\n// RFC 8439 §2.8 / §2.8.1: aligned inputs add nothing, otherwise append 16-(len%16) zero bytes.\nconst updatePadded = (h: ReturnType<typeof poly1305.create>, msg: TArg<Uint8Array>) => {\n h.update(msg);\n const leftover = msg.length % 16;\n if (leftover) h.update(ZEROS16.subarray(leftover));\n};\n\n// RFC 8439 §2.6.1 poly1305_key_gen returns `block[0..31]`, so AEAD key\n// generation only needs 32 zero bytes.\nconst ZEROS32 = /* @__PURE__ */ new Uint8Array(32);\nfunction computeTag(\n fn: TArg<XorStream>,\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n if (AAD !== undefined) abytes(AAD, undefined, 'AAD');\n // RFC 8439 §2.6 / §2.8: derive the Poly1305 one-time key from counter 0,\n // then MAC AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || len(AAD) || len(ciphertext).\n const authKey = fn(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n ZEROS32 as TRet<Uint8Array>\n );\n const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true);\n\n // Methods below can be replaced with\n // return poly1305_computeTag_small(authKey, lengths, ciphertext, AAD)\n const h = poly1305.create(authKey);\n if (AAD) updatePadded(h, AAD);\n updatePadded(h, ciphertext);\n h.update(lengths);\n const res = h.digest();\n clean(authKey, lengths);\n return res;\n}\n\n/**\n * AEAD algorithm from RFC 8439.\n * Salsa20 and chacha (RFC 8439) use poly1305 differently.\n * We could have composed them, but it's hard because of authKey:\n * In salsa20, authKey changes position in salsa stream.\n * In chacha, authKey can't be computed inside computeTag, it modifies the counter.\n */\nexport const _poly1305_aead =\n (xorStream: TArg<XorStream>) =>\n (key: TArg<Uint8Array>, nonce: TArg<Uint8Array>, AAD?: TArg<Uint8Array>): CipherWithOutput => {\n // This borrows caller key/nonce/AAD buffers by reference; mutating them after construction\n // changes future encrypt/decrypt results.\n const tagLength = 16;\n return {\n encrypt(plaintext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array> {\n const plength = plaintext.length;\n output = getOutput(plength + tagLength, output, false);\n output.set(plaintext);\n const oPlain = output.subarray(0, -tagLength);\n // RFC 8439 §2.8: payload encryption starts at counter 1 because counter 0 produced the OTK.\n xorStream(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n oPlain as TRet<Uint8Array>,\n oPlain as TRet<Uint8Array>,\n 1\n );\n const tag = computeTag(xorStream, key, nonce, oPlain, AAD);\n output.set(tag, plength); // append tag\n clean(tag);\n return output as TRet<Uint8Array>;\n },\n decrypt(ciphertext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array> {\n output = getOutput(ciphertext.length - tagLength, output, false);\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = computeTag(xorStream, key, nonce, data, AAD);\n // RFC 8439 §2.8 / §4: authenticate ciphertext before decrypting it, and compare tags with\n // the constant-time equalBytes() helper rather than decrypting speculative plaintext first.\n if (!equalBytes(passedTag, tag)) {\n clean(tag);\n throw new Error('invalid tag');\n }\n output.set(ciphertext.subarray(0, -tagLength));\n // Actual decryption\n xorStream(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n output as TRet<Uint8Array>,\n output as TRet<Uint8Array>,\n 1\n ); // start stream with i=1\n clean(tag);\n return output as TRet<Uint8Array>;\n },\n };\n };\n\n/**\n * ChaCha20-Poly1305 from RFC 8439.\n *\n * Unsafe to use random nonces under the same key, due to collision chance.\n * Prefer XChaCha instead.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param AAD - Additional authenticated data.\n * @returns AEAD cipher instance.\n * @example\n * Encrypts and authenticates plaintext with a fresh key and nonce.\n *\n * ```ts\n * import { chacha20poly1305 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * const cipher = chacha20poly1305(key, nonce);\n * cipher.encrypt(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport const chacha20poly1305: TRet<ARXCipher> = /* @__PURE__ */ wrapCipher(\n { blockSize: 64, nonceLength: 12, tagLength: 16 },\n /* @__PURE__ */ _poly1305_aead(chacha20)\n);\n/**\n * XChaCha20-Poly1305 extended-nonce chacha.\n *\n * Can be safely used with random nonces (CSPRNG).\n * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}.\n * @param key - 32-byte key.\n * @param nonce - 24-byte nonce.\n * @param AAD - Additional authenticated data.\n * @returns AEAD cipher instance.\n * @example\n * Encrypts and authenticates plaintext with a fresh key and random 24-byte nonce.\n *\n * ```ts\n * import { xchacha20poly1305 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(24);\n * const cipher = xchacha20poly1305(key, nonce);\n * cipher.encrypt(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport const xchacha20poly1305: TRet<ARXCipher> = /* @__PURE__ */ wrapCipher(\n { blockSize: 64, nonceLength: 24, tagLength: 16 },\n /* @__PURE__ */ _poly1305_aead(xchacha20)\n);\n\n/**\n * Chacha20 CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n * Compatible with libtomcrypt. It does not have a specification, so unclear how secure it is.\n * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted,\n * only 32 random bytes are mixed into the 40-byte state.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n * @example\n * Seeds the test-only ChaCha20 DRBG from fresh entropy.\n *\n * ```ts\n * import { rngChacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const prg = rngChacha20(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const rngChacha20: TRet<XorPRG> = /* @__PURE__ */ createPRG(chacha20orig, 64, 32, 8);\n/**\n * Chacha20/8 CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n * Faster than `rngChacha20`.\n * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted,\n * only 32 random bytes are mixed into the 44-byte state.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n * @example\n * Seeds the faster test-only ChaCha8 DRBG from fresh entropy.\n *\n * ```ts\n * import { rngChacha8 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const prg = rngChacha8(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const rngChacha8: TRet<XorPRG> = /* @__PURE__ */ createPRG(chacha8, 64, 32, 12);\n","/**\n * core/field-encryption.ts — client-side field encryption (sdk-changes S6,\n * ARCHITECTURE §8.3).\n *\n * Fields the backend stores but never needs to read (mailbox `memo`, history\n * `memo` + `counterparty_nametag`, payment-request `memo`, and the intent\n * payload — E.3) are encrypted client-side so any of the owner's devices can\n * decrypt but the operator cannot.\n *\n * - **Key**: `HKDF-SHA256(ikm = walletPrivKey bytes, info = \"sphere-fieldenc-v1\")`\n * → 32-byte symmetric key. Deterministic per wallet → multi-device by\n * construction (mirrors token-engine/realization.ts — same @noble/hashes\n * HKDF, no salt).\n * - **Cipher/envelope**: XChaCha20-Poly1305 with a random 24-byte nonce; wire\n * form is EXACTLY `\"enc1.\" + base64(nonce ‖ ciphertext)`.\n * - **One mapping rule everywhere** (ARCHITECTURE §8.3): JSON bodies and\n * responses carry the `enc1.` string verbatim; the server validates only\n * prefix + base64 + size cap, stores the exact UTF-8 bytes, and returns them\n * unchanged. {@link assertFieldEnvelopeShape} is that server-side check.\n */\n\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { xchacha20poly1305 } from '@noble/ciphers/chacha.js';\nimport { randomBytes } from '@noble/ciphers/utils.js';\nimport { SphereError } from './errors';\n\n/** HKDF info label — versioned; the same label appears in sdk-changes S6. */\nexport const FIELD_ENCRYPTION_HKDF_INFO = 'sphere-fieldenc-v1';\n\n/** Envelope wire prefix. The version lives in the prefix (`enc1`). */\nexport const FIELD_ENVELOPE_PREFIX = 'enc1.';\n\n/** XChaCha20-Poly1305 nonce length (24 bytes). */\nexport const FIELD_ENVELOPE_NONCE_BYTES = 24;\n\n/** Poly1305 authentication tag length appended to the ciphertext. */\nconst POLY1305_TAG_BYTES = 16;\n\n/**\n * Default envelope size cap in bytes (UTF-8 length of the full `enc1.…`\n * string). Matches the intent-payload cap (≤ 4 KiB — ARCHITECTURE §7/§11).\n * NOTE: the server-side INTENT cap is being raised (wallet-api#102); the SDK\n * deliberately does NOT pre-flight-enforce it on sends (#670) — the server\n * decides, and a deterministic 422 is handled as terminal by the send path.\n */\nexport const FIELD_ENVELOPE_MAX_BYTES = 4096;\n\n// =============================================================================\n// base64 (RFC 4648, with padding) — hand-rolled so the codec is identical in\n// Node and browsers (no Buffer / btoa dependency) and decode is strict.\n// =============================================================================\n\nconst B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst B64_LOOKUP: Record<string, number> = {};\nfor (let i = 0; i < B64_ALPHABET.length; i++) B64_LOOKUP[B64_ALPHABET[i]] = i;\n\nfunction base64Encode(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i];\n const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;\n const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;\n out += B64_ALPHABET[b0 >> 2];\n out += B64_ALPHABET[((b0 & 0x03) << 4) | (b1 >> 4)];\n out += i + 1 < bytes.length ? B64_ALPHABET[((b1 & 0x0f) << 2) | (b2 >> 6)] : '=';\n out += i + 2 < bytes.length ? B64_ALPHABET[b2 & 0x3f] : '=';\n }\n return out;\n}\n\n/** Strict decode: throws on non-alphabet chars, bad length, or bad padding. */\nfunction base64Decode(s: string): Uint8Array {\n if (s.length % 4 !== 0) {\n throw new SphereError('Invalid field envelope: base64 length not a multiple of 4', 'DECRYPTION_ERROR');\n }\n let padding = 0;\n if (s.endsWith('==')) padding = 2;\n else if (s.endsWith('=')) padding = 1;\n const body = s.slice(0, s.length - padding);\n if (body.includes('=')) {\n throw new SphereError('Invalid field envelope: misplaced base64 padding', 'DECRYPTION_ERROR');\n }\n const out = new Uint8Array((s.length / 4) * 3 - padding);\n let o = 0;\n for (let i = 0; i < body.length; i += 4) {\n const n0 = B64_LOOKUP[body[i]];\n const n1 = B64_LOOKUP[body[i + 1]];\n const n2 = body[i + 2] !== undefined ? B64_LOOKUP[body[i + 2]] : 0;\n const n3 = body[i + 3] !== undefined ? B64_LOOKUP[body[i + 3]] : 0;\n if (n0 === undefined || n1 === undefined || n2 === undefined || n3 === undefined) {\n throw new SphereError('Invalid field envelope: non-base64 character', 'DECRYPTION_ERROR');\n }\n const triple = (n0 << 18) | (n1 << 12) | (n2 << 6) | n3;\n if (o < out.length) out[o++] = (triple >> 16) & 0xff;\n if (o < out.length) out[o++] = (triple >> 8) & 0xff;\n if (o < out.length) out[o++] = triple & 0xff;\n }\n return out;\n}\n\n// =============================================================================\n// Key derivation\n// =============================================================================\n\nfunction hexToBytesStrict(hex: string): Uint8Array {\n if (hex.length === 0 || hex.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(hex)) {\n throw new SphereError('Invalid private key hex for field-encryption key derivation', 'INVALID_CONFIG');\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\n/**\n * Derive the wallet's 32-byte field-encryption key (sdk-changes S6):\n * `HKDF-SHA256(ikm = wallet privkey bytes, info = \"sphere-fieldenc-v1\")`.\n *\n * Deterministic per wallet key — every device holding the seed derives the\n * same key, so envelopes round-trip across devices with no key exchange.\n *\n * @param privKeyHex - wallet secp256k1 private key, hex (the HKDF ikm is its raw bytes)\n */\nexport function deriveFieldEncryptionKey(privKeyHex: string): Uint8Array {\n const ikm = hexToBytesStrict(privKeyHex);\n const info = new TextEncoder().encode(FIELD_ENCRYPTION_HKDF_INFO);\n return hkdf(sha256, ikm, undefined, info, 32);\n}\n\n// =============================================================================\n// Envelope encrypt / decrypt\n// =============================================================================\n\n/**\n * Encrypt BINARY plaintext into the S6 wire envelope, optionally bound to associated data (AAD):\n * `\"enc1.\" + base64(nonce ‖ ciphertext)` (XChaCha20-Poly1305, random 24-byte nonce). The AAD is\n * authenticated but NOT stored in the envelope — the reader re-derives it from context, so a\n * record decrypted against a different AAD fails the poly1305 tag (E.4: AAD = `transferId:opIndex`\n * binds a checkpoint to its slot, defeating a mis-served / cross-intent replay at the crypto layer).\n */\nexport function encryptFieldBytes(key: Uint8Array, plaintext: Uint8Array, aad?: Uint8Array): string {\n const nonce = randomBytes(FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = xchacha20poly1305(key, nonce, aad).encrypt(plaintext);\n const packed = new Uint8Array(nonce.length + ciphertext.length);\n packed.set(nonce, 0);\n packed.set(ciphertext, nonce.length);\n return FIELD_ENVELOPE_PREFIX + base64Encode(packed);\n}\n\n/**\n * Decrypt an S6 wire envelope to BINARY bytes, requiring the same `aad` used at encrypt time.\n * Any tampering, wrong key, OR wrong AAD throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptFieldBytes(key: Uint8Array, envelope: string, aad?: Uint8Array): Uint8Array {\n if (typeof envelope !== 'string' || !envelope.startsWith(FIELD_ENVELOPE_PREFIX)) {\n throw new SphereError('Invalid field envelope: missing \"enc1.\" prefix', 'DECRYPTION_ERROR');\n }\n const packed = base64Decode(envelope.slice(FIELD_ENVELOPE_PREFIX.length));\n if (packed.length < FIELD_ENVELOPE_NONCE_BYTES + POLY1305_TAG_BYTES) {\n throw new SphereError('Invalid field envelope: too short for nonce + tag', 'DECRYPTION_ERROR');\n }\n const nonce = packed.slice(0, FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = packed.slice(FIELD_ENVELOPE_NONCE_BYTES);\n try {\n return xchacha20poly1305(key, nonce, aad).decrypt(ciphertext);\n } catch (err) {\n throw new SphereError('Field envelope authentication failed (tampered, wrong key, or wrong AAD)', 'DECRYPTION_ERROR', err);\n }\n}\n\n/**\n * Encrypt a UTF-8 string field into the S6 wire envelope (AAD-less). Thin wrapper over\n * {@link encryptFieldBytes} — the memo/nametag/intent-payload path.\n */\nexport function encryptField(key: Uint8Array, plaintext: string): string {\n return encryptFieldBytes(key, new TextEncoder().encode(plaintext));\n}\n\n/**\n * Decrypt an AAD-less S6 wire envelope to a UTF-8 string (memo/nametag/intent payload). Any\n * tampering throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptField(key: Uint8Array, envelope: string): string {\n return new TextDecoder().decode(decryptFieldBytes(key, envelope));\n}\n\n/**\n * The server-side shape check (ARCHITECTURE §8.3): the value must be a string,\n * carry the `enc1.` prefix, decode as base64, be long enough to hold a nonce +\n * tag, and fit the size cap. The server never sees plaintext — this is the\n * ONLY validation it performs before storing the exact UTF-8 bytes verbatim.\n *\n * Throws `SphereError('VALIDATION_ERROR')` on any violation.\n */\nexport function assertFieldEnvelopeShape(value: unknown, maxBytes: number = FIELD_ENVELOPE_MAX_BYTES): void {\n if (typeof value !== 'string') {\n throw new SphereError('Field envelope must be a string', 'VALIDATION_ERROR');\n }\n if (!value.startsWith(FIELD_ENVELOPE_PREFIX)) {\n throw new SphereError('Field envelope must start with \"enc1.\"', 'VALIDATION_ERROR');\n }\n if (new TextEncoder().encode(value).length > maxBytes) {\n throw new SphereError(`Field envelope exceeds size cap of ${maxBytes} bytes`, 'VALIDATION_ERROR');\n }\n let packed: Uint8Array;\n try {\n packed = base64Decode(value.slice(FIELD_ENVELOPE_PREFIX.length));\n } catch (err) {\n throw new SphereError('Field envelope payload is not valid base64', 'VALIDATION_ERROR', err);\n }\n if (packed.length < FIELD_ENVELOPE_NONCE_BYTES + POLY1305_TAG_BYTES) {\n throw new SphereError('Field envelope payload too short for nonce + tag', 'VALIDATION_ERROR');\n }\n}\n","/**\n * core/delivery-envelope.ts — recipient-addressed delivery envelopes\n * (sdk-changes S6; ARCHITECTURE §8.3).\n *\n * The mailbox `memo` is the one S6 field that is NOT self-scoped: it is written\n * by the SENDER but must be readable by the RECIPIENT (a different wallet). The\n * wallet-scoped field key ({@link deriveFieldEncryptionKey}) is wrong for it —\n * a memo encrypted with the sender's key can never be opened by the recipient.\n *\n * So delivery envelopes key off an **ECDH-to-recipient** shared secret instead:\n *\n * key = HKDF-SHA256(ikm = secp256k1.getSharedSecret(senderPriv, recipientPub),\n * info = \"sphere-deliveryenc-v1\") [0..32)\n *\n * ECDH is symmetric, so the recipient re-derives the identical key from\n * `(recipientPriv, senderPub)` — `entry.senderPubkey` on the wire. A self-send\n * (sender == recipient) is just `ECDH(priv, ownPub)` on both sides and still\n * round-trips.\n *\n * Crucially, the **wire bytes stay the SAME `enc1.` envelope** the self-scoped\n * field encryption uses (XChaCha20-Poly1305, random 24-byte nonce — reused\n * verbatim from {@link encryptField}/{@link decryptField}). The backend cannot\n * tell a delivery envelope from a self-scoped one and stores both opaquely:\n * operator-blind, and NO backend change (the wire prefix and size cap are\n * unchanged).\n *\n * The plaintext is a compact JSON bundle — `{ n?: senderNametag, t?: memo }`\n * (absent fields omitted) — mirroring the Nostr `{ senderNametag, text }`\n * structure so both rails carry the same two facts.\n */\n\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { secp256k1 } from '@noble/curves/secp256k1.js';\nimport { encryptField, decryptField } from './field-encryption';\nimport { SphereError } from './errors';\n\n/** HKDF info label for the ECDH-derived delivery key — versioned, distinct from S6's. */\nexport const DELIVERY_ENCRYPTION_HKDF_INFO = 'sphere-deliveryenc-v1';\n\n/** The decrypted delivery bundle (sender nametag + memo; either may be absent). */\nexport interface DeliveryBundle {\n /** The sender's own nametag (without a leading `@`). */\n senderNametag?: string;\n /** The human memo attached to the transfer. */\n memo?: string;\n}\n\nfunction hexToBytesStrict(hex: string, what: string): Uint8Array {\n if (hex.length === 0 || hex.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(hex)) {\n throw new SphereError(`Invalid ${what} hex for delivery-envelope key derivation`, 'INVALID_CONFIG');\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n return out;\n}\n\n/**\n * Derive the 32-byte symmetric key for a delivery envelope between `privKeyHex`\n * and `peerPubkeyHex` (a 33-byte compressed secp256k1 pubkey, hex):\n *\n * HKDF-SHA256(ikm = secp256k1.getSharedSecret(priv, peerPub), info = \"sphere-deliveryenc-v1\")\n *\n * Symmetric in (priv, peerPub) by ECDH, so sender and recipient derive the same\n * key; reused for a self-send (peerPub == own pubkey).\n */\nexport function deriveDeliveryEncryptionKey(privKeyHex: string, peerPubkeyHex: string): Uint8Array {\n const priv = hexToBytesStrict(privKeyHex, 'private key');\n const peerPub = hexToBytesStrict(peerPubkeyHex, 'peer public key');\n // getSharedSecret returns the 33-byte compressed shared point (incl. its\n // 02/03 prefix). HKDF the whole thing — the prefix is deterministic for a\n // fixed pair and folds into the derived key identically on both sides.\n const shared = secp256k1.getSharedSecret(priv, peerPub);\n const info = new TextEncoder().encode(DELIVERY_ENCRYPTION_HKDF_INFO);\n return hkdf(sha256, shared, undefined, info, 32);\n}\n\n/**\n * Encrypt a delivery bundle into the S6 `enc1.` wire envelope under the\n * ECDH-derived key. Returns `undefined` when there is nothing to carry (no\n * nametag and no memo) — callers then omit the field entirely.\n */\nexport function encryptDeliveryBundle(key: Uint8Array, bundle: DeliveryBundle): string | undefined {\n const compact: { n?: string; t?: string } = {};\n if (bundle.senderNametag !== undefined && bundle.senderNametag !== '') compact.n = bundle.senderNametag;\n if (bundle.memo !== undefined && bundle.memo !== '') compact.t = bundle.memo;\n if (compact.n === undefined && compact.t === undefined) return undefined;\n return encryptField(key, JSON.stringify(compact));\n}\n\n/**\n * Decrypt + parse a delivery envelope under the ECDH-derived key. Throws a\n * `SphereError('DECRYPTION_ERROR')` on a wrong key, tamper, or non-JSON\n * plaintext — the receive loop treats that as \"not for me / unreadable\" and\n * drops it, never as a fatal error.\n */\nexport function decryptDeliveryBundle(key: Uint8Array, envelope: string): DeliveryBundle {\n const plaintext = decryptField(key, envelope);\n let parsed: unknown;\n try {\n parsed = JSON.parse(plaintext);\n } catch (err) {\n throw new SphereError('Delivery envelope payload is not valid JSON', 'DECRYPTION_ERROR', err);\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new SphereError('Delivery envelope payload is not an object', 'DECRYPTION_ERROR');\n }\n const obj = parsed as { n?: unknown; t?: unknown };\n const bundle: DeliveryBundle = {};\n if (typeof obj.n === 'string') bundle.senderNametag = obj.n;\n if (typeof obj.t === 'string') bundle.memo = obj.t;\n return bundle;\n}\n","// P3b: WalletApiDeliveryPort — DeliveryPort over the §16 mailbox (§5.6/§5.7).\n// deliveryId is ALWAYS content-derived hex(SHA-256(tokenId ‖ stateHash)) — never\n// a server row id or seq. The seen-set is S7 port-owned; an entry enters it\n// ONLY after its ack succeeded.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { SerialChain } from '../../modules/payments-v2/async';\nimport type {\n AckOutcome,\n AckRequest,\n DeliverOptions,\n DeliveryPort,\n DeliveryReceipt,\n IncomingDelivery,\n} from '../../modules/payments-v2/ports';\nimport type { ScopedKV } from '../../modules/payments-v2/stores';\nimport { bytesToHex, hexToBytes } from '../../core/crypto';\nimport { logger } from '../../core/logger';\nimport {\n decryptDeliveryBundle,\n deriveDeliveryEncryptionKey,\n encryptDeliveryBundle,\n type DeliveryBundle,\n} from '../../core/delivery-envelope';\nimport { isRetryableStatus, isWalletApiHttpError } from './http';\nimport type {\n MailboxDepositEntry,\n MailboxEntryWire,\n MailboxRejectReason,\n WalletApiV2Client,\n} from './client';\nimport { uploadViaPresigned } from './storage';\n\nexport type DeliveryPortClient = Pick<\n WalletApiV2Client,\n 'uploadUrls' | 'uploadBlob' | 'fetchBlob' | 'deposit' | 'depositBatch' | 'listMailbox' | 'claim' | 'reject'\n>;\n\nexport type DeliveryCustody = 'inventory' | 'external';\n\nexport interface WakeSource {\n subscribeStream(stream: 'inventory' | 'mailbox' | 'payment_requests', handler: () => void): () => void;\n}\n\nexport class DeliveryKeysUnboundError extends Error {\n readonly code = 'DELIVERY_KEYS_UNBOUND';\n constructor() {\n super('deliveryKeys derivation not bound — bindDeliveryKeys(engine.deliveryKeys) must run first (S7)');\n this.name = 'DeliveryKeysUnboundError';\n }\n}\n\nexport class MailboxClaimFailedError extends Error {\n readonly code = 'MAILBOX_CLAIM_FAILED';\n constructor(deliveryId: string, readonly failureCode: string) {\n super(`mailbox claim failed for ${deliveryId}: ${failureCode}`);\n this.name = 'MailboxClaimFailedError';\n }\n}\n\nexport class DeliveryProtocolError extends Error {\n readonly code = 'PROTOCOL';\n constructor(message: string) {\n super(message);\n this.name = 'DeliveryProtocolError';\n }\n}\n\nexport function computeDeliveryId(tokenIdHex: string, stateHashHex: string): string {\n const tokenId = hexToBytes(tokenIdHex);\n const stateHash = hexToBytes(stateHashHex);\n const joined = new Uint8Array(tokenId.length + stateHash.length);\n joined.set(tokenId, 0);\n joined.set(stateHash, tokenId.length);\n return bytesToHex(sha256(joined));\n}\n\nexport const DELIVERY_SEEN_KEY = 'delivery:seen';\n\nexport interface DeliveryIdentity {\n privateKey: string;\n chainPubkey: string;\n}\n\nexport interface WalletApiDeliveryPortConfig {\n client: DeliveryPortClient;\n kv: ScopedKV;\n identity: DeliveryIdentity;\n /** Composition-time custody (S7) — NEVER a per-call flag. */\n custody: DeliveryCustody;\n wake?: WakeSource;\n deliveryKeys?: (blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>;\n}\n\ninterface PreparedDelivery {\n readonly bytes: Uint8Array;\n readonly tokenId: string;\n readonly stateHash: string;\n readonly deliveryId: string;\n readonly sha: string;\n}\n\n/**\n * Entries per claim/reject call. The server caps at 1000, but each entry costs\n * its own S3 read and transaction there, so a huge batch is a multi-second\n * request against an idle timeout with nothing learned about what committed.\n * 50 keeps almost all of the round-trip amortisation.\n */\nconst ACK_CHUNK = 50;\n\nfunction chunked<T>(items: readonly T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n/** Retryable = a per-entry retry hits the same wall, so the caller must NOT fall back. */\nclass RetryableAckFailure extends Error {\n readonly retryable = true;\n constructor(cause: unknown) {\n super(`mailbox ack batch could not be attempted: ${String(cause)}`);\n this.name = 'RetryableAckFailure';\n this.cause = cause;\n }\n}\n\nfunction asRetryable(err: unknown): unknown {\n return isRetryableStatus(err) ? new RetryableAckFailure(err) : err;\n}\n\nexport class WalletApiDeliveryPort implements DeliveryPort {\n readonly custody: DeliveryCustody;\n\n private readonly client: DeliveryPortClient;\n private readonly kv: ScopedKV;\n private readonly identity: DeliveryIdentity;\n private readonly wake: WakeSource | null;\n private deriveFn: ((blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>) | null;\n private readonly seenChain = new SerialChain();\n private lastIncomingEpoch: string | null = null;\n\n constructor(config: WalletApiDeliveryPortConfig) {\n this.client = config.client;\n this.kv = config.kv;\n this.identity = config.identity;\n this.custody = config.custody;\n this.wake = config.wake ?? null;\n this.deriveFn = config.deliveryKeys ?? null;\n }\n\n bindDeliveryKeys(derive: (blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>): void {\n this.deriveFn = derive;\n }\n\n private deriveKeys(blob: Uint8Array): Promise<{ tokenId: string; stateHash: string }> {\n if (this.deriveFn === null) throw new DeliveryKeysUnboundError();\n return this.deriveFn(blob);\n }\n\n // ── deliver ────────────────────────────────────────────────────────────────\n\n async deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt> {\n const receipts = await this.deliverBatch(recipientPubkey, [blob], options);\n const first = receipts[0];\n if (first === undefined) throw new DeliveryProtocolError('deliver produced no receipt');\n return first;\n }\n\n async deliverBatch(\n recipientPubkey: string,\n blobs: Uint8Array[],\n options: DeliverOptions\n ): Promise<DeliveryReceipt[]> {\n if (blobs.length === 0) return [];\n const prepared = await Promise.all(blobs.map(async (bytes) => this.prepare(bytes)));\n const envelope = this.buildEnvelope(recipientPubkey, options);\n const keyBySha = await uploadViaPresigned(\n this.client,\n prepared.map((p) => ({ sha256: p.sha, bytes: p.bytes }))\n );\n const entries = prepared.map((p): MailboxDepositEntry => {\n const key = keyBySha.get(p.sha);\n if (key === undefined) throw new DeliveryProtocolError(`upload returned no key for sha256 ${p.sha}`);\n return {\n recipientPubkey,\n key,\n transferId: options.transferId,\n tokenId: p.tokenId,\n stateHash: p.stateHash,\n ...(envelope !== undefined ? { memo: envelope } : {}),\n };\n });\n return this.depositAll(entries, prepared.map((p) => p.deliveryId));\n }\n\n private async prepare(bytes: Uint8Array): Promise<PreparedDelivery> {\n const keys = await this.deriveKeys(bytes);\n return {\n bytes,\n tokenId: keys.tokenId,\n stateHash: keys.stateHash,\n deliveryId: computeDeliveryId(keys.tokenId, keys.stateHash),\n sha: bytesToHex(sha256(bytes)),\n };\n }\n\n // sphere#487: the nametag is a per-call option and NOT port config — a\n // construction-time copy would silently go stale on registration, and only a\n // caller-supplied value is enforceable by the port contract suite (which any\n // swapped DeliveryPort must pass).\n private buildEnvelope(recipientPubkey: string, options: DeliverOptions): string | undefined {\n const key = deriveDeliveryEncryptionKey(this.identity.privateKey, recipientPubkey);\n return encryptDeliveryBundle(key, {\n senderNametag: options.senderNametag,\n memo: options.memo,\n });\n }\n\n private async depositAll(entries: MailboxDepositEntry[], deliveryIds: string[]): Promise<DeliveryReceipt[]> {\n if (entries.length > 1) {\n try {\n const results = await this.client.depositBatch(entries);\n if (results.length !== entries.length) {\n throw new DeliveryProtocolError(\n `mailbox batch deposit returned ${String(results.length)} entries for ${String(entries.length)}`\n );\n }\n return deliveryIds.map((deliveryId) => ({ deliveryId }));\n } catch (err) {\n if (!isWalletApiHttpError(err, 409)) throw err;\n }\n }\n const receipts: DeliveryReceipt[] = [];\n for (const [i, entry] of entries.entries()) {\n receipts.push(await this.depositOne(entry, deliveryIds[i] as string));\n }\n return receipts;\n }\n\n private async depositOne(entry: MailboxDepositEntry, deliveryId: string): Promise<DeliveryReceipt> {\n try {\n await this.client.deposit(entry);\n } catch (err) {\n if (!isWalletApiHttpError(err, 409)) throw err;\n }\n return { deliveryId };\n }\n\n // ── incoming ───────────────────────────────────────────────────────────────\n\n async *incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery> {\n const seen = await this.readSeen();\n let page = await this.client.listMailbox(sinceCursor === undefined ? 0 : Number(sinceCursor));\n for (;;) {\n this.lastIncomingEpoch = String(page.syncEpoch);\n for (const entry of page.entries) {\n if (entry.status !== 'unclaimed') continue;\n if (seen.has(entry.entryId)) continue;\n yield this.toIncoming(entry);\n }\n if (!page.more) return;\n page = await this.client.listMailbox(page.cursor);\n }\n }\n\n /** §5.7: the page-honest epoch — the restore-detection source Receive keys on. */\n incomingEpoch(): string | null {\n return this.lastIncomingEpoch;\n }\n\n private toIncoming(entry: MailboxEntryWire): IncomingDelivery {\n const bundle = this.openEnvelope(entry);\n return {\n deliveryId: entry.entryId,\n ...(entry.transferId !== '' ? { transferId: entry.transferId } : {}),\n ...(entry.senderPubkey !== '' ? { senderPubkey: entry.senderPubkey } : {}),\n ...(bundle.senderNametag !== undefined ? { senderNametag: bundle.senderNametag } : {}),\n ...(bundle.memo !== undefined ? { memo: bundle.memo } : {}),\n cursor: String(entry.seq),\n fetchBlob: () => this.fetchVerified(entry),\n };\n }\n\n private openEnvelope(entry: MailboxEntryWire): DeliveryBundle {\n if (entry.memo === undefined || entry.senderPubkey === '') return {};\n try {\n const key = deriveDeliveryEncryptionKey(this.identity.privateKey, entry.senderPubkey);\n return decryptDeliveryBundle(key, entry.memo);\n } catch {\n return {};\n }\n }\n\n private async fetchVerified(entry: MailboxEntryWire): Promise<Uint8Array> {\n if (entry.blobCollected === true || entry.getUrl === undefined) {\n throw new DeliveryProtocolError(`mailbox entry ${entry.entryId} has no fetchable blob (blobCollected)`);\n }\n const bytes = await this.client.fetchBlob(entry.getUrl);\n const keys = await this.deriveKeys(bytes);\n const derived = computeDeliveryId(keys.tokenId, keys.stateHash);\n if (derived !== entry.entryId) {\n throw new DeliveryProtocolError(\n `mailbox blob does not match its entry id (expected ${entry.entryId}, bytes derive ${derived})`\n );\n }\n return bytes;\n }\n\n // ── ack ────────────────────────────────────────────────────────────────────\n\n async ack(\n deliveryId: string,\n disposition: 'claimed' | 'rejected',\n reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'\n ): Promise<void> {\n if (disposition === 'claimed') {\n const result = await this.client.claim([deliveryId], this.custody === 'inventory');\n const failed = result.failed.find((f) => f.entryId === deliveryId);\n if (failed !== undefined) throw new MailboxClaimFailedError(deliveryId, failed.code);\n } else {\n await this.client.reject([deliveryId], reason);\n }\n await this.addSeenAll([deliveryId]);\n }\n\n /**\n * §5.7/#757 batched settle. Claims go out grouped, rejects grouped by reason\n * (the endpoint takes one reason per call), and the seen-set is written ONCE\n * after every HTTP call has succeeded — never on a throw, so an aborted batch\n * re-lists rather than being silently forgotten.\n */\n async ackBatch(acks: readonly AckRequest[]): Promise<readonly AckOutcome[]> {\n const settled: string[] = [];\n const outcomes: AckOutcome[] = [];\n try {\n await this.settleClaims(acks, settled, outcomes);\n await this.settleRejects(acks, settled);\n } catch (err) {\n // Chunks that DID commit are acked server-side, so the seen-set must record\n // them or a §5.4 restore re-yields deliveries this wallet already claimed.\n // A failed write is logged, not swallowed: the loss is bounded (a re-yield\n // screens against the view's durable held state and returns a claim ack, so\n // it costs a redundant ack, not a duplicate credit) but silence is not.\n await this.addSeenAll(settled).catch((seenErr: unknown) => {\n logger.warn('WalletApiDelivery', `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);\n });\n throw asRetryable(err);\n }\n await this.addSeenAll(settled);\n return [...outcomes, ...settled.map((deliveryId): AckOutcome => ({ deliveryId, status: 'settled' }))];\n }\n\n private async settleClaims(\n acks: readonly AckRequest[],\n settled: string[],\n outcomes: AckOutcome[]\n ): Promise<void> {\n const ids = acks.filter((a) => a.disposition === 'claimed').map((a) => a.deliveryId);\n for (const chunk of chunked(ids, ACK_CHUNK)) {\n const result = await this.client.claim(chunk, this.custody === 'inventory');\n settled.push(...result.claimed);\n // Idempotent re-delivery is SETTLED; treating it as unsettled stalls the\n // caller's cursor behind an entry that can never change (§6).\n settled.push(...result.alreadyClaimed.map((e) => e.entryId));\n for (const f of result.failed) {\n if (f.code === 'CONFLICT') outcomes.push({ deliveryId: f.entryId, status: 'conflict' });\n else throw new MailboxClaimFailedError(f.entryId, f.code);\n }\n }\n }\n\n private async settleRejects(acks: readonly AckRequest[], settled: string[]): Promise<void> {\n const byReason = new Map<string, string[]>();\n for (const a of acks) {\n if (a.disposition !== 'rejected') continue;\n const key = a.reason ?? '';\n const group = byReason.get(key) ?? [];\n group.push(a.deliveryId);\n byReason.set(key, group);\n }\n for (const [reason, group] of byReason) {\n for (const chunk of chunked(group, ACK_CHUNK)) {\n await this.client.reject(chunk, reason === '' ? undefined : (reason as MailboxRejectReason));\n // A 200 settles the whole requested group: reject runs in ONE server\n // transaction, and an id it skips was already claimed — terminal too.\n settled.push(...chunk);\n }\n }\n }\n\n onWake(cb: () => void): () => void {\n if (this.wake === null) return () => undefined;\n return this.wake.subscribeStream('mailbox', cb);\n }\n\n // ── seen-set (S7) ──────────────────────────────────────────────────────────\n\n private async readSeen(): Promise<Set<string>> {\n const raw = await this.kv.get<string[]>(DELIVERY_SEEN_KEY);\n return new Set(raw ?? []);\n }\n\n /** SerialChain settles-not-fulfills: a rejected write never bricks later acks. */\n private addSeenAll(deliveryIds: readonly string[]): Promise<void> {\n if (deliveryIds.length === 0) return Promise.resolve();\n return this.seenChain.enqueue(async () => {\n const seen = await this.readSeen();\n for (const id of deliveryIds) seen.add(id);\n await this.kv.set(DELIVERY_SEEN_KEY, [...seen]);\n });\n }\n}\n","/**\n * token-engine/sdk.ts — the SINGLE place that imports @unicitylabs/state-transition-sdk.\n *\n * The v1 cut-over is done: the canonical package name now resolves to the v2 SDK\n * (the migration-era `state-transition-sdk-v2` npm alias is gone, and v1 with it).\n *\n * Everything else in token-engine/ imports SDK symbols from `./sdk`, never from the package directly.\n * ESLint `no-restricted-imports` forbids importing the SDK anywhere except this file.\n *\n * Import path note: subpaths are `…/lib/<path>.js` (no `/src/`); no root barrel.\n */\n\n// ── client / aggregator / proof / network / trust base ──────────────────────\nexport { StateTransitionClient } from '@unicitylabs/state-transition-sdk/lib/StateTransitionClient.js';\nexport { AggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/AggregatorClient.js';\nexport type { IAggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/IAggregatorClient.js';\nexport { NetworkId } from '@unicitylabs/state-transition-sdk/lib/api/NetworkId.js';\nexport { CertificationData } from '@unicitylabs/state-transition-sdk/lib/api/CertificationData.js';\nexport { CertificationResponse, CertificationStatus } from '@unicitylabs/state-transition-sdk/lib/api/CertificationResponse.js';\nexport { StateId } from '@unicitylabs/state-transition-sdk/lib/api/StateId.js';\nexport { InclusionProof } from '@unicitylabs/state-transition-sdk/lib/api/InclusionProof.js';\nexport { InclusionProofResponse } from '@unicitylabs/state-transition-sdk/lib/api/InclusionProofResponse.js';\n// #739: the 'not yet certified' answer the proof loop tolerates; tests model the\n// pre-finalization window with it, which is how the deadline path is reachable.\nexport { JsonRpcNetworkError } from '@unicitylabs/state-transition-sdk/lib/api/json-rpc/JsonRpcNetworkError.js';\nexport { RootTrustBase } from '@unicitylabs/state-transition-sdk/lib/api/bft/RootTrustBase.js';\nexport { waitInclusionProof } from '@unicitylabs/state-transition-sdk/lib/util/InclusionProofUtils.js';\nexport { InclusionProofVerificationStatus } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/rule/InclusionProofVerificationRule.js';\n\n// ── token / transactions ────────────────────────────────────────────────────\nexport { Token } from '@unicitylabs/state-transition-sdk/lib/transaction/Token.js';\nexport { MintTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/MintTransaction.js';\nexport { TransferTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction.js';\nexport { CertifiedMintTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/CertifiedMintTransaction.js';\nexport { CertifiedTransferTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/CertifiedTransferTransaction.js';\nexport { TokenId } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenId.js';\nexport { TokenType } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenType.js';\nexport { TokenSalt } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenSalt.js';\nexport type { ITransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/ITransaction.js';\nexport { StateMask } from '@unicitylabs/state-transition-sdk/lib/transaction/StateMask.js';\nexport { MintJustificationVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js';\nexport { TokenIssuanceVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/TokenIssuanceVerifierService.js';\nexport { VerificationContext } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/VerificationContext.js';\nexport { UnicityCertificateVerifier } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/UnicityCertificateVerifier.js';\nexport { UnicitySealQuorumSignaturesVerificationRule } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/rule/UnicitySealQuorumSignaturesVerificationRule.js';\nexport { VerifiedSealCache } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/VerifiedSealCache.js';\nexport { Secp256k1SignatureVerifier } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Secp256k1SignatureVerifier.js';\nexport type { ITokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/ITokenVerifier.js';\nexport { WorkerTokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/WorkerTokenVerifier.js';\nexport type { IWorker } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/IWorker.js';\nexport type { IVerificationContext } from '@unicitylabs/state-transition-sdk/lib/verification/IVerificationContext.js';\n\n// ── predicates / unlock scripts ─────────────────────────────────────────────\nexport type { IPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/IPredicate.js';\nexport type { IUnlockScript } from '@unicitylabs/state-transition-sdk/lib/predicate/IUnlockScript.js';\nexport { EncodedPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/EncodedPredicate.js';\nexport { SignaturePredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicate.js';\nexport { SignaturePredicateUnlockScript } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicateUnlockScript.js';\nexport { BurnPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/BurnPredicate.js';\nexport { PredicateVerifierService } from '@unicitylabs/state-transition-sdk/lib/predicate/verification/PredicateVerifierService.js';\n\n// ── crypto / hashing ────────────────────────────────────────────────────────\nexport { SigningService } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/SigningService.js';\nexport { Signature } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Signature.js';\nexport { MintSigningService } from '@unicitylabs/state-transition-sdk/lib/crypto/MintSigningService.js';\nexport { HashAlgorithm } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/HashAlgorithm.js';\nexport { DataHash } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHash.js';\nexport { DataHasher } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasher.js';\nexport { DataHasherFactory } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasherFactory.js';\n\n// ── CBOR serialization ──────────────────────────────────────────────────────\nexport { CborSerializer } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborSerializer.js';\nexport { CborDeserializer } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborDeserializer.js';\nexport { CborError } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborError.js';\n// Head-only CBOR reads, for classifying a value envelope WITHOUT parsing its body\n// (`value-envelope.ts`): `CborDeserializer.decodeTag` asserts exhaustion, so it\n// cannot tell a corrupt envelope from a payload that carries no envelope at all.\nexport { CborReader } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborReader.js';\nexport { MajorType } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/MajorType.js';\n\n// ── payment / value / split ─────────────────────────────────────────────────\nexport type { IPaymentData } from '@unicitylabs/state-transition-sdk/lib/payment/IPaymentData.js';\nexport { Asset } from '@unicitylabs/state-transition-sdk/lib/payment/asset/Asset.js';\nexport { AssetId } from '@unicitylabs/state-transition-sdk/lib/payment/asset/AssetId.js';\nexport { PaymentAssetCollection } from '@unicitylabs/state-transition-sdk/lib/payment/asset/PaymentAssetCollection.js';\nexport { TokenSplit } from '@unicitylabs/state-transition-sdk/lib/payment/TokenSplit.js';\nexport { SplitTokenRequest } from '@unicitylabs/state-transition-sdk/lib/payment/SplitTokenRequest.js';\nexport { SplitToken } from '@unicitylabs/state-transition-sdk/lib/payment/SplitToken.js';\nexport { SplitAllocationProof } from '@unicitylabs/state-transition-sdk/lib/payment/SplitAllocationProof.js';\nexport { SplitMintJustification } from '@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustification.js';\nexport { SplitMintJustificationVerifier } from '@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustificationVerifier.js';\n\n// ── verification result types ───────────────────────────────────────────────\nexport { VerificationStatus } from '@unicitylabs/state-transition-sdk/lib/verification/VerificationStatus.js';\nexport { VerificationResult } from '@unicitylabs/state-transition-sdk/lib/verification/VerificationResult.js';\n\n// ── util ────────────────────────────────────────────────────────────────────\nexport { HexConverter } from '@unicitylabs/state-transition-sdk/lib/util/HexConverter.js';\nexport { BigintConverter } from '@unicitylabs/state-transition-sdk/lib/util/BigintConverter.js';\nexport { BitString } from '@unicitylabs/state-transition-sdk/lib/util/BitString.js';\n","/**\n * token-engine/identity.ts — legacy `DIRECT://` identity address (Path A, A6).\n *\n * Reproduces the wallet's stable L3 identity address EXACTLY as the v1\n * `UnmaskedPredicateReference` → `DirectAddress` path did, but VENDORED (no v1 SDK\n * import) so the v1 dependency can be removed at the final cut-over. Quest XP is\n * keyed on this address, so it MUST stay byte-identical — the multi-vector\n * golden test (identity.test.ts) locks it.\n *\n * The recipe (recovered from v1 `UnmaskedPredicateReference.create` + `DirectAddress.create`):\n * ref = SHA-256( CBOR[ bstr([UNMASKED]), bstr(tokenType.toCBOR()),\n * tstr(\"secp256k1\"), uint(SHA256), bstr(publicKey) ] )\n * imprint = 0x0000 ‖ ref (SHA-256 DataHash imprint)\n * address = \"DIRECT://\" ‖ hex(imprint) ‖ hex( SHA-256(imprint)[0:4] )\n *\n * The CBOR + SHA-256 are standard, so v2's CborSerializer/DataHasher produce\n * byte-identical output; the v1 enum values (UNMASKED=0, HashAlgorithm.SHA256=0)\n * and the SHA-256 imprint prefix (0x0000) are pinned as constants.\n */\n\nimport { CborSerializer, DataHasher, HashAlgorithm, HexConverter } from './sdk';\n\n/**\n * Unicity L3 token type used for identity-address derivation (immutable).\n * Also pinned as the fixed token type of self-issued Unicity ID tokens\n * (token-engine/unicity-id.ts) — the same constant the v1 nametag mint used,\n * keeping the mint deterministic per (name, wallet key).\n */\nexport const UNICITY_TOKEN_TYPE_HEX = 'f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509';\n/** v1 `SigningService.algorithm` for secp256k1. */\nconst SIGNING_ALGORITHM = 'secp256k1';\n/** v1 `EmbeddedPredicateType.UNMASKED`. */\nconst EMBEDDED_PREDICATE_UNMASKED = 0;\n/** v1 `HashAlgorithm.SHA256` (as encoded in the reference CBOR). */\nconst HASH_ALGORITHM_SHA256 = 0n;\n/** v1 SHA-256 `DataHash` imprint algorithm tag (2-byte big-endian). */\nconst SHA256_IMPRINT_PREFIX = new Uint8Array([0x00, 0x00]);\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nfunction sha256(data: Uint8Array): Promise<Uint8Array> {\n return new DataHasher(HashAlgorithm.SHA256)\n .update(data)\n .digest()\n .then((h) => h.data);\n}\n\n/**\n * Derive the legacy `DIRECT://` identity address for a compressed (33-byte)\n * secp256k1 public key. Deterministic; byte-identical to the v1 path (Path A).\n */\nexport async function deriveDirectAddress(publicKey: Uint8Array): Promise<string> {\n const tokenTypeCbor = CborSerializer.encodeByteString(hexToBytes(UNICITY_TOKEN_TYPE_HEX)); // v1 TokenType.toCBOR()\n const reference = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(new Uint8Array([EMBEDDED_PREDICATE_UNMASKED])),\n CborSerializer.encodeByteString(tokenTypeCbor),\n CborSerializer.encodeTextString(SIGNING_ALGORITHM),\n CborSerializer.encodeUnsignedInteger(HASH_ALGORITHM_SHA256),\n CborSerializer.encodeByteString(publicKey),\n );\n\n const refHash = await sha256(reference);\n const imprint = new Uint8Array([...SHA256_IMPRINT_PREFIX, ...refHash]);\n const checksum = (await sha256(imprint)).slice(0, 4);\n\n return `DIRECT://${HexConverter.encode(imprint)}${HexConverter.encode(checksum)}`;\n}\n","/**\n * token-engine/errors.ts — the engine's typed error surface (Part E.2).\n */\n\nimport { SphereError } from '../core/errors';\n\n/**\n * The source state was already consumed by a *different* transaction — the\n * fetched inclusion proof does not match the rebuilt transaction\n * (`TRANSACTION_HASH_MISMATCH`). Typically the owner's other device raced the\n * same source under a different `transferId` (ARCHITECTURE §7).\n *\n * This is a lost race, **not** an interrupted resume: the engine never applies\n * the foreign proof and never retries. The caller's recovery is to abort the\n * intent, drop the lost source from its plan, and re-plan the remainder under\n * a NEW `transferId` (never reusing the old realization) — sdk-changes E.2.\n */\nexport class TransferConflictError extends SphereError {\n /**\n * #625: the source token id (the caller's id, e.g. `v2_<genesis>`) whose state was already spent.\n * Set by PaymentsModule at the engine call site so the self-healing retry can demote it and re-plan.\n */\n conflictedSourceId?: string;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'TRANSFER_CONFLICT', cause);\n this.name = 'TransferConflictError';\n }\n}\n\n/**\n * The op's certification is INDETERMINATE: the submit was accepted (`SUCCESS`)\n * or failed ambiguously (a thrown submit POST that may have been processed\n * server-side), and the inclusion-proof fetch/verify returned NO verdict — a\n * transient network/timeout error, NOT a matching proof and NOT\n * `TRANSACTION_HASH_MISMATCH`. The source's spend MAY already be on-chain under\n * THIS `transferId`.\n *\n * Unlike {@link TransferConflictError} (a foreign tx won — abort + re-plan under\n * a NEW id), the caller MUST keep the intent OPEN: resume re-derives the\n * byte-identical transaction from `(seed, transferId, opIndex)` and recovers the\n * certified proof + recipient blob, or records the spend if a foreign tx won the\n * race — never a second on-chain spend (sdk-changes E.2/E.3, #631).\n */\nexport class ProofUnconfirmedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CERTIFICATION_UNCONFIRMED', cause);\n this.name = 'ProofUnconfirmedError';\n }\n}\n\n/**\n * A split's burn certified but its checkpoint (sdk-changes E.4, sphere-sdk#501) could NOT be\n * durably persisted — the `SplitCheckpointStore.put` rejected (network / 5xx / timeout / quota) —\n * so NO mint leg was submitted. The burn is on-chain (funds in-flight, not lost); the outputs are\n * fully recoverable on resume.\n *\n * Keep-open family (like {@link ProofUnconfirmedError}): the caller MUST keep the intent OPEN and\n * resume under the SAME `transferId` — the next attempt re-derives the byte-identical burn,\n * re-persists the checkpoint (content-idempotent), and mints. NEVER abort.\n */\nexport class CheckpointPersistFailedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_PERSIST_FAILED', cause);\n this.name = 'CheckpointPersistFailedError';\n }\n}\n\n/**\n * A split cannot be rebuilt from its checkpoint, in a way that is NOT a lost race: either a mint\n * leaf is already certified on-chain but no stored bytes reproduce its certified transactionHash\n * (server data loss / withholding, or a pre-E.4 legacy intent), or a stored checkpoint fails its\n * byte-binding checks (the re-derived burn tx ≠ the stored bytes — cross-version derivation drift\n * — or a corrupt stored proof, or a burnt-token re-encode mismatch).\n *\n * Distinct from {@link TransferConflictError}: a split-mint stateId is HKDF-derived from\n * `(seed, transferId)`, so only a seed-holder under THIS `transferId` can have certified it — this\n * is never a foreign spend. Keep-open, alert loudly: the caller MUST NOT abort, NOT complete, and\n * NOT record the source as foreign-spent (sdk-changes E.4).\n */\nexport class SplitCheckpointLostError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'SPLIT_CHECKPOINT_LOST', cause);\n this.name = 'SplitCheckpointLostError';\n }\n}\n\n/**\n * A stored split checkpoint (sdk-changes E.4) is authentic and byte-bound to the re-derived burn\n * transaction, but its inclusion proof no longer verifies against the CURRENT trust base\n * (`INVALID_TRUSTBASE`) — a validator-set / quorum rotation while the intent was open. The bytes\n * are NOT wrong; re-burning would strand the certified split, so the engine never falls through to\n * a re-burn.\n *\n * Keep-open, distinct signal: the operational remedy is to drain open split intents BEFORE a\n * validator rotation (the SDK has no epoch map — single-epoch trust base, ARCHITECTURE §8.2/§19).\n */\nexport class CheckpointTrustbaseMismatchError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_TRUSTBASE_MISMATCH', cause);\n this.name = 'CheckpointTrustbaseMismatchError';\n }\n}\n","/**\n * NFT payload codec (#785, normative spec: docs/NFT-METADATA.md). Recognition is\n * display-only and never throws, so no path that can refuse a token may depend on\n * it. One validator set serves the encoder and the decoder alike.\n */\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { SphereError } from '../core/errors';\n\nimport {\n CborDeserializer,\n CborReader,\n CborSerializer,\n type DataHash,\n DataHasher,\n HashAlgorithm,\n HexConverter,\n MajorType,\n NetworkId,\n Signature,\n SigningService,\n} from './sdk';\n\nexport const NFT_METADATA_TAG = 39052n;\nexport const NFT_MEDIA_TAG = 39053n;\nexport const NFT_LINK_TAG = 39054n;\nexport const NFT_SIGNED_TAG = 39055n;\nexport const NFT_FORMAT_VERSION = 1n;\n/** The media type of an NftLink that points at a metadata document instead of a media file. */\nexport const NFT_DOCUMENT_MEDIA_TYPE = 'application/vnd.unicity.nft+cbor';\n\n/** An inline file. */\nexport interface NftMedia {\n readonly kind: 'media';\n readonly media_type: string;\n readonly bytes: Uint8Array;\n}\n\n/** A hosted file, pinned by the SHA-256 of its bytes (64 hex; decoded lowercase). */\nexport interface NftLink {\n readonly kind: 'link';\n readonly media_type: string;\n readonly uri: string;\n readonly sha256: string;\n}\n\nexport type NftMediaRef = NftMedia | NftLink;\n\nexport interface NftAttribute {\n readonly trait_type: string;\n /** Text, or an integer within ±(2^53 − 1). Decimals and larger numbers are text. */\n readonly value: string | number;\n}\n\n/** ERC-721 field names; an absent optional field is `null`, never `''`. */\nexport interface NftMetadata {\n readonly kind: 'metadata';\n readonly name: string;\n readonly description: string | null;\n readonly image: NftMediaRef | null;\n readonly animation_url: NftMediaRef | null;\n readonly external_url: string | null;\n readonly attributes: readonly NftAttribute[];\n readonly collection: string | null;\n /** The collection the item claims: 1–64 bytes as even-length hex (decoded lowercase). Never verified here. */\n readonly collection_id: string | null;\n}\n\nexport type NftContent = NftMetadata | NftMedia | NftLink;\nexport type NftSignatureStatus = 'unsigned' | 'valid' | 'invalid';\ntype NftDocument = NftMetadata | NftMedia;\n\nexport interface ParsedNft {\n readonly content: NftContent;\n /** Present iff the top level is NftSigned. */\n readonly signed: {\n readonly creator: Uint8Array;\n readonly payload: Uint8Array;\n readonly signature: Uint8Array;\n } | null;\n}\n\n/** What an NftSigned signature binds besides its payload, exactly as the token's mint records it. */\nexport interface NftSignatureContext {\n /** The network identifier α (`NetworkId.id`). */\n readonly networkId: number | bigint;\n /** The genesis recipient predicate, as `EncodedPredicate.toCBOR()` bytes. */\n readonly recipientPredicate: Uint8Array;\n /** The 32 raw token id bytes. */\n readonly tokenId: Uint8Array;\n readonly tokenType: Uint8Array;\n}\n\nconst METADATA_ARITY = 9;\nconst MEDIA_ARITY = 3;\nconst LINK_ARITY = 4;\nconst SIGNED_ARITY = 4;\nconst CREATOR_BYTES = 33;\nconst SIGNATURE_BYTES = 65;\nconst MAX_URI_LENGTH = 2048;\nconst LINK_SCHEMES = ['https://', 'ipfs://', 'ar://'];\nconst SIGNED_DOMAIN = new TextEncoder().encode('UNICITY_NFT_SIGNED');\nconst MEDIA_TYPE_PATTERN = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/;\nconst SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;\nconst COLLECTION_ID_PATTERN = /^(?:[0-9a-f]{2}){1,64}$/i;\nconst LONE_SURROGATE = /\\p{Cs}/u;\nconst CBOR_MAJOR_TYPE_MASK = 0b1110_0000;\nconst ATTRIBUTE_VALUE_RULE =\n 'must be non-empty text or an integer within ±(2^53 − 1) — write decimals and larger numbers as text';\nconst COLLECTION_ID_RULE = 'must be null or 1–64 bytes as even-length hex (2–128 characters)';\nconst DOCUMENT_AS_MEDIA_RULE = `must not be ${NFT_DOCUMENT_MEDIA_TYPE}: a document link is a token's content, never media`;\n// The SDK's text decoder substitutes U+FFFD, which would recognise invalid UTF-8;\n// ignoreBOM keeps a leading U+FEFF so a decoded string re-encodes byte-identically.\nconst UTF8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });\n\n// ── shared field rules (encoder and decoder) ────────────────────────────────\n\nfunction refuse(field: string, rule: string, cause?: unknown): SphereError {\n return new SphereError(`Invalid NFT ${field}: ${rule}`, 'VALIDATION_ERROR', cause);\n}\n\nfunction ensure(ok: boolean, field: string, rule: string): void {\n if (!ok) throw refuse(field, rule);\n}\n\nconst fieldName = (prefix: string, name: string): string => (prefix === '' ? name : `${prefix}.${name}`);\n\n/** Non-empty and representable as UTF-8 exactly (a lone surrogate is not). */\nconst isText = (value: unknown): value is string =>\n typeof value === 'string' && value.length > 0 && !LONE_SURROGATE.test(value);\n\nconst isBytes = (value: unknown, length?: number): value is Uint8Array =>\n value instanceof Uint8Array && (length === undefined ? value.length > 0 : value.length === length);\n\nconst isMediaType = (value: unknown): boolean => typeof value === 'string' && MEDIA_TYPE_PATTERN.test(value);\n\nconst isCollectionId = (value: unknown): boolean => typeof value === 'string' && COLLECTION_ID_PATTERN.test(value);\n\nconst isAttributeValue = (value: unknown): boolean =>\n typeof value === 'number' ? Number.isSafeInteger(value) : isText(value);\n\nfunction hasSpaceOrControl(value: string): boolean {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (code <= 0x20 || code === 0x7f) return true;\n }\n return false;\n}\n\nfunction isLinkUri(value: unknown): boolean {\n if (!isText(value) || value.length > MAX_URI_LENGTH || hasSpaceOrControl(value)) return false;\n const scheme = LINK_SCHEMES.find((prefix) => value.startsWith(prefix));\n return scheme !== undefined && value.length > scheme.length;\n}\n\nfunction checkText(field: string, value: unknown): void {\n ensure(isText(value), field, 'must be non-empty, well-formed text');\n}\n\nfunction checkOptionalText(field: string, value: unknown): void {\n ensure(value === null || isText(value), field, 'must be null or non-empty, well-formed text');\n}\n\nfunction checkMediaType(field: string, value: unknown): void {\n ensure(isMediaType(value), field, 'must be a lowercase type/subtype media type without parameters');\n}\n\nfunction checkMedia(prefix: string, media: NftMedia): void {\n checkMediaType(fieldName(prefix, 'media_type'), media.media_type);\n ensure(isBytes(media.bytes), fieldName(prefix, 'bytes'), 'must be non-empty bytes');\n}\n\nfunction checkLink(prefix: string, link: NftLink): void {\n checkMediaType(fieldName(prefix, 'media_type'), link.media_type);\n ensure(\n isLinkUri(link.uri),\n fieldName(prefix, 'uri'),\n `must be an https://, ipfs:// or ar:// URI of at most ${MAX_URI_LENGTH} characters with no whitespace or control characters`,\n );\n ensure(\n typeof link.sha256 === 'string' && SHA256_HEX_PATTERN.test(link.sha256),\n fieldName(prefix, 'sha256'),\n 'must be the 64-hex SHA-256 of the linked file',\n );\n}\n\nfunction checkMediaRef(field: string, ref: NftMediaRef | null): void {\n if (ref === null) return;\n if (ref?.kind === 'media') return checkMedia(field, ref);\n if (ref?.kind !== 'link') throw refuse(field, 'must be an NftMedia, an NftLink or null');\n checkLink(field, ref);\n ensure(!isNftDocumentLink(ref), fieldName(field, 'media_type'), DOCUMENT_AS_MEDIA_RULE);\n}\n\nfunction checkAttributes(attributes: readonly NftAttribute[]): void {\n ensure(Array.isArray(attributes), 'attributes', 'must be an array — [] when there are none');\n // entries(), not forEach: a sparse array's holes must be refused, not skipped.\n for (const [index, attribute] of attributes.entries()) {\n checkText(`attributes[${index}].trait_type`, attribute?.trait_type);\n ensure(isAttributeValue(attribute?.value), `attributes[${index}].value`, ATTRIBUTE_VALUE_RULE);\n }\n}\n\nfunction checkMetadata(metadata: NftMetadata): void {\n checkText('name', metadata.name);\n checkOptionalText('description', metadata.description);\n checkMediaRef('image', metadata.image);\n checkMediaRef('animation_url', metadata.animation_url);\n checkOptionalText('external_url', metadata.external_url);\n checkAttributes(metadata.attributes);\n checkOptionalText('collection', metadata.collection);\n ensure(metadata.collection_id === null || isCollectionId(metadata.collection_id), 'collection_id', COLLECTION_ID_RULE);\n}\n\nfunction checkContent(content: NftContent): void {\n switch (content?.kind) {\n case 'metadata':\n return checkMetadata(content);\n case 'media':\n return checkMedia('', content);\n case 'link':\n return checkLink('', content);\n default:\n throw refuse('content', \"kind must be 'metadata', 'media' or 'link'\");\n }\n}\n\nfunction checkSignedParts(creator: unknown, signature: unknown): void {\n ensure(isBytes(creator, CREATOR_BYTES), 'creator', 'must be a 33-byte compressed secp256k1 public key');\n ensure(isBytes(signature, SIGNATURE_BYTES), 'signature', 'must be 65 bytes: r(32) ‖ s(32) ‖ recovery(1)');\n}\n\n// ── encoder ─────────────────────────────────────────────────────────────────\n\nconst text = (value: string): Uint8Array => CborSerializer.encodeTextString(value);\n\nconst optionalText = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, CborSerializer.encodeTextString);\n\nfunction versioned(tag: bigint, ...fields: Uint8Array[]): Uint8Array {\n return CborSerializer.encodeTag(\n tag,\n CborSerializer.encodeArray(CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION), ...fields),\n );\n}\n\n/** Major type 1 shares the unsigned head layout; the SDK serializer has no encoder for it. */\nfunction integerCbor(value: number): Uint8Array {\n if (value >= 0) return CborSerializer.encodeUnsignedInteger(value);\n const head = CborSerializer.encodeUnsignedInteger(-1 - value);\n head[0] |= MajorType.NEGATIVE_INTEGER;\n return head;\n}\n\nfunction mediaCbor(media: NftMedia): Uint8Array {\n return versioned(NFT_MEDIA_TAG, text(media.media_type), CborSerializer.encodeByteString(media.bytes));\n}\n\nfunction linkCbor(link: NftLink): Uint8Array {\n const digest = HexConverter.decode(link.sha256.toLowerCase());\n return versioned(NFT_LINK_TAG, text(link.media_type), text(link.uri), CborSerializer.encodeByteString(digest));\n}\n\nfunction mediaRefCbor(ref: NftMediaRef | null): Uint8Array {\n if (ref === null) return CborSerializer.encodeNull();\n return ref.kind === 'media' ? mediaCbor(ref) : linkCbor(ref);\n}\n\nfunction attributeCbor({ trait_type, value }: NftAttribute): Uint8Array {\n return CborSerializer.encodeArray(text(trait_type), typeof value === 'string' ? text(value) : integerCbor(value));\n}\n\n/**\n * The SDK's array head over a list of any length. Spreading the list into\n * `encodeArray` arguments overflows the call stack past ~125k items (fewer in JSC).\n */\nfunction arrayCbor(items: readonly Uint8Array[]): Uint8Array {\n const head = CborSerializer.encodeUnsignedInteger(items.length);\n head[0] |= MajorType.ARRAY;\n const out = new Uint8Array(items.reduce((length, item) => length + item.length, head.length));\n out.set(head);\n let offset = head.length;\n for (const item of items) {\n out.set(item, offset);\n offset += item.length;\n }\n return out;\n}\n\nconst optionalHexBytes = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, (hex) => CborSerializer.encodeByteString(HexConverter.decode(hex.toLowerCase())));\n\nfunction metadataCbor(metadata: NftMetadata): Uint8Array {\n return versioned(\n NFT_METADATA_TAG,\n text(metadata.name),\n optionalText(metadata.description),\n mediaRefCbor(metadata.image),\n mediaRefCbor(metadata.animation_url),\n optionalText(metadata.external_url),\n arrayCbor(metadata.attributes.map(attributeCbor)),\n optionalText(metadata.collection),\n optionalHexBytes(metadata.collection_id),\n );\n}\n\n/** Encode one unsigned item. Throws SphereError('…', 'VALIDATION_ERROR') naming the offending field. */\nexport function encodeNftContent(content: NftContent): Uint8Array {\n checkContent(content);\n if (content.kind === 'metadata') return metadataCbor(content);\n return content.kind === 'media' ? mediaCbor(content) : linkCbor(content);\n}\n\n/** Wrap an encoded unsigned item; `signature` is `Signature.encode()` over {@link nftSignedDigest}. */\nexport function encodeNftSigned(creator: Uint8Array, payload: Uint8Array, signature: Uint8Array): Uint8Array {\n checkSignedParts(creator, signature);\n checkContent(signablePayload(payload));\n return versioned(\n NFT_SIGNED_TAG,\n CborSerializer.encodeByteString(creator),\n payload,\n CborSerializer.encodeByteString(signature),\n );\n}\n\nfunction signablePayload(payload: Uint8Array): NftContent {\n try {\n return decodeItem(UNSIGNED_DECODERS, 'payload', payload);\n } catch (error) {\n throw refuse('payload', 'must be exactly one encoded NftMetadata, NftMedia or NftLink item', error);\n }\n}\n\n// ── decoder (structure only; value rules are the shared checks above) ──────\n\ntype BodyDecoder<T> = (body: Uint8Array) => T;\n\nconst majorTypeOf = (item: Uint8Array): MajorType => (item.at(0) ?? 0) & CBOR_MAJOR_TYPE_MASK;\n\nfunction decodeText(item: Uint8Array): string {\n const reader = new CborReader(item);\n const bytes = reader.read(Number(reader.readLength(MajorType.TEXT_STRING)));\n reader.assertExhausted();\n return UTF8.decode(bytes);\n}\n\nconst decodeOptionalText = (item: Uint8Array): string | null => CborDeserializer.decodeNullable(item, decodeText);\n\nfunction decodeAttributeValue(item: Uint8Array): string | number {\n const major = majorTypeOf(item);\n if (major === MajorType.TEXT_STRING) return decodeText(item);\n const isInteger = major === MajorType.UNSIGNED_INTEGER || major === MajorType.NEGATIVE_INTEGER;\n ensure(isInteger, 'attribute value', ATTRIBUTE_VALUE_RULE);\n const reader = new CborReader(item);\n const magnitude = reader.readLength(major);\n reader.assertExhausted();\n return Number(major === MajorType.UNSIGNED_INTEGER ? magnitude : -1n - magnitude);\n}\n\nfunction decodeAttributes(item: Uint8Array): NftAttribute[] {\n return CborDeserializer.decodeArray(item).map((entry) => {\n const [traitType, value] = CborDeserializer.decodeArray(entry, 2);\n return { trait_type: decodeText(traitType), value: decodeAttributeValue(value) };\n });\n}\n\nfunction versionedFields(body: Uint8Array, arity: number): Uint8Array[] {\n const fields = CborDeserializer.decodeArray(body, arity);\n ensure(CborDeserializer.decodeUnsignedInteger(fields[0]) === NFT_FORMAT_VERSION, 'version', 'must be 1');\n return fields;\n}\n\nfunction decodeMedia(body: Uint8Array): NftMedia {\n const [, mediaType, bytes] = versionedFields(body, MEDIA_ARITY);\n return { kind: 'media', media_type: decodeText(mediaType), bytes: CborDeserializer.decodeByteString(bytes) };\n}\n\nconst decodeHex = (item: Uint8Array): string => HexConverter.encode(CborDeserializer.decodeByteString(item));\n\nfunction decodeLink(body: Uint8Array): NftLink {\n const [, mediaType, uri, digest] = versionedFields(body, LINK_ARITY);\n return {\n kind: 'link',\n media_type: decodeText(mediaType),\n uri: decodeText(uri),\n sha256: decodeHex(digest),\n };\n}\n\nfunction decodeMetadata(body: Uint8Array): NftMetadata {\n const fields = versionedFields(body, METADATA_ARITY);\n return {\n kind: 'metadata',\n name: decodeText(fields[1]),\n description: decodeOptionalText(fields[2]),\n image: decodeMediaRef('image', fields[3]),\n animation_url: decodeMediaRef('animation_url', fields[4]),\n external_url: decodeOptionalText(fields[5]),\n attributes: decodeAttributes(fields[6]),\n collection: decodeOptionalText(fields[7]),\n collection_id: CborDeserializer.decodeNullable(fields[8], decodeHex),\n };\n}\n\n// The nesting rules: a media slot holds NftMedia or NftLink (never a document link,\n// which checkMediaRef refuses); NftSigned wraps any unsigned item and itself appears\n// only at the top level; a linked document is NftMetadata or NftMedia.\nconst MEDIA_REF_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftMediaRef>> = new Map<bigint, BodyDecoder<NftMediaRef>>([\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst UNSIGNED_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftContent>> = new Map<bigint, BodyDecoder<NftContent>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst DOCUMENT_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftDocument>> = new Map<bigint, BodyDecoder<NftDocument>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n]);\n\nfunction decodeBody<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, tag: bigint, body: Uint8Array): T {\n const decode = decoders.get(tag);\n if (decode === undefined) throw refuse(field, `tag ${tag} is not allowed here`);\n return decode(body);\n}\n\nfunction decodeItem<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, item: Uint8Array): T {\n const { tag, data } = CborDeserializer.decodeTag(item);\n return decodeBody(decoders, field, tag, data);\n}\n\nfunction decodeMediaRef(field: string, item: Uint8Array): NftMediaRef | null {\n return CborDeserializer.decodeNullable(item, (ref) => decodeItem(MEDIA_REF_DECODERS, field, ref));\n}\n\nfunction decodeSigned(body: Uint8Array): ParsedNft {\n const [, creatorItem, payload, signatureItem] = versionedFields(body, SIGNED_ARITY);\n const creator = CborDeserializer.decodeByteString(creatorItem);\n const signature = CborDeserializer.decodeByteString(signatureItem);\n checkSignedParts(creator, signature);\n return { content: decodeItem(UNSIGNED_DECODERS, 'payload', payload), signed: { creator, payload, signature } };\n}\n\nfunction decodePayload(data: Uint8Array): ParsedNft {\n const { tag, data: body } = CborDeserializer.decodeTag(data);\n if (tag === NFT_SIGNED_TAG) return decodeSigned(body);\n return { content: decodeBody(UNSIGNED_DECODERS, 'payload', tag, body), signed: null };\n}\n\n/** Structural parse of a genesis payload. NEVER throws; null = not a recognised NFT. */\nexport function parseNftPayload(data: Uint8Array | null): ParsedNft | null {\n if (data === null) return null;\n try {\n const parsed = decodePayload(data);\n checkContent(parsed.content);\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse the file a document link points at: exactly one NftMetadata or NftMedia item.\n * NEVER throws; null = not a document. Check the bytes with verifyNftLinkContent first.\n */\nexport function parseNftDocument(bytes: Uint8Array): NftMetadata | NftMedia | null {\n try {\n const document = decodeItem(DOCUMENT_DECODERS, 'document', bytes);\n checkContent(document);\n return document;\n } catch {\n return null;\n }\n}\n\n/** Is this an NftLink to a metadata document ({@link NFT_DOCUMENT_MEDIA_TYPE}), resolved with parseNftDocument? */\nexport function isNftDocumentLink(content: NftContent): boolean {\n return content?.kind === 'link' && content.media_type === NFT_DOCUMENT_MEDIA_TYPE;\n}\n\n// ── signature ───────────────────────────────────────────────────────────────\n\n/**\n * SHA-256 of CBOR `[h'UNICITY_NFT_SIGNED', 1, α, h(recipient predicate), h(token id), h(token type), h(payload)]`:\n * every term a byte string except the version and α, as in the yellowpaper genesis commitment.\n */\nexport function nftSignedDigest(context: NftSignatureContext, payload: Uint8Array): Promise<DataHash> {\n const preimage = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(SIGNED_DOMAIN),\n CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION),\n CborSerializer.encodeUnsignedInteger(NetworkId.fromId(context.networkId).id),\n CborSerializer.encodeByteString(context.recipientPredicate),\n CborSerializer.encodeByteString(context.tokenId),\n CborSerializer.encodeByteString(context.tokenType),\n CborSerializer.encodeByteString(payload),\n );\n return new DataHasher(HashAlgorithm.SHA256).update(preimage).digest();\n}\n\n/** Recovering verification: binds the recovery byte and refuses high-s. Never throws. */\nexport async function verifyNftSignature(\n signed: NonNullable<ParsedNft['signed']>,\n context: NftSignatureContext,\n): Promise<Exclude<NftSignatureStatus, 'unsigned'>> {\n try {\n if (!SigningService.isPublicKeyValid(signed.creator)) return 'invalid';\n const signature = Signature.decode(signed.signature);\n const digest = await nftSignedDigest(context, signed.payload);\n return (await SigningService.verifyWithPublicKey(digest, signature, signed.creator)) ? 'valid' : 'invalid';\n } catch {\n return 'invalid';\n }\n}\n\n/** Does `bytes` match the link's sha256? Pure, sync. */\nexport function verifyNftLinkContent(link: NftLink, bytes: Uint8Array): boolean {\n return HexConverter.encode(sha256(bytes)) === link.sha256.toLowerCase();\n}\n","/**\n * token-engine/SphereTokenEngine.ts — the real ITokenEngine adapter (Track A).\n *\n * The full sender-driven engine over the v2 SDK: identity, value reads,\n * serialization, verification, mint, transfer, split and spent-status. All\n * crypto/value logic is the SDK's; this class orchestrates build → submit →\n * wait-proof → certify → realize, and maps SDK errors/states to the\n * sphere-domain ITokenEngine port.\n *\n * SDK objects are injected via `EngineDeps` (built by the factory in A4, or by\n * test wiring around TestAggregatorClient), keeping the engine logic independent\n * of how the aggregator/trust base are constructed.\n *\n * Advertises `deterministicMint` (F13): a same-seed `mint` re-call recovers an\n * existing certification instead of minting a second token.\n */\n\nimport { SphereError, type SphereErrorCode } from '../core/errors';\nimport {\n awaitProofBounded,\n certificationDeadline,\n resolveProofTimeoutMs,\n retryTransient,\n TransientSubmitAnswer,\n} from './proof-wait';\nimport { certificationFailure } from './certification-outcome';\nimport { randomUUID } from '../core/uuid';\nimport {\n CheckpointPersistFailedError,\n CheckpointTrustbaseMismatchError,\n ProofUnconfirmedError,\n SplitCheckpointLostError,\n TransferConflictError,\n} from './errors';\nimport { deriveDirectAddress } from './identity';\nimport { deriveDeliveryKeys } from './blob-keys';\nimport { deriveRealization } from './realization';\nimport { planNftMint, readTokenNft } from './nft-ops';\nimport { burntTokenFromCheckpoint, encodeCheckpoint } from './split-checkpoint';\nimport {\n CertificationData,\n CertificationStatus,\n EncodedPredicate,\n HexConverter,\n type InclusionProof,\n InclusionProofVerificationStatus,\n type ITransaction,\n type MintJustificationVerifierService,\n MintTransaction,\n type NetworkId,\n PaymentAssetCollection,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n SignaturePredicate,\n SignaturePredicateUnlockScript,\n type SigningService,\n SplitMintJustification,\n type SplitToken,\n SplitTokenRequest,\n StateId,\n StateMask,\n type StateTransitionClient,\n Token,\n TokenSalt,\n TokenSplit,\n TokenType,\n TransferTransaction,\n type VerificationContext,\n VerificationStatus,\n waitInclusionProof,\n type ITokenVerifier,\n} from './sdk';\nimport { decodeSpherePaymentData, SpherePaymentData, sphereAssetToSdk } from './SpherePaymentData';\nimport { assertMintableData, classifyValueEnvelope, wrapToken } from './value-envelope';\nimport type { EngineOpOptions, ITokenEngine } from './engine';\nimport type {\n BuildNftMintParams,\n CoinId,\n EngineIdentity,\n EngineVerifyResult,\n MintDataTokenParams,\n MintParams,\n NftMintPlan,\n NftReading,\n SphereToken,\n SphereValue,\n SplitParams,\n SplitResult,\n TokenBlob,\n TransferParams,\n} from './types';\n\n/** SDK objects the engine operates with; assembled by the factory (A4) or test wiring. */\n/** An `ITokenVerifier` that also owns terminable resources (a worker pool). */\nexport interface DisposableTokenVerifier extends ITokenVerifier {\n dispose(): void;\n}\n\nexport interface EngineDeps {\n readonly client: StateTransitionClient;\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly mintJustificationVerifier: MintJustificationVerifierService;\n readonly verificationContext: VerificationContext;\n /**\n * Opt-in parallel verifier (EngineConfig.verification). Absent → tokens verify\n * sequentially via `Token.verify`, which is what every release before 2.0.2 did.\n */\n readonly tokenVerifier?: DisposableTokenVerifier;\n /** The wallet's signing key (its identity + the spender for transfers it owns). */\n readonly signingService: SigningService;\n /**\n * The same key as raw bytes — the HKDF ikm for deterministic realization\n * (Part E.1; SigningService does not expose it back).\n */\n readonly privateKey: Uint8Array;\n readonly networkId: NetworkId;\n /** Inclusion-proof poll cadence in ms (#683); undefined → the tuned default below. */\n readonly proofPollIntervalMs?: number;\n /** Deadline for one inclusion-proof wait; defaults to DEFAULT_PROOF_TIMEOUT_MS (#739). */\n readonly proofTimeoutMs?: number;\n}\n\n/**\n * #683: default inclusion-proof poll interval (ms). Finer than the sdk's 1000ms\n * default so a ~1.2s finalization is caught near ~1.2-1.5s instead of at the 2s\n * poll boundary. Bounded by waitInclusionProof's 10s abort; the extra polls are\n * cheap read-only getInclusionProof calls confined to the ~1.5s finalization window.\n */\nexport const DEFAULT_PROOF_POLL_INTERVAL_MS = 300;\n\n/**\n * #684: max split-mint legs minted concurrently. The mints are independent off the\n * one burn, but an UNBOUNDED fan-out would submit + proof-poll every leg at once\n * against the gateway (the prior sequential loop naturally paced it to one). This\n * cap keeps a typical split (K=2 — payment + change) fully parallel while bounding\n * gateway load on a large multi-output split.\n */\nconst MAX_MINT_CONCURRENCY = 8;\n\n/**\n * The keep-open engine errors a split leg can raise — mirrors PaymentsModule's `keepOpen` set.\n * When one of these settles a parallel mint fan-out, the leg's spend MAY already be certified\n * on-chain, so the intent MUST stay OPEN for checkpoint-based resume; the fan-out must surface a\n * keep-open outcome rather than an abortable clean failure that would strand a certified sibling\n * (#684). Only ProofUnconfirmedError / SplitCheckpointLostError are reachable from a mint leg\n * today; the checkpoint pair is included so the classifier stays faithful to the keep-open family.\n */\nfunction isKeepOpenSplitError(err: unknown): boolean {\n return (\n err instanceof ProofUnconfirmedError ||\n err instanceof CheckpointPersistFailedError ||\n err instanceof SplitCheckpointLostError ||\n err instanceof CheckpointTrustbaseMismatchError\n );\n}\n\n/** Canonical lowercase UUID — the spec's `transferId` wire form (sdk-changes E.1). */\nconst TRANSFER_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n/**\n * The KNOWN validation-reject submit statuses: a well-formed rejection that PROVES the\n * state was never certified (a byte-identical resume of a *valid* tx never later returns\n * a format/signature/state/shard-mismatch failure). E.2 is status-AGNOSTIC for everything\n * else: an UNKNOWN or transitional non-SUCCESS status (e.g. the gateway's transitional\n * `STATE_ID_EXISTS`) means \"a certification for this state MAY already exist\" — it must be\n * treated as possibly-certified (keep the intent OPEN — #631), NEVER a clean abort. Any\n * status outside this set therefore falls through to `ProofUnconfirmedError`.\n *\n * v3's REQUEST_EXPIRED and SERVICE_NOT_READY stay OUT despite their names: each\n * reports only that THIS submit was not admitted, never that no earlier attempt\n * certified. Pinned by expires-at.test.ts.\n */\nconst CLEAN_REJECT_STATUSES: ReadonlySet<string> = new Set([\n CertificationStatus.STATE_ID_MISMATCH,\n CertificationStatus.SIGNATURE_VERIFICATION_FAILED,\n CertificationStatus.INVALID_SIGNATURE_FORMAT,\n CertificationStatus.INVALID_PUBLIC_KEY_FORMAT,\n CertificationStatus.INVALID_SOURCE_STATE_HASH_FORMAT,\n CertificationStatus.INVALID_TRANSACTION_HASH_FORMAT,\n CertificationStatus.UNSUPPORTED_ALGORITHM,\n CertificationStatus.INVALID_SHARD,\n]);\n\n/** The deterministic split plan (burn leg + per-output mint requests) — `TokenSplit.split`'s result. */\ntype SplitPlan = Awaited<ReturnType<typeof TokenSplit.split>>;\n\n/** Threaded through the E.4 burnt-token resolution so its helpers stay within the max-params bound. */\ninterface SplitContext {\n readonly params: SplitParams;\n readonly split: SplitPlan;\n readonly transferId: string;\n readonly options?: EngineOpOptions | undefined;\n}\n\nexport class SphereTokenEngine implements ITokenEngine {\n /** F13 advertisement: mint under a (transferId, opIndex) seed is idempotent-recoverable — a same-seed re-call converges, never double-mints. */\n public readonly deterministicMint = true;\n\n /** Hex form of the wallet key — deriveRealization's ikm input (Part E.1). */\n private readonly privateKeyHex: string;\n\n private readonly proofTimeoutMs: number;\n\n public constructor(private readonly deps: EngineDeps) {\n this.privateKeyHex = HexConverter.encode(deps.privateKey);\n // Refused here, not per op: a bad deadline must not surface as a money error.\n this.proofTimeoutMs = resolveProofTimeoutMs(deps.proofTimeoutMs);\n }\n\n // ── identity ────────────────────────────────────────────────────────────────\n\n public getIdentity(): EngineIdentity {\n return { chainPubkey: new Uint8Array(this.deps.signingService.publicKey) };\n }\n\n /** Legacy DIRECT:// address (Path A). Async: the derivation hashes via the SDK. */\n public deriveIdentityAddress(pubkey?: Uint8Array): Promise<string> {\n return deriveDirectAddress(pubkey ?? this.deps.signingService.publicKey);\n }\n\n // ── value (read) ─────────────────────────────────────────────────────────────\n\n public readValue(token: SphereToken): SphereValue | null {\n return token.value;\n }\n\n public balanceOf(token: SphereToken, coinId: CoinId): bigint {\n let sum = 0n;\n for (const asset of token.value?.assets ?? []) {\n if (asset.coinId === coinId) sum += asset.amount;\n }\n return sum;\n }\n\n public tokenId(token: SphereToken): string {\n return token.blob.tokenId;\n }\n\n public readMemo(token: SphereToken): Uint8Array | null {\n const sdkToken = token.sdkToken;\n // A transferred token delivers its memo on the latest transfer.\n if (sdkToken.transactions.length > 0) {\n return sdkToken.latestTransaction.data;\n }\n // A minted output (e.g. a split output) carries the memo in its value envelope.\n // Classify structurally: a CORRUPT envelope throws rather than reading as a\n // memo-less data token (#778), and only `'sphere'` guarantees fromCBOR succeeds.\n const data = sdkToken.genesis.data;\n if (data && classifyValueEnvelope(data).envelope === 'sphere') {\n return SpherePaymentData.fromCBOR(data).memo;\n }\n return null;\n }\n\n public readTokenData(token: SphereToken): Uint8Array | null {\n const data = token.sdkToken.genesis.data;\n return data ? new Uint8Array(data) : null;\n }\n\n public readNft(token: SphereToken): Promise<NftReading | null> {\n return readTokenNft(token);\n }\n\n // ── lifecycle ────────────────────────────────────────────────────────────────\n\n public async mint(params: MintParams, options?: EngineOpOptions): Promise<SphereToken> {\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const data = params.value ? await SpherePaymentData.fromValue(params.value).encode() : null;\n const transferId = this.resolveTransferId(options);\n const opIndex = this.resolveOpIndex(options);\n\n // #692 F13 — E.1: HKDF-derived salt (→ tokenId → stateId) + tokenType make a\n // re-call with the same transferId rebuild the byte-identical mint. The salt\n // gets its own 'mint' field domain: 'salt' is indexed by split-OUTPUT ordinal\n // under the same transferId, so ('salt', opIndex) would collide with output\n // #opIndex of a sibling split (see RealizationField).\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, {\n data,\n tokenType: new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, 'tokenType')),\n salt: TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, 'mint')),\n });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // The same idempotent submit-then-always-probe primitive as transfer/split (E.2):\n // OK-match = mine (resume), mismatch = typed conflict, clean reject = submit error,\n // inconclusive = ProofUnconfirmedError (keep-open) — never inferred from the status.\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Mint certification failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return wrapToken(token);\n }\n\n public async mintDataToken(params: MintDataTokenParams, options?: EngineOpOptions): Promise<SphereToken> {\n assertMintableData(params.data);\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const tokenType = params.tokenType ? new TokenType(params.tokenType) : TokenType.generate();\n // A deterministic salt yields a stable, terms-derived tokenId (TokenId.fromSalt).\n const salt = params.salt ? TokenSalt.fromBytes(params.salt) : TokenSalt.generate();\n\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, { data: params.data, tokenType, salt });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // #692 F13: the caller's deterministic salt already makes the re-call byte-identical;\n // routing through the probe primitive makes the re-call actually RECOVER (E.2).\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Data-token mint failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return wrapToken(token);\n }\n\n public buildNftMint(params: BuildNftMintParams): Promise<NftMintPlan> {\n return planNftMint(this.deps, params);\n }\n\n public async transfer(params: TransferParams, options?: EngineOpOptions): Promise<SphereToken> {\n this.assertOwned(params.token);\n const transferId = this.resolveTransferId(options);\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n // E.1 deterministic realization: same transferId + inputs ⇒ byte-identical\n // transaction, so an interrupted transfer can be rebuilt and resumed (AC-E1/E2).\n const stateMask = StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'stateMask'),\n );\n\n const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask, {\n data: params.data ?? null,\n });\n const unlockScript = await SignaturePredicateUnlockScript.create(transferTx, this.deps.signingService);\n const certificationData = await CertificationData.fromTransaction(transferTx, unlockScript);\n\n const proof = await this.submitAndAwaitProof(\n certificationData,\n transferTx,\n 'Transfer certification failed',\n 'TRANSFER_FAILED',\n options,\n );\n const certified = await transferTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const transferred = await params.token.sdkToken.transfer(certified, this.deps.verificationContext);\n return wrapToken(transferred);\n }\n\n public async split(params: SplitParams, options?: EngineOpOptions): Promise<SplitResult> {\n this.assertOwned(params.token);\n if (params.outputs.length === 0) {\n throw new SphereError('Split requires at least one output', 'VALIDATION_ERROR');\n }\n // `TokenSplit.split` below is handed `decodeSpherePaymentData`, which reads only\n // the tag-39050 envelope; without this an unreadable source dies inside the SDK\n // with a bare CborError naming neither token nor cause. A coinless token cannot\n // be split by construction, so this never refuses a legitimate split.\n if (params.token.value === null) {\n throw new SphereError(\n `Cannot split token ${params.token.blob.tokenId}: its genesis payload carries no ` +\n `value this SDK can read (envelope: ${params.token.valueEnvelope}). A coinless ` +\n 'token can only be transferred whole.',\n 'VALIDATION_ERROR',\n );\n }\n const transferId = this.resolveTransferId(options);\n\n // E.1 deterministic realization: per-output HKDF salts make every output's\n // mint transaction (and its salt-derived tokenId) reproducible from the\n // wallet key + transferId.\n const requests = params.outputs.map((o, i) =>\n SplitTokenRequest.create(\n SignaturePredicate.create(o.recipientPubkey),\n SpherePaymentData.create(PaymentAssetCollection.create(sphereAssetToSdk(o.coinId, o.amount)), o.data ?? null),\n TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, i, 'salt')),\n ),\n );\n\n // Value conservation is enforced inside the SDK split (root.value === source value).\n // E.1: the burn state mask is HKDF-derived, so the whole split — burn leg\n // included — is rebuildable from the wallet key + transferId (crash resume).\n const split = await TokenSplit.split(params.token.sdkToken, decodeSpherePaymentData, requests, {\n burnStateMask: StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'burn'),\n ),\n });\n\n // 1. Resolve the burnt token: from a durable checkpoint on resume, else burn now and persist\n // the checkpoint BEFORE any mint submit (E.4 — the burn proof is the one non-re-derivable\n // split input; a mint certified against proof bytes that were never stored strands #501).\n const burntToken = await this.resolveBurntToken({ params, split, transferId, options });\n\n // 2. Mint every output IN PARALLEL (#684), each justified by the burnt token + its\n // own split proofs. The mints are independent legs off the ONE already-certified,\n // already-checkpointed burn (step 1, outside this fan-out — E.4 burn-before-mint\n // is unchanged), so they carry no ordering constraint among themselves.\n //\n // MONEY-SAFETY, identical to the prior sequential loop: `allSettled` waits for\n // EVERY leg (no leg abandoned mid-submit) and rethrows the LOWEST-index rejection,\n // which is the error the sequential loop surfaced — so keep-open classification is\n // unchanged. On failure the intent stays OPEN and resume re-runs all legs from the\n // durable checkpoint; an already-certified leg is recovered idempotently (#631/E.2),\n // so legs this fan-out submitted early are never lost. MAX_MINT_CONCURRENCY paces it.\n const settled: PromiseSettledResult<SphereToken>[] = [];\n for (let start = 0; start < split.tokens.length; start += MAX_MINT_CONCURRENCY) {\n const batch = split.tokens.slice(start, start + MAX_MINT_CONCURRENCY);\n settled.push(\n ...(await Promise.allSettled(\n batch.map((token) => this.mintSplitOutput(token, burntToken, options)),\n )),\n );\n }\n // Every leg has settled. Aggregate with a KEEP-OPEN BIAS. The old sequential loop never\n // submitted a later leg once an earlier one failed, so surfacing the first failure could\n // never orphan a certified sibling. THIS fan-out submits every leg, so a lower-index CLEAN\n // failure can coexist with a higher-index leg that already CERTIFIED (fulfilled) or MAY have\n // (a keep-open rejection). Surfacing the lowest-index CLEAN error in that case would let\n // PaymentsModule abort the intent (its committed-source set is still empty here) and strand\n // the certified sibling with no checkpoint recovery (Codex P1 on #684). So, in order:\n // 1. If ANY leg rejected keep-open (ProofUnconfirmed / SplitCheckpointLost / the E.4 pair),\n // surface that verbatim (lowest-index) so its specific keep-open type drives\n // PaymentsModule's classification exactly as before.\n // 2. Else (ANY clean rejection, whether or not a sibling certified) the BURN is already\n // committed + checkpointed (resolveBurntToken, above), so the source is spent on-chain.\n // Convert to a keep-open ProofUnconfirmedError (cause = the clean failure): a plain\n // abortable error would let PaymentsModule abort the intent and STRAND the whole source\n // value (the burn cannot be undone; an aborted intent never re-runs). Keep-open so resume\n // re-runs ALL legs idempotently from the burn checkpoint (HKDF-deterministic stateId → the\n // aggregator returns the existing proof; #631/E.2/E.3). A clean mint reject after a valid,\n // value-conserving burn is transient (e.g. a shard reconfiguration), never permanent.\n const keepOpenRejection = settled.find(\n (r): r is PromiseRejectedResult => r.status === 'rejected' && isKeepOpenSplitError(r.reason),\n );\n if (keepOpenRejection !== undefined) {\n throw keepOpenRejection.reason;\n }\n const firstRejected = settled.findIndex((r) => r.status === 'rejected');\n if (firstRejected !== -1) {\n const cleanReason = (settled[firstRejected] as PromiseRejectedResult).reason;\n // 3. Else (every rejection is clean — none keep-open) the burn is STILL committed +\n // checkpointed (resolveBurntToken, above), whether or not a sibling certified. Surfacing\n // a plain abortable clean error would let PaymentsModule abort the intent and STRAND the\n // entire source value — the burn cannot be undone and an aborted intent never re-runs. So\n // EVERY post-burn mint failure is keep-open: resume re-runs all legs idempotently from the\n // burn checkpoint. (A clean mint reject after a valid, value-conserving burn is transient —\n // e.g. a shard reconfiguration — not a permanent validation failure; keep-open leaves the\n // funds RECOVERABLE, abort loses them.)\n throw new ProofUnconfirmedError(\n settled.some((r) => r.status === 'fulfilled')\n ? 'a split mint leg certified while a sibling leg failed — keep the intent open; resume ' +\n 'completes all legs idempotently from the burn checkpoint (#684 parallel fan-out)'\n : 'every split mint leg failed after the burn certified — keep the intent open; resume ' +\n 're-runs all legs idempotently from the burn checkpoint (post-burn must never abort)',\n cleanReason,\n );\n }\n const outputs = settled.map((r) => (r as PromiseFulfilledResult<SphereToken>).value);\n return { outputs };\n }\n\n /**\n * E.4 burnt-token resolution. With a checkpoint store: `get` → rebuild from the STORED proof on\n * resume; else a leg-0 pre-flight probe (a certified leaf with no checkpoint is unrecoverable),\n * then burn, persist the checkpoint (durable-ack gated), and adopt the authoritative stored\n * bytes. Without a store: burn as before (a documented residual for fully-local compositions).\n */\n private async resolveBurntToken(ctx: SplitContext): Promise<Token> {\n const store = ctx.options?.checkpointStore;\n const opIndex = this.resolveOpIndex(ctx.options);\n const source = ctx.params.token.sdkToken;\n if (store === undefined) {\n return (await this.burnSource(ctx)).burntToken;\n }\n const stored = await store.get(ctx.transferId, opIndex);\n if (stored !== null) {\n return burntTokenFromCheckpoint(this.deps, stored, ctx.split.burn.transaction, source);\n }\n await this.assertNoLegStranded(ctx);\n const { burntToken, burnProof } = await this.burnSource(ctx);\n const envelope = await encodeCheckpoint(ctx.split.burn.transaction, burnProof, burntToken);\n // The durable-ack gate: `put` resolving IS the ack, and NO mint has been submitted yet.\n let authoritative: Uint8Array;\n try {\n authoritative = await store.put(ctx.transferId, opIndex, envelope);\n } catch (err) {\n throw new CheckpointPersistFailedError(\n 'split burn certified but its checkpoint could not be persisted — keep the intent open and resume',\n err,\n );\n }\n // Decode-from-stored discipline: mint from the AUTHORITATIVE bytes (ours, or a racing resumer's\n // that won the slot), never the pre-store in-memory burnt token — so concurrent resumers agree.\n return burntTokenFromCheckpoint(this.deps, authoritative, ctx.split.burn.transaction, source);\n }\n\n /** Burn the source: certify the burn transfer and append it -> burntToken (+ its proof). */\n private async burnSource(ctx: SplitContext): Promise<{ burntToken: Token; burnProof: InclusionProof }> {\n const burnTx = ctx.split.burn.transaction;\n const burnUnlock = await SignaturePredicateUnlockScript.create(burnTx, this.deps.signingService);\n const burnCert = await CertificationData.fromTransaction(burnTx, burnUnlock);\n const burnProof = await this.submitAndAwaitProof(burnCert, burnTx, 'Split burn failed', 'TRANSFER_FAILED', ctx.options);\n const burnCertified = await burnTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, burnProof);\n const burntToken = await ctx.params.token.sdkToken.transfer(burnCertified, this.deps.verificationContext);\n return { burntToken, burnProof };\n }\n\n /**\n * Pre-flight (no-checkpoint path): if ANY mint leaf is already certified on-chain while the\n * checkpoint is missing, the burn proof is genuinely unrecoverable — fail BEFORE any re-burn. A\n * mint's stateId is justification-INDEPENDENT (only the source state hash + salt-derived mask),\n * so a probe mint with a null justification derives the true on-chain key. Every leg is probed,\n * so correctness does NOT depend on the mint loop certifying leg 0 first (E.4 step 3).\n */\n private async assertNoLegStranded(ctx: SplitContext): Promise<void> {\n // #684: probe every leg's stateId IN PARALLEL — read-only getInclusionProof calls,\n // order-independent (it throws if ANY leg is already certified). Promise.all rejects\n // on the first stranded leg, same as the prior sequential loop.\n await Promise.all(\n ctx.split.tokens.map(async (leg) => {\n const data = await leg.paymentData.encode();\n const probe = await MintTransaction.create(leg.networkId, leg.recipient, {\n data,\n tokenType: leg.tokenType,\n salt: leg.salt,\n justification: null,\n });\n const response = await this.deps.client.getInclusionProof(await StateId.fromTransaction(probe));\n // v3: a null `inclusionProof` IS \"not certified yet\"; a present one always\n // describes a real leaf, so there is no longer a field to misread here.\n if (response.inclusionProof !== null) {\n throw new SplitCheckpointLostError(\n 'a split mint leaf is certified on-chain but no burn checkpoint exists — outputs are unrecoverable',\n );\n }\n }),\n );\n }\n\n /** One split output: build the justification from the burnt token, submit, certify, wrap. */\n private async mintSplitOutput(\n splitToken: SplitToken,\n burntToken: Token,\n options?: EngineOpOptions,\n ): Promise<SphereToken> {\n const data = await splitToken.paymentData.encode();\n const justification = SplitMintJustification.create(burntToken, splitToken.proofs).toCBOR();\n const mintTx = await MintTransaction.create(splitToken.networkId, splitToken.recipient, {\n data,\n tokenType: splitToken.tokenType,\n salt: splitToken.salt,\n justification,\n });\n const certData = await CertificationData.fromMintTransaction(mintTx);\n const proof = await this.submitSplitMintLeg(certData, mintTx, options);\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return wrapToken(token);\n }\n\n /**\n * Submit one split-mint leg. A `TRANSACTION_HASH_MISMATCH` on a mint leg is NOT a foreign spend\n * (its stateId is HKDF-derived from `(seed, transferId)`, so only a seed-holder under THIS\n * transferId could have certified a different leaf): the stored checkpoint no longer reproduces\n * the certified leaf → keep-open `SplitCheckpointLostError`, never the abort-and-re-plan\n * `TransferConflictError` (E.2/E.4 split-mint arm).\n */\n private async submitSplitMintLeg(\n certData: CertificationData,\n mintTx: MintTransaction,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n try {\n return await this.submitAndAwaitProof(certData, mintTx, 'Split mint failed', 'AGGREGATOR_ERROR', options);\n } catch (err) {\n if (err instanceof TransferConflictError) {\n throw new SplitCheckpointLostError(\n 'a split mint leg no longer matches its certified leaf — the burn checkpoint is stale or lost',\n err,\n );\n }\n throw err;\n }\n }\n\n // ── verification ─────────────────────────────────────────────────────────────\n\n public async verify(token: SphereToken, _options?: EngineOpOptions): Promise<EngineVerifyResult> {\n // Both verifiers produce the same aggregated result; the worker one only\n // moves the independent per-transfer work off this thread.\n const result = this.deps.tokenVerifier\n ? await this.deps.tokenVerifier.verify(token.sdkToken, this.deps.verificationContext)\n : await token.sdkToken.verify(this.deps.verificationContext);\n return result.status === VerificationStatus.OK ? { ok: true } : { ok: false, reason: String(result.status) };\n }\n\n public isOwnedBy(token: SphereToken, pubkey: Uint8Array): boolean {\n const owner = token.sdkToken.latestTransaction.recipient;\n const claimed = EncodedPredicate.fromPredicate(SignaturePredicate.create(pubkey));\n return EncodedPredicate.equals(owner, claimed);\n }\n\n public async isSpent(token: SphereToken, _options?: EngineOpOptions): Promise<boolean> {\n // The token's current state id = what a future transfer would spend. Derive it via a\n // probe transfer (never submitted) — StateId depends only on the source's lock script\n // and state hash, not on the recipient or state mask.\n const probe = await TransferTransaction.create(\n token.sdkToken,\n SignaturePredicate.create(this.deps.signingService.publicKey),\n StateMask.fromBytes(new Uint8Array(32)),\n );\n const stateId = await StateId.fromTransaction(probe);\n const response = await this.deps.client.getInclusionProof(stateId);\n // Consumed iff the aggregator answers with a PROOF. Reporting an UNSPENT state\n // as spent destroys a live token via the fail-closed recovery gates.\n return response.inclusionProof !== null;\n }\n\n // ── serialization ────────────────────────────────────────────────────────────\n\n /** @inheritDoc — SDK-derived (Token.fromCBOR → latestTransaction.calculateStateHash().imprint). */\n public deliveryKeys(blobBytes: Uint8Array): Promise<{ tokenId: string; stateHash: string }> {\n return deriveDeliveryKeys(blobBytes);\n }\n\n public encodeToken(token: SphereToken): TokenBlob {\n return token.blob;\n }\n\n public async decodeToken(blob: TokenBlob): Promise<SphereToken> {\n const sdkToken = await Token.fromCBOR(blob.token);\n if (sdkToken.genesis.networkId.id !== this.deps.networkId.id) {\n throw new SphereError(\n `Token network mismatch: token is on network ${sdkToken.genesis.networkId.id}, ` +\n `engine on ${this.deps.networkId.id}`,\n 'VALIDATION_ERROR',\n );\n }\n return wrapToken(sdkToken);\n }\n\n // ── internals ────────────────────────────────────────────────────────────────\n\n /**\n * The effective realization seed for one transfer/split (Part E). A caller\n * that wants resumability supplies a pre-persisted UUIDv4 (sdk-changes E.3);\n * otherwise one is generated here — same derivation path, just non-resumable.\n * The canonical-lowercase-UUID check also keeps the HKDF info string\n * unambiguous (no ':' injection, no case-variant double derivations).\n */\n /** Validated op ordinal (§8.1 mask domain separation across ops of one send). */\n private resolveOpIndex(options?: EngineOpOptions): number {\n const opIndex = options?.opIndex ?? 0;\n if (!Number.isInteger(opIndex) || opIndex < 0) {\n throw new SphereError(`opIndex must be a non-negative integer, got ${String(opIndex)}`, 'VALIDATION_ERROR');\n }\n return opIndex;\n }\n\n private resolveTransferId(options?: EngineOpOptions): string {\n const transferId = options?.transferId ?? randomUUID();\n if (!TRANSFER_ID_RE.test(transferId)) {\n throw new SphereError(\n `transferId must be a canonical lowercase UUID string, got \"${transferId}\"`,\n 'VALIDATION_ERROR',\n );\n }\n return transferId;\n }\n\n /**\n * E.2 — status-agnostic idempotent submit with conflict detection\n * (sdk-changes E.2, ARCHITECTURE §8.1).\n *\n * Submit the certification request and treat ANY outcome — success status,\n * error status, or a response-parse throw (the live gateway may still emit\n * statuses this SDK no longer parses, e.g. the transitional STATE_ID_EXISTS)\n * — as \"a certification for this state may already exist\". Then ALWAYS fetch\n * the inclusion proof and match-verify it against the rebuilt transaction\n * (`waitInclusionProof` only returns an OK-verified proof):\n *\n * - match (OK) → proceed; this is how an interrupted\n * attempt with the same transferId resumes;\n * - mismatch (hash ≠ rebuilt tx) → `TransferConflictError`: the source was\n * consumed by a DIFFERENT transaction (lost\n * race) — never applied, never retried;\n * - no proof & the submit failed → the original submit error (a genuine\n * failure, not a resume case).\n */\n private async submitAndAwaitProof(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n const deadline = certificationDeadline(\n this.proofTimeoutMs,\n options?.signal,\n `${failLabel}: not certified`\n );\n try {\n return await this.submitThenProve(certificationData, transaction, failLabel, failCode, deadline.signal);\n } finally {\n deadline.dispose();\n }\n }\n\n /** One certification attempt under one deadline: the metered submit retries\n * transient answers instead of falling through to a proof that cannot exist. */\n private async submitThenProve(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n signal: AbortSignal,\n ): Promise<InclusionProof> {\n let submitError: unknown = null;\n // True ONLY for a KNOWN validation-reject status: a PROVEN clean pre-certification\n // reject. Everything else stays INDETERMINATE (keep-open, #631) — including any\n // submit that was RETRIED, since the earlier POST may already have been processed\n // server-side, which is what sawAmbiguousAttempt latches (#747 review).\n let submitRejectedCleanly = false;\n try {\n const { value: response, retried } = await retryTransient(\n async () => {\n const answer = await this.deps.client.submitCertificationRequest(certificationData);\n // A booting gateway is \"ask again\", not a certification failure — see\n // TransientSubmitAnswer. Everything else, known or unknown, keeps the\n // status-agnostic treatment below.\n if (String(answer.status) === String(CertificationStatus.SERVICE_NOT_READY)) {\n throw new TransientSubmitAnswer(String(answer.status));\n }\n return answer;\n },\n signal,\n this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS,\n );\n if (response.status !== CertificationStatus.SUCCESS) {\n submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);\n submitRejectedCleanly = !retried && CLEAN_REJECT_STATUSES.has(response.status);\n }\n } catch (err) {\n submitError = err ?? new SphereError(`${failLabel}: submit failed`, failCode);\n }\n\n try {\n return await awaitProofBounded(\n {\n client: this.deps.client,\n trustBase: this.deps.trustBase,\n predicateVerifier: this.deps.predicateVerifier,\n unicityCertificateVerifier: this.deps.unicityCertificateVerifier,\n intervalMs: this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS, // #683\n },\n transaction,\n signal,\n );\n } catch (err) {\n throw certificationFailure(err, failLabel, submitError, submitRejectedCleanly);\n }\n }\n\n\n /**\n * One inclusion-proof wait, with the deadline OWNED here (#739) so it is bounded\n * and configurable rather than the SDK's fixed default. A hit throws, and the\n * caller maps it to ProofUnconfirmedError (keep-open) — the correct posture,\n * since the spend may be on-chain.\n */\n /** Fail fast if this engine's key does not own the token's current state. */\n private assertOwned(token: SphereToken): void {\n if (!this.isOwnedBy(token, this.deps.signingService.publicKey)) {\n throw new SphereError('Cannot transfer a token not owned by this engine identity', 'VALIDATION_ERROR');\n }\n }\n\n /**\n * Terminate the verification worker pool, if this engine was configured with\n * one. Idempotent — the pool's dispose only touches workers it spawned.\n */\n public dispose(): void {\n this.deps.tokenVerifier?.dispose();\n }\n\n}\n","// P3b: the E.4 split checkpoint store over the §16 intent-progress endpoints.\n// ENCRYPT ONCE: ciphertext is persisted to ScopedKV BEFORE the first POST and\n// every retry re-POSTs the byte-identical envelope (a fresh AEAD nonce would\n// break the slot's content idempotency). put() resolves with the STORED\n// envelope's plaintext — the slot winner's bytes (insert-once, first-write-wins).\n\nimport { SphereError } from '../../core/errors';\nimport { decryptFieldBytes, encryptFieldBytes } from '../../core/field-encryption';\nimport { progressSignMessage } from '../../core/wallet-api-protocol';\nimport { SplitCheckpointLostError, type SplitCheckpointStore } from '../../token-engine';\nimport { STORE_KEYS, type ScopedKV } from '../../modules/payments-v2/stores';\nimport type { WalletApiV2Client } from './client';\n\nexport type CheckpointClient = Pick<WalletApiV2Client, 'postProgress' | 'getProgress'>;\n\n/** The signed §16 message binding a progress append to its exact envelope bytes. */\nexport { progressSignMessage as progressMessage } from '../../core/wallet-api-protocol';\n\nconst utf8 = (text: string): Uint8Array => new TextEncoder().encode(text);\n\nexport interface WalletApiSplitCheckpointStoreConfig {\n client: CheckpointClient;\n kv: ScopedKV;\n /** S6 self-scoped field key (`deriveFieldEncryptionKey`). */\n fieldKey: Uint8Array;\n /** Signs the wallet-api.progress.v1 message with the chain key. */\n signProgress: (message: string) => string | Promise<string>;\n}\n\nexport class WalletApiSplitCheckpointStore implements SplitCheckpointStore {\n constructor(private readonly config: WalletApiSplitCheckpointStoreConfig) {}\n\n private cacheKey(transferId: string, opIndex: number): string {\n return `${STORE_KEYS.checkpointCache}:${transferId}:${String(opIndex)}`;\n }\n\n private aad(transferId: string, opIndex: number): Uint8Array {\n return utf8(`${transferId}:${String(opIndex)}`);\n }\n\n async put(transferId: string, opIndex: number, bytes: Uint8Array): Promise<Uint8Array> {\n const { kv, fieldKey } = this.config;\n const aad = this.aad(transferId, opIndex);\n const cacheKey = this.cacheKey(transferId, opIndex);\n let envelope = await kv.get<string>(cacheKey);\n if (envelope === null) {\n envelope = encryptFieldBytes(fieldKey, bytes, aad);\n await kv.set(cacheKey, envelope);\n }\n const record = await this.post(transferId, opIndex, envelope);\n return this.open(record.payload, aad);\n }\n\n /** §5.1 restore (CheckpointReseeder): re-POST the cached ciphertext byte-identical; false = none cached. */\n async reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean> {\n const envelope = await this.config.kv.get<string>(this.cacheKey(transferId, opIndex));\n if (envelope === null) return false;\n await this.post(transferId, opIndex, envelope);\n return true;\n }\n\n /** The ONE signed progress-append path put() and reseedCheckpoint() share. */\n private async post(\n transferId: string,\n opIndex: number,\n envelope: string\n ): Promise<{ opIndex: number; payload: string; createdAt: string }> {\n const signature = await this.config.signProgress(progressSignMessage(transferId, opIndex, envelope));\n return this.config.client.postProgress(transferId, opIndex, envelope, signature);\n }\n\n async get(transferId: string, opIndex: number): Promise<Uint8Array | null> {\n const records = await this.config.client.getProgress(transferId);\n const record = records.find((r) => r.opIndex === opIndex);\n if (record === undefined) return null;\n return this.open(record.payload, this.aad(transferId, opIndex));\n }\n\n private open(envelope: string, aad: Uint8Array): Uint8Array {\n try {\n return decryptFieldBytes(this.config.fieldKey, envelope, aad);\n } catch (err) {\n if (err instanceof SphereError && err.code === 'DECRYPTION_ERROR') {\n throw new SplitCheckpointLostError(\n 'split checkpoint record could not be decrypted (tampered or mis-served)',\n err\n );\n }\n throw err;\n }\n }\n}\n"],"mappings":";AAkBO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EACnC;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,QAAgB,MAAc,SAAiB,YAAqB;AAC9E,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,QAAI,eAAe,OAAW,MAAK,aAAa;AAAA,EAClD;AACF;AAGA,IAAM,qBAAqB,oBAAI,IAAI,CAAC,GAAG,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAElE,SAAS,kBAAkB,KAAuB;AACvD,SAAO,eAAe,sBAAsB,mBAAmB,IAAI,IAAI,MAAM;AAC/E;AAEO,SAAS,qBAAqB,KAAc,QAA4C;AAC7F,SAAO,eAAe,uBAAuB,WAAW,UAAa,IAAI,WAAW;AACtF;AAqBA,SAAS,eAAe,UAA2B;AACjD,SACE,aAAa,eACb,SAAS,SAAS,YAAY,KAC9B,mCAAmC,KAAK,QAAQ,KAChD,aAAa,SACb,aAAa;AAEjB;AAGO,SAAS,oBAAoB,SAAyB;AAC3D,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,OAAO;AAAA,EACvB,QAAQ;AACN,UAAM,IAAI,MAAM,gCAAgC,OAAO,EAAE;AAAA,EAC3D;AACA,QAAM,eAAe,IAAI,aAAa,WAAW,eAAe,IAAI,QAAQ;AAC5E,MAAI,IAAI,aAAa,YAAY,CAAC,cAAc;AAC9C,UAAM,IAAI,MAAM,4EAA4E;AAAA,EAC9F;AACA,SAAO,IAAI,SAAS,EAAE,QAAQ,OAAO,EAAE;AACzC;AAEA,SAAS,gBAAgB,KAA2C;AAClE,QAAM,MAAM,IAAI,SAAS,IAAI,aAAa;AAC1C,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,UAAU,OAAO,GAAG;AAC1B,MAAI,OAAO,SAAS,OAAO,EAAG,QAAO,KAAK,IAAI,GAAG,UAAU,GAAI;AAC/D,QAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,SAAO,OAAO,MAAM,IAAI,IAAI,SAAY,KAAK,IAAI,GAAG,OAAO,KAAK,IAAI,CAAC;AACvE;AAEA,eAAe,aAAa,KAAwC;AAClE,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAe,YAAY,KAAuB,MAA2C;AAC3F,MAAI,OAAO,QAAQ,IAAI,MAAM;AAC7B,MAAI,UAAU,GAAG,IAAI,uBAAuB,IAAI,MAAM;AACtD,QAAM,OAAO,MAAM,aAAa,GAAG;AACnC,MAAI,SAAS,IAAI;AACf,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,UAAI,QAAQ,OAAO,KAAM,QAAO,OAAO,MAAM;AAC7C,UAAI,QAAQ,OAAO,QAAS,WAAU,GAAG,IAAI,KAAK,OAAO,MAAM,OAAO;AAAA,IACxE,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,IAAI,mBAAmB,IAAI,QAAQ,MAAM,SAAS,gBAAgB,GAAG,CAAC;AAC/E;AAEA,SAAS,cAAc,MAAc,MAAc,QAAyB;AAC1E,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,UAAM,IAAI,mBAAmB,QAAQ,YAAY,GAAG,IAAI,wBAAwB;AAAA,EAClF;AACF;AAEO,SAAS,oBAAoB,QAA4C;AAC9E,QAAM,UAAU,oBAAoB,OAAO,OAAO;AAClD,QAAM,EAAE,SAAS,SAAS,IAAI;AAE9B,QAAM,WAAW,OAAO,KAAa,SAAqD;AACxF,QAAI;AACF,aAAO,MAAM,QAAQ,KAAK,IAAI;AAAA,IAChC,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,8BAA8B,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,GAAG,CAAC;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,OACd,QACA,MACA,MACA,SACqB;AACrB,UAAM,UAAkC,CAAC;AACzC,QAAI,SAAS,OAAW,SAAQ,cAAc,IAAI;AAClD,QAAI,MAAM,SAAS,OAAO;AACxB,YAAM,QAAQ,SAAS;AACvB,UAAI,UAAU,KAAM,SAAQ,eAAe,IAAI,UAAU,KAAK;AAAA,IAChE;AACA,UAAM,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,IAAI,IAAI;AAAA,MAC9C;AAAA,MACA;AAAA,MACA,GAAI,SAAS,SAAY,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE,IAAI,CAAC;AAAA,IAC7D,CAAC;AACD,UAAM,OAAO,GAAG,MAAM,IAAI,IAAI;AAC9B,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,QAAI,CAAC,IAAI,GAAI,OAAM,MAAM,YAAY,KAAK,IAAI;AAC9C,WAAO,cAAc,MAAM,aAAa,GAAG,GAAG,MAAM,IAAI,MAAM;AAAA,EAChE;AAEA,SAAO,EAAE,SAAS,SAAS,SAAS;AACtC;;;ACnDM,SAAU,QAAQ,GAAU;AAKhC,SACE,aAAa,cACZ,YAAY,OAAO,CAAC,KACnB,EAAE,YAAY,SAAS,gBACvB,uBAAuB,KACvB,EAAE,sBAAsB;AAE9B;AAcM,SAAU,QAAQ,GAAW,QAAgB,IAAE;AACnD,MAAI,OAAO,MAAM,UAAU;AACzB,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,IAAI,UAAU,GAAG,MAAM,wBAAwB,OAAO,CAAC,EAAE;EACjE;AACA,MAAI,CAAC,OAAO,cAAc,CAAC,KAAK,IAAI,GAAG;AACrC,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,IAAI,WAAW,GAAG,MAAM,8BAA8B,CAAC,EAAE;EACjE;AACF;AAgBM,SAAU,OACd,OACA,QACA,QAAgB,IAAE;AAElB,QAAM,QAAQ,QAAQ,KAAK;AAC3B,QAAM,MAAM,OAAO;AACnB,QAAM,WAAW,WAAW;AAC5B,MAAI,CAAC,SAAU,YAAY,QAAQ,QAAS;AAC1C,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,QAAQ,WAAW,cAAc,MAAM,KAAK;AAClD,UAAM,MAAM,QAAQ,UAAU,GAAG,KAAK,QAAQ,OAAO,KAAK;AAC1D,UAAM,UAAU,SAAS,wBAAwB,QAAQ,WAAW;AACpE,QAAI,CAAC;AAAO,YAAM,IAAI,UAAU,OAAO;AACvC,UAAM,IAAI,WAAW,OAAO;EAC9B;AACA,SAAO;AACT;AAkCM,SAAU,MAAM,GAAc;AAClC,MAAI,OAAO,MAAM,cAAc,OAAO,EAAE,WAAW;AACjD,UAAM,IAAI,UAAU,yCAAyC;AAC/D,UAAQ,EAAE,SAAS;AACnB,UAAQ,EAAE,QAAQ;AAGlB,MAAI,EAAE,YAAY;AAAG,UAAM,IAAI,MAAM,0BAA0B;AAC/D,MAAI,EAAE,WAAW;AAAG,UAAM,IAAI,MAAM,yBAAyB;AAC/D;AAgBM,SAAU,QAAQ,UAAe,gBAAgB,MAAI;AACzD,MAAI,SAAS;AAAW,UAAM,IAAI,MAAM,kCAAkC;AAC1E,MAAI,iBAAiB,SAAS;AAAU,UAAM,IAAI,MAAM,uCAAuC;AACjG;AAkBM,SAAU,QAAQ,KAAU,UAAa;AAC7C,SAAO,KAAK,QAAW,qBAAqB;AAC5C,QAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,KAAK;AACpB,UAAM,IAAI,WAAW,sDAAsD,GAAG;EAChF;AACF;AAkDM,SAAU,SAAS,QAA0B;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,WAAO,CAAC,EAAE,KAAK,CAAC;EAClB;AACF;AAYM,SAAU,WAAW,KAAqB;AAC9C,SAAO,IAAI,SAAS,IAAI,QAAQ,IAAI,YAAY,IAAI,UAAU;AAChE;AAaM,SAAU,KAAK,MAAc,OAAa;AAC9C,SAAQ,QAAS,KAAK,QAAW,SAAS;AAC5C;AAsFA,IAAM,gBAA0C;;EAE9C,OAAO,WAAW,KAAK,CAAA,CAAE,EAAE,UAAU,cAAc,OAAO,WAAW,YAAY;GAAW;AAG9F,IAAM,QAAwB,sBAAM,KAAK,EAAE,QAAQ,IAAG,GAAI,CAAC,GAAG,MAC5D,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAgB3B,SAAU,WAAW,OAAuB;AAChD,SAAO,KAAK;AAEZ,MAAI;AAAe,WAAO,MAAM,MAAK;AAErC,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,WAAO,MAAM,MAAM,CAAC,CAAC;EACvB;AACA,SAAO;AACT;AAGA,IAAM,SAAS,EAAE,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAG;AAC5D,SAAS,cAAc,IAAU;AAC/B,MAAI,MAAM,OAAO,MAAM,MAAM,OAAO;AAAI,WAAO,KAAK,OAAO;AAC3D,MAAI,MAAM,OAAO,KAAK,MAAM,OAAO;AAAG,WAAO,MAAM,OAAO,IAAI;AAC9D,MAAI,MAAM,OAAO,KAAK,MAAM,OAAO;AAAG,WAAO,MAAM,OAAO,IAAI;AAC9D;AACF;AAcM,SAAU,WAAW,KAAW;AACpC,MAAI,OAAO,QAAQ;AAAU,UAAM,IAAI,UAAU,8BAA8B,OAAO,GAAG;AACzF,MAAI,eAAe;AACjB,QAAI;AACF,aAAQ,WAAmB,QAAQ,GAAG;IACxC,SAAS,OAAO;AACd,UAAI,iBAAiB;AAAa,cAAM,IAAI,WAAW,MAAM,OAAO;AACpE,YAAM;IACR;EACF;AACA,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,KAAK;AAChB,MAAI,KAAK;AAAG,UAAM,IAAI,WAAW,qDAAqD,EAAE;AACxF,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,WAAS,KAAK,GAAG,KAAK,GAAG,KAAK,IAAI,MAAM,MAAM,GAAG;AAC/C,UAAM,KAAK,cAAc,IAAI,WAAW,EAAE,CAAC;AAC3C,UAAM,KAAK,cAAc,IAAI,WAAW,KAAK,CAAC,CAAC;AAC/C,QAAI,OAAO,UAAa,OAAO,QAAW;AACxC,YAAM,OAAO,IAAI,EAAE,IAAI,IAAI,KAAK,CAAC;AACjC,YAAM,IAAI,WACR,iDAAiD,OAAO,gBAAgB,EAAE;IAE9E;AACA,UAAM,EAAE,IAAI,KAAK,KAAK;EACxB;AACA,SAAO;AACT;AA+FM,SAAU,eAAe,QAA0B;AACvD,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,IAAI,OAAO,CAAC;AAClB,WAAO,CAAC;AACR,WAAO,EAAE;EACX;AACA,QAAM,MAAM,IAAI,WAAW,GAAG;AAC9B,WAAS,IAAI,GAAG,MAAM,GAAG,IAAI,OAAO,QAAQ,KAAK;AAC/C,UAAM,IAAI,OAAO,CAAC;AAClB,QAAI,IAAI,GAAG,GAAG;AACd,WAAO,EAAE;EACX;AACA,SAAO;AACT;AAqJM,SAAU,aACd,UACA,OAAuB,CAAA,GAAE;AAEzB,QAAM,QAAa,CAAC,KAAuB,SACzC,SAAS,IAAY,EAClB,OAAO,GAAG,EACV,OAAM;AACX,QAAM,MAAM,SAAS,MAAS;AAC9B,QAAM,YAAY,IAAI;AACtB,QAAM,WAAW,IAAI;AACrB,QAAM,SAAS,IAAI;AACnB,QAAM,SAAS,CAAC,SAAgB,SAAS,IAAI;AAC7C,SAAO,OAAO,OAAO,IAAI;AACzB,SAAO,OAAO,OAAO,KAAK;AAC5B;AAkBM,SAAU,YAAY,cAAc,IAAE;AAE1C,UAAQ,aAAa,aAAa;AAClC,QAAM,KAAK,OAAO,eAAe,WAAY,WAAmB,SAAS;AACzE,MAAI,OAAO,IAAI,oBAAoB;AACjC,UAAM,IAAI,MAAM,wCAAwC;AAM1D,MAAI,cAAc;AAChB,UAAM,IAAI,WAAW,wCAAwC,WAAW,EAAE;AAC5E,SAAO,GAAG,gBAAgB,IAAI,WAAW,WAAW,CAAC;AACvD;AAcO,IAAM,UAAU,CAAC,YAA8C;;;EAGpE,KAAK,WAAW,KAAK,CAAC,GAAM,GAAM,IAAM,KAAM,IAAM,GAAM,KAAM,GAAM,GAAM,GAAM,MAAM,CAAC;;;;AChzBrF,SAAU,IAAI,GAAW,GAAW,GAAS;AACjD,SAAQ,IAAI,IAAM,CAAC,IAAI;AACzB;AAeM,SAAU,IAAI,GAAW,GAAW,GAAS;AACjD,SAAQ,IAAI,IAAM,IAAI,IAAM,IAAI;AAClC;AAoBM,IAAgB,SAAhB,MAAsB;EASjB;EACA;EACA,SAAS;EACT;EACA;;EAGC;EACA;EACA,WAAW;EACX,SAAS;EACT,MAAM;EACN,YAAY;EAEtB,YAAY,UAAkB,WAAmB,WAAmBA,OAAa;AAC/E,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,OAAOA;AACZ,SAAK,SAAS,IAAI,WAAW,QAAQ;AACrC,SAAK,OAAO,WAAW,KAAK,MAAM;EACpC;EACA,OAAO,MAAsB;AAC3B,YAAQ,IAAI;AACZ,WAAO,IAAI;AACX,UAAM,EAAE,MAAM,QAAQ,SAAQ,IAAK;AACnC,UAAM,MAAM,KAAK;AACjB,aAAS,MAAM,GAAG,MAAM,OAAO;AAC7B,YAAM,OAAO,KAAK,IAAI,WAAW,KAAK,KAAK,MAAM,GAAG;AAGpD,UAAI,SAAS,UAAU;AACrB,cAAM,WAAW,WAAW,IAAI;AAChC,eAAO,YAAY,MAAM,KAAK,OAAO;AAAU,eAAK,QAAQ,UAAU,GAAG;AACzE;MACF;AACA,aAAO,IAAI,KAAK,SAAS,KAAK,MAAM,IAAI,GAAG,KAAK,GAAG;AACnD,WAAK,OAAO;AACZ,aAAO;AACP,UAAI,KAAK,QAAQ,UAAU;AACzB,aAAK,QAAQ,MAAM,CAAC;AACpB,aAAK,MAAM;MACb;IACF;AACA,SAAK,UAAU,KAAK;AACpB,SAAK,WAAU;AACf,WAAO;EACT;EACA,WAAW,KAAqB;AAC9B,YAAQ,IAAI;AACZ,YAAQ,KAAK,IAAI;AACjB,SAAK,WAAW;AAIhB,UAAM,EAAE,QAAQ,MAAM,UAAU,MAAAA,MAAI,IAAK;AACzC,QAAI,EAAE,IAAG,IAAK;AAEd,WAAO,KAAK,IAAI;AAChB,UAAM,KAAK,OAAO,SAAS,GAAG,CAAC;AAG/B,QAAI,KAAK,YAAY,WAAW,KAAK;AACnC,WAAK,QAAQ,MAAM,CAAC;AACpB,YAAM;IACR;AAEA,aAAS,IAAI,KAAK,IAAI,UAAU;AAAK,aAAO,CAAC,IAAI;AAIjD,SAAK,aAAa,WAAW,GAAG,OAAO,KAAK,SAAS,CAAC,GAAGA,KAAI;AAC7D,SAAK,QAAQ,MAAM,CAAC;AACpB,UAAM,QAAQ,WAAW,GAAG;AAC5B,UAAM,MAAM,KAAK;AAEjB,QAAI,MAAM;AAAG,YAAM,IAAI,MAAM,2CAA2C;AACxE,UAAM,SAAS,MAAM;AACrB,UAAM,QAAQ,KAAK,IAAG;AACtB,QAAI,SAAS,MAAM;AAAQ,YAAM,IAAI,MAAM,oCAAoC;AAC/E,aAAS,IAAI,GAAG,IAAI,QAAQ;AAAK,YAAM,UAAU,IAAI,GAAG,MAAM,CAAC,GAAGA,KAAI;EACxE;EACA,SAAM;AACJ,UAAM,EAAE,QAAQ,UAAS,IAAK;AAC9B,SAAK,WAAW,MAAM;AAGtB,UAAM,MAAM,OAAO,MAAM,GAAG,SAAS;AACrC,SAAK,QAAO;AACZ,WAAO;EACT;EACA,WAAW,IAAM;AACf,WAAO,IAAK,KAAK,YAAmB;AACpC,OAAG,IAAI,GAAG,KAAK,IAAG,CAAE;AACpB,UAAM,EAAE,UAAU,QAAQ,QAAQ,UAAU,WAAW,IAAG,IAAK;AAC/D,OAAG,YAAY;AACf,OAAG,WAAW;AACd,OAAG,SAAS;AACZ,OAAG,MAAM;AAGT,QAAI,SAAS;AAAU,SAAG,OAAO,IAAI,MAAM;AAC3C,WAAO;EACT;EACA,QAAK;AACH,WAAO,KAAK,WAAU;EACxB;;AAWK,IAAM,YAA+C,4BAAY,KAAK;EAC3E;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;CACrF;;;ACrLD,IAAM,WAA2B,4BAAY,KAAK;EAChD;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;CACrF;AAGD,IAAM,WAA2B,oBAAI,YAAY,EAAE;AAGnD,IAAe,WAAf,cAAuD,OAAS;EAY9D,YAAY,WAAiB;AAC3B,UAAM,IAAI,WAAW,GAAG,KAAK;EAC/B;EACU,MAAG;AACX,UAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC,IAAK;AACnC,WAAO,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;EAChC;;EAEU,IACR,GAAW,GAAW,GAAW,GAAW,GAAW,GAAW,GAAW,GAAS;AAEtF,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;EACf;EACU,QAAQ,MAAgB,QAAc;AAE9C,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK,UAAU;AAAG,eAAS,CAAC,IAAI,KAAK,UAAU,QAAQ,KAAK;AACpF,aAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,YAAM,MAAM,SAAS,IAAI,EAAE;AAC3B,YAAM,KAAK,SAAS,IAAI,CAAC;AACzB,YAAM,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,IAAK,QAAQ;AACnD,YAAM,KAAK,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAK,OAAO;AACjD,eAAS,CAAC,IAAK,KAAK,SAAS,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAK;IACjE;AAEA,QAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC,IAAK;AACjC,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,SAAS,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,GAAG,EAAE;AACpD,YAAM,KAAM,IAAI,SAAS,IAAI,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC,IAAI,SAAS,CAAC,IAAK;AACrE,YAAM,SAAS,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,GAAG,EAAE;AACpD,YAAM,KAAM,SAAS,IAAI,GAAG,GAAG,CAAC,IAAK;AACrC,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAK,IAAI,KAAM;AACf,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAK,KAAK,KAAM;IAClB;AAEA,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,SAAK,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;EACjC;EACU,aAAU;AAClB,UAAM,QAAQ;EAChB;EACA,UAAO;AAGL,SAAK,YAAY;AACjB,SAAK,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC/B,UAAM,KAAK,MAAM;EACnB;;AAII,IAAO,UAAP,cAAuB,SAAiB;;;EAGlC,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EACrC,cAAA;AACE,UAAM,EAAE;EACV;;AAsUK,IAAM,SAA+C;EAC1D,MAAM,IAAI,QAAO;EACD,wBAAQ,CAAI;AAAC;;;AC1R/B,SAAS,cAAc,OAA2B;AAChD,MAAI,MAAM;AACV,aAAW,KAAK,MAAO,QAAO,OAAO,aAAa,CAAC;AACnD,SAAO,KAAK,GAAG;AACjB;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,MAAqB;AAArB;AAAA,EAAsB;AAAA,EAEnD,IAAI,UAAkB;AACpB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA,EAIA,cAAc,QAA4C;AACxD,WAAO,KAAK,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,OAAO,GAAG,EAAE,MAAM,MAAM,CAAC;AAAA,EACpF;AAAA,EAEA,WAAW,OAAwF;AACjG,WAAO,KAAK,KAAK,QAAQ,QAAQ,mBAAmB,OAAO,EAAE,MAAM,MAAM,CAAC;AAAA,EAC5E;AAAA,EAEA,YAAY,cAA+C;AACzD,WAAO,KAAK,KAAK,QAAQ,QAAQ,oBAAoB,EAAE,aAAa,GAAG,EAAE,MAAM,MAAM,CAAC;AAAA,EACxF;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,KAAK,KAAK,QAAQ,QAAQ,mBAAmB,CAAC,CAAC;AAAA,EACvD;AAAA;AAAA,EAIA,cAAc,OAA4C;AACxD,UAAM,QAAQ,UAAU,SAAY,UAAU,KAAK,KAAK;AACxD,WAAO,KAAK,KAAK,QAAQ,OAAO,gBAAgB,KAAK,EAAE;AAAA,EACzD;AAAA,EAEA,MAAM,WAAmC;AACvC,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,OAAO,cAAc;AAC3D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,SAAS,UAA4C;AACzD,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,SAAS,CAAC;AAGlF,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,WAAW,OAAqE;AACpF,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,0BAA0B,EAAE,MAAM,CAAC;AAGjF,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,OAIsB;AAC1B,WAAO,KAAK,KAAK,QAAQ,QAAQ,uBAAuB,KAAK;AAAA,EAC/D;AAAA,EAEA,MAAM,UAAU,QAAqC;AACnD,UAAM,MAAM,MAAM,KAAK,KAAK,SAAS,QAAQ,EAAE,QAAQ,MAAM,CAAC;AAC9D,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,mBAAmB,IAAI,QAAQ,iBAAiB,oCAAoC,IAAI,MAAM,EAAE;AAAA,IAC5G;AACA,WAAO,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,QAAgB,OAAkC;AACjE,UAAM,MAAM,MAAM,KAAK,KAAK,SAAS,QAAQ;AAAA,MAC3C,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,yBAAyB,cAAc,OAAO,KAAK,CAAC;AAAA,QACpD,iBAAiB;AAAA,MACnB;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AACD,QAAI,IAAI,MAAM,IAAI,WAAW,IAAK;AAClC,UAAM,IAAI,mBAAmB,IAAI,QAAQ,eAAe,kCAAkC,IAAI,MAAM,EAAE;AAAA,EACxG;AAAA;AAAA,EAIA,MAAM,UAAU,YAAoB,iBAAyB,oBAAoB,OAAsB;AACrG,UAAM,OAAO,oBACT,EAAE,SAAS,iBAAiB,mBAAmB,KAAK,IACpD,EAAE,SAAS,gBAAgB;AAC/B,UAAM,KAAK,KAAK,QAAQ,OAAO,eAAe,UAAU,IAAI,IAAI;AAAA,EAClE;AAAA,EAEA,MAAM,YAAY,SAA6B,QAA+B;AAC5E,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,OAAO,sBAAsB,MAAM,EAAE;AAG3E,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,YAAY,YAAmC;AACnD,UAAM,KAAK,KAAK,QAAQ,QAAQ,eAAe,UAAU,QAAQ;AAAA,EACnE;AAAA,EAEA,MAAM,eAAe,YAAoB,WAAmC;AAC1E,UAAM,KAAK,KAAK;AAAA,MACd;AAAA,MACA,eAAe,UAAU;AAAA,MACzB,cAAc,SAAY,EAAE,UAAU,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,YACA,SACA,iBACA,WAC6B;AAC7B,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,eAAe,UAAU,aAAa;AAAA,MAClF;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,YAAY,YAAmD;AACnE,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,OAAO,eAAe,UAAU,WAAW;AAGjF,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,MAAM,QAAQ,OAA6C;AACzD,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,eAAe,KAAK;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,aAAa,SAA6E;AAC9F,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,QAAQ,CAAC;AAG9E,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,OAA0C;AACpD,UAAM,QAAQ,UAAU,SAAY,UAAU,KAAK,KAAK;AACxD,WAAO,KAAK,KAAK,QAAQ,OAAO,cAAc,KAAK,EAAE;AAAA,EACvD;AAAA,EAEA,MAAM,UAAoB,eAAkD;AAC1E,WAAO,KAAK,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,UAAU,cAAc,CAAC;AAAA,EACnF;AAAA,EAEA,MAAM,OAAO,UAAoB,QAA8B,QAAoC;AACjG,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,sBAAsB;AAAA,MAClE;AAAA,MACA,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,MACzC,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3C,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,MAAM,YAAY,SAA8E;AAC9F,WAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,eAAe,EAAE,QAAQ,CAAC;AAAA,EAIpE;AAAA,EAEA,YAAY,UAA+C,CAAC,GAA6B;AACvF,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,QAAQ,WAAW,OAAW,QAAO,IAAI,UAAU,QAAQ,MAAM;AACrE,QAAI,QAAQ,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC1E,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,KAAK,QAAQ,OAAO,cAAc,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EACpE;AAAA;AAAA,EAIA,qBAAqB,OAKW;AAC9B,WAAO,KAAK,KAAK,QAAQ,QAAQ,wBAAwB,KAAK;AAAA,EAChE;AAAA,EAEA,oBAAoB,QAAqE;AACvF,UAAM,QAAQ,IAAI,gBAAgB;AAClC,UAAM,IAAI,QAAQ,OAAO,IAAI;AAC7B,QAAI,OAAO,WAAW,OAAW,OAAM,IAAI,UAAU,OAAO,MAAM;AAClE,QAAI,OAAO,SAAS,YAAY;AAC9B,UAAI,OAAO,UAAU,OAAW,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAAA,IACzE,WAAW,OAAO,WAAW,QAAW;AACtC,YAAM,IAAI,UAAU,OAAO,MAAM;AAAA,IACnC;AACA,WAAO,KAAK,KAAK,QAAQ,OAAO,wBAAwB,MAAM,SAAS,CAAC,EAAE;AAAA,EAC5E;AAAA,EAEA,sBAAsB,IAAY,UAAmE;AACnG,WAAO,KAAK,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,YAAY,QAAQ;AAAA,EACjF;AAAA;AAAA,EAIA,MAAM,WAA4B;AAChC,UAAM,OAAQ,MAAM,KAAK,KAAK,QAAQ,QAAQ,eAAe;AAC7D,WAAO,KAAK;AAAA,EACd;AACF;;;AClWA,IAAM,aAAa;AAQnB,SAAS,WAAwB;AAC/B,QAAM,IAAI;AACV,MAAI,CAAC,EAAE,UAAU,GAAG;AAClB,MAAE,UAAU,IAAI,EAAE,OAAO,OAAO,MAAM,CAAC,GAAG,SAAS,KAAK;AAAA,EAC1D;AACA,SAAO,EAAE,UAAU;AACrB;AAEA,SAAS,UAAU,KAAsB;AACvC,QAAM,QAAQ,SAAS;AAEvB,MAAI,OAAO,MAAM,KAAM,QAAO,MAAM,KAAK,GAAG;AAE5C,SAAO,MAAM;AACf;AAEO,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,UAAU,QAA4B;AACpC,UAAM,QAAQ,SAAS;AACvB,QAAI,OAAO,UAAU,OAAW,OAAM,QAAQ,OAAO;AACrD,QAAI,OAAO,YAAY,OAAW,OAAM,UAAU,OAAO;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAY,KAAa,SAAwB;AAC/C,aAAS,EAAE,KAAK,GAAG,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,KAAmB;AAC/B,WAAO,SAAS,EAAE,KAAK,GAAG;AAAA,EAC5B;AAAA;AAAA,EAGA,eAAe,KAAuB;AACpC,QAAI,IAAK,QAAO,UAAU,GAAG;AAC7B,WAAO,SAAS,EAAE;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAa,YAAoB,MAAuB;AAC5D,QAAI,CAAC,UAAU,GAAG,EAAG;AACrB,UAAM,QAAQ,SAAS;AACvB,QAAI,MAAM,SAAS;AACjB,YAAM,QAAQ,SAAS,KAAK,SAAS,GAAG,IAAI;AAAA,IAC9C,OAAO;AACL,cAAQ,IAAI,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,KAAa,YAAoB,MAAuB;AAC3D,UAAM,QAAQ,SAAS;AACvB,QAAI,MAAM,SAAS;AACjB,YAAM,QAAQ,QAAQ,KAAK,SAAS,GAAG,IAAI;AAAA,IAC7C,OAAO;AACL,cAAQ,KAAK,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAa,YAAoB,MAAuB;AAC5D,UAAM,QAAQ,SAAS;AACvB,QAAI,MAAM,SAAS;AACjB,YAAM,QAAQ,SAAS,KAAK,SAAS,GAAG,IAAI;AAAA,IAC9C,OAAO;AACL,cAAQ,MAAM,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA,EAGA,QAAc;AACZ,UAAM,IAAI;AACV,WAAO,EAAE,UAAU;AAAA,EACrB;AACF;;;AC1BO,IAAM,aAAa;AAAA,EACxB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,cAAc,CAAC,MAAkB,UAAU,CAAC;AAAA,EAC5C,YAAY;AAAA;AAAA,EAEZ,gBAAgB;AAAA,EAChB,aAAa;AACf;;;ACHO,IAAMC,UAAS,CAA6B,OAAU,QAAiB,UAC5E,OAAQ,OAAO,QAAQ,KAAK;AAYvB,IAAMC,WAA2B;AAYjC,IAAMC,cAAiC;AAYvC,IAAMC,eAAc,IAAI,WAC7B,YAAa,GAAG,MAAM;AAYjB,IAAMC,cAAa,CAAC,QAAkC,WAAY,GAAG;AAYrE,IAAMC,WAA2B;AAYjC,IAAMC,eAAc,CAAC,gBAC1B,YAAa,WAAW;AAC1B,IAAM,MAAsB,uBAAO,CAAC;AACpC,IAAM,MAAsB,uBAAO,CAAC;AAyC9B,SAAU,MAAM,OAAgB,QAAgB,IAAE;AACtD,MAAI,OAAO,UAAU,WAAW;AAC9B,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,IAAI,UAAU,SAAS,gCAAgC,OAAO,KAAK;EAC3E;AACA,SAAO;AACT;AAcM,SAAU,WAAsC,GAAI;AACxD,MAAI,OAAO,MAAM,UAAU;AACzB,QAAI,CAAC,SAAS,CAAC;AAAG,YAAM,IAAI,WAAW,mCAAmC,CAAC;EAC7E;AAAO,IAAAL,SAAQ,CAAC;AAChB,SAAO;AACT;AAeM,SAAU,YAAY,OAAe,QAAgB,IAAE;AAC3D,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,IAAI,UAAU,SAAS,+BAA+B,OAAO,KAAK;EAC1E;AACA,MAAI,CAAC,OAAO,cAAc,KAAK,GAAG;AAChC,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,IAAI,WAAW,SAAS,gCAAgC,KAAK;EACrE;AACF;AAgBM,SAAU,oBAAoB,KAAoB;AACtD,QAAM,MAAM,WAAW,GAAG,EAAE,SAAS,EAAE;AACvC,SAAO,IAAI,SAAS,IAAI,MAAM,MAAM;AACtC;AAgBM,SAAU,YAAY,KAAW;AACrC,MAAI,OAAO,QAAQ;AAAU,UAAM,IAAI,UAAU,8BAA8B,OAAO,GAAG;AACzF,SAAO,QAAQ,KAAK,MAAM,OAAO,OAAO,GAAG;AAC7C;AAeM,SAAU,gBAAgB,OAAuB;AACrD,SAAO,YAAY,WAAY,KAAK,CAAC;AACvC;AAaM,SAAU,gBAAgB,OAAuB;AACrD,SAAO,YAAY,WAAY,UAAU,OAAQ,KAAK,CAAC,EAAE,QAAO,CAAE,CAAC;AACrE;AAeM,SAAU,gBAAgB,GAAoB,KAAW;AAC7D,UAAS,GAAG;AACZ,MAAI,QAAQ;AAAG,UAAM,IAAI,WAAW,aAAa;AACjD,MAAI,WAAW,CAAC;AAChB,QAAM,MAAM,EAAE,SAAS,EAAE;AAEzB,MAAI,IAAI,SAAS,MAAM;AAAG,UAAM,IAAI,WAAW,kBAAkB;AACjE,SAAO,WAAY,IAAI,SAAS,MAAM,GAAG,GAAG,CAAC;AAC/C;AAcM,SAAU,gBAAgB,GAAoB,KAAW;AAC7D,SAAO,gBAAgB,GAAG,GAAG,EAAE,QAAO;AACxC;AAoDM,SAAU,UAAU,OAAuB;AAG/C,SAAO,WAAW,KAAKM,QAAO,KAAK,CAAC;AACtC;AA8BA,IAAM,WAAW,CAAC,MAAc,OAAO,MAAM,YAAY,OAAO;AAe1D,SAAU,QAAQ,GAAW,KAAa,KAAW;AACzD,SAAO,SAAS,CAAC,KAAK,SAAS,GAAG,KAAK,SAAS,GAAG,KAAK,OAAO,KAAK,IAAI;AAC1E;AAkBM,SAAU,SAAS,OAAe,GAAW,KAAa,KAAW;AAMzE,MAAI,CAAC,QAAQ,GAAG,KAAK,GAAG;AACtB,UAAM,IAAI,WAAW,oBAAoB,QAAQ,OAAO,MAAM,aAAa,MAAM,WAAW,CAAC;AACjG;AAkBM,SAAU,OAAO,GAAS;AAG9B,MAAI,IAAI;AAAK,UAAM,IAAI,MAAM,uCAAuC,CAAC;AACrE,MAAI;AACJ,OAAK,MAAM,GAAG,IAAI,KAAK,MAAM,KAAK,OAAO;AAAE;AAC3C,SAAO;AACT;AAuDO,IAAM,UAAU,CAAC,OAAuB,OAAO,OAAO,CAAC,KAAK;AA0B7D,SAAU,eACd,SACA,UACA,QAAoB;AAEpB,UAAS,SAAS,SAAS;AAC3B,UAAS,UAAU,UAAU;AAC7B,MAAI,OAAO,WAAW;AAAY,UAAM,IAAI,UAAU,2BAA2B;AAEjF,QAAM,MAAM,CAAC,QAAkC,IAAI,WAAW,GAAG;AACjE,QAAM,OAAO,WAAW,GAAE;AAC1B,QAAM,QAAQ,WAAW,GAAG,CAAI;AAChC,QAAM,QAAQ,WAAW,GAAG,CAAI;AAChC,QAAM,gBAAgB;AAItB,MAAI,IAAgB,IAAI,OAAO;AAE/B,MAAI,IAAgB,IAAI,OAAO;AAC/B,MAAI,IAAI;AACR,QAAM,QAAQ,MAAK;AACjB,MAAE,KAAK,CAAC;AACR,MAAE,KAAK,CAAC;AACR,QAAI;EACN;AAEA,QAAM,IAAI,IAAI,SAA8B,OAAkB,GAAGC,aAAY,GAAG,GAAG,IAAI,CAAC;AACxF,QAAM,SAAS,CAAC,OAAyB,SAAQ;AAE/C,QAAI,EAAE,OAAO,IAAI;AACjB,QAAI,EAAC;AACL,QAAI,KAAK,WAAW;AAAG;AACvB,QAAI,EAAE,OAAO,IAAI;AACjB,QAAI,EAAC;EACP;AACA,QAAM,MAAM,MAAK;AAEf,QAAI,OAAO;AAAe,YAAM,IAAI,MAAM,sCAAsC;AAChF,QAAI,MAAM;AACV,UAAM,MAAoB,CAAA;AAC1B,WAAO,MAAM,UAAU;AACrB,UAAI,EAAC;AACL,YAAM,KAAK,EAAE,MAAK;AAClB,UAAI,KAAK,EAAE;AACX,aAAO,EAAE;IACX;AACA,WAAOA,aAAY,GAAG,GAAG;EAC3B;AACA,QAAM,WAAW,CAAC,MAAwB,SAA0B;AAClE,UAAK;AACL,WAAO,IAAI;AACX,QAAI,MAAqB;AAEzB,YAAQ,MAAO,KAAiB,IAAG,CAAE,OAAO;AAAW,aAAM;AAC7D,UAAK;AACL,WAAO;EACT;AACA,SAAO;AACT;AAiBM,SAAU,eACd,QACA,SAAiC,CAAA,GACjC,YAAoC,CAAA,GAAE;AAEtC,MAAI,OAAO,UAAU,SAAS,KAAK,MAAM,MAAM;AAC7C,UAAM,IAAI,UAAU,+BAA+B;AAErD,WAAS,WAAW,WAAiB,cAAsB,OAAc;AAGvE,QAAI,CAAC,SAAS,iBAAiB,cAAc,CAAC,OAAO,OAAO,QAAQ,SAAS;AAC3E,YAAM,IAAI,UAAU,UAAU,SAAS,qCAAqC;AAC9E,UAAM,MAAM,OAAO,SAAS;AAC5B,QAAI,SAAS,QAAQ;AAAW;AAChC,UAAM,UAAU,OAAO;AACvB,QAAI,YAAY,gBAAgB,QAAQ;AACtC,YAAM,IAAI,UACR,UAAU,SAAS,0BAA0B,YAAY,SAAS,OAAO,EAAE;EAEjF;AACA,QAAM,OAAO,CAAC,GAAkB,UAC9B,OAAO,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,WAAW,GAAG,GAAG,KAAK,CAAC;AAC/D,OAAK,QAAQ,KAAK;AAClB,OAAK,WAAW,IAAI;AACtB;;;AChtBA,IAAMC,OAAsB,uBAAO,CAAC;AAApC,IAAuCC,OAAsB,uBAAO,CAAC;AAArE,IAAwE,MAAsB,uBAAO,CAAC;AAEtG,IAAM,MAAsB,uBAAO,CAAC;AAApC,IAAuC,MAAsB,uBAAO,CAAC;AAArE,IAAwE,MAAsB,uBAAO,CAAC;AAEtG,IAAM,MAAsB,uBAAO,CAAC;AAApC,IAAuC,MAAsB,uBAAO,CAAC;AAArE,IAAwE,MAAsB,uBAAO,CAAC;AACtG,IAAM,OAAuB,uBAAO,EAAE;AAchC,SAAU,IAAI,GAAW,GAAS;AACtC,MAAI,KAAKD;AAAK,UAAM,IAAI,MAAM,yCAAyC,CAAC;AACxE,QAAM,SAAS,IAAI;AACnB,SAAO,UAAUA,OAAM,SAAS,IAAI;AACtC;AAsCM,SAAU,KAAK,GAAW,OAAe,QAAc;AAC3D,MAAI,QAAQE;AAAK,UAAM,IAAI,MAAM,+CAA+C,KAAK;AACrF,MAAI,MAAM;AACV,SAAO,UAAUA,MAAK;AACpB,WAAO;AACP,WAAO;EACT;AACA,SAAO;AACT;AAgBM,SAAU,OAAO,QAAgB,QAAc;AACnD,MAAI,WAAWA;AAAK,UAAM,IAAI,MAAM,kCAAkC;AACtE,MAAI,UAAUA;AAAK,UAAM,IAAI,MAAM,4CAA4C,MAAM;AAErF,MAAI,IAAI,IAAI,QAAQ,MAAM;AAC1B,MAAI,IAAI;AAER,MAAI,IAAIA,MAAK,IAAIC,MAAK,IAAIA,MAAK,IAAID;AACnC,SAAO,MAAMA,MAAK;AAChB,UAAM,IAAI,IAAI;AACd,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,IAAI,IAAI,IAAI;AAElB,QAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;EACzC;AACA,QAAM,MAAM;AACZ,MAAI,QAAQC;AAAK,UAAM,IAAI,MAAM,wBAAwB;AACzD,SAAO,IAAI,GAAG,MAAM;AACtB;AAEA,SAAS,eAAkB,IAAqB,MAAS,GAAI;AAC3D,QAAM,IAAI;AACV,MAAI,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AAAG,UAAM,IAAI,MAAM,yBAAyB;AACvE;AAMA,SAAS,UAAa,IAAqB,GAAI;AAC7C,QAAM,IAAI;AACV,QAAM,UAAU,EAAE,QAAQA,QAAO;AACjC,QAAM,OAAO,EAAE,IAAI,GAAG,MAAM;AAC5B,iBAAe,GAAG,MAAM,CAAC;AACzB,SAAO;AACT;AAIA,SAAS,UAAa,IAAqB,GAAI;AAC7C,QAAM,IAAI;AACV,QAAM,UAAU,EAAE,QAAQ,OAAO;AACjC,QAAM,KAAK,EAAE,IAAI,GAAG,GAAG;AACvB,QAAM,IAAI,EAAE,IAAI,IAAI,MAAM;AAC1B,QAAM,KAAK,EAAE,IAAI,GAAG,CAAC;AACrB,QAAM,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,GAAG,CAAC;AACjC,QAAM,OAAO,EAAE,IAAI,IAAI,EAAE,IAAI,GAAG,EAAE,GAAG,CAAC;AACtC,iBAAe,GAAG,MAAM,CAAC;AACzB,SAAO;AACT;AAIA,SAAS,WAAW,GAAS;AAC3B,QAAM,MAAM,MAAM,CAAC;AACnB,QAAM,KAAK,cAAc,CAAC;AAC1B,QAAM,KAAK,GAAG,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC;AACnC,QAAM,KAAK,GAAG,KAAK,EAAE;AACrB,QAAM,KAAK,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;AAC9B,QAAM,MAAM,IAAI,OAAO;AACvB,UAAQ,CAAI,IAAqB,MAAW;AAC1C,UAAM,IAAI;AACV,QAAI,MAAM,EAAE,IAAI,GAAG,EAAE;AACrB,QAAI,MAAM,EAAE,IAAI,KAAK,EAAE;AACvB,UAAM,MAAM,EAAE,IAAI,KAAK,EAAE;AACzB,UAAM,MAAM,EAAE,IAAI,KAAK,EAAE;AACzB,UAAM,KAAK,EAAE,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC;AAC9B,UAAM,KAAK,EAAE,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC;AAC9B,UAAM,EAAE,KAAK,KAAK,KAAK,EAAE;AACzB,UAAM,EAAE,KAAK,KAAK,KAAK,EAAE;AACzB,UAAM,KAAK,EAAE,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC;AAC9B,UAAM,OAAO,EAAE,KAAK,KAAK,KAAK,EAAE;AAChC,mBAAe,GAAG,MAAM,CAAC;AACzB,WAAO;EACT;AACF;AAoBM,SAAU,cAAc,GAAS;AAGrC,MAAI,IAAI;AAAK,UAAM,IAAI,MAAM,qCAAqC;AAElE,MAAI,IAAI,IAAIA;AACZ,MAAI,IAAI;AACR,SAAO,IAAI,QAAQD,MAAK;AACtB,SAAK;AACL;EACF;AAGA,MAAI,IAAI;AACR,QAAM,MAAM,MAAM,CAAC;AACnB,SAAO,WAAW,KAAK,CAAC,MAAM,GAAG;AAG/B,QAAI,MAAM;AAAM,YAAM,IAAI,MAAM,+CAA+C;EACjF;AAEA,MAAI,MAAM;AAAG,WAAO;AAIpB,MAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AACrB,QAAM,UAAU,IAAIC,QAAO;AAC3B,SAAO,SAAS,YAAe,IAAqB,GAAI;AACtD,UAAM,IAAI;AACV,QAAI,EAAE,IAAI,CAAC;AAAG,aAAO;AAErB,QAAI,WAAW,GAAG,CAAC,MAAM;AAAG,YAAM,IAAI,MAAM,yBAAyB;AAGrE,QAAI,IAAI;AACR,QAAI,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;AACvB,QAAI,IAAI,EAAE,IAAI,GAAG,CAAC;AAClB,QAAI,IAAI,EAAE,IAAI,GAAG,MAAM;AAIvB,WAAO,CAAC,EAAE,IAAI,GAAG,EAAE,GAAG,GAAG;AACvB,UAAI,EAAE,IAAI,CAAC;AAAG,eAAO,EAAE;AACvB,UAAI,IAAI;AAGR,UAAI,QAAQ,EAAE,IAAI,CAAC;AACnB,aAAO,CAAC,EAAE,IAAI,OAAO,EAAE,GAAG,GAAG;AAC3B;AACA,gBAAQ,EAAE,IAAI,KAAK;AACnB,YAAI,MAAM;AAAG,gBAAM,IAAI,MAAM,yBAAyB;MACxD;AAGA,YAAM,WAAWA,QAAO,OAAO,IAAI,IAAI,CAAC;AACxC,YAAM,IAAI,EAAE,IAAI,GAAG,QAAQ;AAG3B,UAAI;AACJ,UAAI,EAAE,IAAI,CAAC;AACX,UAAI,EAAE,IAAI,GAAG,CAAC;AACd,UAAI,EAAE,IAAI,GAAG,CAAC;IAChB;AACA,WAAO;EACT;AACF;AA0BM,SAAU,OAAO,GAAS;AAE9B,MAAI,IAAI,QAAQ;AAAK,WAAO;AAE5B,MAAI,IAAI,QAAQ;AAAK,WAAO;AAE5B,MAAI,IAAI,SAAS;AAAK,WAAO,WAAW,CAAC;AAEzC,SAAO,cAAc,CAAC;AACxB;AA6MA,IAAM,eAAe;EACnB;EAAU;EAAW;EAAO;EAAO;EAAO;EAAQ;EAClD;EAAO;EAAO;EAAO;EAAO;EAAO;EACnC;EAAQ;EAAQ;EAAQ;;AAgBpB,SAAU,cAAiB,OAAsB;AACrD,QAAM,UAAU;IACd,OAAO;IACP,OAAO;IACP,MAAM;;AAER,QAAM,OAAO,aAAa,OAAO,CAAC,KAAK,QAAe;AACpD,QAAI,GAAG,IAAI;AACX,WAAO;EACT,GAAG,OAAO;AACV,iBAAe,OAAO,IAAI;AAG1B,cAAY,MAAM,OAAO,OAAO;AAChC,cAAY,MAAM,MAAM,MAAM;AAG9B,MAAI,MAAM,QAAQ,KAAK,MAAM,OAAO;AAAG,UAAM,IAAI,MAAM,wCAAwC;AAC/F,MAAI,MAAM,SAASC;AAAK,UAAM,IAAI,MAAM,4CAA4C,MAAM,KAAK;AAC/F,SAAO;AACT;AAqBM,SAAU,MAAS,IAAqB,KAAQ,OAAa;AACjE,QAAM,IAAI;AACV,MAAI,QAAQC;AAAK,UAAM,IAAI,MAAM,yCAAyC;AAC1E,MAAI,UAAUA;AAAK,WAAO,EAAE;AAC5B,MAAI,UAAUD;AAAK,WAAO;AAC1B,MAAI,IAAI,EAAE;AACV,MAAI,IAAI;AACR,SAAO,QAAQC,MAAK;AAClB,QAAI,QAAQD;AAAK,UAAI,EAAE,IAAI,GAAG,CAAC;AAC/B,QAAI,EAAE,IAAI,CAAC;AACX,cAAUA;EACZ;AACA,SAAO;AACT;AAkBM,SAAU,cAAiB,IAAqB,MAAW,WAAW,OAAK;AAC/E,QAAM,IAAI;AACV,QAAM,WAAW,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,OAAO,MAAS;AAE1E,QAAM,gBAAgB,KAAK,OAAO,CAAC,KAAK,KAAK,MAAK;AAChD,QAAI,EAAE,IAAI,GAAG;AAAG,aAAO;AACvB,aAAS,CAAC,IAAI;AACd,WAAO,EAAE,IAAI,KAAK,GAAG;EACvB,GAAG,EAAE,GAAG;AAER,QAAM,cAAc,EAAE,IAAI,aAAa;AAEvC,OAAK,YAAY,CAAC,KAAK,KAAK,MAAK;AAC/B,QAAI,EAAE,IAAI,GAAG;AAAG,aAAO;AACvB,aAAS,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC;AACpC,WAAO,EAAE,IAAI,KAAK,GAAG;EACvB,GAAG,WAAW;AACd,SAAO;AACT;AA2CM,SAAU,WAAc,IAAqB,GAAI;AACrD,QAAM,IAAI;AAGV,QAAM,UAAU,EAAE,QAAQE,QAAO;AACjC,QAAM,UAAU,EAAE,IAAI,GAAG,MAAM;AAC/B,QAAM,MAAM,EAAE,IAAI,SAAS,EAAE,GAAG;AAChC,QAAM,OAAO,EAAE,IAAI,SAAS,EAAE,IAAI;AAClC,QAAM,KAAK,EAAE,IAAI,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC;AACtC,MAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;AAAI,UAAM,IAAI,MAAM,gCAAgC;AAC1E,SAAO,MAAM,IAAI,OAAO,IAAI;AAC9B;AA2CM,SAAU,QAAQ,GAAW,YAAmB;AAEpD,MAAI,eAAe;AAAW,IAAAC,SAAQ,UAAU;AAChD,MAAI,KAAKC;AAAK,UAAM,IAAI,MAAM,gDAAgD,CAAC;AAC/E,MAAI,eAAe,UAAa,aAAa;AAC3C,UAAM,IAAI,MAAM,yDAAyD,UAAU;AACrF,QAAM,OAAO,OAAO,CAAC;AAGrB,MAAI,eAAe,UAAa,aAAa;AAC3C,UAAM,IAAI,MAAM,0CAA0C,IAAI,kBAAkB,UAAU,GAAG;AAC/F,QAAM,cAAc,eAAe,SAAY,aAAa;AAC5D,QAAM,cAAc,KAAK,KAAK,cAAc,CAAC;AAC7C,SAAO,EAAE,YAAY,aAAa,YAAW;AAC/C;AAaA,IAAM,aAAa,oBAAI,QAAO;AAC9B,IAAM,SAAN,MAAY;EACD;EACA;EACA;EACA;EACA,OAAOA;EACP,MAAMC;EACN;EACQ;EACjB,YAAY,OAAe,OAAkB,CAAA,GAAE;AAG7C,QAAI,SAASA;AAAK,YAAM,IAAI,MAAM,4CAA4C,KAAK;AACnF,QAAI,cAAkC;AACtC,SAAK,OAAO;AACZ,QAAI,QAAQ,QAAQ,OAAO,SAAS,UAAU;AAE5C,UAAI,OAAO,KAAK,SAAS;AAAU,sBAAc,KAAK;AACtD,UAAI,OAAO,KAAK,SAAS;AAGvB,eAAO,eAAe,MAAM,QAAQ,EAAE,OAAO,KAAK,MAAM,YAAY,KAAI,CAAE;AAC5E,UAAI,OAAO,KAAK,SAAS;AAAW,aAAK,OAAO,KAAK;AACrD,UAAI,KAAK;AAAgB,aAAK,WAAW,OAAO,OAAO,KAAK,eAAe,MAAK,CAAE;AAClF,UAAI,OAAO,KAAK,iBAAiB;AAAW,aAAK,OAAO,KAAK;IAC/D;AACA,UAAM,EAAE,YAAY,YAAW,IAAK,QAAQ,OAAO,WAAW;AAC9D,QAAI,cAAc;AAAM,YAAM,IAAI,MAAM,gDAAgD;AACxF,SAAK,QAAQ;AACb,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,WAAO,OAAO,IAAI;EACpB;EAEA,OAAO,KAAW;AAChB,WAAO,IAAI,KAAK,KAAK,KAAK;EAC5B;EACA,QAAQ,KAAW;AACjB,QAAI,OAAO,QAAQ;AACjB,YAAM,IAAI,UAAU,iDAAiD,OAAO,GAAG;AACjF,WAAOD,QAAO,OAAO,MAAM,KAAK;EAClC;EACA,IAAI,KAAW;AACb,WAAO,QAAQA;EACjB;;EAEA,YAAY,KAAW;AACrB,WAAO,CAAC,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,GAAG;EAC3C;EACA,MAAM,KAAW;AACf,YAAQ,MAAMC,UAASA;EACzB;EACA,IAAI,KAAW;AACb,WAAO,IAAI,CAAC,KAAK,KAAK,KAAK;EAC7B;EACA,IAAI,KAAa,KAAW;AAC1B,WAAO,QAAQ;EACjB;EAEA,IAAI,KAAW;AACb,WAAO,IAAI,MAAM,KAAK,KAAK,KAAK;EAClC;EACA,IAAI,KAAa,KAAW;AAC1B,WAAO,IAAI,MAAM,KAAK,KAAK,KAAK;EAClC;EACA,IAAI,KAAa,KAAW;AAC1B,WAAO,IAAI,MAAM,KAAK,KAAK,KAAK;EAClC;EACA,IAAI,KAAa,KAAW;AAC1B,WAAO,IAAI,MAAM,KAAK,KAAK,KAAK;EAClC;EACA,IAAI,KAAa,OAAa;AAC5B,WAAO,MAAM,MAAM,KAAK,KAAK;EAC/B;EACA,IAAI,KAAa,KAAW;AAC1B,WAAO,IAAI,MAAM,OAAO,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK;EACtD;;EAGA,KAAK,KAAW;AACd,WAAO,MAAM;EACf;EACA,KAAK,KAAa,KAAW;AAC3B,WAAO,MAAM;EACf;EACA,KAAK,KAAa,KAAW;AAC3B,WAAO,MAAM;EACf;EACA,KAAK,KAAa,KAAW;AAC3B,WAAO,MAAM;EACf;EAEA,IAAI,KAAW;AACb,WAAO,OAAO,KAAK,KAAK,KAAK;EAC/B;EACA,KAAK,KAAW;AAGd,QAAI,OAAO,WAAW,IAAI,IAAI;AAC9B,QAAI,CAAC;AAAM,iBAAW,IAAI,MAAO,OAAO,OAAO,KAAK,KAAK,CAAE;AAC3D,WAAO,KAAK,MAAM,GAAG;EACvB;EACA,QAAQ,KAAW;AAIjB,WAAO,KAAK,OAAO,gBAAgB,KAAK,KAAK,KAAK,IAAI,gBAAgB,KAAK,KAAK,KAAK;EACvF;EACA,UAAU,OAAmB,iBAAiB,OAAK;AACjD,IAAAC,QAAO,KAAK;AACZ,UAAM,EAAE,UAAU,gBAAgB,OAAO,MAAAC,OAAM,OAAO,MAAM,aAAY,IAAK;AAC7E,QAAI,gBAAgB;AAGlB,UAAI,MAAM,SAAS,KAAK,CAAC,eAAe,SAAS,MAAM,MAAM,KAAK,MAAM,SAAS,OAAO;AACtF,cAAM,IAAI,MACR,+BAA+B,iBAAiB,iBAAiB,MAAM,MAAM;MAEjF;AACA,YAAM,SAAS,IAAI,WAAW,KAAK;AAEnC,aAAO,IAAI,OAAOA,QAAO,IAAI,OAAO,SAAS,MAAM,MAAM;AACzD,cAAQ;IACV;AACA,QAAI,MAAM,WAAW;AACnB,YAAM,IAAI,MAAM,+BAA+B,QAAQ,iBAAiB,MAAM,MAAM;AACtF,QAAI,SAASA,QAAO,gBAAgB,KAAK,IAAI,gBAAgB,KAAK;AAClE,QAAI;AAAc,eAAS,IAAI,QAAQ,KAAK;AAC5C,QAAI,CAAC;AACH,UAAI,CAAC,KAAK,QAAQ,MAAM;AACtB,cAAM,IAAI,MAAM,kDAAkD;;AAGtE,WAAO;EACT;;EAEA,YAAY,KAAa;AACvB,WAAO,cAAc,MAAM,GAAG;EAChC;;;EAGA,KAAK,GAAW,GAAW,WAAkB;AAG3C,UAAM,WAAW,WAAW;AAC5B,WAAO,YAAY,IAAI;EACzB;;AAIF,OAAO,OAAO,OAAO,SAAS;AA4BxB,SAAU,MAAM,OAAe,OAAkB,CAAA,GAAE;AACvD,SAAO,IAAI,OAAO,OAAO,IAAI;AAC/B;AAyEM,SAAU,oBAAoB,YAAkB;AACpD,MAAI,OAAO,eAAe;AAAU,UAAM,IAAI,MAAM,4BAA4B;AAEhF,MAAI,cAAcC;AAAK,UAAM,IAAI,MAAM,oCAAoC;AAE3E,QAAM,YAAY,OAAO,aAAaA,IAAG;AACzC,SAAO,KAAK,KAAK,YAAY,CAAC;AAChC;AAkBM,SAAU,iBAAiB,YAAkB;AACjD,QAAM,SAAS,oBAAoB,UAAU;AAC7C,SAAO,SAAS,KAAK,KAAK,SAAS,CAAC;AACtC;AAyBM,SAAU,eACd,KACA,YACAC,QAAO,OAAK;AAEZ,EAAAC,QAAO,GAAG;AACV,QAAM,MAAM,IAAI;AAChB,QAAM,WAAW,oBAAoB,UAAU;AAC/C,QAAM,SAAS,KAAK,IAAI,iBAAiB,UAAU,GAAG,EAAE;AAGxD,MAAI,MAAM,UAAU,MAAM;AACxB,UAAM,IAAI,MAAM,cAAc,SAAS,+BAA+B,GAAG;AAC3E,QAAM,MAAMD,QAAO,gBAAgB,GAAG,IAAI,gBAAgB,GAAG;AAE7D,QAAM,UAAU,IAAI,KAAK,aAAaD,IAAG,IAAIA;AAC7C,SAAOC,QAAO,gBAAgB,SAAS,QAAQ,IAAI,gBAAgB,SAAS,QAAQ;AACtF;;;ACliCA,IAAME,OAAsB,uBAAO,CAAC;AACpC,IAAMC,OAAsB,uBAAO,CAAC;AAuR9B,SAAU,SAAwC,WAAoB,MAAO;AACjF,QAAM,MAAM,KAAK,OAAM;AACvB,SAAO,YAAY,MAAM;AAC3B;AAoBM,SAAU,WACd,GACA,QAAW;AAEX,QAAM,aAAa,cACjB,EAAE,IACF,OAAO,IAAI,CAAC,MAAM,EAAE,CAAE,CAAC;AAEzB,SAAO,OAAO,IAAI,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,CAAC;AACrE;AAEA,SAAS,UAAU,GAAW,MAAY;AACxC,MAAI,CAAC,OAAO,cAAc,CAAC,KAAK,KAAK,KAAK,IAAI;AAC5C,UAAM,IAAI,MAAM,uCAAuC,OAAO,cAAc,CAAC;AACjF;AAcA,SAAS,UAAU,GAAW,YAAkB;AAC9C,YAAU,GAAG,UAAU;AACvB,QAAM,UAAU,KAAK,KAAK,aAAa,CAAC,IAAI;AAC5C,QAAM,aAAa,MAAM,IAAI;AAC7B,QAAM,YAAY,KAAK;AACvB,QAAM,OAAO,QAAQ,CAAC;AACtB,QAAM,UAAU,OAAO,CAAC;AACxB,SAAO,EAAE,SAAS,YAAY,MAAM,WAAW,QAAO;AACxD;AAEA,SAAS,YAAY,GAAW,QAAgB,OAAY;AAC1D,QAAM,EAAE,YAAY,MAAM,WAAW,QAAO,IAAK;AACjD,MAAI,QAAQ,OAAO,IAAI,IAAI;AAC3B,MAAI,QAAQ,KAAK;AAQjB,MAAI,QAAQ,YAAY;AAEtB,aAAS;AACT,aAASC;EACX;AACA,QAAM,cAAc,SAAS;AAC7B,QAAM,SAAS,cAAc,KAAK,IAAI,KAAK,IAAI;AAC/C,QAAM,SAAS,UAAU;AACzB,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,SAAS,MAAM;AAC9B,QAAM,UAAU;AAChB,SAAO,EAAE,OAAO,QAAQ,QAAQ,OAAO,QAAQ,QAAO;AACxD;AAkBA,IAAM,mBAAmB,oBAAI,QAAO;AACpC,IAAM,mBAAmB,oBAAI,QAAO;AAEpC,SAAS,KAAK,GAAM;AAIlB,SAAO,iBAAiB,IAAI,CAAC,KAAK;AACpC;AAEA,SAAS,QAAQ,GAAS;AAGxB,MAAI,MAAMC;AAAK,UAAM,IAAI,MAAM,cAAc;AAC/C;AA8BM,IAAO,OAAP,MAAW;EACE;EACA;EACA;EACR;;EAGT,YAAY,OAAW,MAAY;AACjC,SAAK,OAAO,MAAM;AAClB,SAAK,OAAO,MAAM;AAClB,SAAK,KAAK,MAAM;AAChB,SAAK,OAAO;EACd;;EAGA,cAAc,KAAe,GAAW,IAAc,KAAK,MAAI;AAC7D,QAAI,IAAc;AAClB,WAAO,IAAIA,MAAK;AACd,UAAI,IAAIC;AAAK,YAAI,EAAE,IAAI,CAAC;AACxB,UAAI,EAAE,OAAM;AACZ,YAAMA;IACR;AACA,WAAO;EACT;;;;;;;;;;;;;EAcQ,iBAAiB,OAAiB,GAAS;AACjD,UAAM,EAAE,SAAS,WAAU,IAAK,UAAU,GAAG,KAAK,IAAI;AACtD,UAAM,SAAqB,CAAA;AAC3B,QAAI,IAAc;AAClB,QAAI,OAAO;AACX,aAAS,SAAS,GAAG,SAAS,SAAS,UAAU;AAC/C,aAAO;AACP,aAAO,KAAK,IAAI;AAEhB,eAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,eAAO,KAAK,IAAI,CAAC;AACjB,eAAO,KAAK,IAAI;MAClB;AACA,UAAI,KAAK,OAAM;IACjB;AACA,WAAO;EACT;;;;;;;EAQQ,KAAK,GAAW,aAAyB,GAAS;AAExD,QAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;AAAG,YAAM,IAAI,MAAM,gBAAgB;AAEzD,QAAI,IAAI,KAAK;AACb,QAAI,IAAI,KAAK;AAMb,UAAM,KAAK,UAAU,GAAG,KAAK,IAAI;AACjC,aAAS,SAAS,GAAG,SAAS,GAAG,SAAS,UAAU;AAElD,YAAM,EAAE,OAAO,QAAQ,QAAQ,OAAO,QAAQ,QAAO,IAAK,YAAY,GAAG,QAAQ,EAAE;AACnF,UAAI;AACJ,UAAI,QAAQ;AAGV,YAAI,EAAE,IAAI,SAAS,QAAQ,YAAY,OAAO,CAAC,CAAC;MAClD,OAAO;AAEL,YAAI,EAAE,IAAI,SAAS,OAAO,YAAY,MAAM,CAAC,CAAC;MAChD;IACF;AACA,YAAQ,CAAC;AAIT,WAAO,EAAE,GAAG,EAAC;EACf;;;;;;;EAQQ,WACN,GACA,aACA,GACA,MAAgB,KAAK,MAAI;AAEzB,UAAM,KAAK,UAAU,GAAG,KAAK,IAAI;AACjC,aAAS,SAAS,GAAG,SAAS,GAAG,SAAS,UAAU;AAClD,UAAI,MAAMD;AAAK;AACf,YAAM,EAAE,OAAO,QAAQ,QAAQ,MAAK,IAAK,YAAY,GAAG,QAAQ,EAAE;AAClE,UAAI;AACJ,UAAI,QAAQ;AAGV;MACF,OAAO;AACL,cAAM,OAAO,YAAY,MAAM;AAC/B,cAAM,IAAI,IAAI,QAAQ,KAAK,OAAM,IAAK,IAAI;MAC5C;IACF;AACA,YAAQ,CAAC;AACT,WAAO;EACT;EAEQ,eAAe,GAAW,OAAiB,WAA4B;AAG7E,QAAI,OAAO,iBAAiB,IAAI,KAAK;AACrC,QAAI,CAAC,MAAM;AACT,aAAO,KAAK,iBAAiB,OAAO,CAAC;AACrC,UAAI,MAAM,GAAG;AAEX,YAAI,OAAO,cAAc;AAAY,iBAAO,UAAU,IAAI;AAC1D,yBAAiB,IAAI,OAAO,IAAI;MAClC;IACF;AACA,WAAO;EACT;EAEA,OACE,OACA,QACA,WAA4B;AAE5B,UAAM,IAAI,KAAK,KAAK;AACpB,WAAO,KAAK,KAAK,GAAG,KAAK,eAAe,GAAG,OAAO,SAAS,GAAG,MAAM;EACtE;EAEA,OAAO,OAAiB,QAAgB,WAA8B,MAAe;AACnF,UAAM,IAAI,KAAK,KAAK;AACpB,QAAI,MAAM;AAAG,aAAO,KAAK,cAAc,OAAO,QAAQ,IAAI;AAC1D,WAAO,KAAK,WAAW,GAAG,KAAK,eAAe,GAAG,OAAO,SAAS,GAAG,QAAQ,IAAI;EAClF;;;;EAKA,YAAY,GAAa,GAAS;AAChC,cAAU,GAAG,KAAK,IAAI;AACtB,qBAAiB,IAAI,GAAG,CAAC;AACzB,qBAAiB,OAAO,CAAC;EAC3B;EAEA,SAAS,KAAa;AACpB,WAAO,KAAK,GAAG,MAAM;EACvB;;AAoBI,SAAU,cACd,OACA,OACA,IACA,IAAU;AAEV,MAAI,MAAM;AACV,MAAI,KAAK,MAAM;AACf,MAAI,KAAK,MAAM;AACf,SAAO,KAAKA,QAAO,KAAKA,MAAK;AAC3B,QAAI,KAAKC;AAAK,WAAK,GAAG,IAAI,GAAG;AAC7B,QAAI,KAAKA;AAAK,WAAK,GAAG,IAAI,GAAG;AAC7B,UAAM,IAAI,OAAM;AAChB,WAAOA;AACP,WAAOA;EACT;AACA,SAAO,EAAE,IAAI,GAAE;AACjB;AAoLA,SAAS,YAAe,OAAe,OAAyBC,OAAc;AAC5E,MAAI,OAAO;AAIT,QAAI,MAAM,UAAU;AAAO,YAAM,IAAI,MAAM,gDAAgD;AAC3F,kBAAc,KAAK;AACnB,WAAO;EACT,OAAO;AACL,WAAO,MAAM,OAAO,EAAE,MAAAA,MAAI,CAAE;EAC9B;AACF;AAoCM,SAAU,kBACd,MACA,OACA,YAAoC,CAAA,GACpC,QAAgB;AAEhB,MAAI,WAAW;AAAW,aAAS,SAAS;AAC5C,MAAI,CAAC,SAAS,OAAO,UAAU;AAAU,UAAM,IAAI,MAAM,kBAAkB,IAAI,eAAe;AAC9F,aAAW,KAAK,CAAC,KAAK,KAAK,GAAG,GAAY;AACxC,UAAM,MAAM,MAAM,CAAC;AACnB,QAAI,EAAE,OAAO,QAAQ,YAAY,MAAMC;AACrC,YAAM,IAAI,MAAM,SAAS,CAAC,0BAA0B;EACxD;AACA,QAAM,KAAK,YAAY,MAAM,GAAG,UAAU,IAAI,MAAM;AACpD,QAAM,KAAK,YAAY,MAAM,GAAG,UAAU,IAAI,MAAM;AACpD,QAAM,KAAgB,SAAS,gBAAgB,MAAM;AACrD,QAAM,SAAS,CAAC,MAAM,MAAM,KAAK,EAAE;AACnC,aAAW,KAAK,QAAQ;AAEtB,QAAI,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC;AACtB,YAAM,IAAI,MAAM,SAAS,CAAC,0CAA0C;EACxE;AACA,UAAQ,OAAO,OAAO,OAAO,OAAO,CAAA,GAAI,KAAK,CAAC;AAC9C,SAAO,EAAE,OAAO,IAAI,GAAE;AACxB;AAoBM,SAAU,aACd,iBACA,cAA0C;AAE1C,SAAO,SAAS,OAAO,MAAuB;AAC5C,UAAM,YAAY,gBAAgB,IAAI;AACtC,WAAO,EAAE,WAAW,WAAW,aAAa,SAAS,EAAqB;EAC5E;AACF;;;AC93BM,IAAO,QAAP,MAAY;EAChB;EACA;EACA;EACA;EACA,SAAS;EACD,WAAW;EACX,YAAY;EAEpB,YAAY,MAAmB,KAAqB;AAClD,UAAM,IAAI;AACV,WAAO,KAAK,QAAW,KAAK;AAC5B,SAAK,QAAQ,KAAK,OAAM;AACxB,QAAI,OAAO,KAAK,MAAM,WAAW;AAC/B,YAAM,IAAI,MAAM,qDAAqD;AACvE,SAAK,WAAW,KAAK,MAAM;AAC3B,SAAK,YAAY,KAAK,MAAM;AAC5B,UAAM,WAAW,KAAK;AACtB,UAAM,MAAM,IAAI,WAAW,QAAQ;AAEnC,QAAI,IAAI,IAAI,SAAS,WAAW,KAAK,OAAM,EAAG,OAAO,GAAG,EAAE,OAAM,IAAK,GAAG;AACxE,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ;AAAK,UAAI,CAAC,KAAK;AAC/C,SAAK,MAAM,OAAO,GAAG;AAGrB,SAAK,QAAQ,KAAK,OAAM;AAExB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ;AAAK,UAAI,CAAC,KAAK,KAAO;AACtD,SAAK,MAAM,OAAO,GAAG;AACrB,UAAM,GAAG;EACX;EACA,OAAO,KAAqB;AAC1B,YAAQ,IAAI;AACZ,SAAK,MAAM,OAAO,GAAG;AACrB,WAAO;EACT;EACA,WAAW,KAAqB;AAC9B,YAAQ,IAAI;AACZ,YAAQ,KAAK,IAAI;AACjB,SAAK,WAAW;AAChB,UAAM,MAAM,IAAI,SAAS,GAAG,KAAK,SAAS;AAG1C,SAAK,MAAM,WAAW,GAAG;AACzB,SAAK,MAAM,OAAO,GAAG;AACrB,SAAK,MAAM,WAAW,GAAG;AACzB,SAAK,QAAO;EACd;EACA,SAAM;AACJ,UAAM,MAAM,IAAI,WAAW,KAAK,MAAM,SAAS;AAC/C,SAAK,WAAW,GAAG;AACnB,WAAO;EACT;EACA,WAAW,IAAa;AAGtB,WAAO,OAAO,OAAO,OAAO,eAAe,IAAI,GAAG,CAAA,CAAE;AACpD,UAAM,EAAE,OAAO,OAAO,UAAU,WAAW,UAAU,UAAS,IAAK;AACnE,SAAK;AACL,OAAG,WAAW;AACd,OAAG,YAAY;AACf,OAAG,WAAW;AACd,OAAG,YAAY;AACf,OAAG,QAAQ,MAAM,WAAW,GAAG,KAAK;AACpC,OAAG,QAAQ,MAAM,WAAW,GAAG,KAAK;AACpC,WAAO;EACT;EACA,QAAK;AACH,WAAO,KAAK,WAAU;EACxB;EACA,UAAO;AACL,SAAK,YAAY;AACjB,SAAK,MAAM,QAAO;AAClB,SAAK,MAAM,QAAO;EACpB;;AAqBK,IAAM,OAAsC,uBAAK;AACtD,QAAM,SAAS,CACb,MACA,KACA,YACqB,IAAI,MAAW,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,OAAM;AACvE,QAAM,SAAS,CAAC,MAAmB,QACjC,IAAI,MAAW,MAAM,GAAG;AAC1B,SAAO;AACT,GAAE;;;ACVF,IAAM,aAAa,CAAC,KAAa,SAAiB,OAAO,OAAO,IAAI,MAAM,CAAC,OAAOC,QAAO;AAenF,SAAU,iBAAiB,GAAW,OAAkB,GAAS;AAMrE,WAAS,UAAU,GAAGC,MAAK,CAAC;AAE5B,QAAM,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI;AAC7B,QAAM,KAAK,WAAW,KAAK,GAAG,CAAC;AAC/B,QAAM,KAAK,WAAW,CAAC,KAAK,GAAG,CAAC;AAGhC,MAAI,KAAK,IAAI,KAAK,KAAK,KAAK;AAC5B,MAAI,KAAK,CAAC,KAAK,KAAK,KAAK;AACzB,QAAM,QAAQ,KAAKA;AACnB,QAAM,QAAQ,KAAKA;AACnB,MAAI;AAAO,SAAK,CAAC;AACjB,MAAI;AAAO,SAAK,CAAC;AAIjB,QAAM,UAAU,QAAQ,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,IAAIC;AACpD,MAAI,KAAKD,QAAO,MAAM,WAAW,KAAKA,QAAO,MAAM,SAAS;AAC1D,UAAM,IAAI,MAAM,0CAA0C;EAC5D;AACA,SAAO,EAAE,OAAO,IAAI,OAAO,GAAE;AAC/B;AAwEA,SAAS,kBAAkB,QAAc;AACvC,MAAI,CAAC,CAAC,WAAW,aAAa,KAAK,EAAE,SAAS,MAAM;AAClD,UAAM,IAAI,MAAM,2DAA2D;AAC7E,SAAO;AACT;AAEA,SAAS,gBACP,MACA,KAAM;AAEN,iBAAe,IAAI;AACnB,QAAM,QAAQ,CAAA;AAId,WAAS,WAAW,OAAO,KAAK,GAAG,GAAkB;AAEnD,UAAM,OAAO,IAAI,KAAK,OAAO,MAAM,SAAY,IAAI,OAAO,IAAI,KAAK,OAAO;EAC5E;AACA,QAAM,MAAM,MAAO,MAAM;AACzB,QAAM,MAAM,SAAU,SAAS;AAC/B,MAAI,MAAM,WAAW;AAAW,sBAAkB,MAAM,MAAM;AAC9D,SAAO;AACT;AA2NM,IAAO,SAAP,cAAsB,MAAK;EAC/B,YAAY,IAAI,IAAE;AAChB,UAAM,CAAC;EACT;;AA4EK,IAAM,MAAY;;EAEvB,KAAK;;EAEL,MAAM;IACJ,QAAQ,CAAC,KAAa,SAAwB;AAC5C,YAAM,EAAE,KAAK,EAAC,IAAK;AACnB,kBAAY,KAAK,KAAK;AACtB,UAAI,MAAM,KAAK,MAAM;AAAK,cAAM,IAAI,EAAE,uBAAuB;AAC7D,UAAI,OAAO,SAAS;AAClB,cAAM,IAAI,UAAU,sCAAsC,OAAO,IAAI;AAGvE,UAAI,KAAK,SAAS;AAAG,cAAM,IAAI,EAAE,2BAA2B;AAC5D,YAAM,UAAU,KAAK,SAAS;AAC9B,YAAM,MAAM,oBAAoB,OAAO;AACvC,UAAK,IAAI,SAAS,IAAK;AAAa,cAAM,IAAI,EAAE,sCAAsC;AAEtF,YAAM,SAAS,UAAU,MAAM,oBAAqB,IAAI,SAAS,IAAK,GAAW,IAAI;AACrF,YAAM,IAAI,oBAAoB,GAAG;AACjC,aAAO,IAAI,SAAS,MAAM;IAC5B;;IAEA,OAAO,KAAa,MAAsB;AACxC,YAAM,EAAE,KAAK,EAAC,IAAK;AACnB,aAAOE,QAAO,MAAM,QAAW,UAAU;AACzC,UAAI,MAAM;AACV,UAAI,MAAM,KAAK,MAAM;AAAK,cAAM,IAAI,EAAE,uBAAuB;AAC7D,UAAI,KAAK,SAAS,KAAK,KAAK,KAAK,MAAM;AAAK,cAAM,IAAI,EAAE,uBAAuB;AAC/E,YAAM,QAAQ,KAAK,KAAK;AAExB,YAAM,SAAS,CAAC,EAAE,QAAQ;AAC1B,UAAI,SAAS;AACb,UAAI,CAAC;AAAQ,iBAAS;WACjB;AAEH,cAAM,SAAS,QAAQ;AACvB,YAAI,CAAC;AAAQ,gBAAM,IAAI,EAAE,mDAAmD;AAE5E,YAAI,SAAS;AAAG,gBAAM,IAAI,EAAE,0CAA0C;AACtE,cAAM,cAAc,KAAK,SAAS,KAAK,MAAM,MAAM;AACnD,YAAI,YAAY,WAAW;AAAQ,gBAAM,IAAI,EAAE,uCAAuC;AACtF,YAAI,YAAY,CAAC,MAAM;AAAG,gBAAM,IAAI,EAAE,sCAAsC;AAC5E,mBAAW,KAAK;AAAa,mBAAU,UAAU,IAAK;AACtD,eAAO;AACP,YAAI,SAAS;AAAK,gBAAM,IAAI,EAAE,wCAAwC;MACxE;AACA,YAAM,IAAI,KAAK,SAAS,KAAK,MAAM,MAAM;AACzC,UAAI,EAAE,WAAW;AAAQ,cAAM,IAAI,EAAE,gCAAgC;AACrE,aAAO,EAAE,GAAG,GAAG,KAAK,SAAS,MAAM,MAAM,EAAC;IAC5C;;;;;;EAMF,MAAM;IACJ,OAAO,KAAW;AAChB,YAAM,EAAE,KAAK,EAAC,IAAK;AACnB,iBAAW,GAAG;AACd,UAAI,MAAMF;AAAK,cAAM,IAAI,EAAE,4CAA4C;AACvE,UAAI,MAAM,oBAAoB,GAAG;AAEjC,UAAI,OAAO,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI;AAAQ,cAAM,OAAO;AACvD,UAAI,IAAI,SAAS;AAAG,cAAM,IAAI,EAAE,gDAAgD;AAChF,aAAO;IACT;IACA,OAAO,MAAsB;AAC3B,YAAM,EAAE,KAAK,EAAC,IAAK;AACnB,UAAI,KAAK,SAAS;AAAG,cAAM,IAAI,EAAE,kCAAkC;AACnE,UAAI,KAAK,CAAC,IAAI;AAAa,cAAM,IAAI,EAAE,qCAAqC;AAE5E,UAAI,KAAK,SAAS,KAAK,KAAK,CAAC,MAAM,KAAQ,EAAE,KAAK,CAAC,IAAI;AACrD,cAAM,IAAI,EAAE,qDAAqD;AACnE,aAAO,gBAAgB,IAAI;IAC7B;;EAEF,MAAM,OAAuB;AAE3B,UAAM,EAAE,KAAK,GAAG,MAAM,KAAK,MAAM,IAAG,IAAK;AACzC,UAAM,OAAOE,QAAO,OAAO,QAAW,WAAW;AACjD,UAAM,EAAE,GAAG,UAAU,GAAG,aAAY,IAAK,IAAI,OAAO,IAAM,IAAI;AAC9D,QAAI,aAAa;AAAQ,YAAM,IAAI,EAAE,6CAA6C;AAClF,UAAM,EAAE,GAAG,QAAQ,GAAG,WAAU,IAAK,IAAI,OAAO,GAAM,QAAQ;AAC9D,UAAM,EAAE,GAAG,QAAQ,GAAG,WAAU,IAAK,IAAI,OAAO,GAAM,UAAU;AAChE,QAAI,WAAW;AAAQ,YAAM,IAAI,EAAE,6CAA6C;AAChF,WAAO,EAAE,GAAG,IAAI,OAAO,MAAM,GAAG,GAAG,IAAI,OAAO,MAAM,EAAC;EACvD;EACA,WAAW,KAA6B;AACtC,UAAM,EAAE,MAAM,KAAK,MAAM,IAAG,IAAK;AACjC,UAAM,KAAK,IAAI,OAAO,GAAM,IAAI,OAAO,IAAI,CAAC,CAAC;AAC7C,UAAM,KAAK,IAAI,OAAO,GAAM,IAAI,OAAO,IAAI,CAAC,CAAC;AAC7C,UAAM,MAAM,KAAK;AACjB,WAAO,IAAI,OAAO,IAAM,GAAG;EAC7B;;AAEF,OAAO,OAAO,IAAI,IAAI;AACtB,OAAO,OAAO,IAAI,IAAI;AACtB,OAAO,OAAO,GAAG;AAIjB,IAAMF,OAAsB,uBAAO,CAAC;AAApC,IAAuCC,OAAsB,uBAAO,CAAC;AAArE,IAAwEF,OAAsB,uBAAO,CAAC;AAAtG,IAAyGI,OAAsB,uBAAO,CAAC;AAAvI,IAA0IC,OAAsB,uBAAO,CAAC;AA2BlK,SAAU,YACd,QACA,YAAqC,CAAA,GAAE;AAEvC,QAAM,YAAY,kBAAkB,eAAe,QAAQ,SAAS;AACpE,QAAM,KAAK,UAAU;AACrB,QAAM,KAAK,UAAU;AACrB,MAAI,QAAQ,UAAU;AACtB,QAAM,EAAE,GAAG,UAAU,GAAGC,aAAW,IAAK;AACxC,iBACE,WACA,CAAA,GACA;IACE,oBAAoB;IACpB,eAAe;IACf,eAAe;IACf,WAAW;IACX,SAAS;IACT,MAAM;GACP;AAKH,QAAM,EAAE,MAAM,mBAAkB,IAAK;AACrC,MAAI,MAAM;AAER,QAAI,CAAC,GAAG,IAAI,MAAM,CAAC,KAAK,OAAO,KAAK,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK,OAAO,GAAG;AACrF,YAAM,IAAI,MAAM,4DAA4D;IAC9E;EACF;AAEA,QAAM,UAAU,YAAY,IAAuB,EAAE;AAErD,WAAS,+BAA4B;AACnC,QAAI,CAAC,GAAG;AAAO,YAAM,IAAI,MAAM,4DAA4D;EAC7F;AAGA,WAAS,aACP,IACA,OACA,cAAqB;AAIrB,QAAI,sBAAsB,MAAM,IAAG;AAAI,aAAO,WAAW,GAAG,CAAC;AAC7D,UAAM,EAAE,GAAG,EAAC,IAAK,MAAM,SAAQ;AAC/B,UAAM,KAAK,GAAG,QAAQ,CAAC;AACvB,UAAM,cAAc,cAAc;AAClC,QAAI,cAAc;AAChB,mCAA4B;AAC5B,YAAM,WAAW,CAAC,GAAG,MAAO,CAAC;AAC7B,aAAOC,aAAY,QAAQ,QAAQ,GAAG,EAAE;IAC1C,OAAO;AACL,aAAOA,aAAY,WAAW,GAAG,CAAI,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC;IAC3D;EACF;AACA,WAAS,eAAe,OAAuB;AAC7C,IAAAJ,QAAO,OAAO,QAAW,OAAO;AAChC,UAAM,EAAE,WAAW,MAAM,uBAAuB,OAAM,IAAK;AAC3D,UAAM,SAAS,MAAM;AACrB,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,OAAO,MAAM,SAAS,CAAC;AAC7B,QAAI,sBAAsB,WAAW,KAAK,SAAS;AAAM,aAAO,EAAE,GAAG,GAAG,MAAM,GAAG,GAAG,KAAI;AAOxF,QAAI,WAAW,SAAS,SAAS,KAAQ,SAAS,IAAO;AACvD,YAAM,IAAI,GAAG,UAAU,IAAI;AAC3B,UAAI,CAAC,GAAG,QAAQ,CAAC;AAAG,cAAM,IAAI,MAAM,qCAAqC;AACzE,YAAM,KAAK,oBAAoB,CAAC;AAChC,UAAI;AACJ,UAAI;AACF,YAAI,GAAG,KAAK,EAAE;MAChB,SAAS,WAAW;AAClB,cAAM,MAAM,qBAAqB,QAAQ,OAAO,UAAU,UAAU;AACpE,cAAM,IAAI,MAAM,2CAA2C,GAAG;MAChE;AACA,mCAA4B;AAC5B,YAAM,QAAQ,GAAG,MAAO,CAAC;AACzB,YAAM,SAAS,OAAO,OAAO;AAC7B,UAAI,UAAU;AAAO,YAAI,GAAG,IAAI,CAAC;AACjC,aAAO,EAAE,GAAG,EAAC;IACf,WAAW,WAAW,UAAU,SAAS,GAAM;AAE7C,YAAM,IAAI,GAAG;AACb,YAAM,IAAI,GAAG,UAAU,KAAK,SAAS,GAAG,CAAC,CAAC;AAC1C,YAAM,IAAI,GAAG,UAAU,KAAK,SAAS,GAAG,IAAI,CAAC,CAAC;AAC9C,UAAI,CAAC,UAAU,GAAG,CAAC;AAAG,cAAM,IAAI,MAAM,4BAA4B;AAClE,aAAO,EAAE,GAAG,EAAC;IACf,OAAO;AACL,YAAM,IAAI,MACR,yBAAyB,MAAM,yBAAyB,IAAI,oBAAoB,MAAM,EAAE;IAE5F;EACF;AAEA,QAAM,cAAc,UAAU,YAAY,SAAY,eAAe,UAAU;AAC/E,QAAM,cAAc,UAAU,cAAc,SAAY,iBAAiB,UAAU;AACnF,WAAS,oBAAoB,GAAI;AAC/B,UAAM,KAAK,GAAG,IAAI,CAAC;AACnB,UAAM,KAAK,GAAG,IAAI,IAAI,CAAC;AACvB,WAAO,GAAG,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC;EACvD;AAIA,WAAS,UAAU,GAAM,GAAI;AAC3B,UAAM,OAAO,GAAG,IAAI,CAAC;AACrB,UAAM,QAAQ,oBAAoB,CAAC;AACnC,WAAO,GAAG,IAAI,MAAM,KAAK;EAC3B;AAKA,MAAI,CAAC,UAAU,MAAM,IAAI,MAAM,EAAE;AAAG,UAAM,IAAI,MAAM,mCAAmC;AAIvF,QAAM,OAAO,GAAG,IAAI,GAAG,IAAI,MAAM,GAAGC,IAAG,GAAGC,IAAG;AAC7C,QAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;AAChD,MAAI,GAAG,IAAI,GAAG,IAAI,MAAM,KAAK,CAAC;AAAG,UAAM,IAAI,MAAM,0BAA0B;AAG3E,WAAS,OAAO,OAAe,GAAM,UAAU,OAAK;AAClD,QAAI,CAAC,GAAG,QAAQ,CAAC,KAAM,WAAW,GAAG,IAAI,CAAC;AAAI,YAAM,IAAI,MAAM,wBAAwB,KAAK,EAAE;AAC7F,WAAO;EACT;AAEA,WAAS,UAAU,OAAc;AAC/B,QAAI,EAAE,iBAAiB;AAAQ,YAAM,IAAI,MAAM,4BAA4B;EAC7E;AAEA,WAAS,iBAAiB,GAAS;AACjC,QAAI,CAAC,QAAQ,CAAC,KAAK;AAAS,YAAM,IAAI,MAAM,SAAS;AACrD,WAAO,iBAAiB,GAAG,KAAK,SAAS,GAAG,KAAK;EACnD;AAEA,WAAS,WACP,UACA,KACA,KACA,OACA,OAAc;AAEd,UAAM,IAAI,MAAM,GAAG,IAAI,IAAI,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;AACrD,UAAM,SAAS,OAAO,GAAG;AACzB,UAAM,SAAS,OAAO,GAAG;AACzB,WAAO,IAAI,IAAI,GAAG;EACpB;EAOA,MAAM,MAAK;;IAET,OAAgB,OAAO,IAAI,MAAM,MAAM,IAAI,MAAM,IAAI,GAAG,GAAG;;IAE3D,OAAgB,OAAO,IAAI,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI;;;IAEzD,OAAgB,KAAK;;IAErB,OAAgB,KAAK;IAEZ;IACA;IACA;;IAGT,YAAY,GAAM,GAAM,GAAI;AAC1B,WAAK,IAAI,OAAO,KAAK,CAAC;AAItB,WAAK,IAAI,OAAO,KAAK,GAAG,IAAI;AAC5B,WAAK,IAAI,OAAO,KAAK,CAAC;AACtB,aAAO,OAAO,IAAI;IACpB;IAEA,OAAO,QAAK;AACV,aAAO;IACT;;IAGA,OAAO,WAAW,GAAiB;AACjC,YAAM,EAAE,GAAG,EAAC,IAAK,KAAK,CAAA;AACtB,UAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;AAAG,cAAM,IAAI,MAAM,sBAAsB;AAClF,UAAI,aAAa;AAAO,cAAM,IAAI,MAAM,8BAA8B;AAEtE,UAAI,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;AAAG,eAAO,MAAM;AACzC,aAAO,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG;IAC/B;IAEA,OAAO,UAAU,OAAuB;AACtC,YAAM,IAAI,MAAM,WAAW,YAAYF,QAAO,OAAO,QAAW,OAAO,CAAC,CAAC;AACzE,QAAE,eAAc;AAChB,aAAO;IACT;IAEA,OAAO,QAAQ,KAAW;AACxB,aAAO,MAAM,UAAUK,YAAW,GAAG,CAAC;IACxC;IAEA,IAAI,IAAC;AACH,aAAO,KAAK,SAAQ,EAAG;IACzB;IACA,IAAI,IAAC;AACH,aAAO,KAAK,SAAQ,EAAG;IACzB;;;;;;;IAQA,WAAW,aAAqB,GAAG,SAAS,MAAI;AAC9C,WAAK,YAAY,MAAM,UAAU;AACjC,UAAI,CAAC;AAAQ,aAAK,SAASJ,IAAG;AAC9B,aAAO;IACT;;;IAIA,iBAAc;AACZ,YAAM,IAAI;AACV,UAAI,EAAE,IAAG,GAAI;AAKX,YAAI,UAAU,sBAAsB,GAAG,IAAI,EAAE,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC;AAClF;AACF,cAAM,IAAI,MAAM,iBAAiB;MACnC;AAEA,YAAM,EAAE,GAAG,EAAC,IAAK,EAAE,SAAQ;AAC3B,UAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;AAAG,cAAM,IAAI,MAAM,sCAAsC;AAC5F,UAAI,CAAC,UAAU,GAAG,CAAC;AAAG,cAAM,IAAI,MAAM,mCAAmC;AACzE,UAAI,CAAC,EAAE,cAAa;AAAI,cAAM,IAAI,MAAM,wCAAwC;IAClF;IAEA,WAAQ;AACN,YAAM,EAAE,EAAC,IAAK,KAAK,SAAQ;AAC3B,UAAI,CAAC,GAAG;AAAO,cAAM,IAAI,MAAM,6BAA6B;AAC5D,aAAO,CAAC,GAAG,MAAM,CAAC;IACpB;;IAGA,OAAO,OAA0B;AAC/B,gBAAU,KAAK;AACf,YAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAE,IAAK;AAChC,YAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAE,IAAK;AAChC,YAAM,KAAK,GAAG,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AAChD,YAAM,KAAK,GAAG,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AAChD,aAAO,MAAM;IACf;;IAGA,SAAM;AACJ,aAAO,IAAI,MAAM,KAAK,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC;IACjD;;;;;IAMA,SAAM;AACJ,YAAM,EAAE,GAAG,EAAC,IAAK;AACjB,YAAM,KAAK,GAAG,IAAI,GAAGA,IAAG;AACxB,YAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAE,IAAK;AAChC,UAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,KAAK,GAAG;AACxC,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,GAAG,EAAE;AACjB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,GAAG,EAAE;AACjB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,GAAG,EAAE;AACjB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,aAAO,IAAI,MAAM,IAAI,IAAI,EAAE;IAC7B;;;;;IAMA,IAAI,OAA0B;AAC5B,gBAAU,KAAK;AACf,YAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAE,IAAK;AAChC,YAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAE,IAAK;AAChC,UAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,KAAK,GAAG;AACxC,YAAM,IAAI,MAAM;AAChB,YAAM,KAAK,GAAG,IAAI,MAAM,GAAGA,IAAG;AAC9B,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,UAAI,KAAK,GAAG,IAAI,IAAI,EAAE;AACtB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,GAAG,EAAE;AACjB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,GAAG,EAAE;AACjB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,GAAG,EAAE;AACjB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,WAAK,GAAG,IAAI,IAAI,EAAE;AAClB,aAAO,IAAI,MAAM,IAAI,IAAI,EAAE;IAC7B;IAEA,SAAS,OAA0B;AAGjC,gBAAU,KAAK;AACf,aAAO,KAAK,IAAI,MAAM,OAAM,CAAE;IAChC;IAEA,MAAG;AACD,aAAO,KAAK,OAAO,MAAM,IAAI;IAC/B;;;;;;;;;;IAWA,SAAS,QAAc;AACrB,YAAM,EAAE,MAAAK,MAAI,IAAK;AAIjB,UAAI,CAAC,GAAG,YAAY,MAAM;AAAG,cAAM,IAAI,WAAW,8BAA8B;AAChF,UAAI,OAAc;AAClB,YAAM,MAAM,CAAC,MAAc,KAAK,OAAO,MAAM,GAAG,CAAC,MAAM,WAAW,OAAO,CAAC,CAAC;AAE3E,UAAIA,OAAM;AACR,cAAM,EAAE,OAAO,IAAI,OAAO,GAAE,IAAK,iBAAiB,MAAM;AACxD,cAAM,EAAE,GAAG,KAAK,GAAG,IAAG,IAAK,IAAI,EAAE;AACjC,cAAM,EAAE,GAAG,KAAK,GAAG,IAAG,IAAK,IAAI,EAAE;AACjC,eAAO,IAAI,IAAI,GAAG;AAClB,gBAAQ,WAAWA,MAAK,MAAM,KAAK,KAAK,OAAO,KAAK;MACtD,OAAO;AACL,cAAM,EAAE,GAAG,EAAC,IAAK,IAAI,MAAM;AAC3B,gBAAQ;AACR,eAAO;MACT;AAEA,aAAO,WAAW,OAAO,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;IAC3C;;;;;;IAOA,eAAe,QAAc;AAC3B,YAAM,EAAE,MAAAA,MAAI,IAAK;AACjB,YAAM,IAAI;AACV,YAAM,KAAK;AAGX,UAAI,CAAC,GAAG,QAAQ,EAAE;AAAG,cAAM,IAAI,WAAW,8BAA8B;AACxE,UAAI,OAAOR,QAAO,EAAE,IAAG;AAAI,eAAO,MAAM;AACxC,UAAI,OAAOC;AAAK,eAAO;AACvB,UAAI,KAAK,SAAS,IAAI;AAAG,eAAO,KAAK,SAAS,EAAE;AAGhD,UAAIO,OAAM;AACR,cAAM,EAAE,OAAO,IAAI,OAAO,GAAE,IAAK,iBAAiB,EAAE;AACpD,cAAM,EAAE,IAAI,GAAE,IAAK,cAAc,OAAO,GAAG,IAAI,EAAE;AACjD,eAAO,WAAWA,MAAK,MAAM,IAAI,IAAI,OAAO,KAAK;MACnD,OAAO;AACL,eAAO,KAAK,OAAO,GAAG,EAAE;MAC1B;IACF;;;;;;IAOA,SAAS,WAAa;AACpB,YAAM,IAAI;AACV,UAAI,KAAK;AACT,YAAM,EAAE,GAAG,GAAG,EAAC,IAAK;AAEpB,UAAI,GAAG,IAAI,GAAG,GAAG,GAAG;AAAG,eAAO,EAAE,GAAG,GAAG,GAAG,EAAC;AAC1C,YAAM,MAAM,EAAE,IAAG;AAGjB,UAAI,MAAM;AAAM,aAAK,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAC5C,YAAM,IAAI,GAAG,IAAI,GAAG,EAAE;AACtB,YAAM,IAAI,GAAG,IAAI,GAAG,EAAE;AACtB,YAAM,KAAK,GAAG,IAAI,GAAG,EAAE;AACvB,UAAI;AAAK,eAAO,EAAE,GAAG,GAAG,MAAM,GAAG,GAAG,KAAI;AACxC,UAAI,CAAC,GAAG,IAAI,IAAI,GAAG,GAAG;AAAG,cAAM,IAAI,MAAM,kBAAkB;AAC3D,aAAO,EAAE,GAAG,EAAC;IACf;;;;;IAMA,gBAAa;AACX,YAAM,EAAE,cAAa,IAAK;AAC1B,UAAI,aAAaP;AAAK,eAAO;AAC7B,UAAI;AAAe,eAAO,cAAc,OAAO,IAAI;AACnD,aAAO,KAAK,OAAO,MAAMI,YAAW,EAAE,IAAG;IAC3C;IAEA,gBAAa;AACX,YAAM,EAAE,cAAa,IAAK;AAC1B,UAAI,aAAaJ;AAAK,eAAO;AAC7B,UAAI;AAAe,eAAO,cAAc,OAAO,IAAI;AAInD,aAAO,KAAK,eAAe,QAAQ;IACrC;IAEA,eAAY;AACV,UAAI,aAAaA;AAAK,eAAO,KAAK,IAAG;AACrC,aAAO,KAAK,cAAa,EAAG,IAAG;IACjC;IAEA,QAAQ,eAAe,MAAI;AACzB,YAAM,cAAc,cAAc;AAGlC,WAAK,eAAc;AACnB,aAAO,YAAY,OAAO,MAAM,YAAY;IAC9C;IAEA,MAAM,eAAe,MAAI;AACvB,aAAOQ,YAAW,KAAK,QAAQ,YAAY,CAAC;IAC9C;IAEA,WAAQ;AACN,aAAO,UAAU,KAAK,IAAG,IAAK,SAAS,KAAK,MAAK,CAAE;IACrD;;AAEF,QAAM,OAAO,GAAG;AAChB,QAAM,OAAO,IAAI,KAAK,OAAO,UAAU,OAAO,KAAK,KAAK,OAAO,CAAC,IAAI,IAAI;AAGxE,MAAI,QAAQ;AAAG,UAAM,KAAK,WAAW,CAAC;AACtC,SAAO,OAAO,MAAM,SAAS;AAC7B,SAAO,OAAO,KAAK;AACnB,SAAO;AACT;AA6DA,SAAS,QAAQ,UAAiB;AAChC,SAAO,WAAW,GAAG,WAAW,IAAO,CAAI;AAC7C;AA4LA,SAAS,YAAe,IAAqB,IAAwB;AACnE,SAAO;IACL,WAAW,GAAG;IACd,WAAW,IAAI,GAAG;IAClB,uBAAuB,IAAI,IAAI,GAAG;IAClC,oBAAoB;;;IAGpB,WAAW,IAAI,GAAG;;AAEtB;AAoBM,SAAU,KACd,OACA,WAA+E,CAAA,GAAE;AAEjF,QAAM,EAAE,GAAE,IAAK;AACf,QAAM,eAAe,SAAS,gBAAgB,SAAYC,eAAgB,SAAS;AAGnF,QAAM,UAAU,OAAO,OAAO,YAAY,MAAM,IAAI,EAAE,GAAG;IACvD,MAAM,KAAK,IAAI,iBAAiB,GAAG,KAAK,GAAG,EAAE;GAC9C;AAED,WAAS,iBAAiB,WAA2B;AACnD,QAAI;AACF,YAAM,MAAM,GAAG,UAAU,SAAS;AAClC,aAAO,GAAG,YAAY,GAAG;IAC3B,SAAS,OAAO;AACd,aAAO;IACT;EACF;AAEA,WAAS,iBAAiB,WAA6B,cAAsB;AAC3E,UAAM,EAAE,WAAW,MAAM,sBAAqB,IAAK;AACnD,QAAI;AACF,YAAM,IAAI,UAAU;AACpB,UAAI,iBAAiB,QAAQ,MAAM;AAAM,eAAO;AAChD,UAAI,iBAAiB,SAAS,MAAM;AAAuB,eAAO;AAClE,aAAO,CAAC,CAAC,MAAM,UAAU,SAAS;IACpC,SAAS,OAAO;AACd,aAAO;IACT;EACF;AAMA,WAAS,gBAAgB,MAAuB;AAC9C,WAAO,SAAS,SAAY,aAAa,QAAQ,IAAI,IAAI;AACzD,WAAO,eAAeC,QAAO,MAAM,QAAQ,MAAM,MAAM,GAAG,GAAG,KAAK;EACpE;AAOA,WAAS,aAAa,WAA6B,eAAe,MAAI;AACpE,WAAO,MAAM,KAAK,SAAS,GAAG,UAAU,SAAS,CAAC,EAAE,QAAQ,YAAY;EAC1E;AAKA,WAAS,UAAU,MAAsB;AACvC,UAAM,EAAE,WAAW,WAAW,sBAAqB,IAAK;AACxD,UAAM,iBAAkB,GAAwC;AAChE,QAAI,CAACC,SAAQ,IAAI;AAAG,aAAO;AAC3B,UAAM,IAAID,QAAO,MAAM,QAAW,KAAK,EAAE;AACzC,UAAM,QAAQ,MAAM,aAAa,MAAM;AACvC,UAAM,QAAQ,MAAM,aAAa,CAAC,CAAC,gBAAgB,SAAS,CAAC;AAE7D,QAAI,SAAS;AAAO,aAAO;AAC3B,WAAO;EACT;AAcA,WAAS,gBACP,YACA,YACA,eAAe,MAAI;AAEnB,QAAI,UAAU,UAAU,MAAM;AAAM,YAAM,IAAI,MAAM,+BAA+B;AACnF,QAAI,UAAU,UAAU,MAAM;AAAO,YAAM,IAAI,MAAM,+BAA+B;AACpF,UAAM,IAAI,GAAG,UAAU,UAAU;AACjC,UAAM,IAAI,MAAM,UAAU,UAAU;AACpC,WAAO,EAAE,SAAS,CAAC,EAAE,QAAQ,YAAY;EAC3C;AAEA,QAAM,QAAQ;IACZ;IACA;IACA;;AAEF,QAAM,SAAS,aAAa,iBAAiB,YAAY;AACzD,SAAO,OAAO,KAAK;AACnB,SAAO,OAAO,OAAO;AAErB,SAAO,OAAO,OAAO,EAAE,cAAc,iBAAiB,QAAQ,OAAO,OAAO,QAAO,CAAE;AACvF;AA6BM,SAAU,MACd,OACA,MACA,YAA6B,CAAA,GAAE;AAG/B,QAAM,QAAQ;AACd,QAAM,KAAK;AACX,iBACE,WACA,CAAA,GACA;IACE,MAAM;IACN,MAAM;IACN,aAAa;IACb,UAAU;IACV,eAAe;GAChB;AAEH,cAAY,OAAO,OAAO,CAAA,GAAI,SAAS;AACvC,QAAMD,eAAc,UAAU,gBAAgB,SAAYA,eAAgB,UAAU;AACpF,QAAMG,QACJ,UAAU,SAAS,SACf,CAAC,KAAuB,QAA0B,KAAU,OAAO,KAAK,GAAG,IAC1E,UAAU;AAEjB,QAAM,EAAE,IAAI,GAAE,IAAK;AACnB,QAAM,EAAE,OAAOC,cAAa,MAAM,OAAM,IAAK;AAC7C,QAAM,EAAE,QAAQ,cAAc,iBAAiB,OAAO,QAAO,IAAK,KAAK,OAAO,SAAS;AACvF,QAAM,iBAA0C;IAC9C,SAAS;IACT,MAAM,OAAO,UAAU,SAAS,YAAY,UAAU,OAAO;IAC7D,QAAQ;IACR,cAAc;;AAMhB,QAAM,wBAAwBA,eAAcC,OAAMC,OAAM,GAAG;AAE3D,WAAS,sBAAsB,QAAc;AAC3C,UAAM,OAAOF,gBAAeE;AAC5B,WAAO,SAAS;EAClB;AACA,WAAS,WAAW,OAAe,KAAW;AAC5C,QAAI,CAAC,GAAG,YAAY,GAAG;AACrB,YAAM,IAAI,MAAM,qBAAqB,KAAK,kCAAkC;AAC9E,WAAO;EACT;AACA,WAAS,yBAAsB;AAQ7B,QAAI;AACF,YAAM,IAAI,MAAM,8DAA8D;EAClF;AACA,WAAS,kBAAkB,OAAyB,QAA4B;AAC9E,sBAAkB,MAAM;AACxB,UAAM,OAAO,QAAQ;AACrB,UAAM,QAAQ,WAAW,YAAY,OAAO,WAAW,cAAc,OAAO,IAAI;AAChF,WAAOL,QAAO,OAAO,KAAK;EAC5B;EAKA,MAAMM,WAAS;IACJ;IACA;IACA;IAET,YAAY,GAAW,GAAW,UAAiB;AACjD,WAAK,IAAI,WAAW,KAAK,CAAC;AAC1B,WAAK,IAAI,WAAW,KAAK,CAAC;AAC1B,UAAI,YAAY,MAAM;AACpB,+BAAsB;AACtB,YAAI,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,SAAS,QAAQ;AAAG,gBAAM,IAAI,MAAM,qBAAqB;AAC3E,aAAK,WAAW;MAClB;AACA,aAAO,OAAO,IAAI;IACpB;IAEA,OAAO,UACL,OACA,SAA+B,eAAe,QAAM;AAEpD,wBAAkB,OAAO,MAAM;AAC/B,UAAI;AACJ,UAAI,WAAW,OAAO;AACpB,cAAM,EAAE,GAAAC,IAAG,GAAAC,GAAC,IAAK,IAAI,MAAMR,QAAO,KAAK,CAAC;AACxC,eAAO,IAAIM,WAAUC,IAAGC,EAAC;MAC3B;AACA,UAAI,WAAW,aAAa;AAC1B,gBAAQ,MAAM,CAAC;AACf,iBAAS;AACT,gBAAQ,MAAM,SAAS,CAAC;MAC1B;AACA,YAAM,IAAI,QAAQ,YAAa;AAC/B,YAAM,IAAI,MAAM,SAAS,GAAG,CAAC;AAC7B,YAAM,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC;AACjC,aAAO,IAAIF,WAAU,GAAG,UAAU,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,KAAK;IAC9D;IAEA,OAAO,QAAQ,KAAa,QAA6B;AACvD,aAAO,KAAK,UAAUG,YAAW,GAAG,GAAG,MAAM;IAC/C;IAEQ,iBAAc;AACpB,YAAM,EAAE,SAAQ,IAAK;AACrB,UAAI,YAAY;AAAM,cAAM,IAAI,MAAM,sCAAsC;AAC5E,aAAO;IACT;IAEA,eAAe,UAAgB;AAC7B,aAAO,IAAIH,WAAU,KAAK,GAAG,KAAK,GAAG,QAAQ;IAC/C;;;IAIA,iBAAiB,aAA6B;AAC5C,YAAM,EAAE,GAAG,EAAC,IAAK;AACjB,YAAM,WAAW,KAAK,eAAc;AACpC,YAAM,OAAO,aAAa,KAAK,aAAa,IAAI,IAAIH,eAAc;AAClE,UAAI,CAAC,GAAG,QAAQ,IAAI;AAAG,cAAM,IAAI,MAAM,2CAA2C;AAClF,YAAM,IAAI,GAAG,QAAQ,IAAI;AACzB,YAAM,IAAI,MAAM,UAAUO,aAAY,SAAS,WAAW,OAAO,CAAC,GAAG,CAAC,CAAC;AACvE,YAAM,KAAK,GAAG,IAAI,IAAI;AACtB,YAAM,IAAI,cAAcV,QAAO,aAAa,QAAW,SAAS,CAAC;AACjE,YAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE;AAC5B,YAAM,KAAK,GAAG,OAAO,IAAI,EAAE;AAE3B,YAAM,IAAI,MAAM,KAAK,eAAe,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AAChE,UAAI,EAAE,IAAG;AAAI,cAAM,IAAI,MAAM,qCAAqC;AAClE,QAAE,eAAc;AAChB,aAAO;IACT;;IAGA,WAAQ;AACN,aAAO,sBAAsB,KAAK,CAAC;IACrC;IAEA,QAAQ,SAA+B,eAAe,QAAM;AAC1D,wBAAkB,MAAM;AACxB,UAAI,WAAW;AAAO,eAAOS,YAAW,IAAI,WAAW,IAAI,CAAC;AAC5D,YAAM,EAAE,GAAG,EAAC,IAAK;AACjB,YAAM,KAAK,GAAG,QAAQ,CAAC;AACvB,YAAM,KAAK,GAAG,QAAQ,CAAC;AACvB,UAAI,WAAW,aAAa;AAC1B,+BAAsB;AACtB,eAAOC,aAAY,WAAW,GAAG,KAAK,eAAc,CAAE,GAAG,IAAI,EAAE;MACjE;AACA,aAAOA,aAAY,IAAI,EAAE;IAC3B;IAEA,MAAM,QAA6B;AACjC,aAAOC,YAAW,KAAK,QAAQ,MAAM,CAAC;IACxC;;AAGF,SAAO,OAAOL,WAAU,SAAS;AACjC,SAAO,OAAOA,UAAS;AAMvB,QAAM,WACJ,UAAU,aAAa,SACnB,SAAS,aAAa,OAAuB;AAE3C,QAAI,MAAM,SAAS;AAAM,YAAM,IAAI,MAAM,oBAAoB;AAG7D,UAAM,MAAM,gBAAgB,KAAK;AACjC,UAAM,QAAQ,MAAM,SAAS,IAAI;AACjC,WAAO,QAAQ,IAAI,OAAO,OAAO,KAAK,IAAI;EAC5C,IACC,UAAU;AACjB,QAAM,gBACJ,UAAU,kBAAkB,SACxB,SAAS,kBAAkB,OAAuB;AAChD,WAAO,GAAG,OAAO,SAAS,KAAK,CAAC;EAClC,IACC,UAAU;AACjB,QAAM,aAAa,QAAQ,MAAM;AAGjC,WAAS,WAAW,KAAW;AAC7B,aAAS,aAAa,QAAQ,KAAKM,MAAK,UAAU;AAClD,WAAO,GAAG,QAAQ,GAAG;EACvB;AAEA,WAAS,mBAAmB,SAA2B,SAAgB;AACrE,IAAAZ,QAAO,SAAS,QAAW,SAAS;AACpC,WACE,UAAUA,QAAO,MAAM,OAAO,GAAG,QAAW,mBAAmB,IAAI;EAEvE;AAUA,WAAS,QACP,SACA,WACA,MAAyB;AAEzB,UAAM,EAAE,MAAM,SAAS,aAAY,IAAK,gBAAgB,MAAM,cAAc;AAC5E,cAAU,mBAAmB,SAAS,OAAO;AAI7C,UAAM,QAAQ,cAAc,OAAO;AACnC,UAAM,IAAI,GAAG,UAAU,SAAS;AAChC,QAAI,CAAC,GAAG,YAAY,CAAC;AAAG,YAAM,IAAI,MAAM,qBAAqB;AAC7D,UAAM,WAA+B,CAAC,WAAW,CAAC,GAAG,WAAW,KAAK,CAAC;AAEtE,QAAI,gBAAgB,QAAQ,iBAAiB,OAAO;AAGlD,YAAM,IAAI,iBAAiB,OAAOD,aAAY,QAAQ,SAAS,IAAI;AACnE,eAAS,KAAKC,QAAO,GAAG,QAAW,cAAc,CAAC;IACpD;AACA,UAAM,OAAOU,aAAY,GAAG,QAAQ;AACpC,UAAM,IAAI;AASV,aAAS,MAAM,QAAwB;AAGrC,YAAM,IAAI,SAAS,MAAM;AACzB,UAAI,CAAC,GAAG,YAAY,CAAC;AAAG;AACxB,YAAM,KAAK,GAAG,IAAI,CAAC;AACnB,YAAM,IAAI,MAAM,KAAK,SAAS,CAAC,EAAE,SAAQ;AACzC,YAAM,IAAI,GAAG,OAAO,EAAE,CAAC;AACvB,UAAI,MAAME;AAAK;AACf,YAAM,IAAI,GAAG,OAAO,KAAK,GAAG,OAAO,IAAI,IAAI,CAAC,CAAC;AAC7C,UAAI,MAAMA;AAAK;AACf,UAAI,YAAY,EAAE,MAAM,IAAI,IAAI,KAAK,OAAO,EAAE,IAAIP,IAAG;AACrD,UAAI,QAAQ;AACZ,UAAI,QAAQ,sBAAsB,CAAC,GAAG;AACpC,gBAAQ,GAAG,IAAI,CAAC;AAChB,oBAAY;MACd;AACA,aAAO,IAAIC,WAAU,GAAG,OAAO,wBAAwB,SAAY,QAAQ;IAC7E;AACA,WAAO,EAAE,MAAM,MAAK;EACtB;AAeA,WAAS,KACP,SACA,WACA,OAA4B,CAAA,GAAE;AAE9B,UAAM,EAAE,MAAM,MAAK,IAAK,QAAQ,SAAS,WAAW,IAAI;AACxD,UAAM,OAAO,eAA0B,MAAM,WAAW,GAAG,OAAOJ,KAAI;AACtE,UAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,WAAO,IAAI,QAAQ,KAAK,MAAM;EAChC;AAeA,WAAS,OACP,WACA,SACA,WACA,OAA8B,CAAA,GAAE;AAEhC,UAAM,EAAE,MAAM,SAAS,OAAM,IAAK,gBAAgB,MAAM,cAAc;AACtE,gBAAYF,QAAO,WAAW,QAAW,WAAW;AACpD,cAAU,mBAAmB,SAAS,OAAO;AAC7C,QAAI,CAACC,SAAQ,SAAgB,GAAG;AAC9B,YAAM,MAAM,qBAAqBK,aAAY,wBAAwB;AACrE,YAAM,IAAI,MAAM,wCAAwC,GAAG;IAC7D;AACA,sBAAkB,WAAW,MAAM;AACnC,QAAI;AACF,YAAM,MAAMA,WAAU,UAAU,WAAW,MAAM;AACjD,YAAM,IAAI,MAAM,UAAU,SAAS;AACnC,UAAI,QAAQ,IAAI,SAAQ;AAAI,eAAO;AACnC,YAAM,EAAE,GAAG,EAAC,IAAK;AACjB,YAAM,IAAI,cAAc,OAAO;AAC/B,YAAM,KAAK,GAAG,IAAI,CAAC;AACnB,YAAM,KAAK,GAAG,OAAO,IAAI,EAAE;AAC3B,YAAM,KAAK,GAAG,OAAO,IAAI,EAAE;AAC3B,YAAM,IAAI,MAAM,KAAK,eAAe,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AAChE,UAAI,EAAE,IAAG;AAAI,eAAO;AACpB,YAAM,IAAI,GAAG,OAAO,EAAE,CAAC;AACvB,aAAO,MAAM;IACf,SAAS,GAAG;AACV,aAAO;IACT;EACF;AAEA,WAAS,iBACP,WACA,SACA,OAA+B,CAAA,GAAE;AAIjC,UAAM,EAAE,QAAO,IAAK,gBAAgB,MAAM,cAAc;AACxD,cAAU,mBAAmB,SAAS,OAAO;AAC7C,WAAOA,WAAU,UAAU,WAAW,WAAW,EAAE,iBAAiB,OAAO,EAAE,QAAO;EACtF;AAEA,SAAO,OAAO,OAAO;IACnB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,WAAAA;IACA,MAAM;GACP;AACH;;;AC73DA,IAAM,kBAA2C;EAC/C,GAAG,OAAO,oEAAoE;EAC9E,GAAG,OAAO,oEAAoE;EAC9E,GAAG,OAAO,CAAC;EACX,GAAG,OAAO,CAAC;EACX,GAAG,OAAO,CAAC;EACX,IAAI,OAAO,oEAAoE;EAC/E,IAAI,OAAO,oEAAoE;;AAGjF,IAAM,iBAAmC;EACvC,MAAM,OAAO,oEAAoE;EACjF,SAAS;IACP,CAAC,OAAO,oCAAoC,GAAG,CAAC,OAAO,oCAAoC,CAAC;IAC5F,CAAC,OAAO,qCAAqC,GAAG,OAAO,oCAAoC,CAAC;;;AAKhG,IAAMO,OAAsB,uBAAO,CAAC;AAMpC,SAAS,QAAQ,GAAS;AACxB,QAAM,IAAI,gBAAgB;AAE1B,QAAMC,OAAM,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,OAAO,EAAE,GAAG,OAAO,OAAO,EAAE;AAE3E,QAAM,OAAO,OAAO,EAAE,GAAG,OAAO,OAAO,EAAE,GAAG,OAAO,OAAO,EAAE;AAC5D,QAAM,KAAM,IAAI,IAAI,IAAK;AACzB,QAAM,KAAM,KAAK,KAAK,IAAK;AAC3B,QAAM,KAAM,KAAK,IAAIA,MAAK,CAAC,IAAI,KAAM;AACrC,QAAM,KAAM,KAAK,IAAIA,MAAK,CAAC,IAAI,KAAM;AACrC,QAAM,MAAO,KAAK,IAAID,MAAK,CAAC,IAAI,KAAM;AACtC,QAAM,MAAO,KAAK,KAAK,MAAM,CAAC,IAAI,MAAO;AACzC,QAAM,MAAO,KAAK,KAAK,MAAM,CAAC,IAAI,MAAO;AACzC,QAAM,MAAO,KAAK,KAAK,MAAM,CAAC,IAAI,MAAO;AACzC,QAAM,OAAQ,KAAK,KAAK,MAAM,CAAC,IAAI,MAAO;AAC1C,QAAM,OAAQ,KAAK,MAAM,MAAM,CAAC,IAAI,MAAO;AAC3C,QAAM,OAAQ,KAAK,MAAMC,MAAK,CAAC,IAAI,KAAM;AACzC,QAAM,KAAM,KAAK,MAAM,MAAM,CAAC,IAAI,MAAO;AACzC,QAAM,KAAM,KAAK,IAAI,KAAK,CAAC,IAAI,KAAM;AACrC,QAAM,OAAO,KAAK,IAAID,MAAK,CAAC;AAC5B,MAAI,CAAC,KAAK,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAAG,UAAM,IAAI,MAAM,yBAAyB;AAC3E,SAAO;AACT;AAEA,IAAM,OAAO,MAAM,gBAAgB,GAAG,EAAE,MAAM,QAAO,CAAE;AACvD,IAAM,UAA0B,4BAAY,iBAAiB;EAC3D,IAAI;EACJ,MAAM;CACP;AAqBM,IAAM,YAAmC,sBAAM,SAAS,MAAM;;;AC5GrE,YAAY,WAAW;AACvB,OAAO,cAAc;;;AC+Hd,IAAM,cAAN,cAA0B,MAAM;AAAA,EAC5B;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT;AAAA,EAEA,YAAY,SAAiB,MAAuB,OAAiB;AACnE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AACF;;;ADzIA,IAAM,cAAc;AAAA,EAClB;AACF;AAsQO,SAASE,QAAO,MAAc,gBAAgC,OAAe;AAClF,QAAM,SACJ,kBAAkB,QACd,SAAS,IAAI,IAAI,MAAM,IAAI,IAC3B,SAAS,IAAI,KAAK,MAAM,IAAI;AAClC,SAAO,SAAS,OAAO,MAAM,EAAE,SAAS;AAC1C;AAoCO,SAASC,YAAW,KAAyB;AAClD,QAAM,UAAU,IAAI,MAAM,KAAK;AAC/B,MAAI,CAAC,SAAS;AACZ,WAAO,IAAI,WAAW,CAAC;AAAA,EACzB;AACA,SAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC;AAC5D;AAKO,SAASC,YAAW,OAA2B;AACpD,SAAO,MAAM,KAAK,KAAK,EACpB,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACZ;;;AEzUO,SAAS,oBAAoB,YAAoB,SAAiB,iBAAiC;AACxG,SAAO,0BAA0B,UAAU,IAAI,OAAO,OAAO,CAAC,IAAIC,QAAO,iBAAiB,MAAM,CAAC;AACnG;AAQO,IAAM,wBAAwB;AAGrC,IAAM,yBAAyB,KAAK,KAAK;AAElC,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAUA,SAAS,YAAY,MAAmC;AACtD,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,QAAQ;AACN,UAAM,IAAI,uBAAuB,qEAAqE;AAAA,EACxG;AACA,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAC1E,UAAM,IAAI,uBAAuB,sCAAsC;AAAA,EACzE;AACA,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,OAAO,UAAU,YAAY,UAAU,IAAI;AAC7C,YAAM,IAAI,uBAAuB,oBAAoB,GAAG,8BAA8B;AAAA,IACxF;AACA,WAAO,IAAI,KAAK,KAAK;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,aAAa,QAA6B,KAAqB;AACtE,QAAM,QAAQ,OAAO,IAAI,GAAG;AAC5B,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,uBAAuB,6BAA6B,GAAG,SAAS;AAAA,EAC5E;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAe,KAAqB;AAC1D,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,MAAI,OAAO,MAAM,EAAE,GAAG;AACpB,UAAM,IAAI,uBAAuB,cAAc,GAAG,mCAAmC,KAAK,EAAE;AAAA,EAC9F;AACA,SAAO;AACT;AAGO,SAAS,wBAAwB,WAAmB,QAAoC;AAC7F,MAAI,OAAO,cAAc,YAAY,CAAC,UAAU,WAAW,qBAAqB,GAAG;AACjF,UAAM,IAAI,uBAAuB,4EAA4E;AAAA,EAC/G;AACA,QAAM,SAAS,YAAY,UAAU,MAAM,sBAAsB,MAAM,CAAC;AAExE,QAAM,SAAS,aAAa,QAAQ,QAAQ;AAC5C,MAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,GAAG;AACxD,UAAM,IAAI,uBAAuB,sDAAsD;AAAA,EACzF;AAEA,QAAM,QAAQ,aAAa,QAAQ,OAAO;AAC1C,MAAI,UAAU,OAAO,OAAO;AAC1B,UAAM,IAAI,uBAAuB,yDAAyD;AAAA,EAC5F;AAEA,QAAM,UAAU,aAAa,QAAQ,SAAS;AAC9C,MAAI,YAAY,OAAO,SAAS;AAC9B,UAAM,IAAI,uBAAuB,6BAA6B,OAAO,gBAAgB,OAAO,OAAO,GAAG;AAAA,EACxG;AAEA,QAAM,WAAW,eAAe,aAAa,QAAQ,UAAU,GAAG,UAAU;AAC5E,QAAM,YAAY,eAAe,aAAa,QAAQ,WAAW,GAAG,WAAW;AAG/E,MAAI,aAAa,YAAY,YAAY,WAAW,wBAAwB;AAC1E,UAAM,IAAI,uBAAuB,0CAA0C;AAAA,EAC7E;AACF;;;AClFO,IAAM,oBAAN,MAAwB;AAAA,EACrB,MAAM;AAAA,EACN,MAAqB;AAAA,EAE7B,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAQ,YAAoB,KAAsB;AAChD,QAAI,eAAe,KAAK,IAAK,QAAO;AACpC,SAAK,MAAM;AACX,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,eAAe,YAA6B;AAC1C,QAAI,eAAe,KAAK,OAAO,KAAK,QAAQ,KAAM,QAAO;AACzD,SAAK,MAAM;AACX,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,YAAoB,KAAmB;AACnD,QAAI,eAAe,KAAK,OAAO,KAAK,QAAQ,IAAK,MAAK,MAAM;AAAA,EAC9D;AAAA,EAEA,OAAe;AACb,SAAK,OAAO;AACZ,SAAK,MAAM;AACX,WAAO,KAAK;AAAA,EACd;AACF;AAGO,IAAM,eAAsC,CAAC,aAAa,WAAW,kBAAkB;AAmCvF,IAAM,yBAAwC;AAAA,EACnD,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,sBAAsB;AACxB;AAeO,SAAS,gBAAgB,UAA0B;AACxD,SAAO,gBAAgB,QAAQ;AACjC;AAEA,IAAM,qBAAqB;AAO3B,SAAS,eAAe,MAAiC;AACvD,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,QAAQ;AACd,MAAI,MAAM,SAAS,OAAQ,QAAO;AAClC,MAAI,CAAC,aAAa,SAAS,MAAM,MAAoB,EAAG,QAAO;AAC/D,MAAI,OAAO,MAAM,cAAc,YAAY,OAAO,MAAM,cAAc,SAAU,QAAO;AACvF,SAAO,EAAE,QAAQ,MAAM,QAAsB,WAAW,OAAO,MAAM,SAAS,EAAE;AAClF;AAEA,IAAM,gBAA+B;AAAA,EACnC,YAAY,CAAC,IAAI,OAAO,WAAW,IAAI,EAAE;AAAA,EACzC,cAAc,CAAC,MAAM,aAAa,CAAuC;AAAA,EACzE,aAAa,CAAC,IAAI,OAAO,YAAY,IAAI,EAAE;AAAA,EAC3C,eAAe,CAAC,MAAM,cAAc,CAAwC;AAC9E;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAwB5B,YAA6B,MAA4B;AAA5B;AAC3B,SAAK,SAAS,EAAE,GAAG,wBAAwB,GAAG,KAAK,OAAO;AAC1D,SAAK,SAAS,KAAK,UAAU;AAC7B,SAAK,SAAS,KAAK,UAAU,KAAK;AAClC,SAAK,aAAa,gBAAgB,KAAK,QAAQ;AAAA,EACjD;AAAA,EA5BiB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,aAAmC;AAAA,EAEnC,aAA4B;AAAA,EAC5B,cAA6B,QAAQ,QAAQ;AAAA,EAC7C,iBAAiB;AAAA,EACR,gBAAgB,oBAAI,IAAsC;AAAA,EAE1D,WAAW,oBAAI,IAAiC;AAAA,EAChD,iBAAiB,oBAAI,IAAwC;AAAA,EACtE,SAA+B;AAAA,EAC/B,UAAU;AAAA,EACV,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,iBAA0B;AAAA,EAC1B,iBAA0B;AAAA,EAC1B,aAAwB,CAAC;AAAA,EACzB,aAAsC;AAAA;AAAA,EAW9C,MAAM,QAAuB;AAC3B,QAAI,KAAK,QAAS;AAClB,SAAK,UAAU;AACf,SAAK,aAAa,MAAM,KAAK,KAAK,GAAG,IAAY,WAAW,UAAU;AACtE,SAAK,gBAAgB;AACrB,SAAK,KAAK,QAAQ;AAAA,EACpB;AAAA,EAEA,MAAM,OAAsB;AAC1B,SAAK,UAAU;AACf,eAAW,KAAK,KAAK,WAAY,MAAK,OAAO,cAAc,CAAC;AAC5D,SAAK,aAAa,CAAC;AACnB,QAAI,KAAK,mBAAmB,KAAM,MAAK,OAAO,aAAa,KAAK,cAAc;AAC9E,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,UAAM,KAAK,KAAK;AAChB,SAAK,SAAS;AACd,QAAI,MAAM;AACV,UAAM,KAAK;AAAA,EACb;AAAA;AAAA,EAIA,QAAuB;AACrB,WAAO,KAAK,KAAK,KAAK,MAAM;AAAA,EAC9B;AAAA;AAAA,EAGA,aAAmB;AACjB,SAAK,KAAK,KAAK,KAAK;AACpB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,sBAAuC;AAC3C,UAAM,WAAW,KAAK,KAAK,KAAK,MAAM;AACtC,QAAI,aAAa,KAAM,QAAO;AAC9B,UAAM,KAAK,oBAAoB;AAC/B,UAAM,QAAQ,KAAK,KAAK,KAAK,MAAM;AACnC,QAAI,UAAU,MAAM;AAClB,YAAM,IAAI,mBAAmB,KAAK,mBAAmB,6CAA6C;AAAA,IACpG;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,SAAY,IAA6C;AAC7D,UAAM,MAAM,MAAM,KAAK,oBAAoB;AAC3C,UAAM,aAAa,KAAK,KAAK,KAAK;AAClC,QAAI;AACF,aAAO,MAAM,GAAG,GAAG;AAAA,IACrB,SAAS,KAAK;AACZ,UAAI,EAAE,eAAe,sBAAsB,IAAI,WAAW,KAAM,OAAM;AACtE,WAAK,KAAK,KAAK,cAAc,YAAY,GAAG;AAC5C,aAAO,GAAG,MAAM,KAAK,oBAAoB,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA,EAEQ,sBAAqC;AAC3C,QAAI,KAAK,eAAe,KAAM,QAAO,KAAK;AAC1C,UAAM,aAAa,KAAK,KAAK,KAAK;AAClC,UAAM,SAAS,KAAK,aAAa,UAAU,EAAE,QAAQ,MAAM;AACzD,UAAI,KAAK,eAAe,OAAQ,MAAK,aAAa;AAAA,IACpD,CAAC;AACD,SAAK,aAAa;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,aAAa,YAAmC;AAC5D,QAAI,MAAM,KAAK,WAAW,UAAU,EAAG;AACvC,QAAI,KAAK,KAAK,KAAK,eAAe,WAAY;AAC9C,UAAM,KAAK,gBAAgB,UAAU;AAAA,EACvC;AAAA,EAEA,MAAc,WAAW,YAAsC;AAC7D,UAAM,SAAS,MAAM,KAAK,KAAK,GAAG,IAAY,KAAK,UAAU;AAC7D,QAAI,WAAW,KAAM,QAAO;AAC5B,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,KAAK,KAAK,OAAO,YAAY,MAAM;AAAA,IACpD,SAAS,KAAK;AACZ,UAAI,eAAe,sBAAsB,IAAI,UAAU,OAAO,IAAI,SAAS,KAAK;AAC9E,YAAI,KAAK,KAAK,KAAK,eAAe,WAAY,OAAM,KAAK,KAAK,GAAG,OAAO,KAAK,UAAU;AACvF,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AACA,QAAI,CAAC,KAAK,KAAK,KAAK,QAAQ,YAAY,OAAO,GAAG,EAAG,QAAO;AAC5D,UAAM,KAAK,KAAK,GAAG,IAAI,KAAK,YAAY,OAAO,YAAY;AAC3D,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,gBAAgB,YAAmC;AAC/D,UAAM,EAAE,QAAQ,QAAQ,IAAI,KAAK,KAAK;AACtC,UAAM,EAAE,OAAO,UAAU,IAAI,MAAM,KAAK,KAAK,OAAO,cAAc,MAAM;AACxE,4BAAwB,WAAW,EAAE,QAAQ,OAAO,QAAQ,CAAC;AAC7D,UAAM,YAAY,MAAM,KAAK,KAAK,OAAO,KAAK,SAAS;AACvD,UAAM,SAAS,MAAM,KAAK,KAAK,OAAO,WAAW,EAAE,OAAO,WAAW,UAAU,KAAK,KAAK,SAAS,CAAC;AACnG,QAAI,CAAC,KAAK,KAAK,KAAK,QAAQ,YAAY,OAAO,GAAG,EAAG;AACrD,UAAM,KAAK,KAAK,GAAG,IAAI,KAAK,YAAY,OAAO,YAAY;AAAA,EAC7D;AAAA;AAAA;AAAA,EAKA,eAAuB;AACrB,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBAAqB,SAAuD;AAC1E,SAAK,cAAc,IAAI,OAAO;AAC9B,WAAO,MAAM,KAAK,cAAc,OAAO,OAAO;AAAA,EAChD;AAAA,EAEA,UAAU,OAAqB;AAC7B,QAAI,KAAK,eAAe,MAAO;AAC/B,UAAM,WAAW,KAAK;AACtB,SAAK,aAAa;AAClB,QAAI,aAAa,MAAM;AACrB,WAAK,KAAK,KAAK,GAAG,IAAI,WAAW,YAAY,KAAK,EAAE,MAAM,MAAM,MAAS;AACzE;AAAA,IACF;AACA,SAAK,kBAAkB;AACvB,SAAK,cAAc,KAAK,YAAY,KAAK,MAAM,KAAK,UAAU,OAAO,QAAQ,CAAC;AAAA,EAChF;AAAA,EAEA,MAAc,UAAU,OAAe,UAAiC;AACtE,QAAI;AACF,iBAAW,WAAW,CAAC,GAAG,KAAK,aAAa,EAAG,OAAM,QAAQ,KAAK;AAClE,YAAM,KAAK,KAAK,GAAG,IAAI,WAAW,YAAY,KAAK;AAAA,IACrD,QAAQ;AACN,UAAI,KAAK,eAAe,MAAO,MAAK,aAAa;AAAA,IACnD,UAAE;AACA,WAAK,kBAAkB;AACvB,UAAI,KAAK,mBAAmB,EAAG,MAAK,gBAAgB;AAAA,IACtD;AAAA,EACF;AAAA;AAAA,EAIA,gBAAgB,QAAoB,SAAiC;AACnE,QAAI,MAAM,KAAK,SAAS,IAAI,MAAM;AAClC,QAAI,CAAC,KAAK;AACR,YAAM,oBAAI,IAAI;AACd,WAAK,SAAS,IAAI,QAAQ,GAAG;AAAA,IAC/B;AACA,QAAI,IAAI,OAAO;AACf,WAAO,MAAM,IAAI,OAAO,OAAO;AAAA,EACjC;AAAA,EAEQ,SAAS,QAA0B;AACzC,QAAI,KAAK,iBAAiB,EAAG;AAC7B,UAAM,MAAM,KAAK,SAAS,IAAI,MAAM;AACpC,QAAI,CAAC,IAAK;AACV,eAAW,WAAW,IAAK,SAAQ;AAAA,EACrC;AAAA,EAEQ,kBAAwB;AAC9B,eAAW,UAAU,aAAc,MAAK,SAAS,MAAM;AAAA,EACzD;AAAA,EAEQ,kBAAwB;AAC9B,eAAW,UAAU,cAAc;AACjC,WAAK,WAAW,KAAK,KAAK,OAAO,YAAY,MAAM,KAAK,SAAS,MAAM,GAAG,KAAK,OAAO,cAAc,CAAC;AAAA,IACvG;AAAA,EACF;AAAA;AAAA,EAIA,SAA2B;AACzB,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA;AAAA,EAGA,gBAAgB,SAAyD;AACvE,SAAK,eAAe,IAAI,OAAO;AAC/B,WAAO,MAAM,KAAK,eAAe,OAAO,OAAO;AAAA,EACjD;AAAA,EAEQ,WAAW,QAAgC;AACjD,QAAI,KAAK,WAAW,KAAK,eAAe,OAAQ;AAChD,SAAK,aAAa;AAClB,SAAK,KAAK,WAAW,MAAM;AAC3B,eAAW,WAAW,KAAK,eAAgB,SAAQ,MAAM;AAAA,EAC3D;AAAA,EAEA,MAAc,UAAyB;AACrC,QAAI,KAAK,QAAS;AAClB,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,SAAS,MAAM,KAAK,KAAK,OAAO,SAAS,CAAC;AACpE,UAAI,KAAK,QAAS;AAClB,WAAK,WAAW,QAAQ,KAAK,KAAK,KAAK,UAAU;AAAA,IACnD,QAAQ;AACN,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,WAAW,QAAgB,YAA0B;AAC3D,UAAM,SAAS,KAAK,KAAK,OAAO,QAAQ,QAAQ,SAAS,IAAI;AAC7D,UAAM,KAAK,KAAK,KAAK,iBAAiB,GAAG,MAAM,iBAAiB,mBAAmB,MAAM,CAAC,EAAE;AAC5F,SAAK,SAAS;AACd,OAAG,SAAS,MAAM,KAAK,WAAW,EAAE;AACpC,OAAG,YAAY,CAAC,OAAO,KAAK,cAAc,IAAI,GAAG,IAAI;AACrD,OAAG,UAAU,CAAC,OAAO,KAAK,YAAY,IAAI,YAAY,IAAI,IAAI;AAC9D,OAAG,UAAU,MAAM;AAAA,EACrB;AAAA,EAEQ,WAAW,IAAyB;AAC1C,QAAI,OAAO,KAAK,OAAQ;AACxB,SAAK,oBAAoB;AACzB,SAAK,WAAW,WAAW;AAC3B,SAAK,aAAa,EAAE;AAEpB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,cAAc,IAAmB,MAAqB;AAC5D,QAAI,OAAO,KAAK,OAAQ;AACxB,SAAK,aAAa,EAAE;AACpB,UAAM,QAAQ,eAAe,IAAI;AACjC,QAAI,UAAU,KAAM;AACpB,SAAK,UAAU,MAAM,SAAS;AAC9B,SAAK,SAAS,MAAM,MAAM;AAAA,EAC5B;AAAA,EAEQ,YAAY,IAAmB,YAAoB,MAAqB;AAC9E,QAAI,OAAO,KAAK,OAAQ;AACxB,SAAK,SAAS;AACd,SAAK,eAAe;AACpB,QAAI,KAAK,QAAS;AAClB,QAAI,SAAS,oBAAoB;AAE/B,WAAK,KAAK,KAAK,eAAe,UAAU;AACxC,WAAK,WAAW,UAAU;AAC1B,WAAK,KAAK,QAAQ;AAClB;AAAA,IACF;AACA,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,QAAS;AAClB,SAAK,qBAAqB;AAC1B,SAAK,WAAW,KAAK,qBAAqB,KAAK,OAAO,uBAAuB,YAAY,UAAU;AACnG,UAAM,SAAS,KAAK;AAAA,MAClB,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO,kBAAkB,MAAM,KAAK,oBAAoB;AAAA,IAC/D;AACA,UAAM,QAAQ,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM;AAC/C,SAAK,iBAAiB,KAAK,OAAO,WAAW,MAAM,KAAK,KAAK,QAAQ,GAAG,KAAK;AAAA,EAC/E;AAAA,EAEQ,aAAa,IAAyB;AAC5C,SAAK,eAAe;AACpB,SAAK,iBAAiB,KAAK,OAAO,WAAW,MAAM;AACjD,UAAI,OAAO,KAAK,OAAQ,IAAG,MAAM;AAAA,IACnC,GAAG,KAAK,OAAO,kBAAkB;AAAA,EACnC;AAAA,EAEQ,iBAAuB;AAC7B,QAAI,KAAK,mBAAmB,KAAM,MAAK,OAAO,aAAa,KAAK,cAAc;AAC9E,SAAK,iBAAiB;AAAA,EACxB;AACF;;;ACxbO,IAAM,6BAA6B;AAOnC,IAAM,gCAAgC;AAWtC,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAE5C,YAAY,SAA0B,OAAiB;AACrD,UAAM,OAAO;AADuB;AAEpC,SAAK,OAAO;AAAA,EACd;AAAA,EAJS,OAAO;AAKlB;AAGO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAE9C,YAAY,SAA0B,OAAiB;AACrD,UAAM,OAAO;AADuB;AAEpC,SAAK,OAAO;AAAA,EACd;AAAA,EAJS,OAAO;AAKlB;AAEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EACzC,OAAO;AAAA,EAChB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGA,eAAsB,WACpB,OACA,OACA,IACc;AACd,QAAM,MAAM,IAAI,MAAS,MAAM,MAAM;AACrC,MAAI,OAAO;AACX,MAAI,SAAS;AACb,QAAM,SAAS,YAA2B;AACxC,eAAS;AACP,UAAI,OAAQ;AACZ,YAAM,QAAQ;AACd,cAAQ;AACR,UAAI,SAAS,MAAM,OAAQ;AAC3B,UAAI;AACF,YAAI,KAAK,IAAI,MAAM,GAAG,MAAM,KAAK,GAAQ,KAAK;AAAA,MAChD,SAAS,KAAK;AACZ,iBAAS;AACT,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC,EAAE,GAAG,MAAM;AACzF,QAAM,QAAQ,IAAI,OAAO;AACzB,SAAO;AACT;AAGA,eAAsB,mBACpB,QACA,OAC8B;AAC9B,MAAI,MAAM,WAAW,EAAG,QAAO,oBAAI,IAAI;AACvC,QAAM,OAAO,MAAM,OAAO,WAAW,MAAM,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;AACnG,QAAM,WAAW,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;AACvD,QAAM,UAAU,MAAM,IAAI,CAAC,SAAS;AAClC,UAAM,MAAM,SAAS,IAAI,KAAK,MAAM;AACpC,QAAI,QAAQ,QAAW;AACrB,YAAM,IAAI,yBAAyB,uCAAuC,KAAK,MAAM,EAAE;AAAA,IACzF;AACA,WAAO,EAAE,MAAM,IAAI;AAAA,EACrB,CAAC;AACD,QAAM;AAAA,IAAW;AAAA,IAAS;AAAA,IAA4B,CAAC,EAAE,MAAM,IAAI,MACjE,OAAO,WAAW,IAAI,QAAQ,KAAK,KAAK;AAAA,EAC1C;AACA,SAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,EAAE,MAAM,IAAI,MAAM,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,CAAC;AACvE;AAEO,IAAM,uBAAN,MAAkD;AAAA,EACvD,YAA6B,QAA2B;AAA3B;AAAA,EAA4B;AAAA,EAEzD,MAAM,cAAc,OAAwC;AAC1D,UAAM,OAAO,MAAM,KAAK,OAAO,cAAc,KAAK;AAClD,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,WAAW,OAAO,KAAK,SAAS;AAAA,MAChC,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SAAS,UAAsD;AACnE,UAAM,SAAS,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC;AACpC,UAAM,SAAS,oBAAI,IAAwB;AAC3C,aAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,+BAA+B;AACjF,YAAM,OAAO,MAAM,KAAK,OAAO,SAAS,OAAO,MAAM,OAAO,QAAQ,6BAA6B,CAAC;AAClG,YAAM,QAAQ,MAAM,WAAW,MAAM,4BAA4B,CAAC,MAAM,KAAK,OAAO,UAAU,EAAE,MAAM,CAAC;AACvG,iBAAW,CAAC,GAAG,GAAG,KAAK,KAAK,QAAQ,GAAG;AACrC,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,SAAS,OAAW,QAAO,IAAI,IAAI,SAAS,IAAI;AAAA,MACtD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,OAA8E;AACxF,WAAO,mBAAmB,KAAK,QAAQ,KAAK;AAAA,EAC9C;AAAA,EAEA,MAAM,WAAW,OAIa;AAC5B,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAO,MAAM,KAAK;AAC5C,aAAO,EAAE,QAAQ,OAAO,QAAQ,WAAW,OAAO,OAAO,SAAS,EAAE;AAAA,IACtE,SAAS,KAAK;AACZ,UAAI,qBAAqB,KAAK,GAAG,EAAG,OAAM,IAAI,mBAAmB,IAAI,SAAS,GAAG;AACjF,UAAI,qBAAqB,KAAK,GAAG,EAAG,OAAM,IAAI,qBAAqB,IAAI,SAAS,GAAG;AACnF,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;ACjIO,IAAM,cAAN,MAAkB;AAAA,EACf,OAAyB,QAAQ,QAAQ;AAAA;AAAA,EAGjD,QAAW,IAAkC;AAC3C,UAAM,MAAM,KAAK,KAAK,KAAK,IAAI,EAAE;AACjC,SAAK,OAAO,IAAI;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,WAAO;AAAA,EACT;AACF;;;ACJM,SAAU,QACd,MACA,KACA,MAAuB;AAEvB,QAAM,IAAI;AAIV,MAAI,SAAS;AAAW,WAAO,IAAI,WAAW,KAAK,SAAS;AAC5D,SAAO,KAAK,MAAM,MAAM,GAAG;AAC7B;AAIA,IAAM,eAA+B,2BAAW,GAAG,CAAC;AAEpD,IAAM,eAA+B,2BAAW,GAAE;AAqB5C,SAAU,OACd,MACA,KACA,MACA,SAAiB,IAAE;AAEnB,QAAM,IAAI;AACV,UAAQ,QAAQ,QAAQ;AACxB,SAAO,KAAK,QAAW,KAAK;AAC5B,QAAM,OAAO,KAAK;AAElB,MAAI,IAAI,SAAS;AAAM,UAAM,IAAI,MAAM,uCAAuC;AAE9E,MAAI,SAAS,MAAM;AAAM,UAAM,IAAI,MAAM,+BAA+B;AACxE,QAAM,SAAS,KAAK,KAAK,SAAS,IAAI;AACtC,MAAI,SAAS;AAAW,WAAO;;AAC1B,WAAO,MAAM,QAAW,MAAM;AAEnC,QAAM,MAAM,IAAI,WAAW,SAAS,IAAI;AAExC,QAAM,OAAO,KAAK,OAAO,MAAM,GAAG;AAClC,QAAM,UAAU,KAAK,WAAU;AAC/B,QAAM,IAAI,IAAI,WAAW,KAAK,SAAS;AACvC,WAAS,UAAU,GAAG,UAAU,QAAQ,WAAW;AACjD,iBAAa,CAAC,IAAI,UAAU;AAG5B,YAAQ,OAAO,YAAY,IAAI,eAAe,CAAC,EAC5C,OAAO,IAAI,EACX,OAAO,YAAY,EACnB,WAAW,CAAC;AACf,QAAI,IAAI,GAAG,OAAO,OAAO;AACzB,SAAK,WAAW,OAAO;EACzB;AACA,OAAK,QAAO;AACZ,UAAQ,QAAO;AACf,QAAM,GAAG,YAAY;AACrB,SAAO,IAAI,MAAM,GAAG,MAAM;AAC5B;AA0BO,IAAM,OAAO,CAClB,MACA,KACA,MACA,MACA,WACqB,OAAO,MAAM,QAAQ,MAAM,KAAK,IAAI,GAAG,MAAM,MAAM;;;ACTpE,SAAUC,SAAQ,GAAU;AAKhC,SACE,aAAa,cACZ,YAAY,OAAO,CAAC,KACnB,EAAE,YAAY,SAAS,gBACvB,uBAAuB,KACvB,EAAE,sBAAsB;AAE9B;AAaM,SAAUC,OAAM,GAAU;AAC9B,MAAI,OAAO,MAAM;AAAW,UAAM,IAAI,UAAU,yBAAyB,CAAC,EAAE;AAC9E;AAcM,SAAUC,SAAQ,GAAS;AAC/B,MAAI,OAAO,MAAM;AAAU,UAAM,IAAI,UAAU,0BAA0B,OAAO,CAAC;AACjF,MAAI,CAAC,OAAO,cAAc,CAAC,KAAK,IAAI;AAClC,UAAM,IAAI,WAAW,oCAAoC,CAAC;AAC9D;AAkBM,SAAUC,QACd,OACA,QACA,QAAgB,IAAE;AAElB,QAAM,QAAQH,SAAQ,KAAK;AAC3B,QAAM,MAAM,OAAO;AACnB,QAAM,WAAW,WAAW;AAC5B,MAAI,CAAC,SAAU,YAAY,QAAQ,QAAS;AAC1C,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,QAAQ,WAAW,cAAc,MAAM,KAAK;AAClD,UAAM,MAAM,QAAQ,UAAU,GAAG,KAAK,QAAQ,OAAO,KAAK;AAC1D,UAAM,UAAU,SAAS,wBAAwB,QAAQ,WAAW;AACpE,QAAI,CAAC;AAAO,YAAM,IAAI,UAAU,OAAO;AACvC,UAAM,IAAI,WAAW,OAAO;EAC9B;AACA,SAAO;AACT;AAeM,SAAUI,SAAQ,UAAe,gBAAgB,MAAI;AACzD,MAAI,SAAS;AAAW,UAAM,IAAI,MAAM,kCAAkC;AAC1E,MAAI,iBAAiB,SAAS;AAAU,UAAM,IAAI,MAAM,uCAAuC;AACjG;AAmBM,SAAUC,SAAQ,KAAU,UAAe,cAAc,OAAK;AAClE,EAAAF,QAAO,KAAK,QAAW,QAAQ;AAC/B,QAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,KAAK;AACpB,UAAM,IAAI,WAAW,2DAA2D,GAAG;EACrF;AACA,MAAI,eAAe,CAAC,YAAY,GAAG;AAAG,UAAM,IAAI,MAAM,iCAAiC;AACzF;AA6DM,SAAU,IAAI,KAAqB;AACvC,SAAO,IAAI,YACT,IAAI,QACJ,IAAI,YACJ,KAAK,MAAM,IAAI,aAAa,CAAC,CAAC;AAElC;AAcM,SAAUG,UAAS,QAA0B;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,WAAO,CAAC,EAAE,KAAK,CAAC;EAClB;AACF;AAaM,SAAUC,YAAW,KAAqB;AAC9C,SAAO,IAAI,SAAS,IAAI,QAAQ,IAAI,YAAY,IAAI,UAAU;AAChE;AAMO,IAAM,OAAiC,uBAC5C,IAAI,WAAW,IAAI,YAAY,CAAC,SAAU,CAAC,EAAE,MAAM,EAAE,CAAC,MAAM,IAAK;AAa5D,IAAM,WAAW,CAAC,SACrB,QAAQ,KAAM,aACd,QAAQ,IAAK,WACb,SAAS,IAAK,QACd,SAAS,KAAM;AAaZ,IAAM,YAAmC,OAC5C,CAAC,MAAc,IACf,CAAC,MAAc,SAAS,CAAC,MAAM;AAa5B,IAAM,aAAa,CAAC,QAA6C;AACtE,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ;AAAK,QAAI,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC;AAC7D,SAAO;AACT;AAaO,IAAM,aAA0D,OACnE,CAAC,MAAyB,IAC1B;AAmRE,SAAU,UACd,UACA,MAAQ;AAER,MAAI,QAAQ,QAAQ,OAAO,SAAS;AAAU,UAAM,IAAI,MAAM,yBAAyB;AACvF,QAAM,SAAS,OAAO,OAAO,UAAU,IAAI;AAC3C,SAAO;AACT;AAcM,SAAU,WAAW,GAAqB,GAAmB;AACjE,MAAI,EAAE,WAAW,EAAE;AAAQ,WAAO;AAClC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ;AAAK,YAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AACrD,SAAO,SAAS;AAClB;AA2CM,SAAU,mBACd,QACA,SACA,SAAsC;AAEtC,QAAM,MAAM;AACZ,QAAM,UAAW,YAAY,MAAM,CAAA;AACnC,QAAM,OAAY,CAAC,KAAuB,QACxC,IAAI,KAAK,GAAG,QAAQ,GAAG,CAAC,EACrB,OAAO,GAAG,EACV,OAAM;AACX,QAAM,MAAM,IAAI,IAAI,WAAW,MAAM,GAAG,GAAG,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC;AACrE,OAAK,YAAY,IAAI;AACrB,OAAK,WAAW,IAAI;AACpB,OAAK,SAAS,CAAC,QAA0B,SAAY,IAAI,KAAK,GAAG,IAAI;AACrE,SAAO;AACT;AAuGO,IAAM,wCAAa,CACxB,QACA,gBACS;AACT,WAAS,cAAc,QAA0B,MAAW;AAE1D,IAAAC,QAAO,KAAK,QAAW,KAAK;AAG5B,QAAI,OAAO,gBAAgB,QAAW;AACpC,YAAM,QAAQ,KAAK,CAAC;AACpB,MAAAA,QAAO,OAAO,OAAO,eAAe,SAAY,OAAO,aAAa,OAAO;IAC7E;AAGA,UAAM,OAAO,OAAO;AACpB,QAAI,QAAQ,KAAK,CAAC,MAAM;AAAW,MAAAA,QAAO,KAAK,CAAC,GAAG,QAAW,KAAK;AAEnE,UAAM,SAAS,YAAY,KAAK,GAAG,IAAI;AACvC,UAAM,cAAc,CAAC,UAAkB,WAA6B;AAClE,UAAI,WAAW,QAAW;AACxB,YAAI,aAAa;AAAG,gBAAM,IAAI,MAAM,6BAA6B;AACjE,QAAAA,QAAO,QAAQ,QAAW,QAAQ;MACpC;IACF;AAEA,QAAI,SAAS;AACb,UAAM,WAAW;MACf,QAAQ,MAAwB,QAAyB;AACvD,YAAI;AAAQ,gBAAM,IAAI,MAAM,8CAA8C;AAC1E,iBAAS;AACT,QAAAA,QAAO,IAAI;AACX,oBAAY,OAAO,QAAQ,QAAQ,MAAM;AACzC,eAAQ,OAA4B,QAAQ,MAAM,MAAM;MAC1D;MACA,QAAQ,MAAwB,QAAyB;AACvD,QAAAA,QAAO,IAAI;AACX,YAAI,QAAQ,KAAK,SAAS;AACxB,gBAAM,IAAI,MAAM,wDAAwD,IAAI;AAC9E,oBAAY,OAAO,QAAQ,QAAQ,MAAM;AACzC,eAAQ,OAA4B,QAAQ,MAAM,MAAM;MAC1D;;AAGF,WAAO;EACT;AAEA,SAAO,OAAO,eAAe,MAAM;AACnC,SAAO;AACT;AAmCM,SAAU,UACd,gBACA,KACA,cAAc,MAAI;AAElB,MAAI,QAAQ;AAAW,WAAO,IAAI,WAAW,cAAc;AAE3D,EAAAA,QAAO,KAAK,QAAW,QAAQ;AAC/B,MAAI,IAAI,WAAW;AACjB,UAAM,IAAI,MACR,4CAA4C,iBAAiB,YAAY,IAAI,MAAM;AAEvF,MAAI,eAAe,CAAC,YAAY,GAAG;AAAG,UAAM,IAAI,MAAM,iCAAiC;AACvF,SAAO;AACT;AAmBM,SAAU,WAAW,YAAoB,WAAmBC,OAAa;AAE7E,EAAAC,SAAQ,UAAU;AAClB,EAAAA,SAAQ,SAAS;AACjB,EAAAC,OAAMF,KAAI;AACV,QAAM,MAAM,IAAI,WAAW,EAAE;AAC7B,QAAM,OAAOG,YAAW,GAAG;AAC3B,OAAK,aAAa,GAAG,OAAO,SAAS,GAAGH,KAAI;AAC5C,OAAK,aAAa,GAAG,OAAO,UAAU,GAAGA,KAAI;AAC7C,SAAO;AACT;AAaM,SAAU,YAAY,OAAuB;AACjD,SAAO,MAAM,aAAa,MAAM;AAClC;AAcM,SAAUI,WAAU,OAAuB;AAG/C,SAAO,WAAW,KAAKL,QAAO,KAAK,CAAC;AACtC;AAmBM,SAAUM,aAAY,cAAc,IAAE;AAG1C,EAAAJ,SAAQ,WAAW;AACnB,QAAM,KAAK,OAAO,eAAe,WAAY,WAAmB,SAAS;AACzE,MAAI,OAAO,IAAI,oBAAoB;AACjC,UAAM,IAAI,MAAM,wCAAwC;AAC1D,SAAO,GAAG,gBAAgB,IAAI,WAAW,WAAW,CAAC;AACvD;;;AC9+BA,IAAM,YAAY,CAAC,QAAgB,WAAW,KAAK,IAAI,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAKxF,IAAM,aAA8B,uBAAM,WAAW,IAAI,UAAU,kBAAkB,CAAC,CAAC,GAAE;AAGzF,IAAM,aAA8B,uBAAM,WAAW,IAAI,UAAU,kBAAkB,CAAC,CAAC,GAAE;AAanF,SAAU,KAAK,GAAW,GAAS;AACvC,SAAQ,KAAK,IAAM,MAAO,KAAK;AACjC;AAqDA,IAAM,YAAY;AAElB,IAAM,cAAc;AAepB,IAAM,cAA+B,uBAAM,KAAK,KAAK,GAAE;AACvD,IAAM,YAA4B,4BAAY,GAAE;AAChD,SAAS,UACP,MACA,OACA,KACA,OACA,MACA,QACA,SACA,QAAc;AAEd,QAAM,MAAM,KAAK;AACjB,QAAM,QAAQ,IAAI,WAAW,SAAS;AACtC,QAAM,MAAM,IAAI,KAAK;AAErB,QAAM,YAAY,QAAQ,YAAY,IAAI,KAAK,YAAY,MAAM;AACjE,QAAM,MAAM,YAAY,IAAI,IAAI,IAAI;AACpC,QAAM,MAAM,YAAY,IAAI,MAAM,IAAI;AAGtC,MAAI,CAAC,MAAM;AACT,aAAS,MAAM,GAAG,MAAM,KAAK,WAAW;AACtC,WACE,OACA,KACA,OACA,KACA,SACA,MAAM;AAGR,iBAAW,GAAG;AACd,UAAI,WAAW;AAAa,cAAM,IAAI,MAAM,uBAAuB;AACnE,YAAM,OAAO,KAAK,IAAI,WAAW,MAAM,GAAG;AAC1C,eAAS,IAAI,GAAG,MAAM,IAAI,MAAM,KAAK;AACnC,eAAO,MAAM;AACb,eAAO,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC;MACrC;AACA,aAAO;IACT;AACA;EACF;AACA,WAAS,MAAM,GAAG,MAAM,KAAK,WAAW;AACtC,SACE,OACA,KACA,OACA,KACA,SACA,MAAM;AAGR,QAAI,WAAW;AAAa,YAAM,IAAI,MAAM,uBAAuB;AACnE,UAAM,OAAO,KAAK,IAAI,WAAW,MAAM,GAAG;AAE1C,QAAI,aAAa,SAAS,WAAW;AACnC,YAAM,QAAQ,MAAM;AACpB,UAAI,MAAM,MAAM;AAAG,cAAM,IAAI,MAAM,6BAA6B;AAChE,eAAS,IAAI,GAAG,MAAc,IAAI,aAAa,KAAK;AAClD,eAAO,QAAQ;AACf,YAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;MAC/B;AACA,aAAO;AACP;IACF;AACA,aAAS,IAAI,GAAG,MAAM,IAAI,MAAM,KAAK;AACnC,aAAO,MAAM;AACb,aAAO,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC;IACrC;AACA,WAAO;EACT;AACF;AAUM,SAAU,aAAa,MAA0B,MAAsB;AAC3E,QAAM,EAAE,gBAAgB,eAAe,eAAe,cAAc,OAAM,IAAK,UAC7E,EAAE,gBAAgB,OAAO,eAAe,GAAG,cAAc,OAAO,QAAQ,GAAE,GAC1E,IAAI;AAEN,MAAI,OAAO,SAAS;AAAY,UAAM,IAAI,MAAM,yBAAyB;AACzE,EAAAK,SAAQ,aAAa;AACrB,EAAAA,SAAQ,MAAM;AACd,EAAAC,OAAM,YAAY;AAClB,EAAAA,OAAM,cAAc;AACpB,SAAO,CACL,KACA,OACA,MACA,QACA,UAAU,MACU;AACpB,IAAAC,QAAO,KAAK,QAAW,KAAK;AAC5B,IAAAA,QAAO,OAAO,QAAW,OAAO;AAChC,IAAAA,QAAO,MAAM,QAAW,MAAM;AAC9B,UAAM,MAAM,KAAK;AAGjB,aAAS,UAAU,KAAK,QAAQ,KAAK;AACrC,IAAAF,SAAQ,OAAO;AAEf,QAAI,UAAU,KAAK,WAAW;AAAa,YAAM,IAAI,MAAM,uBAAuB;AAClF,UAAM,UAAU,CAAA;AAKhB,QAAI,IAAI,IAAI;AACZ,QAAI;AACJ,QAAI;AACJ,QAAI,MAAM,IAAI;AAGZ,cAAQ,KAAM,IAAIG,WAAU,GAAG,CAAE;AACjC,cAAQ;IACV,WAAW,MAAM,MAAM,gBAAgB;AACrC,UAAI,IAAI,WAAW,EAAE;AACrB,QAAE,IAAI,GAAG;AACT,QAAE,IAAI,KAAK,EAAE;AACb,cAAQ;AACR,cAAQ,KAAK,CAAC;IAChB,OAAO;AACL,MAAAD,QAAO,KAAK,IAAI,SAAS;AACzB,YAAM,IAAI,MAAM,kBAAkB;IAEpC;AAUA,QAAI,CAAC,QAAQ,CAAC,YAAY,KAAK;AAAG,cAAQ,KAAM,QAAQC,WAAU,KAAK,CAAE;AAEzE,QAAI,MAAM,IAAI,CAAC;AAEf,QAAI,eAAe;AACjB,UAAI,MAAM,WAAW;AAAI,cAAM,IAAI,MAAM,sCAAsC;AAC/E,YAAM,MAAM,MAAM,SAAS,GAAG,EAAE;AAChC,UAAI;AAAM,sBAAc,OAA4B,KAAK,IAAI,GAAG,GAAG,GAAG;WACjE;AACH,cAAM,WAAW,WAAW,YAAY,KAAK,KAAK,CAAC;AACnD,sBAAc,UAAU,KAAK,IAAI,GAAG,GAAG,GAAG;AAC1C,QAAAC,OAAM,QAAQ;AACd,mBAAW,GAAG;MAChB;AACA,cAAQ,MAAM,SAAS,EAAE;IAC3B,WAAW,CAAC;AAAM,iBAAW,GAAG;AAGhC,UAAM,aAAa,KAAK;AACxB,QAAI,eAAe,MAAM;AACvB,YAAM,IAAI,MAAM,sBAAsB,UAAU,cAAc;AAIhE,QAAI,eAAe,IAAI;AACrB,YAAM,KAAK,IAAI,WAAW,EAAE;AAC5B,SAAG,IAAI,OAAO,eAAe,IAAI,KAAK,MAAM,MAAM;AAClD,cAAQ;AACR,cAAQ,KAAK,KAAK;IACpB;AACA,UAAM,MAAM,WAAW,IAAI,KAAK,CAAC;AAGjC,QAAI;AACF,gBAAU,MAAM,OAAO,KAAK,KAAK,MAAM,QAAQ,SAAS,MAAM;AAC9D,aAAO;IACT;AACE,MAAAA,OAAM,GAAG,OAAO;IAClB;EACF;AACF;;;ACrTA,SAAS,OAAO,GAAqB,GAAS;AAC5C,SAAQ,EAAE,GAAG,IAAI,OAAU,EAAE,GAAG,IAAI,QAAS;AAC/C;AAsEM,IAAO,WAAP,MAAe;EACV,WAAW;EACX,YAAY;EACb,SAAS,IAAI,WAAW,EAAE;EAC1B,IAAI,IAAI,YAAY,EAAE;;EACtB,IAAI,IAAI,YAAY,EAAE;EACtB,MAAM,IAAI,YAAY,CAAC;EACvB,MAAM;EACJ,WAAW;EACX,YAAY;;EAGtB,YAAY,KAAqB;AAC/B,UAAMC,WAAUC,QAAO,KAAK,IAAI,KAAK,CAAC;AACtC,UAAM,KAAK,OAAO,KAAK,CAAC;AACxB,UAAM,KAAK,OAAO,KAAK,CAAC;AACxB,UAAM,KAAK,OAAO,KAAK,CAAC;AACxB,UAAM,KAAK,OAAO,KAAK,CAAC;AACxB,UAAM,KAAK,OAAO,KAAK,CAAC;AACxB,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,KAAK,OAAO,KAAK,EAAE;AAMzB,SAAK,EAAE,CAAC,IAAI,KAAK;AACjB,SAAK,EAAE,CAAC,KAAM,OAAO,KAAO,MAAM,KAAM;AACxC,SAAK,EAAE,CAAC,KAAM,OAAO,KAAO,MAAM,KAAM;AACxC,SAAK,EAAE,CAAC,KAAM,OAAO,IAAM,MAAM,KAAM;AACvC,SAAK,EAAE,CAAC,KAAM,OAAO,IAAM,MAAM,MAAO;AACxC,SAAK,EAAE,CAAC,IAAK,OAAO,IAAK;AACzB,SAAK,EAAE,CAAC,KAAM,OAAO,KAAO,MAAM,KAAM;AACxC,SAAK,EAAE,CAAC,KAAM,OAAO,KAAO,MAAM,KAAM;AACxC,SAAK,EAAE,CAAC,KAAM,OAAO,IAAM,MAAM,KAAM;AACvC,SAAK,EAAE,CAAC,IAAK,OAAO,IAAK;AACzB,aAAS,IAAI,GAAG,IAAI,GAAG;AAAK,WAAK,IAAI,CAAC,IAAI,OAAO,KAAK,KAAK,IAAI,CAAC;EAClE;EAEQ,QAAQ,MAAwB,QAAgB,SAAS,OAAK;AAIpE,UAAM,QAAQ,SAAS,IAAI,KAAK;AAChC,UAAM,EAAE,GAAG,EAAC,IAAK;AACjB,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,CAAC;AAEd,UAAM,KAAK,OAAO,MAAM,SAAS,CAAC;AAClC,UAAM,KAAK,OAAO,MAAM,SAAS,CAAC;AAClC,UAAM,KAAK,OAAO,MAAM,SAAS,CAAC;AAClC,UAAM,KAAK,OAAO,MAAM,SAAS,CAAC;AAClC,UAAM,KAAK,OAAO,MAAM,SAAS,CAAC;AAClC,UAAM,KAAK,OAAO,MAAM,SAAS,EAAE;AACnC,UAAM,KAAK,OAAO,MAAM,SAAS,EAAE;AACnC,UAAM,KAAK,OAAO,MAAM,SAAS,EAAE;AAEnC,QAAI,KAAK,EAAE,CAAC,KAAK,KAAK;AACtB,QAAI,KAAK,EAAE,CAAC,MAAO,OAAO,KAAO,MAAM,KAAM;AAC7C,QAAI,KAAK,EAAE,CAAC,MAAO,OAAO,KAAO,MAAM,KAAM;AAC7C,QAAI,KAAK,EAAE,CAAC,MAAO,OAAO,IAAM,MAAM,KAAM;AAC5C,QAAI,KAAK,EAAE,CAAC,MAAO,OAAO,IAAM,MAAM,MAAO;AAC7C,QAAI,KAAK,EAAE,CAAC,KAAM,OAAO,IAAK;AAC9B,QAAI,KAAK,EAAE,CAAC,MAAO,OAAO,KAAO,MAAM,KAAM;AAC7C,QAAI,KAAK,EAAE,CAAC,MAAO,OAAO,KAAO,MAAM,KAAM;AAC7C,QAAI,KAAK,EAAE,CAAC,MAAO,OAAO,IAAM,MAAM,KAAM;AAC5C,QAAI,KAAK,EAAE,CAAC,KAAM,OAAO,IAAK;AAE9B,QAAI,IAAI;AAER,QAAI,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AACjF,QAAI,OAAO;AACX,UAAM;AACN,UAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AAChF,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AAC3E,QAAI,OAAO;AACX,UAAM;AACN,UAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AAChF,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI;AACrE,QAAI,OAAO;AACX,UAAM;AACN,UAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AAChF,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI;AAC/D,QAAI,OAAO;AACX,UAAM;AACN,UAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AAChF,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC1D,QAAI,OAAO;AACX,UAAM;AACN,UAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AAChF,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC1D,QAAI,OAAO;AACX,UAAM;AACN,UAAM,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AAC1E,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC1D,QAAI,OAAO;AACX,UAAM;AACN,UAAM,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI;AACpE,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC1D,QAAI,OAAO;AACX,UAAM;AACN,UAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI;AAC9D,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC1D,QAAI,OAAO;AACX,UAAM;AACN,UAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI;AACxD,SAAK,OAAO;AACZ,UAAM;AAEN,QAAI,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC1D,QAAI,OAAO;AACX,UAAM;AACN,UAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AACnD,SAAK,OAAO;AACZ,UAAM;AAEN,SAAM,KAAK,KAAK,IAAK;AACrB,QAAK,IAAI,KAAM;AACf,SAAK,IAAI;AACT,QAAI,MAAM;AACV,UAAM;AAEN,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;EACT;EAEQ,WAAQ;AACd,UAAM,EAAE,GAAG,IAAG,IAAK;AACnB,UAAM,IAAI,IAAI,YAAY,EAAE;AAC5B,QAAI,IAAI,EAAE,CAAC,MAAM;AACjB,MAAE,CAAC,KAAK;AACR,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAE,CAAC,KAAK;AACR,UAAI,EAAE,CAAC,MAAM;AACb,QAAE,CAAC,KAAK;IACV;AACA,MAAE,CAAC,KAAK,IAAI;AACZ,QAAI,EAAE,CAAC,MAAM;AACb,MAAE,CAAC,KAAK;AACR,MAAE,CAAC,KAAK;AACR,QAAI,EAAE,CAAC,MAAM;AACb,MAAE,CAAC,KAAK;AACR,MAAE,CAAC,KAAK;AAIR,MAAE,CAAC,IAAI,EAAE,CAAC,IAAI;AACd,QAAI,EAAE,CAAC,MAAM;AACb,MAAE,CAAC,KAAK;AACR,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAE,CAAC,IAAI,EAAE,CAAC,IAAI;AACd,UAAI,EAAE,CAAC,MAAM;AACb,QAAE,CAAC,KAAK;IACV;AACA,MAAE,CAAC,KAAK,KAAK;AAEb,QAAI,QAAQ,IAAI,KAAK;AACrB,aAAS,IAAI,GAAG,IAAI,IAAI;AAAK,QAAE,CAAC,KAAK;AACrC,WAAO,CAAC;AACR,aAAS,IAAI,GAAG,IAAI,IAAI;AAAK,QAAE,CAAC,IAAK,EAAE,CAAC,IAAI,OAAQ,EAAE,CAAC;AACvD,MAAE,CAAC,KAAK,EAAE,CAAC,IAAK,EAAE,CAAC,KAAK,MAAO;AAC/B,MAAE,CAAC,KAAM,EAAE,CAAC,MAAM,IAAM,EAAE,CAAC,KAAK,MAAO;AACvC,MAAE,CAAC,KAAM,EAAE,CAAC,MAAM,IAAM,EAAE,CAAC,KAAK,KAAM;AACtC,MAAE,CAAC,KAAM,EAAE,CAAC,MAAM,IAAM,EAAE,CAAC,KAAK,KAAM;AACtC,MAAE,CAAC,KAAM,EAAE,CAAC,MAAM,KAAO,EAAE,CAAC,KAAK,IAAM,EAAE,CAAC,KAAK,MAAO;AACtD,MAAE,CAAC,KAAM,EAAE,CAAC,MAAM,IAAM,EAAE,CAAC,KAAK,MAAO;AACvC,MAAE,CAAC,KAAM,EAAE,CAAC,MAAM,IAAM,EAAE,CAAC,KAAK,KAAM;AACtC,MAAE,CAAC,KAAM,EAAE,CAAC,MAAM,IAAM,EAAE,CAAC,KAAK,KAAM;AAEtC,QAAI,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC;AACpB,MAAE,CAAC,IAAI,IAAI;AACX,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,WAAO,EAAE,CAAC,IAAI,IAAI,CAAC,IAAK,MAAM,MAAM,MAAO;AAC3C,QAAE,CAAC,IAAI,IAAI;IACb;AACA,IAAAC,OAAM,CAAC;EACT;EACA,OAAO,MAAsB;AAC3B,IAAAC,SAAQ,IAAI;AACZ,IAAAF,QAAO,IAAI;AACX,WAAOD,WAAU,IAAI;AACrB,UAAM,EAAE,QAAQ,SAAQ,IAAK;AAC7B,UAAM,MAAM,KAAK;AAEjB,aAAS,MAAM,GAAG,MAAM,OAAO;AAC7B,YAAM,OAAO,KAAK,IAAI,WAAW,KAAK,KAAK,MAAM,GAAG;AAEpD,UAAI,SAAS,UAAU;AACrB,eAAO,YAAY,MAAM,KAAK,OAAO;AAAU,eAAK,QAAQ,MAAM,GAAG;AACrE;MACF;AACA,aAAO,IAAI,KAAK,SAAS,KAAK,MAAM,IAAI,GAAG,KAAK,GAAG;AACnD,WAAK,OAAO;AACZ,aAAO;AACP,UAAI,KAAK,QAAQ,UAAU;AACzB,aAAK,QAAQ,QAAQ,GAAG,KAAK;AAC7B,aAAK,MAAM;MACb;IACF;AACA,WAAO;EACT;EACA,UAAO;AAEL,SAAK,YAAY;AACjB,IAAAE,OAAM,KAAK,GAAG,KAAK,GAAG,KAAK,QAAQ,KAAK,GAAG;EAC7C;EACA,WAAW,KAAqB;AAC9B,IAAAC,SAAQ,IAAI;AACZ,IAAAC,SAAQ,KAAK,IAAI;AACjB,SAAK,WAAW;AAChB,UAAM,EAAE,QAAQ,EAAC,IAAK;AACtB,QAAI,EAAE,IAAG,IAAK;AACd,QAAI,KAAK;AAIP,aAAO,KAAK,IAAI;AAChB,aAAO,MAAM,IAAI;AAAO,eAAO,GAAG,IAAI;AACtC,WAAK,QAAQ,QAAQ,GAAG,IAAI;IAC9B;AACA,SAAK,SAAQ;AACb,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,MAAM,IAAI,EAAE,CAAC,MAAM;AACvB,UAAI,MAAM,IAAI,EAAE,CAAC,MAAM;IACzB;EACF;EACA,SAAM;AACJ,UAAM,EAAE,QAAQ,UAAS,IAAK;AAC9B,SAAK,WAAW,MAAM;AAEtB,UAAM,MAAM,OAAO,MAAM,GAAG,SAAS;AACrC,SAAK,QAAO;AACZ,WAAO;EACT;;AAqBK,IAAM,WAAwC,mCACnD,IACA,CAAC,QAA0B,IAAI,SAAS,GAAG,CAAC;;;AC9R9C,SAAS,WACP,GAAsB,GAAsB,GAAsB,KAAwB,KAAa,SAAS,IAAE;AAElH,MAAI,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAC7C,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAC7C,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAC7C,MAAM,KAAM,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;AAEjD,MAAI,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KACvC,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KACvC,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KACvC,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM;AAC3C,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK,GAAG;AAClC,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;EAChD;AAEA,MAAI,KAAK;AACT,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACvD,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACvD,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACvD,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACvD,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACvD,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACvD,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACvD,MAAI,IAAI,IAAK,MAAM,MAAO;AAAG,MAAI,IAAI,IAAK,MAAM,MAAO;AACzD;AAsBM,SAAU,QACd,GAAsB,GAAsB,GAAsB,KAAsB;AAExF,MAAI,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GACzF,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GACzF,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GACzF,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC,CAAC;AAC7F,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG;AAC9B,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAE9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,EAAE;AAC/C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;AAC9C,UAAO,MAAM,MAAO;AAAG,UAAM,KAAK,MAAM,KAAK,CAAC;EAChD;AAEA,MAAI,KAAK;AACT,MAAI,IAAI,IAAI;AAAK,MAAI,IAAI,IAAI;AAC7B,MAAI,IAAI,IAAI;AAAK,MAAI,IAAI,IAAI;AAC7B,MAAI,IAAI,IAAI;AAAK,MAAI,IAAI,IAAI;AAC7B,MAAI,IAAI,IAAI;AAAK,MAAI,IAAI,IAAI;AAC7B,aAAW,GAAG;AAChB;AA8EO,IAAM,YAA6C,6BAAa,YAAY;EACjF,cAAc;EACd,eAAe;EACf,eAAe;EACf,gBAAgB;CACjB;AA2DD,IAAM,UAA0B,oBAAI,WAAW,EAAE;AAEjD,IAAM,eAAe,CAAC,GAAuC,QAAyB;AACpF,IAAE,OAAO,GAAG;AACZ,QAAM,WAAW,IAAI,SAAS;AAC9B,MAAI;AAAU,MAAE,OAAO,QAAQ,SAAS,QAAQ,CAAC;AACnD;AAIA,IAAM,UAA0B,oBAAI,WAAW,EAAE;AACjD,SAAS,WACP,IACA,KACA,OACA,YACA,KAAsB;AAEtB,MAAI,QAAQ;AAAW,IAAAC,QAAO,KAAK,QAAW,KAAK;AAGnD,QAAM,UAAU,GACd,KACA,OACA,OAA2B;AAE7B,QAAM,UAAU,WAAW,WAAW,QAAQ,MAAM,IAAI,SAAS,GAAG,IAAI;AAIxE,QAAM,IAAI,SAAS,OAAO,OAAO;AACjC,MAAI;AAAK,iBAAa,GAAG,GAAG;AAC5B,eAAa,GAAG,UAAU;AAC1B,IAAE,OAAO,OAAO;AAChB,QAAM,MAAM,EAAE,OAAM;AACpB,EAAAC,OAAM,SAAS,OAAO;AACtB,SAAO;AACT;AASO,IAAM,iBACX,CAAC,cACD,CAAC,KAAuB,OAAyB,QAA4C;AAG3F,QAAM,YAAY;AAClB,SAAO;IACL,QAAQ,WAA6B,QAAyB;AAC5D,YAAM,UAAU,UAAU;AAC1B,eAAS,UAAU,UAAU,WAAW,QAAQ,KAAK;AACrD,aAAO,IAAI,SAAS;AACpB,YAAM,SAAS,OAAO,SAAS,GAAG,CAAC,SAAS;AAE5C,gBACE,KACA,OACA,QACA,QACA,CAAC;AAEH,YAAM,MAAM,WAAW,WAAW,KAAK,OAAO,QAAQ,GAAG;AACzD,aAAO,IAAI,KAAK,OAAO;AACvB,MAAAA,OAAM,GAAG;AACT,aAAO;IACT;IACA,QAAQ,YAA8B,QAAyB;AAC7D,eAAS,UAAU,WAAW,SAAS,WAAW,QAAQ,KAAK;AAC/D,YAAM,OAAO,WAAW,SAAS,GAAG,CAAC,SAAS;AAC9C,YAAM,YAAY,WAAW,SAAS,CAAC,SAAS;AAChD,YAAM,MAAM,WAAW,WAAW,KAAK,OAAO,MAAM,GAAG;AAGvD,UAAI,CAAC,WAAW,WAAW,GAAG,GAAG;AAC/B,QAAAA,OAAM,GAAG;AACT,cAAM,IAAI,MAAM,aAAa;MAC/B;AACA,aAAO,IAAI,WAAW,SAAS,GAAG,CAAC,SAAS,CAAC;AAE7C,gBACE,KACA,OACA,QACA,QACA,CAAC;AAEH,MAAAA,OAAM,GAAG;AACT,aAAO;IACT;;AAEJ;AAgDK,IAAM,oBAAqD;EAChE,EAAE,WAAW,IAAI,aAAa,IAAI,WAAW,GAAE;EAC/B,+BAAe,SAAS;AAAC;;;AC3fpC,IAAM,wBAAwB;AAG9B,IAAM,6BAA6B;AAG1C,IAAM,qBAAqB;AAgB3B,IAAM,eAAe;AACrB,IAAM,aAAqC,CAAC;AAC5C,SAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,IAAK,YAAW,aAAa,CAAC,CAAC,IAAI;AAE5E,SAAS,aAAa,OAA2B;AAC/C,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,UAAM,KAAK,MAAM,CAAC;AAClB,UAAM,KAAK,IAAI,IAAI,MAAM,SAAS,MAAM,IAAI,CAAC,IAAI;AACjD,UAAM,KAAK,IAAI,IAAI,MAAM,SAAS,MAAM,IAAI,CAAC,IAAI;AACjD,WAAO,aAAa,MAAM,CAAC;AAC3B,WAAO,cAAe,KAAK,MAAS,IAAM,MAAM,CAAE;AAClD,WAAO,IAAI,IAAI,MAAM,SAAS,cAAe,KAAK,OAAS,IAAM,MAAM,CAAE,IAAI;AAC7E,WAAO,IAAI,IAAI,MAAM,SAAS,aAAa,KAAK,EAAI,IAAI;AAAA,EAC1D;AACA,SAAO;AACT;AAGA,SAAS,aAAa,GAAuB;AAC3C,MAAI,EAAE,SAAS,MAAM,GAAG;AACtB,UAAM,IAAI,YAAY,6DAA6D,kBAAkB;AAAA,EACvG;AACA,MAAI,UAAU;AACd,MAAI,EAAE,SAAS,IAAI,EAAG,WAAU;AAAA,WACvB,EAAE,SAAS,GAAG,EAAG,WAAU;AACpC,QAAM,OAAO,EAAE,MAAM,GAAG,EAAE,SAAS,OAAO;AAC1C,MAAI,KAAK,SAAS,GAAG,GAAG;AACtB,UAAM,IAAI,YAAY,oDAAoD,kBAAkB;AAAA,EAC9F;AACA,QAAM,MAAM,IAAI,WAAY,EAAE,SAAS,IAAK,IAAI,OAAO;AACvD,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,KAAK,WAAW,KAAK,CAAC,CAAC;AAC7B,UAAM,KAAK,WAAW,KAAK,IAAI,CAAC,CAAC;AACjC,UAAM,KAAK,KAAK,IAAI,CAAC,MAAM,SAAY,WAAW,KAAK,IAAI,CAAC,CAAC,IAAI;AACjE,UAAM,KAAK,KAAK,IAAI,CAAC,MAAM,SAAY,WAAW,KAAK,IAAI,CAAC,CAAC,IAAI;AACjE,QAAI,OAAO,UAAa,OAAO,UAAa,OAAO,UAAa,OAAO,QAAW;AAChF,YAAM,IAAI,YAAY,gDAAgD,kBAAkB;AAAA,IAC1F;AACA,UAAM,SAAU,MAAM,KAAO,MAAM,KAAO,MAAM,IAAK;AACrD,QAAI,IAAI,IAAI,OAAQ,KAAI,GAAG,IAAK,UAAU,KAAM;AAChD,QAAI,IAAI,IAAI,OAAQ,KAAI,GAAG,IAAK,UAAU,IAAK;AAC/C,QAAI,IAAI,IAAI,OAAQ,KAAI,GAAG,IAAI,SAAS;AAAA,EAC1C;AACA,SAAO;AACT;AA2CO,SAAS,kBAAkB,KAAiB,WAAuB,KAA0B;AAClG,QAAM,QAAQC,aAAY,0BAA0B;AACpD,QAAM,aAAa,kBAAkB,KAAK,OAAO,GAAG,EAAE,QAAQ,SAAS;AACvE,QAAM,SAAS,IAAI,WAAW,MAAM,SAAS,WAAW,MAAM;AAC9D,SAAO,IAAI,OAAO,CAAC;AACnB,SAAO,IAAI,YAAY,MAAM,MAAM;AACnC,SAAO,wBAAwB,aAAa,MAAM;AACpD;AAMO,SAAS,kBAAkB,KAAiB,UAAkB,KAA8B;AACjG,MAAI,OAAO,aAAa,YAAY,CAAC,SAAS,WAAW,qBAAqB,GAAG;AAC/E,UAAM,IAAI,YAAY,kDAAkD,kBAAkB;AAAA,EAC5F;AACA,QAAM,SAAS,aAAa,SAAS,MAAM,sBAAsB,MAAM,CAAC;AACxE,MAAI,OAAO,SAAS,6BAA6B,oBAAoB;AACnE,UAAM,IAAI,YAAY,qDAAqD,kBAAkB;AAAA,EAC/F;AACA,QAAM,QAAQ,OAAO,MAAM,GAAG,0BAA0B;AACxD,QAAM,aAAa,OAAO,MAAM,0BAA0B;AAC1D,MAAI;AACF,WAAO,kBAAkB,KAAK,OAAO,GAAG,EAAE,QAAQ,UAAU;AAAA,EAC9D,SAAS,KAAK;AACZ,UAAM,IAAI,YAAY,4EAA4E,oBAAoB,GAAG;AAAA,EAC3H;AACF;AAMO,SAAS,aAAa,KAAiB,WAA2B;AACvE,SAAO,kBAAkB,KAAK,IAAI,YAAY,EAAE,OAAO,SAAS,CAAC;AACnE;AAMO,SAAS,aAAa,KAAiB,UAA0B;AACtE,SAAO,IAAI,YAAY,EAAE,OAAO,kBAAkB,KAAK,QAAQ,CAAC;AAClE;;;ACpJO,IAAM,gCAAgC;AAU7C,SAAS,iBAAiB,KAAa,MAA0B;AAC/D,MAAI,IAAI,WAAW,KAAK,IAAI,SAAS,MAAM,KAAK,CAAC,iBAAiB,KAAK,GAAG,GAAG;AAC3E,UAAM,IAAI,YAAY,WAAW,IAAI,6CAA6C,gBAAgB;AAAA,EACpG;AACA,QAAM,MAAM,IAAI,WAAW,IAAI,SAAS,CAAC;AACzC,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,KAAI,CAAC,IAAI,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;AACtF,SAAO;AACT;AAWO,SAAS,4BAA4B,YAAoB,eAAmC;AACjG,QAAM,OAAO,iBAAiB,YAAY,aAAa;AACvD,QAAM,UAAU,iBAAiB,eAAe,iBAAiB;AAIjE,QAAM,SAAS,UAAU,gBAAgB,MAAM,OAAO;AACtD,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,6BAA6B;AACnE,SAAO,KAAK,QAAQ,QAAQ,QAAW,MAAM,EAAE;AACjD;AAOO,SAAS,sBAAsB,KAAiB,QAA4C;AACjG,QAAM,UAAsC,CAAC;AAC7C,MAAI,OAAO,kBAAkB,UAAa,OAAO,kBAAkB,GAAI,SAAQ,IAAI,OAAO;AAC1F,MAAI,OAAO,SAAS,UAAa,OAAO,SAAS,GAAI,SAAQ,IAAI,OAAO;AACxE,MAAI,QAAQ,MAAM,UAAa,QAAQ,MAAM,OAAW,QAAO;AAC/D,SAAO,aAAa,KAAK,KAAK,UAAU,OAAO,CAAC;AAClD;AAQO,SAAS,sBAAsB,KAAiB,UAAkC;AACvF,QAAM,YAAY,aAAa,KAAK,QAAQ;AAC5C,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,SAAS;AAAA,EAC/B,SAAS,KAAK;AACZ,UAAM,IAAI,YAAY,+CAA+C,oBAAoB,GAAG;AAAA,EAC9F;AACA,MAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,UAAM,IAAI,YAAY,8CAA8C,kBAAkB;AAAA,EACxF;AACA,QAAM,MAAM;AACZ,QAAM,SAAyB,CAAC;AAChC,MAAI,OAAO,IAAI,MAAM,SAAU,QAAO,gBAAgB,IAAI;AAC1D,MAAI,OAAO,IAAI,MAAM,SAAU,QAAO,OAAO,IAAI;AACjD,SAAO;AACT;;;ACnEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EACzC,OAAO;AAAA,EAChB,cAAc;AACZ,UAAM,oGAA+F;AACrG,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,0BAAN,cAAsC,MAAM;AAAA,EAEjD,YAAY,YAA6B,aAAqB;AAC5D,UAAM,4BAA4B,UAAU,KAAK,WAAW,EAAE;AADvB;AAEvC,SAAK,OAAO;AAAA,EACd;AAAA,EAJS,OAAO;AAKlB;AAEO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EACtC,OAAO;AAAA,EAChB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,kBAAkB,YAAoB,cAA8B;AAClF,QAAM,UAAUC,YAAW,UAAU;AACrC,QAAM,YAAYA,YAAW,YAAY;AACzC,QAAM,SAAS,IAAI,WAAW,QAAQ,SAAS,UAAU,MAAM;AAC/D,SAAO,IAAI,SAAS,CAAC;AACrB,SAAO,IAAI,WAAW,QAAQ,MAAM;AACpC,SAAOC,YAAW,OAAO,MAAM,CAAC;AAClC;AAEO,IAAM,oBAAoB;AA+BjC,IAAM,YAAY;AAElB,SAAS,QAAW,OAAqB,MAAqB;AAC5D,QAAM,MAAa,CAAC;AACpB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,KAAM,KAAI,KAAK,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC;AAC9E,SAAO;AACT;AAGA,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC7B,YAAY;AAAA,EACrB,YAAY,OAAgB;AAC1B,UAAM,6CAA6C,OAAO,KAAK,CAAC,EAAE;AAClE,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AACF;AAEA,SAAS,YAAY,KAAuB;AAC1C,SAAO,kBAAkB,GAAG,IAAI,IAAI,oBAAoB,GAAG,IAAI;AACjE;AAEO,IAAM,wBAAN,MAAoD;AAAA,EAChD;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACS,YAAY,IAAI,YAAY;AAAA,EACrC,oBAAmC;AAAA,EAE3C,YAAY,QAAqC;AAC/C,SAAK,SAAS,OAAO;AACrB,SAAK,KAAK,OAAO;AACjB,SAAK,WAAW,OAAO;AACvB,SAAK,UAAU,OAAO;AACtB,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,WAAW,OAAO,gBAAgB;AAAA,EACzC;AAAA,EAEA,iBAAiB,QAAqF;AACpG,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,WAAW,MAAmE;AACpF,QAAI,KAAK,aAAa,KAAM,OAAM,IAAI,yBAAyB;AAC/D,WAAO,KAAK,SAAS,IAAI;AAAA,EAC3B;AAAA;AAAA,EAIA,MAAM,QAAQ,iBAAyB,MAAkB,SAAmD;AAC1G,UAAM,WAAW,MAAM,KAAK,aAAa,iBAAiB,CAAC,IAAI,GAAG,OAAO;AACzE,UAAM,QAAQ,SAAS,CAAC;AACxB,QAAI,UAAU,OAAW,OAAM,IAAI,sBAAsB,6BAA6B;AACtF,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,iBACA,OACA,SAC4B;AAC5B,QAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAChC,UAAM,WAAW,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,UAAU,KAAK,QAAQ,KAAK,CAAC,CAAC;AAClF,UAAM,WAAW,KAAK,cAAc,iBAAiB,OAAO;AAC5D,UAAM,WAAW,MAAM;AAAA,MACrB,KAAK;AAAA,MACL,SAAS,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE;AAAA,IACzD;AACA,UAAM,UAAU,SAAS,IAAI,CAAC,MAA2B;AACvD,YAAM,MAAM,SAAS,IAAI,EAAE,GAAG;AAC9B,UAAI,QAAQ,OAAW,OAAM,IAAI,sBAAsB,qCAAqC,EAAE,GAAG,EAAE;AACnG,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,YAAY,QAAQ;AAAA,QACpB,SAAS,EAAE;AAAA,QACX,WAAW,EAAE;AAAA,QACb,GAAI,aAAa,SAAY,EAAE,MAAM,SAAS,IAAI,CAAC;AAAA,MACrD;AAAA,IACF,CAAC;AACD,WAAO,KAAK,WAAW,SAAS,SAAS,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;AAAA,EACnE;AAAA,EAEA,MAAc,QAAQ,OAA8C;AAClE,UAAM,OAAO,MAAM,KAAK,WAAW,KAAK;AACxC,WAAO;AAAA,MACL;AAAA,MACA,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,MAChB,YAAY,kBAAkB,KAAK,SAAS,KAAK,SAAS;AAAA,MAC1D,KAAKA,YAAW,OAAO,KAAK,CAAC;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,iBAAyB,SAA6C;AAC1F,UAAM,MAAM,4BAA4B,KAAK,SAAS,YAAY,eAAe;AACjF,WAAO,sBAAsB,KAAK;AAAA,MAChC,eAAe,QAAQ;AAAA,MACvB,MAAM,QAAQ;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,WAAW,SAAgC,aAAmD;AAC1G,QAAI,QAAQ,SAAS,GAAG;AACtB,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,OAAO,aAAa,OAAO;AACtD,YAAI,QAAQ,WAAW,QAAQ,QAAQ;AACrC,gBAAM,IAAI;AAAA,YACR,kCAAkC,OAAO,QAAQ,MAAM,CAAC,gBAAgB,OAAO,QAAQ,MAAM,CAAC;AAAA,UAChG;AAAA,QACF;AACA,eAAO,YAAY,IAAI,CAAC,gBAAgB,EAAE,WAAW,EAAE;AAAA,MACzD,SAAS,KAAK;AACZ,YAAI,CAAC,qBAAqB,KAAK,GAAG,EAAG,OAAM;AAAA,MAC7C;AAAA,IACF;AACA,UAAM,WAA8B,CAAC;AACrC,eAAW,CAAC,GAAG,KAAK,KAAK,QAAQ,QAAQ,GAAG;AAC1C,eAAS,KAAK,MAAM,KAAK,WAAW,OAAO,YAAY,CAAC,CAAW,CAAC;AAAA,IACtE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,WAAW,OAA4B,YAA8C;AACjG,QAAI;AACF,YAAM,KAAK,OAAO,QAAQ,KAAK;AAAA,IACjC,SAAS,KAAK;AACZ,UAAI,CAAC,qBAAqB,KAAK,GAAG,EAAG,OAAM;AAAA,IAC7C;AACA,WAAO,EAAE,WAAW;AAAA,EACtB;AAAA;AAAA,EAIA,OAAO,SAAS,aAAuD;AACrE,UAAM,OAAO,MAAM,KAAK,SAAS;AACjC,QAAI,OAAO,MAAM,KAAK,OAAO,YAAY,gBAAgB,SAAY,IAAI,OAAO,WAAW,CAAC;AAC5F,eAAS;AACP,WAAK,oBAAoB,OAAO,KAAK,SAAS;AAC9C,iBAAW,SAAS,KAAK,SAAS;AAChC,YAAI,MAAM,WAAW,YAAa;AAClC,YAAI,KAAK,IAAI,MAAM,OAAO,EAAG;AAC7B,cAAM,KAAK,WAAW,KAAK;AAAA,MAC7B;AACA,UAAI,CAAC,KAAK,KAAM;AAChB,aAAO,MAAM,KAAK,OAAO,YAAY,KAAK,MAAM;AAAA,IAClD;AAAA,EACF;AAAA;AAAA,EAGA,gBAA+B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,WAAW,OAA2C;AAC5D,UAAM,SAAS,KAAK,aAAa,KAAK;AACtC,WAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB,GAAI,MAAM,eAAe,KAAK,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,MAClE,GAAI,MAAM,iBAAiB,KAAK,EAAE,cAAc,MAAM,aAAa,IAAI,CAAC;AAAA,MACxE,GAAI,OAAO,kBAAkB,SAAY,EAAE,eAAe,OAAO,cAAc,IAAI,CAAC;AAAA,MACpF,GAAI,OAAO,SAAS,SAAY,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA,MACzD,QAAQ,OAAO,MAAM,GAAG;AAAA,MACxB,WAAW,MAAM,KAAK,cAAc,KAAK;AAAA,IAC3C;AAAA,EACF;AAAA,EAEQ,aAAa,OAAyC;AAC5D,QAAI,MAAM,SAAS,UAAa,MAAM,iBAAiB,GAAI,QAAO,CAAC;AACnE,QAAI;AACF,YAAM,MAAM,4BAA4B,KAAK,SAAS,YAAY,MAAM,YAAY;AACpF,aAAO,sBAAsB,KAAK,MAAM,IAAI;AAAA,IAC9C,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,OAA8C;AACxE,QAAI,MAAM,kBAAkB,QAAQ,MAAM,WAAW,QAAW;AAC9D,YAAM,IAAI,sBAAsB,iBAAiB,MAAM,OAAO,wCAAwC;AAAA,IACxG;AACA,UAAM,QAAQ,MAAM,KAAK,OAAO,UAAU,MAAM,MAAM;AACtD,UAAM,OAAO,MAAM,KAAK,WAAW,KAAK;AACxC,UAAM,UAAU,kBAAkB,KAAK,SAAS,KAAK,SAAS;AAC9D,QAAI,YAAY,MAAM,SAAS;AAC7B,YAAM,IAAI;AAAA,QACR,sDAAsD,MAAM,OAAO,kBAAkB,OAAO;AAAA,MAC9F;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,IACJ,YACA,aACA,QACe;AACf,QAAI,gBAAgB,WAAW;AAC7B,YAAM,SAAS,MAAM,KAAK,OAAO,MAAM,CAAC,UAAU,GAAG,KAAK,YAAY,WAAW;AACjF,YAAM,SAAS,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,YAAY,UAAU;AACjE,UAAI,WAAW,OAAW,OAAM,IAAI,wBAAwB,YAAY,OAAO,IAAI;AAAA,IACrF,OAAO;AACL,YAAM,KAAK,OAAO,OAAO,CAAC,UAAU,GAAG,MAAM;AAAA,IAC/C;AACA,UAAM,KAAK,WAAW,CAAC,UAAU,CAAC;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,MAA6D;AAC1E,UAAM,UAAoB,CAAC;AAC3B,UAAM,WAAyB,CAAC;AAChC,QAAI;AACF,YAAM,KAAK,aAAa,MAAM,SAAS,QAAQ;AAC/C,YAAM,KAAK,cAAc,MAAM,OAAO;AAAA,IACxC,SAAS,KAAK;AAMZ,YAAM,KAAK,WAAW,OAAO,EAAE,MAAM,CAAC,YAAqB;AACzD,eAAO,KAAK,qBAAqB,6BAA6B,OAAO,QAAQ,MAAM,CAAC,oBAAoB,OAAO;AAAA,MACjH,CAAC;AACD,YAAM,YAAY,GAAG;AAAA,IACvB;AACA,UAAM,KAAK,WAAW,OAAO;AAC7B,WAAO,CAAC,GAAG,UAAU,GAAG,QAAQ,IAAI,CAAC,gBAA4B,EAAE,YAAY,QAAQ,UAAU,EAAE,CAAC;AAAA,EACtG;AAAA,EAEA,MAAc,aACZ,MACA,SACA,UACe;AACf,UAAM,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,gBAAgB,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU;AACnF,eAAW,SAAS,QAAQ,KAAK,SAAS,GAAG;AAC3C,YAAM,SAAS,MAAM,KAAK,OAAO,MAAM,OAAO,KAAK,YAAY,WAAW;AAC1E,cAAQ,KAAK,GAAG,OAAO,OAAO;AAG9B,cAAQ,KAAK,GAAG,OAAO,eAAe,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAC3D,iBAAW,KAAK,OAAO,QAAQ;AAC7B,YAAI,EAAE,SAAS,WAAY,UAAS,KAAK,EAAE,YAAY,EAAE,SAAS,QAAQ,WAAW,CAAC;AAAA,YACjF,OAAM,IAAI,wBAAwB,EAAE,SAAS,EAAE,IAAI;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,MAA6B,SAAkC;AACzF,UAAM,WAAW,oBAAI,IAAsB;AAC3C,eAAW,KAAK,MAAM;AACpB,UAAI,EAAE,gBAAgB,WAAY;AAClC,YAAM,MAAM,EAAE,UAAU;AACxB,YAAM,QAAQ,SAAS,IAAI,GAAG,KAAK,CAAC;AACpC,YAAM,KAAK,EAAE,UAAU;AACvB,eAAS,IAAI,KAAK,KAAK;AAAA,IACzB;AACA,eAAW,CAAC,QAAQ,KAAK,KAAK,UAAU;AACtC,iBAAW,SAAS,QAAQ,OAAO,SAAS,GAAG;AAC7C,cAAM,KAAK,OAAO,OAAO,OAAO,WAAW,KAAK,SAAa,MAA8B;AAG3F,gBAAQ,KAAK,GAAG,KAAK;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,IAA4B;AACjC,QAAI,KAAK,SAAS,KAAM,QAAO,MAAM;AACrC,WAAO,KAAK,KAAK,gBAAgB,WAAW,EAAE;AAAA,EAChD;AAAA;AAAA,EAIA,MAAc,WAAiC;AAC7C,UAAM,MAAM,MAAM,KAAK,GAAG,IAAc,iBAAiB;AACzD,WAAO,IAAI,IAAI,OAAO,CAAC,CAAC;AAAA,EAC1B;AAAA;AAAA,EAGQ,WAAW,aAA+C;AAChE,QAAI,YAAY,WAAW,EAAG,QAAO,QAAQ,QAAQ;AACrD,WAAO,KAAK,UAAU,QAAQ,YAAY;AACxC,YAAM,OAAO,MAAM,KAAK,SAAS;AACjC,iBAAW,MAAM,YAAa,MAAK,IAAI,EAAE;AACzC,YAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC,GAAG,IAAI,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AACF;;;AC/YA,SAAS,6BAA6B;AACtC,SAAS,wBAAwB;AAEjC,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,uBAAuB,2BAA2B;AAC3D,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,8BAA8B;AAGvC,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AACnC,SAAS,wCAAwC;AAGjD,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AACpC,SAAS,gCAAgC;AACzC,SAAS,oCAAoC;AAC7C,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAE1B,SAAS,iBAAiB;AAC1B,SAAS,wCAAwC;AACjD,SAAS,oCAAoC;AAC7C,SAAS,2BAA2B;AACpC,SAAS,kCAAkC;AAC3C,SAAS,mDAAmD;AAC5D,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAE3C,SAAS,2BAA2B;AAOpC,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,sCAAsC;AAC/C,SAAS,qBAAqB;AAC9B,SAAS,gCAAgC;AAGzC,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAGlC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,iBAAiB;AAI1B,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAI1B,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,8BAA8B;AACvC,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAC3B,SAAS,4BAA4B;AACrC,SAAS,8BAA8B;AACvC,SAAS,sCAAsC;AAG/C,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AAGnC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;;;AC/D1B,IAAM,wBAAwB,IAAI,WAAW,CAAC,GAAM,CAAI,CAAC;;;ACgDlD,IAAM,2BAAN,cAAuC,YAAY;AAAA,EACxD,YAAY,SAAiB,OAAiB;AAC5C,UAAM,SAAS,yBAAyB,KAAK;AAC7C,SAAK,OAAO;AAAA,EACd;AACF;;;AC5DO,IAAM,0BAA0B;AAwEvC,IAAM,gBAAgB,IAAI,YAAY,EAAE,OAAO,oBAAoB;AASnE,IAAM,yBAAyB,eAAe,uBAAuB;AAGrE,IAAM,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;;;AC8DtE,IAAM,wBAA6C,oBAAI,IAAI;AAAA,EACzD,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AACtB,CAAC;;;ACtKD,IAAM,OAAO,CAAC,SAA6B,IAAI,YAAY,EAAE,OAAO,IAAI;AAWjE,IAAM,gCAAN,MAAoE;AAAA,EACzE,YAA6B,QAA6C;AAA7C;AAAA,EAA8C;AAAA,EAEnE,SAAS,YAAoB,SAAyB;AAC5D,WAAO,GAAG,WAAW,eAAe,IAAI,UAAU,IAAI,OAAO,OAAO,CAAC;AAAA,EACvE;AAAA,EAEQ,IAAI,YAAoB,SAA6B;AAC3D,WAAO,KAAK,GAAG,UAAU,IAAI,OAAO,OAAO,CAAC,EAAE;AAAA,EAChD;AAAA,EAEA,MAAM,IAAI,YAAoB,SAAiB,OAAwC;AACrF,UAAM,EAAE,IAAI,SAAS,IAAI,KAAK;AAC9B,UAAM,MAAM,KAAK,IAAI,YAAY,OAAO;AACxC,UAAM,WAAW,KAAK,SAAS,YAAY,OAAO;AAClD,QAAI,WAAW,MAAM,GAAG,IAAY,QAAQ;AAC5C,QAAI,aAAa,MAAM;AACrB,iBAAW,kBAAkB,UAAU,OAAO,GAAG;AACjD,YAAM,GAAG,IAAI,UAAU,QAAQ;AAAA,IACjC;AACA,UAAM,SAAS,MAAM,KAAK,KAAK,YAAY,SAAS,QAAQ;AAC5D,WAAO,KAAK,KAAK,OAAO,SAAS,GAAG;AAAA,EACtC;AAAA;AAAA,EAGA,MAAM,iBAAiB,YAAoB,SAAmC;AAC5E,UAAM,WAAW,MAAM,KAAK,OAAO,GAAG,IAAY,KAAK,SAAS,YAAY,OAAO,CAAC;AACpF,QAAI,aAAa,KAAM,QAAO;AAC9B,UAAM,KAAK,KAAK,YAAY,SAAS,QAAQ;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAc,KACZ,YACA,SACA,UACkE;AAClE,UAAM,YAAY,MAAM,KAAK,OAAO,aAAa,oBAAoB,YAAY,SAAS,QAAQ,CAAC;AACnG,WAAO,KAAK,OAAO,OAAO,aAAa,YAAY,SAAS,UAAU,SAAS;AAAA,EACjF;AAAA,EAEA,MAAM,IAAI,YAAoB,SAA6C;AACzE,UAAM,UAAU,MAAM,KAAK,OAAO,OAAO,YAAY,UAAU;AAC/D,UAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO;AACxD,QAAI,WAAW,OAAW,QAAO;AACjC,WAAO,KAAK,KAAK,OAAO,SAAS,KAAK,IAAI,YAAY,OAAO,CAAC;AAAA,EAChE;AAAA,EAEQ,KAAK,UAAkB,KAA6B;AAC1D,QAAI;AACF,aAAO,kBAAkB,KAAK,OAAO,UAAU,UAAU,GAAG;AAAA,IAC9D,SAAS,KAAK;AACZ,UAAI,eAAe,eAAe,IAAI,SAAS,oBAAoB;AACjE,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;","names":["isLE","abytes","anumber","bytesToHex","concatBytes","hexToBytes","isBytes","randomBytes","abytes","concatBytes","_0n","_1n","_0n","_1n","_1n","_0n","_1n","anumber","_0n","_1n","abytes","isLE","_1n","isLE","abytes","_0n","_1n","_1n","_0n","_1n","isLE","_0n","_2n","_0n","_1n","abytes","_3n","_4n","CURVE_ORDER","concatBytes","hexToBytes","endo","bytesToHex","randomBytes","abytes","isBytes","hmac","CURVE_ORDER","_2n","_1n","Signature","r","s","hexToBytes","concatBytes","bytesToHex","_0n","_2n","_3n","sha256","hexToBytes","bytesToHex","sha256","isBytes","abool","anumber","abytes","aexists","aoutput","clean","createView","abytes","isLE","anumber","abool","createView","copyBytes","randomBytes","anumber","abool","abytes","copyBytes","clean","copyBytes","abytes","clean","aexists","aoutput","abytes","clean","randomBytes","hexToBytes","bytesToHex"]}
|
|
1
|
+
{"version":3,"sources":["../../../impl/wallet-api-v2/http.ts","../../../node_modules/@noble/hashes/src/utils.ts","../../../node_modules/@noble/hashes/src/_md.ts","../../../node_modules/@noble/hashes/src/sha2.ts","../../../impl/wallet-api-v2/client.ts","../../../core/logger.ts","../../../modules/payments-v2/stores.ts","../../../node_modules/@noble/curves/src/utils.ts","../../../node_modules/@noble/curves/src/abstract/modular.ts","../../../node_modules/@noble/curves/src/abstract/curve.ts","../../../node_modules/@noble/hashes/src/hmac.ts","../../../node_modules/@noble/curves/src/abstract/weierstrass.ts","../../../node_modules/@noble/curves/src/secp256k1.ts","../../../core/crypto.ts","../../../core/errors.ts","../../../core/wallet-api-protocol.ts","../../../impl/wallet-api-v2/session.ts","../../../impl/wallet-api-v2/storage.ts","../../../modules/payments-v2/async.ts","../../../node_modules/@noble/hashes/src/hkdf.ts","../../../node_modules/@noble/ciphers/src/utils.ts","../../../node_modules/@noble/ciphers/src/_arx.ts","../../../node_modules/@noble/ciphers/src/_poly1305.ts","../../../node_modules/@noble/ciphers/src/chacha.ts","../../../core/field-encryption.ts","../../../core/delivery-envelope.ts","../../../impl/wallet-api-v2/mailbox.ts","../../../token-engine/sdk.ts","../../../token-engine/identity.ts","../../../token-engine/errors.ts","../../../token-engine/nft-payload.ts","../../../token-engine/SphereTokenEngine.ts","../../../impl/wallet-api-v2/checkpoints.ts"],"sourcesContent":["// §5.1 http plumbing: fetch wrapper, https rule, typed error envelope.\n\nexport interface HttpResponseLike {\n readonly status: number;\n readonly ok: boolean;\n readonly headers?: { get(name: string): string | null };\n text(): Promise<string>;\n arrayBuffer(): Promise<ArrayBuffer>;\n}\n\nexport interface HttpRequestInit {\n method: string;\n headers?: Record<string, string>;\n body?: string | Uint8Array;\n}\n\nexport type FetchLike = (url: string, init?: HttpRequestInit) => Promise<HttpResponseLike>;\n\nexport class WalletApiHttpError extends Error {\n readonly status: number;\n readonly code: string;\n /** Milliseconds, parsed from a Retry-After header when present. */\n readonly retryAfter?: number;\n\n constructor(status: number, code: string, message: string, retryAfter?: number) {\n super(message);\n this.name = 'WalletApiHttpError';\n this.status = status;\n this.code = code;\n if (retryAfter !== undefined) this.retryAfter = retryAfter;\n }\n}\n\n/** Asking again may work; escalating will not. 0 is fetchRaw's NETWORK wrapper. */\nconst RETRYABLE_STATUSES = new Set([0, 408, 425, 429, 500, 502, 503, 504]);\n\nexport function isRetryableStatus(err: unknown): boolean {\n return err instanceof WalletApiHttpError && RETRYABLE_STATUSES.has(err.status);\n}\n\nexport function isWalletApiHttpError(err: unknown, status?: number): err is WalletApiHttpError {\n return err instanceof WalletApiHttpError && (status === undefined || err.status === status);\n}\n\nexport interface WalletApiHttpConfig {\n baseUrl: string;\n fetchFn: FetchLike;\n /** Bearer source; `null` sends the request unauthenticated. */\n getToken: () => string | null;\n}\n\nexport interface RequestOptions {\n /** Default true; auth endpoints opt out so a stale bearer is never attached. */\n auth?: boolean;\n}\n\nexport interface WalletApiHttp {\n readonly baseUrl: string;\n request(method: string, path: string, body?: unknown, opts?: RequestOptions): Promise<unknown>;\n /** Direct fetch for presigned S3 URLs — no base URL, no bearer. */\n fetchRaw(url: string, init: HttpRequestInit): Promise<HttpResponseLike>;\n}\n\nfunction isLoopbackHost(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname.endsWith('.localhost') ||\n /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname) ||\n hostname === '::1' ||\n hostname === '[::1]'\n );\n}\n\n/** ARCHITECTURE §4 transport rule: non-loopback MUST be https. Returns the URL without a trailing slash. */\nexport function assertSecureBaseUrl(baseUrl: string): string {\n let url: URL;\n try {\n url = new URL(baseUrl);\n } catch {\n throw new Error(`Invalid wallet-api base URL: ${baseUrl}`);\n }\n const httpLoopback = url.protocol === 'http:' && isLoopbackHost(url.hostname);\n if (url.protocol !== 'https:' && !httpLoopback) {\n throw new Error('wallet-api base URL must be https (plain http is allowed only on loopback)');\n }\n return url.toString().replace(/\\/$/, '');\n}\n\nfunction parseRetryAfter(res: HttpResponseLike): number | undefined {\n const raw = res.headers?.get('retry-after');\n if (!raw) return undefined;\n const seconds = Number(raw);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const when = Date.parse(raw);\n return Number.isNaN(when) ? undefined : Math.max(0, when - Date.now());\n}\n\nasync function readBodyText(res: HttpResponseLike): Promise<string> {\n try {\n return await res.text();\n } catch {\n return '';\n }\n}\n\n/** Parse the `{ error: { code, message } }` envelope into the typed error. */\nasync function toHttpError(res: HttpResponseLike, what: string): Promise<WalletApiHttpError> {\n let code = `HTTP_${res.status}`;\n let message = `${what} failed with status ${res.status}`;\n const text = await readBodyText(res);\n if (text !== '') {\n try {\n const parsed = JSON.parse(text) as { error?: { code?: string; message?: string } };\n if (parsed?.error?.code) code = parsed.error.code;\n if (parsed?.error?.message) message = `${what}: ${parsed.error.message}`;\n } catch {\n // non-JSON error body — keep the generic message\n }\n }\n return new WalletApiHttpError(res.status, code, message, parseRetryAfter(res));\n}\n\nfunction parseJsonBody(text: string, what: string, status: number): unknown {\n if (text === '') return null;\n try {\n return JSON.parse(text);\n } catch {\n throw new WalletApiHttpError(status, 'PROTOCOL', `${what}: response is not JSON`);\n }\n}\n\nexport function createWalletApiHttp(config: WalletApiHttpConfig): WalletApiHttp {\n const baseUrl = assertSecureBaseUrl(config.baseUrl);\n const { fetchFn, getToken } = config;\n\n const fetchRaw = async (url: string, init: HttpRequestInit): Promise<HttpResponseLike> => {\n try {\n return await fetchFn(url, init);\n } catch (err) {\n throw new WalletApiHttpError(\n 0,\n 'NETWORK',\n `wallet-api request failed: ${init.method} ${url}: ${String(err)}`\n );\n }\n };\n\n const request = async (\n method: string,\n path: string,\n body?: unknown,\n opts?: RequestOptions\n ): Promise<unknown> => {\n const headers: Record<string, string> = {};\n if (body !== undefined) headers['content-type'] = 'application/json';\n if (opts?.auth !== false) {\n const token = getToken();\n if (token !== null) headers['authorization'] = `Bearer ${token}`;\n }\n const res = await fetchRaw(`${baseUrl}${path}`, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n const what = `${method} ${path}`;\n if (res.status === 204) return null;\n if (!res.ok) throw await toHttpError(res, what);\n return parseJsonBody(await readBodyText(res), what, res.status);\n };\n\n return { baseUrl, request, fetchRaw };\n}\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n/**\n * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.\n * @param a - value to test\n * @returns `true` when the value is a Uint8Array-compatible view.\n * @example\n * Check whether a value is a Uint8Array-compatible view.\n * ```ts\n * isBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.\n // The fallback still requires a real ArrayBuffer view, so plain\n // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and\n // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n\n/**\n * Asserts something is a non-negative integer.\n * @param n - number to validate\n * @param title - label included in thrown errors\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a non-negative integer option.\n * ```ts\n * anumber(32, 'length');\n * ```\n */\nexport function anumber(n: number, title: string = ''): void {\n if (typeof n !== 'number') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(`${prefix}expected number, got ${typeof n}`);\n }\n if (!Number.isSafeInteger(n) || n < 0) {\n const prefix = title && `\"${title}\" `;\n throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);\n }\n}\n\n/**\n * Asserts something is Uint8Array.\n * @param value - value to validate\n * @param length - optional exact length constraint\n * @param title - label included in thrown errors\n * @returns The validated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate that a value is a byte array.\n * ```ts\n * abytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function abytes(\n value: TArg<Uint8Array>,\n length?: number,\n title: string = ''\n): TRet<Uint8Array> {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n if (!bytes) throw new TypeError(message);\n throw new RangeError(message);\n }\n return value as TRet<Uint8Array>;\n}\n\n/**\n * Copies bytes into a fresh Uint8Array.\n * Buffer-style slices can alias the same backing store, so callers that need ownership should copy.\n * @param bytes - source bytes to clone\n * @returns Freshly allocated copy of `bytes`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Clone a byte array before mutating it.\n * ```ts\n * const copy = copyBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Asserts something is a wrapped hash constructor.\n * @param h - hash constructor to validate\n * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError}\n * @throws On invalid hash metadata ranges or values. {@link RangeError}\n * @throws If the hash metadata allows empty outputs or block sizes. {@link Error}\n * @example\n * Validate a callable hash wrapper.\n * ```ts\n * import { ahash } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * ahash(sha256);\n * ```\n */\nexport function ahash(h: TArg<CHash>): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new TypeError('Hash must wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass\n // validation and can produce empty outputs instead of failing fast.\n if (h.outputLen < 1) throw new Error('\"outputLen\" must be >= 1');\n if (h.blockLen < 1) throw new Error('\"blockLen\" must be >= 1');\n}\n\n/**\n * Asserts a hash instance has not been destroyed or finished.\n * @param instance - hash instance to validate\n * @param checkFinished - whether to reject finalized instances\n * @throws If the hash instance has already been destroyed or finalized. {@link Error}\n * @example\n * Validate that a hash instance is still usable.\n * ```ts\n * import { aexists } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aexists(hash);\n * ```\n */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/**\n * Asserts output is a sufficiently-sized byte array.\n * @param out - destination buffer\n * @param instance - hash instance providing output length\n * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a caller-provided digest buffer.\n * ```ts\n * import { aoutput } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aoutput(new Uint8Array(hash.outputLen), hash);\n * ```\n */\nexport function aoutput(out: any, instance: any): void {\n abytes(out, undefined, 'digestInto() output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new RangeError('\"digestInto() output\" expected to be of length >=' + min);\n }\n}\n\n/** Generic type encompassing 8/16/32-byte array views, but not 64-bit variants. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/**\n * Casts a typed array view to Uint8Array.\n * @param arr - source typed array\n * @returns Uint8Array view over the same buffer.\n * @example\n * Reinterpret a typed array as bytes.\n * ```ts\n * u8(new Uint32Array([1, 2]));\n * ```\n */\nexport function u8(arr: TArg<TypedArray>): TRet<Uint8Array> {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet<Uint8Array>;\n}\n\n/**\n * Casts a typed array view to Uint32Array.\n * `arr.byteOffset` must already be 4-byte aligned or the platform\n * Uint32Array constructor will throw.\n * @param arr - source typed array\n * @returns Uint32Array view over the same buffer.\n * @example\n * Reinterpret a byte array as 32-bit words.\n * ```ts\n * u32(new Uint8Array(8));\n * ```\n */\nexport function u32(arr: TArg<TypedArray>): TRet<Uint32Array> {\n return new Uint32Array(\n arr.buffer,\n arr.byteOffset,\n Math.floor(arr.byteLength / 4)\n ) as TRet<Uint32Array>;\n}\n\n/**\n * Zeroizes typed arrays in place. Warning: JS provides no guarantees.\n * @param arrays - arrays to overwrite with zeros\n * @example\n * Zeroize sensitive buffers in place.\n * ```ts\n * clean(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function clean(...arrays: TArg<TypedArray[]>): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/**\n * Creates a DataView for byte-level manipulation.\n * @param arr - source typed array\n * @returns DataView over the same buffer region.\n * @example\n * Create a DataView over an existing buffer.\n * ```ts\n * createView(new Uint8Array(4));\n * ```\n */\nexport function createView(arr: TArg<TypedArray>): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Rotate-right operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the right.\n * ```ts\n * rotr(0x12345678, 8);\n * ```\n */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n\n/**\n * Rotate-left operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the left.\n * ```ts\n * rotl(0x12345678, 8);\n * ```\n */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Whether the current platform is little-endian. */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/**\n * Byte-swap operation for uint32 values.\n * @param word - source word\n * @returns Word with reversed byte order.\n * @example\n * Reverse the byte order of a 32-bit word.\n * ```ts\n * byteSwap(0x11223344);\n * ```\n */\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/**\n * Conditionally byte-swaps one 32-bit word on big-endian platforms.\n * @param n - source word\n * @returns Original or byte-swapped word depending on platform endianness.\n * @example\n * Normalize a 32-bit word for host endianness.\n * ```ts\n * swap8IfBE(0x11223344);\n * ```\n */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n) >>> 0;\n\n/**\n * Byte-swaps every word of a Uint32Array in place.\n * @param arr - array to mutate\n * @returns The same array after mutation; callers pass live state arrays here.\n * @example\n * Reverse the byte order of every word in place.\n * ```ts\n * byteSwap32(new Uint32Array([0x11223344]));\n * ```\n */\nexport function byteSwap32(arr: TArg<Uint32Array>): TRet<Uint32Array> {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr as TRet<Uint32Array>;\n}\n\n/**\n * Conditionally byte-swaps a Uint32Array on big-endian platforms.\n * @param u - array to normalize for host endianness\n * @returns Original or byte-swapped array depending on platform endianness.\n * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`.\n * @example\n * Normalize a word array for host endianness.\n * ```ts\n * swap32IfBE(new Uint32Array([0x11223344]));\n * ```\n */\nexport const swap32IfBE: (u: TArg<Uint32Array>) => TRet<Uint32Array> = isLE\n ? (u: TArg<Uint32Array>) => u as TRet<Uint32Array>\n : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string.\n * Uses the built-in function when available and assumes it matches the tested\n * fallback semantics.\n * @param bytes - bytes to encode\n * @returns Lowercase hexadecimal string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Convert bytes to lowercase hexadecimal.\n * ```ts\n * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'\n * ```\n */\nexport function bytesToHex(bytes: TArg<Uint8Array>): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @param hex - hexadecimal string to decode\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Decode lowercase hexadecimal into bytes.\n * ```ts\n * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n * ```\n */\nexport function hexToBytes(hex: string): TRet<Uint8Array> {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n if (hasHexBuiltin) {\n try {\n return (Uint8Array as any).fromHex(hex);\n } catch (error) {\n if (error instanceof SyntaxError) throw new RangeError(error.message);\n throw error;\n }\n }\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new RangeError(\n 'hex string expected, got non-hex character \"' + char + '\" at index ' + hi\n );\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * This yields to the Promise/microtask scheduler queue, not to timers or the\n * full macrotask event loop.\n * @example\n * Yield to the next scheduler tick.\n * ```ts\n * await nextTick();\n * ```\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/**\n * Returns control to the Promise/microtask scheduler every `tick`\n * milliseconds to avoid blocking long loops.\n * @param iters - number of loop iterations to run\n * @param tick - maximum time slice in milliseconds\n * @param cb - callback executed on each iteration\n * @example\n * Run a loop that periodically yields back to the event loop.\n * ```ts\n * await asyncLoop(2, 0, () => {});\n * ```\n */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * Built-in doesn't validate input to be string: we do the check.\n * Non-ASCII details are delegated to the platform `TextEncoder`.\n * @param str - string to encode\n * @returns UTF-8 encoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encode a string as UTF-8 bytes.\n * ```ts\n * utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99])\n * ```\n */\nexport function utf8ToBytes(str: string): TRet<Uint8Array> {\n if (typeof str !== 'string') throw new TypeError('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n\n/**\n * Helper for KDFs: consumes Uint8Array or string.\n * String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer.\n * @param data - user-provided KDF input\n * @param errorTitle - label included in thrown errors\n * @returns Byte representation of the input.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Normalize KDF input to bytes.\n * ```ts\n * kdfInputToBytes('password');\n * ```\n */\nexport function kdfInputToBytes(data: TArg<KDFInput>, errorTitle = ''): TRet<Uint8Array> {\n if (typeof data === 'string') return utf8ToBytes(data);\n return abytes(data, undefined, errorTitle);\n}\n\n/**\n * Copies several Uint8Arrays into one.\n * @param arrays - arrays to concatenate\n * @returns Concatenated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Concatenate multiple byte arrays.\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nexport function concatBytes(...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\ntype EmptyObj = {};\n/**\n * Merges default options and passed options.\n * @param defaults - base option object\n * @param opts - user overrides\n * @returns Merged option object. The merge mutates `defaults` in place.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Merge user overrides onto default options.\n * ```ts\n * checkOpts({ dkLen: 32 }, { asyncTick: 10 });\n * ```\n */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new TypeError('options must be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Common interface for all hash instances. */\nexport interface Hash<T> {\n /** Bytes processed per compression block. */\n blockLen: number;\n /** Bytes produced by `digest()`. */\n outputLen: number;\n /** Whether the instance supports XOF-style variable-length output via `xof()` / `xofInto()`. */\n canXOF: boolean;\n /**\n * Absorbs more message bytes into the running hash state.\n * @param buf - message chunk to absorb\n * @returns The same hash instance for chaining.\n */\n update(buf: TArg<Uint8Array>): this;\n /**\n * Finalizes the hash into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Nothing. Implementations write into `buf` in place.\n */\n digestInto(buf: TArg<Uint8Array>): void;\n /**\n * Finalizes the hash and returns a freshly allocated digest.\n * @returns Digest bytes.\n */\n digest(): TRet<Uint8Array>;\n /** Wipes internal state and makes the instance unusable. */\n destroy(): void;\n /**\n * Copies the current hash state into an existing or new instance.\n * @param to - Optional destination instance to reuse.\n * @returns Cloned hash state.\n */\n _cloneInto(to?: T): T;\n /**\n * Creates an independent copy of the current hash state.\n * @returns Cloned hash instance.\n */\n clone(): T;\n}\n\n/** Pseudorandom generator interface. */\nexport interface PRG {\n /**\n * Mixes more entropy into the generator state.\n * @param seed - fresh entropy bytes\n * @returns Nothing. Implementations update internal state in place.\n */\n addEntropy(seed: TArg<Uint8Array>): void;\n /**\n * Generates pseudorandom output bytes.\n * @param length - number of bytes to generate\n * @returns Generated pseudorandom bytes.\n */\n randomBytes(length: number): TRet<Uint8Array>;\n /** Wipes generator state and makes the instance unusable. */\n clean(): void;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n /**\n * Reads more bytes from the XOF stream.\n * @param bytes - number of bytes to read\n * @returns Requested digest bytes.\n */\n xof(bytes: number): TRet<Uint8Array>;\n /**\n * Reads more bytes from the XOF stream into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Filled output buffer.\n */\n xofInto(buf: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/** Hash constructor or factory type. */\nexport type HasherCons<T, Opts = undefined> = Opts extends undefined ? () => T : (opts?: Opts) => T;\n/** Optional hash metadata. */\nexport type HashInfo = {\n /** DER-encoded object identifier bytes for the hash algorithm. */\n oid?: TRet<Uint8Array>;\n};\n/** Callable hash function type. */\nexport type CHash<T extends Hash<T> = Hash<any>, Opts = undefined> = {\n /** Digest size in bytes. */\n outputLen: number;\n /** Input block size in bytes. */\n blockLen: number;\n /** Whether `.create()` returns a hash instance that can be used as an XOF stream. */\n canXOF: boolean;\n} & HashInfo &\n (Opts extends undefined\n ? {\n (msg: TArg<Uint8Array>): TRet<Uint8Array>;\n create(): T;\n }\n : {\n (msg: TArg<Uint8Array>, opts?: TArg<Opts>): TRet<Uint8Array>;\n create(opts?: Opts): T;\n });\n/** Callable extendable-output hash function type. */\nexport type CHashXOF<T extends HashXOF<T> = HashXOF<any>, Opts = undefined> = CHash<T, Opts>;\n\n/**\n * Creates a callable hash function from a stateful class constructor.\n * @param hashCons - hash constructor or factory\n * @param info - optional metadata such as DER OID\n * @returns Frozen callable hash wrapper with `.create()`.\n * Wrapper construction eagerly calls `hashCons(undefined)` once to read\n * `outputLen` / `blockLen`, so constructor side effects happen at module\n * init time.\n * @example\n * Wrap a stateful hash constructor into a callable helper.\n * ```ts\n * import { createHasher } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const wrapped = createHasher(sha256.create, { oid: sha256.oid });\n * wrapped(new Uint8Array([1]));\n * ```\n */\nexport function createHasher<T extends Hash<T>, Opts = undefined>(\n hashCons: HasherCons<T, Opts>,\n info: TArg<HashInfo> = {}\n): TRet<CHash<T, Opts>> {\n const hashC: any = (msg: TArg<Uint8Array>, opts?: TArg<Opts>) =>\n hashCons(opts as Opts)\n .update(msg)\n .digest();\n const tmp = hashCons(undefined);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.canXOF = tmp.canXOF;\n hashC.create = (opts?: Opts) => hashCons(opts);\n Object.assign(hashC, info);\n return Object.freeze(hashC) as TRet<CHash<T, Opts>>;\n}\n\n/**\n * Cryptographically secure PRNG backed by `crypto.getRandomValues`.\n * @param bytesLength - number of random bytes to generate\n * @returns Random bytes.\n * The platform `getRandomValues()` implementation still defines any\n * single-call length cap, and this helper rejects oversize requests\n * with a stable library `RangeError` instead of host-specific errors.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error}\n * @example\n * Generate a fresh random key or nonce.\n * ```ts\n * const key = randomBytes(16);\n * ```\n */\nexport function randomBytes(bytesLength = 32): TRet<Uint8Array> {\n // Match the repo's other length-taking helpers instead of relying on Uint8Array coercion.\n anumber(bytesLength, 'bytesLength');\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n // Web Cryptography API Level 2 §10.1.1:\n // if `byteLength > 65536`, throw `QuotaExceededError`.\n // Keep the guard explicit so callers can see the quota in code\n // instead of discovering it by reading the spec or host errors.\n // This wrapper surfaces the same quota as a stable library RangeError.\n if (bytesLength > 65536)\n throw new RangeError(`\"bytesLength\" expected <= 65536, got ${bytesLength}`);\n return cr.getRandomValues(new Uint8Array(bytesLength));\n}\n\n/**\n * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.\n * @param suffix - final OID byte for the selected hash.\n * The helper accepts any byte even though only the documented NIST hash\n * suffixes are meaningful downstream.\n * @returns Object containing the DER-encoded OID.\n * @example\n * Build OID metadata for a NIST hash.\n * ```ts\n * oidNist(0x01);\n * ```\n */\nexport const oidNist = (suffix: number): TRet<Required<HashInfo>> => ({\n // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.\n // Larger suffix values would need base-128 OID encoding and a different length byte.\n oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),\n});\n","/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n createView,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`.\n * Returns bits from `b` when `a` is set, otherwise from `c`.\n * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never\n * set the same bit.\n * @param a - selector word\n * @param b - word chosen when selector bit is set\n * @param c - word chosen when selector bit is clear\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit choice primitive.\n * ```ts\n * Chi(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Chi(a: number, b: number, c: number): number {\n return (a & b) ^ (~a & c);\n}\n\n/**\n * Shared 32-bit majority primitive reused by SHA-256 and SHA-1.\n * Returns bits shared by at least two inputs.\n * @param a - first input word\n * @param b - second input word\n * @param c - third input word\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit majority primitive.\n * ```ts\n * Maj(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Maj(a: number, b: number, c: number): number {\n return (a & b) ^ (a & c) ^ (b & c);\n}\n\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit\n * strings with partial-byte tails.\n * @param blockLen - internal block size in bytes\n * @param outputLen - digest size in bytes\n * @param padOffset - trailing length field size in bytes\n * @param isLE - whether length and state words are encoded in little-endian\n * @example\n * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.\n * ```ts\n * import { _SHA1 } from '@noble/hashes/legacy.js';\n * const hash = new _SHA1();\n * hash.update(new Uint8Array([97, 98, 99]));\n * hash.digest();\n * ```\n */\nexport abstract class HashMD<T extends HashMD<T>> implements Hash<T> {\n // Subclasses must treat `buf` as read-only: `update()` may pass a direct view over caller input\n // when it can process whole blocks without buffering first.\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n\n readonly blockLen: number;\n readonly outputLen: number;\n readonly canXOF = false;\n readonly padOffset: number;\n readonly isLE: boolean;\n\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n const { view, buffer, blockLen } = this;\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path only when there is no buffered partial block: `take === blockLen` implies\n // `this.pos === 0`, so we can process full blocks directly from the input view.\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n clean(this.buffer.subarray(pos));\n // we have less than padOffset left in buffer, so we cannot put length in\n // current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from\n // the padding fill above, and JS will overflow before user input can make that half non-zero.\n // So we only need to write the low 64 bits here.\n view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen must be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return\n // fresh bytes to the caller.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.destroyed = destroyed;\n to.finished = finished;\n to.length = length;\n to.pos = pos;\n // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and\n // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.\n if (length % blockLen) to.buffer.set(buffer);\n return to as unknown as any;\n }\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n\n/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the\n * square roots of the first eight prime numbers. Exported as a shared table; callers must treat\n * it as read-only because constructors copy words from it by index. */\nexport const SHA256_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must\n * treat it as read-only because constructors copy words from it by index. */\nexport const SHA224_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n]);\n\n/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth\n * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only\n * because constructors copy halves from it by index. */\nexport const SHA384_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,\n]);\n\n/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first\n * eight prime numbers. Exported as a shared table; callers must treat it as read-only because\n * constructors copy halves from it by index. */\nexport const SHA512_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,\n]);\n","/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and\n * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.\n * @module\n */\nimport { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';\nimport * as u64 from './_u64.ts';\nimport { type CHash, clean, createHasher, oidNist, rotr, type TRet } from './utils.ts';\n\n/**\n * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits\n * of the cube roots of the first 64 primes (2..311).\n */\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\n\n/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */\nabstract class SHA2_32B<T extends SHA2_32B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected abstract A: number;\n protected abstract B: number;\n protected abstract C: number;\n protected abstract D: number;\n protected abstract E: number;\n protected abstract F: number;\n protected abstract G: number;\n protected abstract H: number;\n\n constructor(outputLen: number) {\n super(64, outputLen, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean(): void {\n clean(SHA256_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */\nexport class _SHA256 extends SHA2_32B<_SHA256> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected A: number = SHA256_IV[0] | 0;\n protected B: number = SHA256_IV[1] | 0;\n protected C: number = SHA256_IV[2] | 0;\n protected D: number = SHA256_IV[3] | 0;\n protected E: number = SHA256_IV[4] | 0;\n protected F: number = SHA256_IV[5] | 0;\n protected G: number = SHA256_IV[6] | 0;\n protected H: number = SHA256_IV[7] | 0;\n constructor() {\n super(32);\n }\n}\n\n/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */\nexport class _SHA224 extends SHA2_32B<_SHA224> {\n protected A: number = SHA224_IV[0] | 0;\n protected B: number = SHA224_IV[1] | 0;\n protected C: number = SHA224_IV[2] | 0;\n protected D: number = SHA224_IV[3] | 0;\n protected E: number = SHA224_IV[4] | 0;\n protected F: number = SHA224_IV[5] | 0;\n protected G: number = SHA224_IV[6] | 0;\n protected H: number = SHA224_IV[7] | 0;\n constructor() {\n super(28);\n }\n}\n\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n\n// SHA-384 / SHA-512 round constants from RFC 6234 §5.2:\n// 80 full 64-bit words split into high/low halves.\n// prettier-ignore\nconst K512 = /* @__PURE__ */ (() => u64.split([\n '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n\n// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\n// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n\n/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */\nabstract class SHA2_64B<T extends SHA2_64B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n // h -- high 32 bits, l -- low 32 bits\n protected abstract Ah: number;\n protected abstract Al: number;\n protected abstract Bh: number;\n protected abstract Bl: number;\n protected abstract Ch: number;\n protected abstract Cl: number;\n protected abstract Dh: number;\n protected abstract Dl: number;\n protected abstract Eh: number;\n protected abstract El: number;\n protected abstract Fh: number;\n protected abstract Fl: number;\n protected abstract Gh: number;\n protected abstract Gl: number;\n protected abstract Hh: number;\n protected abstract Hl: number;\n\n constructor(outputLen: number) {\n super(128, outputLen, 16, false);\n }\n // prettier-ignore\n protected get(): [\n number, number, number, number, number, number, number, number,\n number, number, number, number, number, number, number, number\n ] {\n const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n }\n // prettier-ignore\n protected set(\n Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number,\n Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number\n ): void {\n this.Ah = Ah | 0;\n this.Al = Al | 0;\n this.Bh = Bh | 0;\n this.Bl = Bl | 0;\n this.Ch = Ch | 0;\n this.Cl = Cl | 0;\n this.Dh = Dh | 0;\n this.Dl = Dl | 0;\n this.Eh = Eh | 0;\n this.El = El | 0;\n this.Fh = Fh | 0;\n this.Fl = Fl | 0;\n this.Gh = Gh | 0;\n this.Gl = Gl | 0;\n this.Hh = Hh | 0;\n this.Hl = Hl | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) {\n SHA512_W_H[i] = view.getUint32(offset);\n SHA512_W_L[i] = view.getUint32((offset += 4));\n }\n for (let i = 16; i < 80; i++) {\n // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n const W15h = SHA512_W_H[i - 15] | 0;\n const W15l = SHA512_W_L[i - 15] | 0;\n const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n const W2h = SHA512_W_H[i - 2] | 0;\n const W2l = SHA512_W_L[i - 2] | 0;\n const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16];\n const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n SHA512_W_H[i] = SUMh | 0;\n SHA512_W_L[i] = SUMl | 0;\n }\n let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n // Compression function main loop, 80 rounds\n for (let i = 0; i < 80; i++) {\n // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n const CHIl = (El & Fl) ^ (~El & Gl);\n // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n // prettier-ignore\n const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n const T1l = T1ll | 0;\n // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n Hh = Gh | 0;\n Hl = Gl | 0;\n Gh = Fh | 0;\n Gl = Fl | 0;\n Fh = Eh | 0;\n Fl = El | 0;\n ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n Dh = Ch | 0;\n Dl = Cl | 0;\n Ch = Bh | 0;\n Cl = Bl | 0;\n Bh = Ah | 0;\n Bl = Al | 0;\n const All = u64.add3L(T1l, sigma0l, MAJl);\n Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n Al = All | 0;\n }\n // Add the compressed chunk to the current hash value\n ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n }\n protected roundClean(): void {\n clean(SHA512_W_H, SHA512_W_L);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n}\n\n/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA512 extends SHA2_64B<_SHA512> {\n protected Ah: number = SHA512_IV[0] | 0;\n protected Al: number = SHA512_IV[1] | 0;\n protected Bh: number = SHA512_IV[2] | 0;\n protected Bl: number = SHA512_IV[3] | 0;\n protected Ch: number = SHA512_IV[4] | 0;\n protected Cl: number = SHA512_IV[5] | 0;\n protected Dh: number = SHA512_IV[6] | 0;\n protected Dl: number = SHA512_IV[7] | 0;\n protected Eh: number = SHA512_IV[8] | 0;\n protected El: number = SHA512_IV[9] | 0;\n protected Fh: number = SHA512_IV[10] | 0;\n protected Fl: number = SHA512_IV[11] | 0;\n protected Gh: number = SHA512_IV[12] | 0;\n protected Gl: number = SHA512_IV[13] | 0;\n protected Hh: number = SHA512_IV[14] | 0;\n protected Hl: number = SHA512_IV[15] | 0;\n\n constructor() {\n super(64);\n }\n}\n\n/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA384 extends SHA2_64B<_SHA384> {\n protected Ah: number = SHA384_IV[0] | 0;\n protected Al: number = SHA384_IV[1] | 0;\n protected Bh: number = SHA384_IV[2] | 0;\n protected Bl: number = SHA384_IV[3] | 0;\n protected Ch: number = SHA384_IV[4] | 0;\n protected Cl: number = SHA384_IV[5] | 0;\n protected Dh: number = SHA384_IV[6] | 0;\n protected Dl: number = SHA384_IV[7] | 0;\n protected Eh: number = SHA384_IV[8] | 0;\n protected El: number = SHA384_IV[9] | 0;\n protected Fh: number = SHA384_IV[10] | 0;\n protected Fl: number = SHA384_IV[11] | 0;\n protected Gh: number = SHA384_IV[12] | 0;\n protected Gl: number = SHA384_IV[13] | 0;\n protected Hh: number = SHA384_IV[14] | 0;\n protected Hl: number = SHA384_IV[15] | 0;\n\n constructor() {\n super(48);\n }\n}\n\n/**\n * Truncated SHA512/256 and SHA512/224.\n * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as \"intermediary\" IV of SHA512/t.\n * Then t hashes string to produce result IV.\n * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`.\n * These IV literals are checked against that script rather than a dedicated\n * local RFC section.\n */\n\n/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T224_IV = /* @__PURE__ */ Uint32Array.from([\n 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf,\n 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1,\n]);\n\n/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T256_IV = /* @__PURE__ */ Uint32Array.from([\n 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd,\n 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2,\n]);\n\n/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_224 extends SHA2_64B<_SHA512_224> {\n protected Ah: number = T224_IV[0] | 0;\n protected Al: number = T224_IV[1] | 0;\n protected Bh: number = T224_IV[2] | 0;\n protected Bl: number = T224_IV[3] | 0;\n protected Ch: number = T224_IV[4] | 0;\n protected Cl: number = T224_IV[5] | 0;\n protected Dh: number = T224_IV[6] | 0;\n protected Dl: number = T224_IV[7] | 0;\n protected Eh: number = T224_IV[8] | 0;\n protected El: number = T224_IV[9] | 0;\n protected Fh: number = T224_IV[10] | 0;\n protected Fl: number = T224_IV[11] | 0;\n protected Gh: number = T224_IV[12] | 0;\n protected Gl: number = T224_IV[13] | 0;\n protected Hh: number = T224_IV[14] | 0;\n protected Hl: number = T224_IV[15] | 0;\n\n constructor() {\n super(28);\n }\n}\n\n/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_256 extends SHA2_64B<_SHA512_256> {\n protected Ah: number = T256_IV[0] | 0;\n protected Al: number = T256_IV[1] | 0;\n protected Bh: number = T256_IV[2] | 0;\n protected Bl: number = T256_IV[3] | 0;\n protected Ch: number = T256_IV[4] | 0;\n protected Cl: number = T256_IV[5] | 0;\n protected Dh: number = T256_IV[6] | 0;\n protected Dl: number = T256_IV[7] | 0;\n protected Eh: number = T256_IV[8] | 0;\n protected El: number = T256_IV[9] | 0;\n protected Fh: number = T256_IV[10] | 0;\n protected Fl: number = T256_IV[11] | 0;\n protected Gh: number = T256_IV[12] | 0;\n protected Gl: number = T256_IV[13] | 0;\n protected Hh: number = T256_IV[14] | 0;\n protected Hl: number = T256_IV[15] | 0;\n\n constructor() {\n super(32);\n }\n}\n\n/**\n * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:\n *\n * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.\n * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n * - Each sha256 hash is executing 2^18 bit operations.\n * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-256.\n * ```ts\n * sha256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha256: TRet<CHash<_SHA256>> = /* @__PURE__ */ createHasher(\n () => new _SHA256(),\n /* @__PURE__ */ oidNist(0x01)\n);\n/**\n * SHA2-224 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-224.\n * ```ts\n * sha224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha224: TRet<CHash<_SHA224>> = /* @__PURE__ */ createHasher(\n () => new _SHA224(),\n /* @__PURE__ */ oidNist(0x04)\n);\n\n/**\n * SHA2-512 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512.\n * ```ts\n * sha512(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512: TRet<CHash<_SHA512>> = /* @__PURE__ */ createHasher(\n () => new _SHA512(),\n /* @__PURE__ */ oidNist(0x03)\n);\n/**\n * SHA2-384 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-384.\n * ```ts\n * sha384(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha384: TRet<CHash<_SHA384>> = /* @__PURE__ */ createHasher(\n () => new _SHA384(),\n /* @__PURE__ */ oidNist(0x02)\n);\n\n/**\n * SHA2-512/256 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/256.\n * ```ts\n * sha512_256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_256: TRet<CHash<_SHA512_256>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_256(),\n /* @__PURE__ */ oidNist(0x06)\n);\n/**\n * SHA2-512/224 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/224.\n * ```ts\n * sha512_224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_224: TRet<CHash<_SHA512_224>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_224(),\n /* @__PURE__ */ oidNist(0x05)\n);\n","// §16 typed endpoints over http.ts. Amounts are decimal STRINGS end-to-end.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { WalletApiHttpError, type WalletApiHttp } from './http';\n\nexport interface AuthChallengeWire {\n nonce: string;\n challenge: string;\n expiresAt: string;\n}\n\nexport interface AuthTokensWire {\n jwt: string;\n refreshToken: string;\n}\n\nexport interface AssetWire {\n coinId: string;\n amount: string;\n}\n\nexport interface InventoryItemWire {\n tokenId: string;\n status: 'active' | 'removed';\n seq: number;\n stateHash: string;\n /**\n * Omitted for a tombstone AND for an ACTIVE COINLESS token (wallet-api#140),\n * so absence is never \"removed\" or \"not loaded\" — discriminate on `status`.\n */\n assets?: AssetWire[];\n /**\n * Genesis `TokenType`, lowercase hex (1-64 bytes ⇒ 2-128 chars). Names the\n * token's CLASS, not the instance (wallet-api#147). Absent on rows written\n * before wallet-api migration 0015. An unrecognised type is legitimate: never\n * reject or hide a token for it.\n */\n tokenType?: string;\n}\n\nexport interface InventoryPageWire {\n cursor: number;\n syncEpoch: number;\n more: boolean;\n items: InventoryItemWire[];\n}\n\nexport interface BalanceWire {\n coinId: string;\n total: string;\n tokenCount: number;\n}\n\nexport interface BlobUrlWire {\n tokenId: string;\n getUrl: string;\n}\n\nexport interface UploadUrlWire {\n sha256: string;\n key: string;\n putUrl: string;\n}\n\nexport interface ApplyDeltaWire {\n cursor: number;\n syncEpoch: number;\n}\n\nexport interface IntentWire {\n transferId: string;\n payload: string;\n status: 'open' | 'aborted';\n createdAt: string;\n}\n\nexport interface ProgressRecordWire {\n opIndex: number;\n payload: string;\n createdAt: string;\n}\n\nexport interface MailboxDepositEntry {\n recipientPubkey: string;\n key: string;\n transferId: string;\n tokenId: string;\n stateHash: string;\n memo?: string;\n}\n\nexport interface MailboxEntryWire {\n entryId: string;\n seq: number;\n status: string;\n transferId: string;\n tokenId: string;\n assets: AssetWire[];\n senderPubkey: string;\n memo?: string;\n createdAt: string;\n getUrl?: string;\n blobCollected?: boolean;\n}\n\nexport interface MailboxPageWire {\n readPointer: number;\n cursor: number;\n syncEpoch: number;\n more: boolean;\n entries: MailboxEntryWire[];\n}\n\nexport interface ClaimResultWire {\n claimed: string[];\n alreadyClaimed: { entryId: string; intoInventory: boolean }[];\n failed: { entryId: string; code: string }[];\n}\n\nexport type MailboxRejectReason = 'invalid' | 'not-owned' | 'storage-rejected' | 'other';\n\nexport interface HistoryRecordWire {\n dedupKey: string;\n id: string;\n type: 'SENT' | 'RECEIVED' | 'MINT';\n assets: AssetWire[];\n ts: string;\n transferId?: string;\n tokenId?: string;\n counterpartyPubkey?: string;\n counterpartyNametag?: string;\n memo?: string;\n}\n\nexport interface HistoryPageWire {\n records: HistoryRecordWire[];\n more: boolean;\n cursor: string | null;\n syncEpoch: number;\n}\n\nexport type PaymentRequestWireStatus = 'open' | 'paid' | 'declined' | 'expired';\n\nexport interface PaymentRequestWire {\n id: string;\n seq: number;\n fromPubkey: string;\n toPubkey: string;\n assets: AssetWire[];\n memo?: string;\n status: PaymentRequestWireStatus;\n transferId: string | null;\n createdAt: string;\n expiresAt?: string;\n}\n\nexport interface PaymentRequestsPageWire {\n requests: PaymentRequestWire[];\n more: boolean;\n cursor: number | string | null;\n syncEpoch: number;\n}\n\nexport type ListPaymentRequestsParams =\n | { role: 'incoming'; status?: PaymentRequestWireStatus; since?: number }\n | { role: 'outgoing'; status?: PaymentRequestWireStatus; before?: string };\n\nexport type RespondPaymentRequestInput =\n | { action: 'paid'; transferId: string }\n | { action: 'declined' };\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let bin = '';\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin);\n}\n\nexport class WalletApiV2Client {\n constructor(private readonly http: WalletApiHttp) {}\n\n get baseUrl(): string {\n return this.http.baseUrl;\n }\n\n // ── auth ─────────────────────────────────────────────────────────────────\n\n authChallenge(pubkey: string): Promise<AuthChallengeWire> {\n return this.http.request('POST', '/v1/auth/challenge', { pubkey }, { auth: false }) as Promise<AuthChallengeWire>;\n }\n\n authVerify(input: { nonce: string; signature: string; deviceId: string }): Promise<AuthTokensWire> {\n return this.http.request('POST', '/v1/auth/verify', input, { auth: false }) as Promise<AuthTokensWire>;\n }\n\n authRefresh(refreshToken: string): Promise<AuthTokensWire> {\n return this.http.request('POST', '/v1/auth/refresh', { refreshToken }, { auth: false }) as Promise<AuthTokensWire>;\n }\n\n async authLogout(): Promise<void> {\n await this.http.request('POST', '/v1/auth/logout', {});\n }\n\n // ── inventory / blobs ────────────────────────────────────────────────────\n\n listInventory(since?: number): Promise<InventoryPageWire> {\n const query = since !== undefined ? `?since=${since}` : '';\n return this.http.request('GET', `/v1/inventory${query}`) as Promise<InventoryPageWire>;\n }\n\n async balances(): Promise<BalanceWire[]> {\n const body = (await this.http.request('GET', '/v1/balances')) as { balances: BalanceWire[] };\n return body.balances;\n }\n\n async blobUrls(tokenIds: string[]): Promise<BlobUrlWire[]> {\n const body = (await this.http.request('POST', '/v1/tokens/blob-urls', { tokenIds })) as {\n urls: BlobUrlWire[];\n };\n return body.urls;\n }\n\n async uploadUrls(blobs: { sha256: string; size: number }[]): Promise<UploadUrlWire[]> {\n const body = (await this.http.request('POST', '/v1/tokens/upload-urls', { blobs })) as {\n urls: UploadUrlWire[];\n };\n return body.urls;\n }\n\n apply(delta: {\n transferId: string;\n spent: string[];\n added: { tokenId: string; key: string }[];\n }): Promise<ApplyDeltaWire> {\n return this.http.request('POST', '/v1/inventory/apply', delta) as Promise<ApplyDeltaWire>;\n }\n\n async fetchBlob(getUrl: string): Promise<Uint8Array> {\n const res = await this.http.fetchRaw(getUrl, { method: 'GET' });\n if (!res.ok) {\n throw new WalletApiHttpError(res.status, 'BLOB_DOWNLOAD', `blob download failed with status ${res.status}`);\n }\n return new Uint8Array(await res.arrayBuffer());\n }\n\n /**\n * PUT to a presigned S3 URL. `x-amz-checksum-sha256` (base64) and\n * `If-None-Match: *` are SIGNED headers — sent verbatim. S3 412 = the\n * identical blob already exists = success.\n */\n async uploadBlob(putUrl: string, bytes: Uint8Array): Promise<void> {\n const res = await this.http.fetchRaw(putUrl, {\n method: 'PUT',\n headers: {\n 'content-type': 'application/octet-stream',\n 'x-amz-checksum-sha256': bytesToBase64(sha256(bytes)),\n 'if-none-match': '*',\n },\n body: bytes,\n });\n if (res.ok || res.status === 412) return;\n throw new WalletApiHttpError(res.status, 'BLOB_UPLOAD', `blob upload failed with status ${res.status}`);\n }\n\n // ── intents ──────────────────────────────────────────────────────────────\n\n async putIntent(transferId: string, payloadEnvelope: string, requiresSeedClose = false): Promise<void> {\n const body = requiresSeedClose\n ? { payload: payloadEnvelope, requiresSeedClose: true }\n : { payload: payloadEnvelope };\n await this.http.request('PUT', `/v1/intents/${transferId}`, body);\n }\n\n async listIntents(status: 'open' | 'aborted' = 'open'): Promise<IntentWire[]> {\n const body = (await this.http.request('GET', `/v1/intents?status=${status}`)) as {\n intents: IntentWire[];\n };\n return body.intents;\n }\n\n async abortIntent(transferId: string): Promise<void> {\n await this.http.request('POST', `/v1/intents/${transferId}/abort`);\n }\n\n async completeIntent(transferId: string, signature?: string): Promise<void> {\n await this.http.request(\n 'POST',\n `/v1/intents/${transferId}/complete`,\n signature !== undefined ? { signature } : undefined\n );\n }\n\n async postProgress(\n transferId: string,\n opIndex: number,\n payloadEnvelope: string,\n signature: string\n ): Promise<ProgressRecordWire> {\n const body = (await this.http.request('POST', `/v1/intents/${transferId}/progress`, {\n opIndex,\n payload: payloadEnvelope,\n signature,\n })) as { record: ProgressRecordWire };\n return body.record;\n }\n\n async getProgress(transferId: string): Promise<ProgressRecordWire[]> {\n const body = (await this.http.request('GET', `/v1/intents/${transferId}/progress`)) as {\n records: ProgressRecordWire[];\n };\n return body.records;\n }\n\n // ── mailbox ──────────────────────────────────────────────────────────────\n\n async deposit(entry: MailboxDepositEntry): Promise<string> {\n const body = (await this.http.request('POST', '/v1/mailbox', entry)) as { entryId: string };\n return body.entryId;\n }\n\n async depositBatch(entries: MailboxDepositEntry[]): Promise<{ entryId: string; seq: number }[]> {\n const body = (await this.http.request('POST', '/v1/mailbox/batch', { entries })) as {\n entries: { entryId: string; seq: number }[];\n };\n return body.entries;\n }\n\n listMailbox(since?: number): Promise<MailboxPageWire> {\n const query = since !== undefined ? `?since=${since}` : '';\n return this.http.request('GET', `/v1/mailbox${query}`) as Promise<MailboxPageWire>;\n }\n\n claim(entryIds: string[], intoInventory: boolean): Promise<ClaimResultWire> {\n return this.http.request('POST', '/v1/mailbox/claim', { entryIds, intoInventory }) as Promise<ClaimResultWire>;\n }\n\n async reject(entryIds: string[], reason?: MailboxRejectReason, detail?: string): Promise<string[]> {\n const body = (await this.http.request('POST', '/v1/mailbox/reject', {\n entryIds,\n ...(reason !== undefined ? { reason } : {}),\n ...(detail !== undefined ? { detail } : {}),\n })) as { rejected: string[] };\n return body.rejected;\n }\n\n // ── history ──────────────────────────────────────────────────────────────\n\n async postHistory(records: HistoryRecordWire[]): Promise<{ inserted: number; deduped: number }> {\n return (await this.http.request('POST', '/v1/history', { records })) as {\n inserted: number;\n deduped: number;\n };\n }\n\n listHistory(options: { before?: string; limit?: number } = {}): Promise<HistoryPageWire> {\n const params = new URLSearchParams();\n if (options.before !== undefined) params.set('before', options.before);\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n const qs = params.toString();\n return this.http.request('GET', `/v1/history${qs ? `?${qs}` : ''}`) as Promise<HistoryPageWire>;\n }\n\n // ── payment requests ─────────────────────────────────────────────────────\n\n createPaymentRequest(input: {\n toPubkey: string;\n assets: AssetWire[];\n memo?: string;\n expiresAt?: string;\n }): Promise<PaymentRequestWire> {\n return this.http.request('POST', '/v1/payment-requests', input) as Promise<PaymentRequestWire>;\n }\n\n listPaymentRequests(params: ListPaymentRequestsParams): Promise<PaymentRequestsPageWire> {\n const query = new URLSearchParams();\n query.set('role', params.role);\n if (params.status !== undefined) query.set('status', params.status);\n if (params.role === 'incoming') {\n if (params.since !== undefined) query.set('since', String(params.since));\n } else if (params.before !== undefined) {\n query.set('before', params.before);\n }\n return this.http.request('GET', `/v1/payment-requests?${query.toString()}`) as Promise<PaymentRequestsPageWire>;\n }\n\n respondPaymentRequest(id: string, response: RespondPaymentRequestInput): Promise<PaymentRequestWire> {\n return this.http.request('POST', `/v1/payment-requests/${id}/respond`, response) as Promise<PaymentRequestWire>;\n }\n\n // ── realtime ─────────────────────────────────────────────────────────────\n\n async wsTicket(): Promise<string> {\n const body = (await this.http.request('POST', '/v1/ws-ticket')) as { ticket: string };\n return body.ticket;\n }\n}\n","/**\n * Centralized SDK Logger\n *\n * A lightweight singleton logger that works across all tsup bundles\n * by storing state on globalThis. Supports three log levels:\n * - debug: detailed messages (only shown when debug=true)\n * - warn: important warnings (ALWAYS shown regardless of debug flag)\n * - error: critical errors (ALWAYS shown regardless of debug flag)\n *\n * Global debug flag enables all logging. Per-tag overrides allow\n * granular control (e.g., only transport debug).\n *\n * @example\n * ```ts\n * import { logger } from '@unicitylabs/sphere-sdk';\n *\n * // Enable all debug logging\n * logger.configure({ debug: true });\n *\n * // Enable only specific tags\n * logger.setTagDebug('Nostr', true);\n *\n * // Usage in SDK classes\n * logger.debug('Payments', 'Transfer started', { amount, recipient });\n * logger.warn('Nostr', 'queryEvents timed out after 5s');\n * logger.error('Sphere', 'Critical failure', error);\n * ```\n */\n\nexport type LogLevel = 'debug' | 'warn' | 'error';\n\nexport type LogHandler = (level: LogLevel, tag: string, message: string, ...args: unknown[]) => void;\n\nexport interface LoggerConfig {\n /** Enable debug logging globally (default: false). When false, only warn and error messages are shown. */\n debug?: boolean;\n /** Custom log handler. If provided, replaces console output. Useful for tests or custom log sinks. */\n handler?: LogHandler | null;\n}\n\n// Use a unique symbol-like key on globalThis to share logger state across tsup bundles\nconst LOGGER_KEY = '__sphere_sdk_logger__';\n\ninterface LoggerState {\n debug: boolean;\n tags: Record<string, boolean>;\n handler: LogHandler | null;\n}\n\nfunction getState(): LoggerState {\n const g = globalThis as unknown as Record<string, unknown>;\n if (!g[LOGGER_KEY]) {\n g[LOGGER_KEY] = { debug: false, tags: {}, handler: null } satisfies LoggerState;\n }\n return g[LOGGER_KEY] as LoggerState;\n}\n\nfunction isEnabled(tag: string): boolean {\n const state = getState();\n // Per-tag override takes priority\n if (tag in state.tags) return state.tags[tag];\n // Fall back to global flag\n return state.debug;\n}\n\nexport const logger = {\n /**\n * Configure the logger. Can be called multiple times (last write wins).\n * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().\n */\n configure(config: LoggerConfig): void {\n const state = getState();\n if (config.debug !== undefined) state.debug = config.debug;\n if (config.handler !== undefined) state.handler = config.handler;\n },\n\n /**\n * Enable/disable debug logging for a specific tag.\n * Per-tag setting overrides the global debug flag.\n *\n * @example\n * ```ts\n * logger.setTagDebug('Nostr', true); // enable only Nostr logs\n * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true\n * ```\n */\n setTagDebug(tag: string, enabled: boolean): void {\n getState().tags[tag] = enabled;\n },\n\n /**\n * Clear per-tag override, falling back to global debug flag.\n */\n clearTagDebug(tag: string): void {\n delete getState().tags[tag];\n },\n\n /** Returns true if debug mode is enabled for the given tag (or globally). */\n isDebugEnabled(tag?: string): boolean {\n if (tag) return isEnabled(tag);\n return getState().debug;\n },\n\n /**\n * Debug-level log. Only shown when debug is enabled (globally or for this tag).\n * Use for detailed operational information.\n */\n debug(tag: string, message: string, ...args: unknown[]): void {\n if (!isEnabled(tag)) return;\n const state = getState();\n if (state.handler) {\n state.handler('debug', tag, message, ...args);\n } else {\n console.log(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Warning-level log. ALWAYS shown regardless of debug flag.\n * Use for important but non-critical issues (timeouts, retries, degraded state).\n */\n warn(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('warn', tag, message, ...args);\n } else {\n console.warn(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Error-level log. ALWAYS shown regardless of debug flag.\n * Use for critical failures that should never be silenced.\n */\n error(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('error', tag, message, ...args);\n } else {\n console.error(`[${tag}]`, message, ...args);\n }\n },\n\n /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */\n reset(): void {\n const g = globalThis as unknown as Record<string, unknown>;\n delete g[LOGGER_KEY];\n },\n};\n","// The complete §6 durable-state inventory. One writer per store.\n\nimport { logger } from '../../core/logger';\nimport type { StorageProvider } from '../../storage';\n\n/** Generation 2 of the durable client state; renaming IS the 3.x migration\n * (kv-generation.test.ts). Must not START with a superseded prefix — the sweep\n * below matches by `startsWith`. */\nconst KV_PREFIX = 'pv2g2:';\n\nconst SUPERSEDED_KV_PREFIXES = ['pv2:'] as const;\n\n/** Never `storage.clear()` — that takes the keys too. */\nexport async function sweepSupersededState(storage: StorageProvider): Promise<void> {\n for (const prefix of SUPERSEDED_KV_PREFIXES) {\n try {\n await storage.clear(prefix);\n } catch (err) {\n logger.warn('PaymentsV2', `could not clear superseded state under \"${prefix}\": ${String(err)}`);\n }\n }\n}\n\nexport interface ScopedKV {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T): Promise<void>;\n remove(key: string): Promise<void>;\n}\n\nexport function createScopedKV(\n storage: StorageProvider,\n network: string,\n chainPubkey: string\n): ScopedKV {\n const prefix = `${KV_PREFIX}${network}:${chainPubkey}:`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.get(prefix + key);\n if (raw === null || raw === undefined) return null;\n return typeof raw === 'string' ? (JSON.parse(raw) as T) : (raw as T);\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.set(prefix + key, JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.remove(prefix + key);\n },\n };\n}\n\n\nexport interface IntentBackstopEntry {\n transferId: string;\n payloadEnvelope: string;\n requiresSeedClose: boolean;\n // #676: a locally-aborted intent is NEVER resumed.\n disposition: 'open' | 'abortPending' | 'aborted';\n createdAt: number;\n}\n\n\n// #621 delivery journal.\nexport interface DeliveryJournalEntry {\n transferId: string;\n opIndex: number;\n recipientPubkey: string;\n blobHex: string;\n memo?: string;\n // Poison budget (#517); 429 deferrals do NOT count.\n attempts: number;\n deferredUntil?: number;\n undeliverable?: boolean;\n}\n\n// §5.9 mint journal.\nexport interface MintJournalEntry {\n mintId: string;\n coinId: string;\n amount: string;\n tokenId: string;\n createdAt: number;\n}\n\n// §5.9 NFT mint journal (#785). Its own store: an older client reading a coin\n// journal entry without coinId/amount would retry it every pass, forever.\n// Every field a byte-identical re-mint needs is journaled, so resume never re-signs.\nexport interface NftMintJournalEntry {\n mintId: string;\n tokenId: string;\n dataHex: string;\n saltHex: string;\n tokenTypeHex: string;\n createdAt: number;\n}\n\n// #690 shortfall record.\nexport interface ShortfallEntry {\n transferId: string;\n remainingAmount: string;\n coinId: string;\n recipient: string;\n // Already delivered — NEVER re-send these sources.\n committedTokenIds: string[];\n createdAt: number;\n}\n\n// #441 settling link.\nexport interface SettlingLink {\n requestId: string;\n transferId: string;\n committed: boolean;\n createdAt: number;\n}\n\nexport type StreamName = 'inventory' | 'mailbox' | 'payment_requests' | 'history';\n\n// Cursor+epoch persist as ONE record — never two keys (#692 F10).\nexport interface StreamCursor {\n cursor: number | string;\n syncEpoch: string;\n}\n\nexport const STORE_KEYS = {\n intentBackstop: 'intents',\n checkpointCache: 'checkpoints',\n deliveryJournal: 'delivery-journal',\n mintJournal: 'mint-journal',\n nftMintJournal: 'nft-mint-journal',\n shortfalls: 'shortfalls',\n settlingLinks: 'settling',\n streamCursor: (s: StreamName) => `cursor:${s}`,\n epochLatch: 'epoch-latch',\n // §5.2 InventoryView durable overlays (#625/#679).\n suspectedSpent: 'suspected-spent',\n knownSpends: 'known-spends',\n} as const;\n","/**\n * Hex, bytes and number utilities.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport {\n abytes as abytes_,\n anumber as anumber_,\n bytesToHex as bytesToHex_,\n concatBytes as concatBytes_,\n hexToBytes as hexToBytes_,\n isBytes as isBytes_,\n randomBytes as randomBytes_,\n} from '@noble/hashes/utils.js';\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n/**\n * Validates that a value is a byte array.\n * @param value - Value to validate.\n * @param length - Optional exact byte length.\n * @param title - Optional field name.\n * @returns Original byte array.\n * @example\n * Reject non-byte input before passing data into curve code.\n *\n * ```ts\n * abytes(new Uint8Array(1));\n * ```\n */\nexport const abytes = <T extends TArg<Uint8Array>>(value: T, length?: number, title?: string): T =>\n abytes_(value, length, title) as T;\n/**\n * Validates that a value is a non-negative safe integer.\n * @param n - Value to validate.\n * @param title - Optional field name.\n * @example\n * Validate a numeric length before allocating buffers.\n *\n * ```ts\n * anumber(1);\n * ```\n */\nexport const anumber: typeof anumber_ = anumber_;\n/**\n * Encodes bytes as lowercase hex.\n * @param bytes - Bytes to encode.\n * @returns Lowercase hex string.\n * @example\n * Serialize bytes as hex for logging or fixtures.\n *\n * ```ts\n * bytesToHex(Uint8Array.of(1, 2, 3));\n * ```\n */\nexport const bytesToHex: typeof bytesToHex_ = bytesToHex_;\n/**\n * Concatenates byte arrays.\n * @param arrays - Byte arrays to join.\n * @returns Concatenated bytes.\n * @example\n * Join domain-separated chunks into one buffer.\n *\n * ```ts\n * concatBytes(Uint8Array.of(1), Uint8Array.of(2));\n * ```\n */\nexport const concatBytes = (...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> =>\n concatBytes_(...arrays) as TRet<Uint8Array>;\n/**\n * Decodes lowercase or uppercase hex into bytes.\n * @param hex - Hex string to decode.\n * @returns Decoded bytes.\n * @example\n * Parse fixture hex into bytes before hashing.\n *\n * ```ts\n * hexToBytes('0102');\n * ```\n */\nexport const hexToBytes = (hex: string): TRet<Uint8Array> => hexToBytes_(hex) as TRet<Uint8Array>;\n/**\n * Checks whether a value is a Uint8Array.\n * @param a - Value to inspect.\n * @returns `true` when `a` is a Uint8Array.\n * @example\n * Branch on byte input before decoding it.\n *\n * ```ts\n * isBytes(new Uint8Array(1));\n * ```\n */\nexport const isBytes: typeof isBytes_ = isBytes_;\n/**\n * Reads random bytes from the platform CSPRNG.\n * @param bytesLength - Number of random bytes to read.\n * @returns Fresh random bytes.\n * @example\n * Generate a random seed for a keypair.\n *\n * ```ts\n * randomBytes(2);\n * ```\n */\nexport const randomBytes = (bytesLength?: number): TRet<Uint8Array> =>\n randomBytes_(bytesLength) as TRet<Uint8Array>;\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _1n = /* @__PURE__ */ BigInt(1);\n\n/** Callable hash interface with metadata and optional extendable output support. */\nexport type CHash = {\n /**\n * Hash one message.\n * @param message - Message bytes to hash.\n * @returns Digest bytes.\n */\n (message: TArg<Uint8Array>): TRet<Uint8Array>;\n /** Hash block length in bytes. */\n blockLen: number;\n /** Default output length in bytes. */\n outputLen: number;\n /** Whether `.create()` can be used as an XOF stream. */\n canXOF: boolean;\n /**\n * Create one stateful hash or XOF instance, for example SHAKE with a custom output length.\n * @param opts - Optional extendable-output configuration:\n * - `dkLen` (optional): Optional output length for XOF-style hashes.\n * @returns Hash instance.\n */\n create(opts?: { dkLen?: number }): any;\n};\n/** Plain callable hash interface. */\nexport type FHash = (message: TArg<Uint8Array>) => TRet<Uint8Array>;\n/** HMAC callback signature. */\nexport type HmacFn = (key: TArg<Uint8Array>, message: TArg<Uint8Array>) => TRet<Uint8Array>;\n/**\n * Validates that a flag is boolean.\n * @param value - Value to validate.\n * @param title - Optional field name.\n * @returns Original value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Reject non-boolean option flags early.\n *\n * ```ts\n * abool(true);\n * ```\n */\nexport function abool(value: boolean, title: string = ''): boolean {\n if (typeof value !== 'boolean') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(prefix + 'expected boolean, got type=' + typeof value);\n }\n return value;\n}\n\n/**\n * Validates that a value is a non-negative bigint or safe integer.\n * @param n - Value to validate.\n * @returns The same validated value.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate one integer-like value before serializing it.\n *\n * ```ts\n * abignumber(1n);\n * ```\n */\nexport function abignumber<T extends number | bigint>(n: T): T {\n if (typeof n === 'bigint') {\n if (!isPosBig(n)) throw new RangeError('positive bigint expected, got ' + n);\n } else anumber(n);\n return n;\n}\n\n/**\n * Validates that a value is a safe integer.\n * @param value - Integer to validate.\n * @param title - Optional field name.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a window size before scalar arithmetic uses it.\n *\n * ```ts\n * asafenumber(1);\n * ```\n */\nexport function asafenumber(value: number, title: string = ''): void {\n if (typeof value !== 'number') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(prefix + 'expected number, got type=' + typeof value);\n }\n if (!Number.isSafeInteger(value)) {\n const prefix = title && `\"${title}\" `;\n throw new RangeError(prefix + 'expected safe integer, got ' + value);\n }\n}\n\n/**\n * Encodes a bigint into even-length big-endian hex.\n * The historical \"unpadded\" name only means \"no fixed-width field padding\"; odd-length hex still\n * gets one leading zero nibble so the result always represents whole bytes.\n * @param num - Number to encode.\n * @returns Big-endian hex string.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Encode a scalar into hex without a `0x` prefix.\n *\n * ```ts\n * numberToHexUnpadded(255n);\n * ```\n */\nexport function numberToHexUnpadded(num: number | bigint): string {\n const hex = abignumber(num).toString(16);\n return hex.length & 1 ? '0' + hex : hex;\n}\n\n/**\n * Parses a big-endian hex string into bigint.\n * Accepts odd-length hex through the native `BigInt('0x' + hex)` parser and currently surfaces the\n * same native `SyntaxError` for malformed hex instead of wrapping it in a library-specific error.\n * @param hex - Hex string without `0x`.\n * @returns Parsed bigint value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Parse a scalar from fixture hex.\n *\n * ```ts\n * hexToNumber('ff');\n * ```\n */\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian\n}\n\n// BE: Big Endian, LE: Little Endian\n/**\n * Parses big-endian bytes into bigint.\n * @param bytes - Bytes in big-endian order.\n * @returns Parsed bigint value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Read a scalar encoded in network byte order.\n *\n * ```ts\n * bytesToNumberBE(Uint8Array.of(1, 0));\n * ```\n */\nexport function bytesToNumberBE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex_(bytes));\n}\n/**\n * Parses little-endian bytes into bigint.\n * @param bytes - Bytes in little-endian order.\n * @returns Parsed bigint value.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Read a scalar encoded in little-endian form.\n *\n * ```ts\n * bytesToNumberLE(Uint8Array.of(1, 0));\n * ```\n */\nexport function bytesToNumberLE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex_(copyBytes(abytes_(bytes)).reverse()));\n}\n\n/**\n * Encodes a bigint into fixed-length big-endian bytes.\n * @param n - Number to encode.\n * @param len - Output length in bytes. Must be greater than zero.\n * @returns Big-endian byte array.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Serialize a scalar into a 32-byte field element.\n *\n * ```ts\n * numberToBytesBE(255n, 2);\n * ```\n */\nexport function numberToBytesBE(n: number | bigint, len: number): TRet<Uint8Array> {\n anumber_(len);\n if (len === 0) throw new RangeError('zero length');\n n = abignumber(n);\n const hex = n.toString(16);\n // Detect overflow before hex parsing so oversized values don't leak the shared odd-hex error.\n if (hex.length > len * 2) throw new RangeError('number too large');\n return hexToBytes_(hex.padStart(len * 2, '0')) as TRet<Uint8Array>;\n}\n/**\n * Encodes a bigint into fixed-length little-endian bytes.\n * @param n - Number to encode.\n * @param len - Output length in bytes.\n * @returns Little-endian byte array.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Serialize a scalar for little-endian protocols.\n *\n * ```ts\n * numberToBytesLE(255n, 2);\n * ```\n */\nexport function numberToBytesLE(n: number | bigint, len: number): TRet<Uint8Array> {\n return numberToBytesBE(n, len).reverse() as TRet<Uint8Array>;\n}\n// Unpadded, rarely used\n/**\n * Encodes a bigint into variable-length big-endian bytes.\n * @param n - Number to encode.\n * @returns Variable-length big-endian bytes.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Serialize a bigint without fixed-width padding.\n *\n * ```ts\n * numberToVarBytesBE(255n);\n * ```\n */\nexport function numberToVarBytesBE(n: number | bigint): TRet<Uint8Array> {\n return hexToBytes_(numberToHexUnpadded(abignumber(n))) as TRet<Uint8Array>;\n}\n\n// Compares 2 u8a-s in kinda constant time\n/**\n * Compares two byte arrays in constant-ish time.\n * @param a - Left byte array.\n * @param b - Right byte array.\n * @returns `true` when bytes match.\n * @example\n * Compare two encoded points without early exit.\n *\n * ```ts\n * equalBytes(Uint8Array.of(1), Uint8Array.of(1));\n * ```\n */\nexport function equalBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n a = abytes(a);\n b = abytes(b);\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n/**\n * Copies Uint8Array. We can't use u8a.slice(), because u8a can be Buffer,\n * and Buffer#slice creates mutable copy. Never use Buffers!\n * @param bytes - Bytes to copy.\n * @returns Detached copy.\n * @example\n * Make an isolated copy before mutating serialized bytes.\n *\n * ```ts\n * copyBytes(Uint8Array.of(1, 2, 3));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Decodes 7-bit ASCII string to Uint8Array, throws on non-ascii symbols\n * Should be safe to use for things expected to be ASCII.\n * Returns exact same result as `TextEncoder` for ASCII or throws.\n * @param ascii - ASCII input text.\n * @returns Encoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encode an ASCII domain-separation tag.\n *\n * ```ts\n * asciiToBytes('ABC');\n * ```\n */\nexport function asciiToBytes(ascii: string): TRet<Uint8Array> {\n if (typeof ascii !== 'string') throw new TypeError('ascii string expected, got ' + typeof ascii);\n return Uint8Array.from(ascii, (c, i) => {\n const charCode = c.charCodeAt(0);\n if (c.length !== 1 || charCode > 127) {\n throw new RangeError(\n `string contains non-ASCII character \"${ascii[i]}\" with code ${charCode} at position ${i}`\n );\n }\n return charCode;\n }) as TRet<Uint8Array>;\n}\n\n// Historical name: this accepts non-negative bigints, including zero.\nconst isPosBig = (n: bigint) => typeof n === 'bigint' && _0n <= n;\n\n/**\n * Checks whether a bigint lies inside a half-open range.\n * @param n - Candidate value.\n * @param min - Inclusive lower bound.\n * @param max - Exclusive upper bound.\n * @returns `true` when the value is inside the range.\n * @example\n * Check whether a candidate scalar fits the field order.\n *\n * ```ts\n * inRange(2n, 1n, 3n);\n * ```\n */\nexport function inRange(n: bigint, min: bigint, max: bigint): boolean {\n return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;\n}\n\n/**\n * Asserts `min <= n < max`. NOTE: upper bound is exclusive.\n * @param title - Value label for error messages.\n * @param n - Candidate value.\n * @param min - Inclusive lower bound.\n * @param max - Exclusive upper bound.\n * Wrong-type inputs are not separated from out-of-range values here: they still flow through the\n * shared `RangeError` path because this is only a throwing wrapper around `inRange(...)`.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Assert that a bigint stays within one half-open range.\n *\n * ```ts\n * aInRange('x', 2n, 1n, 256n);\n * ```\n */\nexport function aInRange(title: string, n: bigint, min: bigint, max: bigint): void {\n // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?\n // consider P=256n, min=0n, max=P\n // - a for min=0 would require -1: `inRange('x', x, -1n, P)`\n // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`\n // - our way is the cleanest: `inRange('x', x, 0n, P)\n if (!inRange(n, min, max))\n throw new RangeError('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);\n}\n\n// Bit operations\n\n/**\n * Calculates amount of bits in a bigint.\n * Same as `n.toString(2).length`\n * TODO: merge with nLength in modular\n * @param n - Value to inspect.\n * @returns Bit length.\n * @throws If the value is negative. {@link Error}\n * @example\n * Measure the bit length of a scalar before serialization.\n *\n * ```ts\n * bitLen(8n);\n * ```\n */\nexport function bitLen(n: bigint): number {\n // Size callers in this repo only use non-negative orders / scalars, so negative inputs are a\n // contract bug and must not silently collapse to zero bits.\n if (n < _0n) throw new Error('expected non-negative bigint, got ' + n);\n let len;\n for (len = 0; n > _0n; n >>= _1n, len += 1);\n return len;\n}\n\n/**\n * Gets single bit at position.\n * NOTE: first bit position is 0 (same as arrays)\n * Same as `!!+Array.from(n.toString(2)).reverse()[pos]`\n * @param n - Source value.\n * @param pos - Bit position. Negative positions are passed through to raw\n * bigint shift semantics; because the mask is built as `1n << pos`,\n * they currently collapse to `0n` and make the helper a no-op.\n * @returns Bit as bigint.\n * @example\n * Gets single bit at position.\n *\n * ```ts\n * bitGet(5n, 0);\n * ```\n */\nexport function bitGet(n: bigint, pos: number): bigint {\n return (n >> BigInt(pos)) & _1n;\n}\n\n/**\n * Sets single bit at position.\n * @param n - Source value.\n * @param pos - Bit position. Negative positions are passed through to raw bigint shift semantics,\n * so they currently behave like left shifts.\n * @param value - Whether the bit should be set.\n * @returns Updated bigint.\n * @example\n * Sets single bit at position.\n *\n * ```ts\n * bitSet(0n, 1, true);\n * ```\n */\nexport function bitSet(n: bigint, pos: number, value: boolean): bigint {\n const mask = _1n << BigInt(pos);\n // Clearing needs AND-not here; OR with zero leaves an already-set bit untouched.\n return value ? n | mask : n & ~mask;\n}\n\n/**\n * Calculate mask for N bits. Not using ** operator with bigints because of old engines.\n * Same as BigInt(`0b${Array(i).fill('1').join('')}`)\n * @param n - Number of bits. Negative widths are currently passed through to raw bigint shift\n * semantics and therefore produce `-1n`.\n * @returns Bitmask value.\n * @example\n * Calculate mask for N bits.\n *\n * ```ts\n * bitMask(4);\n * ```\n */\nexport const bitMask = (n: number): bigint => (_1n << BigInt(n)) - _1n;\n\n// DRBG\n\ntype Pred<T> = (v: TArg<Uint8Array>) => T | undefined;\n/**\n * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n * @param hashLen - Hash output size in bytes. Callers are expected to pass a positive length; `0`\n * is not rejected here and would make the internal generate loop non-progressing.\n * @param qByteLen - Requested output size in bytes. Callers are expected to pass a positive length.\n * @param hmacFn - HMAC implementation.\n * @returns Function that will call DRBG until the predicate returns anything\n * other than `undefined`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Build a deterministic nonce generator for RFC6979-style signing.\n *\n * ```ts\n * import { createHmacDrbg } from '@noble/curves/utils.js';\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const drbg = createHmacDrbg(32, 32, (key, msg) => hmac(sha256, key, msg));\n * const seed = new Uint8Array(32);\n * drbg(seed, (bytes) => bytes);\n * ```\n */\nexport function createHmacDrbg<T>(\n hashLen: number,\n qByteLen: number,\n hmacFn: TArg<HmacFn>\n): TRet<(seed: Uint8Array, predicate: Pred<T>) => T> {\n anumber_(hashLen, 'hashLen');\n anumber_(qByteLen, 'qByteLen');\n if (typeof hmacFn !== 'function') throw new TypeError('hmacFn must be a function');\n // creates Uint8Array\n const u8n = (len: number): TRet<Uint8Array> => new Uint8Array(len) as TRet<Uint8Array>;\n const NULL = Uint8Array.of();\n const byte0 = Uint8Array.of(0x00);\n const byte1 = Uint8Array.of(0x01);\n const _maxDrbgIters = 1000;\n\n // Step B, Step C: set hashLen to 8*ceil(hlen/8).\n // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 signatures.\n let v: Uint8Array = u8n(hashLen);\n // Steps B and C of RFC6979 3.2.\n let k: Uint8Array = u8n(hashLen);\n let i = 0; // Iterations counter, will throw when over 1000\n const reset = () => {\n v.fill(1);\n k.fill(0);\n i = 0;\n };\n // hmac(k)(v, ...values)\n const h = (...msgs: TArg<Uint8Array[]>) => (hmacFn as HmacFn)(k, concatBytes(v, ...msgs));\n const reseed = (seed: TArg<Uint8Array> = NULL) => {\n // HMAC-DRBG reseed() function. Steps D-G\n k = h(byte0, seed); // k = hmac(k || v || 0x00 || seed)\n v = h(); // v = hmac(k || v)\n if (seed.length === 0) return;\n k = h(byte1, seed); // k = hmac(k || v || 0x01 || seed)\n v = h(); // v = hmac(k || v)\n };\n const gen = () => {\n // HMAC-DRBG generate() function\n if (i++ >= _maxDrbgIters) throw new Error('drbg: tried max amount of iterations');\n let len = 0;\n const out: Uint8Array[] = [];\n while (len < qByteLen) {\n v = h();\n const sl = v.slice();\n out.push(sl);\n len += v.length;\n }\n return concatBytes(...out);\n };\n const genUntil = (seed: TArg<Uint8Array>, pred: TArg<Pred<T>>): T => {\n reset();\n reseed(seed); // Steps D-G\n let res: T | undefined = undefined; // Step H: grind until the predicate accepts a candidate.\n // Falsy values like 0 are valid outputs.\n while ((res = (pred as Pred<T>)(gen())) === undefined) reseed();\n reset();\n return res;\n };\n return genUntil as TRet<(seed: Uint8Array, predicate: Pred<T>) => T>;\n}\n\n/**\n * Validates declared required and optional field types on a plain object.\n * Extra keys are intentionally ignored because many callers validate only the subset they use from\n * richer option bags or runtime objects.\n * @param object - Object to validate.\n * @param fields - Required field types.\n * @param optFields - Optional field types.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Check user options before building a curve helper.\n *\n * ```ts\n * validateObject({ flag: true }, { flag: 'boolean' });\n * ```\n */\nexport function validateObject(\n object: Record<string, any>,\n fields: Record<string, string> = {},\n optFields: Record<string, string> = {}\n): void {\n if (Object.prototype.toString.call(object) !== '[object Object]')\n throw new TypeError('expected valid options object');\n type Item = keyof typeof object;\n function checkField(fieldName: Item, expectedType: string, isOpt: boolean) {\n // Config/data fields must be explicit own properties, but runtime objects such as Field\n // instances intentionally satisfy required method slots via their shared prototype.\n if (!isOpt && expectedType !== 'function' && !Object.hasOwn(object, fieldName))\n throw new TypeError(`param \"${fieldName}\" is invalid: expected own property`);\n const val = object[fieldName];\n if (isOpt && val === undefined) return;\n const current = typeof val;\n if (current !== expectedType || val === null)\n throw new TypeError(\n `param \"${fieldName}\" is invalid: expected ${expectedType}, got ${current}`\n );\n }\n const iter = (f: typeof fields, isOpt: boolean) =>\n Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));\n iter(fields, false);\n iter(optFields, true);\n}\n\n/**\n * Throws not implemented error.\n * @returns Never returns.\n * @throws If the unfinished code path is reached. {@link Error}\n * @example\n * Surface the placeholder error from an unfinished code path.\n *\n * ```ts\n * try {\n * notImplemented();\n * } catch {}\n * ```\n */\nexport const notImplemented = (): never => {\n throw new Error('not implemented');\n};\n\n/** Generic keygen/getPublicKey interface shared by curve helpers. */\nexport interface CryptoKeys {\n /** Public byte lengths for keys and optional seeds. */\n lengths: { seed?: number; public?: number; secret?: number };\n /**\n * Generate one secret/public keypair.\n * @param seed - Optional seed bytes for deterministic key generation.\n * @returns Fresh secret/public keypair.\n */\n keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };\n /**\n * Derive one public key from a secret key.\n * @param secretKey - Secret key bytes.\n * @returns Public key bytes.\n */\n getPublicKey: (secretKey: Uint8Array) => Uint8Array;\n}\n\n/** Generic interface for signatures. Has keygen, sign and verify. */\nexport interface Signer extends CryptoKeys {\n // Interfaces are fun. We cannot just add new fields without copying old ones.\n /** Public byte lengths for keys, signatures, and optional signing randomness. */\n lengths: {\n seed?: number;\n public?: number;\n secret?: number;\n signRand?: number;\n signature?: number;\n };\n /**\n * Sign one message.\n * @param msg - Message bytes to sign.\n * @param secretKey - Secret key bytes.\n * @returns Signature bytes.\n */\n sign: (msg: Uint8Array, secretKey: Uint8Array) => Uint8Array;\n /**\n * Verify one signature.\n * @param sig - Signature bytes.\n * @param msg - Signed message bytes.\n * @param publicKey - Public key bytes.\n * @returns `true` when the signature is valid.\n */\n verify: (sig: Uint8Array, msg: Uint8Array, publicKey: Uint8Array) => boolean;\n}\n","/**\n * Utils for modular division and fields.\n * Field over 11 is a finite (Galois) field is integer number operations `mod 11`.\n * There is no division: it is replaced by modular multiplicative inverse.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport {\n abool,\n abytes,\n anumber,\n asafenumber,\n bitLen,\n bytesToNumberBE,\n bytesToNumberLE,\n numberToBytesBE,\n numberToBytesLE,\n validateObject,\n type TArg,\n type TRet,\n} from '../utils.ts';\n\n// Numbers aren't used in x25519 / x448 builds\n// prettier-ignore\nconst _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2);\n// prettier-ignore\nconst _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _5n = /* @__PURE__ */ BigInt(5);\n// prettier-ignore\nconst _7n = /* @__PURE__ */ BigInt(7), _8n = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9);\nconst _16n = /* @__PURE__ */ BigInt(16);\n\n/**\n * @param a - Dividend value.\n * @param b - Positive modulus.\n * @returns Reduced value in `[0, b)` only when `b` is positive.\n * @throws If the modulus is not positive. {@link Error}\n * @example\n * Normalize a bigint into one field residue.\n *\n * ```ts\n * mod(-1n, 5n);\n * ```\n */\nexport function mod(a: bigint, b: bigint): bigint {\n if (b <= _0n) throw new Error('mod: expected positive modulus, got ' + b);\n const result = a % b;\n return result >= _0n ? result : b + result;\n}\n/**\n * Efficiently raise num to a power with modular reduction.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n * Low-level helper: callers that need canonical residues must pass a valid `num` for the chosen\n * modulus instead of relying on the `power===0/1` fast paths to normalize it.\n * @param num - Base value.\n * @param power - Exponent value.\n * @param modulo - Reduction modulus.\n * @returns Modular exponentiation result.\n * @throws If the modulus or exponent is invalid. {@link Error}\n * @example\n * Raise one bigint to a modular power.\n *\n * ```ts\n * pow(2n, 6n, 11n) // 64n % 11n == 9n\n * ```\n */\nexport function pow(num: bigint, power: bigint, modulo: bigint): bigint {\n return FpPow(Field(modulo), num, power);\n}\n\n/**\n * Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)`.\n * Low-level helper: callers that need canonical residues must pass a valid `x` for the chosen\n * modulus; the `power===0` fast path intentionally returns the input unchanged.\n * @param x - Base value.\n * @param power - Number of squarings.\n * @param modulo - Reduction modulus.\n * @returns Repeated-squaring result.\n * @throws If the exponent is negative. {@link Error}\n * @example\n * Apply repeated squaring inside one field.\n *\n * ```ts\n * pow2(3n, 2n, 11n);\n * ```\n */\nexport function pow2(x: bigint, power: bigint, modulo: bigint): bigint {\n if (power < _0n) throw new Error('pow2: expected non-negative exponent, got ' + power);\n let res = x;\n while (power-- > _0n) {\n res *= res;\n res %= modulo;\n }\n return res;\n}\n\n/**\n * Inverses number over modulo.\n * Implemented using the {@link https://brilliant.org/wiki/extended-euclidean-algorithm/ | extended Euclidean algorithm}.\n * @param number - Value to invert.\n * @param modulo - Positive modulus.\n * @returns Multiplicative inverse.\n * @throws If the modulus is invalid or the inverse does not exist. {@link Error}\n * @example\n * Compute one modular inverse with the extended Euclidean algorithm.\n *\n * ```ts\n * invert(3n, 11n);\n * ```\n */\nexport function invert(number: bigint, modulo: bigint): bigint {\n if (number === _0n) throw new Error('invert: expected non-zero number');\n if (modulo <= _0n) throw new Error('invert: expected positive modulus, got ' + modulo);\n // Fermat's little theorem \"CT-like\" version inv(n) = n^(m-2) mod m is 30x slower.\n let a = mod(number, modulo);\n let b = modulo;\n // prettier-ignore\n let x = _0n, y = _1n, u = _1n, v = _0n;\n while (a !== _0n) {\n const q = b / a;\n const r = b - a * q;\n const m = x - u * q;\n const n = y - v * q;\n // prettier-ignore\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n const gcd = b;\n if (gcd !== _1n) throw new Error('invert: does not exist');\n return mod(x, modulo);\n}\n\nfunction assertIsSquare<T>(Fp: TArg<IField<T>>, root: T, n: T): void {\n const F = Fp as IField<T>;\n if (!F.eql(F.sqr(root), n)) throw new Error('Cannot find square root');\n}\n\n// Not all roots are possible! Example which will throw:\n// const NUM =\n// n = 72057594037927816n;\n// Fp = Field(BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'));\nfunction sqrt3mod4<T>(Fp: TArg<IField<T>>, n: T) {\n const F = Fp as IField<T>;\n const p1div4 = (F.ORDER + _1n) / _4n;\n const root = F.pow(n, p1div4);\n assertIsSquare(F, root, n);\n return root;\n}\n\n// Equivalent `q = 5 (mod 8)` square-root formula (Atkin-style), not the RFC Appendix I.2 CMOV\n// pseudocode verbatim.\nfunction sqrt5mod8<T>(Fp: TArg<IField<T>>, n: T) {\n const F = Fp as IField<T>;\n const p5div8 = (F.ORDER - _5n) / _8n;\n const n2 = F.mul(n, _2n);\n const v = F.pow(n2, p5div8);\n const nv = F.mul(n, v);\n const i = F.mul(F.mul(nv, _2n), v);\n const root = F.mul(nv, F.sub(i, F.ONE));\n assertIsSquare(F, root, n);\n return root;\n}\n\n// Based on RFC9380, Kong algorithm\n// prettier-ignore\nfunction sqrt9mod16(P: bigint): TRet<<T>(Fp: IField<T>, n: T) => T> {\n const Fp_ = Field(P);\n const tn = tonelliShanks(P);\n const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));// 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F\n const c2 = tn(Fp_, c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F\n const c3 = tn(Fp_, Fp_.neg(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F\n const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic\n return (<T>(Fp: TArg<IField<T>>, n: T): T => {\n const F = Fp as IField<T>;\n let tv1 = F.pow(n, c4); // 1. tv1 = x^c4\n let tv2 = F.mul(tv1, c1); // 2. tv2 = c1 * tv1\n const tv3 = F.mul(tv1, c2); // 3. tv3 = c2 * tv1\n const tv4 = F.mul(tv1, c3); // 4. tv4 = c3 * tv1\n const e1 = F.eql(F.sqr(tv2), n); // 5. e1 = (tv2^2) == x\n const e2 = F.eql(F.sqr(tv3), n); // 6. e2 = (tv3^2) == x\n tv1 = F.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x\n tv2 = F.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x\n const e3 = F.eql(F.sqr(tv2), n); // 9. e3 = (tv2^2) == x\n const root = F.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select sqrt from tv1 & tv2\n assertIsSquare(F, root, n);\n return root;\n }) as TRet<<T>(Fp: IField<T>, n: T) => T>;\n}\n\n/**\n * Tonelli-Shanks square root search algorithm.\n * This implementation is variable-time: it searches data-dependently for the first non-residue `Z`\n * and for the smallest `i` in the main loop, unlike RFC 9380 Appendix I.4's constant-time shape.\n * 1. {@link https://eprint.iacr.org/2012/685.pdf | eprint 2012/685}, page 12\n * 2. Square Roots from 1; 24, 51, 10 to Dan Shanks\n * @param P - field order\n * @returns function that takes field Fp (created from P) and number n\n * @throws If the field is too small, non-prime, or the square root does not exist. {@link Error}\n * @example\n * Construct a square-root helper for primes that need Tonelli-Shanks.\n *\n * ```ts\n * import { Field, tonelliShanks } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const sqrt = tonelliShanks(17n)(Fp, 4n);\n * ```\n */\nexport function tonelliShanks(P: bigint): TRet<<T>(Fp: IField<T>, n: T) => T> {\n // Initialization (precomputation).\n // Caching initialization could boost perf by 7%.\n if (P < _3n) throw new Error('sqrt is not defined for small field');\n // Factor P - 1 = Q * 2^S, where Q is odd\n let Q = P - _1n;\n let S = 0;\n while (Q % _2n === _0n) {\n Q /= _2n;\n S++;\n }\n\n // Find the first quadratic non-residue Z >= 2\n let Z = _2n;\n const _Fp = Field(P);\n while (FpLegendre(_Fp, Z) === 1) {\n // Basic primality test for P. After x iterations, chance of\n // not finding quadratic non-residue is 2^x, so 2^1000.\n if (Z++ > 1000) throw new Error('Cannot find square root: probably non-prime P');\n }\n // Fast-path; usually done before Z, but we do \"primality test\".\n if (S === 1) return sqrt3mod4 as TRet<<T>(Fp: IField<T>, n: T) => T>;\n\n // Slow-path\n // TODO: test on Fp2 and others\n let cc = _Fp.pow(Z, Q); // c = z^Q\n const Q1div2 = (Q + _1n) / _2n;\n return function tonelliSlow<T>(Fp: TArg<IField<T>>, n: T): T {\n const F = Fp as IField<T>;\n if (F.is0(n)) return n;\n // Check if n is a quadratic residue using Legendre symbol\n if (FpLegendre(F, n) !== 1) throw new Error('Cannot find square root');\n\n // Initialize variables for the main loop\n let M = S;\n let c = F.mul(F.ONE, cc); // c = z^Q, move cc from field _Fp into field Fp\n let t = F.pow(n, Q); // t = n^Q, first guess at the fudge factor\n let R = F.pow(n, Q1div2); // R = n^((Q+1)/2), first guess at the square root\n\n // Main loop\n // while t != 1\n while (!F.eql(t, F.ONE)) {\n if (F.is0(t)) return F.ZERO; // if t=0 return R=0\n let i = 1;\n\n // Find the smallest i >= 1 such that t^(2^i) ≡ 1 (mod P)\n let t_tmp = F.sqr(t); // t^(2^1)\n while (!F.eql(t_tmp, F.ONE)) {\n i++;\n t_tmp = F.sqr(t_tmp); // t^(2^2)...\n if (i === M) throw new Error('Cannot find square root');\n }\n\n // Calculate the exponent for b: 2^(M - i - 1)\n const exponent = _1n << BigInt(M - i - 1); // bigint is important\n const b = F.pow(c, exponent); // b = 2^(M - i - 1)\n\n // Update variables\n M = i;\n c = F.sqr(b); // c = b^2\n t = F.mul(t, c); // t = (t * b^2)\n R = F.mul(R, b); // R = R*b\n }\n return R;\n } as TRet<<T>(Fp: IField<T>, n: T) => T>;\n}\n\n/**\n * Square root for a finite field. Will try optimized versions first:\n *\n * 1. P ≡ 3 (mod 4)\n * 2. P ≡ 5 (mod 8)\n * 3. P ≡ 9 (mod 16)\n * 4. Tonelli-Shanks algorithm\n *\n * Different algorithms can give different roots, it is up to user to decide which one they want.\n * For example there is FpSqrtOdd/FpSqrtEven to choose a root by oddness\n * (used for hash-to-curve).\n * @param P - Field order.\n * @returns Square-root helper. The generic fallback inherits Tonelli-Shanks' variable-time\n * behavior and this selector assumes prime-field-style integer moduli.\n * @throws If the field is unsupported or the square root does not exist. {@link Error}\n * @example\n * Choose the square-root helper appropriate for one field modulus.\n *\n * ```ts\n * import { Field, FpSqrt } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const sqrt = FpSqrt(17n)(Fp, 4n);\n * ```\n */\nexport function FpSqrt(P: bigint): TRet<<T>(Fp: IField<T>, n: T) => T> {\n // P ≡ 3 (mod 4) => √n = n^((P+1)/4)\n if (P % _4n === _3n) return sqrt3mod4 as TRet<<T>(Fp: IField<T>, n: T) => T>;\n // P ≡ 5 (mod 8) => Atkin algorithm, page 10 of https://eprint.iacr.org/2012/685.pdf\n if (P % _8n === _5n) return sqrt5mod8 as TRet<<T>(Fp: IField<T>, n: T) => T>;\n // P ≡ 9 (mod 16) => Kong algorithm, page 11 of https://eprint.iacr.org/2012/685.pdf (algorithm 4)\n if (P % _16n === _9n) return sqrt9mod16(P);\n // Tonelli-Shanks algorithm\n return tonelliShanks(P);\n}\n\n/**\n * @param num - Value to inspect.\n * @param modulo - Field modulus.\n * @returns `true` when the least-significant little-endian bit is set.\n * @throws If the modulus is invalid for `mod(...)`. {@link Error}\n * @example\n * Inspect the low bit used by little-endian sign conventions.\n *\n * ```ts\n * isNegativeLE(3n, 11n);\n * ```\n */\nexport const isNegativeLE = (num: bigint, modulo: bigint): boolean =>\n (mod(num, modulo) & _1n) === _1n;\n\n/** Generic field interface used by prime and extension fields alike.\n * Generic helpers treat field operations as pure functions: implementations MUST treat provided\n * values/byte buffers as read-only and return detached results instead of mutating arguments.\n */\nexport interface IField<T> {\n /** Field order `q`, which may be prime or a prime power. */\n ORDER: bigint;\n /** Canonical encoded byte length. */\n BYTES: number;\n /** Canonical encoded bit length. */\n BITS: number;\n /** Whether encoded field elements use little-endian bytes. */\n isLE: boolean;\n /** Additive identity. */\n ZERO: T;\n /** Multiplicative identity. */\n ONE: T;\n // 1-arg\n /**\n * Normalize one value into the field.\n * @param num - Input value.\n * @returns Normalized field value.\n */\n create: (num: T) => T;\n /**\n * Check whether one value already belongs to the field.\n * @param num - Input value.\n * Implementations may throw `TypeError` on malformed input types instead of returning `false`.\n * @returns Whether the value already belongs to the field.\n */\n isValid: (num: T) => boolean;\n /**\n * Check whether one value is zero.\n * @param num - Input value.\n * @returns Whether the value is zero.\n */\n is0: (num: T) => boolean;\n /**\n * Check whether one value is non-zero and belongs to the field.\n * @param num - Input value.\n * Implementations may throw `TypeError` on malformed input types instead of returning `false`.\n * @returns Whether the value is non-zero and valid.\n */\n isValidNot0: (num: T) => boolean;\n /**\n * Negate one value.\n * @param num - Input value.\n * @returns Negated value.\n */\n neg(num: T): T;\n /**\n * Invert one value multiplicatively.\n * @param num - Input value.\n * @returns Multiplicative inverse.\n */\n inv(num: T): T;\n /**\n * Compute one square root when it exists.\n * @param num - Input value.\n * @returns Square root.\n */\n sqrt(num: T): T;\n /**\n * Square one value.\n * @param num - Input value.\n * @returns Squared value.\n */\n sqr(num: T): T;\n // 2-args\n /**\n * Compare two field values.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Whether both values are equal.\n */\n eql(lhs: T, rhs: T): boolean;\n /**\n * Add two normalized field values.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Sum value.\n */\n add(lhs: T, rhs: T): T;\n /**\n * Subtract two normalized field values.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Difference value.\n */\n sub(lhs: T, rhs: T): T;\n /**\n * Multiply two field values.\n * @param lhs - Left value.\n * @param rhs - Right value or scalar.\n * @returns Product value.\n */\n mul(lhs: T, rhs: T | bigint): T;\n /**\n * Raise one field value to a power.\n * @param lhs - Base value.\n * @param power - Exponent.\n * @returns Power value.\n */\n pow(lhs: T, power: bigint): T;\n /**\n * Divide one field value by another.\n * @param lhs - Dividend.\n * @param rhs - Divisor or scalar.\n * @returns Quotient value.\n */\n div(lhs: T, rhs: T | bigint): T;\n // N for NonNormalized (for now)\n /**\n * Add two values without re-normalizing the result.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Non-normalized sum.\n */\n addN(lhs: T, rhs: T): T;\n /**\n * Subtract two values without re-normalizing the result.\n * @param lhs - Left value.\n * @param rhs - Right value.\n * @returns Non-normalized difference.\n */\n subN(lhs: T, rhs: T): T;\n /**\n * Multiply two values without re-normalizing the result.\n * @param lhs - Left value.\n * @param rhs - Right value or scalar.\n * @returns Non-normalized product.\n */\n mulN(lhs: T, rhs: T | bigint): T;\n /**\n * Square one value without re-normalizing the result.\n * @param num - Input value.\n * @returns Non-normalized square.\n */\n sqrN(num: T): T;\n\n // Optional\n // Should be same as sgn0 function in\n // [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#section-4.1).\n // NOTE: sgn0 is \"negative in LE\", which is the same as odd.\n // Negative in LE is a somewhat strange definition anyway.\n /**\n * Return the RFC 9380 `sgn0`-style oddness bit when supported.\n * This uses oddness instead of evenness so extension fields like Fp2 can expose the same hook.\n * Returns whether the value is odd under the field encoding.\n */\n isOdd?(num: T): boolean;\n // legendre?(num: T): T;\n /**\n * Invert many field elements in one batch.\n * @param lst - Values to invert.\n * @returns Batch of inverses.\n */\n invertBatch: (lst: T[]) => T[];\n /**\n * Encode one field value into fixed-width bytes.\n * Callers that need canonical encodings MUST supply a valid field element.\n * Low-level protocols may also use this to serialize raw / non-canonical residues.\n * @param num - Input value.\n * @returns Fixed-width byte encoding.\n */\n toBytes(num: T): Uint8Array;\n /**\n * Decode one field value from fixed-width bytes.\n * @param bytes - Fixed-width byte encoding.\n * @param skipValidation - Whether to skip range validation.\n * Implementations MUST treat `bytes` as read-only.\n * @returns Decoded field value.\n */\n fromBytes(bytes: Uint8Array, skipValidation?: boolean): T;\n // If c is False, CMOV returns a, otherwise it returns b.\n /**\n * Constant-time conditional move.\n * @param a - Value used when the condition is false.\n * @param b - Value used when the condition is true.\n * @param c - Selection bit.\n * @returns Selected value.\n */\n cmov(a: T, b: T, c: boolean): T;\n}\n// prettier-ignore\n// Arithmetic-only subset checked by validateField(). This is intentionally not the full runtime\n// IField contract: helpers like `isValidNot0`, `invertBatch`, `toBytes`, `fromBytes`, `cmov`, and\n// field-specific extras like `isOdd` are left to the callers that actually need them.\nconst FIELD_FIELDS = [\n 'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',\n 'eql', 'add', 'sub', 'mul', 'pow', 'div',\n 'addN', 'subN', 'mulN', 'sqrN'\n] as const;\n/**\n * @param field - Field implementation.\n * @returns Validated field. This only checks the arithmetic subset needed by generic helpers; it\n * does not guarantee full runtime-method coverage for serialization, batching, `cmov`, or\n * field-specific extras beyond positive `BYTES` / `BITS`.\n * @throws If the field shape or numeric metadata are invalid. {@link Error}\n * @example\n * Check that a field implementation exposes the operations curve code expects.\n *\n * ```ts\n * import { Field, validateField } from '@noble/curves/abstract/modular.js';\n * const Fp = validateField(Field(17n));\n * ```\n */\nexport function validateField<T>(field: TArg<IField<T>>): TRet<IField<T>> {\n const initial = {\n ORDER: 'bigint',\n BYTES: 'number',\n BITS: 'number',\n } as Record<string, string>;\n const opts = FIELD_FIELDS.reduce((map, val: string) => {\n map[val] = 'function';\n return map;\n }, initial);\n validateObject(field, opts);\n // Runtime field implementations must expose real integer byte/bit sizes; fractional / NaN /\n // infinite metadata leaks through validateObject(type='number') but breaks encoders and caches.\n asafenumber(field.BYTES, 'BYTES');\n asafenumber(field.BITS, 'BITS');\n // Runtime field implementations must expose positive byte/bit sizes; zero leaks through the\n // numeric shape checks above but still breaks encoding helpers and cached-length assumptions.\n if (field.BYTES < 1 || field.BITS < 1) throw new Error('invalid field: expected BYTES/BITS > 0');\n if (field.ORDER <= _1n) throw new Error('invalid field: expected ORDER > 1, got ' + field.ORDER);\n return field as TRet<IField<T>>;\n}\n\n// Generic field functions\n\n/**\n * Same as `pow` but for Fp: non-constant-time.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n * @param Fp - Field implementation.\n * @param num - Base value.\n * @param power - Exponent value.\n * @returns Powered field element.\n * @throws If the exponent is negative. {@link Error}\n * @example\n * Raise one field element to a public exponent.\n *\n * ```ts\n * import { Field, FpPow } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const x = FpPow(Fp, 3n, 5n);\n * ```\n */\nexport function FpPow<T>(Fp: TArg<IField<T>>, num: T, power: bigint): T {\n const F = Fp as IField<T>;\n if (power < _0n) throw new Error('invalid exponent, negatives unsupported');\n if (power === _0n) return F.ONE;\n if (power === _1n) return num;\n let p = F.ONE;\n let d = num;\n while (power > _0n) {\n if (power & _1n) p = F.mul(p, d);\n d = F.sqr(d);\n power >>= _1n;\n }\n return p;\n}\n\n/**\n * Efficiently invert an array of Field elements.\n * Exception-free. Zero-valued field elements stay `undefined` unless `passZero` is enabled.\n * @param Fp - Field implementation.\n * @param nums - Values to invert.\n * @param passZero - map 0 to 0 (instead of undefined)\n * @returns Inverted values.\n * @example\n * Invert several field elements with one shared inversion.\n *\n * ```ts\n * import { Field, FpInvertBatch } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const inv = FpInvertBatch(Fp, [1n, 2n, 4n]);\n * ```\n */\nexport function FpInvertBatch<T>(Fp: TArg<IField<T>>, nums: T[], passZero = false): T[] {\n const F = Fp as IField<T>;\n const inverted = new Array(nums.length).fill(passZero ? F.ZERO : undefined) as T[];\n // Walk from first to last, multiply them by each other MOD p\n const multipliedAcc = nums.reduce((acc, num, i) => {\n if (F.is0(num)) return acc;\n inverted[i] = acc;\n return F.mul(acc, num);\n }, F.ONE);\n // Invert last element\n const invertedAcc = F.inv(multipliedAcc);\n // Walk from last to first, multiply them by inverted each other MOD p\n nums.reduceRight((acc, num, i) => {\n if (F.is0(num)) return acc;\n inverted[i] = F.mul(acc, inverted[i]);\n return F.mul(acc, num);\n }, invertedAcc);\n return inverted;\n}\n\n/**\n * @param Fp - Field implementation.\n * @param lhs - Dividend value.\n * @param rhs - Divisor value.\n * @returns Division result.\n * @throws If the divisor is non-invertible. {@link Error}\n * @example\n * Divide one field element by another.\n *\n * ```ts\n * import { Field, FpDiv } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const x = FpDiv(Fp, 6n, 3n);\n * ```\n */\nexport function FpDiv<T>(Fp: TArg<IField<T>>, lhs: T, rhs: T | bigint): T {\n const F = Fp as IField<T>;\n return F.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, F.ORDER) : F.inv(rhs));\n}\n\n/**\n * Legendre symbol.\n * Legendre constant is used to calculate Legendre symbol (a | p)\n * which denotes the value of a^((p-1)/2) (mod p).\n *\n * * (a | p) ≡ 1 if a is a square (mod p), quadratic residue\n * * (a | p) ≡ -1 if a is not a square (mod p), quadratic non residue\n * * (a | p) ≡ 0 if a ≡ 0 (mod p)\n * @param Fp - Field implementation.\n * @param n - Value to inspect.\n * @returns Legendre symbol.\n * @throws If the field returns an invalid Legendre symbol value. {@link Error}\n * @example\n * Compute the Legendre symbol of one field element.\n *\n * ```ts\n * import { Field, FpLegendre } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const symbol = FpLegendre(Fp, 4n);\n * ```\n */\nexport function FpLegendre<T>(Fp: TArg<IField<T>>, n: T): -1 | 0 | 1 {\n const F = Fp as IField<T>;\n // We can use 3rd argument as optional cache of this value\n // but seems unneeded for now. The operation is very fast.\n const p1mod2 = (F.ORDER - _1n) / _2n;\n const powered = F.pow(n, p1mod2);\n const yes = F.eql(powered, F.ONE);\n const zero = F.eql(powered, F.ZERO);\n const no = F.eql(powered, F.neg(F.ONE));\n if (!yes && !zero && !no) throw new Error('invalid Legendre symbol result');\n return yes ? 1 : zero ? 0 : -1;\n}\n\n/**\n * @param Fp - Field implementation.\n * @param n - Value to inspect.\n * @returns `true` when `Fp.sqrt(n)` exists. This includes `0`, even though strict \"quadratic\n * residue\" terminology often reserves that name for the non-zero square class.\n * @throws If the field returns an invalid Legendre symbol value. {@link Error}\n * @example\n * Check whether one field element has a square root in the field.\n *\n * ```ts\n * import { Field, FpIsSquare } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const isSquare = FpIsSquare(Fp, 4n);\n * ```\n */\nexport function FpIsSquare<T>(Fp: TArg<IField<T>>, n: T): boolean {\n const l = FpLegendre(Fp as IField<T>, n);\n // Zero is a square too: 0 = 0^2, and Fp.sqrt(0) already returns 0.\n return l !== -1;\n}\n\n/** Byte and bit lengths derived from one scalar order. */\nexport type NLength = {\n /** Canonical byte length. */\n nByteLength: number;\n /** Canonical bit length. */\n nBitLength: number;\n};\n/**\n * @param n - Curve order. Callers are expected to pass a positive order.\n * @param nBitLength - Optional cached bit length. Callers are expected to pass a positive cached\n * value when overriding the derived bit length.\n * @returns Byte and bit lengths.\n * @throws If the order or cached bit length is invalid. {@link Error}\n * @example\n * Measure the encoding sizes needed for one modulus.\n *\n * ```ts\n * nLength(255n);\n * ```\n */\nexport function nLength(n: bigint, nBitLength?: number): NLength {\n // Bit size, byte size of CURVE.n\n if (nBitLength !== undefined) anumber(nBitLength);\n if (n <= _0n) throw new Error('invalid n length: expected positive n, got ' + n);\n if (nBitLength !== undefined && nBitLength < 1)\n throw new Error('invalid n length: expected positive bit length, got ' + nBitLength);\n const bits = bitLen(n);\n // Cached bit lengths smaller than ORDER would truncate serialized scalars/elements and poison\n // any math that relies on the derived field metadata.\n if (nBitLength !== undefined && nBitLength < bits)\n throw new Error(`invalid n length: expected bit length (${bits}) >= n.length (${nBitLength})`);\n const _nBitLength = nBitLength !== undefined ? nBitLength : bits;\n const nByteLength = Math.ceil(_nBitLength / 8);\n return { nBitLength: _nBitLength, nByteLength };\n}\n\ntype FpField = IField<bigint> & Required<Pick<IField<bigint>, 'isOdd'>>;\ntype SqrtFn = (n: bigint) => bigint;\ntype FieldOpts = Partial<{\n isLE: boolean;\n BITS: number;\n sqrt: SqrtFn;\n allowedLengths?: readonly number[]; // for P521 (adds padding for smaller sizes); must stay > 0\n modFromBytes: boolean; // bls12-381 requires mod(n) instead of rejecting keys >= n\n}>;\n// Keep the lazy sqrt cache off-instance so Field(...) can return a frozen object. Otherwise the\n// cached helper write would keep the field surface externally mutable.\nconst FIELD_SQRT = new WeakMap<object, ReturnType<typeof FpSqrt>>();\nclass _Field implements IField<bigint> {\n readonly ORDER: bigint;\n readonly BITS: number;\n readonly BYTES: number;\n readonly isLE: boolean;\n readonly ZERO = _0n;\n readonly ONE = _1n;\n readonly _lengths?: readonly number[];\n private readonly _mod?: boolean;\n constructor(ORDER: bigint, opts: FieldOpts = {}) {\n // ORDER <= 1 is degenerate: ONE would not be a valid field element and helpers like pow/inv\n // would stop modeling field arithmetic.\n if (ORDER <= _1n) throw new Error('invalid field: expected ORDER > 1, got ' + ORDER);\n let _nbitLength: number | undefined = undefined;\n this.isLE = false;\n if (opts != null && typeof opts === 'object') {\n // Cached bit lengths are trusted here and should already be positive / consistent with ORDER.\n if (typeof opts.BITS === 'number') _nbitLength = opts.BITS;\n if (typeof opts.sqrt === 'function')\n // `_Field.prototype` is frozen below, so custom sqrt hooks must become own properties\n // explicitly instead of relying on writable prototype shadowing via assignment.\n Object.defineProperty(this, 'sqrt', { value: opts.sqrt, enumerable: true });\n if (typeof opts.isLE === 'boolean') this.isLE = opts.isLE;\n if (opts.allowedLengths) this._lengths = Object.freeze(opts.allowedLengths.slice());\n if (typeof opts.modFromBytes === 'boolean') this._mod = opts.modFromBytes;\n }\n const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);\n if (nByteLength > 2048) throw new Error('invalid field: expected ORDER of <= 2048 bytes');\n this.ORDER = ORDER;\n this.BITS = nBitLength;\n this.BYTES = nByteLength;\n Object.freeze(this);\n }\n\n create(num: bigint) {\n return mod(num, this.ORDER);\n }\n isValid(num: bigint) {\n if (typeof num !== 'bigint')\n throw new TypeError('invalid field element: expected bigint, got ' + typeof num);\n return _0n <= num && num < this.ORDER; // 0 is valid element, but it's not invertible\n }\n is0(num: bigint) {\n return num === _0n;\n }\n // is valid and invertible\n isValidNot0(num: bigint) {\n return !this.is0(num) && this.isValid(num);\n }\n isOdd(num: bigint) {\n return (num & _1n) === _1n;\n }\n neg(num: bigint) {\n return mod(-num, this.ORDER);\n }\n eql(lhs: bigint, rhs: bigint) {\n return lhs === rhs;\n }\n\n sqr(num: bigint) {\n return mod(num * num, this.ORDER);\n }\n add(lhs: bigint, rhs: bigint) {\n return mod(lhs + rhs, this.ORDER);\n }\n sub(lhs: bigint, rhs: bigint) {\n return mod(lhs - rhs, this.ORDER);\n }\n mul(lhs: bigint, rhs: bigint) {\n return mod(lhs * rhs, this.ORDER);\n }\n pow(num: bigint, power: bigint): bigint {\n return FpPow(this, num, power);\n }\n div(lhs: bigint, rhs: bigint) {\n return mod(lhs * invert(rhs, this.ORDER), this.ORDER);\n }\n\n // Same as above, but doesn't normalize\n sqrN(num: bigint) {\n return num * num;\n }\n addN(lhs: bigint, rhs: bigint) {\n return lhs + rhs;\n }\n subN(lhs: bigint, rhs: bigint) {\n return lhs - rhs;\n }\n mulN(lhs: bigint, rhs: bigint) {\n return lhs * rhs;\n }\n\n inv(num: bigint) {\n return invert(num, this.ORDER);\n }\n sqrt(num: bigint): bigint {\n // Caching sqrt helpers speeds up sqrt9mod16 by 5x and Tonelli-Shanks by about 10% without keeping\n // the field instance itself mutable.\n let sqrt = FIELD_SQRT.get(this);\n if (!sqrt) FIELD_SQRT.set(this, (sqrt = FpSqrt(this.ORDER)));\n return sqrt(this, num);\n }\n toBytes(num: bigint) {\n // Serialize fixed-width limbs without re-validating the field range. Callers that need a\n // canonical encoding must pass a valid element; some protocols intentionally serialize raw\n // residues here and reduce or validate them elsewhere.\n return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);\n }\n fromBytes(bytes: Uint8Array, skipValidation = false) {\n abytes(bytes);\n const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;\n if (allowedLengths) {\n // `allowedLengths` must list real positive byte lengths; otherwise empty input would get\n // padded into zero and silently decode as a field element.\n if (bytes.length < 1 || !allowedLengths.includes(bytes.length) || bytes.length > BYTES) {\n throw new Error(\n 'Field.fromBytes: expected ' + allowedLengths + ' bytes, got ' + bytes.length\n );\n }\n const padded = new Uint8Array(BYTES);\n // isLE add 0 to right, !isLE to the left.\n padded.set(bytes, isLE ? 0 : padded.length - bytes.length);\n bytes = padded;\n }\n if (bytes.length !== BYTES)\n throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);\n let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n if (modFromBytes) scalar = mod(scalar, ORDER);\n if (!skipValidation)\n if (!this.isValid(scalar))\n throw new Error('invalid field element: outside of range 0..ORDER');\n // Range validation is optional here because some protocols intentionally decode raw residues\n // and reduce or validate them elsewhere.\n return scalar;\n }\n // TODO: we don't need it here, move out to separate fn\n invertBatch(lst: bigint[]): bigint[] {\n return FpInvertBatch(this, lst);\n }\n // We can't move this out because Fp6, Fp12 implement it\n // and it's unclear what to return in there.\n cmov(a: bigint, b: bigint, condition: boolean) {\n // Field elements have `isValid(...)`; the CMOV branch bit is a direct runtime input, so reject\n // non-boolean selectors here instead of letting JS truthiness silently change arithmetic.\n abool(condition, 'condition');\n return condition ? b : a;\n }\n}\n// Freeze the shared method surface too; otherwise callers can still poison every Field instance by\n// monkey-patching `_Field.prototype` even if each instance is frozen.\nObject.freeze(_Field.prototype);\n\n/**\n * Creates a finite field. Major performance optimizations:\n * * 1. Denormalized operations like mulN instead of mul.\n * * 2. Identical object shape: never add or remove keys.\n * * 3. Frozen stable object shape; the lazy sqrt cache lives in a module-level `WeakMap`.\n * Fragile: always run a benchmark on a change.\n * Security note: operations and low-level serializers like `toBytes` don't check `isValid` for\n * all elements for performance and protocol-flexibility reasons; callers are responsible for\n * supplying valid elements when they need canonical field behavior.\n * This is low-level code, please make sure you know what you're doing.\n *\n * Note about field properties:\n * * CHARACTERISTIC p = prime number, number of elements in main subgroup.\n * * ORDER q = similar to cofactor in curves, may be composite `q = p^m`.\n *\n * @param ORDER - field order, probably prime, or could be composite\n * @param opts - Field options such as bit length or endianness. See {@link FieldOpts}.\n * @returns Frozen field instance with a stable object shape. This wrapper forwards `opts` straight\n * into `_Field`, so it inherits `_Field`'s assumptions about cached sizes and `allowedLengths`.\n * @example\n * Construct one prime field with optional overrides.\n *\n * ```ts\n * Field(11n);\n * ```\n */\nexport function Field(ORDER: bigint, opts: FieldOpts = {}): TRet<Readonly<FpField>> {\n return new _Field(ORDER, opts);\n}\n\n// Generic random scalar, we can do same for other fields if via Fp2.mul(Fp2.ONE, Fp2.random)?\n// This allows unsafe methods like ignore bias or zero. These unsafe, but often used in different protocols (if deterministic RNG).\n// which mean we cannot force this via opts.\n// Not sure what to do with randomBytes, we can accept it inside opts if wanted.\n// Probably need to export getMinHashLength somewhere?\n// random(bytes?: Uint8Array, unsafeAllowZero = false, unsafeAllowBias = false) {\n// const LEN = !unsafeAllowBias ? getMinHashLength(ORDER) : BYTES;\n// if (bytes === undefined) bytes = randomBytes(LEN); // _opts.randomBytes?\n// const num = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n// // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n// const reduced = unsafeAllowZero ? mod(num, ORDER) : mod(num, ORDER - _1n) + _1n;\n// return reduced;\n// },\n\n/**\n * @param Fp - Field implementation.\n * @param elm - Value to square-root.\n * @returns Odd square root when two roots exist. The special case `elm = 0` still returns `0`,\n * which is the only square root but is not odd.\n * @throws If the field lacks oddness checks or the square root does not exist. {@link Error}\n * @example\n * Select the odd square root when two roots exist.\n *\n * ```ts\n * import { Field, FpSqrtOdd } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const root = FpSqrtOdd(Fp, 4n);\n * ```\n */\nexport function FpSqrtOdd<T>(Fp: TArg<IField<T>>, elm: T): T {\n const F = Fp as IField<T>;\n if (!F.isOdd) throw new Error(\"Field doesn't have isOdd\");\n const root = F.sqrt(elm);\n return F.isOdd(root) ? root : F.neg(root);\n}\n\n/**\n * @param Fp - Field implementation.\n * @param elm - Value to square-root.\n * @returns Even square root.\n * @throws If the field lacks oddness checks or the square root does not exist. {@link Error}\n * @example\n * Select the even square root when two roots exist.\n *\n * ```ts\n * import { Field, FpSqrtEven } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const root = FpSqrtEven(Fp, 4n);\n * ```\n */\nexport function FpSqrtEven<T>(Fp: TArg<IField<T>>, elm: T): T {\n const F = Fp as IField<T>;\n if (!F.isOdd) throw new Error(\"Field doesn't have isOdd\");\n const root = F.sqrt(elm);\n return F.isOdd(root) ? F.neg(root) : root;\n}\n\n/**\n * Returns total number of bytes consumed by the field element.\n * For example, 32 bytes for usual 256-bit weierstrass curve.\n * @param fieldOrder - number of field elements, usually CURVE.n. Callers are expected to pass an\n * order greater than 1.\n * @returns byte length of field\n * @throws If the field order is not a bigint. {@link Error}\n * @example\n * Read the fixed-width byte length of one field.\n *\n * ```ts\n * getFieldBytesLength(255n);\n * ```\n */\nexport function getFieldBytesLength(fieldOrder: bigint): number {\n if (typeof fieldOrder !== 'bigint') throw new Error('field order must be bigint');\n // Valid field elements are in 0..ORDER-1, so ORDER <= 1 would make the encoded range degenerate.\n if (fieldOrder <= _1n) throw new Error('field order must be greater than 1');\n // Valid field elements are < ORDER, so the maximal encoded element is ORDER - 1.\n const bitLength = bitLen(fieldOrder - _1n);\n return Math.ceil(bitLength / 8);\n}\n\n/**\n * Returns minimal amount of bytes that can be safely reduced\n * by field order.\n * Should be 2^-128 for 128-bit curve such as P256.\n * This is the reduction / modulo-bias lower bound; higher-level helpers may still impose a larger\n * absolute floor for policy reasons.\n * @param fieldOrder - number of field elements greater than 1, usually CURVE.n.\n * @returns byte length of target hash\n * @throws If the field order is invalid. {@link Error}\n * @example\n * Compute the minimum hash length needed for field reduction.\n *\n * ```ts\n * getMinHashLength(255n);\n * ```\n */\nexport function getMinHashLength(fieldOrder: bigint): number {\n const length = getFieldBytesLength(fieldOrder);\n return length + Math.ceil(length / 2);\n}\n\n/**\n * \"Constant-time\" private key generation utility.\n * Can take (n + n/2) or more bytes of uniform input e.g. from CSPRNG or KDF\n * and convert them into private scalar, with the modulo bias being negligible.\n * Needs at least 48 bytes of input for 32-byte private key. The implementation also keeps a hard\n * 16-byte minimum even when `getMinHashLength(...)` is smaller, so toy-small inputs do not look\n * accidentally acceptable for real scalar derivation.\n * See {@link https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/ | Kudelski's modulo-bias guide},\n * {@link https://csrc.nist.gov/publications/detail/fips/186/5/final | FIPS 186-5 appendix A.2}, and\n * {@link https://www.rfc-editor.org/rfc/rfc9380#section-5 | RFC 9380 section 5}. Unlike RFC 9380\n * `hash_to_field`, this helper intentionally maps into the non-zero private-scalar range `1..n-1`.\n * @param key - Uniform input bytes.\n * @param fieldOrder - Size of subgroup.\n * @param isLE - interpret hash bytes as LE num\n * @returns valid private scalar\n * @throws If the hash length or field order is invalid for scalar reduction. {@link Error}\n * @example\n * Map hash output into a private scalar range.\n *\n * ```ts\n * mapHashToField(new Uint8Array(48).fill(1), 255n);\n * ```\n */\nexport function mapHashToField(\n key: TArg<Uint8Array>,\n fieldOrder: bigint,\n isLE = false\n): TRet<Uint8Array> {\n abytes(key);\n const len = key.length;\n const fieldLen = getFieldBytesLength(fieldOrder);\n const minLen = Math.max(getMinHashLength(fieldOrder), 16);\n // No toy-small inputs: the helper is for real scalar derivation, not tiny test curves. No huge\n // inputs: easier to reason about JS timing / allocation behavior.\n if (len < minLen || len > 1024)\n throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);\n const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);\n // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n const reduced = mod(num, fieldOrder - _1n) + _1n;\n return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);\n}\n","/**\n * Methods for elliptic curve multiplication by scalars.\n * Contains wNAF, pippenger.\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { bitLen, bitMask, validateObject, type Signer, type TArg, type TRet } from '../utils.ts';\nimport { Field, FpInvertBatch, validateField, type IField } from './modular.ts';\n\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _1n = /* @__PURE__ */ BigInt(1);\n\n/** Affine point coordinates without projective fields. */\nexport type AffinePoint<T> = {\n /** Affine x coordinate. */\n x: T;\n /** Affine y coordinate. */\n y: T;\n} & { Z?: never };\n\n// We can't \"abstract out\" coordinates (X, Y, Z; and T in Edwards): argument names of constructor\n// are not accessible. See Typescript gh-56093, gh-41594.\n//\n// We have to use recursive types, so it will return actual point, not constained `CurvePoint`.\n// If, at any point, P is `any`, it will erase all types and replace it\n// with `any`, because of recursion, `any implements CurvePoint`,\n// but we lose all constrains on methods.\n\n/** Base interface for all elliptic-curve point instances. */\nexport interface CurvePoint<F, P extends CurvePoint<F, P>> {\n /** Affine x coordinate. Different from projective / extended X coordinate. */\n x: F;\n /** Affine y coordinate. Different from projective / extended Y coordinate. */\n y: F;\n /** Projective Z coordinate when the point keeps projective state. */\n Z?: F;\n /**\n * Double the point.\n * @returns Doubled point.\n */\n double(): P;\n /**\n * Negate the point.\n * @returns Negated point.\n */\n negate(): P;\n /**\n * Add another point from the same curve.\n * @param other - Point to add.\n * @returns Sum point.\n */\n add(other: P): P;\n /**\n * Subtract another point from the same curve.\n * @param other - Point to subtract.\n * @returns Difference point.\n */\n subtract(other: P): P;\n /**\n * Compare two points for equality.\n * @param other - Point to compare.\n * @returns Whether the points are equal.\n */\n equals(other: P): boolean;\n /**\n * Multiply the point by a scalar in constant time.\n * Implementations keep the subgroup-scalar contract strict and may reject\n * `0` instead of returning the identity point.\n * @param scalar - Scalar multiplier.\n * @returns Product point.\n */\n multiply(scalar: bigint): P;\n /** Assert that the point satisfies the curve equation and subgroup checks. */\n assertValidity(): void;\n /**\n * Map the point into the prime-order subgroup when the curve requires it.\n * @returns Prime-order point.\n */\n clearCofactor(): P;\n /**\n * Check whether the point is the point at infinity.\n * @returns Whether the point is zero.\n */\n is0(): boolean;\n /**\n * Check whether the point belongs to the prime-order subgroup.\n * @returns Whether the point is torsion-free.\n */\n isTorsionFree(): boolean;\n /**\n * Check whether the point lies in a small torsion subgroup.\n * @returns Whether the point has small order.\n */\n isSmallOrder(): boolean;\n /**\n * Multiply the point by a scalar without constant-time guarantees.\n * Public-scalar callers that need `0` should use this method instead of\n * relying on `multiply(...)` to return the identity point.\n * @param scalar - Scalar multiplier.\n * @returns Product point.\n */\n multiplyUnsafe(scalar: bigint): P;\n /**\n * Massively speeds up `p.multiply(n)` by using precompute tables (caching). See {@link wNAF}.\n * Cache state lives in internal WeakMaps keyed by point identity, not on the point object.\n * Repeating `precompute(...)` for the same point identity replaces the remembered window size\n * and forces table regeneration for that point.\n * @param windowSize - Precompute window size.\n * @param isLazy - calculate cache now. Default (true) ensures it's deferred to first `multiply()`\n * @returns Same point instance with precompute tables attached.\n */\n precompute(windowSize?: number, isLazy?: boolean): P;\n /**\n * Converts point to 2D xy affine coordinates.\n * @param invertedZ - Optional inverted Z coordinate for batch normalization.\n * @returns Affine x/y coordinates.\n */\n toAffine(invertedZ?: F): AffinePoint<F>;\n /**\n * Encode the point into the curve's canonical byte form.\n * @returns Encoded point bytes.\n */\n toBytes(): Uint8Array;\n /**\n * Encode the point into the curve's canonical hex form.\n * @returns Encoded point hex.\n */\n toHex(): string;\n}\n\n/** Base interface for elliptic-curve point constructors. */\nexport interface CurvePointCons<P extends CurvePoint<any, P>> {\n /**\n * Runtime brand check for points created by this constructor.\n * @param item - Value to test.\n * @returns Whether the value is a point from this constructor.\n */\n [Symbol.hasInstance]: (item: unknown) => boolean;\n /** Canonical subgroup generator. */\n BASE: P;\n /** Point at infinity. */\n ZERO: P;\n /** Field for basic curve math */\n Fp: IField<P_F<P>>;\n /** Scalar field, for scalars in multiply and others */\n Fn: IField<bigint>;\n /**\n * Create one point from affine coordinates.\n * Does NOT validate curve, subgroup, or wrapper invariants.\n * Use `.assertValidity()` on adversarial inputs.\n * @param p - Affine point coordinates.\n * @returns Point instance.\n */\n fromAffine(p: AffinePoint<P_F<P>>): P;\n /**\n * Decode a point from the canonical byte encoding.\n * @param bytes - Encoded point bytes.\n * Implementations MUST treat `bytes` as read-only.\n * @returns Point instance.\n */\n fromBytes(bytes: Uint8Array): P;\n /**\n * Decode a point from the canonical hex encoding.\n * @param hex - Encoded point hex.\n * @returns Point instance.\n */\n fromHex(hex: string): P;\n}\n\n// Type inference helpers: PC - PointConstructor, P - Point, Fp - Field element\n// Short names, because we use them a lot in result types:\n// * we can't do 'P = GetCurvePoint<PC>': this is default value and doesn't constrain anything\n// * we can't do 'type X = GetCurvePoint<PC>': it won't be accesible for arguments/return types\n// * `CurvePointCons<P extends CurvePoint<any, P>>` constraints from interface definition\n// won't propagate, if `PC extends CurvePointCons<any>`: the P would be 'any', which is incorrect\n// * PC could be super specific with super specific P, which implements CurvePoint<any, P>.\n// this means we need to do stuff like\n// `function test<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(`\n// if we want type safety around P, otherwise PC_P<PC> will be any\n\n/** Returns the affine field type for a point instance (`P_F<P> == P.F`). */\nexport type P_F<P extends CurvePoint<any, P>> = P extends CurvePoint<infer F, P> ? F : never;\n/** Returns the affine field type for a point constructor (`PC_F<PC> == PC.P.F`). */\nexport type PC_F<PC extends CurvePointCons<CurvePoint<any, any>>> = PC['Fp']['ZERO'];\n/** Returns the point instance type for a point constructor (`PC_P<PC> == PC.P`). */\nexport type PC_P<PC extends CurvePointCons<CurvePoint<any, any>>> = PC['ZERO'];\n\n// Ugly hack to get proper type inference, because in typescript fails to infer resursively.\n// The hack allows to do up to 10 chained operations without applying type erasure.\n//\n// Types which won't work:\n// * `CurvePointCons<CurvePoint<any, any>>`, will return `any` after 1 operation\n// * `CurvePointCons<any>: WeierstrassPointCons<bigint> extends CurvePointCons<any> = false`\n// * `P extends CurvePoint, PC extends CurvePointCons<P>`\n// * It can't infer P from PC alone\n// * Too many relations between F, P & PC\n// * It will infer P/F if `arg: CurvePointCons<F, P>`, but will fail if PC is generic\n// * It will work correctly if there is an additional argument of type P\n// * But generally, we don't want to parametrize `CurvePointCons` over `F`: it will complicate\n// types, making them un-inferable\n// prettier-ignore\n/** Wide point-constructor type used when the concrete curve is not important. */\nexport type PC_ANY = CurvePointCons<\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any,\n CurvePoint<any, any>\n >>>>>>>>>\n>;\n\n/**\n * Validates the static surface of a point constructor.\n * This is only a cheap sanity check for the constructor hooks and fields consumed by generic\n * factories; it does not certify `BASE`/`ZERO` semantics or prove the curve implementation itself.\n * @param Point - Runtime point constructor.\n * @throws On missing constructor hooks or malformed field metadata. {@link TypeError}\n * @example\n * Check that one point constructor exposes the static hooks generic helpers need.\n *\n * ```ts\n * import { ed25519 } from '@noble/curves/ed25519.js';\n * import { validatePointCons } from '@noble/curves/abstract/curve.js';\n * validatePointCons(ed25519.Point);\n * ```\n */\nexport function validatePointCons<P extends CurvePoint<any, P>>(Point: CurvePointCons<P>): void {\n const pc = Point as unknown as CurvePointCons<any>;\n if (typeof (pc as unknown) !== 'function') throw new TypeError('Point must be a constructor');\n // validateObject only accepts plain objects, so copy the constructor statics into one bag first.\n validateObject(\n {\n Fp: pc.Fp,\n Fn: pc.Fn,\n fromAffine: pc.fromAffine,\n fromBytes: pc.fromBytes,\n fromHex: pc.fromHex,\n },\n {\n Fp: 'object',\n Fn: 'object',\n fromAffine: 'function',\n fromBytes: 'function',\n fromHex: 'function',\n }\n );\n validateField(pc.Fp);\n validateField(pc.Fn);\n}\n\n/** Byte lengths used by one curve implementation. */\nexport interface CurveLengths {\n /** Secret-key length in bytes. */\n secretKey?: number;\n /** Compressed public-key length in bytes. */\n publicKey?: number;\n /** Uncompressed public-key length in bytes. */\n publicKeyUncompressed?: number;\n /** Whether public-key encodings include a format prefix byte. */\n publicKeyHasPrefix?: boolean;\n /** Signature length in bytes. */\n signature?: number;\n /** Seed length in bytes when the curve exposes deterministic keygen from seed. */\n seed?: number;\n}\n\n/** Reorders or otherwise remaps a batch while preserving its element type. */\nexport type Mapper<T> = (i: T[]) => T[];\n\n/**\n * Computes both candidates first, but the final selection still branches on `condition`, so this\n * is not a strict constant-time CMOV primitive.\n * @param condition - Whether to negate the point.\n * @param item - Point-like value.\n * @returns Original or negated value.\n * @example\n * Keep the point or return its negation based on one boolean branch.\n *\n * ```ts\n * import { negateCt } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const maybeNegated = negateCt(true, p256.Point.BASE);\n * ```\n */\nexport function negateCt<T extends { negate: () => T }>(condition: boolean, item: T): T {\n const neg = item.negate();\n return condition ? neg : item;\n}\n\n/**\n * Takes a bunch of Projective Points but executes only one\n * inversion on all of them. Inversion is very slow operation,\n * so this improves performance massively.\n * Optimization: converts a list of projective points to a list of identical points with Z=1.\n * Input points are left unchanged; the normalized points are returned as fresh instances.\n * @param c - Point constructor.\n * @param points - Projective points.\n * @returns Fresh projective points reconstructed from normalized affine coordinates.\n * @example\n * Batch-normalize projective points with a single shared inversion.\n *\n * ```ts\n * import { normalizeZ } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const points = normalizeZ(p256.Point, [p256.Point.BASE, p256.Point.BASE.double()]);\n * ```\n */\nexport function normalizeZ<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n c: PC,\n points: P[]\n): P[] {\n const invertedZs = FpInvertBatch(\n c.Fp,\n points.map((p) => p.Z!)\n );\n return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));\n}\n\nfunction validateW(W: number, bits: number) {\n if (!Number.isSafeInteger(W) || W <= 0 || W > bits)\n throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);\n}\n\n/** Internal wNAF opts for specific W and scalarBits.\n * Zero digits are skipped, so tables store only the positive half-window and callers reserve one\n * extra carry window.\n */\ntype WOpts = {\n windows: number;\n windowSize: number;\n mask: bigint;\n maxNumber: number;\n shiftBy: bigint;\n};\n\nfunction calcWOpts(W: number, scalarBits: number): WOpts {\n validateW(W, scalarBits);\n const windows = Math.ceil(scalarBits / W) + 1; // W=8 33. Not 32, because we skip zero\n const windowSize = 2 ** (W - 1); // W=8 128. Not 256, because we skip zero\n const maxNumber = 2 ** W; // W=8 256\n const mask = bitMask(W); // W=8 255 == mask 0b11111111\n const shiftBy = BigInt(W); // W=8 8\n return { windows, windowSize, mask, maxNumber, shiftBy };\n}\n\nfunction calcOffsets(n: bigint, window: number, wOpts: WOpts) {\n const { windowSize, mask, maxNumber, shiftBy } = wOpts;\n let wbits = Number(n & mask); // extract W bits.\n let nextN = n >> shiftBy; // shift number by W bits.\n\n // What actually happens here:\n // const highestBit = Number(mask ^ (mask >> 1n));\n // let wbits2 = wbits - 1; // skip zero\n // if (wbits2 & highestBit) { wbits2 ^= Number(mask); // (~);\n\n // split if bits > max: +224 => 256-32\n if (wbits > windowSize) {\n // we skip zero, which means instead of `>= size-1`, we do `> size`\n wbits -= maxNumber; // -32, can be maxNumber - wbits, but then we need to set isNeg here.\n nextN += _1n; // +256 (carry)\n }\n const offsetStart = window * windowSize;\n const offset = offsetStart + Math.abs(wbits) - 1; // -1 because we skip zero; ignore when isZero\n const isZero = wbits === 0; // is current window slice a 0?\n const isNeg = wbits < 0; // is current window slice negative?\n const isNegF = window % 2 !== 0; // fake branch noise only\n const offsetF = offsetStart; // fake branch noise only\n return { nextN, offset, isZero, isNeg, isNegF, offsetF };\n}\n\nfunction validateMSMPoints(points: any[], c: any) {\n if (!Array.isArray(points)) throw new Error('array expected');\n points.forEach((p, i) => {\n if (!(p instanceof c)) throw new Error('invalid point at index ' + i);\n });\n}\nfunction validateMSMScalars(scalars: any[], field: any) {\n if (!Array.isArray(scalars)) throw new Error('array of scalars expected');\n scalars.forEach((s, i) => {\n if (!field.isValid(s)) throw new Error('invalid scalar at index ' + i);\n });\n}\n\n// Since points in different groups cannot be equal (different object constructor),\n// we can have single place to store precomputes.\n// Allows to make points frozen / immutable.\nconst pointPrecomputes = new WeakMap<any, any[]>();\nconst pointWindowSizes = new WeakMap<any, number>();\n\nfunction getW(P: any): number {\n // To disable precomputes:\n // return 1;\n // `1` is also the uncached sentinel: use the ladder / non-precomputed path.\n return pointWindowSizes.get(P) || 1;\n}\n\nfunction assert0(n: bigint): void {\n // Internal invariant: a non-zero remainder here means the wNAF window decomposition or loop\n // count is inconsistent, not that the original caller provided a bad scalar.\n if (n !== _0n) throw new Error('invalid wNAF');\n}\n\n/**\n * Elliptic curve multiplication of Point by scalar. Fragile.\n * Table generation takes **30MB of ram and 10ms on high-end CPU**,\n * but may take much longer on slow devices. Actual generation will happen on\n * first call of `multiply()`. By default, `BASE` point is precomputed.\n *\n * Scalars should always be less than curve order: this should be checked inside of a curve itself.\n * Creates precomputation tables for fast multiplication:\n * - private scalar is split by fixed size windows of W bits\n * - every window point is collected from window's table & added to accumulator\n * - since windows are different, same point inside tables won't be accessed more than once per calc\n * - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)\n * - +1 window is neccessary for wNAF\n * - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication\n *\n * TODO: research returning a 2d JS array of windows instead of a single window.\n * This would allow windows to be in different memory locations.\n * @param Point - Point constructor.\n * @param bits - Scalar bit length.\n * @example\n * Elliptic curve multiplication of Point by scalar.\n *\n * ```ts\n * import { wNAF } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const ladder = new wNAF(p256.Point, p256.Point.Fn.BITS);\n * ```\n */\nexport class wNAF<PC extends PC_ANY> {\n private readonly BASE: PC_P<PC>;\n private readonly ZERO: PC_P<PC>;\n private readonly Fn: PC['Fn'];\n readonly bits: number;\n\n // Parametrized with a given Point class (not individual point)\n constructor(Point: PC, bits: number) {\n this.BASE = Point.BASE;\n this.ZERO = Point.ZERO;\n this.Fn = Point.Fn;\n this.bits = bits;\n }\n\n // non-const time multiplication ladder\n _unsafeLadder(elm: PC_P<PC>, n: bigint, p: PC_P<PC> = this.ZERO): PC_P<PC> {\n let d: PC_P<PC> = elm;\n while (n > _0n) {\n if (n & _1n) p = p.add(d);\n d = d.double();\n n >>= _1n;\n }\n return p;\n }\n\n /**\n * Creates a wNAF precomputation window. Used for caching.\n * Default window size is set by `utils.precompute()` and is equal to 8.\n * Number of precomputed points depends on the curve size:\n * 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:\n * - 𝑊 is the window size\n * - 𝑛 is the bitlength of the curve order.\n * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.\n * @param point - Point instance\n * @param W - window size\n * @returns precomputed point tables flattened to a single array\n */\n private precomputeWindow(point: PC_P<PC>, W: number): PC_P<PC>[] {\n const { windows, windowSize } = calcWOpts(W, this.bits);\n const points: PC_P<PC>[] = [];\n let p: PC_P<PC> = point;\n let base = p;\n for (let window = 0; window < windows; window++) {\n base = p;\n points.push(base);\n // i=1, bc we skip 0\n for (let i = 1; i < windowSize; i++) {\n base = base.add(p);\n points.push(base);\n }\n p = base.double();\n }\n return points;\n }\n\n /**\n * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.\n * More compact implementation:\n * https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541\n * @returns real and fake (for const-time) points\n */\n private wNAF(W: number, precomputes: PC_P<PC>[], n: bigint): { p: PC_P<PC>; f: PC_P<PC> } {\n // Scalar should be smaller than field order\n if (!this.Fn.isValid(n)) throw new Error('invalid scalar');\n // Accumulators\n let p = this.ZERO;\n let f = this.BASE;\n // This code was first written with assumption that 'f' and 'p' will never be infinity point:\n // since each addition is multiplied by 2 ** W, it cannot cancel each other. However,\n // there is negate now: it is possible that negated element from low value\n // would be the same as high element, which will create carry into next window.\n // It's not obvious how this can fail, but still worth investigating later.\n const wo = calcWOpts(W, this.bits);\n for (let window = 0; window < wo.windows; window++) {\n // (n === _0n) is handled and not early-exited. isEven and offsetF are used for noise\n const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);\n n = nextN;\n if (isZero) {\n // bits are 0: add garbage to fake point\n // Important part for const-time getPublicKey: add random \"noise\" point to f.\n f = f.add(negateCt(isNegF, precomputes[offsetF]));\n } else {\n // bits are 1: add to result point\n p = p.add(negateCt(isNeg, precomputes[offset]));\n }\n }\n assert0(n);\n // Return both real and fake points so JIT keeps the noise path alive.\n // Known caveat: negate/carry interactions can still drive `f` to infinity even when `p` is not,\n // which weakens the noise path and leaves this only \"less const-time\" by about one bigint mul.\n return { p, f };\n }\n\n /**\n * Implements unsafe EC multiplication using precomputed tables\n * and w-ary non-adjacent form.\n * @param acc - accumulator point to add result of multiplication\n * @returns point\n */\n private wNAFUnsafe(\n W: number,\n precomputes: PC_P<PC>[],\n n: bigint,\n acc: PC_P<PC> = this.ZERO\n ): PC_P<PC> {\n const wo = calcWOpts(W, this.bits);\n for (let window = 0; window < wo.windows; window++) {\n if (n === _0n) break; // Early-exit, skip 0 value\n const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);\n n = nextN;\n if (isZero) {\n // Window bits are 0: skip processing.\n // Move to next window.\n continue;\n } else {\n const item = precomputes[offset];\n acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM\n }\n }\n assert0(n);\n return acc;\n }\n\n private getPrecomputes(W: number, point: PC_P<PC>, transform?: Mapper<PC_P<PC>>): PC_P<PC>[] {\n // Cache key is only point identity plus the remembered window size; callers must not reuse the\n // same point with incompatible `transform(...)` layouts and expect a separate cache entry.\n let comp = pointPrecomputes.get(point);\n if (!comp) {\n comp = this.precomputeWindow(point, W) as PC_P<PC>[];\n if (W !== 1) {\n // Doing transform outside of if brings 15% perf hit\n if (typeof transform === 'function') comp = transform(comp);\n pointPrecomputes.set(point, comp);\n }\n }\n return comp;\n }\n\n cached(\n point: PC_P<PC>,\n scalar: bigint,\n transform?: Mapper<PC_P<PC>>\n ): { p: PC_P<PC>; f: PC_P<PC> } {\n const W = getW(point);\n return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);\n }\n\n unsafe(point: PC_P<PC>, scalar: bigint, transform?: Mapper<PC_P<PC>>, prev?: PC_P<PC>): PC_P<PC> {\n const W = getW(point);\n if (W === 1) return this._unsafeLadder(point, scalar, prev); // For W=1 ladder is ~x2 faster\n return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);\n }\n\n // We calculate precomputes for elliptic curve point multiplication\n // using windowed method. This specifies window size and\n // stores precomputed values. Usually only base point would be precomputed.\n createCache(P: PC_P<PC>, W: number): void {\n validateW(W, this.bits);\n pointWindowSizes.set(P, W);\n pointPrecomputes.delete(P);\n }\n\n hasCache(elm: PC_P<PC>): boolean {\n return getW(elm) !== 1;\n }\n}\n\n/**\n * Endomorphism-specific multiplication for Koblitz curves.\n * Cost: 128 dbl, 0-256 adds.\n * @param Point - Point constructor.\n * @param point - Input point.\n * @param k1 - First non-negative absolute scalar chunk.\n * @param k2 - Second non-negative absolute scalar chunk.\n * @returns Partial multiplication results.\n * @example\n * Endomorphism-specific multiplication for Koblitz curves.\n *\n * ```ts\n * import { mulEndoUnsafe } from '@noble/curves/abstract/curve.js';\n * import { secp256k1 } from '@noble/curves/secp256k1.js';\n * const parts = mulEndoUnsafe(secp256k1.Point, secp256k1.Point.BASE, 3n, 5n);\n * ```\n */\nexport function mulEndoUnsafe<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n Point: PC,\n point: P,\n k1: bigint,\n k2: bigint\n): { p1: P; p2: P } {\n let acc = point;\n let p1 = Point.ZERO;\n let p2 = Point.ZERO;\n while (k1 > _0n || k2 > _0n) {\n if (k1 & _1n) p1 = p1.add(acc);\n if (k2 & _1n) p2 = p2.add(acc);\n acc = acc.double();\n k1 >>= _1n;\n k2 >>= _1n;\n }\n return { p1, p2 };\n}\n\n/**\n * Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n * 30x faster vs naive addition on L=4096, 10x faster than precomputes.\n * For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.\n * Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.\n * @param c - Curve Point constructor\n * @param points - array of L curve points\n * @param scalars - array of L scalars (aka secret keys / bigints)\n * @returns MSM result point. Empty input is accepted and returns the identity.\n * @throws If the point set, scalar set, or MSM sizing is invalid. {@link Error}\n * @example\n * Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n *\n * ```ts\n * import { pippenger } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const point = pippenger(p256.Point, [p256.Point.BASE, p256.Point.BASE.double()], [2n, 3n]);\n * ```\n */\nexport function pippenger<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n c: PC,\n points: P[],\n scalars: bigint[]\n): P {\n // If we split scalars by some window (let's say 8 bits), every chunk will only\n // take 256 buckets even if there are 4096 scalars, also re-uses double.\n // TODO:\n // - https://eprint.iacr.org/2024/750.pdf\n // - https://tches.iacr.org/index.php/TCHES/article/view/10287\n // 0 is accepted in scalars\n const fieldN = c.Fn;\n validateMSMPoints(points, c);\n validateMSMScalars(scalars, fieldN);\n const plength = points.length;\n const slength = scalars.length;\n if (plength !== slength) throw new Error('arrays of points and scalars must have equal length');\n // if (plength === 0) throw new Error('array must be of length >= 2');\n const zero = c.ZERO;\n const wbits = bitLen(BigInt(plength));\n let windowSize = 1; // bits\n if (wbits > 12) windowSize = wbits - 3;\n else if (wbits > 4) windowSize = wbits - 2;\n else if (wbits > 0) windowSize = 2;\n const MASK = bitMask(windowSize);\n const buckets = new Array(Number(MASK) + 1).fill(zero); // +1 for zero array\n const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;\n let sum = zero;\n for (let i = lastBits; i >= 0; i -= windowSize) {\n buckets.fill(zero);\n for (let j = 0; j < slength; j++) {\n const scalar = scalars[j];\n const wbits = Number((scalar >> BigInt(i)) & MASK);\n buckets[wbits] = buckets[wbits].add(points[j]);\n }\n let resI = zero; // not using this will do small speed-up, but will lose ct\n // Skip first bucket, because it is zero\n for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {\n sumI = sumI.add(buckets[j]);\n resI = resI.add(sumI);\n }\n sum = sum.add(resI);\n if (i !== 0) for (let j = 0; j < windowSize; j++) sum = sum.double();\n }\n return sum as P;\n}\n/**\n * Precomputed multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n * @param c - Curve Point constructor\n * @param points - array of L curve points\n * @param windowSize - Precompute window size.\n * @returns Function which multiplies points with scalars. The closure accepts\n * `scalars.length <= points.length`, and omitted trailing scalars are treated as zero.\n * @throws If the point set or precompute window is invalid. {@link Error}\n * @example\n * Precomputed multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).\n *\n * ```ts\n * import { precomputeMSMUnsafe } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const msm = precomputeMSMUnsafe(p256.Point, [p256.Point.BASE], 4);\n * const point = msm([3n]);\n * ```\n */\nexport function precomputeMSMUnsafe<P extends CurvePoint<any, P>, PC extends CurvePointCons<P>>(\n c: PC,\n points: P[],\n windowSize: number\n): (scalars: bigint[]) => P {\n /**\n * Performance Analysis of Window-based Precomputation\n *\n * Base Case (256-bit scalar, 8-bit window):\n * - Standard precomputation requires:\n * - 31 additions per scalar × 256 scalars = 7,936 ops\n * - Plus 255 summary additions = 8,191 total ops\n * Note: Summary additions can be optimized via accumulator\n *\n * Chunked Precomputation Analysis:\n * - Using 32 chunks requires:\n * - 255 additions per chunk\n * - 256 doublings\n * - Total: (255 × 32) + 256 = 8,416 ops\n *\n * Memory Usage Comparison:\n * Window Size | Standard Points | Chunked Points\n * ------------|-----------------|---------------\n * 4-bit | 520 | 15\n * 8-bit | 4,224 | 255\n * 10-bit | 13,824 | 1,023\n * 16-bit | 557,056 | 65,535\n *\n * Key Advantages:\n * 1. Enables larger window sizes due to reduced memory overhead\n * 2. More efficient for smaller scalar counts:\n * - 16 chunks: (16 × 255) + 256 = 4,336 ops\n * - ~2x faster than standard 8,191 ops\n *\n * Limitations:\n * - Not suitable for plain precomputes (requires 256 constant doublings)\n * - Performance degrades with larger scalar counts:\n * - Optimal for ~256 scalars\n * - Less efficient for 4096+ scalars (Pippenger preferred)\n */\n const fieldN = c.Fn;\n validateW(windowSize, fieldN.BITS);\n validateMSMPoints(points, c);\n const zero = c.ZERO;\n const tableSize = 2 ** windowSize - 1; // table size (without zero)\n const chunks = Math.ceil(fieldN.BITS / windowSize); // chunks of item\n const MASK = bitMask(windowSize);\n const tables = points.map((p: P) => {\n const res = [];\n for (let i = 0, acc = p; i < tableSize; i++) {\n res.push(acc);\n acc = acc.add(p);\n }\n return res;\n });\n return (scalars: bigint[]): P => {\n validateMSMScalars(scalars, fieldN);\n if (scalars.length > points.length)\n throw new Error('array of scalars must be smaller than array of points');\n let res = zero;\n for (let i = 0; i < chunks; i++) {\n // No need to double if accumulator is still zero.\n if (res !== zero) for (let j = 0; j < windowSize; j++) res = res.double();\n const shiftBy = BigInt(chunks * windowSize - (i + 1) * windowSize);\n for (let j = 0; j < scalars.length; j++) {\n const n = scalars[j];\n const curr = Number((n >> shiftBy) & MASK);\n if (!curr) continue; // skip zero scalars chunks\n res = res.add(tables[j][curr - 1]);\n }\n }\n return res;\n };\n}\n\n/** Minimal curve parameters needed to construct a Weierstrass or Edwards curve. */\nexport type ValidCurveParams<T> = {\n /** Base-field modulus. */\n p: bigint;\n /** Prime subgroup order. */\n n: bigint;\n /** Cofactor. */\n h: bigint;\n /** Curve parameter `a`. */\n a: T;\n /** Weierstrass curve parameter `b`. */\n b?: T;\n /** Edwards curve parameter `d`. */\n d?: T;\n /** Generator x coordinate. */\n Gx: T;\n /** Generator y coordinate. */\n Gy: T;\n};\n\nfunction createField<T>(order: bigint, field?: TArg<IField<T>>, isLE?: boolean): TRet<IField<T>> {\n if (field) {\n // Reuse supplied field overrides as-is; `isLE` only affects freshly constructed fallback\n // fields, and validateField() below only checks the arithmetic subset, not full byte/cmov\n // behavior.\n if (field.ORDER !== order) throw new Error('Field.ORDER must match order: Fp == p, Fn == n');\n validateField(field);\n return field as TRet<IField<T>>;\n } else {\n return Field(order, { isLE }) as unknown as TRet<IField<T>>;\n }\n}\n/** Pair of fields used by curve constructors. */\nexport type FpFn<T> = {\n /** Base field used for curve coordinates. */\n Fp: IField<T>;\n /** Scalar field used for secret scalars and subgroup arithmetic. */\n Fn: IField<bigint>;\n};\n\n/**\n * Validates basic CURVE shape and field membership, then creates fields.\n * This does not prove that the generator is on-curve, that subgroup/order data are consistent, or\n * that the curve equation itself is otherwise sane.\n * @param type - Curve family.\n * @param CURVE - Curve parameters.\n * @param curveOpts - Optional field overrides:\n * - `Fp` (optional): Optional base-field override.\n * - `Fn` (optional): Optional scalar-field override.\n * @param FpFnLE - Whether field encoding is little-endian.\n * @returns Frozen curve parameters and fields.\n * @throws If the curve parameters or field overrides are invalid. {@link Error}\n * @example\n * Build curve fields from raw constants before constructing a curve instance.\n *\n * ```ts\n * const curve = createCurveFields('weierstrass', {\n * p: 17n,\n * n: 19n,\n * h: 1n,\n * a: 2n,\n * b: 2n,\n * Gx: 5n,\n * Gy: 1n,\n * });\n * ```\n */\nexport function createCurveFields<T>(\n type: 'weierstrass' | 'edwards',\n CURVE: ValidCurveParams<T>,\n curveOpts: TArg<Partial<FpFn<T>>> = {},\n FpFnLE?: boolean\n): TRet<FpFn<T> & { CURVE: ValidCurveParams<T> }> {\n if (FpFnLE === undefined) FpFnLE = type === 'edwards';\n if (!CURVE || typeof CURVE !== 'object') throw new Error(`expected valid ${type} CURVE object`);\n for (const p of ['p', 'n', 'h'] as const) {\n const val = CURVE[p];\n if (!(typeof val === 'bigint' && val > _0n))\n throw new Error(`CURVE.${p} must be positive bigint`);\n }\n const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);\n const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);\n const _b: 'b' | 'd' = type === 'weierstrass' ? 'b' : 'd';\n const params = ['Gx', 'Gy', 'a', _b] as const;\n for (const p of params) {\n // @ts-ignore\n if (!Fp.isValid(CURVE[p]))\n throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);\n }\n CURVE = Object.freeze(Object.assign({}, CURVE));\n return { CURVE, Fp, Fn } as TRet<FpFn<T> & { CURVE: ValidCurveParams<T> }>;\n}\n\ntype KeygenFn = (\n seed?: Uint8Array,\n isCompressed?: boolean\n) => { secretKey: Uint8Array; publicKey: Uint8Array };\n/**\n * @param randomSecretKey - Secret-key generator.\n * @param getPublicKey - Public-key derivation helper.\n * @returns Keypair generator.\n * @example\n * Build a `keygen()` helper from existing secret-key and public-key primitives.\n *\n * ```ts\n * import { createKeygen } from '@noble/curves/abstract/curve.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const keygen = createKeygen(p256.utils.randomSecretKey, p256.getPublicKey);\n * const pair = keygen();\n * ```\n */\nexport function createKeygen(\n randomSecretKey: Function,\n getPublicKey: TArg<Signer['getPublicKey']>\n): TRet<KeygenFn> {\n return function keygen(seed?: TArg<Uint8Array>) {\n const secretKey = randomSecretKey(seed) as TRet<Uint8Array>;\n return { secretKey, publicKey: getPublicKey(secretKey) as TRet<Uint8Array> };\n };\n}\n","/**\n * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport {\n abytes,\n aexists,\n ahash,\n aoutput,\n clean,\n type CHash,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Internal class for HMAC.\n * Accepts any byte key, although RFC 2104 §3 recommends keys at least\n * `HashLen` bytes long.\n */\nexport class _HMAC<T extends Hash<T>> implements Hash<_HMAC<T>> {\n oHash: T;\n iHash: T;\n blockLen: number;\n outputLen: number;\n canXOF = false;\n private finished = false;\n private destroyed = false;\n\n constructor(hash: TArg<CHash>, key: TArg<Uint8Array>) {\n ahash(hash);\n abytes(key, undefined, 'key');\n this.iHash = hash.create() as T;\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of the first block) of the outer hash here,\n // we can re-use it between multiple calls via clone.\n this.oHash = hash.create() as T;\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n clean(pad);\n }\n update(buf: TArg<Uint8Array>): this {\n aexists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const buf = out.subarray(0, this.outputLen);\n // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before\n // overwriting that same prefix with the final tag, leaving any oversized tail untouched.\n this.iHash.digestInto(buf);\n this.oHash.update(buf);\n this.oHash.digestInto(buf);\n this.destroy();\n }\n digest(): TRet<Uint8Array> {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out as TRet<Uint8Array>;\n }\n _cloneInto(to?: _HMAC<T>): _HMAC<T> {\n // Create new instance without calling constructor since the key\n // is already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to as this;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n clone(): _HMAC<T> {\n return this._cloneInto();\n }\n destroy(): void {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - authentication key bytes\n * @param message - message bytes to authenticate\n * @returns Authentication tag bytes.\n * @example\n * Compute an RFC 2104 HMAC.\n * ```ts\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\ntype HmacFn = {\n (hash: TArg<CHash>, key: TArg<Uint8Array>, message: TArg<Uint8Array>): TRet<Uint8Array>;\n create(hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>>;\n};\nexport const hmac: TRet<HmacFn> = /* @__PURE__ */ (() => {\n const hmac_ = ((\n hash: TArg<CHash>,\n key: TArg<Uint8Array>,\n message: TArg<Uint8Array>\n ): TRet<Uint8Array> => new _HMAC<any>(hash, key).update(message).digest()) as TRet<HmacFn>;\n hmac_.create = (hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>> =>\n new _HMAC<any>(hash, key) as TRet<_HMAC<any>>;\n return hmac_;\n})();\n","/**\n * Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.\n *\n * ### Design rationale for types\n *\n * * Interaction between classes from different curves should fail:\n * `k256.Point.BASE.add(p256.Point.BASE)`\n * * For this purpose we want to use `instanceof` operator, which is fast and works during runtime\n * * Different calls of `curve()` would return different classes -\n * `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,\n * it won't affect others\n *\n * TypeScript can't infer types for classes created inside a function. Classes is one instance\n * of nominative types in TypeScript and interfaces only check for shape, so it's hard to create\n * unique type for every function call.\n *\n * We can use generic types via some param, like curve opts, but that would:\n * 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)\n * which is hard to debug.\n * 2. Params can be generic and we can't enforce them to be constant value:\n * if somebody creates curve from non-constant params,\n * it would be allowed to interact with other curves with non-constant params\n *\n * @todo https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { hmac as nobleHmac } from '@noble/hashes/hmac.js';\nimport { ahash } from '@noble/hashes/utils.js';\nimport {\n abignumber,\n abool,\n abytes,\n aInRange,\n asafenumber,\n bitLen,\n bitMask,\n bytesToHex,\n bytesToNumberBE,\n concatBytes,\n createHmacDrbg,\n hexToBytes,\n isBytes,\n numberToHexUnpadded,\n validateObject,\n randomBytes as wcRandomBytes,\n type CHash,\n type HmacFn,\n type Signer,\n type TArg,\n type TRet,\n} from '../utils.ts';\nimport {\n createCurveFields,\n createKeygen,\n mulEndoUnsafe,\n negateCt,\n normalizeZ,\n wNAF,\n type AffinePoint,\n type CurveLengths,\n type CurvePoint,\n type CurvePointCons,\n} from './curve.ts';\nimport {\n FpInvertBatch,\n FpIsSquare,\n getMinHashLength,\n mapHashToField,\n validateField,\n type IField,\n} from './modular.ts';\n\n/** Shared affine point shape used by Weierstrass helpers. */\nexport type { AffinePoint };\n\ntype EndoBasis = [[bigint, bigint], [bigint, bigint]];\n/**\n * When Weierstrass curve has `a=0`, it becomes Koblitz curve.\n * Koblitz curves allow using **efficiently-computable GLV endomorphism ψ**.\n * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.\n * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.\n *\n * Endomorphism consists of beta, lambda and splitScalar:\n *\n * 1. GLV endomorphism ψ transforms a point: `P = (x, y) ↦ ψ(P) = (β·x mod p, y)`\n * 2. GLV scalar decomposition transforms a scalar: `k ≡ k₁ + k₂·λ (mod n)`\n * 3. Then these are combined: `k·P = k₁·P + k₂·ψ(P)`\n * 4. Two 128-bit point-by-scalar multiplications + one point addition is faster than\n * one 256-bit multiplication.\n *\n * where\n * * beta: β ∈ Fₚ with β³ = 1, β ≠ 1\n * * lambda: λ ∈ Fₙ with λ³ = 1, λ ≠ 1\n * * splitScalar decomposes k ↦ k₁, k₂, by using reduced basis vectors.\n * Gauss lattice reduction calculates them from initial basis vectors `(n, 0), (-λ, 0)`\n *\n * Check out `test/misc/endomorphism.js` and\n * {@link https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066 | this endomorphism gist}.\n */\nexport type EndomorphismOpts = {\n /** Cube root of unity used by the GLV endomorphism. */\n beta: bigint;\n /** Reduced lattice basis used for scalar splitting. */\n basises?: EndoBasis;\n /**\n * Optional custom scalar-splitting helper.\n * Receives one scalar and returns two half-sized scalar components.\n */\n splitScalar?: (k: bigint) => { k1neg: boolean; k1: bigint; k2neg: boolean; k2: bigint };\n};\n// We construct the basis so `den` is always positive and equals `n`,\n// but the `num` sign depends on the basis, not on the secret value.\n// Exact half-way cases round away from zero, which keeps the split symmetric\n// around the reduced-basis boundaries used by endomorphism decomposition.\nconst divNearest = (num: bigint, den: bigint) => (num + (num >= 0 ? den : -den) / _2n) / den;\n\n/** Two half-sized scalar components returned by endomorphism splitting. */\nexport type ScalarEndoParts = {\n /** Whether the first split scalar should be negated. */\n k1neg: boolean;\n /** Absolute value of the first split scalar. */\n k1: bigint;\n /** Whether the second split scalar should be negated. */\n k2neg: boolean;\n /** Absolute value of the second split scalar. */\n k2: bigint;\n};\n\n/** Splits scalar for GLV endomorphism. */\nexport function _splitEndoScalar(k: bigint, basis: EndoBasis, n: bigint): ScalarEndoParts {\n // Split scalar into two such that part is ~half bits: `abs(part) < sqrt(N)`\n // Since part can be negative, we need to do this on point.\n // Callers must provide a reduced GLV basis whose vectors satisfy\n // `a + b * lambda ≡ 0 (mod n)`; this helper only sees the basis and `n`.\n // Reject unreduced scalars instead of silently treating them mod n.\n aInRange('scalar', k, _0n, n);\n // TODO: verifyScalar function which consumes lambda\n const [[a1, b1], [a2, b2]] = basis;\n const c1 = divNearest(b2 * k, n);\n const c2 = divNearest(-b1 * k, n);\n // |k1|/|k2| is < sqrt(N), but can be negative.\n // If we do `k1 mod N`, we'll get big scalar (`> sqrt(N)`): so, we do cheaper negation instead.\n let k1 = k - c1 * a1 - c2 * a2;\n let k2 = -c1 * b1 - c2 * b2;\n const k1neg = k1 < _0n;\n const k2neg = k2 < _0n;\n if (k1neg) k1 = -k1;\n if (k2neg) k2 = -k2;\n // Double check that resulting scalar less than half bits of N: otherwise wNAF will fail.\n // This should only happen on wrong bases.\n // Also, the math inside is complex enough that this guard is worth keeping.\n const MAX_NUM = bitMask(Math.ceil(bitLen(n) / 2)) + _1n; // Half bits of N\n if (k1 < _0n || k1 >= MAX_NUM || k2 < _0n || k2 >= MAX_NUM) {\n throw new Error('splitScalar (endomorphism): failed for k');\n }\n return { k1neg, k1, k2neg, k2 };\n}\n\n/**\n * Option to enable hedged signatures with improved security.\n *\n * * Randomly generated k is bad, because broken CSPRNG would leak private keys.\n * * Deterministic k (RFC6979) is better; but is suspectible to fault attacks.\n *\n * We allow using technique described in RFC6979 3.6: additional k', a.k.a. adding randomness\n * to deterministic sig. If CSPRNG is broken & randomness is weak, it would STILL be as secure\n * as ordinary sig without ExtraEntropy.\n *\n * * `true` means \"fetch data, from CSPRNG, incorporate it into k generation\"\n * * `false` means \"disable extra entropy, use purely deterministic k\"\n * * `Uint8Array` passed means \"incorporate following data into k generation\"\n *\n * See {@link https://paulmillr.com/posts/deterministic-signatures/ | deterministic signatures}.\n */\nexport type ECDSAExtraEntropy = boolean | Uint8Array;\n/**\n * - `compact` is the default format\n * - `recovered` is the same as compact, but with an extra byte indicating recovery byte\n * - `der` is ASN.1 DER encoding\n */\nexport type ECDSASignatureFormat = 'compact' | 'recovered' | 'der';\n/**\n * - `prehash`: (default: true) indicates whether to do sha256(message).\n * When a custom hash is used, it must be set to `false`.\n */\nexport type ECDSARecoverOpts = {\n /** Whether to hash the message before signature recovery. */\n prehash?: boolean;\n};\n/**\n * - `prehash`: (default: true) indicates whether to do sha256(message).\n * When a custom hash is used, it must be set to `false`.\n * - `lowS`: (default: true) prohibits signatures with `sig.s >= CURVE.n/2n`.\n * Compatible with BTC/ETH. Setting `lowS: false` allows to create malleable signatures,\n * which is default openssl behavior.\n * Non-malleable signatures can still be successfully verified in openssl.\n * - `format`: (default: 'compact') 'compact' or 'recovered' with recovery byte\n */\nexport type ECDSAVerifyOpts = {\n /** Whether to hash the message before verification. */\n prehash?: boolean;\n /** Whether to reject high-S signatures. */\n lowS?: boolean;\n /** Signature encoding to accept. */\n format?: ECDSASignatureFormat;\n};\n/**\n * - `prehash`: (default: true) indicates whether to do sha256(message).\n * When a custom hash is used, it must be set to `false`.\n * - `lowS`: (default: true) prohibits signatures with `sig.s >= CURVE.n/2n`.\n * Compatible with BTC/ETH. Setting `lowS: false` allows to create malleable signatures,\n * which is default openssl behavior.\n * Non-malleable signatures can still be successfully verified in openssl.\n * - `format`: (default: 'compact') 'compact' or 'recovered' with recovery byte\n * - `extraEntropy`: (default: false) creates signatures with increased\n * security, see {@link ECDSAExtraEntropy}\n */\nexport type ECDSASignOpts = {\n /** Whether to hash the message before signing. */\n prehash?: boolean;\n /** Whether to normalize signatures into the low-S half-order. */\n lowS?: boolean;\n /** Signature encoding to produce. */\n format?: ECDSASignatureFormat;\n /** Optional hedging input for deterministic k generation. */\n extraEntropy?: ECDSAExtraEntropy;\n};\n\nfunction validateSigFormat(format: string): ECDSASignatureFormat {\n if (!['compact', 'recovered', 'der'].includes(format))\n throw new Error('Signature format must be \"compact\", \"recovered\", or \"der\"');\n return format as ECDSASignatureFormat;\n}\n\nfunction validateSigOpts<T extends ECDSASignOpts, D extends Required<ECDSASignOpts>>(\n opts: T,\n def: D\n): D {\n validateObject(opts);\n const optsn = {} as D;\n // Normalize only the declared option subset from `def`; unknown keys are\n // intentionally ignored so shared / superset option bags stay valid here too.\n // `extraEntropy` stays an opaque payload until the signing path consumes it.\n for (let optName of Object.keys(def) as (keyof D)[]) {\n // @ts-ignore\n optsn[optName] = opts[optName] === undefined ? def[optName] : opts[optName];\n }\n abool(optsn.lowS!, 'lowS');\n abool(optsn.prehash!, 'prehash');\n if (optsn.format !== undefined) validateSigFormat(optsn.format);\n return optsn;\n}\n\n/** Projective XYZ point used by short Weierstrass curves. */\nexport interface WeierstrassPoint<T> extends CurvePoint<T, WeierstrassPoint<T>> {\n /** projective X coordinate. Different from affine x. */\n readonly X: T;\n /** projective Y coordinate. Different from affine y. */\n readonly Y: T;\n /** projective z coordinate */\n readonly Z: T;\n /** affine x coordinate. Different from projective X. */\n get x(): T;\n /** affine y coordinate. Different from projective Y. */\n get y(): T;\n /**\n * Encode the point into compressed or uncompressed SEC1 bytes.\n * @param isCompressed - Whether to use the compressed form.\n * @returns Encoded point bytes.\n */\n toBytes(isCompressed?: boolean): TRet<Uint8Array>;\n /**\n * Encode the point into compressed or uncompressed SEC1 hex.\n * @param isCompressed - Whether to use the compressed form.\n * @returns Encoded point hex.\n */\n toHex(isCompressed?: boolean): string;\n}\n\n/** Constructor and metadata helpers for Weierstrass points. */\nexport interface WeierstrassPointCons<T> extends CurvePointCons<WeierstrassPoint<T>> {\n /** Does NOT validate if the point is valid. Use `.assertValidity()`. */\n new (X: T, Y: T, Z: T): WeierstrassPoint<T>;\n /**\n * Return the curve parameters captured by this point constructor.\n * @returns Curve parameters.\n */\n CURVE(): WeierstrassOpts<T>;\n}\n\n/**\n * Weierstrass curve options.\n *\n * * p: prime characteristic (order) of finite field, in which arithmetics is done\n * * n: order of prime subgroup a.k.a total amount of valid curve points\n * * h: cofactor, usually 1. h*n is group order; n is subgroup order\n * * a: formula param, must be in field of p\n * * b: formula param, must be in field of p\n * * Gx: x coordinate of generator point a.k.a. base point\n * * Gy: y coordinate of generator point\n */\nexport type WeierstrassOpts<T> = Readonly<{\n /** Base-field modulus. */\n p: bigint;\n /** Prime subgroup order. */\n n: bigint;\n /** Curve cofactor. */\n h: bigint;\n /** Weierstrass curve parameter `a`. */\n a: T;\n /** Weierstrass curve parameter `b`. */\n b: T;\n /** Generator x coordinate. */\n Gx: T;\n /** Generator y coordinate. */\n Gy: T;\n}>;\n\n/**\n * Optional helpers and overrides for a Weierstrass point constructor.\n *\n * When a cofactor != 1, there can be effective methods to:\n * 1. Determine whether a point is torsion-free\n * 2. Clear torsion component\n */\nexport type WeierstrassExtraOpts<T> = Partial<{\n /** Optional base-field override. */\n Fp: IField<T>;\n /** Optional scalar-field override. */\n Fn: IField<bigint>;\n /** Whether the point constructor accepts infinity points. */\n allowInfinityPoint: boolean;\n /** Optional GLV endomorphism data. */\n endo: EndomorphismOpts;\n /** Optional torsion-check override. */\n isTorsionFree: (c: WeierstrassPointCons<T>, point: WeierstrassPoint<T>) => boolean;\n /** Optional cofactor-clearing override. */\n clearCofactor: (c: WeierstrassPointCons<T>, point: WeierstrassPoint<T>) => WeierstrassPoint<T>;\n /** Optional custom point decoder. */\n fromBytes: (bytes: TArg<Uint8Array>) => AffinePoint<T>;\n /** Optional custom point encoder. */\n toBytes: (\n c: WeierstrassPointCons<T>,\n point: WeierstrassPoint<T>,\n isCompressed: boolean\n ) => TRet<Uint8Array>;\n}>;\n\n/**\n * Options for ECDSA signatures over a Weierstrass curve.\n *\n * * lowS: (default: true) whether produced or verified signatures occupy the\n * low half of `ecdsaOpts.n`. Prevents malleability.\n * * hmac: (default: noble-hashes hmac) function, would be used to init hmac-drbg for k generation.\n * * randomBytes: (default: webcrypto os-level CSPRNG) custom method for fetching secure randomness.\n * * bits2int, bits2int_modN: used in sigs, sometimes overridden by curves. Custom hooks are\n * treated as pure functions over validated bytes and MUST NOT mutate caller-owned buffers or\n * closure-captured option bags. `bits2int_modN` must also return a canonical scalar in\n * `[0..Point.Fn.ORDER-1]`.\n */\nexport type ECDSAOpts = Partial<{\n /** Default low-S policy for this ECDSA instance. */\n lowS: boolean;\n /** HMAC implementation used by RFC6979 DRBG. */\n hmac: HmacFn;\n /** RNG override used by helper constructors. */\n randomBytes: (bytesLength?: number) => TRet<Uint8Array>;\n /** Hash-to-integer conversion override. */\n bits2int: (bytes: TArg<Uint8Array>) => bigint;\n /** Hash-to-integer-mod-n conversion override. Returns a canonical scalar in `[0..Fn.ORDER-1]`. */\n bits2int_modN: (bytes: TArg<Uint8Array>) => bigint;\n}>;\n\n/** Elliptic Curve Diffie-Hellman helper namespace. */\nexport interface ECDH {\n /**\n * Generate a secret/public key pair.\n * @param seed - Optional seed material.\n * @returns Secret/public key pair.\n */\n keygen: (seed?: TArg<Uint8Array>) => { secretKey: TRet<Uint8Array>; publicKey: TRet<Uint8Array> };\n /**\n * Derive the public key from a secret key.\n * @param secretKey - Secret key bytes.\n * @param isCompressed - Whether to emit compressed SEC1 bytes.\n * @returns Encoded public key.\n */\n getPublicKey: (secretKey: TArg<Uint8Array>, isCompressed?: boolean) => TRet<Uint8Array>;\n /**\n * Compute the shared secret point from a secret key and peer public key.\n * @param secretKeyA - Local secret key bytes.\n * @param publicKeyB - Peer public key bytes.\n * @param isCompressed - Whether to emit compressed SEC1 bytes.\n * @returns Encoded shared point.\n */\n getSharedSecret: (\n secretKeyA: TArg<Uint8Array>,\n publicKeyB: TArg<Uint8Array>,\n isCompressed?: boolean\n ) => TRet<Uint8Array>;\n /** Point constructor used by this ECDH instance. */\n Point: WeierstrassPointCons<bigint>;\n /** Validation and random-key helpers. */\n utils: {\n /** Check whether a secret key has the expected encoding. */\n isValidSecretKey: (secretKey: TArg<Uint8Array>) => boolean;\n /** Check whether a public key decodes to a valid point. */\n isValidPublicKey: (publicKey: TArg<Uint8Array>, isCompressed?: boolean) => boolean;\n /** Generate a valid random secret key. */\n randomSecretKey: (seed?: TArg<Uint8Array>) => TRet<Uint8Array>;\n };\n /** Byte lengths for keys and signatures exposed by this curve. */\n lengths: CurveLengths;\n}\n\n/**\n * ECDSA interface.\n * Only supported for prime fields, not Fp2 (extension fields).\n */\nexport interface ECDSA extends ECDH {\n /**\n * Sign a message with the given secret key.\n * @param message - Message bytes.\n * @param secretKey - Secret key bytes.\n * @param opts - Optional signing tweaks. See {@link ECDSASignOpts}.\n * @returns Encoded signature bytes.\n */\n sign: (\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts?: TArg<ECDSASignOpts>\n ) => TRet<Uint8Array>;\n /**\n * Verify a signature against a message and public key.\n * @param signature - Encoded signature bytes.\n * @param message - Message bytes.\n * @param publicKey - Encoded public key.\n * @param opts - Optional verification tweaks. See {@link ECDSAVerifyOpts}.\n * @returns Whether the signature is valid.\n */\n verify: (\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>,\n opts?: TArg<ECDSAVerifyOpts>\n ) => boolean;\n /**\n * Recover the public key encoded into a recoverable signature.\n * @param signature - Recoverable signature bytes.\n * @param message - Message bytes.\n * @param opts - Optional recovery tweaks. See {@link ECDSARecoverOpts}.\n * @returns Encoded recovered public key.\n */\n recoverPublicKey(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n opts?: TArg<ECDSARecoverOpts>\n ): TRet<Uint8Array>;\n /** Signature constructor and parser helpers. */\n Signature: ECDSASignatureCons;\n}\n/**\n * @param m - Error message.\n * @example\n * Throw a DER-specific error when signature parsing encounters invalid bytes.\n *\n * ```ts\n * new DERErr('bad der');\n * ```\n */\nexport class DERErr extends Error {\n constructor(m = '') {\n super(m);\n }\n}\n/** DER helper namespace used by ECDSA signature parsing and encoding. */\nexport type IDER = {\n // asn.1 DER encoding utils\n /**\n * DER-specific error constructor.\n * @param m - Error message.\n * @returns DER-specific error instance.\n */\n Err: typeof DERErr;\n // Basic building block is TLV (Tag-Length-Value)\n /** Low-level tag-length-value helpers used by DER encoders. */\n _tlv: {\n /**\n * Encode one TLV record.\n * @param tag - ASN.1 tag byte.\n * @param data - Hex-encoded value payload.\n * @returns Encoded TLV string.\n */\n encode: (tag: number, data: string) => string;\n // v - value, l - left bytes (unparsed)\n /**\n * Decode one TLV record and return the value plus leftover bytes.\n * @param tag - Expected ASN.1 tag byte.\n * @param data - Remaining DER bytes.\n * @returns Parsed value plus leftover bytes.\n */\n decode(tag: number, data: TArg<Uint8Array>): TRet<{ v: Uint8Array; l: Uint8Array }>;\n };\n // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,\n // since we always use positive integers here. It must always be empty:\n // - add zero byte if exists\n // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)\n /** Positive-integer DER helpers used by ECDSA signature encoding. */\n _int: {\n /**\n * Encode one positive bigint as a DER INTEGER.\n * @param num - Positive integer to encode.\n * @returns Encoded DER INTEGER.\n */\n encode(num: bigint): string;\n /**\n * Decode one DER INTEGER into a bigint.\n * @param data - DER INTEGER bytes.\n * @returns Decoded bigint.\n */\n decode(data: TArg<Uint8Array>): bigint;\n };\n /**\n * Parse a DER signature into `{ r, s }`.\n * @param bytes - DER signature bytes.\n * @returns Parsed signature components.\n */\n toSig(bytes: TArg<Uint8Array>): { r: bigint; s: bigint };\n /**\n * Encode `{ r, s }` as a DER signature.\n * @param sig - Signature components.\n * @returns DER-encoded signature hex.\n */\n hexFromSig(sig: { r: bigint; s: bigint }): string;\n};\n/**\n * ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:\n *\n * [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]\n *\n * Docs: {@link https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/ | Let's Encrypt ASN.1 guide} and\n * {@link https://luca.ntop.org/Teaching/Appunti/asn1.html | Luca Deri's ASN.1 notes}.\n * @example\n * ASN.1 DER encoding utilities.\n *\n * ```ts\n * const der = DER.hexFromSig({ r: 1n, s: 2n });\n * ```\n */\nexport const DER: IDER = {\n // asn.1 DER encoding utils\n Err: DERErr,\n // Basic building block is TLV (Tag-Length-Value)\n _tlv: {\n encode: (tag: number, data: string): string => {\n const { Err: E } = DER;\n asafenumber(tag, 'tag');\n if (tag < 0 || tag > 255) throw new E('tlv.encode: wrong tag');\n if (typeof data !== 'string')\n throw new TypeError('\"data\" expected string, got type=' + typeof data);\n // Internal helper: callers hand this already-validated hex payload, so we only enforce\n // byte alignment here instead of re-validating every nibble.\n if (data.length & 1) throw new E('tlv.encode: unpadded data');\n const dataLen = data.length / 2;\n const len = numberToHexUnpadded(dataLen);\n if ((len.length / 2) & 0b1000_0000) throw new E('tlv.encode: long form length too big');\n // length of length with long form flag\n const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 0b1000_0000) : '';\n const t = numberToHexUnpadded(tag);\n return t + lenLen + len + data;\n },\n // v - value, l - left bytes (unparsed)\n decode(tag: number, data: TArg<Uint8Array>): TRet<{ v: Uint8Array; l: Uint8Array }> {\n const { Err: E } = DER;\n data = abytes(data, undefined, 'DER data');\n let pos = 0;\n if (tag < 0 || tag > 255) throw new E('tlv.encode: wrong tag');\n if (data.length < 2 || data[pos++] !== tag) throw new E('tlv.decode: wrong tlv');\n const first = data[pos++];\n // First bit of first length byte is the short/long form flag.\n const isLong = !!(first & 0b1000_0000);\n let length = 0;\n if (!isLong) length = first;\n else {\n // Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]\n const lenLen = first & 0b0111_1111;\n if (!lenLen) throw new E('tlv.decode(long): indefinite length not supported');\n // This would overflow u32 in JS.\n if (lenLen > 4) throw new E('tlv.decode(long): byte length is too big');\n const lengthBytes = data.subarray(pos, pos + lenLen);\n if (lengthBytes.length !== lenLen) throw new E('tlv.decode: length bytes not complete');\n if (lengthBytes[0] === 0) throw new E('tlv.decode(long): zero leftmost byte');\n for (const b of lengthBytes) length = (length << 8) | b;\n pos += lenLen;\n if (length < 128) throw new E('tlv.decode(long): not minimal encoding');\n }\n const v = data.subarray(pos, pos + length);\n if (v.length !== length) throw new E('tlv.decode: wrong value length');\n return { v, l: data.subarray(pos + length) } as TRet<{ v: Uint8Array; l: Uint8Array }>;\n },\n },\n // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,\n // since we always use positive integers here. It must always be empty:\n // - add zero byte if exists\n // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)\n _int: {\n encode(num: bigint): string {\n const { Err: E } = DER;\n abignumber(num);\n if (num < _0n) throw new E('integer: negative integers are not allowed');\n let hex = numberToHexUnpadded(num);\n // Pad with zero byte if negative flag is present\n if (Number.parseInt(hex[0], 16) & 0b1000) hex = '00' + hex;\n if (hex.length & 1) throw new E('unexpected DER parsing assertion: unpadded hex');\n return hex;\n },\n decode(data: TArg<Uint8Array>): bigint {\n const { Err: E } = DER;\n if (data.length < 1) throw new E('invalid signature integer: empty');\n if (data[0] & 0b1000_0000) throw new E('invalid signature integer: negative');\n // Single-byte zero `00` is the canonical DER INTEGER encoding for zero.\n if (data.length > 1 && data[0] === 0x00 && !(data[1] & 0b1000_0000))\n throw new E('invalid signature integer: unnecessary leading zero');\n return bytesToNumberBE(data);\n },\n },\n toSig(bytes: TArg<Uint8Array>): { r: bigint; s: bigint } {\n // parse DER signature\n const { Err: E, _int: int, _tlv: tlv } = DER;\n const data = abytes(bytes, undefined, 'signature');\n const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);\n if (seqLeftBytes.length) throw new E('invalid signature: left bytes after parsing');\n const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);\n const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);\n if (sLeftBytes.length) throw new E('invalid signature: left bytes after parsing');\n return { r: int.decode(rBytes), s: int.decode(sBytes) };\n },\n hexFromSig(sig: { r: bigint; s: bigint }): string {\n const { _tlv: tlv, _int: int } = DER;\n const rs = tlv.encode(0x02, int.encode(sig.r));\n const ss = tlv.encode(0x02, int.encode(sig.s));\n const seq = rs + ss;\n return tlv.encode(0x30, seq);\n },\n};\nObject.freeze(DER._tlv);\nObject.freeze(DER._int);\nObject.freeze(DER);\n\n// Be friendly to bad ECMAScript parsers by not using bigint literals\n// prettier-ignore\nconst _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2), _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4);\n\n/**\n * Creates weierstrass Point constructor, based on specified curve options.\n *\n * See {@link WeierstrassOpts}.\n * @param params - Curve parameters. See {@link WeierstrassOpts}.\n * @param extraOpts - Optional helpers and overrides. See {@link WeierstrassExtraOpts}.\n * @returns Weierstrass point constructor.\n * @throws If the curve parameters, overrides, or point codecs are invalid. {@link Error}\n *\n * @example\n * Construct a point type from explicit Weierstrass curve parameters.\n *\n * ```js\n * const opts = {\n * p: 0xfffffffffffffffffffffffffffffffeffffac73n,\n * n: 0x100000000000000000001b8fa16dfab9aca16b6b3n,\n * h: 1n,\n * a: 0n,\n * b: 7n,\n * Gx: 0x3b4c382ce37aa192a4019e763036f4f5dd4d7ebbn,\n * Gy: 0x938cf935318fdced6bc28286531733c3f03c4feen,\n * };\n * const secp160k1_Point = weierstrass(opts);\n * ```\n */\nexport function weierstrass<T>(\n params: WeierstrassOpts<T>,\n extraOpts: WeierstrassExtraOpts<T> = {}\n): WeierstrassPointCons<T> {\n const validated = createCurveFields('weierstrass', params, extraOpts);\n const Fp = validated.Fp as IField<T>;\n const Fn = validated.Fn as IField<bigint>;\n let CURVE = validated.CURVE as WeierstrassOpts<T>;\n const { h: cofactor, n: CURVE_ORDER } = CURVE;\n validateObject(\n extraOpts,\n {},\n {\n allowInfinityPoint: 'boolean',\n clearCofactor: 'function',\n isTorsionFree: 'function',\n fromBytes: 'function',\n toBytes: 'function',\n endo: 'object',\n }\n );\n\n // Snapshot constructor-time flags whose later mutation would otherwise change\n // validity semantics of an already-built point type.\n const { endo, allowInfinityPoint } = extraOpts;\n if (endo) {\n // validateObject(endo, { beta: 'bigint', splitScalar: 'function' });\n if (!Fp.is0(CURVE.a) || typeof endo.beta !== 'bigint' || !Array.isArray(endo.basises)) {\n throw new Error('invalid endo: expected \"beta\": bigint and \"basises\": array');\n }\n }\n\n const lengths = getWLengths(Fp as TArg<IField<T>>, Fn);\n\n function assertCompressionIsSupported() {\n if (!Fp.isOdd) throw new Error('compression is not supported: Field does not have .isOdd()');\n }\n\n // Implements IEEE P1363 point encoding\n function pointToBytes(\n _c: WeierstrassPointCons<T>,\n point: WeierstrassPoint<T>,\n isCompressed: boolean\n ): TRet<Uint8Array> {\n // SEC 1 v2.0 §2.3.3 encodes infinity as the single octet 0x00. Only curves\n // that opt into infinity as a public point value should expose that byte form.\n if (allowInfinityPoint && point.is0()) return Uint8Array.of(0) as TRet<Uint8Array>;\n const { x, y } = point.toAffine();\n const bx = Fp.toBytes(x);\n abool(isCompressed, 'isCompressed');\n if (isCompressed) {\n assertCompressionIsSupported();\n const hasEvenY = !Fp.isOdd!(y);\n return concatBytes(pprefix(hasEvenY), bx) as TRet<Uint8Array>;\n } else {\n return concatBytes(Uint8Array.of(0x04), bx, Fp.toBytes(y)) as TRet<Uint8Array>;\n }\n }\n function pointFromBytes(bytes: TArg<Uint8Array>) {\n abytes(bytes, undefined, 'Point');\n const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths; // e.g. for 32-byte: 33, 65\n const length = bytes.length;\n const head = bytes[0];\n const tail = bytes.subarray(1);\n if (allowInfinityPoint && length === 1 && head === 0x00) return { x: Fp.ZERO, y: Fp.ZERO };\n // SEC 1 v2.0 §2.3.4 decodes 0x00 as infinity, but §3.2.2 public-key validation\n // rejects infinity. We therefore keep 0x00 rejected by default because callers\n // reuse this parser as the strict public-key boundary, and only admit it when\n // the curve explicitly opts into infinity as a public point value. secp256k1\n // crosstests show OpenSSL raw point codecs accept 0x00 too.\n // No actual validation is done here: use .assertValidity()\n if (length === comp && (head === 0x02 || head === 0x03)) {\n const x = Fp.fromBytes(tail);\n if (!Fp.isValid(x)) throw new Error('bad point: is not on curve, wrong x');\n const y2 = weierstrassEquation(x); // y² = x³ + ax + b\n let y: T;\n try {\n y = Fp.sqrt(y2); // y = y² ^ (p+1)/4\n } catch (sqrtError) {\n const err = sqrtError instanceof Error ? ': ' + sqrtError.message : '';\n throw new Error('bad point: is not on curve, sqrt error' + err);\n }\n assertCompressionIsSupported();\n const evenY = Fp.isOdd!(y);\n const evenH = (head & 1) === 1; // ECDSA-specific\n if (evenH !== evenY) y = Fp.neg(y);\n return { x, y };\n } else if (length === uncomp && head === 0x04) {\n // TODO: more checks\n const L = Fp.BYTES;\n const x = Fp.fromBytes(tail.subarray(0, L));\n const y = Fp.fromBytes(tail.subarray(L, L * 2));\n if (!isValidXY(x, y)) throw new Error('bad point: is not on curve');\n return { x, y };\n } else {\n throw new Error(\n `bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`\n );\n }\n }\n\n const encodePoint = extraOpts.toBytes === undefined ? pointToBytes : extraOpts.toBytes;\n const decodePoint = extraOpts.fromBytes === undefined ? pointFromBytes : extraOpts.fromBytes;\n function weierstrassEquation(x: T): T {\n const x2 = Fp.sqr(x); // x * x\n const x3 = Fp.mul(x2, x); // x² * x\n return Fp.add(Fp.add(x3, Fp.mul(x, CURVE.a)), CURVE.b); // x³ + a * x + b\n }\n\n // TODO: move top-level\n /** Checks whether equation holds for given x, y: y² == x³ + ax + b */\n function isValidXY(x: T, y: T): boolean {\n const left = Fp.sqr(y); // y²\n const right = weierstrassEquation(x); // x³ + ax + b\n return Fp.eql(left, right);\n }\n\n // Keep constructor-time generator validation cheap: callers are responsible for supplying the\n // correct prime-order base point, while eager subgroup checks here would slow heavy module imports.\n // Test 1: equation y² = x³ + ax + b should work for generator point.\n if (!isValidXY(CURVE.Gx, CURVE.Gy)) throw new Error('bad curve params: generator point');\n\n // Test 2: discriminant Δ part should be non-zero: 4a³ + 27b² != 0.\n // Guarantees curve is genus-1, smooth (non-singular).\n const _4a3 = Fp.mul(Fp.pow(CURVE.a, _3n), _4n);\n const _27b2 = Fp.mul(Fp.sqr(CURVE.b), BigInt(27));\n if (Fp.is0(Fp.add(_4a3, _27b2))) throw new Error('bad curve params: a or b');\n\n /** Asserts coordinate is valid: 0 <= n < Fp.ORDER. */\n function acoord(title: string, n: T, banZero = false) {\n if (!Fp.isValid(n) || (banZero && Fp.is0(n))) throw new Error(`bad point coordinate ${title}`);\n return n;\n }\n\n function aprjpoint(other: unknown): asserts other is Point {\n if (!(other instanceof Point)) throw new Error('Weierstrass Point expected');\n }\n\n function splitEndoScalarN(k: bigint) {\n if (!endo || !endo.basises) throw new Error('no endo');\n return _splitEndoScalar(k, endo.basises, Fn.ORDER);\n }\n\n function finishEndo(\n endoBeta: EndomorphismOpts['beta'],\n k1p: Point,\n k2p: Point,\n k1neg: boolean,\n k2neg: boolean\n ) {\n k2p = new Point(Fp.mul(k2p.X, endoBeta), k2p.Y, k2p.Z);\n k1p = negateCt(k1neg, k1p);\n k2p = negateCt(k2neg, k2p);\n return k1p.add(k2p);\n }\n\n /**\n * Projective Point works in 3d / projective (homogeneous) coordinates:(X, Y, Z) ∋ (x=X/Z, y=Y/Z).\n * Default Point works in 2d / affine coordinates: (x, y).\n * We're doing calculations in projective, because its operations don't require costly inversion.\n */\n class Point implements WeierstrassPoint<T> {\n // base / generator point\n static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);\n // zero / infinity / identity point\n static readonly ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); // 0, 1, 0\n // math field\n static readonly Fp = Fp;\n // scalar field\n static readonly Fn = Fn;\n\n readonly X: T;\n readonly Y: T;\n readonly Z: T;\n\n /** Does NOT validate if the point is valid. Use `.assertValidity()`. */\n constructor(X: T, Y: T, Z: T) {\n this.X = acoord('x', X);\n // This is not just about ZERO / infinity: ambient curves can have real\n // finite points with y=0. Those points are 2-torsion, so they cannot lie\n // in the odd prime-order subgroups this point type is meant to represent.\n this.Y = acoord('y', Y, true);\n this.Z = acoord('z', Z);\n Object.freeze(this);\n }\n\n static CURVE(): WeierstrassOpts<T> {\n return CURVE;\n }\n\n /** Does NOT validate if the point is valid. Use `.assertValidity()`. */\n static fromAffine(p: AffinePoint<T>): Point {\n const { x, y } = p || {};\n if (!p || !Fp.isValid(x) || !Fp.isValid(y)) throw new Error('invalid affine point');\n if (p instanceof Point) throw new Error('projective point not allowed');\n // (0, 0) would've produced (0, 0, 1) - instead, we need (0, 1, 0)\n if (Fp.is0(x) && Fp.is0(y)) return Point.ZERO;\n return new Point(x, y, Fp.ONE);\n }\n\n static fromBytes(bytes: TArg<Uint8Array>): Point {\n const P = Point.fromAffine(decodePoint(abytes(bytes, undefined, 'point')));\n P.assertValidity();\n return P;\n }\n\n static fromHex(hex: string): Point {\n return Point.fromBytes(hexToBytes(hex));\n }\n\n get x(): T {\n return this.toAffine().x;\n }\n get y(): T {\n return this.toAffine().y;\n }\n\n /**\n *\n * @param windowSize\n * @param isLazy - true will defer table computation until the first multiplication\n * @returns\n */\n precompute(windowSize: number = 8, isLazy = true): Point {\n wnaf.createCache(this, windowSize);\n if (!isLazy) this.multiply(_3n); // random number\n return this;\n }\n\n // TODO: return `this`\n /** A point on curve is valid if it conforms to equation. */\n assertValidity(): void {\n const p = this;\n if (p.is0()) {\n // (0, 1, 0) aka ZERO is invalid in most contexts.\n // In BLS, ZERO can be serialized, so we allow it.\n // Keep the accepted infinity encoding canonical: projective-equivalent (X, Y, 0) points\n // like (1, 1, 0) compare equal to ZERO, but only (0, 1, 0) should pass this guard.\n if (extraOpts.allowInfinityPoint && Fp.is0(p.X) && Fp.eql(p.Y, Fp.ONE) && Fp.is0(p.Z))\n return;\n throw new Error('bad point: ZERO');\n }\n // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`\n const { x, y } = p.toAffine();\n if (!Fp.isValid(x) || !Fp.isValid(y)) throw new Error('bad point: x or y not field elements');\n if (!isValidXY(x, y)) throw new Error('bad point: equation left != right');\n if (!p.isTorsionFree()) throw new Error('bad point: not in prime-order subgroup');\n }\n\n hasEvenY(): boolean {\n const { y } = this.toAffine();\n if (!Fp.isOdd) throw new Error(\"Field doesn't support isOdd\");\n return !Fp.isOdd(y);\n }\n\n /** Compare one point to another. */\n equals(other: WeierstrassPoint<T>): boolean {\n aprjpoint(other);\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const { X: X2, Y: Y2, Z: Z2 } = other;\n const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));\n const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));\n return U1 && U2;\n }\n\n /** Flips point to one corresponding to (x, -y) in Affine coordinates. */\n negate(): Point {\n return new Point(this.X, Fp.neg(this.Y), this.Z);\n }\n\n // Renes-Costello-Batina exception-free doubling formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 3\n // Cost: 8M + 3S + 3*a + 2*b3 + 15add.\n double() {\n const { a, b } = CURVE;\n const b3 = Fp.mul(b, _3n);\n const { X: X1, Y: Y1, Z: Z1 } = this;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n let t0 = Fp.mul(X1, X1); // step 1\n let t1 = Fp.mul(Y1, Y1);\n let t2 = Fp.mul(Z1, Z1);\n let t3 = Fp.mul(X1, Y1);\n t3 = Fp.add(t3, t3); // step 5\n Z3 = Fp.mul(X1, Z1);\n Z3 = Fp.add(Z3, Z3);\n X3 = Fp.mul(a, Z3);\n Y3 = Fp.mul(b3, t2);\n Y3 = Fp.add(X3, Y3); // step 10\n X3 = Fp.sub(t1, Y3);\n Y3 = Fp.add(t1, Y3);\n Y3 = Fp.mul(X3, Y3);\n X3 = Fp.mul(t3, X3);\n Z3 = Fp.mul(b3, Z3); // step 15\n t2 = Fp.mul(a, t2);\n t3 = Fp.sub(t0, t2);\n t3 = Fp.mul(a, t3);\n t3 = Fp.add(t3, Z3);\n Z3 = Fp.add(t0, t0); // step 20\n t0 = Fp.add(Z3, t0);\n t0 = Fp.add(t0, t2);\n t0 = Fp.mul(t0, t3);\n Y3 = Fp.add(Y3, t0);\n t2 = Fp.mul(Y1, Z1); // step 25\n t2 = Fp.add(t2, t2);\n t0 = Fp.mul(t2, t3);\n X3 = Fp.sub(X3, t0);\n Z3 = Fp.mul(t2, t1);\n Z3 = Fp.add(Z3, Z3); // step 30\n Z3 = Fp.add(Z3, Z3);\n return new Point(X3, Y3, Z3);\n }\n\n // Renes-Costello-Batina exception-free addition formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 1\n // Cost: 12M + 0S + 3*a + 3*b3 + 23add.\n add(other: WeierstrassPoint<T>): Point {\n aprjpoint(other);\n const { X: X1, Y: Y1, Z: Z1 } = this;\n const { X: X2, Y: Y2, Z: Z2 } = other;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n const a = CURVE.a;\n const b3 = Fp.mul(CURVE.b, _3n);\n let t0 = Fp.mul(X1, X2); // step 1\n let t1 = Fp.mul(Y1, Y2);\n let t2 = Fp.mul(Z1, Z2);\n let t3 = Fp.add(X1, Y1);\n let t4 = Fp.add(X2, Y2); // step 5\n t3 = Fp.mul(t3, t4);\n t4 = Fp.add(t0, t1);\n t3 = Fp.sub(t3, t4);\n t4 = Fp.add(X1, Z1);\n let t5 = Fp.add(X2, Z2); // step 10\n t4 = Fp.mul(t4, t5);\n t5 = Fp.add(t0, t2);\n t4 = Fp.sub(t4, t5);\n t5 = Fp.add(Y1, Z1);\n X3 = Fp.add(Y2, Z2); // step 15\n t5 = Fp.mul(t5, X3);\n X3 = Fp.add(t1, t2);\n t5 = Fp.sub(t5, X3);\n Z3 = Fp.mul(a, t4);\n X3 = Fp.mul(b3, t2); // step 20\n Z3 = Fp.add(X3, Z3);\n X3 = Fp.sub(t1, Z3);\n Z3 = Fp.add(t1, Z3);\n Y3 = Fp.mul(X3, Z3);\n t1 = Fp.add(t0, t0); // step 25\n t1 = Fp.add(t1, t0);\n t2 = Fp.mul(a, t2);\n t4 = Fp.mul(b3, t4);\n t1 = Fp.add(t1, t2);\n t2 = Fp.sub(t0, t2); // step 30\n t2 = Fp.mul(a, t2);\n t4 = Fp.add(t4, t2);\n t0 = Fp.mul(t1, t4);\n Y3 = Fp.add(Y3, t0);\n t0 = Fp.mul(t5, t4); // step 35\n X3 = Fp.mul(t3, X3);\n X3 = Fp.sub(X3, t0);\n t0 = Fp.mul(t3, t1);\n Z3 = Fp.mul(t5, Z3);\n Z3 = Fp.add(Z3, t0); // step 40\n return new Point(X3, Y3, Z3);\n }\n\n subtract(other: WeierstrassPoint<T>) {\n // Validate before calling `negate()` so wrong inputs fail with the point guard\n // instead of leaking a foreign `negate()` error.\n aprjpoint(other);\n return this.add(other.negate());\n }\n\n is0(): boolean {\n return this.equals(Point.ZERO);\n }\n\n /**\n * Constant time multiplication.\n * Uses wNAF method. Windowed method may be 10% faster,\n * but takes 2x longer to generate and consumes 2x memory.\n * Uses precomputes when available.\n * Uses endomorphism for Koblitz curves.\n * @param scalar - by which the point would be multiplied\n * @returns New point\n */\n multiply(scalar: bigint): Point {\n const { endo } = extraOpts;\n // Keep the subgroup-scalar contract strict instead of reducing 0 / n to ZERO.\n // In key/signature-style callers, those values usually mean broken hash/scalar plumbing,\n // and failing closed is safer than silently producing the identity point.\n if (!Fn.isValidNot0(scalar)) throw new RangeError('invalid scalar: out of range'); // 0 is invalid\n let point: Point, fake: Point; // Fake point is used to const-time mult\n const mul = (n: bigint) => wnaf.cached(this, n, (p) => normalizeZ(Point, p));\n /** See docs for {@link EndomorphismOpts} */\n if (endo) {\n const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar);\n const { p: k1p, f: k1f } = mul(k1);\n const { p: k2p, f: k2f } = mul(k2);\n fake = k1f.add(k2f);\n point = finishEndo(endo.beta, k1p, k2p, k1neg, k2neg);\n } else {\n const { p, f } = mul(scalar);\n point = p;\n fake = f;\n }\n // Normalize `z` for both points, but return only real one\n return normalizeZ(Point, [point, fake])[0];\n }\n\n /**\n * Non-constant-time multiplication. Uses double-and-add algorithm.\n * It's faster, but should only be used when you don't care about\n * an exposed secret key e.g. sig verification, which works over *public* keys.\n */\n multiplyUnsafe(scalar: bigint): Point {\n const { endo } = extraOpts;\n const p = this as Point;\n const sc = scalar;\n // Public-scalar callers may need 0, but n and larger values stay rejected here too.\n // Reducing them mod n would turn bad caller input into an accidental identity point.\n if (!Fn.isValid(sc)) throw new RangeError('invalid scalar: out of range'); // 0 is valid\n if (sc === _0n || p.is0()) return Point.ZERO; // 0\n if (sc === _1n) return p; // 1\n if (wnaf.hasCache(this)) return this.multiply(sc); // precomputes\n // We don't have method for double scalar multiplication (aP + bQ):\n // Even with using Strauss-Shamir trick, it's 35% slower than naïve mul+add.\n if (endo) {\n const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(sc);\n const { p1, p2 } = mulEndoUnsafe(Point, p, k1, k2); // 30% faster vs wnaf.unsafe\n return finishEndo(endo.beta, p1, p2, k1neg, k2neg);\n } else {\n return wnaf.unsafe(p, sc);\n }\n }\n\n /**\n * Converts Projective point to affine (x, y) coordinates.\n * (X, Y, Z) ∋ (x=X/Z, y=Y/Z).\n * @param invertedZ - Z^-1 (inverted zero) - optional, precomputation is useful for invertBatch\n */\n toAffine(invertedZ?: T): AffinePoint<T> {\n const p = this;\n let iz = invertedZ;\n const { X, Y, Z } = p;\n // Fast-path for normalized points\n if (Fp.eql(Z, Fp.ONE)) return { x: X, y: Y };\n const is0 = p.is0();\n // If invZ was 0, we return zero point. However we still want to execute\n // all operations, so we replace invZ with a random number, 1.\n if (iz == null) iz = is0 ? Fp.ONE : Fp.inv(Z);\n const x = Fp.mul(X, iz);\n const y = Fp.mul(Y, iz);\n const zz = Fp.mul(Z, iz);\n if (is0) return { x: Fp.ZERO, y: Fp.ZERO };\n if (!Fp.eql(zz, Fp.ONE)) throw new Error('invZ was invalid');\n return { x, y };\n }\n\n /**\n * Checks whether Point is free of torsion elements (is in prime subgroup).\n * Always torsion-free for cofactor=1 curves.\n */\n isTorsionFree(): boolean {\n const { isTorsionFree } = extraOpts;\n if (cofactor === _1n) return true;\n if (isTorsionFree) return isTorsionFree(Point, this);\n return wnaf.unsafe(this, CURVE_ORDER).is0();\n }\n\n clearCofactor(): Point {\n const { clearCofactor } = extraOpts;\n if (cofactor === _1n) return this; // Fast-path\n if (clearCofactor) return clearCofactor(Point, this) as Point;\n // Default fallback assumes the cofactor fits the usual subgroup-scalar\n // multiplyUnsafe() contract. Curves with larger / structured cofactors\n // should define a clearCofactor override anyway (e.g. psi/Frobenius maps).\n return this.multiplyUnsafe(cofactor);\n }\n\n isSmallOrder(): boolean {\n if (cofactor === _1n) return this.is0(); // Fast-path\n return this.clearCofactor().is0();\n }\n\n toBytes(isCompressed = true): TRet<Uint8Array> {\n abool(isCompressed, 'isCompressed');\n // Same policy as pointFromBytes(): keep ZERO out of the default byte surface because\n // callers use these encodings as public keys, where SEC 1 validation rejects infinity.\n this.assertValidity();\n return encodePoint(Point, this, isCompressed);\n }\n\n toHex(isCompressed = true): string {\n return bytesToHex(this.toBytes(isCompressed));\n }\n\n toString() {\n return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;\n }\n }\n const bits = Fn.BITS;\n const wnaf = new wNAF(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits);\n // Tiny toy curves can have scalar fields narrower than 8 bits. Skip the\n // eager W=8 cache there instead of rejecting an otherwise valid constructor.\n if (bits >= 8) Point.BASE.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.\n Object.freeze(Point.prototype);\n Object.freeze(Point);\n return Point;\n}\n\n/** Parsed ECDSA signature with helpers for recovery and re-encoding. */\nexport interface ECDSASignature {\n /** Signature component `r`. */\n readonly r: bigint;\n /** Signature component `s`. */\n readonly s: bigint;\n /** Optional recovery bit for recoverable signatures. */\n readonly recovery?: number;\n /**\n * Return a copy of the signature with a recovery bit attached.\n * @param recovery - Recovery bit to attach.\n * @returns Signature with an attached recovery bit.\n */\n addRecoveryBit(recovery: number): ECDSASignature & { readonly recovery: number };\n /**\n * Check whether the signature uses the high-S half-order.\n * @returns Whether the signature uses the high-S half-order.\n */\n hasHighS(): boolean;\n /**\n * Recover the public key from the hashed message and recovery bit.\n * @param messageHash - Hashed message bytes.\n * @returns Recovered public-key point.\n */\n recoverPublicKey(messageHash: TArg<Uint8Array>): WeierstrassPoint<bigint>;\n /**\n * Encode the signature into bytes.\n * @param format - Signature encoding to produce.\n * @returns Encoded signature bytes.\n */\n toBytes(format?: string): TRet<Uint8Array>;\n /**\n * Encode the signature into hex.\n * @param format - Signature encoding to produce.\n * @returns Encoded signature hex.\n */\n toHex(format?: string): string;\n}\n/** Constructor and decoding helpers for ECDSA signatures. */\nexport type ECDSASignatureCons = {\n /** Create a signature from `r`, `s`, and an optional recovery bit. */\n new (r: bigint, s: bigint, recovery?: number): ECDSASignature;\n /**\n * Decode a signature from bytes.\n * @param bytes - Encoded signature bytes.\n * @param format - Signature encoding to parse.\n * @returns Parsed signature.\n */\n fromBytes(bytes: TArg<Uint8Array>, format?: ECDSASignatureFormat): ECDSASignature;\n /**\n * Decode a signature from hex.\n * @param hex - Encoded signature hex.\n * @param format - Signature encoding to parse.\n * @returns Parsed signature.\n */\n fromHex(hex: string, format?: ECDSASignatureFormat): ECDSASignature;\n};\n\n// Points start with byte 0x02 when y is even; otherwise 0x03\nfunction pprefix(hasEvenY: boolean): TRet<Uint8Array> {\n return Uint8Array.of(hasEvenY ? 0x02 : 0x03) as TRet<Uint8Array>;\n}\n\n/**\n * Implementation of the Shallue and van de Woestijne method for any weierstrass curve.\n * TODO: check if there is a way to merge this with uvRatio in Edwards; move to modular.\n * b = True and y = sqrt(u / v) if (u / v) is square in F, and\n * b = False and y = sqrt(Z * (u / v)) otherwise.\n * RFC 9380 expects callers to provide `v != 0`; this helper does not enforce it.\n * @param Fp - Field implementation.\n * @param Z - Simplified SWU map parameter.\n * @returns Square-root ratio helper.\n * @example\n * Build the square-root ratio helper used by SWU map implementations.\n *\n * ```ts\n * import { SWUFpSqrtRatio } from '@noble/curves/abstract/weierstrass.js';\n * import { Field } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const sqrtRatio = SWUFpSqrtRatio(Fp, 3n);\n * const out = sqrtRatio(4n, 1n);\n * ```\n */\nexport function SWUFpSqrtRatio<T>(\n Fp: TArg<IField<T>>,\n Z: T\n): (u: T, v: T) => { isValid: boolean; value: T } {\n // Fail with the usual field-shape error before touching pow/cmov on malformed field shims.\n const F = validateField(Fp as IField<T>) as IField<T>;\n // Generic implementation\n const q = F.ORDER;\n let l = _0n;\n for (let o = q - _1n; o % _2n === _0n; o /= _2n) l += _1n;\n const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.\n // We need 2n ** c1 and 2n ** (c1-1). We can't use **; but we can use <<.\n // 2n ** c1 == 2n << (c1-1)\n const _2n_pow_c1_1 = _2n << (c1 - _1n - _1n);\n const _2n_pow_c1 = _2n_pow_c1_1 * _2n;\n const c2 = (q - _1n) / _2n_pow_c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic\n const c3 = (c2 - _1n) / _2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic\n const c4 = _2n_pow_c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic\n const c5 = _2n_pow_c1_1; // 5. c5 = 2^(c1 - 1) # Integer arithmetic\n const c6 = F.pow(Z, c2); // 6. c6 = Z^c2\n const c7 = F.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2)\n // RFC 9380 Appendix F.2.1.1 defines sqrt_ratio(u, v) only for v != 0.\n // We keep v=0 on the regular result path with isValid=false instead of\n // throwing so the helper stays closer to the RFC's fixed control flow.\n let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => {\n let tv1 = c6; // 1. tv1 = c6\n let tv2 = F.pow(v, c4); // 2. tv2 = v^c4\n let tv3 = F.sqr(tv2); // 3. tv3 = tv2^2\n tv3 = F.mul(tv3, v); // 4. tv3 = tv3 * v\n let tv5 = F.mul(u, tv3); // 5. tv5 = u * tv3\n tv5 = F.pow(tv5, c3); // 6. tv5 = tv5^c3\n tv5 = F.mul(tv5, tv2); // 7. tv5 = tv5 * tv2\n tv2 = F.mul(tv5, v); // 8. tv2 = tv5 * v\n tv3 = F.mul(tv5, u); // 9. tv3 = tv5 * u\n let tv4 = F.mul(tv3, tv2); // 10. tv4 = tv3 * tv2\n tv5 = F.pow(tv4, c5); // 11. tv5 = tv4^c5\n let isQR = F.eql(tv5, F.ONE); // 12. isQR = tv5 == 1\n tv2 = F.mul(tv3, c7); // 13. tv2 = tv3 * c7\n tv5 = F.mul(tv4, tv1); // 14. tv5 = tv4 * tv1\n tv3 = F.cmov(tv2, tv3, isQR); // 15. tv3 = CMOV(tv2, tv3, isQR)\n tv4 = F.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)\n // 17. for i in (c1, c1 - 1, ..., 2):\n for (let i = c1; i > _1n; i--) {\n let tv5 = i - _2n; // 18. tv5 = i - 2\n tv5 = _2n << (tv5 - _1n); // 19. tv5 = 2^tv5\n let tvv5 = F.pow(tv4, tv5); // 20. tv5 = tv4^tv5\n const e1 = F.eql(tvv5, F.ONE); // 21. e1 = tv5 == 1\n tv2 = F.mul(tv3, tv1); // 22. tv2 = tv3 * tv1\n tv1 = F.mul(tv1, tv1); // 23. tv1 = tv1 * tv1\n tvv5 = F.mul(tv4, tv1); // 24. tv5 = tv4 * tv1\n tv3 = F.cmov(tv2, tv3, e1); // 25. tv3 = CMOV(tv2, tv3, e1)\n tv4 = F.cmov(tvv5, tv4, e1); // 26. tv4 = CMOV(tv5, tv4, e1)\n }\n // RFC 9380 Appendix F.2.1.1 defines sqrt_ratio(u, v) for v != 0.\n // When u = 0 and v != 0, u / v = 0 is square and the computed root is\n // still 0, so widen only the final flag and keep the full control flow.\n return { isValid: !F.is0(v) && (isQR || F.is0(u)), value: tv3 };\n };\n if (F.ORDER % _4n === _3n) {\n // sqrt_ratio_3mod4(u, v)\n const c1 = (F.ORDER - _3n) / _4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic\n const c2 = F.sqrt(F.neg(Z)); // 2. c2 = sqrt(-Z)\n sqrtRatio = (u: T, v: T) => {\n let tv1 = F.sqr(v); // 1. tv1 = v^2\n const tv2 = F.mul(u, v); // 2. tv2 = u * v\n tv1 = F.mul(tv1, tv2); // 3. tv1 = tv1 * tv2\n let y1 = F.pow(tv1, c1); // 4. y1 = tv1^c1\n y1 = F.mul(y1, tv2); // 5. y1 = y1 * tv2\n const y2 = F.mul(y1, c2); // 6. y2 = y1 * c2\n const tv3 = F.mul(F.sqr(y1), v); // 7. tv3 = y1^2; 8. tv3 = tv3 * v\n const isQR = F.eql(tv3, u); // 9. isQR = tv3 == u\n let y = F.cmov(y2, y1, isQR); // 10. y = CMOV(y2, y1, isQR)\n return { isValid: !F.is0(v) && isQR, value: y }; // 11. return (isQR, y) isQR ? y : y*c2\n };\n }\n // No curves uses that\n // if (Fp.ORDER % _8n === _5n) // sqrt_ratio_5mod8\n return sqrtRatio;\n}\n/**\n * Simplified Shallue-van de Woestijne-Ulas Method\n * See {@link https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2 | RFC 9380 section 6.6.2}.\n * @param Fp - Field implementation.\n * @param opts - SWU parameters:\n * - `A`: Curve parameter `A`.\n * - `B`: Curve parameter `B`.\n * - `Z`: Simplified SWU map parameter.\n * @returns Deterministic map-to-curve function.\n * @throws If the SWU parameters are invalid or the field lacks the required helpers. {@link Error}\n * @example\n * Map one field element to a Weierstrass curve point with the SWU recipe.\n *\n * ```ts\n * import { mapToCurveSimpleSWU } from '@noble/curves/abstract/weierstrass.js';\n * import { Field } from '@noble/curves/abstract/modular.js';\n * const Fp = Field(17n);\n * const map = mapToCurveSimpleSWU(Fp, { A: 1n, B: 2n, Z: 3n });\n * const point = map(5n);\n * ```\n */\nexport function mapToCurveSimpleSWU<T>(\n Fp: TArg<IField<T>>,\n opts: {\n A: T;\n B: T;\n Z: T;\n }\n): (u: T) => { x: T; y: T } {\n const F = validateField(Fp as IField<T>) as IField<T>;\n const { A, B, Z } = opts;\n if (!F.isValidNot0(A) || !F.isValidNot0(B) || !F.isValid(Z))\n throw new Error('mapToCurveSimpleSWU: invalid opts');\n // RFC 9380 §6.6.2 and Appendix H.2 require:\n // 1. Z is non-square in F\n // 2. Z != -1 in F\n // 3. g(x) - Z is irreducible over F\n // 4. g(B / (Z * A)) is square in F\n // We can enforce 1, 2, and 4 with the current field API.\n // Criterion 3 is not checked here because generic `IField<T>` does not expose\n // polynomial-ring / irreducibility operations, and this helper is used for\n // both prime and extension fields.\n if (F.eql(Z, F.neg(F.ONE)) || FpIsSquare(F, Z))\n throw new Error('mapToCurveSimpleSWU: invalid opts');\n // RFC 9380 Appendix H.2 criterion 4: g(B / (Z * A)) is square in F.\n // x = B / (Z * A)\n const x = F.mul(B, F.inv(F.mul(Z, A)));\n // g(x) = x^3 + A*x + B\n const gx = F.add(F.add(F.mul(F.sqr(x), x), F.mul(A, x)), B);\n if (!FpIsSquare(F, gx)) throw new Error('mapToCurveSimpleSWU: invalid opts');\n const sqrtRatio = SWUFpSqrtRatio(F, Z);\n if (!F.isOdd) throw new Error('Field does not have .isOdd()');\n // Input: u, an element of F.\n // Output: (x, y), a point on E.\n return (u: T): { x: T; y: T } => {\n // prettier-ignore\n let tv1, tv2, tv3, tv4, tv5, tv6, x, y;\n tv1 = F.sqr(u); // 1. tv1 = u^2\n tv1 = F.mul(tv1, Z); // 2. tv1 = Z * tv1\n tv2 = F.sqr(tv1); // 3. tv2 = tv1^2\n tv2 = F.add(tv2, tv1); // 4. tv2 = tv2 + tv1\n tv3 = F.add(tv2, F.ONE); // 5. tv3 = tv2 + 1\n tv3 = F.mul(tv3, B); // 6. tv3 = B * tv3\n tv4 = F.cmov(Z, F.neg(tv2), !F.eql(tv2, F.ZERO)); // 7. tv4 = CMOV(Z, -tv2, tv2 != 0)\n tv4 = F.mul(tv4, A); // 8. tv4 = A * tv4\n tv2 = F.sqr(tv3); // 9. tv2 = tv3^2\n tv6 = F.sqr(tv4); // 10. tv6 = tv4^2\n tv5 = F.mul(tv6, A); // 11. tv5 = A * tv6\n tv2 = F.add(tv2, tv5); // 12. tv2 = tv2 + tv5\n tv2 = F.mul(tv2, tv3); // 13. tv2 = tv2 * tv3\n tv6 = F.mul(tv6, tv4); // 14. tv6 = tv6 * tv4\n tv5 = F.mul(tv6, B); // 15. tv5 = B * tv6\n tv2 = F.add(tv2, tv5); // 16. tv2 = tv2 + tv5\n x = F.mul(tv1, tv3); // 17. x = tv1 * tv3\n const { isValid, value } = sqrtRatio(tv2, tv6); // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)\n y = F.mul(tv1, u); // 19. y = tv1 * u -> Z * u^3 * y1\n y = F.mul(y, value); // 20. y = y * y1\n x = F.cmov(x, tv3, isValid); // 21. x = CMOV(x, tv3, is_gx1_square)\n y = F.cmov(y, value, isValid); // 22. y = CMOV(y, y1, is_gx1_square)\n const e1 = F.isOdd!(u) === F.isOdd!(y); // 23. e1 = sgn0(u) == sgn0(y)\n y = F.cmov(F.neg(y), y, e1); // 24. y = CMOV(-y, y, e1)\n const tv4_inv = FpInvertBatch(F, [tv4], true)[0];\n x = F.mul(x, tv4_inv); // 25. x = x / tv4\n return { x, y };\n };\n}\n\nfunction getWLengths<T>(Fp: TArg<IField<T>>, Fn: TArg<IField<bigint>>) {\n return {\n secretKey: Fn.BYTES,\n publicKey: 1 + Fp.BYTES,\n publicKeyUncompressed: 1 + 2 * Fp.BYTES,\n publicKeyHasPrefix: true,\n // Raw compact `(r || s)` signature width; DER and recovered signatures use\n // different lengths outside this helper.\n signature: 2 * Fn.BYTES,\n };\n}\n\n/**\n * Sometimes users only need getPublicKey, getSharedSecret, and secret key handling.\n * This helper ensures no signature functionality is present. Less code, smaller bundle size.\n * @param Point - Weierstrass point constructor.\n * @param ecdhOpts - Optional randomness helpers:\n * - `randomBytes` (optional): Optional RNG override.\n * @returns ECDH helper namespace.\n * @example\n * Sometimes users only need getPublicKey, getSharedSecret, and secret key handling.\n *\n * ```ts\n * import { ecdh } from '@noble/curves/abstract/weierstrass.js';\n * import { p256 } from '@noble/curves/nist.js';\n * const dh = ecdh(p256.Point);\n * const alice = dh.keygen();\n * const shared = dh.getSharedSecret(alice.secretKey, alice.publicKey);\n * ```\n */\nexport function ecdh(\n Point: WeierstrassPointCons<bigint>,\n ecdhOpts: TArg<{ randomBytes?: (bytesLength?: number) => TRet<Uint8Array> }> = {}\n): ECDH {\n const { Fn } = Point;\n const randomBytes_ = ecdhOpts.randomBytes === undefined ? wcRandomBytes : ecdhOpts.randomBytes;\n // Keep the advertised seed length aligned with mapHashToField(), which keeps a hard 16-byte\n // minimum even on toy curves.\n const lengths = Object.assign(getWLengths(Point.Fp, Fn), {\n seed: Math.max(getMinHashLength(Fn.ORDER), 16),\n });\n\n function isValidSecretKey(secretKey: TArg<Uint8Array>) {\n try {\n const num = Fn.fromBytes(secretKey);\n return Fn.isValidNot0(num);\n } catch (error) {\n return false;\n }\n }\n\n function isValidPublicKey(publicKey: TArg<Uint8Array>, isCompressed?: boolean): boolean {\n const { publicKey: comp, publicKeyUncompressed } = lengths;\n try {\n const l = publicKey.length;\n if (isCompressed === true && l !== comp) return false;\n if (isCompressed === false && l !== publicKeyUncompressed) return false;\n return !!Point.fromBytes(publicKey);\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Produces cryptographically secure secret key from random of size\n * (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.\n */\n function randomSecretKey(seed?: TArg<Uint8Array>): TRet<Uint8Array> {\n seed = seed === undefined ? randomBytes_(lengths.seed) : seed;\n return mapHashToField(abytes(seed, lengths.seed, 'seed'), Fn.ORDER) as TRet<Uint8Array>;\n }\n\n /**\n * Computes public key for a secret key. Checks for validity of the secret key.\n * @param isCompressed - whether to return compact (default), or full key\n * @returns Public key, full when isCompressed=false; short when isCompressed=true\n */\n function getPublicKey(secretKey: TArg<Uint8Array>, isCompressed = true): TRet<Uint8Array> {\n return Point.BASE.multiply(Fn.fromBytes(secretKey)).toBytes(isCompressed);\n }\n\n /**\n * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.\n */\n function isProbPub(item: TArg<Uint8Array>): boolean | undefined {\n const { secretKey, publicKey, publicKeyUncompressed } = lengths;\n const allowedLengths = (Fn as { _lengths?: readonly number[] })._lengths;\n if (!isBytes(item)) return undefined;\n const l = abytes(item, undefined, 'key').length;\n const isPub = l === publicKey || l === publicKeyUncompressed;\n const isSec = l === secretKey || !!allowedLengths?.includes(l);\n // P-521 accepts both 65- and 66-byte secret keys, so overlapping lengths stay ambiguous.\n if (isPub && isSec) return undefined;\n return isPub;\n }\n\n /**\n * ECDH (Elliptic Curve Diffie Hellman).\n * Computes encoded shared point from secret key A and public key B.\n * Checks: 1) secret key validity 2) shared key is on-curve.\n * Does NOT hash the result or expose the SEC 1 x-coordinate-only `z`.\n * Returns the encoded shared point on purpose: callers that need `x_P`\n * can derive it from the encoded point, but `x_P` alone cannot recover the\n * point/parity back.\n * This helper only exposes the fully validated public-key path, not cofactor DH.\n * @param isCompressed - whether to return compact (default), or full key\n * @returns shared point encoding\n */\n function getSharedSecret(\n secretKeyA: TArg<Uint8Array>,\n publicKeyB: TArg<Uint8Array>,\n isCompressed = true\n ): TRet<Uint8Array> {\n if (isProbPub(secretKeyA) === true) throw new Error('first arg must be private key');\n if (isProbPub(publicKeyB) === false) throw new Error('second arg must be public key');\n const s = Fn.fromBytes(secretKeyA);\n const b = Point.fromBytes(publicKeyB); // checks for being on-curve\n return b.multiply(s).toBytes(isCompressed);\n }\n\n const utils = {\n isValidSecretKey,\n isValidPublicKey,\n randomSecretKey,\n };\n const keygen = createKeygen(randomSecretKey, getPublicKey);\n Object.freeze(utils);\n Object.freeze(lengths);\n\n return Object.freeze({ getPublicKey, getSharedSecret, keygen, Point, utils, lengths });\n}\n\n/**\n * Creates ECDSA signing interface for given elliptic curve `Point` and `hash` function.\n *\n * @param Point - created using {@link weierstrass} function\n * @param hash - used for 1) message prehash-ing 2) k generation in `sign`, using hmac_drbg(hash)\n * @param ecdsaOpts - rarely needed, see {@link ECDSAOpts}:\n * - `lowS`: Default low-S policy.\n * - `hmac`: HMAC implementation used by RFC6979 DRBG.\n * - `randomBytes`: Optional RNG override.\n * - `bits2int`: Optional hash-to-int conversion override.\n * - `bits2int_modN`: Optional hash-to-int-mod-n conversion override.\n *\n * @returns ECDSA helper namespace.\n * @example\n * Create an ECDSA signer/verifier bundle for one curve implementation.\n *\n * ```ts\n * import { ecdsa } from '@noble/curves/abstract/weierstrass.js';\n * import { p256 } from '@noble/curves/nist.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const p256ecdsa = ecdsa(p256.Point, sha256);\n * const { secretKey, publicKey } = p256ecdsa.keygen();\n * const msg = new TextEncoder().encode('hello noble');\n * const sig = p256ecdsa.sign(msg, secretKey);\n * const isValid = p256ecdsa.verify(sig, msg, publicKey);\n * ```\n */\nexport function ecdsa(\n Point: WeierstrassPointCons<bigint>,\n hash: TArg<CHash>,\n ecdsaOpts: TArg<ECDSAOpts> = {}\n): ECDSA {\n // Custom hash / bits2int hooks are treated as pure functions over validated caller-owned bytes.\n const hash_ = hash as CHash;\n ahash(hash_);\n validateObject(\n ecdsaOpts,\n {},\n {\n hmac: 'function',\n lowS: 'boolean',\n randomBytes: 'function',\n bits2int: 'function',\n bits2int_modN: 'function',\n }\n );\n ecdsaOpts = Object.assign({}, ecdsaOpts);\n const randomBytes = ecdsaOpts.randomBytes === undefined ? wcRandomBytes : ecdsaOpts.randomBytes;\n const hmac =\n ecdsaOpts.hmac === undefined\n ? (key: TArg<Uint8Array>, msg: TArg<Uint8Array>) => nobleHmac(hash_, key, msg)\n : (ecdsaOpts.hmac as HmacFn);\n\n const { Fp, Fn } = Point;\n const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;\n const { keygen, getPublicKey, getSharedSecret, utils, lengths } = ecdh(Point, ecdsaOpts);\n const defaultSigOpts: Required<ECDSASignOpts> = {\n prehash: true,\n lowS: typeof ecdsaOpts.lowS === 'boolean' ? ecdsaOpts.lowS : true,\n format: 'compact' as ECDSASignatureFormat,\n extraEntropy: false,\n };\n // SEC 1 4.1.6 public-key recovery tries x = r + jn for j = 0..h. Our recovered-signature\n // format only stores one overflow bit, so it can only distinguish q.x = r from q.x = r + n.\n // A third lift would have the form q.x = r + 2n. Since valid ECDSA r is in 1..n-1, the\n // smallest such lift is 1 + 2n, not 2n.\n const hasLargeRecoveryLifts = CURVE_ORDER * _2n + _1n < Fp.ORDER;\n\n function isBiggerThanHalfOrder(number: bigint) {\n const HALF = CURVE_ORDER >> _1n;\n return number > HALF;\n }\n function validateRS(title: string, num: bigint): bigint {\n if (!Fn.isValidNot0(num))\n throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);\n return num;\n }\n function assertRecoverableCurve(): void {\n // ECDSA recovery only supports curves where the current recovery id can distinguish\n // q.x = r and q.x = r + n; larger lifts may need additional `r + n*i` branches.\n // SEC 1 4.1.6 recovers candidates via x = r + jn, but this format only encodes j = 0 or 1.\n // The next possible candidate is q.x = r + 2n, and its smallest valid value is 1 + 2n.\n // To easily get i, we either need to:\n // a. increase amount of valid recid values (4, 5...); OR\n // b. prohibit recovered signatures for those curves.\n if (hasLargeRecoveryLifts)\n throw new Error('\"recovered\" sig type is not supported for cofactor >2 curves');\n }\n function validateSigLength(bytes: TArg<Uint8Array>, format: ECDSASignatureFormat) {\n validateSigFormat(format);\n const size = lengths.signature!;\n const sizer = format === 'compact' ? size : format === 'recovered' ? size + 1 : undefined;\n return abytes(bytes, sizer);\n }\n\n /**\n * ECDSA signature with its (r, s) properties. Supports compact, recovered & DER representations.\n */\n class Signature implements ECDSASignature {\n readonly r: bigint;\n readonly s: bigint;\n readonly recovery?: number;\n\n constructor(r: bigint, s: bigint, recovery?: number) {\n this.r = validateRS('r', r); // r in [1..N-1];\n this.s = validateRS('s', s); // s in [1..N-1];\n if (recovery != null) {\n assertRecoverableCurve();\n if (![0, 1, 2, 3].includes(recovery)) throw new Error('invalid recovery id');\n this.recovery = recovery;\n }\n Object.freeze(this);\n }\n\n static fromBytes(\n bytes: TArg<Uint8Array>,\n format: ECDSASignatureFormat = defaultSigOpts.format\n ): Signature {\n validateSigLength(bytes, format);\n let recid: number | undefined;\n if (format === 'der') {\n const { r, s } = DER.toSig(abytes(bytes));\n return new Signature(r, s);\n }\n if (format === 'recovered') {\n recid = bytes[0];\n format = 'compact';\n bytes = bytes.subarray(1);\n }\n const L = lengths.signature! / 2;\n const r = bytes.subarray(0, L);\n const s = bytes.subarray(L, L * 2);\n return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid);\n }\n\n static fromHex(hex: string, format?: ECDSASignatureFormat) {\n return this.fromBytes(hexToBytes(hex), format);\n }\n\n private assertRecovery(): number {\n const { recovery } = this;\n if (recovery == null) throw new Error('invalid recovery id: must be present');\n return recovery;\n }\n\n addRecoveryBit(recovery: number): RecoveredSignature {\n return new Signature(this.r, this.s, recovery) as RecoveredSignature;\n }\n\n // Unlike the top-level helper below, this method expects a digest that has\n // already been hashed to the curve's message representative.\n recoverPublicKey(messageHash: TArg<Uint8Array>): WeierstrassPoint<bigint> {\n const { r, s } = this;\n const recovery = this.assertRecovery();\n const radj = recovery === 2 || recovery === 3 ? r + CURVE_ORDER : r;\n if (!Fp.isValid(radj)) throw new Error('invalid recovery id: sig.r+curve.n != R.x');\n const x = Fp.toBytes(radj);\n const R = Point.fromBytes(concatBytes(pprefix((recovery & 1) === 0), x));\n const ir = Fn.inv(radj); // r^-1\n const h = bits2int_modN(abytes(messageHash, undefined, 'msgHash')); // Truncate hash\n const u1 = Fn.create(-h * ir); // -hr^-1\n const u2 = Fn.create(s * ir); // sr^-1\n // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1). unsafe is fine: there is no private data.\n const Q = Point.BASE.multiplyUnsafe(u1).add(R.multiplyUnsafe(u2));\n if (Q.is0()) throw new Error('invalid recovery: point at infinify');\n Q.assertValidity();\n return Q;\n }\n\n // Signatures should be low-s, to prevent malleability.\n hasHighS(): boolean {\n return isBiggerThanHalfOrder(this.s);\n }\n\n toBytes(format: ECDSASignatureFormat = defaultSigOpts.format): TRet<Uint8Array> {\n validateSigFormat(format);\n if (format === 'der') return hexToBytes(DER.hexFromSig(this)) as TRet<Uint8Array>;\n const { r, s } = this;\n const rb = Fn.toBytes(r);\n const sb = Fn.toBytes(s);\n if (format === 'recovered') {\n assertRecoverableCurve();\n return concatBytes(Uint8Array.of(this.assertRecovery()), rb, sb) as TRet<Uint8Array>;\n }\n return concatBytes(rb, sb) as TRet<Uint8Array>;\n }\n\n toHex(format?: ECDSASignatureFormat) {\n return bytesToHex(this.toBytes(format));\n }\n }\n type RecoveredSignature = Signature & { recovery: number };\n Object.freeze(Signature.prototype);\n Object.freeze(Signature);\n\n // RFC6979: ensure ECDSA msg is X bytes and < N. RFC suggests optional truncating via bits2octets.\n // FIPS 186-4 4.6 suggests the leftmost min(nBitLen, outLen) bits, which matches bits2int.\n // bits2int can produce res>N, we can do mod(res, N) since the bitLen is the same.\n // int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors\n const bits2int: (bytes: TArg<Uint8Array>) => bigint =\n ecdsaOpts.bits2int === undefined\n ? function bits2int_def(bytes: TArg<Uint8Array>): bigint {\n // Our custom check \"just in case\", for protection against DoS\n if (bytes.length > 8192) throw new Error('input is too large');\n // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)\n // for some cases, since bytes.length * 8 is not actual bitLength.\n const num = bytesToNumberBE(bytes); // check for == u8 done here\n const delta = bytes.length * 8 - fnBits; // truncate to nBitLength leftmost bits\n return delta > 0 ? num >> BigInt(delta) : num;\n }\n : (ecdsaOpts.bits2int as (bytes: TArg<Uint8Array>) => bigint);\n const bits2int_modN: (bytes: TArg<Uint8Array>) => bigint =\n ecdsaOpts.bits2int_modN === undefined\n ? function bits2int_modN_def(bytes: TArg<Uint8Array>): bigint {\n return Fn.create(bits2int(bytes)); // can't use bytesToNumberBE here\n }\n : (ecdsaOpts.bits2int_modN as (bytes: TArg<Uint8Array>) => bigint);\n const ORDER_MASK = bitMask(fnBits);\n // Pads output with zero as per spec.\n /** Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`. */\n function int2octets(num: bigint): TRet<Uint8Array> {\n aInRange('num < 2^' + fnBits, num, _0n, ORDER_MASK);\n return Fn.toBytes(num) as TRet<Uint8Array>;\n }\n\n function validateMsgAndHash(message: TArg<Uint8Array>, prehash: boolean): TRet<Uint8Array> {\n abytes(message, undefined, 'message');\n return (\n prehash ? abytes(hash_(message), undefined, 'prehashed message') : message\n ) as TRet<Uint8Array>;\n }\n\n /**\n * Steps A, D of RFC6979 3.2.\n * Creates RFC6979 seed; converts msg/privKey to numbers.\n * Used only in sign, not in verify.\n *\n * Warning: we cannot assume here that message has same amount of bytes as curve order,\n * this will be invalid at least for P521. Also it can be bigger for P224 + SHA256.\n */\n function prepSig(\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts: TArg<ECDSASignOpts>\n ) {\n const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts);\n message = validateMsgAndHash(message, prehash); // RFC6979 3.2 A: h1 = H(m)\n // We can't later call bits2octets, since nested bits2int is broken for curves\n // with fnBits % 8 !== 0. Because of that, we unwrap it here as int2octets call.\n // const bits2octets = (bits) => int2octets(bits2int_modN(bits))\n const h1int = bits2int_modN(message);\n const d = Fn.fromBytes(secretKey); // validate secret key, convert to bigint\n if (!Fn.isValidNot0(d)) throw new Error('invalid private key');\n const seedArgs: TArg<Uint8Array>[] = [int2octets(d), int2octets(h1int)];\n // extraEntropy. RFC6979 3.6: additional k' (optional).\n if (extraEntropy != null && extraEntropy !== false) {\n // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')\n // gen random bytes OR pass as-is\n const e = extraEntropy === true ? randomBytes(lengths.secretKey) : extraEntropy;\n seedArgs.push(abytes(e, undefined, 'extraEntropy')); // check for being bytes\n }\n const seed = concatBytes(...seedArgs) as TRet<Uint8Array>; // Step D of RFC6979 3.2\n const m = h1int; // no need to call bits2int second time here, it is inside truncateHash!\n // Converts signature params into point w r/s, checks result for validity.\n // To transform k => Signature:\n // q = k⋅G\n // r = q.x mod n\n // s = k^-1(m + rd) mod n\n // Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to\n // https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it:\n // a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT\n function k2sig(kBytes: TArg<Uint8Array>): Signature | undefined {\n // RFC 6979 Section 3.2, step 3: k = bits2int(T)\n // Important: all mod() calls here must be done over N\n const k = bits2int(kBytes); // Cannot use fields methods, since it is group element\n if (!Fn.isValidNot0(k)) return; // Valid scalars (including k) must be in 1..N-1\n const ik = Fn.inv(k); // k^-1 mod n\n const q = Point.BASE.multiply(k).toAffine(); // q = k⋅G\n const r = Fn.create(q.x); // r = q.x mod n\n if (r === _0n) return;\n const s = Fn.create(ik * Fn.create(m + r * d)); // s = k^-1(m + rd) mod n\n if (s === _0n) return;\n let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3 when q.x>n)\n let normS = s;\n if (lowS && isBiggerThanHalfOrder(s)) {\n normS = Fn.neg(s); // if lowS was passed, ensure s is always in the bottom half of N\n recovery ^= 1;\n }\n return new Signature(r, normS, hasLargeRecoveryLifts ? undefined : recovery);\n }\n return { seed, k2sig };\n }\n\n /**\n * Signs a message or message hash with a secret key.\n * With the default `prehash: true`, raw message bytes are hashed internally;\n * only `{ prehash: false }` expects a caller-supplied digest.\n *\n * ```\n * sign(m, d) where\n * k = rfc6979_hmac_drbg(m, d)\n * (x, y) = G × k\n * r = x mod n\n * s = (m + dr) / k mod n\n * ```\n */\n function sign(\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts: TArg<ECDSASignOpts> = {}\n ): TRet<Uint8Array> {\n const { seed, k2sig } = prepSig(message, secretKey, opts); // Steps A, D of RFC6979 3.2.\n const drbg = createHmacDrbg<Signature>(hash_.outputLen, Fn.BYTES, hmac);\n const sig = drbg(seed, k2sig); // Steps B, C, D, E, F, G\n return sig.toBytes(opts.format);\n }\n\n /**\n * Verifies a signature against message and public key.\n * Rejects lowS signatures by default: see {@link ECDSAVerifyOpts}.\n * Implements section 4.1.4 from https://www.secg.org/sec1-v2.pdf:\n *\n * ```\n * verify(r, s, h, P) where\n * u1 = hs^-1 mod n\n * u2 = rs^-1 mod n\n * R = u1⋅G + u2⋅P\n * mod(R.x, n) == r\n * ```\n */\n function verify(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>,\n opts: TArg<ECDSAVerifyOpts> = {}\n ): boolean {\n const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);\n publicKey = abytes(publicKey, undefined, 'publicKey');\n message = validateMsgAndHash(message, prehash);\n if (!isBytes(signature as any)) {\n const end = signature instanceof Signature ? ', use sig.toBytes()' : '';\n throw new Error('verify expects Uint8Array signature' + end);\n }\n validateSigLength(signature, format); // execute this twice because we want loud error\n try {\n const sig = Signature.fromBytes(signature, format);\n const P = Point.fromBytes(publicKey);\n if (lowS && sig.hasHighS()) return false;\n const { r, s } = sig;\n const h = bits2int_modN(message); // mod n, not mod p\n const is = Fn.inv(s); // s^-1 mod n\n const u1 = Fn.create(h * is); // u1 = hs^-1 mod n\n const u2 = Fn.create(r * is); // u2 = rs^-1 mod n\n const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2)); // u1⋅G + u2⋅P\n if (R.is0()) return false;\n const v = Fn.create(R.x); // v = r.x mod n\n return v === r;\n } catch (e) {\n return false;\n }\n }\n\n function recoverPublicKey(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n opts: TArg<ECDSARecoverOpts> = {}\n ): TRet<Uint8Array> {\n // Top-level recovery mirrors `sign()` / `verify()`: it hashes raw message\n // bytes first unless the caller passes `{ prehash: false }`.\n const { prehash } = validateSigOpts(opts, defaultSigOpts);\n message = validateMsgAndHash(message, prehash);\n return Signature.fromBytes(signature, 'recovered').recoverPublicKey(message).toBytes();\n }\n\n return Object.freeze({\n keygen,\n getPublicKey,\n getSharedSecret,\n utils,\n lengths,\n Point,\n sign,\n verify,\n recoverPublicKey,\n Signature,\n hash: hash_,\n }) satisfies Signer;\n}\n","/**\n * SECG secp256k1. See [pdf](https://www.secg.org/sec2-v2.pdf).\n *\n * Belongs to Koblitz curves: it has efficiently-computable GLV endomorphism ψ,\n * check out {@link EndomorphismOpts}. Seems to be rigid (not backdoored).\n * @module\n */\n/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { randomBytes } from '@noble/hashes/utils.js';\nimport { createKeygen, type CurveLengths } from './abstract/curve.ts';\nimport {\n createFROST,\n type FROST,\n type FrostPublic,\n type FrostSecret,\n type Nonces,\n} from './abstract/frost.ts';\nimport { createHasher, type H2CHasher, isogenyMap } from './abstract/hash-to-curve.ts';\nimport { Field, mapHashToField, pow2 } from './abstract/modular.ts';\nimport {\n type ECDSA,\n ecdsa,\n type EndomorphismOpts,\n mapToCurveSimpleSWU,\n type WeierstrassPoint as PointType,\n weierstrass,\n type WeierstrassOpts,\n type WeierstrassPointCons,\n} from './abstract/weierstrass.ts';\nimport {\n abytes,\n asciiToBytes,\n bytesToNumberBE,\n concatBytes,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n// Seems like generator was produced from some seed:\n// `Pointk1.BASE.multiply(Pointk1.Fn.inv(2n, N)).toAffine().x`\n// // gives short x 0x3b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63n\nconst secp256k1_CURVE: WeierstrassOpts<bigint> = {\n p: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),\n n: BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'),\n h: BigInt(1),\n a: BigInt(0),\n b: BigInt(7),\n Gx: BigInt('0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),\n Gy: BigInt('0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'),\n};\n\nconst secp256k1_ENDO: EndomorphismOpts = {\n beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),\n basises: [\n [BigInt('0x3086d221a7d46bcde86c90e49284eb15'), -BigInt('0xe4437ed6010e88286f547fa90abfe4c3')],\n [BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8'), BigInt('0x3086d221a7d46bcde86c90e49284eb15')],\n ],\n};\n\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _2n = /* @__PURE__ */ BigInt(2);\n\n/**\n * √n = n^((p+1)/4) for fields p = 3 mod 4. We unwrap the loop and multiply bit-by-bit.\n * (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]\n */\nfunction sqrtMod(y: bigint): bigint {\n const P = secp256k1_CURVE.p;\n // prettier-ignore\n const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);\n // prettier-ignore\n const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);\n const b2 = (y * y * y) % P; // x^3, 11\n const b3 = (b2 * b2 * y) % P; // x^7\n const b6 = (pow2(b3, _3n, P) * b3) % P;\n const b9 = (pow2(b6, _3n, P) * b3) % P;\n const b11 = (pow2(b9, _2n, P) * b2) % P;\n const b22 = (pow2(b11, _11n, P) * b11) % P;\n const b44 = (pow2(b22, _22n, P) * b22) % P;\n const b88 = (pow2(b44, _44n, P) * b44) % P;\n const b176 = (pow2(b88, _88n, P) * b88) % P;\n const b220 = (pow2(b176, _44n, P) * b44) % P;\n const b223 = (pow2(b220, _3n, P) * b3) % P;\n const t1 = (pow2(b223, _23n, P) * b22) % P;\n const t2 = (pow2(t1, _6n, P) * b2) % P;\n const root = pow2(t2, _2n, P);\n if (!Fpk1.eql(Fpk1.sqr(root), y)) throw new Error('Cannot find square root');\n return root;\n}\n\nconst Fpk1 = Field(secp256k1_CURVE.p, { sqrt: sqrtMod });\nconst Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, {\n Fp: Fpk1,\n endo: secp256k1_ENDO,\n});\n\n/**\n * secp256k1 curve: ECDSA and ECDH methods.\n *\n * Uses sha256 to hash messages. To use a different hash,\n * pass `{ prehash: false }` to sign / verify.\n *\n * @example\n * Generate one secp256k1 keypair, sign a message, and verify it.\n *\n * ```js\n * import { secp256k1 } from '@noble/curves/secp256k1.js';\n * const { secretKey, publicKey } = secp256k1.keygen();\n * // const publicKey = secp256k1.getPublicKey(secretKey);\n * const msg = new TextEncoder().encode('hello noble');\n * const sig = secp256k1.sign(msg, secretKey);\n * const isValid = secp256k1.verify(sig, msg, publicKey);\n * // const sigKeccak = secp256k1.sign(keccak256(msg), secretKey, { prehash: false });\n * ```\n */\nexport const secp256k1: ECDSA = /* @__PURE__ */ ecdsa(Pointk1, sha256);\n\n// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.\n// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki\n/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */\nconst TAGGED_HASH_PREFIXES: { [tag: string]: Uint8Array } = {};\n// BIP-340 phrases tags as UTF-8, but all current standardized names here are 7-bit ASCII.\nfunction taggedHash(tag: string, ...messages: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let tagP = TAGGED_HASH_PREFIXES[tag];\n if (tagP === undefined) {\n const tagH = sha256(asciiToBytes(tag));\n tagP = concatBytes(tagH, tagH);\n TAGGED_HASH_PREFIXES[tag] = tagP;\n }\n return sha256(concatBytes(tagP, ...messages)) as TRet<Uint8Array>;\n}\n\n// ECDSA compact points are 33-byte. Schnorr is 32: we strip first byte 0x02 or 0x03\nconst pointToBytes = (point: TArg<PointType<bigint>>): TRet<Uint8Array> =>\n point.toBytes(true).slice(1) as TRet<Uint8Array>;\nconst hasEven = (y: bigint) => y % _2n === _0n;\n\n// Calculate point, scalar and bytes\nfunction schnorrGetExtPubKey(priv: TArg<Uint8Array>) {\n const { Fn, BASE } = Pointk1;\n const d_ = Fn.fromBytes(priv);\n const p = BASE.multiply(d_); // P = d'⋅G; 0 < d' < n check is done inside\n const scalar = hasEven(p.y) ? d_ : Fn.neg(d_);\n return { scalar, bytes: pointToBytes(p) };\n}\n/**\n * lift_x from BIP340. Convert 32-byte x coordinate to elliptic curve point.\n * @returns valid point checked for being on-curve\n */\nfunction lift_x(x: bigint): PointType<bigint> {\n const Fp = Fpk1;\n if (!Fp.isValidNot0(x)) throw new Error('invalid x: Fail if x ≥ p');\n const xx = Fp.create(x * x);\n const c = Fp.create(xx * x + BigInt(7)); // Let c = x³ + 7 mod p.\n let y = Fp.sqrt(c); // Let y = c^(p+1)/4 mod p. Same as sqrt().\n // Return the unique point P such that x(P) = x and\n // y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.\n if (!hasEven(y)) y = Fp.neg(y);\n const p = Pointk1.fromAffine({ x, y });\n p.assertValidity();\n return p;\n}\n// BIP-340 callers still need to supply canonical 32-byte inputs where required; this alias only\n// parses big-endian bytes and does not enforce the fixed-width contract itself.\nconst num = bytesToNumberBE;\n/** Create tagged hash, convert it to bigint, reduce modulo-n. */\nfunction challenge(...args: TArg<Uint8Array[]>): bigint {\n return Pointk1.Fn.create(num(taggedHash('BIP0340/challenge', ...args)));\n}\n\n/** Schnorr public key is just `x` coordinate of Point as per BIP340. */\nfunction schnorrGetPublicKey(secretKey: TArg<Uint8Array>): TRet<Uint8Array> {\n return schnorrGetExtPubKey(secretKey).bytes; // d'=int(sk). Fail if d'=0 or d'≥n. Ret bytes(d'⋅G)\n}\n\n/**\n * Creates Schnorr signature as per BIP340. Verifies itself before returning anything.\n * `auxRand` is optional and is not the sole source of `k` generation: bad CSPRNG output will not\n * be catastrophic, but BIP-340 still recommends fresh auxiliary randomness when available to harden\n * deterministic signing against side-channel and fault-injection attacks.\n */\nfunction schnorrSign(\n message: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n auxRand: TArg<Uint8Array> = randomBytes(32)\n): TRet<Uint8Array> {\n const { Fn, BASE } = Pointk1;\n const m = abytes(message, undefined, 'message');\n const { bytes: px, scalar: d } = schnorrGetExtPubKey(secretKey); // checks for isWithinCurveOrder\n const a = abytes(auxRand, 32, 'auxRand'); // Auxiliary random data a: a 32-byte array\n // Let t be the byte-wise xor of bytes(d) and hash/aux(a).\n const t = Fn.toBytes(d ^ num(taggedHash('BIP0340/aux', a)));\n const rand = taggedHash('BIP0340/nonce', t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)\n // BIP340 defines k' = int(rand) mod n. We can't reuse schnorrGetExtPubKey(rand)\n // here: that helper parses canonical secret keys and rejects rand >= n instead\n // of reducing the nonce hash modulo the group order.\n const k_ = Fn.create(num(rand));\n // BIP-340: \"Let k' = int(rand) mod n. Fail if k' = 0. Let R = k'⋅G.\"\n if (k_ === 0n) throw new Error('sign failed: k is zero');\n const p = BASE.multiply(k_); // Rejects zero; only the raw nonce hash needs reduction.\n const k = hasEven(p.y) ? k_ : Fn.neg(k_);\n const rx = pointToBytes(p);\n const e = challenge(rx, px, m); // Let e = int(hash/challenge(bytes(R) || bytes(P) || m)) mod n.\n const sig = new Uint8Array(64); // Let sig = bytes(R) || bytes((k + ed) mod n).\n sig.set(rx, 0);\n sig.set(Fn.toBytes(Fn.create(k + e * d)), 32);\n // If Verify(bytes(P), m, sig) (see below) returns failure, abort\n if (!schnorrVerify(sig, m, px)) throw new Error('sign: Invalid signature produced');\n return sig as TRet<Uint8Array>;\n}\n\n/**\n * Verifies Schnorr signature.\n * Will swallow errors & return false except for initial type validation of arguments.\n */\nfunction schnorrVerify(\n signature: TArg<Uint8Array>,\n message: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>\n): boolean {\n const { Fp, Fn, BASE } = Pointk1;\n const sig = abytes(signature, 64, 'signature');\n const m = abytes(message, undefined, 'message');\n const pub = abytes(publicKey, 32, 'publicKey');\n try {\n const P = lift_x(num(pub)); // P = lift_x(int(pk)); fail if that fails\n const r = num(sig.subarray(0, 32)); // Let r = int(sig[0:32]); fail if r ≥ p.\n if (!Fp.isValidNot0(r)) return false;\n const s = num(sig.subarray(32, 64)); // Let s = int(sig[32:64]); fail if s ≥ n.\n // Stricter than BIP-340/libsecp256k1, which only reject s >= n. Honest signing reaches\n // s = 0 only with negligible probability (k + e*d ≡ 0 mod n), so treat zero-s inputs as\n // crafted edge cases and fail closed instead of carrying that extra verification surface.\n if (!Fn.isValidNot0(s)) return false;\n\n // int(challenge(bytes(r) || bytes(P) || m)) % n\n const e = challenge(Fn.toBytes(r), pointToBytes(P), m);\n // R = s⋅G - e⋅P, where -eP == (n-e)P\n const R = BASE.multiplyUnsafe(s).add(P.multiplyUnsafe(Fn.neg(e)));\n const { x, y } = R.toAffine();\n // Fail if is_infinite(R) / not has_even_y(R) / x(R) ≠ r.\n if (R.is0() || !hasEven(y) || x !== r) return false;\n return true;\n } catch (error) {\n return false;\n }\n}\n\nexport const __TEST: { lift_x: typeof lift_x } = /* @__PURE__ */ Object.freeze({ lift_x });\n\n/** Schnorr-specific secp256k1 API from BIP340. */\nexport type SecpSchnorr = {\n /**\n * Generate one Schnorr secret/public keypair.\n * @param seed - Optional seed for deterministic testing or custom randomness.\n * @returns Fresh secret/public keypair.\n */\n keygen: (seed?: TArg<Uint8Array>) => { secretKey: TRet<Uint8Array>; publicKey: TRet<Uint8Array> };\n /**\n * Derive the x-only public key from a secret key.\n * @param secretKey - Secret key bytes.\n * @returns X-only public key bytes.\n */\n getPublicKey: typeof schnorrGetPublicKey;\n /**\n * Create one BIP340 Schnorr signature.\n * @param message - Message bytes to sign.\n * @param secretKey - Secret key bytes.\n * @param auxRand - Optional auxiliary randomness.\n * @returns Compact Schnorr signature bytes.\n */\n sign: typeof schnorrSign;\n /**\n * Verify one BIP340 Schnorr signature.\n * @param signature - Compact signature bytes.\n * @param message - Signed message bytes.\n * @param publicKey - X-only public key bytes.\n * @returns `true` when the signature is valid.\n */\n verify: typeof schnorrVerify;\n /** Underlying secp256k1 point constructor. */\n Point: WeierstrassPointCons<bigint>;\n /** Helper utilities for Schnorr-specific key handling and tagged hashing. */\n utils: {\n /** Generate one Schnorr secret key. */\n randomSecretKey: (seed?: TArg<Uint8Array>) => TRet<Uint8Array>;\n /** Convert one point into its x-only BIP340 byte encoding. */\n pointToBytes: (point: TArg<PointType<bigint>>) => TRet<Uint8Array>;\n /** Lift one x coordinate into the unique even-Y point. */\n lift_x: typeof lift_x;\n /** Compute a BIP340 tagged hash. */\n taggedHash: typeof taggedHash;\n };\n /** Public byte lengths for keys, signatures, and seeds. */\n lengths: CurveLengths;\n};\n/**\n * Schnorr signatures over secp256k1.\n * See {@link https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki | BIP 340}.\n * @example\n * Generate one BIP340 Schnorr keypair, sign a message, and verify it.\n *\n * ```js\n * import { schnorr } from '@noble/curves/secp256k1.js';\n * const { secretKey, publicKey } = schnorr.keygen();\n * // const publicKey = schnorr.getPublicKey(secretKey);\n * const msg = new TextEncoder().encode('hello');\n * const sig = schnorr.sign(msg, secretKey);\n * const isValid = schnorr.verify(sig, msg, publicKey);\n * ```\n */\nexport const schnorr: SecpSchnorr = /* @__PURE__ */ (() => {\n const size = 32;\n const seedLength = 48;\n const randomSecretKey = (seed?: TArg<Uint8Array>): TRet<Uint8Array> => {\n seed = seed === undefined ? randomBytes(seedLength) : seed;\n return mapHashToField(seed, secp256k1_CURVE.n);\n };\n return Object.freeze({\n keygen: createKeygen(randomSecretKey, schnorrGetPublicKey),\n getPublicKey: schnorrGetPublicKey,\n sign: schnorrSign,\n verify: schnorrVerify,\n Point: Pointk1,\n utils: Object.freeze({\n randomSecretKey,\n taggedHash,\n lift_x,\n pointToBytes,\n }),\n lengths: Object.freeze({\n secretKey: size,\n publicKey: size,\n publicKeyHasPrefix: false,\n signature: size * 2,\n seed: seedLength,\n }),\n });\n})();\n\n// RFC 9380 Appendix E.1 3-isogeny coefficients for secp256k1, stored in ascending degree order.\n// The final `1` in each denominator array is the explicit monic leading term.\nconst isoMap = /* @__PURE__ */ (() =>\n isogenyMap(\n Fpk1,\n [\n // xNum\n [\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7',\n '0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581',\n '0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262',\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c',\n ],\n // xDen\n [\n '0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b',\n '0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n // yNum\n [\n '0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c',\n '0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3',\n '0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931',\n '0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84',\n ],\n // yDen\n [\n '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b',\n '0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573',\n '0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n ].map((i) => i.map((j) => BigInt(j))) as [bigint[], bigint[], bigint[], bigint[]]\n ))();\n// RFC 9380 §8.7 secp256k1 E' parameters for the SWU-to-isogeny pipeline below.\nlet mapSWU: ((u: bigint) => { x: bigint; y: bigint }) | undefined;\nconst getMapSWU = () =>\n mapSWU ||\n (mapSWU = mapToCurveSimpleSWU(Fpk1, {\n // Building the SWU sqrt-ratio helper eagerly adds noticeable `secp256k1.js` import cost, so\n // defer it to first use; after that the cached mapper is reused directly.\n A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),\n B: BigInt('1771'),\n Z: Fpk1.create(BigInt('-11')),\n }));\n\n/**\n * Hashing / encoding to secp256k1 points / field. RFC 9380 methods.\n * @example\n * Hash one message onto secp256k1.\n *\n * ```ts\n * const point = secp256k1_hasher.hashToCurve(new TextEncoder().encode('hello noble'));\n * ```\n */\nexport const secp256k1_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__ */ (() =>\n createHasher(\n Pointk1,\n (scalars: bigint[]) => {\n const { x, y } = getMapSWU()(Fpk1.create(scalars[0]));\n return isoMap(x, y);\n },\n {\n DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',\n encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_',\n p: Fpk1.ORDER,\n m: 1,\n k: 128,\n expand: 'xmd',\n hash: sha256,\n }\n ))();\n/**\n * FROST threshold signatures over secp256k1. RFC 9591.\n * @example\n * Create one trusted-dealer package for 2-of-3 secp256k1 signing.\n *\n * ```ts\n * const alice = secp256k1_FROST.Identifier.derive('alice@example.com');\n * const bob = secp256k1_FROST.Identifier.derive('bob@example.com');\n * const carol = secp256k1_FROST.Identifier.derive('carol@example.com');\n * const deal = secp256k1_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);\n * ```\n */\nexport const secp256k1_FROST: TRet<FROST> = /* @__PURE__ */ (() =>\n createFROST({\n name: 'FROST-secp256k1-SHA256-v1',\n Point: Pointk1,\n hashToScalar: secp256k1_hasher.hashToScalar,\n hash: sha256,\n }))();\n\n// Taproot utils\n// `undefined` means \"disable TapTweak entirely\"; callers that want the BIP-341/BIP-386 empty\n// merkle root must pass `new Uint8Array(0)` explicitly.\nfunction tweak(point: PointType<bigint>, merkleRoot?: TArg<Uint8Array>): bigint {\n if (merkleRoot === undefined) return _0n;\n const x = pointToBytes(point);\n const t = bytesToNumberBE(taggedHash('TapTweak', x, merkleRoot));\n // BIP-341 taproot_tweak_pubkey/taproot_tweak_seckey: \"if t >= SECP256K1_ORDER:\n // raise ValueError\". TapTweak must reject overflow instead of reducing modulo n.\n if (!Pointk1.Fn.isValid(t)) throw new Error('invalid TapTweak hash');\n return t;\n}\nfunction frostPubToEvenY(pub: TArg<FrostPublic>): TRet<FrostPublic> {\n const VK = Pointk1.fromBytes(pub.commitments[0]);\n // Keep aliasing on the already-even path so wrapper callers can skip unnecessary cloning.\n if (hasEven(VK.y)) return pub as TRet<FrostPublic>;\n return {\n signers: { min: pub.signers.min, max: pub.signers.max },\n commitments: pub.commitments.map((i) => Pointk1.fromBytes(i).negate().toBytes()),\n verifyingShares: Object.fromEntries(\n Object.entries(pub.verifyingShares).map(([k, v]) => [\n k,\n Pointk1.fromBytes(v).negate().toBytes(),\n ])\n ),\n } as TRet<FrostPublic>;\n}\nfunction frostSecretToEvenY(s: TArg<FrostSecret>, pub: TArg<FrostPublic>): TRet<FrostSecret> {\n const VK = Pointk1.fromBytes(pub.commitments[0]);\n // Keep aliasing on the already-even path so wrapper callers can preserve package identity.\n if (hasEven(VK.y)) return s as TRet<FrostSecret>;\n const Fn = Pointk1.Fn;\n return {\n ...s,\n signingShare: Fn.toBytes(Fn.neg(Fn.fromBytes(s.signingShare))),\n } as TRet<FrostSecret>;\n}\nfunction frostNoncesToEvenY(PK: PointType<bigint>, nonces: TArg<Nonces>): TRet<Nonces> {\n if (hasEven(PK.y)) return nonces as TRet<Nonces>;\n const Fn = Pointk1.Fn;\n return {\n binding: Fn.toBytes(Fn.neg(Fn.fromBytes(nonces.binding))),\n hiding: Fn.toBytes(Fn.neg(Fn.fromBytes(nonces.hiding))),\n } as TRet<Nonces>;\n}\n\nfunction frostTweakSecret(\n s: TArg<FrostSecret>,\n pub: TArg<FrostPublic>,\n merkleRoot?: TArg<Uint8Array>\n): TRet<FrostSecret> {\n const Fn = Pointk1.Fn;\n const keyPackage = frostSecretToEvenY(s, pub);\n const evenPub = frostPubToEvenY(pub);\n const t = tweak(Pointk1.fromBytes(evenPub.commitments[0]), merkleRoot);\n const signingShare = Fn.toBytes(Fn.add(Fn.fromBytes(keyPackage.signingShare), t));\n return {\n identifier: keyPackage.identifier,\n signingShare,\n } as TRet<FrostSecret>;\n}\n\nfunction frostTweakPublic(\n pub: TArg<FrostPublic>,\n merkleRoot?: TArg<Uint8Array>\n): TRet<FrostPublic> {\n const PKPackage = frostPubToEvenY(pub);\n const t = tweak(Pointk1.fromBytes(PKPackage.commitments[0]), merkleRoot);\n const tp = Pointk1.BASE.multiply(t);\n const commitments = PKPackage.commitments.map((c, i) =>\n (i === 0 ? Pointk1.fromBytes(c).add(tp) : Pointk1.fromBytes(c)).toBytes()\n );\n const verifyingShares: Record<string, Uint8Array> = {};\n for (const k in PKPackage.verifyingShares) {\n verifyingShares[k] = Pointk1.fromBytes(PKPackage.verifyingShares[k]).add(tp).toBytes();\n }\n return {\n signers: { min: PKPackage.signers.min, max: PKPackage.signers.max },\n commitments,\n verifyingShares,\n } as TRet<FrostPublic>;\n}\n\n/**\n * FROST threshold signatures over secp256k1-schnorr-taproot. RFC 9591.\n * DKG outputs are auto-tweaked with the empty Taproot merkle root for compatibility, while\n * `trustedDealer()` outputs stay untweaked unless callers apply the Taproot tweak themselves.\n * @example\n * Create one trusted-dealer package for Taproot-compatible FROST signing.\n *\n * ```ts\n * const alice = schnorr_FROST.Identifier.derive('alice@example.com');\n * const bob = schnorr_FROST.Identifier.derive('bob@example.com');\n * const carol = schnorr_FROST.Identifier.derive('carol@example.com');\n * const deal = schnorr_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);\n * ```\n */\nexport const schnorr_FROST: TRet<FROST> = /* @__PURE__ */ (() =>\n createFROST({\n name: 'FROST-secp256k1-SHA256-TR-v1',\n Point: Pointk1,\n hashToScalar: secp256k1_hasher.hashToScalar,\n hash: sha256,\n // Taproot related hacks\n parsePublicKey(publicKey) {\n // External Taproot keys are x-only, but local key packages still use compressed points.\n if (publicKey.length === 32) return lift_x(bytesToNumberBE(publicKey));\n if (publicKey.length === 33) return Pointk1.fromBytes(publicKey);\n throw new Error(`expected x-only or compressed public key, got length=${publicKey.length}`);\n },\n adjustScalar(n: bigint) {\n const PK = Pointk1.BASE.multiply(n);\n return hasEven(PK.y) ? n : Pointk1.Fn.neg(n);\n },\n adjustPoint: (p) => (hasEven(p.y) ? p : p.negate()),\n challenge(R, PK, msg) {\n return challenge(pointToBytes(R), pointToBytes(PK), msg);\n },\n adjustNonces: frostNoncesToEvenY,\n adjustGroupCommitmentShare: (GC, GCShare) => (!hasEven(GC.y) ? GCShare.negate() : GCShare),\n adjustPublic: frostPubToEvenY,\n adjustSecret: frostSecretToEvenY,\n adjustTx: {\n // Compat with official implementation\n encode: (tx) => tx.subarray(1) as TRet<Uint8Array>,\n decode: (tx) => concatBytes(Uint8Array.of(0x02), tx) as TRet<Uint8Array>,\n },\n adjustDKG: (k) => {\n // Compatibility with frost-secp256k1-tr: DKG output is auto-tweaked with the\n // empty Taproot merkle root, while dealer-generated keys stay untweaked.\n const merkleRoot = new Uint8Array(0);\n return {\n public: frostTweakPublic(k.public, merkleRoot),\n secret: frostTweakSecret(k.secret, k.public, merkleRoot),\n };\n },\n }))();\n","/**\n * Cryptographic utilities for SDK2\n *\n * Provides BIP39 mnemonic and BIP32 key derivation functions.\n * Platform-independent - no browser-specific APIs.\n */\n\nimport { secp256k1 } from '@noble/curves/secp256k1.js';\nimport * as bip39 from 'bip39';\nimport CryptoJS from 'crypto-js';\nimport { SphereError } from './errors';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** secp256k1 curve order */\nconst CURVE_ORDER = BigInt(\n '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'\n);\n\n/** A secp256k1 private key is exactly 32 bytes — 64 hex chars. */\nconst PRIVKEY_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\n/**\n * Reject a malformed private key BEFORE it reaches the curve (#674 review).\n * `hexToBytes` coerces any non-hex character to a zero byte\n * (`parseInt('gg', 16)` → NaN → 0), so a right-length string with a stray\n * non-hex char would otherwise derive/sign with a DIFFERENT valid key and no\n * error — silently signing with an unintended key. secp256k1 already rejects\n * wrong-*length* input; this closes the same-length-wrong-chars hole.\n */\nfunction assertPrivKeyHex(privateKeyHex: string): void {\n if (!PRIVKEY_HEX_RE.test(privateKeyHex)) {\n throw new SphereError(\n `Invalid private key: expected 64 hex chars, got ${privateKeyHex.length}`,\n 'VALIDATION_ERROR',\n );\n }\n}\n\n/** Default derivation path for Unicity (BIP44) */\nexport const DEFAULT_DERIVATION_PATH = \"m/44'/0'/0'\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MasterKey {\n privateKey: string;\n chainCode: string;\n}\n\nexport interface DerivedKey {\n privateKey: string;\n chainCode: string;\n}\n\nexport interface KeyPair {\n privateKey: string;\n publicKey: string;\n}\n\nexport interface AddressInfo extends KeyPair {\n path: string;\n index: number;\n}\n\n// =============================================================================\n// BIP39 Mnemonic Functions\n// =============================================================================\n\n/**\n * Generate a new BIP39 mnemonic phrase\n * @param strength - Entropy bits (128 = 12 words, 256 = 24 words)\n */\nexport function generateMnemonic(strength: 128 | 256 = 128): string {\n return bip39.generateMnemonic(strength);\n}\n\n/**\n * Validate a BIP39 mnemonic phrase\n */\nexport function validateMnemonic(mnemonic: string): boolean {\n return bip39.validateMnemonic(mnemonic);\n}\n\n/**\n * Convert mnemonic to seed (64-byte hex string)\n * @param mnemonic - BIP39 mnemonic phrase\n * @param passphrase - Optional passphrase for additional security\n */\nexport async function mnemonicToSeed(\n mnemonic: string,\n passphrase: string = ''\n): Promise<string> {\n const seedBuffer = await bip39.mnemonicToSeed(mnemonic, passphrase);\n return Buffer.from(seedBuffer).toString('hex');\n}\n\n/**\n * Synchronous version of mnemonicToSeed\n */\nexport function mnemonicToSeedSync(\n mnemonic: string,\n passphrase: string = ''\n): string {\n const seedBuffer = bip39.mnemonicToSeedSync(mnemonic, passphrase);\n return Buffer.from(seedBuffer).toString('hex');\n}\n\n/**\n * Convert mnemonic to entropy (for recovery purposes)\n */\nexport function mnemonicToEntropy(mnemonic: string): string {\n return bip39.mnemonicToEntropy(mnemonic);\n}\n\n/**\n * Convert entropy to mnemonic\n */\nexport function entropyToMnemonic(entropy: string): string {\n return bip39.entropyToMnemonic(entropy);\n}\n\n// =============================================================================\n// BIP32 Key Derivation\n// =============================================================================\n\n/**\n * Generate master key from seed (BIP32 standard)\n * Uses HMAC-SHA512 with key \"Bitcoin seed\"\n */\nexport function generateMasterKey(seedHex: string): MasterKey {\n const I = CryptoJS.HmacSHA512(\n CryptoJS.enc.Hex.parse(seedHex),\n CryptoJS.enc.Utf8.parse('Bitcoin seed')\n ).toString();\n\n const IL = I.substring(0, 64); // Left 32 bytes - master private key\n const IR = I.substring(64); // Right 32 bytes - master chain code\n\n // Validate master key\n const masterKeyBigInt = BigInt('0x' + IL);\n if (masterKeyBigInt === 0n || masterKeyBigInt >= CURVE_ORDER) {\n throw new SphereError('Invalid master key generated', 'VALIDATION_ERROR');\n }\n\n return {\n privateKey: IL,\n chainCode: IR,\n };\n}\n\n/**\n * Derive child key using BIP32 standard\n * @param parentPrivKey - Parent private key (64 hex chars)\n * @param parentChainCode - Parent chain code (64 hex chars)\n * @param index - Child index (>= 0x80000000 for hardened)\n */\nexport function deriveChildKey(\n parentPrivKey: string,\n parentChainCode: string,\n index: number\n): DerivedKey {\n const isHardened = index >= 0x80000000;\n let data: string;\n\n if (isHardened) {\n // Hardened derivation: 0x00 || parentPrivKey || index\n const indexHex = index.toString(16).padStart(8, '0');\n data = '00' + parentPrivKey + indexHex;\n } else {\n // Non-hardened derivation: compressedPubKey || index\n const compressedPubKey = getPublicKey(parentPrivKey, true);\n const indexHex = index.toString(16).padStart(8, '0');\n data = compressedPubKey + indexHex;\n }\n\n // HMAC-SHA512 with chain code as key\n const I = CryptoJS.HmacSHA512(\n CryptoJS.enc.Hex.parse(data),\n CryptoJS.enc.Hex.parse(parentChainCode)\n ).toString();\n\n const IL = I.substring(0, 64); // Left 32 bytes\n const IR = I.substring(64); // Right 32 bytes (new chain code)\n\n // Add IL to parent key mod n (curve order)\n const ilBigInt = BigInt('0x' + IL);\n const parentKeyBigInt = BigInt('0x' + parentPrivKey);\n\n // Check IL is valid (less than curve order)\n if (ilBigInt >= CURVE_ORDER) {\n throw new SphereError('Invalid key: IL >= curve order', 'VALIDATION_ERROR');\n }\n\n const childKeyBigInt = (ilBigInt + parentKeyBigInt) % CURVE_ORDER;\n\n // Check child key is valid (not zero)\n if (childKeyBigInt === 0n) {\n throw new SphereError('Invalid key: child key is zero', 'VALIDATION_ERROR');\n }\n\n const childPrivKey = childKeyBigInt.toString(16).padStart(64, '0');\n\n return {\n privateKey: childPrivKey,\n chainCode: IR,\n };\n}\n\n/**\n * Derive key at a full BIP32/BIP44 path\n * @param masterPrivKey - Master private key\n * @param masterChainCode - Master chain code\n * @param path - BIP44 path like \"m/44'/0'/0'/0/0\"\n */\nexport function deriveKeyAtPath(\n masterPrivKey: string,\n masterChainCode: string,\n path: string\n): DerivedKey {\n const pathParts = path.replace('m/', '').split('/');\n\n let currentKey = masterPrivKey;\n let currentChainCode = masterChainCode;\n\n for (const part of pathParts) {\n const isHardened = part.endsWith(\"'\") || part.endsWith('h');\n const indexStr = part.replace(/['h]$/, '');\n let index = parseInt(indexStr, 10);\n\n if (isHardened) {\n index += 0x80000000; // Add hardened offset\n }\n\n const derived = deriveChildKey(currentKey, currentChainCode, index);\n currentKey = derived.privateKey;\n currentChainCode = derived.chainCode;\n }\n\n return {\n privateKey: currentKey,\n chainCode: currentChainCode,\n };\n}\n\n// =============================================================================\n// Key Pair Operations\n// =============================================================================\n\n/**\n * Get public key from private key\n * @param privateKey - Private key as hex string\n * @param compressed - Return compressed public key (default: true)\n */\nexport function getPublicKey(privateKey: string, compressed: boolean = true): string {\n assertPrivKeyHex(privateKey);\n // SEC1 encoding: compressed = 02/03 prefix + x (33 bytes),\n // uncompressed = 04 prefix + x + y (65 bytes) — identical to elliptic's output.\n return bytesToHex(secp256k1.getPublicKey(hexToBytes(privateKey), compressed));\n}\n\n/**\n * Create key pair from private key\n */\nexport function createKeyPair(privateKey: string): KeyPair {\n return {\n privateKey,\n publicKey: getPublicKey(privateKey),\n };\n}\n\n// =============================================================================\n// Hash Functions\n// =============================================================================\n\n/**\n * Compute SHA256 hash\n */\nexport function sha256(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const parsed =\n inputEncoding === 'hex'\n ? CryptoJS.enc.Hex.parse(data)\n : CryptoJS.enc.Utf8.parse(data);\n return CryptoJS.SHA256(parsed).toString();\n}\n\n/**\n * Compute RIPEMD160 hash\n */\nexport function ripemd160(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const parsed =\n inputEncoding === 'hex'\n ? CryptoJS.enc.Hex.parse(data)\n : CryptoJS.enc.Utf8.parse(data);\n return CryptoJS.RIPEMD160(parsed).toString();\n}\n\n/**\n * Compute HASH160 (SHA256 -> RIPEMD160)\n */\nexport function hash160(data: string): string {\n const sha = sha256(data, 'hex');\n return ripemd160(sha, 'hex');\n}\n\n/**\n * Compute double SHA256\n */\nexport function doubleSha256(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const first = sha256(data, inputEncoding);\n return sha256(first, 'hex');\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Convert hex string to Uint8Array\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const matches = hex.match(/../g);\n if (!matches) {\n return new Uint8Array(0);\n }\n return Uint8Array.from(matches.map((x) => parseInt(x, 16)));\n}\n\n/**\n * Convert Uint8Array to hex string\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Generate random bytes as hex string\n */\nexport function randomBytes(length: number): string {\n const words = CryptoJS.lib.WordArray.random(length);\n return words.toString(CryptoJS.enc.Hex);\n}\n\n// =============================================================================\n// High-Level Functions\n// =============================================================================\n\n/**\n * Generate identity from mnemonic\n * Returns master key derived from mnemonic seed\n */\nexport async function identityFromMnemonic(\n mnemonic: string,\n passphrase: string = ''\n): Promise<MasterKey> {\n if (!validateMnemonic(mnemonic)) {\n throw new SphereError('Invalid mnemonic phrase', 'INVALID_IDENTITY');\n }\n const seedHex = await mnemonicToSeed(mnemonic, passphrase);\n return generateMasterKey(seedHex);\n}\n\n/**\n * Synchronous version of identityFromMnemonic\n */\nexport function identityFromMnemonicSync(\n mnemonic: string,\n passphrase: string = ''\n): MasterKey {\n if (!validateMnemonic(mnemonic)) {\n throw new SphereError('Invalid mnemonic phrase', 'INVALID_IDENTITY');\n }\n const seedHex = mnemonicToSeedSync(mnemonic, passphrase);\n return generateMasterKey(seedHex);\n}\n\n/**\n * Derive key info at a specific path\n * @param masterKey - Master key with privateKey and chainCode\n * @param basePath - Base derivation path (e.g., \"m/44'/0'/0'\")\n * @param index - Address index\n * @param isChange - Whether this is a change address (chain 1 vs 0)\n */\nexport function deriveAddressInfo(\n masterKey: MasterKey,\n basePath: string,\n index: number,\n isChange: boolean = false\n): AddressInfo {\n const chain = isChange ? 1 : 0;\n const fullPath = `${basePath}/${chain}/${index}`;\n\n const derived = deriveKeyAtPath(masterKey.privateKey, masterKey.chainCode, fullPath);\n const publicKey = getPublicKey(derived.privateKey);\n\n return {\n privateKey: derived.privateKey,\n publicKey,\n path: fullPath,\n index,\n };\n}\n\n/**\n * Generate full key info from private key with index and path\n */\nexport function generateAddressInfo(\n privateKey: string,\n index: number,\n path: string\n): AddressInfo {\n const publicKey = getPublicKey(privateKey);\n return {\n privateKey,\n publicKey,\n path,\n index,\n };\n}\n\n/**\n * Generate key info from master private key using HMAC-SHA512 derivation\n * This matches exactly the original index.html implementation\n * NOTE: This is NON-STANDARD derivation for legacy wallet compatibility.\n *\n * Dual-use: in `wif_hmac` derivation mode (legacy wallet import) this derives\n * the wallet's chainPubkey (used for L3 identity).\n *\n * @param masterPrivateKey - 32-byte hex private key (64 chars)\n * @param index - Address index\n */\nexport function generateAddressFromMasterKey(\n masterPrivateKey: string,\n index: number\n): AddressInfo {\n const derivationPath = `m/44'/0'/${index}'`;\n\n // HMAC-SHA512 with path as key (matching index.html exactly)\n const hmacInput = CryptoJS.enc.Hex.parse(masterPrivateKey);\n const hmacKey = CryptoJS.enc.Utf8.parse(derivationPath);\n const hmacOutput = CryptoJS.HmacSHA512(hmacInput, hmacKey).toString();\n\n // Use left 32 bytes for private key\n const childPrivateKey = hmacOutput.substring(0, 64);\n\n return generateAddressInfo(childPrivateKey, index, derivationPath);\n}\n\n// =============================================================================\n// Message Signing (secp256k1 ECDSA with recoverable signature)\n// =============================================================================\n\n/** Prefix prepended to all signed messages (Bitcoin-like signed message format) */\nexport const SIGN_MESSAGE_PREFIX = 'Sphere Signed Message:\\n';\n\n/** Encode an integer as a Bitcoin-style compact varint */\nfunction varint(n: number): Uint8Array {\n if (n < 253) return new Uint8Array([n]);\n const buf = new Uint8Array(3);\n buf[0] = 253;\n buf[1] = n & 0xff;\n buf[2] = (n >> 8) & 0xff;\n return buf;\n}\n\n/**\n * Hash a message for signing using the Bitcoin-like double-SHA256 scheme:\n * SHA256(SHA256(varint(prefix.length) + prefix + varint(msg.length) + msg))\n *\n * @returns 64-char lowercase hex hash\n */\nexport function hashSignMessage(message: string): string {\n const prefix = new TextEncoder().encode(SIGN_MESSAGE_PREFIX);\n const msg = new TextEncoder().encode(message);\n const prefixLen = varint(prefix.length);\n const msgLen = varint(msg.length);\n const full = new Uint8Array(prefixLen.length + prefix.length + msgLen.length + msg.length);\n let off = 0;\n full.set(prefixLen, off); off += prefixLen.length;\n full.set(prefix, off); off += prefix.length;\n full.set(msgLen, off); off += msgLen.length;\n full.set(msg, off);\n const hex = Array.from(full).map(b => b.toString(16).padStart(2, '0')).join('');\n const h1 = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(hex)).toString();\n return CryptoJS.SHA256(CryptoJS.enc.Hex.parse(h1)).toString();\n}\n\n/**\n * Sign a message with a secp256k1 private key.\n *\n * Returns a 130-character hex string: v (2 chars) + r (64 chars) + s (64 chars).\n * The recovery byte `v` is `31 + recoveryParam` (0-3).\n *\n * @param privateKeyHex - 64-char hex private key\n * @param message - plaintext message to sign\n */\nexport function signMessage(privateKeyHex: string, message: string): string {\n assertPrivKeyHex(privateKeyHex);\n const hashHex = hashSignMessage(message);\n // prehash:false — the message is already hashed (double-SHA256 above);\n // lowS:true — canonical low-S signatures (same as elliptic's {canonical:true});\n // format:'recovered' — recoveryId(1) || r(32) || s(32), RFC6979-deterministic.\n const sigBytes = secp256k1.sign(hexToBytes(hashHex), hexToBytes(privateKeyHex), {\n prehash: false,\n lowS: true,\n format: 'recovered',\n });\n\n const recoveryParam = sigBytes[0];\n const v = (31 + recoveryParam).toString(16).padStart(2, '0');\n // r and s are fixed-width 32-byte big-endian — already left-padded.\n return v + bytesToHex(sigBytes.subarray(1));\n}\n\n/**\n * Verify a signed message against a compressed secp256k1 public key.\n *\n * @param message - The original plaintext message\n * @param signature - 130-char hex signature (v + r + s)\n * @param expectedPubkey - 66-char compressed public key hex\n * @returns `true` if the signature is valid and matches the expected public key\n */\nexport function verifySignedMessage(\n message: string,\n signature: string,\n expectedPubkey: string,\n): boolean {\n if (signature.length !== 130) return false;\n\n const v = parseInt(signature.slice(0, 2), 16) - 31;\n const r = signature.slice(2, 66);\n const s = signature.slice(66, 130);\n\n if (v < 0 || v > 3) return false;\n\n const hashHex = hashSignMessage(message);\n\n try {\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true) === expectedPubkey; // compressed\n } catch {\n return false;\n }\n}\n\n/**\n * Recover the compressed secp256k1 public key from a signed message.\n *\n * Use this when the server needs to identify the signer (not just verify\n * a signature against a known pubkey). Combined with `sphere.resolve(pubkey)`\n * it gives a fully cryptographically-attributable identity for backend auth,\n * without trusting any client-supplied identifier claim.\n *\n * @param message - The plaintext that was signed\n * @param signature - 130-char hex (v + r + s) as produced by `signMessage`\n * @returns - Compressed 66-char hex pubkey\n * @throws - On malformed signature length or out-of-range recovery byte\n */\nexport function recoverPubkeyFromSignature(message: string, signature: string): string {\n if (signature.length !== 130) {\n throw new SphereError(\n `Invalid signature length: expected 130 hex chars, got ${signature.length}`,\n 'SIGNING_ERROR',\n );\n }\n\n const v = parseInt(signature.slice(0, 2), 16) - 31;\n const r = signature.slice(2, 66);\n const s = signature.slice(66, 130);\n\n if (v < 0 || v > 3) {\n throw new SphereError(\n `Invalid recovery byte: v=${v} out of range [0..3]`,\n 'SIGNING_ERROR',\n );\n }\n\n const hashHex = hashSignMessage(message);\n\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true); // compressed\n}\n","/**\n * SDK Error Types\n *\n * Structured error codes for programmatic error handling in UI.\n * UI can switch on error.code to show appropriate user-facing messages.\n *\n * @example\n * ```ts\n * import { SphereError } from '@unicitylabs/sphere-sdk';\n *\n * try {\n * await sphere.payments.send({ ... });\n * } catch (err) {\n * if (err instanceof SphereError) {\n * switch (err.code) {\n * case 'INSUFFICIENT_BALANCE': showToast('Not enough funds'); break;\n * case 'INVALID_RECIPIENT': showToast('Recipient not found'); break;\n * case 'TRANSPORT_ERROR': showToast('Network connection issue'); break;\n * case 'TIMEOUT': showToast('Request timed out, try again'); break;\n * default: showToast(err.message);\n * }\n * }\n * }\n * ```\n */\n\nexport type SphereErrorCode =\n | 'NOT_INITIALIZED'\n | 'ALREADY_INITIALIZED'\n | 'INVALID_CONFIG'\n | 'INVALID_IDENTITY'\n | 'INSUFFICIENT_BALANCE'\n | 'INVALID_RECIPIENT'\n | 'TRANSFER_FAILED'\n // The source state was consumed by a DIFFERENT transaction (lost race, not a\n // resume) — raised as TransferConflictError (token-engine/errors.ts, Part E.2).\n | 'TRANSFER_CONFLICT'\n // The op's certification is INDETERMINATE (submit accepted / proof fetch\n // inconclusive) — raised as ProofUnconfirmedError; keep the intent OPEN (#631).\n | 'CERTIFICATION_UNCONFIRMED'\n // Split burn checkpoint (sdk-changes E.4, sphere-sdk#501) — all keep-open (token-engine/errors.ts):\n // burn certified but the checkpoint could not be persisted (no mint submitted);\n | 'CHECKPOINT_PERSIST_FAILED'\n // a certified mint leaf has no reproducing stored bytes, or a stored checkpoint fails byte-binding;\n | 'SPLIT_CHECKPOINT_LOST'\n // a byte-bound checkpoint proof no longer verifies against the current trust base (validator rotation).\n | 'CHECKPOINT_TRUSTBASE_MISMATCH'\n | 'STORAGE_ERROR'\n // #665: the on-chain spend committed but the post-commit wallet-api mirror\n // sync (inventory apply / blob upload / save) failed. NOT a lost payment —\n // the intent is kept open and resume converges the mirror (idempotent apply,\n // #664). Surfaced distinctly so a UI can reassure (\"sent — wallet catching\n // up\") instead of showing a hard send failure.\n | 'SEND_SYNC_PENDING'\n // #677: a multi-leg send lost a source to a concurrent transfer AFTER ≥1\n // earlier leg had already certified on-chain AND been journaled/delivered.\n // The delivered value has irreversibly left the wallet, so this is NOT a\n // plain, re-sendable failure: surfacing a bare TransferConflictError makes\n // the caller re-send the FULL amount and pay the delivered leg twice. Raised\n // as PartialSendConflictError; the caller MUST re-plan ONLY the remainder\n // under a NEW transferId, never the whole amount.\n | 'SEND_PARTIALLY_COMPLETED'\n | 'TRANSPORT_ERROR'\n | 'AGGREGATOR_ERROR'\n | 'VALIDATION_ERROR'\n | 'INVALID_AMOUNT'\n | 'NETWORK_ERROR'\n | 'TIMEOUT'\n | 'DECRYPTION_ERROR'\n | 'MODULE_NOT_AVAILABLE'\n // #793: this Sphere was initialised with `walletApi: 'none'` — the explicit\n // messaging-only composition. Distinct from NOT_INITIALIZED, which is transient\n // (init in flight, mid address-switch, destroyed): this one never resolves.\n | 'PAYMENTS_NOT_COMPOSED'\n | 'SIGNING_ERROR'\n // Token Spend Queue error codes\n | 'SEND_QUEUE_TIMEOUT'\n | 'SEND_INSUFFICIENT_BALANCE'\n | 'SEND_RESERVATION_CANCELLED'\n | 'SEND_QUEUE_FULL'\n | 'MODULE_DESTROYED'\n | 'REENTRANT_GATE'\n // Invoice / Accounting error codes\n | 'INVOICE_NO_TARGETS'\n | 'INVOICE_INVALID_ADDRESS'\n | 'INVOICE_NO_ASSETS'\n | 'INVOICE_INVALID_ASSET'\n | 'INVOICE_INVALID_AMOUNT'\n | 'INVOICE_INVALID_COIN'\n | 'INVOICE_INVALID_NFT'\n | 'INVOICE_PAST_DUE_DATE'\n | 'INVOICE_DUPLICATE_ADDRESS'\n | 'INVOICE_DUPLICATE_COIN'\n | 'INVOICE_DUPLICATE_NFT'\n | 'INVOICE_MINT_FAILED'\n | 'INVOICE_INVALID_PROOF'\n | 'INVOICE_WRONG_TOKEN_TYPE'\n | 'INVOICE_INVALID_DATA'\n | 'INVOICE_ALREADY_EXISTS'\n | 'INVOICE_NOT_FOUND'\n | 'INVOICE_NOT_TARGET'\n | 'INVOICE_ALREADY_CLOSED'\n | 'INVOICE_ALREADY_CANCELLED'\n | 'INVOICE_ORACLE_REQUIRED'\n | 'INVOICE_TERMINATED'\n | 'INVOICE_INVALID_TARGET'\n | 'INVOICE_INVALID_ASSET_INDEX'\n | 'INVOICE_RETURN_EXCEEDS_BALANCE'\n | 'INVOICE_INVALID_DELIVERY_METHOD'\n | 'INVOICE_INVALID_REFUND_ADDRESS'\n | 'INVOICE_INVALID_CONTACT'\n | 'INVOICE_INVALID_ID'\n | 'INVOICE_TOO_MANY_TARGETS'\n | 'INVOICE_TOO_MANY_ASSETS'\n | 'INVOICE_MEMO_TOO_LONG'\n | 'INVOICE_TERMS_TOO_LARGE'\n | 'INVOICE_NOT_TERMINATED'\n | 'INVOICE_NOT_CANCELLED'\n | 'INVOICE_STORAGE_FAILED'\n | 'RATE_LIMITED'\n | 'COMMUNICATIONS_UNAVAILABLE'\n // Swap error codes\n | 'SWAP_INVALID_DEAL'\n | 'SWAP_INVALID_MANIFEST'\n | 'SWAP_NOT_FOUND'\n | 'SWAP_WRONG_STATE'\n | 'SWAP_RESOLVE_FAILED'\n | 'SWAP_DM_SEND_FAILED'\n | 'SWAP_ESCROW_REJECTED'\n | 'SWAP_DEPOSIT_FAILED'\n | 'SWAP_PAYOUT_VERIFICATION_FAILED'\n | 'SWAP_ALREADY_EXISTS'\n | 'SWAP_ALREADY_COMPLETED'\n | 'SWAP_ALREADY_CANCELLED'\n | 'SWAP_TIMEOUT'\n | 'SWAP_LIMIT_EXCEEDED'\n | 'SWAP_ALREADY_INITIALIZED'\n | 'SWAP_MODULE_DESTROYED'\n | 'SWAP_NOT_INITIALIZED';\n\nexport class SphereError extends Error {\n readonly code: SphereErrorCode;\n readonly cause?: unknown;\n /**\n * #441 deferred-paid linkage: the transferId of the possibly-committed send,\n * stamped by `sendOnce` before the error leaves so a payment-request consumer\n * can durably journal request→transfer and resolve 'paid' only when that\n * transfer actually completes (never optimistically). Present ONLY on\n * possibly-committed outcomes ({@link isPossiblyCommittedSendOutcome}).\n */\n transferId?: string;\n\n constructor(message: string, code: SphereErrorCode, cause?: unknown) {\n super(message);\n this.name = 'SphereError';\n this.code = code;\n this.cause = cause;\n }\n}\n\n/**\n * #677: a send that PARTIALLY completed before losing a source to a concurrent\n * transfer. At least one earlier leg certified on-chain and was journaled for\n * delivery (its {@link committedTokenIds}) — that value has irreversibly left\n * the wallet — but a LATER leg raised `TransferConflictError` (a lost race), and\n * `send()` could NOT COMPLETE the {@link remainingAmount} from the remaining live\n * sources. This is the fallback after the internal remainder re-plan gave up —\n * either insufficient funds OR a transient/transport error during the re-plan\n * (the underlying reason is on `cause`), not necessarily an \"out of funds\" state.\n *\n * Distinct from `TransferConflictError` on purpose: a bare conflict makes the\n * caller re-send the FULL amount, paying the already-delivered leg a second\n * time. Catching THIS type (or `code === 'SEND_PARTIALLY_COMPLETED'`) tells the\n * caller/UI: the delivered legs are final, the conflicted intent stays OPEN\n * (resume converges its certified legs), and only the REMAINDER\n * ({@link remainingAmount}) may be re-planned — under a NEW transferId, never\n * re-sending the whole amount.\n *\n * NOT a subclass of `TransferConflictError` by design: existing conflict\n * handlers that re-send in full must NOT treat this as an ordinary conflict.\n */\nexport class PartialSendConflictError extends SphereError {\n /**\n * The FIRST partial attempt's transferId — its intent stays open for resume,\n * and it is the §6 handoff anchor. NOTE: `send()` may re-plan the remainder across\n * SEVERAL internal attempts before giving up, so {@link committedTokenIds} can\n * span MULTIPLE transferIds — they do NOT all map to this single id.\n */\n readonly transferId: string;\n /**\n * Source token ids whose spend already certified on-chain (and whose finished\n * output blob is journaled for delivery). Their value has already been\n * delivered; NEVER re-send these. May accumulate across several internal\n * remainder-re-plan attempts (so not all are journaled under {@link transferId}).\n */\n readonly committedTokenIds: readonly string[];\n /**\n * The still-undelivered portion (base units, decimal string) — `send()` could\n * not COMPLETE it from the remaining live sources (insufficient funds or a\n * transient error; see `cause`). Re-plan ONLY this amount, under a new\n * transferId; the delivered legs converge via the recipient's §6 claim.\n */\n readonly remainingAmount: string;\n\n constructor(\n message: string,\n transferId: string,\n committedTokenIds: readonly string[],\n remainingAmount: string,\n cause?: unknown,\n ) {\n super(message, 'SEND_PARTIALLY_COMPLETED', cause);\n this.name = 'PartialSendConflictError';\n this.transferId = transferId;\n this.committedTokenIds = [...committedTokenIds];\n this.remainingAmount = remainingAmount;\n }\n}\n\n/**\n * Error codes for a send outcome where money has (or may have) already left the\n * wallet on-chain, so the send is NOT a clean, re-sendable failure. A consumer\n * that persists a \"paid\" flag (e.g. a payment request) must keep the request\n * NON-payable on any of these — reverting to a re-payable state would double-pay\n * (#441). Covers the post-commit mirror-sync-pending / keep-open certification\n * states AND the partial-conflict outcome.\n */\nconst POSSIBLY_COMMITTED_SEND_CODES: ReadonlySet<SphereErrorCode> = new Set([\n 'SEND_SYNC_PENDING',\n 'CERTIFICATION_UNCONFIRMED',\n 'CHECKPOINT_PERSIST_FAILED',\n 'SPLIT_CHECKPOINT_LOST',\n 'CHECKPOINT_TRUSTBASE_MISMATCH',\n 'SEND_PARTIALLY_COMPLETED',\n]);\n\n/**\n * #441: true when a send failed with an outcome where the payment has (or may\n * have) irreversibly left the wallet — a post-commit sync-pending / keep-open\n * certification state, or a `PartialSendConflictError`. Such a send completes (or\n * has already partially completed) via resume/claim and MUST NOT be re-sent, so\n * a persisted \"paid\" state must stay non-payable. A `false` result is a clean\n * pre-commit failure — nothing left the wallet, safe to re-pay.\n */\nexport function isPossiblyCommittedSendOutcome(err: unknown): boolean {\n return isSphereError(err) && POSSIBLY_COMMITTED_SEND_CODES.has(err.code);\n}\n\n/**\n * Type guard to check if an error is a SphereError\n */\nexport function isSphereError(err: unknown): err is SphereError {\n return err instanceof SphereError;\n}\n","/**\n * The ONE source for the wallet-api cross-repo contract strings (§4 auth\n * challenge, E.4/#87/§16 seed-holder messages) — never re-derive them.\n * Grammar + rationale (#662 device-clock ban): wallet-api ARCHITECTURE §4/§16.\n */\n\nimport { sha256 } from './crypto';\n\n/** The §16 progress-append message: signed over the EXACT stored-envelope bytes (E.4). */\nexport function progressSignMessage(transferId: string, opIndex: number, payloadEnvelope: string): string {\n return `wallet-api.progress.v1:${transferId}:${String(opIndex)}:${sha256(payloadEnvelope, 'utf8')}`;\n}\n\n/** The §16/#87 terminal-close message for a checkpoint-bearing intent. */\nexport function completeSignMessage(transferId: string): string {\n return `wallet-api.complete.v1:${transferId}`;\n}\n\n/** Fixed domain-separation prefix (ARCHITECTURE §4 step 1). */\nexport const AUTH_CHALLENGE_PREFIX = 'unicity:wallet-api:auth:v1\\n';\n\n/** Maximum plausible challenge validity window (server default: NONCE_TTL = 5 min). */\nconst MAX_VALIDITY_WINDOW_MS = 60 * 60 * 1000;\n\nexport class ChallengeTemplateError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ChallengeTemplateError';\n }\n}\n\nexport interface ChallengeExpectation {\n /** The client's own compressed pubkey hex — the challenge MUST embed it. */\n pubkey: string;\n nonce: string;\n /** The client's network — refused if the challenge names a different one. */\n network: string;\n}\n\nfunction parseFields(body: string): Map<string, string> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n throw new ChallengeTemplateError('Challenge body is not the single-line JSON object the backend emits');\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new ChallengeTemplateError('Challenge body must be a JSON object');\n }\n const fields = new Map<string, string>();\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value !== 'string' || value === '') {\n throw new ChallengeTemplateError(`Challenge field \"${key}\" must be a non-empty string`);\n }\n fields.set(key, value);\n }\n return fields;\n}\n\nfunction requireField(fields: Map<string, string>, key: string): string {\n const value = fields.get(key);\n if (value === undefined) {\n throw new ChallengeTemplateError(`Challenge is missing the \"${key}\" field`);\n }\n return value;\n}\n\nfunction parseTimestamp(value: string, key: string): number {\n const ms = Date.parse(value);\n if (Number.isNaN(ms)) {\n throw new ChallengeTemplateError(`Challenge \"${key}\" is not a parseable timestamp: ${value}`);\n }\n return ms;\n}\n\n/** The spend key never signs unverified server text — throws on ANY violation. */\nexport function verifyChallengeTemplate(challenge: string, expect: ChallengeExpectation): void {\n if (typeof challenge !== 'string' || !challenge.startsWith(AUTH_CHALLENGE_PREFIX)) {\n throw new ChallengeTemplateError('Challenge does not start with the unicity:wallet-api:auth:v1 domain prefix');\n }\n const fields = parseFields(challenge.slice(AUTH_CHALLENGE_PREFIX.length));\n\n const pubkey = requireField(fields, 'pubkey');\n if (pubkey.toLowerCase() !== expect.pubkey.toLowerCase()) {\n throw new ChallengeTemplateError('Challenge embeds a different pubkey than this wallet');\n }\n\n const nonce = requireField(fields, 'nonce');\n if (nonce !== expect.nonce) {\n throw new ChallengeTemplateError('Challenge nonce does not match the nonce issued with it');\n }\n\n const network = requireField(fields, 'network');\n if (network !== expect.network) {\n throw new ChallengeTemplateError(`Challenge is for network \"${network}\", expected \"${expect.network}\"`);\n }\n\n const issuedAt = parseTimestamp(requireField(fields, 'issuedAt'), 'issuedAt');\n const expiresAt = parseTimestamp(requireField(fields, 'expiresAt'), 'expiresAt');\n\n // Server timestamps only — no device-clock comparison (#662).\n if (expiresAt <= issuedAt || expiresAt - issuedAt > MAX_VALIDITY_WINDOW_MS) {\n throw new ChallengeTemplateError('Challenge validity window is implausible');\n }\n}\n","// §5.1 WalletApiSession: auth generation-cell, single-flight refresh,\n// challenge-template verification, wake-socket supervisor, epoch latch.\n\nimport { STORE_KEYS, type ScopedKV } from '../../modules/payments-v2/stores';\nimport { verifyChallengeTemplate } from '../../core/wallet-api-protocol';\nimport { WalletApiHttpError } from './http';\nimport type { AuthTokensWire, WalletApiV2Client } from './client';\n\n// The spend key never signs unverified server text (S1/§4) — the canonical\n// verifier is the ONE source; re-exported so existing importers keep working.\nexport {\n AUTH_CHALLENGE_PREFIX,\n ChallengeTemplateError,\n verifyChallengeTemplate,\n type ChallengeExpectation,\n} from '../../core/wallet-api-protocol';\n\n/**\n * The JWT generation cell (#692 F8/F14). Every write is a compare-and-swap on\n * a generation captured at operation start — the CAS lives INSIDE the setter,\n * so a continuation returning from an await can never clobber a newer session.\n */\nexport class JwtGenerationCell {\n private gen = 0;\n private jwt: string | null = null;\n\n get generation(): number {\n return this.gen;\n }\n\n token(): string | null {\n return this.jwt;\n }\n\n install(generation: number, jwt: string): boolean {\n if (generation !== this.gen) return false;\n this.jwt = jwt;\n return true;\n }\n\n /** authGone(G) is a no-op when the cell moved to G+1 (F14). */\n clearIfCurrent(generation: number): boolean {\n if (generation !== this.gen || this.jwt === null) return false;\n this.jwt = null;\n return true;\n }\n\n dropIfMatches(generation: number, jwt: string): void {\n if (generation === this.gen && this.jwt === jwt) this.jwt = null;\n }\n\n bump(): number {\n this.gen += 1;\n this.jwt = null;\n return this.gen;\n }\n}\n\nexport type WakeStream = 'inventory' | 'mailbox' | 'payment_requests';\nexport const WAKE_STREAMS: readonly WakeStream[] = ['inventory', 'mailbox', 'payment_requests'];\n\nexport type ConnectionStatus = 'connected' | 'degraded' | 'offline';\n\nexport interface SessionSigner {\n readonly pubkey: string;\n readonly network: string;\n sign(message: string): string | Promise<string>;\n}\n\nexport interface WebSocketLike {\n onopen: (() => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n onclose: ((ev: { code?: number }) => void) | null;\n onerror: ((err: unknown) => void) | null;\n close(code?: number, reason?: string): void;\n}\n\nexport type WebSocketFactory = (url: string) => WebSocketLike;\n\nexport interface SessionTimers {\n setTimeout(cb: () => void, ms: number): unknown;\n clearTimeout(handle: unknown): void;\n setInterval(cb: () => void, ms: number): unknown;\n clearInterval(handle: unknown): void;\n}\n\nexport interface SessionTiming {\n pullIntervalMs: number;\n reconnectBaseMs: number;\n reconnectCapMs: number;\n heartbeatTimeoutMs: number;\n offlineAfterFailures: number;\n}\n\nexport const DEFAULT_SESSION_TIMING: SessionTiming = {\n pullIntervalMs: 30_000,\n reconnectBaseMs: 1_000,\n reconnectCapMs: 30_000,\n heartbeatTimeoutMs: 120_000,\n offlineAfterFailures: 3,\n};\n\nexport interface WalletApiSessionDeps {\n client: WalletApiV2Client;\n cell: JwtGenerationCell;\n signer: SessionSigner;\n deviceId: string;\n kv: ScopedKV;\n webSocketFactory: WebSocketFactory;\n emitStatus: (status: ConnectionStatus) => void;\n timing?: Partial<SessionTiming>;\n timers?: SessionTimers;\n random?: () => number;\n}\n\nexport function refreshTokenKey(deviceId: string): string {\n return `auth:refresh:${deviceId}`;\n}\n\nconst WS_CLOSE_AUTH_GONE = 4401;\n\ninterface WakeFrame {\n stream: WakeStream;\n syncEpoch: string;\n}\n\nfunction parseWakeFrame(data: unknown): WakeFrame | null {\n if (typeof data !== 'string') return null;\n let json: unknown;\n try {\n json = JSON.parse(data);\n } catch {\n return null;\n }\n const frame = json as { type?: unknown; stream?: unknown; syncEpoch?: unknown };\n if (frame.type !== 'wake') return null;\n if (!WAKE_STREAMS.includes(frame.stream as WakeStream)) return null;\n if (typeof frame.syncEpoch !== 'number' && typeof frame.syncEpoch !== 'string') return null;\n return { stream: frame.stream as WakeStream, syncEpoch: String(frame.syncEpoch) };\n}\n\nconst GLOBAL_TIMERS: SessionTimers = {\n setTimeout: (cb, ms) => setTimeout(cb, ms),\n clearTimeout: (h) => clearTimeout(h as Parameters<typeof clearTimeout>[0]),\n setInterval: (cb, ms) => setInterval(cb, ms),\n clearInterval: (h) => clearInterval(h as Parameters<typeof clearInterval>[0]),\n};\n\nexport class WalletApiSession {\n private readonly timing: SessionTiming;\n private readonly timers: SessionTimers;\n private readonly random: () => number;\n private readonly refreshKey: string;\n\n private authFlight: Promise<void> | null = null;\n\n private epochLatch: string | null = null;\n private reseedChain: Promise<void> = Promise.resolve();\n private reseedsPending = 0;\n private readonly epochHandlers = new Set<(epoch: string) => Promise<void>>();\n\n private readonly handlers = new Map<WakeStream, Set<() => void>>();\n private readonly statusHandlers = new Set<(status: ConnectionStatus) => void>();\n private socket: WebSocketLike | null = null;\n private started = false;\n private stopped = false;\n private reconnectAttempts = 0;\n private reconnectTimer: unknown = null;\n private heartbeatTimer: unknown = null;\n private pullTimers: unknown[] = [];\n private lastStatus: ConnectionStatus | null = null;\n\n constructor(private readonly deps: WalletApiSessionDeps) {\n this.timing = { ...DEFAULT_SESSION_TIMING, ...deps.timing };\n this.timers = deps.timers ?? GLOBAL_TIMERS;\n this.random = deps.random ?? Math.random;\n this.refreshKey = refreshTokenKey(deps.deviceId);\n }\n\n // ── lifecycle ─────────────────────────────────────────────────────────────\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n this.epochLatch = await this.deps.kv.get<string>(STORE_KEYS.epochLatch);\n this.startPullTimers();\n void this.connect();\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n for (const t of this.pullTimers) this.timers.clearInterval(t);\n this.pullTimers = [];\n if (this.reconnectTimer !== null) this.timers.clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n this.clearHeartbeat();\n const ws = this.socket;\n this.socket = null;\n ws?.close();\n await this.reseedChain;\n }\n\n // ── auth cell (F8/F14) ────────────────────────────────────────────────────\n\n token(): string | null {\n return this.deps.cell.token();\n }\n\n /** Identity switch / lock / logout: supersede every in-flight auth continuation. */\n invalidate(): void {\n this.deps.cell.bump();\n this.authFlight = null;\n }\n\n async ensureAuthenticated(): Promise<string> {\n const existing = this.deps.cell.token();\n if (existing !== null) return existing;\n await this.runAuthSingleFlight();\n const fresh = this.deps.cell.token();\n if (fresh === null) {\n throw new WalletApiHttpError(401, 'AUTH_SUPERSEDED', 'authentication superseded before completion');\n }\n return fresh;\n }\n\n /** Run an authenticated op; one 401 → single-flight re-auth → one retry. */\n async withAuth<T>(op: (jwt: string) => Promise<T>): Promise<T> {\n const jwt = await this.ensureAuthenticated();\n const generation = this.deps.cell.generation;\n try {\n return await op(jwt);\n } catch (err) {\n if (!(err instanceof WalletApiHttpError && err.status === 401)) throw err;\n this.deps.cell.dropIfMatches(generation, jwt);\n return op(await this.ensureAuthenticated());\n }\n }\n\n private runAuthSingleFlight(): Promise<void> {\n if (this.authFlight !== null) return this.authFlight;\n const generation = this.deps.cell.generation;\n const flight = this.authenticate(generation).finally(() => {\n if (this.authFlight === flight) this.authFlight = null;\n });\n this.authFlight = flight;\n return flight;\n }\n\n private async authenticate(generation: number): Promise<void> {\n if (await this.tryRefresh(generation)) return;\n if (this.deps.cell.generation !== generation) return;\n await this.challengeSignIn(generation);\n }\n\n private async tryRefresh(generation: number): Promise<boolean> {\n const stored = await this.deps.kv.get<string>(this.refreshKey);\n if (stored === null) return false;\n let tokens: AuthTokensWire;\n try {\n tokens = await this.deps.client.authRefresh(stored);\n } catch (err) {\n if (err instanceof WalletApiHttpError && err.status >= 400 && err.status < 500) {\n if (this.deps.cell.generation === generation) await this.deps.kv.remove(this.refreshKey);\n return false;\n }\n throw err;\n }\n if (!this.deps.cell.install(generation, tokens.jwt)) return true;\n await this.deps.kv.set(this.refreshKey, tokens.refreshToken);\n return true;\n }\n\n private async challengeSignIn(generation: number): Promise<void> {\n const { pubkey, network } = this.deps.signer;\n const { nonce, challenge } = await this.deps.client.authChallenge(pubkey);\n verifyChallengeTemplate(challenge, { pubkey, nonce, network });\n const signature = await this.deps.signer.sign(challenge);\n const tokens = await this.deps.client.authVerify({ nonce, signature, deviceId: this.deps.deviceId });\n if (!this.deps.cell.install(generation, tokens.jwt)) return;\n await this.deps.kv.set(this.refreshKey, tokens.refreshToken);\n }\n\n // ── epoch latch (F12) ─────────────────────────────────────────────────────\n\n /** §5.1: the latched server syncEpoch ('' before first server contact). */\n currentEpoch(): string {\n return this.epochLatch ?? '';\n }\n\n /**\n * §5.1 restore hook (FacadeSession contract): handlers are AWAITED inside\n * the reseed chain, BEFORE any stream nudge resumes.\n */\n subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void {\n this.epochHandlers.add(handler);\n return () => this.epochHandlers.delete(handler);\n }\n\n noteEpoch(epoch: string): void {\n if (this.epochLatch === epoch) return;\n const previous = this.epochLatch;\n this.epochLatch = epoch;\n if (previous === null) {\n void this.deps.kv.set(STORE_KEYS.epochLatch, epoch).catch(() => undefined);\n return;\n }\n this.reseedsPending += 1;\n this.reseedChain = this.reseedChain.then(() => this.runReseed(epoch, previous));\n }\n\n private async runReseed(epoch: string, previous: string): Promise<void> {\n try {\n for (const handler of [...this.epochHandlers]) await handler(epoch);\n await this.deps.kv.set(STORE_KEYS.epochLatch, epoch);\n } catch {\n if (this.epochLatch === epoch) this.epochLatch = previous;\n } finally {\n this.reseedsPending -= 1;\n if (this.reseedsPending === 0) this.nudgeAllStreams();\n }\n }\n\n // ── streams ───────────────────────────────────────────────────────────────\n\n subscribeStream(stream: WakeStream, handler: () => void): () => void {\n let set = this.handlers.get(stream);\n if (!set) {\n set = new Set();\n this.handlers.set(stream, set);\n }\n set.add(handler);\n return () => set.delete(handler);\n }\n\n private dispatch(stream: WakeStream): void {\n if (this.reseedsPending > 0) return;\n const set = this.handlers.get(stream);\n if (!set) return;\n for (const handler of set) handler();\n }\n\n private nudgeAllStreams(): void {\n for (const stream of WAKE_STREAMS) this.dispatch(stream);\n }\n\n private startPullTimers(): void {\n for (const stream of WAKE_STREAMS) {\n this.pullTimers.push(this.timers.setInterval(() => this.dispatch(stream), this.timing.pullIntervalMs));\n }\n }\n\n // ── wake socket ───────────────────────────────────────────────────────────\n\n status(): ConnectionStatus {\n return this.lastStatus ?? 'offline';\n }\n\n /** Transition feed off the existing emitStatus point (FacadeSession.subscribeStatus). */\n subscribeStatus(handler: (status: ConnectionStatus) => void): () => void {\n this.statusHandlers.add(handler);\n return () => this.statusHandlers.delete(handler);\n }\n\n private emitStatus(status: ConnectionStatus): void {\n if (this.stopped || this.lastStatus === status) return;\n this.lastStatus = status;\n this.deps.emitStatus(status);\n for (const handler of this.statusHandlers) handler(status);\n }\n\n private async connect(): Promise<void> {\n if (this.stopped) return;\n try {\n const ticket = await this.withAuth(() => this.deps.client.wsTicket());\n if (this.stopped) return;\n this.openSocket(ticket, this.deps.cell.generation);\n } catch {\n this.scheduleReconnect();\n }\n }\n\n private openSocket(ticket: string, generation: number): void {\n const wsBase = this.deps.client.baseUrl.replace(/^http/, 'ws');\n const ws = this.deps.webSocketFactory(`${wsBase}/v1/ws?ticket=${encodeURIComponent(ticket)}`);\n this.socket = ws;\n ws.onopen = () => this.handleOpen(ws);\n ws.onmessage = (ev) => this.handleMessage(ws, ev.data);\n ws.onclose = (ev) => this.handleClose(ws, generation, ev?.code);\n ws.onerror = () => undefined;\n }\n\n private handleOpen(ws: WebSocketLike): void {\n if (ws !== this.socket) return;\n this.reconnectAttempts = 0;\n this.emitStatus('connected');\n this.armHeartbeat(ws);\n // Wakes before this instant are lost — one synthetic nudge per stream.\n this.nudgeAllStreams();\n }\n\n private handleMessage(ws: WebSocketLike, data: unknown): void {\n if (ws !== this.socket) return;\n this.armHeartbeat(ws);\n const frame = parseWakeFrame(data);\n if (frame === null) return;\n this.noteEpoch(frame.syncEpoch);\n this.dispatch(frame.stream);\n }\n\n private handleClose(ws: WebSocketLike, generation: number, code?: number): void {\n if (ws !== this.socket) return;\n this.socket = null;\n this.clearHeartbeat();\n if (this.stopped) return;\n if (code === WS_CLOSE_AUTH_GONE) {\n // CAS inside the cell: a stale socket's auth-gone never clears a newer JWT (F14).\n this.deps.cell.clearIfCurrent(generation);\n this.emitStatus('degraded');\n void this.connect();\n return;\n }\n this.scheduleReconnect();\n }\n\n private scheduleReconnect(): void {\n if (this.stopped) return;\n this.reconnectAttempts += 1;\n this.emitStatus(this.reconnectAttempts >= this.timing.offlineAfterFailures ? 'offline' : 'degraded');\n const capped = Math.min(\n this.timing.reconnectCapMs,\n this.timing.reconnectBaseMs * 2 ** (this.reconnectAttempts - 1)\n );\n const delay = Math.floor(this.random() * capped);\n this.reconnectTimer = this.timers.setTimeout(() => void this.connect(), delay);\n }\n\n private armHeartbeat(ws: WebSocketLike): void {\n this.clearHeartbeat();\n this.heartbeatTimer = this.timers.setTimeout(() => {\n if (ws === this.socket) ws.close();\n }, this.timing.heartbeatTimeoutMs);\n }\n\n private clearHeartbeat(): void {\n if (this.heartbeatTimer !== null) this.timers.clearTimeout(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n}\n","// P3b: WalletApiStoragePort — thin StoragePort over the §16 client\n// (InventoryView owns the mirror; this file owns wire mapping + fan-out only).\n\nimport type { ApplyDeltaResult, InventoryPage, StoragePort } from '../../modules/payments-v2/ports';\nimport { isWalletApiHttpError } from './http';\nimport type { WalletApiV2Client } from './client';\n\nexport const WALLET_API_V2_FANOUT_WIDTH = 8;\n\n/**\n * Unique ids per blob-urls request. wallet-api answers more than its PAGE_LIMIT\n * (1000 by default, set per deployment) with 429 QUOTA_EXCEEDED, and a small batch\n * keeps each presigned GET well inside its TTL.\n */\nexport const WALLET_API_V2_BLOB_URLS_BATCH = 100;\n\nexport type StoragePortClient = Pick<\n WalletApiV2Client,\n 'listInventory' | 'blobUrls' | 'uploadUrls' | 'apply' | 'fetchBlob' | 'uploadBlob'\n>;\n\n/** The presigned-upload protocol step shared by storage and delivery (§5.6). */\nexport type PresignedUploadClient = Pick<WalletApiV2Client, 'uploadUrls' | 'uploadBlob'>;\n\n/** 409 on applyDelta: the server refused the delta on lineage grounds. */\nexport class DeltaConflictError extends Error {\n readonly code = 'DELTA_CONFLICT';\n constructor(message: string, readonly cause?: unknown) {\n super(message);\n this.name = 'DeltaConflictError';\n }\n}\n\n/** 422 on applyDelta: the delta itself is invalid (bad blob, unknown spend, …). */\nexport class DeltaValidationError extends Error {\n readonly code = 'DELTA_VALIDATION';\n constructor(message: string, readonly cause?: unknown) {\n super(message);\n this.name = 'DeltaValidationError';\n }\n}\n\nexport class StoragePortProtocolError extends Error {\n readonly code = 'PROTOCOL';\n constructor(message: string) {\n super(message);\n this.name = 'StoragePortProtocolError';\n }\n}\n\n/** Bounded-parallel map: at most `width` in flight; stops claiming new work after a failure. */\nexport async function mapBounded<T, R>(\n items: readonly T[],\n width: number,\n fn: (item: T, index: number) => Promise<R>\n): Promise<R[]> {\n const out = new Array<R>(items.length);\n let next = 0;\n let failed = false;\n const worker = async (): Promise<void> => {\n for (;;) {\n if (failed) return;\n const index = next;\n next += 1;\n if (index >= items.length) return;\n try {\n out[index] = await fn(items[index] as T, index);\n } catch (err) {\n failed = true;\n throw err;\n }\n }\n };\n const workers = Array.from({ length: Math.max(1, Math.min(width, items.length)) }, worker);\n await Promise.all(workers);\n return out;\n}\n\n/** upload-urls → bounded PUTs → sha256→key map (S3 412 = exists = success). */\nexport async function uploadViaPresigned(\n client: PresignedUploadClient,\n blobs: readonly { sha256: string; bytes: Uint8Array }[]\n): Promise<Map<string, string>> {\n if (blobs.length === 0) return new Map();\n const urls = await client.uploadUrls(blobs.map((b) => ({ sha256: b.sha256, size: b.bytes.length })));\n const urlBySha = new Map(urls.map((u) => [u.sha256, u]));\n const uploads = blobs.map((blob) => {\n const url = urlBySha.get(blob.sha256);\n if (url === undefined) {\n throw new StoragePortProtocolError(`upload-urls response missing sha256 ${blob.sha256}`);\n }\n return { blob, url };\n });\n await mapBounded(uploads, WALLET_API_V2_FANOUT_WIDTH, ({ blob, url }) =>\n client.uploadBlob(url.putUrl, blob.bytes)\n );\n return new Map(uploads.map(({ blob, url }) => [blob.sha256, url.key]));\n}\n\nexport class WalletApiStoragePort implements StoragePort {\n constructor(private readonly client: StoragePortClient) {}\n\n async listInventory(since?: number): Promise<InventoryPage> {\n const page = await this.client.listInventory(since);\n return {\n cursor: page.cursor,\n syncEpoch: String(page.syncEpoch),\n more: page.more,\n items: page.items,\n };\n }\n\n /** One blob-urls request per batch of unique ids, each batch fetched before the next is presigned. */\n async getBlobs(tokenIds: string[]): Promise<Map<string, Uint8Array>> {\n const unique = [...new Set(tokenIds)];\n const result = new Map<string, Uint8Array>();\n for (let start = 0; start < unique.length; start += WALLET_API_V2_BLOB_URLS_BATCH) {\n const urls = await this.client.blobUrls(unique.slice(start, start + WALLET_API_V2_BLOB_URLS_BATCH));\n const bytes = await mapBounded(urls, WALLET_API_V2_FANOUT_WIDTH, (u) => this.client.fetchBlob(u.getUrl));\n for (const [i, url] of urls.entries()) {\n const blob = bytes[i];\n if (blob !== undefined) result.set(url.tokenId, blob);\n }\n }\n return result;\n }\n\n uploadBlobs(blobs: { sha256: string; bytes: Uint8Array }[]): Promise<Map<string, string>> {\n return uploadViaPresigned(this.client, blobs);\n }\n\n async applyDelta(delta: {\n transferId: string;\n spent: string[];\n added: { tokenId: string; key: string }[];\n }): Promise<ApplyDeltaResult> {\n try {\n const result = await this.client.apply(delta);\n return { cursor: result.cursor, syncEpoch: String(result.syncEpoch) };\n } catch (err) {\n if (isWalletApiHttpError(err, 409)) throw new DeltaConflictError(err.message, err);\n if (isWalletApiHttpError(err, 422)) throw new DeltaValidationError(err.message, err);\n throw err;\n }\n }\n}\n","// Shared concurrency primitives. Both advance on SETTLED, never fulfilled —\n// a rejection never bricks the next run (async.test.ts pins the recovery).\n\nexport class SingleFlight<T> {\n private flight: Promise<T> | null = null;\n\n run(fn: () => Promise<T>): Promise<T> {\n if (this.flight !== null) return this.flight;\n const current = fn().finally(() => {\n this.flight = null;\n });\n this.flight = current;\n return current;\n }\n}\n\nexport class SerialChain {\n private tail: Promise<unknown> = Promise.resolve();\n\n /** FIFO; starts after every prior fn settled; returns this fn's own outcome. */\n enqueue<T>(fn: () => Promise<T>): Promise<T> {\n const run = this.tail.then(fn, fn);\n this.tail = run.then(\n () => undefined,\n () => undefined\n );\n return run;\n }\n}\n\n/** Fire-and-forget sibling of {@link SingleFlight}: one in flight, one queued behind it. */\nexport function coalesced(\n run: () => Promise<unknown>,\n observe?: (op: Promise<unknown>) => void\n): () => void {\n let inFlight = false;\n let queued = false;\n const start = (): void => {\n inFlight = true;\n // A synchronous throw would escape before .catch attaches and strand\n // inFlight, wedging every later trigger. Started eagerly, not on a\n // microtask, so a caller can rely on the first run having begun.\n let running: Promise<unknown>;\n try {\n running = run();\n } catch {\n running = Promise.resolve();\n }\n observe?.(running);\n void running\n .catch(() => undefined)\n .finally(() => {\n inFlight = false;\n if (!queued) return;\n queued = false;\n start();\n });\n };\n return () => {\n if (inFlight) {\n queued = true;\n return;\n }\n start();\n };\n}\n","/**\n * HKDF (RFC 5869): extract + expand in one step.\n * See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}.\n * @module\n */\nimport { hmac } from './hmac.ts';\nimport { abytes, ahash, anumber, type CHash, clean, type TArg, type TRet } from './utils.ts';\n\n/**\n * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK`\n * Arguments position differs from spec (IKM is first one, since it is not optional)\n * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`.\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @returns Pseudorandom key derived from input keying material.\n * @example\n * Run the HKDF extract step.\n * ```ts\n * import { extract } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\nexport function extract(\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n ahash(hash);\n // NOTE: some libraries treat zero-length array as 'not provided';\n // we don't, since we have undefined as 'not provided'\n // https://github.com/RustCrypto/KDFs/issues/15\n if (salt === undefined) salt = new Uint8Array(hash.outputLen);\n return hmac(hash, salt, ikm);\n}\n\n// Shared mutable scratch byte for the RFC 5869 block counter `N`.\n// Safe to reuse because `expand()` is synchronous and resets it with `clean(...)` before returning.\nconst HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);\n// Shared RFC 5869 empty string for both `info === undefined` and the first-block `T(0)` input.\nconst EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();\n\n/**\n * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM`\n * @param hash - hash function that would be used (e.g. sha256)\n * @param prk - a pseudorandom key of at least HashLen octets\n * (usually, the output from the extract step)\n * @param info - optional context and application specific information (can be a zero-length string)\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material with the requested length.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * Run the HKDF expand step.\n * ```ts\n * import { expand } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16);\n * ```\n */\nexport function expand(\n hash: TArg<CHash>,\n prk: TArg<Uint8Array>,\n info?: TArg<Uint8Array>,\n length: number = 32\n): TRet<Uint8Array> {\n ahash(hash);\n anumber(length, 'length');\n abytes(prk, undefined, 'prk');\n const olen = hash.outputLen;\n // RFC 5869 §2.3: PRK is \"a pseudorandom key of at least HashLen octets\".\n if (prk.length < olen) throw new Error('\"prk\" must be at least HashLen octets');\n // RFC 5869 §2.3 only bounds `L` by `<= 255*HashLen`; `L=0` is valid and yields empty OKM.\n if (length > 255 * olen) throw new Error('Length must be <= 255*HashLen');\n const blocks = Math.ceil(length / olen);\n if (info === undefined) info = EMPTY_BUFFER;\n else abytes(info, undefined, 'info');\n // first L(ength) octets of T\n const okm = new Uint8Array(blocks * olen);\n // Re-use HMAC instance between blocks\n const HMAC = hmac.create(hash, prk);\n const HMACTmp = HMAC._cloneInto();\n const T = new Uint8Array(HMAC.outputLen);\n for (let counter = 0; counter < blocks; counter++) {\n HKDF_COUNTER[0] = counter + 1;\n // T(0) = empty string (zero length)\n // T(N) = HMAC-Hash(PRK, T(N-1) | info | N)\n HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T)\n .update(info)\n .update(HKDF_COUNTER)\n .digestInto(T);\n okm.set(T, olen * counter);\n HMAC._cloneInto(HMACTmp);\n }\n HMAC.destroy();\n HMACTmp.destroy();\n clean(T, HKDF_COUNTER);\n return okm.slice(0, length) as TRet<Uint8Array>;\n}\n\n/**\n * HKDF (RFC 5869): derive keys from an initial input.\n * Combines hkdf_extract + hkdf_expand in one step\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @param info - optional context and application specific information bytes\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material derived from the input key.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * HKDF (RFC 5869): derive keys from an initial input.\n * ```ts\n * import { hkdf } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';\n * const inputKey = randomBytes(32);\n * const salt = randomBytes(32);\n * const info = utf8ToBytes('application-key');\n * const okm = hkdf(sha256, inputKey, salt, info, 32);\n * ```\n */\nexport const hkdf = (\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt: TArg<Uint8Array | undefined>,\n info: TArg<Uint8Array | undefined>,\n length: number\n): TRet<Uint8Array> => expand(hash, extract(hash, ikm, salt), info, length);\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */\n\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n\n/**\n * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.\n * @param a - Value to inspect.\n * @returns `true` when the value is a Uint8Array view, including Node's `Buffer`.\n * @example\n * Guards a value before treating it as raw key material.\n *\n * ```ts\n * isBytes(new Uint8Array());\n * ```\n */\nexport function isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy /\n // cross-realm cases. The fallback still requires a real ArrayBuffer view\n // so plain JSON-deserialized `{ constructor: ... }`\n // spoofing is rejected, and `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n\n/**\n * Asserts something is boolean.\n * @param b - Value to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validates a boolean option before branching on it.\n *\n * ```ts\n * abool(true);\n * ```\n */\nexport function abool(b: boolean): void {\n if (typeof b !== 'boolean') throw new TypeError(`boolean expected, not ${b}`);\n}\n\n/**\n * Asserts something is a non-negative safe integer.\n * @param n - Value to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validates a non-negative length or counter.\n *\n * ```ts\n * anumber(1);\n * ```\n */\nexport function anumber(n: number): void {\n if (typeof n !== 'number') throw new TypeError('number expected, got ' + typeof n);\n if (!Number.isSafeInteger(n) || n < 0)\n throw new RangeError('positive integer expected, got ' + n);\n}\n\n/**\n * Asserts something is Uint8Array.\n * @param value - Value to validate.\n * @param length - Expected byte length.\n * @param title - Optional label used in error messages.\n * @returns The validated byte array.\n * On Node, `Buffer` is accepted too because it is a Uint8Array view.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument lengths. {@link RangeError}\n * @example\n * Validates a fixed-length nonce or key buffer.\n *\n * ```ts\n * abytes(new Uint8Array([1, 2]), 2);\n * ```\n */\nexport function abytes(\n value: TArg<Uint8Array>,\n length?: number,\n title: string = ''\n): TRet<Uint8Array> {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n if (!bytes) throw new TypeError(message);\n throw new RangeError(message);\n }\n return value as TRet<Uint8Array>;\n}\n\n/**\n * Asserts a hash- or MAC-like instance has not been destroyed or finished.\n * @param instance - Stateful instance to validate.\n * @param checkFinished - Whether to reject finished instances.\n * When `false`, only `destroyed` is checked.\n * @throws If the hash instance has already been destroyed or finalized. {@link Error}\n * @example\n * Guards against calling `update()` or `digest()` on a finished hash.\n *\n * ```ts\n * aexists({ destroyed: false, finished: false });\n * ```\n */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/**\n * Asserts output is a properly-sized byte array.\n * @param out - Output buffer to validate.\n * @param instance - Hash-like instance providing `outputLen`.\n * This is the relaxed `digestInto()`-style contract: output must be at least `outputLen`,\n * unlike one-shot cipher helpers elsewhere in the repo that often require exact lengths.\n * @throws On wrong argument types. {@link TypeError}\n * @param onlyAligned - Whether `out` must be 4-byte aligned for zero-allocation word views.\n * @throws On wrong output buffer lengths. {@link RangeError}\n * @throws On wrong output buffer alignment. {@link Error}\n * @example\n * Verifies that a caller-provided output buffer is large enough.\n *\n * ```ts\n * aoutput(new Uint8Array(16), { outputLen: 16 });\n * ```\n */\nexport function aoutput(out: any, instance: any, onlyAligned = false): void {\n abytes(out, undefined, 'output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new RangeError('digestInto() expects output buffer of length at least ' + min);\n }\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n}\n\n/** One-shot hash helper with `.create()`. */\nexport type IHash = {\n (data: string | TArg<Uint8Array>): TRet<Uint8Array>;\n /** Input block size in bytes. */\n blockLen: number;\n /** Digest size in bytes. */\n outputLen: number;\n /** Creates a fresh incremental hash instance of the same algorithm. */\n create: any;\n};\n\n/** One-shot MAC helper with `.create()`. */\nexport type CMac<H extends IHash2 = IHash2, A extends any[] = []> = {\n (msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array>;\n /** Input block size in bytes. */\n blockLen: number;\n /** Digest size in bytes. */\n outputLen: number;\n /**\n * Creates a fresh incremental MAC instance of the same algorithm.\n * @param key - MAC key bytes.\n * @param args - Additional constructor arguments, when the MAC wrapper needs them.\n * @returns Fresh incremental MAC instance.\n */\n create(key: TArg<Uint8Array>, ...args: A): H;\n};\n\n/** Generic type encompassing 8/16/32-bit typed arrays, but not 64-bit. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/**\n * Casts a typed-array view to Uint8Array.\n * @param arr - Typed-array view to reinterpret.\n * @returns Uint8Array view over the same bytes.\n * @example\n * Views 32-bit words as raw bytes without copying.\n *\n * ```ts\n * u8(new Uint32Array([1]));\n * ```\n */\nexport function u8(arr: TArg<TypedArray>): TRet<Uint8Array> {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet<Uint8Array>;\n}\n\n/**\n * Casts a typed-array view to Uint32Array.\n * @param arr - Typed-array view to reinterpret.\n * @returns Uint32Array view over the same bytes. Callers are expected to provide a\n * 4-byte-aligned offset; trailing `1..3` bytes are silently dropped.\n * @example\n * Views a byte buffer as 32-bit words for block processing.\n *\n * ```ts\n * u32(new Uint8Array(4));\n * ```\n */\nexport function u32(arr: TArg<TypedArray>): TRet<Uint32Array> {\n return new Uint32Array(\n arr.buffer,\n arr.byteOffset,\n Math.floor(arr.byteLength / 4)\n ) as TRet<Uint32Array>;\n}\n\n/**\n * Zeroizes typed arrays in place.\n * Warning: JS provides no guarantees.\n * @param arrays - Arrays to wipe.\n * @example\n * Wipes a temporary key buffer after use.\n *\n * ```ts\n * const bytes = new Uint8Array([1]);\n * clean(bytes);\n * ```\n */\nexport function clean(...arrays: TArg<TypedArray[]>): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/**\n * Creates a DataView for byte-level manipulation.\n * @param arr - Typed-array view to wrap.\n * @returns DataView over the same bytes.\n * @example\n * Creates an endian-aware view for length encoding.\n *\n * ```ts\n * createView(new Uint8Array(4));\n * ```\n */\nexport function createView(arr: TArg<TypedArray>): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Whether the current platform is little-endian.\n * Most are; some IBM systems are not.\n */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/**\n * Reverses byte order of one 32-bit word.\n * @param word - Unsigned 32-bit word to swap.\n * @returns The same word with bytes reversed.\n * @example\n * Swaps a big-endian word into little-endian byte order.\n *\n * ```ts\n * byteSwap(0x11223344);\n * ```\n */\nexport const byteSwap = (word: number): number =>\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff);\n\n/**\n * Normalizes one 32-bit word to the little-endian representation expected by cipher cores.\n * @param n - Unsigned 32-bit word to normalize.\n * @returns Little-endian normalized word on big-endian hosts, else the input word unchanged.\n * @example\n * Normalizes a host-endian word before passing it into an ARX/AES core.\n *\n * ```ts\n * swap8IfBE(0x11223344);\n * ```\n */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n) >>> 0;\n\n/**\n * Byte-swaps every word of a Uint32Array in place.\n * @param arr - Uint32Array whose words should be swapped.\n * @returns The same array after in-place byte swapping.\n * @example\n * Swaps every 32-bit word in a word-view buffer.\n *\n * ```ts\n * byteSwap32(new Uint32Array([0x11223344]));\n * ```\n */\nexport const byteSwap32 = (arr: TArg<Uint32Array>): TRet<Uint32Array> => {\n for (let i = 0; i < arr.length; i++) arr[i] = byteSwap(arr[i]);\n return arr as TRet<Uint32Array>;\n};\n\n/**\n * Normalizes a Uint32Array view to the little-endian representation expected by cipher cores.\n * @param u - Word view to normalize in place.\n * @returns Little-endian normalized word view.\n * @example\n * Normalizes a word-view buffer before block processing.\n *\n * ```ts\n * swap32IfBE(new Uint32Array([0x11223344]));\n * ```\n */\nexport const swap32IfBE: (u: TArg<Uint32Array>) => TRet<Uint32Array> = isLE\n ? (u: TArg<Uint32Array>) => u as TRet<Uint32Array>\n : byteSwap32;\n\n// Built-in hex conversion:\n// {@link https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex | caniuse entry}\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @param bytes - Bytes to encode.\n * @returns Lowercase hexadecimal string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Formats ciphertext bytes for logs or test vectors.\n *\n * ```ts\n * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'\n * ```\n */\nexport function bytesToHex(bytes: TArg<Uint8Array>): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @param hex - Hexadecimal string to decode.\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On malformed hexadecimal input. {@link RangeError}\n * @example\n * Parses a hex test vector into bytes.\n *\n * ```ts\n * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n * ```\n */\nexport function hexToBytes(hex: string): TRet<Uint8Array> {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n if (hasHexBuiltin) {\n try {\n return (Uint8Array as any).fromHex(hex);\n } catch (error) {\n if (error instanceof SyntaxError) throw new RangeError(error.message);\n throw error;\n }\n }\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new RangeError(\n 'hex string expected, got non-hex character \"' + char + '\" at index ' + hi\n );\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array as TRet<Uint8Array>;\n}\n\n// Used in micro\n/**\n * Converts a big-endian hex string into bigint.\n * @param hex - Hexadecimal string without `0x`.\n * @returns Parsed bigint value. The empty string is treated as `0n`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Parses a big-endian field element or counter from hex.\n *\n * ```ts\n * hexToNumber('ff');\n * ```\n */\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian\n}\n\n// Used in ff1\n// BE: Big Endian, LE: Little Endian\n/**\n * Converts big-endian bytes into bigint.\n * @param bytes - Big-endian bytes.\n * @returns Parsed bigint value. Empty input is treated as `0n`.\n * @throws On invalid byte input passed to the internal hex conversion. {@link TypeError}\n * @example\n * Reads a big-endian integer from serialized bytes.\n *\n * ```ts\n * bytesToNumberBE(new Uint8Array([1, 0]));\n * ```\n */\nexport function bytesToNumberBE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\n\n// Used in micro, ff1\n/**\n * Converts a number into big-endian bytes of fixed length.\n * @param n - Number to encode.\n * @param len - Output length in bytes.\n * @returns Big-endian bytes padded to `len`.\n * Validation is indirect through `hexToBytes(...)`, so negative values, `len = 0`,\n * and values that do not fit surface through the downstream hex parser instead of a\n * dedicated range guard here.\n * @throws On wrong argument types. {@link TypeError}\n * @throws If the requested output length cannot represent the encoded value. {@link RangeError}\n * @example\n * Encodes a counter as fixed-width big-endian bytes.\n *\n * ```ts\n * numberToBytesBE(1, 2);\n * ```\n */\nexport function numberToBytesBE(n: number | bigint, len: number): TRet<Uint8Array> {\n // Reject coercible non-numeric inputs before string/hex conversion changes behavior.\n if (typeof n === 'number') anumber(n);\n else if (typeof n !== 'bigint') throw new TypeError(`number or bigint expected, got ${typeof n}`);\n anumber(len);\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\n\n// Global symbols, but ts doesn't see them:\n// {@link https://github.com/microsoft/TypeScript/issues/31535 | TypeScript issue 31535}\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @param str - String to encode.\n * @returns UTF-8 bytes in a detached fresh Uint8Array copy.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encodes application text before encryption or MACing.\n *\n * ```ts\n * utf8ToBytes('abc'); // new Uint8Array([97, 98, 99])\n * ```\n */\nexport function utf8ToBytes(str: string): TRet<Uint8Array> {\n if (typeof str !== 'string') throw new TypeError('string expected');\n return new Uint8Array(new TextEncoder().encode(str)) as TRet<Uint8Array>; // {@link https://bugzil.la/1681809 | Firefox bug 1681809}\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @param bytes - UTF-8 bytes.\n * @returns Decoded string. Input validation is delegated to `TextDecoder`, and malformed\n * UTF-8 is replacement-decoded instead of rejected.\n * @example\n * Decodes UTF-8 plaintext back into a string.\n *\n * ```ts\n * bytesToUtf8(new Uint8Array([97, 98, 99])); // 'abc'\n * ```\n */\nexport function bytesToUtf8(bytes: TArg<Uint8Array>): string {\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Checks if two U8A use same underlying buffer and overlaps.\n * This is invalid and can corrupt data.\n * @param a - First byte view.\n * @param b - Second byte view.\n * @returns `true` when the views overlap in memory.\n * @example\n * Detects whether two slices alias the same backing buffer.\n *\n * ```ts\n * overlapBytes(new Uint8Array(4), new Uint8Array(4));\n * ```\n */\nexport function overlapBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n // Zero-length views cannot overwrite anything, even if their offset sits inside another range.\n if (!a.byteLength || !b.byteLength) return false;\n return (\n a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy\n a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end\n b.byteOffset < a.byteOffset + a.byteLength // b starts before a end\n );\n}\n\n/**\n * If input and output overlap and input starts before output, we will overwrite end of input before\n * we start processing it, so this is not supported for most ciphers\n * (except chacha/salsa, which were designed for this)\n * @param input - Input bytes.\n * @param output - Output bytes.\n * @throws If the output view would overwrite unread input bytes. {@link Error}\n * @example\n * Rejects an in-place layout that would overwrite unread input bytes.\n *\n * ```ts\n * complexOverlapBytes(new Uint8Array(4), new Uint8Array(4));\n * ```\n */\nexport function complexOverlapBytes(input: TArg<Uint8Array>, output: TArg<Uint8Array>): void {\n // This is very cursed. It works somehow, but I'm completely unsure,\n // reasoning about overlapping aligned windows is very hard.\n if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)\n throw new Error('complex overlap of input and output is not supported');\n}\n\n/**\n * Copies several Uint8Arrays into one.\n * @param arrays - Byte arrays to concatenate.\n * @returns Combined byte array.\n * @throws On wrong argument types inside the byte-array list. {@link TypeError}\n * @example\n * Builds a `nonce || ciphertext` style buffer.\n *\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nexport function concatBytes(...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res as TRet<Uint8Array>;\n}\n\n// Used in ARX only\ntype EmptyObj = {};\n/**\n * Merges user options into defaults.\n * @param defaults - Default option values.\n * @param opts - User-provided overrides.\n * @returns Combined options object.\n * The merge mutates `defaults` in place and returns the same object.\n * @throws If options are missing or not an object. {@link Error}\n * @example\n * Applies user overrides to the default cipher options.\n *\n * ```ts\n * checkOpts({ rounds: 20 }, { rounds: 8 });\n * ```\n */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts: T2\n): T1 & T2 {\n if (opts == null || typeof opts !== 'object') throw new Error('options must be defined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/**\n * Compares two byte arrays in kinda constant time once lengths already match.\n * @param a - First byte array.\n * @param b - Second byte array.\n * @returns `true` when the arrays contain the same bytes. Different lengths still return early.\n * @example\n * Compares an expected authentication tag with the received one.\n *\n * ```ts\n * equalBytes(new Uint8Array([1]), new Uint8Array([1]));\n * ```\n */\nexport function equalBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n// TODO: remove\n/** Incremental hash interface used internally. */\nexport interface IHash2 {\n /** Bytes processed per compression block. */\n blockLen: number;\n /** Bytes produced by the final digest. */\n outputLen: number;\n /**\n * Absorbs one more chunk into the hash state.\n * @param buf - Data chunk to hash.\n * @returns The same hash instance for chaining.\n */\n update(buf: string | TArg<Uint8Array>): this;\n /**\n * Writes the final digest into a caller-provided buffer.\n * @param buf - Destination buffer for the digest bytes.\n * @returns Nothing. Implementations write into `buf` in place.\n */\n digestInto(buf: TArg<Uint8Array>): void;\n /**\n * Finalizes the hash and returns a fresh digest buffer.\n * @returns Digest bytes.\n */\n digest(): TRet<Uint8Array>;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n destroy(): void;\n}\n\n/**\n * Wraps a keyed MAC constructor into a one-shot helper with `.create()`.\n * @param keyLen - Valid probe-key length used to read static metadata once.\n * The probe key is only used for `outputLen` / `blockLen`, so callers with several valid key sizes\n * can pass any representative size as long as those values stay fixed.\n * @param macCons - Keyed MAC constructor or factory.\n * @param fromMsg - Optional adapter that derives extra constructor args from the one-shot message.\n * @returns Callable MAC helper with `.create()`.\n */\nexport function wrapMacConstructor<H extends IHash2, A extends any[] = []>(\n keyLen: number,\n macCons: TArg<(key: Uint8Array, ...args: A) => H>,\n fromMsg?: TArg<(msg: Uint8Array) => A>\n): TRet<CMac<H, A>> {\n const mac = macCons as (key: TArg<Uint8Array>, ...args: A) => H;\n const getArgs = (fromMsg || (() => [] as unknown as A)) as (msg: TArg<Uint8Array>) => A;\n const macC: any = (msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array> =>\n mac(key, ...getArgs(msg))\n .update(msg)\n .digest();\n const tmp = mac(new Uint8Array(keyLen), ...getArgs(new Uint8Array(0)));\n macC.outputLen = tmp.outputLen;\n macC.blockLen = tmp.blockLen;\n macC.create = (key: TArg<Uint8Array>, ...args: A) => mac(key, ...args);\n return macC as TRet<CMac<H, A>>;\n}\n\n// This will allow to re-use with composable things like packed & base encoders\n// Also, we probably can make tags composable\n\n/** Sync cipher: takes byte array and returns byte array. */\nexport type Cipher = {\n /**\n * Encrypts plaintext bytes.\n * @param plaintext - Data to encrypt.\n * @returns Ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>): TRet<Uint8Array>;\n /**\n * Decrypts ciphertext bytes.\n * @param ciphertext - Data to decrypt.\n * @returns Plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/** Async cipher e.g. from built-in WebCrypto. */\nexport type AsyncCipher = {\n /**\n * Encrypts plaintext bytes.\n * @param plaintext - Data to encrypt.\n * @returns Promise resolving to ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>): Promise<TRet<Uint8Array>>;\n /**\n * Decrypts ciphertext bytes.\n * @param ciphertext - Data to decrypt.\n * @returns Promise resolving to plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>): Promise<TRet<Uint8Array>>;\n};\n\n/** Cipher with `output` argument which can optimize by doing 1 less allocation. */\nexport type CipherWithOutput = Cipher & {\n /**\n * Encrypts plaintext bytes into an optional caller-provided buffer.\n * @param plaintext - Data to encrypt.\n * @param output - Optional destination buffer.\n * @returns Ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array>;\n /**\n * Decrypts ciphertext bytes into an optional caller-provided buffer.\n * @param ciphertext - Data to decrypt.\n * @param output - Optional destination buffer.\n * @returns Plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/**\n * Params are outside of return type, so it is accessible before calling constructor.\n * If function support multiple nonceLength's, we return the best one.\n */\nexport type CipherParams = {\n /** Cipher block size in bytes. */\n blockSize: number;\n /** Nonce length in bytes when the cipher uses a fixed nonce size. */\n nonceLength?: number;\n /** Authentication-tag length in bytes for AEAD modes. */\n tagLength?: number;\n /** Whether nonce length is variable at runtime. */\n varSizeNonce?: boolean;\n};\n/**\n * ARX AEAD cipher, like salsa or chacha.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param AAD - Optional associated data.\n * @returns Cipher instance with caller-managed output buffers.\n */\nexport type ARXCipher = ((\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n};\n/**\n * Cipher constructor signature.\n * @param key - Secret key bytes.\n * @param args - Additional constructor arguments, such as nonce or IV.\n * @returns Cipher instance.\n */\nexport type CipherCons<T extends any[]> = (key: TArg<Uint8Array>, ...args: T) => Cipher;\n/**\n * Wraps a cipher: validates args, ensures encrypt() can only be called once.\n * Used internally by the exported cipher constructors.\n * Output-buffer support is inferred from the wrapped `encrypt` / `decrypt`\n * arity (`fn.length === 2`), and tag-bearing constructors are expected to use\n * `args[1]` for optional AAD.\n * @__NO_SIDE_EFFECTS__\n * @param params - Static cipher metadata. See {@link CipherParams}.\n * @param constructor - Cipher constructor.\n * @returns Wrapped constructor with validation.\n */\nexport const wrapCipher = <C extends CipherCons<any>, P extends CipherParams>(\n params: P,\n constructor: C\n): C & P => {\n function wrappedCipher(key: TArg<Uint8Array>, ...args: any[]): TRet<CipherWithOutput> {\n // Validate key\n abytes(key, undefined, 'key');\n\n // Validate nonce if nonceLength is present\n if (params.nonceLength !== undefined) {\n const nonce = args[0];\n abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce');\n }\n\n // Validate AAD if tagLength present\n const tagl = params.tagLength;\n if (tagl && args[1] !== undefined) abytes(args[1], undefined, 'AAD');\n\n const cipher = constructor(key, ...args);\n const checkOutput = (fnLength: number, output?: TArg<Uint8Array>) => {\n if (output !== undefined) {\n if (fnLength !== 2) throw new Error('cipher output not supported');\n abytes(output, undefined, 'output');\n }\n };\n // Create wrapped cipher with validation and single-use encryption\n let called = false;\n const wrCipher = {\n encrypt(data: TArg<Uint8Array>, output?: TArg<Uint8Array>) {\n if (called) throw new Error('cannot encrypt() twice with same key + nonce');\n called = true;\n abytes(data);\n checkOutput(cipher.encrypt.length, output);\n return (cipher as CipherWithOutput).encrypt(data, output);\n },\n decrypt(data: TArg<Uint8Array>, output?: TArg<Uint8Array>) {\n abytes(data);\n if (tagl && data.length < tagl)\n throw new Error('\"ciphertext\" expected length bigger than tagLength=' + tagl);\n checkOutput(cipher.decrypt.length, output);\n return (cipher as CipherWithOutput).decrypt(data, output);\n },\n };\n\n return wrCipher as TRet<CipherWithOutput>;\n }\n\n Object.assign(wrappedCipher, params);\n return wrappedCipher as C & P;\n};\n\n/**\n * Represents a Salsa or ChaCha xor stream.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Optional starting block counter.\n * @returns Output bytes.\n */\nexport type XorStream = (\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n data: TArg<Uint8Array>,\n output?: TArg<Uint8Array>,\n counter?: number\n) => TRet<Uint8Array>;\n\n/**\n * By default, returns u8a of length.\n * When out is available, it checks it for validity and uses it.\n * @param expectedLength - Required output length.\n * @param out - Optional destination buffer.\n * @param onlyAligned - Whether `out` must be 4-byte aligned.\n * @returns Output buffer ready for writing.\n * @throws On wrong argument types. {@link TypeError}\n * @throws If the provided output buffer has the wrong size or alignment. {@link Error}\n * @example\n * Reuses a caller-provided output buffer when lengths match.\n *\n * ```ts\n * getOutput(16, new Uint8Array(16));\n * ```\n */\nexport function getOutput(\n expectedLength: number,\n out?: TArg<Uint8Array>,\n onlyAligned = true\n): TRet<Uint8Array> {\n if (out === undefined) return new Uint8Array(expectedLength) as TRet<Uint8Array>;\n // Keep Buffer/cross-realm Uint8Array support here instead of trusting a shape-compatible object.\n abytes(out, undefined, 'output');\n if (out.length !== expectedLength)\n throw new Error(\n '\"output\" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length\n );\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n return out as TRet<Uint8Array>;\n}\n\n/**\n * Encodes data and AAD bit lengths into a 16-byte buffer.\n * @param dataLength - Data length in bits.\n * @param aadLength - AAD length in bits.\n * The serialized block is still `aadLength || dataLength`, matching GCM/Poly1305\n * conventions even though the helper parameter order is `(dataLength, aadLength)`.\n * @param isLE - Whether to encode lengths as little-endian.\n * @returns 16-byte length block.\n * @throws On wrong argument types passed to the endian validator. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Builds the length block appended by GCM and Poly1305.\n *\n * ```ts\n * u64Lengths(16, 8, true);\n * ```\n */\nexport function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): TRet<Uint8Array> {\n // Reject coercible non-number lengths like '10' and true before BigInt(...) accepts them.\n anumber(dataLength);\n anumber(aadLength);\n abool(isLE);\n const num = new Uint8Array(16);\n const view = createView(num);\n view.setBigUint64(0, BigInt(aadLength), isLE);\n view.setBigUint64(8, BigInt(dataLength), isLE);\n return num as TRet<Uint8Array>;\n}\n\n/**\n * Checks whether a byte array is aligned to a 4-byte offset.\n * @param bytes - Byte array to inspect.\n * @returns `true` when the view is 4-byte aligned.\n * @example\n * Checks whether a buffer can be safely viewed as Uint32Array.\n *\n * ```ts\n * isAligned32(new Uint8Array(4));\n * ```\n */\nexport function isAligned32(bytes: TArg<Uint8Array>): boolean {\n return bytes.byteOffset % 4 === 0;\n}\n\n/**\n * Copies bytes into a new Uint8Array.\n * @param bytes - Bytes to copy.\n * @returns Copied byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Copies input into an aligned Uint8Array before block processing.\n *\n * ```ts\n * copyBytes(new Uint8Array([1, 2]));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Cryptographically secure PRNG.\n * Uses internal OS-level `crypto.getRandomValues`.\n * @param bytesLength - Number of bytes to produce.\n * Validation is delegated to `Uint8Array(bytesLength)` and `getRandomValues`, so\n * non-integers, negative lengths, and oversize requests surface backend/runtime errors.\n * @returns Random byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @throws If the runtime does not expose `crypto.getRandomValues`. {@link Error}\n * @example\n * Generates a fresh nonce or key.\n *\n * ```ts\n * randomBytes(16);\n * ```\n */\nexport function randomBytes(bytesLength = 32): TRet<Uint8Array> {\n // Validate upfront so fractional / coercible lengths do not silently\n // truncate through Uint8Array().\n anumber(bytesLength);\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n return cr.getRandomValues(new Uint8Array(bytesLength)) as TRet<Uint8Array>;\n}\n\n/**\n * The pseudorandom number generator doesn't wipe current state:\n * instead, it generates new one based on previous state + entropy.\n * Not reseed/rekey, since AES CTR DRBG does rekey on each randomBytes,\n * which is in fact `reseed`, since it changes counter too.\n */\nexport interface PRG {\n /**\n * Mixes fresh entropy into the current generator state.\n * @param seed - Entropy bytes to absorb.\n */\n addEntropy(seed: TArg<Uint8Array>): void;\n /**\n * Produces a requested number of pseudorandom bytes.\n * @param bytesLength - Number of bytes to generate.\n * @returns Random byte array.\n */\n randomBytes(bytesLength: number): TRet<Uint8Array>;\n /** Destroys the generator state. */\n clean(): void;\n}\n\n/** Removes the nonce argument from a cipher constructor type. */\nexport type RemoveNonce<T extends (...args: any) => any> = T extends (\n arg0: any,\n arg1: any,\n ...rest: infer R\n) => infer Ret\n ? (key: TArg<Uint8Array>, ...args: R) => Ret\n : never;\n/**\n * Cipher constructor that requires a nonce argument.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param args - Additional cipher-specific arguments.\n * @returns Cipher instance.\n */\nexport type CipherWithNonce = ((\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n ...args: any[]\n) => Cipher | AsyncCipher) & {\n nonceLength: number;\n};\n\n/**\n * Uses CSPRNG for nonce, nonce injected in ciphertext.\n * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and\n * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext\n * are treated as nonce. The wrapper always allocates a fresh `nonce || ciphertext`\n * buffer on encrypt and intentionally does not support caller-provided destination buffers.\n * Too-short decrypt inputs are split into short/empty nonce views and then delegated\n * to the wrapped cipher instead of being rejected here first.\n *\n * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha\n * should be limited to `2**23` (8M) messages to get a collision chance of\n * `2**-50`. Stretching to `2**32` (4B) messages would raise that chance to\n * `2**-33`, still negligible but creeping up.\n * @param fn - Cipher constructor that expects a nonce.\n * @param randomBytes_ - Random-byte source used for nonce generation.\n * @returns Cipher constructor that prepends the nonce to ciphertext.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On invalid nonce lengths observed at wrapper construction or use. {@link RangeError}\n * @example\n * Prepends a fresh random nonce to every ciphertext.\n *\n * ```ts\n * import { gcm } from '@noble/ciphers/aes.js';\n * import { managedNonce, randomBytes } from '@noble/ciphers/utils.js';\n * const wrapped = managedNonce(gcm);\n * const key = randomBytes(16);\n * const ciphertext = wrapped(key).encrypt(new Uint8Array([1, 2, 3]));\n * wrapped(key).decrypt(ciphertext);\n * ```\n */\nexport function managedNonce<T extends CipherWithNonce>(\n fn: T,\n randomBytes_: typeof randomBytes = randomBytes\n): TRet<RemoveNonce<T>> {\n const { nonceLength } = fn;\n anumber(nonceLength);\n const addNonce = (\n nonce: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n plaintext: TArg<Uint8Array>\n ) => {\n const out = concatBytes(nonce, ciphertext);\n // Wrapped ciphers may alias caller plaintext on encrypt(); never zero\n // caller-owned buffers here.\n if (!overlapBytes(plaintext, ciphertext)) ciphertext.fill(0);\n return out;\n };\n // NOTE: we cannot support DST here, it would be mistake:\n // - we don't know how much dst length cipher requires\n // - nonce may unalign dst and break everything\n // - we create new u8a anyway (concatBytes)\n // - previously we passed all args to cipher, but that was mistake!\n const res = ((key: TArg<Uint8Array>, ...args: any[]): any => ({\n encrypt(plaintext: TArg<Uint8Array>) {\n abytes(plaintext);\n const nonce = randomBytes_(nonceLength);\n const encrypted = fn(key, nonce, ...args).encrypt(plaintext);\n // @ts-ignore\n if (encrypted instanceof Promise)\n return encrypted.then((ct) => addNonce(nonce, ct, plaintext));\n return addNonce(nonce, encrypted, plaintext);\n },\n decrypt(ciphertext: TArg<Uint8Array>) {\n abytes(ciphertext);\n const nonce = ciphertext.subarray(0, nonceLength);\n const decrypted = ciphertext.subarray(nonceLength);\n return fn(key, nonce, ...args).decrypt(decrypted);\n },\n })) as RemoveNonce<T> & { blockSize?: number; tagLength?: number };\n // Auto-nonce wrappers still preserve the wrapped payload geometry.\n if ('blockSize' in fn) res.blockSize = (fn as any).blockSize;\n if ('tagLength' in fn) res.tagLength = (fn as any).tagLength;\n return res as TRet<RemoveNonce<T>>;\n}\n\n/** `Uint8Array.of()` return type helper for TS 5.9. */\nexport type Uint8ArrayBuffer = TRet<Uint8Array>;\n","/**\n * Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.\n\nRFC8439 requires multi-step cipher stream, where\nauthKey starts with counter: 0, actual msg with counter: 1.\n\nFor this, we need a way to re-use nonce / counter:\n\n const counter = new Uint8Array(4);\n chacha(..., counter, ...); // counter is now 1\n chacha(..., counter, ...); // counter is now 2\n\nThis is complicated:\n\n- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB\n- Original papers don't allow mutating counters\n- Counter overflow is undefined [^1]\n- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it\n- Caveat: Cannot be re-used through all cases:\n- * chacha has (counter | nonce)\n- * xchacha has (nonce16 | counter | nonce16)\n- Idea B: separate nonce / counter and provide separate API for counter re-use\n- Caveat: there are different counter sizes depending on an algorithm.\n- salsa & chacha also differ in structures of key & sigma:\n salsa20: s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3]\n chacha: s(4) | k(8) | cnt(1) | nonce(3)\n chacha20orig: s(4) | k(8) | cnt(2) | nonce(2)\n- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`\n- Caveat: we can't re-use counter array\n\nxchacha uses the subkey and remaining 8 byte nonce with ChaCha20 as normal\n(prefixed by 4 NUL bytes, since RFC8439 specifies a 12-byte nonce).\nCounter overflow is undefined; see {@link https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/ | the CFRG thread}.\nCurrent noble policy is strict non-wrap for the shared 32-bit counter path:\nexported ARX ciphers reject initial `0xffffffff` and stop before any implicit\nwrap back to zero.\nSee {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2 | the XChaCha appendix} for the extended-nonce construction.\n\n * @module\n */\nimport {\n type PRG,\n type TArg,\n type TRet,\n type XorStream,\n abool,\n abytes,\n anumber,\n checkOpts,\n clean,\n copyBytes,\n getOutput,\n isAligned32,\n isLE,\n randomBytes,\n swap32IfBE,\n u32,\n} from './utils.ts';\n\n// Replaces `TextEncoder` for ASCII literals, which is enough for sigma constants.\n// Non-ASCII input would not match UTF-8 `TextEncoder` output.\nconst encodeStr = (str: string) => Uint8Array.from(str.split(''), (c) => c.charCodeAt(0));\n// Raw `createCipher(...)` exports consume these native-endian `u32(...)` views directly.\n// Public `wrapCipher(...)` APIs reject non-little-endian platforms before reaching this path.\n// RFC 8439 §2.3 / RFC 7539 §2.3 only define the 256-bit-key constants; this 16-byte sigma is\n// kept for legacy allowShortKeys Salsa/ChaCha variants.\nconst sigma16_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 16-byte k'))))();\n// RFC 8439 §2.3 / RFC 7539 §2.3 define words 0-3 as\n// `0x61707865 0x3320646e 0x79622d32 0x6b206574`, i.e. `expand 32-byte k`.\nconst sigma32_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 32-byte k'))))();\n\n/**\n * Rotates a 32-bit word left.\n * @param a - Input word.\n * @param b - Rotation count in bits.\n * @returns Rotated 32-bit word.\n * @example\n * Moves the top byte of `0x12345678` into the low byte position.\n * ```ts\n * rotl(0x12345678, 8);\n * ```\n */\nexport function rotl(a: number, b: number): number {\n return (a << b) | (a >>> (32 - b));\n}\n\n/**\n * ARX core function operating on 32-bit words. Ciphers must use u32 for efficiency.\n * @param sigma - Sigma constants for the selected cipher layout.\n * @param key - Expanded key words.\n * @param nonce - Nonce and counter words prepared for the round function.\n * @param output - Output block written in place.\n * @param counter - Block counter value.\n * @param rounds - Optional round count override.\n */\nexport type CipherCoreFn = (\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n nonce: TArg<Uint32Array>,\n output: TArg<Uint32Array>,\n counter: number,\n rounds?: number\n) => void;\n\n/**\n * Nonce-extension function used by XChaCha and XSalsa.\n * @param sigma - Sigma constants for the selected cipher layout.\n * @param key - Expanded key words.\n * @param input - Input nonce words used for subkey derivation.\n * @param output - Output buffer written with the derived nonce words.\n */\nexport type ExtendNonceFn = (\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n input: TArg<Uint32Array>,\n output: TArg<Uint32Array>\n) => void;\n\n/** ARX cipher options.\n * * `allowShortKeys` for 16-byte keys\n * * `counterLength` in bytes\n * * `counterRight`: right: `nonce|counter`; left: `counter|nonce`\n * */\nexport type CipherOpts = {\n /** Whether 16-byte keys are accepted for legacy Salsa and ChaCha variants. */\n allowShortKeys?: boolean;\n /** Optional nonce-expansion hook used by extended-nonce variants. */\n extendNonceFn?: ExtendNonceFn;\n /** Counter length in bytes inside the nonce/counter layout. */\n counterLength?: number;\n /** Whether the layout is `nonce|counter` instead of `counter|nonce`. */\n counterRight?: boolean;\n /** Number of core rounds to execute. */\n rounds?: number;\n};\n\n// Salsa and Chacha block length is always 512-bit\nconst BLOCK_LEN = 64;\n// RFC 8439 §2.2 / RFC 7539 §2.2: the ChaCha state has 16 32-bit words.\nconst BLOCK_LEN32 = 16;\n\n// Counter policy for the shared public `counter` argument:\n// - RFC/IETF ChaCha20 uses a 32-bit counter.\n// - OpenSSL/Node `chacha20` instead treat the full 16-byte IV as a 128-bit\n// counter state and carry into the next word.\n// - Raw `chacha20orig`, `salsa20`, `xsalsa20`, and `xchacha20` use 64-bit counters in libsodium\n// and libtomcrypt, while some libs (for example libtomcrypt's RFC/IETF path) reject the max\n// boundary instead of carrying.\n// - AEAD wrappers diverge too: libsodium `xchacha20poly1305` uses the IETF payload counter from\n// block 1, while `secretstream_xchacha20poly1305` is a different protocol with rekey/reset.\n// Noble intentionally throws instead of silently picking one wrap model for users. In the default\n// path, even a 32-bit boundary would take 2^32 blocks * 64 bytes = 256 GiB, which is practically\n// unreachable for normal JS callers; advanced users who pass `counter` explicitly can implement\n// whatever wider carry / wrap policy they need on top.\nconst MAX_COUNTER = /* @__PURE__ */ (() => 2 ** 32 - 1)();\nconst U32_EMPTY = /* @__PURE__ */ Uint32Array.of();\nfunction runCipher(\n core: TArg<CipherCoreFn>,\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n nonce: TArg<Uint32Array>,\n data: TArg<Uint8Array>,\n output: TArg<Uint8Array>,\n counter: number,\n rounds: number\n): void {\n const len = data.length;\n const block = new Uint8Array(BLOCK_LEN);\n const b32 = u32(block);\n // Make sure that buffers aligned to 4 bytes\n const isAligned = isLE && isAligned32(data) && isAligned32(output);\n const d32 = isAligned ? u32(data) : U32_EMPTY;\n const o32 = isAligned ? u32(output) : U32_EMPTY;\n // RFC 8439 §2.4.1 / RFC 7539 §2.4.1 allow XORing one keystream block at a time and\n // truncating the final partial block instead of materializing the whole keystream.\n if (!isLE) {\n for (let pos = 0; pos < len; counter++) {\n core(\n sigma as TRet<Uint32Array>,\n key as TRet<Uint32Array>,\n nonce as TRet<Uint32Array>,\n b32,\n counter,\n rounds\n );\n // RFC 8439 §2.4 / RFC 7539 §2.4 serialize keystream words in little-endian order.\n swap32IfBE(b32);\n if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const take = Math.min(BLOCK_LEN, len - pos);\n for (let j = 0, posj; j < take; j++) {\n posj = pos + j;\n output[posj] = data[posj] ^ block[j];\n }\n pos += take;\n }\n return;\n }\n for (let pos = 0; pos < len; counter++) {\n core(\n sigma as TRet<Uint32Array>,\n key as TRet<Uint32Array>,\n nonce as TRet<Uint32Array>,\n b32,\n counter,\n rounds\n );\n // See MAX_COUNTER policy note above: never silently wrap the shared public counter.\n if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const take = Math.min(BLOCK_LEN, len - pos);\n // aligned to 4 bytes\n if (isAligned && take === BLOCK_LEN) {\n const pos32 = pos / 4;\n if (pos % 4 !== 0) throw new Error('arx: invalid block position');\n for (let j = 0, posj: number; j < BLOCK_LEN32; j++) {\n posj = pos32 + j;\n o32[posj] = d32[posj] ^ b32[j];\n }\n pos += BLOCK_LEN;\n continue;\n }\n for (let j = 0, posj; j < take; j++) {\n posj = pos + j;\n output[posj] = data[posj] ^ block[j];\n }\n pos += take;\n }\n}\n\n/**\n * Creates an ARX stream cipher from a 32-bit core permutation.\n * Used internally to build the exported Salsa and ChaCha stream ciphers.\n * @param core - Core function that fills one keystream block.\n * @param opts - Cipher layout and nonce-extension options. See {@link CipherOpts}.\n * @returns Stream cipher function over byte arrays.\n * @throws If the core callback, key size, counter, or output sizing is invalid. {@link Error}\n */\nexport function createCipher(core: TArg<CipherCoreFn>, opts: TArg<CipherOpts>): TRet<XorStream> {\n const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts(\n { allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 },\n opts\n );\n if (typeof core !== 'function') throw new Error('core must be a function');\n anumber(counterLength);\n anumber(rounds);\n abool(counterRight);\n abool(allowShortKeys);\n return (\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n data: TArg<Uint8Array>,\n output?: TArg<Uint8Array>,\n counter = 0\n ): TRet<Uint8Array> => {\n abytes(key, undefined, 'key');\n abytes(nonce, undefined, 'nonce');\n abytes(data, undefined, 'data');\n const len = data.length;\n // Raw XorStream APIs return ciphertext/plaintext bytes directly, so caller-provided outputs\n // must match the logical result length exactly instead of returning an oversized workspace.\n output = getOutput(len, output, false);\n anumber(counter);\n // See MAX_COUNTER policy note above: reject advanced explicit-counter requests before any wrap.\n if (counter < 0 || counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const toClean = [];\n\n // Key & sigma\n // key=16 -> sigma16, k=key|key\n // key=32 -> sigma32, k=key\n let l = key.length;\n let k: Uint8Array;\n let sigma: Uint32Array;\n if (l === 32) {\n // Copy caller keys too: big-endian normalization, extended-nonce subkey derivation, and\n // final clean(...) all mutate or wipe the temporary buffer in place.\n toClean.push((k = copyBytes(key)));\n sigma = sigma32_32;\n } else if (l === 16 && allowShortKeys) {\n k = new Uint8Array(32);\n k.set(key);\n k.set(key, 16);\n sigma = sigma16_32;\n toClean.push(k);\n } else {\n abytes(key, 32, 'arx key');\n throw new Error('invalid key size');\n // throw new Error(`\"arx key\" expected Uint8Array of length 32, got length=${l}`);\n }\n\n // Nonce\n // salsa20: 8 (8-byte counter)\n // chacha20orig: 8 (8-byte counter)\n // chacha20: 12 (4-byte counter)\n // xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)\n // xchacha20: 24 (16 -> hchacha, 8 -> old nonce)\n // Copy before taking u32(...) views on misaligned inputs, and on big-endian so later\n // swap32IfBE(...) never mutates caller nonce bytes in place.\n if (!isLE || !isAligned32(nonce)) toClean.push((nonce = copyBytes(nonce)));\n\n let k32 = u32(k);\n // hsalsa & hchacha: handle extended nonce\n if (extendNonceFn) {\n if (nonce.length !== 24) throw new Error(`arx: extended nonce must be 24 bytes`);\n const n16 = nonce.subarray(0, 16);\n if (isLE) extendNonceFn(sigma as TRet<Uint32Array>, k32, u32(n16), k32);\n else {\n const sigmaRaw = swap32IfBE(Uint32Array.from(sigma));\n extendNonceFn(sigmaRaw, k32, u32(n16), k32);\n clean(sigmaRaw);\n swap32IfBE(k32);\n }\n nonce = nonce.subarray(16);\n } else if (!isLE) swap32IfBE(k32);\n\n // Handle nonce counter\n const nonceNcLen = 16 - counterLength;\n if (nonceNcLen !== nonce.length)\n throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);\n\n // Normalize 64-bit-nonce layouts to the 12-byte core input: ChaCha/XChaCha prefix 4 zero\n // counter bytes, while Salsa/XSalsa append them after the nonce words.\n if (nonceNcLen !== 12) {\n const nc = new Uint8Array(12);\n nc.set(nonce, counterRight ? 0 : 12 - nonce.length);\n nonce = nc;\n toClean.push(nonce);\n }\n const n32 = swap32IfBE(u32(nonce));\n // Ensure temporary key/nonce copies are wiped even if the remaining\n // runtime guard in runCipher(...) throws on counter overflow.\n try {\n runCipher(core, sigma, k32, n32, data, output, counter, rounds);\n return output as TRet<Uint8Array>;\n } finally {\n clean(...toClean);\n }\n };\n}\n\n/** Internal class which wraps chacha20 or chacha8 to create CSPRNG. */\nexport class _XorStreamPRG implements PRG {\n readonly blockLen: number;\n readonly keyLen: number;\n readonly nonceLen: number;\n private state: TRet<Uint8Array>;\n private buf: TRet<Uint8Array>;\n private key: TRet<Uint8Array>;\n private nonce: TRet<Uint8Array>;\n private pos: number;\n private ctr: number;\n private cipher: TArg<XorStream>;\n constructor(\n cipher: TArg<XorStream>,\n blockLen: number,\n keyLen: number,\n nonceLen: number,\n seed: TArg<Uint8Array>\n ) {\n this.cipher = cipher;\n this.blockLen = blockLen;\n this.keyLen = keyLen;\n this.nonceLen = nonceLen;\n this.state = new Uint8Array(this.keyLen + this.nonceLen) as TRet<Uint8Array>;\n this.reseed(seed);\n this.ctr = 0;\n this.pos = this.blockLen;\n this.buf = new Uint8Array(this.blockLen) as TRet<Uint8Array>;\n // Keep a single key||nonce backing buffer so reseed/addEntropy/clean update the live cipher\n // inputs in place through these subarray views.\n this.key = this.state.subarray(0, this.keyLen) as TRet<Uint8Array>;\n this.nonce = this.state.subarray(this.keyLen) as TRet<Uint8Array>;\n }\n private reseed(seed: TArg<Uint8Array>) {\n abytes(seed);\n if (!seed || seed.length === 0) throw new Error('entropy required');\n // Mix variable-length entropy cyclically across the whole key||nonce state, then restart the\n // keystream so buffered leftovers from the previous state are never reused.\n for (let i = 0; i < seed.length; i++) this.state[i % this.state.length] ^= seed[i];\n this.ctr = 0;\n this.pos = this.blockLen;\n }\n addEntropy(seed: TArg<Uint8Array>): void {\n // Reject empty entropy before re-keying, otherwise a throwing call would still advance state.\n abytes(seed);\n if (seed.length === 0) throw new Error('entropy required');\n // Re-key from the current stream first, then mix external entropy into the fresh key||nonce\n // state through reseed() so stale buffered bytes are discarded.\n this.state.set(this.randomBytes(this.state.length));\n this.reseed(seed);\n }\n randomBytes(len: number): TRet<Uint8Array> {\n anumber(len);\n if (len === 0) return new Uint8Array(0) as TRet<Uint8Array>;\n const avail = this.pos < this.blockLen ? this.blockLen - this.pos : 0;\n const blocks = Math.ceil(Math.max(0, len - avail) / this.blockLen);\n // Preflight overflow so failed reads don't partially consume keystream\n // and leave the PRG repeating blocks.\n if (blocks > 0 && this.ctr > MAX_COUNTER - blocks) throw new Error('arx: counter overflow');\n const out = new Uint8Array(len);\n let outPos = 0;\n // `out` starts zero-filled, and `buf.fill(0)` below does the same for leftovers: XOR-stream\n // ciphers then emit raw keystream bytes directly into those buffers.\n // Serve buffered leftovers first so split reads stay identical to one larger read.\n if (this.pos < this.blockLen) {\n const take = Math.min(len, this.blockLen - this.pos);\n out.set(this.buf.subarray(this.pos, this.pos + take), 0);\n this.pos += take;\n outPos += take;\n if (outPos === len) return out as TRet<Uint8Array>; // fast path\n }\n // Full blocks directly to out\n const full = Math.floor((len - outPos) / this.blockLen);\n if (full > 0) {\n const blockBytes = full * this.blockLen;\n const b = out.subarray(outPos, outPos + blockBytes);\n this.cipher(this.key, this.nonce, b as TRet<Uint8Array>, b as TRet<Uint8Array>, this.ctr);\n this.ctr += full;\n outPos += blockBytes;\n }\n // Save leftovers\n const left = len - outPos;\n if (left > 0) {\n this.buf.fill(0);\n // NOTE: cipher will handle overflow\n this.cipher(\n this.key,\n this.nonce,\n this.buf as TRet<Uint8Array>,\n this.buf as TRet<Uint8Array>,\n this.ctr++\n );\n out.set(this.buf.subarray(0, left), outPos);\n this.pos = left;\n }\n return out as TRet<Uint8Array>;\n }\n // Clone seeds the new instance from this stream, so the source PRG advances too.\n clone(): _XorStreamPRG {\n return new _XorStreamPRG(\n this.cipher,\n this.blockLen,\n this.keyLen,\n this.nonceLen,\n this.randomBytes(this.state.length)\n );\n }\n // Zeroes the current state and leftover buffer, but does not make the instance unusable:\n // Later reads first drain zeros from the cleared buffer and then continue\n // from zero key||nonce state.\n clean(): void {\n this.pos = 0;\n this.ctr = 0;\n this.buf.fill(0);\n this.state.fill(0);\n }\n}\n\n/**\n * PRG constructor backed by an ARX stream cipher.\n * @param seed - Optional seed bytes mixed into the initial state. When omitted, exactly 32\n * random bytes are mixed in by default: larger states keep a zero tail, while smaller states\n * wrap those bytes through `reseed()`'s XOR schedule.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n */\nexport type XorPRG = (seed?: TArg<Uint8Array>) => TRet<_XorStreamPRG>;\n\n/**\n * Creates a PRG constructor from a stream cipher.\n * @param cipher - Stream cipher used to fill output blocks.\n * @param blockLen - Keystream block length in bytes.\n * @param keyLen - Internal key length in bytes.\n * @param nonceLen - Internal nonce length in bytes.\n * @returns PRG factory for seeded concrete `_XorStreamPRG` instances.\n * @example\n * Builds a PRG from XChaCha20 and reads bytes from a randomly seeded instance.\n * ```ts\n * import { xchacha20 } from '@noble/ciphers/chacha.js';\n * import { createPRG } from '@noble/ciphers/_arx.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const init = createPRG(xchacha20, 64, 32, 24);\n * const prg = init(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const createPRG = (\n cipher: TArg<XorStream>,\n blockLen: number,\n keyLen: number,\n nonceLen: number\n): TRet<XorPRG> => {\n return ((seed: TArg<Uint8Array> = randomBytes(32)): TRet<_XorStreamPRG> =>\n new _XorStreamPRG(\n cipher,\n blockLen,\n keyLen,\n nonceLen,\n seed\n ) as TRet<_XorStreamPRG>) as TRet<XorPRG>;\n};\n","/**\n * Poly1305 ({@link https://cr.yp.to/mac/poly1305-20050329.pdf | PDF},\n * {@link https://en.wikipedia.org/wiki/Poly1305 | wiki})\n * is a fast and parallel secret-key message-authentication code suitable for\n * a wide variety of applications. It was standardized in\n * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and is now used in TLS 1.3.\n *\n * Polynomial MACs are not perfect for every situation:\n * they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes.\n * See {@link https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/ | the invisible salamanders attack writeup}.\n * To combat invisible salamanders, `hash(key)` can be included in ciphertext,\n * however, this would violate ciphertext indistinguishability:\n * an attacker would know which key was used - so `HKDF(key, i)`\n * could be used instead.\n *\n * Check out the {@link https://cr.yp.to/mac.html | original website}.\n * Based on public-domain {@link https://github.com/floodyberry/poly1305-donna | poly1305-donna}.\n * @module\n */\n// prettier-ignore\nimport {\n abytes, aexists, aoutput, bytesToHex,\n clean, concatBytes, copyBytes, hexToNumber, numberToBytesBE,\n wrapMacConstructor, type CMac, type IHash2, type TArg, type TRet\n} from './utils.ts';\n\n// Little-endian 2-byte load used by the Poly1305 limb decomposition.\nfunction u8to16(a: TArg<Uint8Array>, i: number) {\n return (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);\n}\n\nfunction bytesToNumberLE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));\n}\n\n/** Small version of `poly1305` without loop unrolling. Unused, provided for auditability. */\nfunction poly1305_small(msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array> {\n abytes(msg);\n abytes(key, 32, 'key');\n const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5); // 2^130-5\n const POW_2_128_1 = BigInt(2) ** BigInt(128) - BigInt(1); // 2^128-1\n const CLAMP_R = BigInt('0x0ffffffc0ffffffc0ffffffc0fffffff');\n const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R;\n const s = bytesToNumberLE(key.subarray(16));\n // Process by 16 byte chunks\n let acc = BigInt(0);\n for (let i = 0; i < msg.length; i += 16) {\n const m = msg.subarray(i, i + 16);\n // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 append [0x01] to each chunk before multiplying by r.\n const n = bytesToNumberLE(m) | (BigInt(1) << BigInt(8 * m.length));\n acc = ((acc + n) * r) % POW_2_130_5;\n }\n const res = (acc + s) & POW_2_128_1;\n // RFC 8439 §2.5 / RFC 7539 §2.5 serialize the low 128 bits in little-endian order.\n return numberToBytesBE(res, 16).reverse() as TRet<Uint8Array>; // LE\n}\n\n// Can be used to replace `computeTag` in chacha.ts. Unused, provided for auditability.\n// @ts-expect-error\nfunction poly1305_computeTag_small(\n authKey: TArg<Uint8Array>,\n // AEAD trailer must already be the 16-byte length block:\n // 8-byte little-endian AAD length || 8-byte little-endian ciphertext length.\n lengths: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n // RFC 8439 §2.8.1 / RFC 7539 §2.8.1 MAC input is\n // AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || lengths.\n const res = [];\n const updatePadded2 = (msg: TArg<Uint8Array>) => {\n res.push(msg);\n const leftover = msg.length % 16;\n // RFC 8439 §2.8.1 / RFC 7539 §2.8.1: pad16(x) is empty for aligned\n // inputs, else 16-(len%16) zero bytes.\n if (leftover) res.push(new Uint8Array(16).slice(leftover));\n };\n if (AAD) updatePadded2(AAD);\n updatePadded2(ciphertext);\n res.push(lengths);\n return poly1305_small(concatBytes(...res), authKey);\n}\n\n/**\n * Incremental Poly1305 MAC state.\n * Prefer `poly1305()` for one-shot use.\n * @param key - 32-byte Poly1305 one-time key.\n * @example\n * Feeds one chunk into an incremental Poly1305 state with a fresh one-time key.\n *\n * ```ts\n * import { Poly1305 } from '@noble/ciphers/_poly1305.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const mac = new Poly1305(key);\n * mac.update(new Uint8Array([1, 2, 3]));\n * mac.digest();\n * ```\n */\nexport class Poly1305 implements IHash2 {\n readonly blockLen = 16;\n readonly outputLen = 16;\n private buffer = new Uint8Array(16);\n private r = new Uint16Array(10); // Allocating 1 array with .subarray() here is slower than 3\n private h = new Uint16Array(10);\n private pad = new Uint16Array(8);\n private pos = 0;\n protected finished = false;\n protected destroyed = false;\n\n // Can be speed-up using BigUint64Array, at the cost of complexity\n constructor(key: TArg<Uint8Array>) {\n key = copyBytes(abytes(key, 32, 'key'));\n const t0 = u8to16(key, 0);\n const t1 = u8to16(key, 2);\n const t2 = u8to16(key, 4);\n const t3 = u8to16(key, 6);\n const t4 = u8to16(key, 8);\n const t5 = u8to16(key, 10);\n const t6 = u8to16(key, 12);\n const t7 = u8to16(key, 14);\n\n // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 clamp r before multiplication.\n // These masks unpack that clamped value into 13-bit limbs, while pad\n // keeps the raw s half for finalize().\n // {@link https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47 | poly1305-donna reference}\n this.r[0] = t0 & 0x1fff;\n this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;\n this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;\n this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;\n this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;\n this.r[5] = (t4 >>> 1) & 0x1ffe;\n this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;\n this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;\n this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;\n this.r[9] = (t7 >>> 5) & 0x007f;\n for (let i = 0; i < 8; i++) this.pad[i] = u8to16(key, 16 + 2 * i);\n }\n\n private process(data: TArg<Uint8Array>, offset: number, isLast = false) {\n // RFC 8439 §2.5 / §2.5.1 and RFC 7539 §2.5 / §2.5.1 add an extra high\n // bit to every full 16-byte block. The final partial block gets its\n // explicit `1` byte during digestInto(), so `hibit` stays zero there.\n const hibit = isLast ? 0 : 1 << 11;\n const { h, r } = this;\n const r0 = r[0];\n const r1 = r[1];\n const r2 = r[2];\n const r3 = r[3];\n const r4 = r[4];\n const r5 = r[5];\n const r6 = r[6];\n const r7 = r[7];\n const r8 = r[8];\n const r9 = r[9];\n\n const t0 = u8to16(data, offset + 0);\n const t1 = u8to16(data, offset + 2);\n const t2 = u8to16(data, offset + 4);\n const t3 = u8to16(data, offset + 6);\n const t4 = u8to16(data, offset + 8);\n const t5 = u8to16(data, offset + 10);\n const t6 = u8to16(data, offset + 12);\n const t7 = u8to16(data, offset + 14);\n\n let h0 = h[0] + (t0 & 0x1fff);\n let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);\n let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);\n let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);\n let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);\n let h5 = h[5] + ((t4 >>> 1) & 0x1fff);\n let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);\n let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);\n let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);\n let h9 = h[9] + ((t7 >>> 5) | hibit);\n\n let c = 0;\n\n let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6);\n c = d0 >>> 13;\n d0 &= 0x1fff;\n d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1);\n c += d0 >>> 13;\n d0 &= 0x1fff;\n\n let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7);\n c = d1 >>> 13;\n d1 &= 0x1fff;\n d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2);\n c += d1 >>> 13;\n d1 &= 0x1fff;\n\n let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);\n c = d2 >>> 13;\n d2 &= 0x1fff;\n d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3);\n c += d2 >>> 13;\n d2 &= 0x1fff;\n\n let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);\n c = d3 >>> 13;\n d3 &= 0x1fff;\n d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4);\n c += d3 >>> 13;\n d3 &= 0x1fff;\n\n let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;\n c = d4 >>> 13;\n d4 &= 0x1fff;\n d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5);\n c += d4 >>> 13;\n d4 &= 0x1fff;\n\n let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;\n c = d5 >>> 13;\n d5 &= 0x1fff;\n d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6);\n c += d5 >>> 13;\n d5 &= 0x1fff;\n\n let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;\n c = d6 >>> 13;\n d6 &= 0x1fff;\n d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);\n c += d6 >>> 13;\n d6 &= 0x1fff;\n\n let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;\n c = d7 >>> 13;\n d7 &= 0x1fff;\n d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);\n c += d7 >>> 13;\n d7 &= 0x1fff;\n\n let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;\n c = d8 >>> 13;\n d8 &= 0x1fff;\n d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);\n c += d8 >>> 13;\n d8 &= 0x1fff;\n\n let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;\n c = d9 >>> 13;\n d9 &= 0x1fff;\n d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;\n c += d9 >>> 13;\n d9 &= 0x1fff;\n\n c = ((c << 2) + c) | 0;\n c = (c + d0) | 0;\n d0 = c & 0x1fff;\n c = c >>> 13;\n d1 += c;\n\n h[0] = d0;\n h[1] = d1;\n h[2] = d2;\n h[3] = d3;\n h[4] = d4;\n h[5] = d5;\n h[6] = d6;\n h[7] = d7;\n h[8] = d8;\n h[9] = d9;\n }\n\n private finalize() {\n const { h, pad } = this;\n const g = new Uint16Array(10);\n let c = h[1] >>> 13;\n h[1] &= 0x1fff;\n for (let i = 2; i < 10; i++) {\n h[i] += c;\n c = h[i] >>> 13;\n h[i] &= 0x1fff;\n }\n h[0] += c * 5;\n c = h[0] >>> 13;\n h[0] &= 0x1fff;\n h[1] += c;\n c = h[1] >>> 13;\n h[1] &= 0x1fff;\n h[2] += c;\n\n // RFC 8439 §2.5 / RFC 7539 §2.5 reduce modulo 2^130-5 before repacking\n // to 16-bit words and adding the raw s half.\n g[0] = h[0] + 5;\n c = g[0] >>> 13;\n g[0] &= 0x1fff;\n for (let i = 1; i < 10; i++) {\n g[i] = h[i] + c;\n c = g[i] >>> 13;\n g[i] &= 0x1fff;\n }\n g[9] -= 1 << 13;\n\n let mask = (c ^ 1) - 1;\n for (let i = 0; i < 10; i++) g[i] &= mask;\n mask = ~mask;\n for (let i = 0; i < 10; i++) h[i] = (h[i] & mask) | g[i];\n h[0] = (h[0] | (h[1] << 13)) & 0xffff;\n h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;\n h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;\n h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;\n h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;\n h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;\n h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;\n h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;\n\n let f = h[0] + pad[0];\n h[0] = f & 0xffff;\n for (let i = 1; i < 8; i++) {\n f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;\n h[i] = f & 0xffff;\n }\n clean(g);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n data = copyBytes(data);\n const { buffer, blockLen } = this;\n const len = data.length;\n\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input\n if (take === blockLen) {\n for (; blockLen <= len - pos; pos += blockLen) this.process(data, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(buffer, 0, false);\n this.pos = 0;\n }\n }\n return this;\n }\n destroy(): void {\n // `aexists(this)` guards update/digest paths, so destroy must mark the instance unusable too.\n this.destroyed = true;\n clean(this.h, this.r, this.buffer, this.pad);\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const { buffer, h } = this;\n let { pos } = this;\n if (pos) {\n // RFC 8439 §2.5 / RFC 7539 §2.5: the final short block appends a\n // single `0x01` byte and zero-fills the remaining bytes before the\n // last multiplication step.\n buffer[pos++] = 1;\n for (; pos < 16; pos++) buffer[pos] = 0;\n this.process(buffer, 0, true);\n }\n this.finalize();\n let opos = 0;\n for (let i = 0; i < 8; i++) {\n out[opos++] = h[i] >>> 0;\n out[opos++] = h[i] >>> 8;\n }\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy out before destroy() zeroes the internal buffer.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n}\n\n/** One-shot keyed hash helper with `.create()`. */\nexport type CHash = CMac<Poly1305>;\n\n/**\n * Poly1305 MAC from RFC 8439.\n * @param msg - Message bytes to authenticate.\n * @param key - 32-byte Poly1305 one-time key.\n * @returns 16-byte authentication tag.\n * @example\n * Authenticates one message with a one-shot Poly1305 call and a fresh key.\n *\n * ```ts\n * import { poly1305 } from '@noble/ciphers/_poly1305.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * poly1305(new Uint8Array(), key);\n * ```\n */\nexport const poly1305: TRet<CHash> = /* @__PURE__ */ wrapMacConstructor(\n 32,\n (key: TArg<Uint8Array>) => new Poly1305(key)\n);\n","/**\n * ChaCha stream cipher, released\n * in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round.\n * It was standardized in\n * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and\n * is now used in TLS 1.3.\n *\n * {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | XChaCha20}\n * extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with\n * randomly-generated nonces.\n *\n * Check out\n * {@link http://cr.yp.to/chacha/chacha-20080128.pdf | PDF},\n * {@link https://en.wikipedia.org/wiki/Salsa20 | wiki}, and\n * {@link https://cr.yp.to/chacha.html | website}.\n *\n * @module\n */\nimport { type XorPRG, createCipher, createPRG, rotl } from './_arx.ts';\nimport { poly1305 } from './_poly1305.ts';\nimport {\n type ARXCipher,\n type CipherWithOutput,\n type TArg,\n type TRet,\n type XorStream,\n abytes,\n clean,\n equalBytes,\n getOutput,\n swap8IfBE,\n swap32IfBE,\n u64Lengths,\n wrapCipher,\n} from './utils.ts';\n\n/**\n * ChaCha core function. It is implemented twice:\n * 1. Simple loop (chachaCore_small, hchacha_small)\n * 2. Unrolled loop (chachaCore, hchacha) - 4x faster, but larger & harder to read\n * The specific implementation is selected in `createCipher` below.\n */\n\n/** RFC 8439 §2.1 quarter round on words a, b, c, d. */\n// prettier-ignore\nfunction chachaQR(x: TArg<Uint32Array>, a: number, b: number, c: number, d: number) {\n x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 16);\n x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 12);\n x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 8);\n x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 7);\n}\n\n/** Repeated ChaCha double rounds; callers are expected to pass an even round count. */\nfunction chachaRound(x: TArg<Uint32Array>, rounds = 20) {\n for (let r = 0; r < rounds; r += 2) {\n // RFC 8439 §2.3 / §2.3.1 inner_block: four column rounds, then four diagonal rounds.\n chachaQR(x, 0, 4, 8, 12);\n chachaQR(x, 1, 5, 9, 13);\n chachaQR(x, 2, 6, 10, 14);\n chachaQR(x, 3, 7, 11, 15);\n chachaQR(x, 0, 5, 10, 15);\n chachaQR(x, 1, 6, 11, 12);\n chachaQR(x, 2, 7, 8, 13);\n chachaQR(x, 3, 4, 9, 14);\n }\n}\n\n// Shared scratch for the auditability-only helper below; only the test-only\n// __TESTS.chachaCore_small hook reaches it, so production exports stay reentrant.\nconst ctmp = /* @__PURE__ */ new Uint32Array(16);\n\n/** Small version of chacha without loop unrolling. Unused, provided for auditability. */\n// prettier-ignore\nfunction chacha(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, i: TArg<Uint32Array>, out: TArg<Uint32Array>,\n isHChacha: boolean = true, rounds: number = 20\n): void {\n // `i` is either `[counter, nonce0, nonce1, nonce2]` for the ChaCha block\n // function or the full 128-bit nonce prefix for the HChaCha subkey path.\n // Create initial array using common pattern\n const y = Uint32Array.from([\n s[0], s[1], s[2], s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n k[0], k[1], k[2], k[3], // Key Key Key Key\n k[4], k[5], k[6], k[7], // Key Key Key Key\n i[0], i[1], i[2], i[3], // Counter Counter Nonce Nonce\n ]);\n const x = ctmp;\n x.set(y);\n chachaRound(x, rounds);\n\n // HChaCha writes words 0..3 and 12..15 after the rounds; the ChaCha\n // block path adds the original state word-by-word.\n if (isHChacha) {\n const xindexes = [0, 1, 2, 3, 12, 13, 14, 15];\n for (let i = 0; i < 8; i++) out[i] = x[xindexes[i]];\n } else {\n for (let i = 0; i < 16; i++) out[i] = (y[i] + x[i]) | 0;\n }\n}\n\n/** Identical to `chachaCore`. Reached only through the test-only `__TESTS` export. */\n// @ts-ignore\nconst chachaCore_small: typeof chachaCore = (s, k, n, out, cnt, rounds) =>\n // Keep the reference wrapper on the same [counter, nonce0, nonce1, nonce2] layout as chacha().\n chacha(s, k, Uint32Array.from([cnt, n[0], n[1], n[2]]), out, false, rounds);\n/** Identical to `hchacha`. Unused. */\n// @ts-ignore\nconst hchacha_small: typeof hchacha = chacha;\n\n/** RFC 8439 §2.3 block core for `state = constants | key | counter | nonce`. */\n// prettier-ignore\nfunction chachaCore(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, n: TArg<Uint32Array>, out: TArg<Uint32Array>, cnt: number, rounds = 20\n): void {\n let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key\n y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key\n y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Nonce Nonce Nonce\n // Save state to temporary variables\n let x00 = y00, x01 = y01, x02 = y02, x03 = y03,\n x04 = y04, x05 = y05, x06 = y06, x07 = y07,\n x08 = y08, x09 = y09, x10 = y10, x11 = y11,\n x12 = y12, x13 = y13, x14 = y14, x15 = y15;\n for (let r = 0; r < rounds; r += 2) {\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8)\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16)\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7);\n }\n // RFC 8439 §2.3 / §2.3.1: add the original state words back in state order.\n let oi = 0;\n out[oi++] = (y00 + x00) | 0; out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0; out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0; out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0; out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0; out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0; out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0; out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0; out[oi++] = (y15 + x15) | 0;\n}\n/**\n * hchacha hashes key and nonce into key' and nonce' for xchacha20.\n * Algorithmically identical to `hchacha_small`, but this exported path\n * normalizes word order on big-endian hosts.\n * Need to find a way to merge it with `chachaCore` without 25% performance hit.\n * @param s - Sigma constants as 32-bit words.\n * @param k - Key words.\n * @param i - Nonce-prefix words.\n * @param out - Output buffer for the derived subkey.\n * @example\n * Derives the XChaCha subkey from sigma, key, and nonce-prefix words.\n *\n * ```ts\n * const sigma = new Uint32Array(4);\n * const key = new Uint32Array(8);\n * const nonce = new Uint32Array(4);\n * const out = new Uint32Array(8);\n * hchacha(sigma, key, nonce, out);\n * ```\n */\n// prettier-ignore\nexport function hchacha(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, i: TArg<Uint32Array>, out: TArg<Uint32Array>\n): void {\n let x00 = swap8IfBE(s[0]), x01 = swap8IfBE(s[1]), x02 = swap8IfBE(s[2]), x03 = swap8IfBE(s[3]),\n x04 = swap8IfBE(k[0]), x05 = swap8IfBE(k[1]), x06 = swap8IfBE(k[2]), x07 = swap8IfBE(k[3]),\n x08 = swap8IfBE(k[4]), x09 = swap8IfBE(k[5]), x10 = swap8IfBE(k[6]), x11 = swap8IfBE(k[7]),\n x12 = swap8IfBE(i[0]), x13 = swap8IfBE(i[1]), x14 = swap8IfBE(i[2]), x15 = swap8IfBE(i[3]);\n for (let r = 0; r < 20; r += 2) {\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8)\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16)\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7);\n }\n // HChaCha derives the subkey from state words 0..3 and 12..15 after 20 rounds.\n let oi = 0;\n out[oi++] = x00; out[oi++] = x01;\n out[oi++] = x02; out[oi++] = x03;\n out[oi++] = x12; out[oi++] = x13;\n out[oi++] = x14; out[oi++] = x15;\n swap32IfBE(out);\n}\n\n/**\n * Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter.\n * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public\n * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts`\n * near `MAX_COUNTER` for the full counter-policy rationale.\n * @param key - 16-byte or 32-byte key.\n * @param nonce - 8-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with the original 8-byte-nonce ChaCha variant and a fresh key/nonce.\n *\n * ```ts\n * import { chacha20orig } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(8);\n * chacha20orig(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha20orig: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n allowShortKeys: true,\n});\n/**\n * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.\n * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with the RFC 8439 ChaCha20 stream cipher and a fresh key/nonce.\n *\n * ```ts\n * import { chacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha20(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha20: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n allowShortKeys: false,\n});\n\n/**\n * XChaCha eXtended-nonce ChaCha. With 24-byte nonce, it's safe to make it random (CSPRNG).\n * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}.\n * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public\n * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts`\n * near `MAX_COUNTER` for the full counter-policy rationale.\n * @param key - 32-byte key.\n * @param nonce - 24-byte extended nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with XChaCha20 using a fresh key and random 24-byte nonce.\n *\n * ```ts\n * import { xchacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(24);\n * xchacha20(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const xchacha20: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n extendNonceFn: hchacha,\n allowShortKeys: false,\n});\n\n/**\n * Reduced 8-round chacha, described in original paper.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Uses the reduced 8-round variant for non-critical workloads with a fresh key/nonce.\n *\n * ```ts\n * import { chacha8 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha8(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha8: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 8,\n});\n\n/**\n * Reduced 12-round chacha, described in original paper.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Uses the reduced 12-round variant for non-critical workloads with a fresh key/nonce.\n *\n * ```ts\n * import { chacha12 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha12(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha12: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 12,\n});\n\n// Test-only hooks for keeping the simple/reference core aligned with the unrolled production core.\nexport const __TESTS: {\n chachaCore_small: typeof chachaCore_small;\n chachaCore: typeof chachaCore;\n} = /* @__PURE__ */ Object.freeze({ chachaCore_small, chachaCore });\n\n// RFC 8439 §2.8.1 pad16(x): shared zero block for AAD/ciphertext padding.\nconst ZEROS16 = /* @__PURE__ */ new Uint8Array(16);\n// RFC 8439 §2.8 / §2.8.1: aligned inputs add nothing, otherwise append 16-(len%16) zero bytes.\nconst updatePadded = (h: ReturnType<typeof poly1305.create>, msg: TArg<Uint8Array>) => {\n h.update(msg);\n const leftover = msg.length % 16;\n if (leftover) h.update(ZEROS16.subarray(leftover));\n};\n\n// RFC 8439 §2.6.1 poly1305_key_gen returns `block[0..31]`, so AEAD key\n// generation only needs 32 zero bytes.\nconst ZEROS32 = /* @__PURE__ */ new Uint8Array(32);\nfunction computeTag(\n fn: TArg<XorStream>,\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n if (AAD !== undefined) abytes(AAD, undefined, 'AAD');\n // RFC 8439 §2.6 / §2.8: derive the Poly1305 one-time key from counter 0,\n // then MAC AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || len(AAD) || len(ciphertext).\n const authKey = fn(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n ZEROS32 as TRet<Uint8Array>\n );\n const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true);\n\n // Methods below can be replaced with\n // return poly1305_computeTag_small(authKey, lengths, ciphertext, AAD)\n const h = poly1305.create(authKey);\n if (AAD) updatePadded(h, AAD);\n updatePadded(h, ciphertext);\n h.update(lengths);\n const res = h.digest();\n clean(authKey, lengths);\n return res;\n}\n\n/**\n * AEAD algorithm from RFC 8439.\n * Salsa20 and chacha (RFC 8439) use poly1305 differently.\n * We could have composed them, but it's hard because of authKey:\n * In salsa20, authKey changes position in salsa stream.\n * In chacha, authKey can't be computed inside computeTag, it modifies the counter.\n */\nexport const _poly1305_aead =\n (xorStream: TArg<XorStream>) =>\n (key: TArg<Uint8Array>, nonce: TArg<Uint8Array>, AAD?: TArg<Uint8Array>): CipherWithOutput => {\n // This borrows caller key/nonce/AAD buffers by reference; mutating them after construction\n // changes future encrypt/decrypt results.\n const tagLength = 16;\n return {\n encrypt(plaintext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array> {\n const plength = plaintext.length;\n output = getOutput(plength + tagLength, output, false);\n output.set(plaintext);\n const oPlain = output.subarray(0, -tagLength);\n // RFC 8439 §2.8: payload encryption starts at counter 1 because counter 0 produced the OTK.\n xorStream(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n oPlain as TRet<Uint8Array>,\n oPlain as TRet<Uint8Array>,\n 1\n );\n const tag = computeTag(xorStream, key, nonce, oPlain, AAD);\n output.set(tag, plength); // append tag\n clean(tag);\n return output as TRet<Uint8Array>;\n },\n decrypt(ciphertext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array> {\n output = getOutput(ciphertext.length - tagLength, output, false);\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = computeTag(xorStream, key, nonce, data, AAD);\n // RFC 8439 §2.8 / §4: authenticate ciphertext before decrypting it, and compare tags with\n // the constant-time equalBytes() helper rather than decrypting speculative plaintext first.\n if (!equalBytes(passedTag, tag)) {\n clean(tag);\n throw new Error('invalid tag');\n }\n output.set(ciphertext.subarray(0, -tagLength));\n // Actual decryption\n xorStream(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n output as TRet<Uint8Array>,\n output as TRet<Uint8Array>,\n 1\n ); // start stream with i=1\n clean(tag);\n return output as TRet<Uint8Array>;\n },\n };\n };\n\n/**\n * ChaCha20-Poly1305 from RFC 8439.\n *\n * Unsafe to use random nonces under the same key, due to collision chance.\n * Prefer XChaCha instead.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param AAD - Additional authenticated data.\n * @returns AEAD cipher instance.\n * @example\n * Encrypts and authenticates plaintext with a fresh key and nonce.\n *\n * ```ts\n * import { chacha20poly1305 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * const cipher = chacha20poly1305(key, nonce);\n * cipher.encrypt(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport const chacha20poly1305: TRet<ARXCipher> = /* @__PURE__ */ wrapCipher(\n { blockSize: 64, nonceLength: 12, tagLength: 16 },\n /* @__PURE__ */ _poly1305_aead(chacha20)\n);\n/**\n * XChaCha20-Poly1305 extended-nonce chacha.\n *\n * Can be safely used with random nonces (CSPRNG).\n * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}.\n * @param key - 32-byte key.\n * @param nonce - 24-byte nonce.\n * @param AAD - Additional authenticated data.\n * @returns AEAD cipher instance.\n * @example\n * Encrypts and authenticates plaintext with a fresh key and random 24-byte nonce.\n *\n * ```ts\n * import { xchacha20poly1305 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(24);\n * const cipher = xchacha20poly1305(key, nonce);\n * cipher.encrypt(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport const xchacha20poly1305: TRet<ARXCipher> = /* @__PURE__ */ wrapCipher(\n { blockSize: 64, nonceLength: 24, tagLength: 16 },\n /* @__PURE__ */ _poly1305_aead(xchacha20)\n);\n\n/**\n * Chacha20 CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n * Compatible with libtomcrypt. It does not have a specification, so unclear how secure it is.\n * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted,\n * only 32 random bytes are mixed into the 40-byte state.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n * @example\n * Seeds the test-only ChaCha20 DRBG from fresh entropy.\n *\n * ```ts\n * import { rngChacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const prg = rngChacha20(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const rngChacha20: TRet<XorPRG> = /* @__PURE__ */ createPRG(chacha20orig, 64, 32, 8);\n/**\n * Chacha20/8 CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n * Faster than `rngChacha20`.\n * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted,\n * only 32 random bytes are mixed into the 44-byte state.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n * @example\n * Seeds the faster test-only ChaCha8 DRBG from fresh entropy.\n *\n * ```ts\n * import { rngChacha8 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const prg = rngChacha8(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const rngChacha8: TRet<XorPRG> = /* @__PURE__ */ createPRG(chacha8, 64, 32, 12);\n","/**\n * core/field-encryption.ts — client-side field encryption (sdk-changes S6,\n * ARCHITECTURE §8.3).\n *\n * Fields the backend stores but never needs to read (mailbox `memo`, history\n * `memo` + `counterparty_nametag`, payment-request `memo`, and the intent\n * payload — E.3) are encrypted client-side so any of the owner's devices can\n * decrypt but the operator cannot.\n *\n * - **Key**: `HKDF-SHA256(ikm = walletPrivKey bytes, info = \"sphere-fieldenc-v1\")`\n * → 32-byte symmetric key. Deterministic per wallet → multi-device by\n * construction (mirrors token-engine/realization.ts — same @noble/hashes\n * HKDF, no salt).\n * - **Cipher/envelope**: XChaCha20-Poly1305 with a random 24-byte nonce; wire\n * form is EXACTLY `\"enc1.\" + base64(nonce ‖ ciphertext)`.\n * - **One mapping rule everywhere** (ARCHITECTURE §8.3): JSON bodies and\n * responses carry the `enc1.` string verbatim; the server validates only\n * prefix + base64 + size cap, stores the exact UTF-8 bytes, and returns them\n * unchanged. {@link assertFieldEnvelopeShape} is that server-side check.\n */\n\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { xchacha20poly1305 } from '@noble/ciphers/chacha.js';\nimport { randomBytes } from '@noble/ciphers/utils.js';\nimport { SphereError } from './errors';\n\n/** HKDF info label — versioned; the same label appears in sdk-changes S6. */\nexport const FIELD_ENCRYPTION_HKDF_INFO = 'sphere-fieldenc-v1';\n\n/** Envelope wire prefix. The version lives in the prefix (`enc1`). */\nexport const FIELD_ENVELOPE_PREFIX = 'enc1.';\n\n/** XChaCha20-Poly1305 nonce length (24 bytes). */\nexport const FIELD_ENVELOPE_NONCE_BYTES = 24;\n\n/** Poly1305 authentication tag length appended to the ciphertext. */\nconst POLY1305_TAG_BYTES = 16;\n\n/**\n * Default envelope size cap in bytes (UTF-8 length of the full `enc1.…`\n * string). Matches the intent-payload cap (≤ 4 KiB — ARCHITECTURE §7/§11).\n * NOTE: the server-side INTENT cap is being raised (wallet-api#102); the SDK\n * deliberately does NOT pre-flight-enforce it on sends (#670) — the server\n * decides, and a deterministic 422 is handled as terminal by the send path.\n */\nexport const FIELD_ENVELOPE_MAX_BYTES = 4096;\n\n// =============================================================================\n// base64 (RFC 4648, with padding) — hand-rolled so the codec is identical in\n// Node and browsers (no Buffer / btoa dependency) and decode is strict.\n// =============================================================================\n\nconst B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst B64_LOOKUP: Record<string, number> = {};\nfor (let i = 0; i < B64_ALPHABET.length; i++) B64_LOOKUP[B64_ALPHABET[i]] = i;\n\nfunction base64Encode(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i];\n const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;\n const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;\n out += B64_ALPHABET[b0 >> 2];\n out += B64_ALPHABET[((b0 & 0x03) << 4) | (b1 >> 4)];\n out += i + 1 < bytes.length ? B64_ALPHABET[((b1 & 0x0f) << 2) | (b2 >> 6)] : '=';\n out += i + 2 < bytes.length ? B64_ALPHABET[b2 & 0x3f] : '=';\n }\n return out;\n}\n\n/** Strict decode: throws on non-alphabet chars, bad length, or bad padding. */\nfunction base64Decode(s: string): Uint8Array {\n if (s.length % 4 !== 0) {\n throw new SphereError('Invalid field envelope: base64 length not a multiple of 4', 'DECRYPTION_ERROR');\n }\n let padding = 0;\n if (s.endsWith('==')) padding = 2;\n else if (s.endsWith('=')) padding = 1;\n const body = s.slice(0, s.length - padding);\n if (body.includes('=')) {\n throw new SphereError('Invalid field envelope: misplaced base64 padding', 'DECRYPTION_ERROR');\n }\n const out = new Uint8Array((s.length / 4) * 3 - padding);\n let o = 0;\n for (let i = 0; i < body.length; i += 4) {\n const n0 = B64_LOOKUP[body[i]];\n const n1 = B64_LOOKUP[body[i + 1]];\n const n2 = body[i + 2] !== undefined ? B64_LOOKUP[body[i + 2]] : 0;\n const n3 = body[i + 3] !== undefined ? B64_LOOKUP[body[i + 3]] : 0;\n if (n0 === undefined || n1 === undefined || n2 === undefined || n3 === undefined) {\n throw new SphereError('Invalid field envelope: non-base64 character', 'DECRYPTION_ERROR');\n }\n const triple = (n0 << 18) | (n1 << 12) | (n2 << 6) | n3;\n if (o < out.length) out[o++] = (triple >> 16) & 0xff;\n if (o < out.length) out[o++] = (triple >> 8) & 0xff;\n if (o < out.length) out[o++] = triple & 0xff;\n }\n return out;\n}\n\n// =============================================================================\n// Key derivation\n// =============================================================================\n\nfunction hexToBytesStrict(hex: string): Uint8Array {\n if (hex.length === 0 || hex.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(hex)) {\n throw new SphereError('Invalid private key hex for field-encryption key derivation', 'INVALID_CONFIG');\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\n/**\n * Derive the wallet's 32-byte field-encryption key (sdk-changes S6):\n * `HKDF-SHA256(ikm = wallet privkey bytes, info = \"sphere-fieldenc-v1\")`.\n *\n * Deterministic per wallet key — every device holding the seed derives the\n * same key, so envelopes round-trip across devices with no key exchange.\n *\n * @param privKeyHex - wallet secp256k1 private key, hex (the HKDF ikm is its raw bytes)\n */\nexport function deriveFieldEncryptionKey(privKeyHex: string): Uint8Array {\n const ikm = hexToBytesStrict(privKeyHex);\n const info = new TextEncoder().encode(FIELD_ENCRYPTION_HKDF_INFO);\n return hkdf(sha256, ikm, undefined, info, 32);\n}\n\n// =============================================================================\n// Envelope encrypt / decrypt\n// =============================================================================\n\n/**\n * Encrypt BINARY plaintext into the S6 wire envelope, optionally bound to associated data (AAD):\n * `\"enc1.\" + base64(nonce ‖ ciphertext)` (XChaCha20-Poly1305, random 24-byte nonce). The AAD is\n * authenticated but NOT stored in the envelope — the reader re-derives it from context, so a\n * record decrypted against a different AAD fails the poly1305 tag (E.4: AAD = `transferId:opIndex`\n * binds a checkpoint to its slot, defeating a mis-served / cross-intent replay at the crypto layer).\n */\nexport function encryptFieldBytes(key: Uint8Array, plaintext: Uint8Array, aad?: Uint8Array): string {\n const nonce = randomBytes(FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = xchacha20poly1305(key, nonce, aad).encrypt(plaintext);\n const packed = new Uint8Array(nonce.length + ciphertext.length);\n packed.set(nonce, 0);\n packed.set(ciphertext, nonce.length);\n return FIELD_ENVELOPE_PREFIX + base64Encode(packed);\n}\n\n/**\n * Decrypt an S6 wire envelope to BINARY bytes, requiring the same `aad` used at encrypt time.\n * Any tampering, wrong key, OR wrong AAD throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptFieldBytes(key: Uint8Array, envelope: string, aad?: Uint8Array): Uint8Array {\n if (typeof envelope !== 'string' || !envelope.startsWith(FIELD_ENVELOPE_PREFIX)) {\n throw new SphereError('Invalid field envelope: missing \"enc1.\" prefix', 'DECRYPTION_ERROR');\n }\n const packed = base64Decode(envelope.slice(FIELD_ENVELOPE_PREFIX.length));\n if (packed.length < FIELD_ENVELOPE_NONCE_BYTES + POLY1305_TAG_BYTES) {\n throw new SphereError('Invalid field envelope: too short for nonce + tag', 'DECRYPTION_ERROR');\n }\n const nonce = packed.slice(0, FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = packed.slice(FIELD_ENVELOPE_NONCE_BYTES);\n try {\n return xchacha20poly1305(key, nonce, aad).decrypt(ciphertext);\n } catch (err) {\n throw new SphereError('Field envelope authentication failed (tampered, wrong key, or wrong AAD)', 'DECRYPTION_ERROR', err);\n }\n}\n\n/**\n * Encrypt a UTF-8 string field into the S6 wire envelope (AAD-less). Thin wrapper over\n * {@link encryptFieldBytes} — the memo/nametag/intent-payload path.\n */\nexport function encryptField(key: Uint8Array, plaintext: string): string {\n return encryptFieldBytes(key, new TextEncoder().encode(plaintext));\n}\n\n/**\n * Decrypt an AAD-less S6 wire envelope to a UTF-8 string (memo/nametag/intent payload). Any\n * tampering throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptField(key: Uint8Array, envelope: string): string {\n return new TextDecoder().decode(decryptFieldBytes(key, envelope));\n}\n\n/**\n * The server-side shape check (ARCHITECTURE §8.3): the value must be a string,\n * carry the `enc1.` prefix, decode as base64, be long enough to hold a nonce +\n * tag, and fit the size cap. The server never sees plaintext — this is the\n * ONLY validation it performs before storing the exact UTF-8 bytes verbatim.\n *\n * Throws `SphereError('VALIDATION_ERROR')` on any violation.\n */\nexport function assertFieldEnvelopeShape(value: unknown, maxBytes: number = FIELD_ENVELOPE_MAX_BYTES): void {\n if (typeof value !== 'string') {\n throw new SphereError('Field envelope must be a string', 'VALIDATION_ERROR');\n }\n if (!value.startsWith(FIELD_ENVELOPE_PREFIX)) {\n throw new SphereError('Field envelope must start with \"enc1.\"', 'VALIDATION_ERROR');\n }\n if (new TextEncoder().encode(value).length > maxBytes) {\n throw new SphereError(`Field envelope exceeds size cap of ${maxBytes} bytes`, 'VALIDATION_ERROR');\n }\n let packed: Uint8Array;\n try {\n packed = base64Decode(value.slice(FIELD_ENVELOPE_PREFIX.length));\n } catch (err) {\n throw new SphereError('Field envelope payload is not valid base64', 'VALIDATION_ERROR', err);\n }\n if (packed.length < FIELD_ENVELOPE_NONCE_BYTES + POLY1305_TAG_BYTES) {\n throw new SphereError('Field envelope payload too short for nonce + tag', 'VALIDATION_ERROR');\n }\n}\n","/**\n * core/delivery-envelope.ts — recipient-addressed delivery envelopes\n * (sdk-changes S6; ARCHITECTURE §8.3).\n *\n * The mailbox `memo` is the one S6 field that is NOT self-scoped: it is written\n * by the SENDER but must be readable by the RECIPIENT (a different wallet). The\n * wallet-scoped field key ({@link deriveFieldEncryptionKey}) is wrong for it —\n * a memo encrypted with the sender's key can never be opened by the recipient.\n *\n * So delivery envelopes key off an **ECDH-to-recipient** shared secret instead:\n *\n * key = HKDF-SHA256(ikm = secp256k1.getSharedSecret(senderPriv, recipientPub),\n * info = \"sphere-deliveryenc-v1\") [0..32)\n *\n * ECDH is symmetric, so the recipient re-derives the identical key from\n * `(recipientPriv, senderPub)` — `entry.senderPubkey` on the wire. A self-send\n * (sender == recipient) is just `ECDH(priv, ownPub)` on both sides and still\n * round-trips.\n *\n * Crucially, the **wire bytes stay the SAME `enc1.` envelope** the self-scoped\n * field encryption uses (XChaCha20-Poly1305, random 24-byte nonce — reused\n * verbatim from {@link encryptField}/{@link decryptField}). The backend cannot\n * tell a delivery envelope from a self-scoped one and stores both opaquely:\n * operator-blind, and NO backend change (the wire prefix and size cap are\n * unchanged).\n *\n * The plaintext is a compact JSON bundle — `{ n?: senderNametag, t?: memo }`\n * (absent fields omitted) — mirroring the Nostr `{ senderNametag, text }`\n * structure so both rails carry the same two facts.\n */\n\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { secp256k1 } from '@noble/curves/secp256k1.js';\nimport { encryptField, decryptField } from './field-encryption';\nimport { SphereError } from './errors';\n\n/** HKDF info label for the ECDH-derived delivery key — versioned, distinct from S6's. */\nexport const DELIVERY_ENCRYPTION_HKDF_INFO = 'sphere-deliveryenc-v1';\n\n/** The decrypted delivery bundle (sender nametag + memo; either may be absent). */\nexport interface DeliveryBundle {\n /** The sender's own nametag (without a leading `@`). */\n senderNametag?: string;\n /** The human memo attached to the transfer. */\n memo?: string;\n}\n\nfunction hexToBytesStrict(hex: string, what: string): Uint8Array {\n if (hex.length === 0 || hex.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(hex)) {\n throw new SphereError(`Invalid ${what} hex for delivery-envelope key derivation`, 'INVALID_CONFIG');\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n return out;\n}\n\n/**\n * Derive the 32-byte symmetric key for a delivery envelope between `privKeyHex`\n * and `peerPubkeyHex` (a 33-byte compressed secp256k1 pubkey, hex):\n *\n * HKDF-SHA256(ikm = secp256k1.getSharedSecret(priv, peerPub), info = \"sphere-deliveryenc-v1\")\n *\n * Symmetric in (priv, peerPub) by ECDH, so sender and recipient derive the same\n * key; reused for a self-send (peerPub == own pubkey).\n */\nexport function deriveDeliveryEncryptionKey(privKeyHex: string, peerPubkeyHex: string): Uint8Array {\n const priv = hexToBytesStrict(privKeyHex, 'private key');\n const peerPub = hexToBytesStrict(peerPubkeyHex, 'peer public key');\n // getSharedSecret returns the 33-byte compressed shared point (incl. its\n // 02/03 prefix). HKDF the whole thing — the prefix is deterministic for a\n // fixed pair and folds into the derived key identically on both sides.\n const shared = secp256k1.getSharedSecret(priv, peerPub);\n const info = new TextEncoder().encode(DELIVERY_ENCRYPTION_HKDF_INFO);\n return hkdf(sha256, shared, undefined, info, 32);\n}\n\n/**\n * Encrypt a delivery bundle into the S6 `enc1.` wire envelope under the\n * ECDH-derived key. Returns `undefined` when there is nothing to carry (no\n * nametag and no memo) — callers then omit the field entirely.\n */\nexport function encryptDeliveryBundle(key: Uint8Array, bundle: DeliveryBundle): string | undefined {\n const compact: { n?: string; t?: string } = {};\n if (bundle.senderNametag !== undefined && bundle.senderNametag !== '') compact.n = bundle.senderNametag;\n if (bundle.memo !== undefined && bundle.memo !== '') compact.t = bundle.memo;\n if (compact.n === undefined && compact.t === undefined) return undefined;\n return encryptField(key, JSON.stringify(compact));\n}\n\n/**\n * Decrypt + parse a delivery envelope under the ECDH-derived key. Throws a\n * `SphereError('DECRYPTION_ERROR')` on a wrong key, tamper, or non-JSON\n * plaintext — the receive loop treats that as \"not for me / unreadable\" and\n * drops it, never as a fatal error.\n */\nexport function decryptDeliveryBundle(key: Uint8Array, envelope: string): DeliveryBundle {\n const plaintext = decryptField(key, envelope);\n let parsed: unknown;\n try {\n parsed = JSON.parse(plaintext);\n } catch (err) {\n throw new SphereError('Delivery envelope payload is not valid JSON', 'DECRYPTION_ERROR', err);\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new SphereError('Delivery envelope payload is not an object', 'DECRYPTION_ERROR');\n }\n const obj = parsed as { n?: unknown; t?: unknown };\n const bundle: DeliveryBundle = {};\n if (typeof obj.n === 'string') bundle.senderNametag = obj.n;\n if (typeof obj.t === 'string') bundle.memo = obj.t;\n return bundle;\n}\n","// P3b: WalletApiDeliveryPort — DeliveryPort over the §16 mailbox (§5.6/§5.7).\n// deliveryId is ALWAYS content-derived hex(SHA-256(tokenId ‖ stateHash)) — never\n// a server row id or seq. The seen-set is S7 port-owned; an entry enters it\n// ONLY after its ack succeeded.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { SerialChain } from '../../modules/payments-v2/async';\nimport type {\n AckOutcome,\n AckRequest,\n DeliverOptions,\n DeliveryPort,\n DeliveryReceipt,\n IncomingDelivery,\n} from '../../modules/payments-v2/ports';\nimport type { ScopedKV } from '../../modules/payments-v2/stores';\nimport { bytesToHex, hexToBytes } from '../../core/crypto';\nimport { logger } from '../../core/logger';\nimport {\n decryptDeliveryBundle,\n deriveDeliveryEncryptionKey,\n encryptDeliveryBundle,\n type DeliveryBundle,\n} from '../../core/delivery-envelope';\nimport { isRetryableStatus, isWalletApiHttpError } from './http';\nimport type {\n MailboxDepositEntry,\n MailboxEntryWire,\n MailboxRejectReason,\n WalletApiV2Client,\n} from './client';\nimport { uploadViaPresigned } from './storage';\n\nexport type DeliveryPortClient = Pick<\n WalletApiV2Client,\n 'uploadUrls' | 'uploadBlob' | 'fetchBlob' | 'deposit' | 'depositBatch' | 'listMailbox' | 'claim' | 'reject'\n>;\n\nexport type DeliveryCustody = 'inventory' | 'external';\n\nexport interface WakeSource {\n subscribeStream(stream: 'inventory' | 'mailbox' | 'payment_requests', handler: () => void): () => void;\n}\n\nexport class DeliveryKeysUnboundError extends Error {\n readonly code = 'DELIVERY_KEYS_UNBOUND';\n constructor() {\n super('deliveryKeys derivation not bound — bindDeliveryKeys(engine.deliveryKeys) must run first (S7)');\n this.name = 'DeliveryKeysUnboundError';\n }\n}\n\nexport class MailboxClaimFailedError extends Error {\n readonly code = 'MAILBOX_CLAIM_FAILED';\n constructor(deliveryId: string, readonly failureCode: string) {\n super(`mailbox claim failed for ${deliveryId}: ${failureCode}`);\n this.name = 'MailboxClaimFailedError';\n }\n}\n\nexport class DeliveryProtocolError extends Error {\n readonly code = 'PROTOCOL';\n constructor(message: string) {\n super(message);\n this.name = 'DeliveryProtocolError';\n }\n}\n\nexport function computeDeliveryId(tokenIdHex: string, stateHashHex: string): string {\n const tokenId = hexToBytes(tokenIdHex);\n const stateHash = hexToBytes(stateHashHex);\n const joined = new Uint8Array(tokenId.length + stateHash.length);\n joined.set(tokenId, 0);\n joined.set(stateHash, tokenId.length);\n return bytesToHex(sha256(joined));\n}\n\nexport const DELIVERY_SEEN_KEY = 'delivery:seen';\n\nexport interface DeliveryIdentity {\n privateKey: string;\n chainPubkey: string;\n}\n\nexport interface WalletApiDeliveryPortConfig {\n client: DeliveryPortClient;\n kv: ScopedKV;\n identity: DeliveryIdentity;\n /** Composition-time custody (S7) — NEVER a per-call flag. */\n custody: DeliveryCustody;\n wake?: WakeSource;\n deliveryKeys?: (blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>;\n}\n\ninterface PreparedDelivery {\n readonly bytes: Uint8Array;\n readonly tokenId: string;\n readonly stateHash: string;\n readonly deliveryId: string;\n readonly sha: string;\n}\n\n/**\n * Entries per claim/reject call. The server caps at 1000, but each entry costs\n * its own S3 read and transaction there, so a huge batch is a multi-second\n * request against an idle timeout with nothing learned about what committed.\n * 50 keeps almost all of the round-trip amortisation.\n */\nconst ACK_CHUNK = 50;\n\nfunction chunked<T>(items: readonly T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n/** Retryable = a per-entry retry hits the same wall, so the caller must NOT fall back. */\nclass RetryableAckFailure extends Error {\n readonly retryable = true;\n constructor(cause: unknown) {\n super(`mailbox ack batch could not be attempted: ${String(cause)}`);\n this.name = 'RetryableAckFailure';\n this.cause = cause;\n }\n}\n\nfunction asRetryable(err: unknown): unknown {\n return isRetryableStatus(err) ? new RetryableAckFailure(err) : err;\n}\n\nexport class WalletApiDeliveryPort implements DeliveryPort {\n readonly custody: DeliveryCustody;\n\n private readonly client: DeliveryPortClient;\n private readonly kv: ScopedKV;\n private readonly identity: DeliveryIdentity;\n private readonly wake: WakeSource | null;\n private deriveFn: ((blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>) | null;\n private readonly seenChain = new SerialChain();\n private lastIncomingEpoch: string | null = null;\n\n constructor(config: WalletApiDeliveryPortConfig) {\n this.client = config.client;\n this.kv = config.kv;\n this.identity = config.identity;\n this.custody = config.custody;\n this.wake = config.wake ?? null;\n this.deriveFn = config.deliveryKeys ?? null;\n }\n\n bindDeliveryKeys(derive: (blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>): void {\n this.deriveFn = derive;\n }\n\n private deriveKeys(blob: Uint8Array): Promise<{ tokenId: string; stateHash: string }> {\n if (this.deriveFn === null) throw new DeliveryKeysUnboundError();\n return this.deriveFn(blob);\n }\n\n // ── deliver ────────────────────────────────────────────────────────────────\n\n async deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt> {\n const receipts = await this.deliverBatch(recipientPubkey, [blob], options);\n const first = receipts[0];\n if (first === undefined) throw new DeliveryProtocolError('deliver produced no receipt');\n return first;\n }\n\n async deliverBatch(\n recipientPubkey: string,\n blobs: Uint8Array[],\n options: DeliverOptions\n ): Promise<DeliveryReceipt[]> {\n if (blobs.length === 0) return [];\n const prepared = await Promise.all(blobs.map(async (bytes) => this.prepare(bytes)));\n const envelope = this.buildEnvelope(recipientPubkey, options);\n const keyBySha = await uploadViaPresigned(\n this.client,\n prepared.map((p) => ({ sha256: p.sha, bytes: p.bytes }))\n );\n const entries = prepared.map((p): MailboxDepositEntry => {\n const key = keyBySha.get(p.sha);\n if (key === undefined) throw new DeliveryProtocolError(`upload returned no key for sha256 ${p.sha}`);\n return {\n recipientPubkey,\n key,\n transferId: options.transferId,\n tokenId: p.tokenId,\n stateHash: p.stateHash,\n ...(envelope !== undefined ? { memo: envelope } : {}),\n };\n });\n return this.depositAll(entries, prepared.map((p) => p.deliveryId));\n }\n\n private async prepare(bytes: Uint8Array): Promise<PreparedDelivery> {\n const keys = await this.deriveKeys(bytes);\n return {\n bytes,\n tokenId: keys.tokenId,\n stateHash: keys.stateHash,\n deliveryId: computeDeliveryId(keys.tokenId, keys.stateHash),\n sha: bytesToHex(sha256(bytes)),\n };\n }\n\n // sphere#487: the nametag is a per-call option and NOT port config — a\n // construction-time copy would silently go stale on registration, and only a\n // caller-supplied value is enforceable by the port contract suite (which any\n // swapped DeliveryPort must pass).\n private buildEnvelope(recipientPubkey: string, options: DeliverOptions): string | undefined {\n const key = deriveDeliveryEncryptionKey(this.identity.privateKey, recipientPubkey);\n return encryptDeliveryBundle(key, {\n senderNametag: options.senderNametag,\n memo: options.memo,\n });\n }\n\n private async depositAll(entries: MailboxDepositEntry[], deliveryIds: string[]): Promise<DeliveryReceipt[]> {\n if (entries.length > 1) {\n try {\n const results = await this.client.depositBatch(entries);\n if (results.length !== entries.length) {\n throw new DeliveryProtocolError(\n `mailbox batch deposit returned ${String(results.length)} entries for ${String(entries.length)}`\n );\n }\n return deliveryIds.map((deliveryId) => ({ deliveryId }));\n } catch (err) {\n if (!isWalletApiHttpError(err, 409)) throw err;\n }\n }\n const receipts: DeliveryReceipt[] = [];\n for (const [i, entry] of entries.entries()) {\n receipts.push(await this.depositOne(entry, deliveryIds[i] as string));\n }\n return receipts;\n }\n\n private async depositOne(entry: MailboxDepositEntry, deliveryId: string): Promise<DeliveryReceipt> {\n try {\n await this.client.deposit(entry);\n } catch (err) {\n if (!isWalletApiHttpError(err, 409)) throw err;\n }\n return { deliveryId };\n }\n\n // ── incoming ───────────────────────────────────────────────────────────────\n\n async *incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery> {\n const seen = await this.readSeen();\n let page = await this.client.listMailbox(sinceCursor === undefined ? 0 : Number(sinceCursor));\n for (;;) {\n this.lastIncomingEpoch = String(page.syncEpoch);\n for (const entry of page.entries) {\n if (entry.status !== 'unclaimed') continue;\n if (seen.has(entry.entryId)) continue;\n yield this.toIncoming(entry);\n }\n if (!page.more) return;\n page = await this.client.listMailbox(page.cursor);\n }\n }\n\n /** §5.7: the page-honest epoch — the restore-detection source Receive keys on. */\n incomingEpoch(): string | null {\n return this.lastIncomingEpoch;\n }\n\n private toIncoming(entry: MailboxEntryWire): IncomingDelivery {\n const bundle = this.openEnvelope(entry);\n return {\n deliveryId: entry.entryId,\n ...(entry.transferId !== '' ? { transferId: entry.transferId } : {}),\n ...(entry.senderPubkey !== '' ? { senderPubkey: entry.senderPubkey } : {}),\n ...(bundle.senderNametag !== undefined ? { senderNametag: bundle.senderNametag } : {}),\n ...(bundle.memo !== undefined ? { memo: bundle.memo } : {}),\n cursor: String(entry.seq),\n fetchBlob: () => this.fetchVerified(entry),\n };\n }\n\n private openEnvelope(entry: MailboxEntryWire): DeliveryBundle {\n if (entry.memo === undefined || entry.senderPubkey === '') return {};\n try {\n const key = deriveDeliveryEncryptionKey(this.identity.privateKey, entry.senderPubkey);\n return decryptDeliveryBundle(key, entry.memo);\n } catch {\n return {};\n }\n }\n\n private async fetchVerified(entry: MailboxEntryWire): Promise<Uint8Array> {\n if (entry.blobCollected === true || entry.getUrl === undefined) {\n throw new DeliveryProtocolError(`mailbox entry ${entry.entryId} has no fetchable blob (blobCollected)`);\n }\n const bytes = await this.client.fetchBlob(entry.getUrl);\n const keys = await this.deriveKeys(bytes);\n const derived = computeDeliveryId(keys.tokenId, keys.stateHash);\n if (derived !== entry.entryId) {\n throw new DeliveryProtocolError(\n `mailbox blob does not match its entry id (expected ${entry.entryId}, bytes derive ${derived})`\n );\n }\n return bytes;\n }\n\n // ── ack ────────────────────────────────────────────────────────────────────\n\n async ack(\n deliveryId: string,\n disposition: 'claimed' | 'rejected',\n reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'\n ): Promise<void> {\n if (disposition === 'claimed') {\n const result = await this.client.claim([deliveryId], this.custody === 'inventory');\n const failed = result.failed.find((f) => f.entryId === deliveryId);\n if (failed !== undefined) throw new MailboxClaimFailedError(deliveryId, failed.code);\n } else {\n await this.client.reject([deliveryId], reason);\n }\n await this.addSeenAll([deliveryId]);\n }\n\n /**\n * §5.7/#757 batched settle. Claims go out grouped, rejects grouped by reason\n * (the endpoint takes one reason per call), and the seen-set is written ONCE\n * after every HTTP call has succeeded — never on a throw, so an aborted batch\n * re-lists rather than being silently forgotten.\n */\n async ackBatch(acks: readonly AckRequest[]): Promise<readonly AckOutcome[]> {\n const settled: string[] = [];\n const outcomes: AckOutcome[] = [];\n try {\n await this.settleClaims(acks, settled, outcomes);\n await this.settleRejects(acks, settled);\n } catch (err) {\n // Chunks that DID commit are acked server-side, so the seen-set must record\n // them or a §5.4 restore re-yields deliveries this wallet already claimed.\n // A failed write is logged, not swallowed: the loss is bounded (a re-yield\n // screens against the view's durable held state and returns a claim ack, so\n // it costs a redundant ack, not a duplicate credit) but silence is not.\n await this.addSeenAll(settled).catch((seenErr: unknown) => {\n logger.warn('WalletApiDelivery', `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);\n });\n throw asRetryable(err);\n }\n await this.addSeenAll(settled);\n return [...outcomes, ...settled.map((deliveryId): AckOutcome => ({ deliveryId, status: 'settled' }))];\n }\n\n private async settleClaims(\n acks: readonly AckRequest[],\n settled: string[],\n outcomes: AckOutcome[]\n ): Promise<void> {\n const ids = acks.filter((a) => a.disposition === 'claimed').map((a) => a.deliveryId);\n for (const chunk of chunked(ids, ACK_CHUNK)) {\n const result = await this.client.claim(chunk, this.custody === 'inventory');\n settled.push(...result.claimed);\n // Idempotent re-delivery is SETTLED; treating it as unsettled stalls the\n // caller's cursor behind an entry that can never change (§6).\n settled.push(...result.alreadyClaimed.map((e) => e.entryId));\n for (const f of result.failed) {\n if (f.code === 'CONFLICT') outcomes.push({ deliveryId: f.entryId, status: 'conflict' });\n else throw new MailboxClaimFailedError(f.entryId, f.code);\n }\n }\n }\n\n private async settleRejects(acks: readonly AckRequest[], settled: string[]): Promise<void> {\n const byReason = new Map<string, string[]>();\n for (const a of acks) {\n if (a.disposition !== 'rejected') continue;\n const key = a.reason ?? '';\n const group = byReason.get(key) ?? [];\n group.push(a.deliveryId);\n byReason.set(key, group);\n }\n for (const [reason, group] of byReason) {\n for (const chunk of chunked(group, ACK_CHUNK)) {\n await this.client.reject(chunk, reason === '' ? undefined : (reason as MailboxRejectReason));\n // A 200 settles the whole requested group: reject runs in ONE server\n // transaction, and an id it skips was already claimed — terminal too.\n settled.push(...chunk);\n }\n }\n }\n\n onWake(cb: () => void): () => void {\n if (this.wake === null) return () => undefined;\n return this.wake.subscribeStream('mailbox', cb);\n }\n\n // ── seen-set (S7) ──────────────────────────────────────────────────────────\n\n private async readSeen(): Promise<Set<string>> {\n const raw = await this.kv.get<string[]>(DELIVERY_SEEN_KEY);\n return new Set(raw ?? []);\n }\n\n /** SerialChain settles-not-fulfills: a rejected write never bricks later acks. */\n private addSeenAll(deliveryIds: readonly string[]): Promise<void> {\n if (deliveryIds.length === 0) return Promise.resolve();\n return this.seenChain.enqueue(async () => {\n const seen = await this.readSeen();\n for (const id of deliveryIds) seen.add(id);\n await this.kv.set(DELIVERY_SEEN_KEY, [...seen]);\n });\n }\n}\n","/**\n * token-engine/sdk.ts — the SINGLE place that imports @unicitylabs/state-transition-sdk.\n *\n * The v1 cut-over is done: the canonical package name now resolves to the v2 SDK\n * (the migration-era `state-transition-sdk-v2` npm alias is gone, and v1 with it).\n *\n * Everything else in token-engine/ imports SDK symbols from `./sdk`, never from the package directly.\n * ESLint `no-restricted-imports` forbids importing the SDK anywhere except this file.\n *\n * Import path note: subpaths are `…/lib/<path>.js` (no `/src/`); no root barrel.\n */\n\n// ── client / aggregator / proof / network / trust base ──────────────────────\nexport { StateTransitionClient } from '@unicitylabs/state-transition-sdk/lib/StateTransitionClient.js';\nexport { AggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/AggregatorClient.js';\nexport type { IAggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/IAggregatorClient.js';\nexport { NetworkId } from '@unicitylabs/state-transition-sdk/lib/api/NetworkId.js';\nexport { CertificationData } from '@unicitylabs/state-transition-sdk/lib/api/CertificationData.js';\nexport { CertificationResponse, CertificationStatus } from '@unicitylabs/state-transition-sdk/lib/api/CertificationResponse.js';\nexport { StateId } from '@unicitylabs/state-transition-sdk/lib/api/StateId.js';\nexport { InclusionProof } from '@unicitylabs/state-transition-sdk/lib/api/InclusionProof.js';\nexport { InclusionProofResponse } from '@unicitylabs/state-transition-sdk/lib/api/InclusionProofResponse.js';\n// #739: the 'not yet certified' answer the proof loop tolerates; tests model the\n// pre-finalization window with it, which is how the deadline path is reachable.\nexport { JsonRpcNetworkError } from '@unicitylabs/state-transition-sdk/lib/api/json-rpc/JsonRpcNetworkError.js';\nexport { RootTrustBase } from '@unicitylabs/state-transition-sdk/lib/api/bft/RootTrustBase.js';\nexport { waitInclusionProof } from '@unicitylabs/state-transition-sdk/lib/util/InclusionProofUtils.js';\nexport { InclusionProofVerificationStatus } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/rule/InclusionProofVerificationRule.js';\n\n// ── token / transactions ────────────────────────────────────────────────────\nexport { Token } from '@unicitylabs/state-transition-sdk/lib/transaction/Token.js';\nexport { MintTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/MintTransaction.js';\nexport { TransferTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction.js';\nexport { CertifiedMintTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/CertifiedMintTransaction.js';\nexport { CertifiedTransferTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/CertifiedTransferTransaction.js';\nexport { TokenId } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenId.js';\nexport { TokenType } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenType.js';\nexport { TokenSalt } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenSalt.js';\nexport type { ITransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/ITransaction.js';\nexport { StateMask } from '@unicitylabs/state-transition-sdk/lib/transaction/StateMask.js';\nexport { MintJustificationVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js';\nexport { TokenIssuanceVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/TokenIssuanceVerifierService.js';\nexport { VerificationContext } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/VerificationContext.js';\nexport { UnicityCertificateVerifier } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/UnicityCertificateVerifier.js';\nexport { UnicitySealQuorumSignaturesVerificationRule } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/rule/UnicitySealQuorumSignaturesVerificationRule.js';\nexport { VerifiedSealCache } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/VerifiedSealCache.js';\nexport { Secp256k1SignatureVerifier } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Secp256k1SignatureVerifier.js';\nexport type { ITokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/ITokenVerifier.js';\nexport { WorkerTokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/WorkerTokenVerifier.js';\nexport type { IWorker } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/IWorker.js';\nexport type { IVerificationContext } from '@unicitylabs/state-transition-sdk/lib/verification/IVerificationContext.js';\n\n// ── predicates / unlock scripts ─────────────────────────────────────────────\nexport type { IPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/IPredicate.js';\nexport type { IUnlockScript } from '@unicitylabs/state-transition-sdk/lib/predicate/IUnlockScript.js';\nexport { EncodedPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/EncodedPredicate.js';\nexport { SignaturePredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicate.js';\nexport { SignaturePredicateUnlockScript } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicateUnlockScript.js';\nexport { BurnPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/BurnPredicate.js';\nexport { PredicateVerifierService } from '@unicitylabs/state-transition-sdk/lib/predicate/verification/PredicateVerifierService.js';\n\n// ── crypto / hashing ────────────────────────────────────────────────────────\nexport { SigningService } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/SigningService.js';\nexport { Signature } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Signature.js';\nexport { MintSigningService } from '@unicitylabs/state-transition-sdk/lib/crypto/MintSigningService.js';\nexport { HashAlgorithm } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/HashAlgorithm.js';\nexport { DataHash } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHash.js';\nexport { DataHasher } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasher.js';\nexport { DataHasherFactory } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasherFactory.js';\n\n// ── CBOR serialization ──────────────────────────────────────────────────────\nexport { CborSerializer } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborSerializer.js';\nexport { CborDeserializer } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborDeserializer.js';\nexport { CborError } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborError.js';\n// Head-only CBOR reads, for classifying a value envelope WITHOUT parsing its body\n// (`value-envelope.ts`): `CborDeserializer.decodeTag` asserts exhaustion, so it\n// cannot tell a corrupt envelope from a payload that carries no envelope at all.\nexport { CborReader } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborReader.js';\nexport { MajorType } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/MajorType.js';\n\n// ── payment / value / split ─────────────────────────────────────────────────\nexport type { IPaymentData } from '@unicitylabs/state-transition-sdk/lib/payment/IPaymentData.js';\nexport { Asset } from '@unicitylabs/state-transition-sdk/lib/payment/asset/Asset.js';\nexport { AssetId } from '@unicitylabs/state-transition-sdk/lib/payment/asset/AssetId.js';\nexport { PaymentAssetCollection } from '@unicitylabs/state-transition-sdk/lib/payment/asset/PaymentAssetCollection.js';\nexport { TokenSplit } from '@unicitylabs/state-transition-sdk/lib/payment/TokenSplit.js';\nexport { SplitTokenRequest } from '@unicitylabs/state-transition-sdk/lib/payment/SplitTokenRequest.js';\nexport { SplitToken } from '@unicitylabs/state-transition-sdk/lib/payment/SplitToken.js';\nexport { SplitAllocationProof } from '@unicitylabs/state-transition-sdk/lib/payment/SplitAllocationProof.js';\nexport { SplitMintJustification } from '@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustification.js';\nexport { SplitMintJustificationVerifier } from '@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustificationVerifier.js';\n\n// ── verification result types ───────────────────────────────────────────────\nexport { VerificationStatus } from '@unicitylabs/state-transition-sdk/lib/verification/VerificationStatus.js';\nexport { VerificationResult } from '@unicitylabs/state-transition-sdk/lib/verification/VerificationResult.js';\n\n// ── util ────────────────────────────────────────────────────────────────────\nexport { HexConverter } from '@unicitylabs/state-transition-sdk/lib/util/HexConverter.js';\nexport { BigintConverter } from '@unicitylabs/state-transition-sdk/lib/util/BigintConverter.js';\nexport { BitString } from '@unicitylabs/state-transition-sdk/lib/util/BitString.js';\n","/**\n * token-engine/identity.ts — legacy `DIRECT://` identity address (Path A, A6).\n *\n * Reproduces the wallet's stable L3 identity address EXACTLY as the v1\n * `UnmaskedPredicateReference` → `DirectAddress` path did, but VENDORED (no v1 SDK\n * import) so the v1 dependency can be removed at the final cut-over. Quest XP is\n * keyed on this address, so it MUST stay byte-identical — the multi-vector\n * golden test (identity.test.ts) locks it.\n *\n * The recipe (recovered from v1 `UnmaskedPredicateReference.create` + `DirectAddress.create`):\n * ref = SHA-256( CBOR[ bstr([UNMASKED]), bstr(tokenType.toCBOR()),\n * tstr(\"secp256k1\"), uint(SHA256), bstr(publicKey) ] )\n * imprint = 0x0000 ‖ ref (SHA-256 DataHash imprint)\n * address = \"DIRECT://\" ‖ hex(imprint) ‖ hex( SHA-256(imprint)[0:4] )\n *\n * The CBOR + SHA-256 are standard, so v2's CborSerializer/DataHasher produce\n * byte-identical output; the v1 enum values (UNMASKED=0, HashAlgorithm.SHA256=0)\n * and the SHA-256 imprint prefix (0x0000) are pinned as constants.\n */\n\nimport { CborSerializer, DataHasher, HashAlgorithm, HexConverter } from './sdk';\n\n/**\n * Unicity L3 token type used for identity-address derivation (immutable).\n * Also pinned as the fixed token type of self-issued Unicity ID tokens\n * (token-engine/unicity-id.ts) — the same constant the v1 nametag mint used,\n * keeping the mint deterministic per (name, wallet key).\n */\nexport const UNICITY_TOKEN_TYPE_HEX = 'f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509';\n/** v1 `SigningService.algorithm` for secp256k1. */\nconst SIGNING_ALGORITHM = 'secp256k1';\n/** v1 `EmbeddedPredicateType.UNMASKED`. */\nconst EMBEDDED_PREDICATE_UNMASKED = 0;\n/** v1 `HashAlgorithm.SHA256` (as encoded in the reference CBOR). */\nconst HASH_ALGORITHM_SHA256 = 0n;\n/** v1 SHA-256 `DataHash` imprint algorithm tag (2-byte big-endian). */\nconst SHA256_IMPRINT_PREFIX = new Uint8Array([0x00, 0x00]);\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nfunction sha256(data: Uint8Array): Promise<Uint8Array> {\n return new DataHasher(HashAlgorithm.SHA256)\n .update(data)\n .digest()\n .then((h) => h.data);\n}\n\n/**\n * Derive the legacy `DIRECT://` identity address for a compressed (33-byte)\n * secp256k1 public key. Deterministic; byte-identical to the v1 path (Path A).\n */\nexport async function deriveDirectAddress(publicKey: Uint8Array): Promise<string> {\n const tokenTypeCbor = CborSerializer.encodeByteString(hexToBytes(UNICITY_TOKEN_TYPE_HEX)); // v1 TokenType.toCBOR()\n const reference = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(new Uint8Array([EMBEDDED_PREDICATE_UNMASKED])),\n CborSerializer.encodeByteString(tokenTypeCbor),\n CborSerializer.encodeTextString(SIGNING_ALGORITHM),\n CborSerializer.encodeUnsignedInteger(HASH_ALGORITHM_SHA256),\n CborSerializer.encodeByteString(publicKey),\n );\n\n const refHash = await sha256(reference);\n const imprint = new Uint8Array([...SHA256_IMPRINT_PREFIX, ...refHash]);\n const checksum = (await sha256(imprint)).slice(0, 4);\n\n return `DIRECT://${HexConverter.encode(imprint)}${HexConverter.encode(checksum)}`;\n}\n","/**\n * token-engine/errors.ts — the engine's typed error surface (Part E.2).\n */\n\nimport { SphereError } from '../core/errors';\n\n/**\n * The source state was already consumed by a *different* transaction — the\n * fetched inclusion proof does not match the rebuilt transaction\n * (`TRANSACTION_HASH_MISMATCH`). Typically the owner's other device raced the\n * same source under a different `transferId` (ARCHITECTURE §7).\n *\n * This is a lost race, **not** an interrupted resume: the engine never applies\n * the foreign proof and never retries. The caller's recovery is to abort the\n * intent, drop the lost source from its plan, and re-plan the remainder under\n * a NEW `transferId` (never reusing the old realization) — sdk-changes E.2.\n */\nexport class TransferConflictError extends SphereError {\n /**\n * #625: the source token id (the caller's id, e.g. `v2_<genesis>`) whose state was already spent.\n * Set by PaymentsModule at the engine call site so the self-healing retry can demote it and re-plan.\n */\n conflictedSourceId?: string;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'TRANSFER_CONFLICT', cause);\n this.name = 'TransferConflictError';\n }\n}\n\n/**\n * The op's certification is INDETERMINATE: the submit was accepted (`SUCCESS`)\n * or failed ambiguously (a thrown submit POST that may have been processed\n * server-side), and the inclusion-proof fetch/verify returned NO verdict — a\n * transient network/timeout error, NOT a matching proof and NOT\n * `TRANSACTION_HASH_MISMATCH`. The source's spend MAY already be on-chain under\n * THIS `transferId`.\n *\n * Unlike {@link TransferConflictError} (a foreign tx won — abort + re-plan under\n * a NEW id), the caller MUST keep the intent OPEN: resume re-derives the\n * byte-identical transaction from `(seed, transferId, opIndex)` and recovers the\n * certified proof + recipient blob, or records the spend if a foreign tx won the\n * race — never a second on-chain spend (sdk-changes E.2/E.3, #631).\n */\nexport class ProofUnconfirmedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CERTIFICATION_UNCONFIRMED', cause);\n this.name = 'ProofUnconfirmedError';\n }\n}\n\n/**\n * A split's burn certified but its checkpoint (sdk-changes E.4, sphere-sdk#501) could NOT be\n * durably persisted — the `SplitCheckpointStore.put` rejected (network / 5xx / timeout / quota) —\n * so NO mint leg was submitted. The burn is on-chain (funds in-flight, not lost); the outputs are\n * fully recoverable on resume.\n *\n * Keep-open family (like {@link ProofUnconfirmedError}): the caller MUST keep the intent OPEN and\n * resume under the SAME `transferId` — the next attempt re-derives the byte-identical burn,\n * re-persists the checkpoint (content-idempotent), and mints. NEVER abort.\n */\nexport class CheckpointPersistFailedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_PERSIST_FAILED', cause);\n this.name = 'CheckpointPersistFailedError';\n }\n}\n\n/**\n * A split cannot be rebuilt from its checkpoint, in a way that is NOT a lost race: either a mint\n * leaf is already certified on-chain but no stored bytes reproduce its certified transactionHash\n * (server data loss / withholding, or a pre-E.4 legacy intent), or a stored checkpoint fails its\n * byte-binding checks (the re-derived burn tx ≠ the stored bytes — cross-version derivation drift\n * — or a corrupt stored proof, or a burnt-token re-encode mismatch).\n *\n * Distinct from {@link TransferConflictError}: a split-mint stateId is HKDF-derived from\n * `(seed, transferId)`, so only a seed-holder under THIS `transferId` can have certified it — this\n * is never a foreign spend. Keep-open, alert loudly: the caller MUST NOT abort, NOT complete, and\n * NOT record the source as foreign-spent (sdk-changes E.4).\n */\nexport class SplitCheckpointLostError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'SPLIT_CHECKPOINT_LOST', cause);\n this.name = 'SplitCheckpointLostError';\n }\n}\n\n/**\n * A stored split checkpoint (sdk-changes E.4) is authentic and byte-bound to the re-derived burn\n * transaction, but its inclusion proof no longer verifies against the CURRENT trust base\n * (`INVALID_TRUSTBASE`) — a validator-set / quorum rotation while the intent was open. The bytes\n * are NOT wrong; re-burning would strand the certified split, so the engine never falls through to\n * a re-burn.\n *\n * Keep-open, distinct signal: the operational remedy is to drain open split intents BEFORE a\n * validator rotation (the SDK has no epoch map — single-epoch trust base, ARCHITECTURE §8.2/§19).\n */\nexport class CheckpointTrustbaseMismatchError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_TRUSTBASE_MISMATCH', cause);\n this.name = 'CheckpointTrustbaseMismatchError';\n }\n}\n","/**\n * NFT payload codec (#785, normative spec: docs/NFT-METADATA.md). Recognition is\n * display-only and never throws, so no path that can refuse a token may depend on\n * it. One validator set serves the encoder and the decoder alike.\n */\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { SphereError } from '../core/errors';\n\nimport {\n CborDeserializer,\n CborReader,\n CborSerializer,\n type DataHash,\n DataHasher,\n HashAlgorithm,\n HexConverter,\n MajorType,\n NetworkId,\n Signature,\n SigningService,\n} from './sdk';\n\nexport const NFT_METADATA_TAG = 39052n;\nexport const NFT_MEDIA_TAG = 39053n;\nexport const NFT_LINK_TAG = 39054n;\nexport const NFT_SIGNED_TAG = 39055n;\nexport const NFT_FORMAT_VERSION = 1n;\n/** The media type of an NftLink that points at a metadata document instead of a media file. */\nexport const NFT_DOCUMENT_MEDIA_TYPE = 'application/vnd.unicity.nft+cbor';\n\n/** An inline file. */\nexport interface NftMedia {\n readonly kind: 'media';\n readonly media_type: string;\n readonly bytes: Uint8Array;\n}\n\n/** A hosted file, pinned by the SHA-256 of its bytes (64 hex; decoded lowercase). */\nexport interface NftLink {\n readonly kind: 'link';\n readonly media_type: string;\n readonly uri: string;\n readonly sha256: string;\n}\n\nexport type NftMediaRef = NftMedia | NftLink;\n\nexport interface NftAttribute {\n readonly trait_type: string;\n /** Text, or an integer within ±(2^53 − 1). Decimals and larger numbers are text. */\n readonly value: string | number;\n}\n\n/** ERC-721 field names; an absent optional field is `null`, never `''`. */\nexport interface NftMetadata {\n readonly kind: 'metadata';\n readonly name: string;\n readonly description: string | null;\n readonly image: NftMediaRef | null;\n readonly animation_url: NftMediaRef | null;\n readonly external_url: string | null;\n readonly attributes: readonly NftAttribute[];\n readonly collection: string | null;\n /** The collection the item claims: 1–64 bytes as even-length hex (decoded lowercase). Never verified here. */\n readonly collection_id: string | null;\n}\n\nexport type NftContent = NftMetadata | NftMedia | NftLink;\nexport type NftSignatureStatus = 'unsigned' | 'valid' | 'invalid';\ntype NftDocument = NftMetadata | NftMedia;\n\nexport interface ParsedNft {\n readonly content: NftContent;\n /** Present iff the top level is NftSigned. */\n readonly signed: {\n readonly creator: Uint8Array;\n readonly payload: Uint8Array;\n readonly signature: Uint8Array;\n } | null;\n}\n\n/** What an NftSigned signature binds besides its payload, exactly as the token's mint records it. */\nexport interface NftSignatureContext {\n /** The network identifier α (`NetworkId.id`). */\n readonly networkId: number | bigint;\n /** The genesis recipient predicate, as `EncodedPredicate.toCBOR()` bytes. */\n readonly recipientPredicate: Uint8Array;\n /** The 32 raw token id bytes. */\n readonly tokenId: Uint8Array;\n readonly tokenType: Uint8Array;\n}\n\nconst METADATA_ARITY = 9;\nconst MEDIA_ARITY = 3;\nconst LINK_ARITY = 4;\nconst SIGNED_ARITY = 4;\nconst CREATOR_BYTES = 33;\nconst SIGNATURE_BYTES = 65;\nconst MAX_URI_LENGTH = 2048;\nconst LINK_SCHEMES = ['https://', 'ipfs://', 'ar://'];\nconst SIGNED_DOMAIN = new TextEncoder().encode('UNICITY_NFT_SIGNED');\nconst MEDIA_TYPE_PATTERN = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/;\nconst SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;\nconst COLLECTION_ID_PATTERN = /^(?:[0-9a-f]{2}){1,64}$/i;\nconst LONE_SURROGATE = /\\p{Cs}/u;\nconst CBOR_MAJOR_TYPE_MASK = 0b1110_0000;\nconst ATTRIBUTE_VALUE_RULE =\n 'must be non-empty text or an integer within ±(2^53 − 1) — write decimals and larger numbers as text';\nconst COLLECTION_ID_RULE = 'must be null or 1–64 bytes as even-length hex (2–128 characters)';\nconst DOCUMENT_AS_MEDIA_RULE = `must not be ${NFT_DOCUMENT_MEDIA_TYPE}: a document link is a token's content, never media`;\n// The SDK's text decoder substitutes U+FFFD, which would recognise invalid UTF-8;\n// ignoreBOM keeps a leading U+FEFF so a decoded string re-encodes byte-identically.\nconst UTF8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });\n\n// ── shared field rules (encoder and decoder) ────────────────────────────────\n\nfunction refuse(field: string, rule: string, cause?: unknown): SphereError {\n return new SphereError(`Invalid NFT ${field}: ${rule}`, 'VALIDATION_ERROR', cause);\n}\n\nfunction ensure(ok: boolean, field: string, rule: string): void {\n if (!ok) throw refuse(field, rule);\n}\n\nconst fieldName = (prefix: string, name: string): string => (prefix === '' ? name : `${prefix}.${name}`);\n\n/** Non-empty and representable as UTF-8 exactly (a lone surrogate is not). */\nconst isText = (value: unknown): value is string =>\n typeof value === 'string' && value.length > 0 && !LONE_SURROGATE.test(value);\n\nconst isBytes = (value: unknown, length?: number): value is Uint8Array =>\n value instanceof Uint8Array && (length === undefined ? value.length > 0 : value.length === length);\n\nconst isMediaType = (value: unknown): boolean => typeof value === 'string' && MEDIA_TYPE_PATTERN.test(value);\n\nconst isCollectionId = (value: unknown): boolean => typeof value === 'string' && COLLECTION_ID_PATTERN.test(value);\n\nconst isAttributeValue = (value: unknown): boolean =>\n typeof value === 'number' ? Number.isSafeInteger(value) : isText(value);\n\nfunction hasSpaceOrControl(value: string): boolean {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (code <= 0x20 || code === 0x7f) return true;\n }\n return false;\n}\n\nfunction isLinkUri(value: unknown): boolean {\n if (!isText(value) || value.length > MAX_URI_LENGTH || hasSpaceOrControl(value)) return false;\n const scheme = LINK_SCHEMES.find((prefix) => value.startsWith(prefix));\n return scheme !== undefined && value.length > scheme.length;\n}\n\nfunction checkText(field: string, value: unknown): void {\n ensure(isText(value), field, 'must be non-empty, well-formed text');\n}\n\nfunction checkOptionalText(field: string, value: unknown): void {\n ensure(value === null || isText(value), field, 'must be null or non-empty, well-formed text');\n}\n\nfunction checkMediaType(field: string, value: unknown): void {\n ensure(isMediaType(value), field, 'must be a lowercase type/subtype media type without parameters');\n}\n\nfunction checkMedia(prefix: string, media: NftMedia): void {\n checkMediaType(fieldName(prefix, 'media_type'), media.media_type);\n ensure(isBytes(media.bytes), fieldName(prefix, 'bytes'), 'must be non-empty bytes');\n}\n\nfunction checkLink(prefix: string, link: NftLink): void {\n checkMediaType(fieldName(prefix, 'media_type'), link.media_type);\n ensure(\n isLinkUri(link.uri),\n fieldName(prefix, 'uri'),\n `must be an https://, ipfs:// or ar:// URI of at most ${MAX_URI_LENGTH} characters with no whitespace or control characters`,\n );\n ensure(\n typeof link.sha256 === 'string' && SHA256_HEX_PATTERN.test(link.sha256),\n fieldName(prefix, 'sha256'),\n 'must be the 64-hex SHA-256 of the linked file',\n );\n}\n\nfunction checkMediaRef(field: string, ref: NftMediaRef | null): void {\n if (ref === null) return;\n if (ref?.kind === 'media') return checkMedia(field, ref);\n if (ref?.kind !== 'link') throw refuse(field, 'must be an NftMedia, an NftLink or null');\n checkLink(field, ref);\n ensure(!isNftDocumentLink(ref), fieldName(field, 'media_type'), DOCUMENT_AS_MEDIA_RULE);\n}\n\nfunction checkAttributes(attributes: readonly NftAttribute[]): void {\n ensure(Array.isArray(attributes), 'attributes', 'must be an array — [] when there are none');\n // entries(), not forEach: a sparse array's holes must be refused, not skipped.\n for (const [index, attribute] of attributes.entries()) {\n checkText(`attributes[${index}].trait_type`, attribute?.trait_type);\n ensure(isAttributeValue(attribute?.value), `attributes[${index}].value`, ATTRIBUTE_VALUE_RULE);\n }\n}\n\nfunction checkMetadata(metadata: NftMetadata): void {\n checkText('name', metadata.name);\n checkOptionalText('description', metadata.description);\n checkMediaRef('image', metadata.image);\n checkMediaRef('animation_url', metadata.animation_url);\n checkOptionalText('external_url', metadata.external_url);\n checkAttributes(metadata.attributes);\n checkOptionalText('collection', metadata.collection);\n ensure(metadata.collection_id === null || isCollectionId(metadata.collection_id), 'collection_id', COLLECTION_ID_RULE);\n}\n\nfunction checkContent(content: NftContent): void {\n switch (content?.kind) {\n case 'metadata':\n return checkMetadata(content);\n case 'media':\n return checkMedia('', content);\n case 'link':\n return checkLink('', content);\n default:\n throw refuse('content', \"kind must be 'metadata', 'media' or 'link'\");\n }\n}\n\nfunction checkSignedParts(creator: unknown, signature: unknown): void {\n ensure(isBytes(creator, CREATOR_BYTES), 'creator', 'must be a 33-byte compressed secp256k1 public key');\n ensure(isBytes(signature, SIGNATURE_BYTES), 'signature', 'must be 65 bytes: r(32) ‖ s(32) ‖ recovery(1)');\n}\n\n// ── encoder ─────────────────────────────────────────────────────────────────\n\nconst text = (value: string): Uint8Array => CborSerializer.encodeTextString(value);\n\nconst optionalText = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, CborSerializer.encodeTextString);\n\nfunction versioned(tag: bigint, ...fields: Uint8Array[]): Uint8Array {\n return CborSerializer.encodeTag(\n tag,\n CborSerializer.encodeArray(CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION), ...fields),\n );\n}\n\n/** Major type 1 shares the unsigned head layout; the SDK serializer has no encoder for it. */\nfunction integerCbor(value: number): Uint8Array {\n if (value >= 0) return CborSerializer.encodeUnsignedInteger(value);\n const head = CborSerializer.encodeUnsignedInteger(-1 - value);\n head[0] |= MajorType.NEGATIVE_INTEGER;\n return head;\n}\n\nfunction mediaCbor(media: NftMedia): Uint8Array {\n return versioned(NFT_MEDIA_TAG, text(media.media_type), CborSerializer.encodeByteString(media.bytes));\n}\n\nfunction linkCbor(link: NftLink): Uint8Array {\n const digest = HexConverter.decode(link.sha256.toLowerCase());\n return versioned(NFT_LINK_TAG, text(link.media_type), text(link.uri), CborSerializer.encodeByteString(digest));\n}\n\nfunction mediaRefCbor(ref: NftMediaRef | null): Uint8Array {\n if (ref === null) return CborSerializer.encodeNull();\n return ref.kind === 'media' ? mediaCbor(ref) : linkCbor(ref);\n}\n\nfunction attributeCbor({ trait_type, value }: NftAttribute): Uint8Array {\n return CborSerializer.encodeArray(text(trait_type), typeof value === 'string' ? text(value) : integerCbor(value));\n}\n\n/**\n * The SDK's array head over a list of any length. Spreading the list into\n * `encodeArray` arguments overflows the call stack past ~125k items (fewer in JSC).\n */\nfunction arrayCbor(items: readonly Uint8Array[]): Uint8Array {\n const head = CborSerializer.encodeUnsignedInteger(items.length);\n head[0] |= MajorType.ARRAY;\n const out = new Uint8Array(items.reduce((length, item) => length + item.length, head.length));\n out.set(head);\n let offset = head.length;\n for (const item of items) {\n out.set(item, offset);\n offset += item.length;\n }\n return out;\n}\n\nconst optionalHexBytes = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, (hex) => CborSerializer.encodeByteString(HexConverter.decode(hex.toLowerCase())));\n\nfunction metadataCbor(metadata: NftMetadata): Uint8Array {\n return versioned(\n NFT_METADATA_TAG,\n text(metadata.name),\n optionalText(metadata.description),\n mediaRefCbor(metadata.image),\n mediaRefCbor(metadata.animation_url),\n optionalText(metadata.external_url),\n arrayCbor(metadata.attributes.map(attributeCbor)),\n optionalText(metadata.collection),\n optionalHexBytes(metadata.collection_id),\n );\n}\n\n/** Encode one unsigned item. Throws SphereError('…', 'VALIDATION_ERROR') naming the offending field. */\nexport function encodeNftContent(content: NftContent): Uint8Array {\n checkContent(content);\n if (content.kind === 'metadata') return metadataCbor(content);\n return content.kind === 'media' ? mediaCbor(content) : linkCbor(content);\n}\n\n/** Wrap an encoded unsigned item; `signature` is `Signature.encode()` over {@link nftSignedDigest}. */\nexport function encodeNftSigned(creator: Uint8Array, payload: Uint8Array, signature: Uint8Array): Uint8Array {\n checkSignedParts(creator, signature);\n checkContent(signablePayload(payload));\n return versioned(\n NFT_SIGNED_TAG,\n CborSerializer.encodeByteString(creator),\n payload,\n CborSerializer.encodeByteString(signature),\n );\n}\n\nfunction signablePayload(payload: Uint8Array): NftContent {\n try {\n return decodeItem(UNSIGNED_DECODERS, 'payload', payload);\n } catch (error) {\n throw refuse('payload', 'must be exactly one encoded NftMetadata, NftMedia or NftLink item', error);\n }\n}\n\n// ── decoder (structure only; value rules are the shared checks above) ──────\n\ntype BodyDecoder<T> = (body: Uint8Array) => T;\n\nconst majorTypeOf = (item: Uint8Array): MajorType => (item.at(0) ?? 0) & CBOR_MAJOR_TYPE_MASK;\n\nfunction decodeText(item: Uint8Array): string {\n const reader = new CborReader(item);\n const bytes = reader.read(Number(reader.readLength(MajorType.TEXT_STRING)));\n reader.assertExhausted();\n return UTF8.decode(bytes);\n}\n\nconst decodeOptionalText = (item: Uint8Array): string | null => CborDeserializer.decodeNullable(item, decodeText);\n\nfunction decodeAttributeValue(item: Uint8Array): string | number {\n const major = majorTypeOf(item);\n if (major === MajorType.TEXT_STRING) return decodeText(item);\n const isInteger = major === MajorType.UNSIGNED_INTEGER || major === MajorType.NEGATIVE_INTEGER;\n ensure(isInteger, 'attribute value', ATTRIBUTE_VALUE_RULE);\n const reader = new CborReader(item);\n const magnitude = reader.readLength(major);\n reader.assertExhausted();\n return Number(major === MajorType.UNSIGNED_INTEGER ? magnitude : -1n - magnitude);\n}\n\nfunction decodeAttributes(item: Uint8Array): NftAttribute[] {\n return CborDeserializer.decodeArray(item).map((entry) => {\n const [traitType, value] = CborDeserializer.decodeArray(entry, 2);\n return { trait_type: decodeText(traitType), value: decodeAttributeValue(value) };\n });\n}\n\nfunction versionedFields(body: Uint8Array, arity: number): Uint8Array[] {\n const fields = CborDeserializer.decodeArray(body, arity);\n ensure(CborDeserializer.decodeUnsignedInteger(fields[0]) === NFT_FORMAT_VERSION, 'version', 'must be 1');\n return fields;\n}\n\nfunction decodeMedia(body: Uint8Array): NftMedia {\n const [, mediaType, bytes] = versionedFields(body, MEDIA_ARITY);\n return { kind: 'media', media_type: decodeText(mediaType), bytes: CborDeserializer.decodeByteString(bytes) };\n}\n\nconst decodeHex = (item: Uint8Array): string => HexConverter.encode(CborDeserializer.decodeByteString(item));\n\nfunction decodeLink(body: Uint8Array): NftLink {\n const [, mediaType, uri, digest] = versionedFields(body, LINK_ARITY);\n return {\n kind: 'link',\n media_type: decodeText(mediaType),\n uri: decodeText(uri),\n sha256: decodeHex(digest),\n };\n}\n\nfunction decodeMetadata(body: Uint8Array): NftMetadata {\n const fields = versionedFields(body, METADATA_ARITY);\n return {\n kind: 'metadata',\n name: decodeText(fields[1]),\n description: decodeOptionalText(fields[2]),\n image: decodeMediaRef('image', fields[3]),\n animation_url: decodeMediaRef('animation_url', fields[4]),\n external_url: decodeOptionalText(fields[5]),\n attributes: decodeAttributes(fields[6]),\n collection: decodeOptionalText(fields[7]),\n collection_id: CborDeserializer.decodeNullable(fields[8], decodeHex),\n };\n}\n\n// The nesting rules: a media slot holds NftMedia or NftLink (never a document link,\n// which checkMediaRef refuses); NftSigned wraps any unsigned item and itself appears\n// only at the top level; a linked document is NftMetadata or NftMedia.\nconst MEDIA_REF_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftMediaRef>> = new Map<bigint, BodyDecoder<NftMediaRef>>([\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst UNSIGNED_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftContent>> = new Map<bigint, BodyDecoder<NftContent>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst DOCUMENT_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftDocument>> = new Map<bigint, BodyDecoder<NftDocument>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n]);\n\nfunction decodeBody<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, tag: bigint, body: Uint8Array): T {\n const decode = decoders.get(tag);\n if (decode === undefined) throw refuse(field, `tag ${tag} is not allowed here`);\n return decode(body);\n}\n\nfunction decodeItem<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, item: Uint8Array): T {\n const { tag, data } = CborDeserializer.decodeTag(item);\n return decodeBody(decoders, field, tag, data);\n}\n\nfunction decodeMediaRef(field: string, item: Uint8Array): NftMediaRef | null {\n return CborDeserializer.decodeNullable(item, (ref) => decodeItem(MEDIA_REF_DECODERS, field, ref));\n}\n\nfunction decodeSigned(body: Uint8Array): ParsedNft {\n const [, creatorItem, payload, signatureItem] = versionedFields(body, SIGNED_ARITY);\n const creator = CborDeserializer.decodeByteString(creatorItem);\n const signature = CborDeserializer.decodeByteString(signatureItem);\n checkSignedParts(creator, signature);\n return { content: decodeItem(UNSIGNED_DECODERS, 'payload', payload), signed: { creator, payload, signature } };\n}\n\nfunction decodePayload(data: Uint8Array): ParsedNft {\n const { tag, data: body } = CborDeserializer.decodeTag(data);\n if (tag === NFT_SIGNED_TAG) return decodeSigned(body);\n return { content: decodeBody(UNSIGNED_DECODERS, 'payload', tag, body), signed: null };\n}\n\n/** Structural parse of a genesis payload. NEVER throws; null = not a recognised NFT. */\nexport function parseNftPayload(data: Uint8Array | null): ParsedNft | null {\n if (data === null) return null;\n try {\n const parsed = decodePayload(data);\n checkContent(parsed.content);\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse the file a document link points at: exactly one NftMetadata or NftMedia item.\n * NEVER throws; null = not a document. Check the bytes with verifyNftLinkContent first.\n */\nexport function parseNftDocument(bytes: Uint8Array): NftMetadata | NftMedia | null {\n try {\n const document = decodeItem(DOCUMENT_DECODERS, 'document', bytes);\n checkContent(document);\n return document;\n } catch {\n return null;\n }\n}\n\n/** Is this an NftLink to a metadata document ({@link NFT_DOCUMENT_MEDIA_TYPE}), resolved with parseNftDocument? */\nexport function isNftDocumentLink(content: NftContent): boolean {\n return content?.kind === 'link' && content.media_type === NFT_DOCUMENT_MEDIA_TYPE;\n}\n\n// ── signature ───────────────────────────────────────────────────────────────\n\n/**\n * SHA-256 of CBOR `[h'UNICITY_NFT_SIGNED', 1, α, h(recipient predicate), h(token id), h(token type), h(payload)]`:\n * every term a byte string except the version and α, as in the yellowpaper genesis commitment.\n */\nexport function nftSignedDigest(context: NftSignatureContext, payload: Uint8Array): Promise<DataHash> {\n const preimage = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(SIGNED_DOMAIN),\n CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION),\n CborSerializer.encodeUnsignedInteger(NetworkId.fromId(context.networkId).id),\n CborSerializer.encodeByteString(context.recipientPredicate),\n CborSerializer.encodeByteString(context.tokenId),\n CborSerializer.encodeByteString(context.tokenType),\n CborSerializer.encodeByteString(payload),\n );\n return new DataHasher(HashAlgorithm.SHA256).update(preimage).digest();\n}\n\n/** Recovering verification: binds the recovery byte and refuses high-s. Never throws. */\nexport async function verifyNftSignature(\n signed: NonNullable<ParsedNft['signed']>,\n context: NftSignatureContext,\n): Promise<Exclude<NftSignatureStatus, 'unsigned'>> {\n try {\n if (!SigningService.isPublicKeyValid(signed.creator)) return 'invalid';\n const signature = Signature.decode(signed.signature);\n const digest = await nftSignedDigest(context, signed.payload);\n return (await SigningService.verifyWithPublicKey(digest, signature, signed.creator)) ? 'valid' : 'invalid';\n } catch {\n return 'invalid';\n }\n}\n\n/** Does `bytes` match the link's sha256? Pure, sync. */\nexport function verifyNftLinkContent(link: NftLink, bytes: Uint8Array): boolean {\n return HexConverter.encode(sha256(bytes)) === link.sha256.toLowerCase();\n}\n","/**\n * token-engine/SphereTokenEngine.ts — the real ITokenEngine adapter (Track A).\n *\n * The full sender-driven engine over the v2 SDK: identity, value reads,\n * serialization, verification, mint, transfer, split and spent-status. All\n * crypto/value logic is the SDK's; this class orchestrates build → submit →\n * wait-proof → certify → realize, and maps SDK errors/states to the\n * sphere-domain ITokenEngine port.\n *\n * SDK objects are injected via `EngineDeps` (built by the factory in A4, or by\n * test wiring around TestAggregatorClient), keeping the engine logic independent\n * of how the aggregator/trust base are constructed.\n *\n * Advertises `deterministicMint` (F13): a same-seed `mint` re-call recovers an\n * existing certification instead of minting a second token.\n */\n\nimport { SphereError, type SphereErrorCode } from '../core/errors';\nimport {\n awaitProofBounded,\n certificationDeadline,\n resolveProofTimeoutMs,\n retryTransient,\n TransientSubmitAnswer,\n} from './proof-wait';\nimport { certificationFailure } from './certification-outcome';\nimport { randomUUID } from '../core/uuid';\nimport {\n CheckpointPersistFailedError,\n CheckpointTrustbaseMismatchError,\n ProofUnconfirmedError,\n SplitCheckpointLostError,\n TransferConflictError,\n} from './errors';\nimport { deriveDirectAddress } from './identity';\nimport { deriveDeliveryKeys } from './blob-keys';\nimport { deriveRealization } from './realization';\nimport { planNftMint, readTokenNft } from './nft-ops';\nimport { burntTokenFromCheckpoint, encodeCheckpoint } from './split-checkpoint';\nimport {\n CertificationData,\n CertificationStatus,\n EncodedPredicate,\n HexConverter,\n type InclusionProof,\n InclusionProofVerificationStatus,\n type ITransaction,\n type MintJustificationVerifierService,\n MintTransaction,\n type NetworkId,\n PaymentAssetCollection,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n SignaturePredicate,\n SignaturePredicateUnlockScript,\n type SigningService,\n SplitMintJustification,\n type SplitToken,\n SplitTokenRequest,\n StateId,\n StateMask,\n type StateTransitionClient,\n Token,\n TokenSalt,\n TokenSplit,\n TokenType,\n TransferTransaction,\n type VerificationContext,\n VerificationStatus,\n waitInclusionProof,\n type ITokenVerifier,\n} from './sdk';\nimport { decodeSpherePaymentData, SpherePaymentData, sphereAssetToSdk } from './SpherePaymentData';\nimport { assertMintableData, classifyValueEnvelope, wrapToken } from './value-envelope';\nimport type { EngineOpOptions, ITokenEngine } from './engine';\nimport type {\n BuildNftMintParams,\n CoinId,\n EngineIdentity,\n EngineVerifyResult,\n MintDataTokenParams,\n MintParams,\n NftMintPlan,\n NftReading,\n SphereToken,\n SphereValue,\n SplitParams,\n SplitResult,\n TokenBlob,\n TransferParams,\n} from './types';\n\n/** SDK objects the engine operates with; assembled by the factory (A4) or test wiring. */\n/** An `ITokenVerifier` that also owns terminable resources (a worker pool). */\nexport interface DisposableTokenVerifier extends ITokenVerifier {\n dispose(): void;\n}\n\nexport interface EngineDeps {\n readonly client: StateTransitionClient;\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly mintJustificationVerifier: MintJustificationVerifierService;\n readonly verificationContext: VerificationContext;\n /**\n * Opt-in parallel verifier (EngineConfig.verification). Absent → tokens verify\n * sequentially via `Token.verify`, which is what every release before 2.0.2 did.\n */\n readonly tokenVerifier?: DisposableTokenVerifier;\n /** The wallet's signing key (its identity + the spender for transfers it owns). */\n readonly signingService: SigningService;\n /**\n * The same key as raw bytes — the HKDF ikm for deterministic realization\n * (Part E.1; SigningService does not expose it back).\n */\n readonly privateKey: Uint8Array;\n readonly networkId: NetworkId;\n /** Inclusion-proof poll cadence in ms (#683); undefined → the tuned default below. */\n readonly proofPollIntervalMs?: number;\n /** Deadline for one inclusion-proof wait; defaults to DEFAULT_PROOF_TIMEOUT_MS (#739). */\n readonly proofTimeoutMs?: number;\n}\n\n/**\n * #683: default inclusion-proof poll interval (ms). Finer than the sdk's 1000ms\n * default so a ~1.2s finalization is caught near ~1.2-1.5s instead of at the 2s\n * poll boundary. Bounded by waitInclusionProof's 10s abort; the extra polls are\n * cheap read-only getInclusionProof calls confined to the ~1.5s finalization window.\n */\nexport const DEFAULT_PROOF_POLL_INTERVAL_MS = 300;\n\n/**\n * #684: max split-mint legs minted concurrently. The mints are independent off the\n * one burn, but an UNBOUNDED fan-out would submit + proof-poll every leg at once\n * against the gateway (the prior sequential loop naturally paced it to one). This\n * cap keeps a typical split (K=2 — payment + change) fully parallel while bounding\n * gateway load on a large multi-output split.\n */\nconst MAX_MINT_CONCURRENCY = 8;\n\n/**\n * The keep-open engine errors a split leg can raise — mirrors PaymentsModule's `keepOpen` set.\n * When one of these settles a parallel mint fan-out, the leg's spend MAY already be certified\n * on-chain, so the intent MUST stay OPEN for checkpoint-based resume; the fan-out must surface a\n * keep-open outcome rather than an abortable clean failure that would strand a certified sibling\n * (#684). Only ProofUnconfirmedError / SplitCheckpointLostError are reachable from a mint leg\n * today; the checkpoint pair is included so the classifier stays faithful to the keep-open family.\n */\nfunction isKeepOpenSplitError(err: unknown): boolean {\n return (\n err instanceof ProofUnconfirmedError ||\n err instanceof CheckpointPersistFailedError ||\n err instanceof SplitCheckpointLostError ||\n err instanceof CheckpointTrustbaseMismatchError\n );\n}\n\n/** Canonical lowercase UUID — the spec's `transferId` wire form (sdk-changes E.1). */\nconst TRANSFER_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n/**\n * The KNOWN validation-reject submit statuses: a well-formed rejection that PROVES the\n * state was never certified (a byte-identical resume of a *valid* tx never later returns\n * a format/signature/state/shard-mismatch failure). E.2 is status-AGNOSTIC for everything\n * else: an UNKNOWN or transitional non-SUCCESS status (e.g. the gateway's transitional\n * `STATE_ID_EXISTS`) means \"a certification for this state MAY already exist\" — it must be\n * treated as possibly-certified (keep the intent OPEN — #631), NEVER a clean abort. Any\n * status outside this set therefore falls through to `ProofUnconfirmedError`.\n *\n * v3's REQUEST_EXPIRED and SERVICE_NOT_READY stay OUT despite their names: each\n * reports only that THIS submit was not admitted, never that no earlier attempt\n * certified. Pinned by expires-at.test.ts.\n */\nconst CLEAN_REJECT_STATUSES: ReadonlySet<string> = new Set([\n CertificationStatus.STATE_ID_MISMATCH,\n CertificationStatus.SIGNATURE_VERIFICATION_FAILED,\n CertificationStatus.INVALID_SIGNATURE_FORMAT,\n CertificationStatus.INVALID_PUBLIC_KEY_FORMAT,\n CertificationStatus.INVALID_SOURCE_STATE_HASH_FORMAT,\n CertificationStatus.INVALID_TRANSACTION_HASH_FORMAT,\n CertificationStatus.UNSUPPORTED_ALGORITHM,\n CertificationStatus.INVALID_SHARD,\n]);\n\n/** The deterministic split plan (burn leg + per-output mint requests) — `TokenSplit.split`'s result. */\ntype SplitPlan = Awaited<ReturnType<typeof TokenSplit.split>>;\n\n/** Threaded through the E.4 burnt-token resolution so its helpers stay within the max-params bound. */\ninterface SplitContext {\n readonly params: SplitParams;\n readonly split: SplitPlan;\n readonly transferId: string;\n readonly options?: EngineOpOptions | undefined;\n}\n\nexport class SphereTokenEngine implements ITokenEngine {\n /** F13 advertisement: mint under a (transferId, opIndex) seed is idempotent-recoverable — a same-seed re-call converges, never double-mints. */\n public readonly deterministicMint = true;\n\n /** Hex form of the wallet key — deriveRealization's ikm input (Part E.1). */\n private readonly privateKeyHex: string;\n\n private readonly proofTimeoutMs: number;\n\n public constructor(private readonly deps: EngineDeps) {\n this.privateKeyHex = HexConverter.encode(deps.privateKey);\n // Refused here, not per op: a bad deadline must not surface as a money error.\n this.proofTimeoutMs = resolveProofTimeoutMs(deps.proofTimeoutMs);\n }\n\n // ── identity ────────────────────────────────────────────────────────────────\n\n public getIdentity(): EngineIdentity {\n return { chainPubkey: new Uint8Array(this.deps.signingService.publicKey) };\n }\n\n /** Legacy DIRECT:// address (Path A). Async: the derivation hashes via the SDK. */\n public deriveIdentityAddress(pubkey?: Uint8Array): Promise<string> {\n return deriveDirectAddress(pubkey ?? this.deps.signingService.publicKey);\n }\n\n // ── value (read) ─────────────────────────────────────────────────────────────\n\n public readValue(token: SphereToken): SphereValue | null {\n return token.value;\n }\n\n public balanceOf(token: SphereToken, coinId: CoinId): bigint {\n let sum = 0n;\n for (const asset of token.value?.assets ?? []) {\n if (asset.coinId === coinId) sum += asset.amount;\n }\n return sum;\n }\n\n public tokenId(token: SphereToken): string {\n return token.blob.tokenId;\n }\n\n public readMemo(token: SphereToken): Uint8Array | null {\n const sdkToken = token.sdkToken;\n // A transferred token delivers its memo on the latest transfer.\n if (sdkToken.transactions.length > 0) {\n return sdkToken.latestTransaction.data;\n }\n // A minted output (e.g. a split output) carries the memo in its value envelope.\n // Classify structurally: a CORRUPT envelope throws rather than reading as a\n // memo-less data token (#778), and only `'sphere'` guarantees fromCBOR succeeds.\n const data = sdkToken.genesis.data;\n if (data && classifyValueEnvelope(data).envelope === 'sphere') {\n return SpherePaymentData.fromCBOR(data).memo;\n }\n return null;\n }\n\n public readTokenData(token: SphereToken): Uint8Array | null {\n const data = token.sdkToken.genesis.data;\n return data ? new Uint8Array(data) : null;\n }\n\n public readNft(token: SphereToken): Promise<NftReading | null> {\n return readTokenNft(token);\n }\n\n // ── lifecycle ────────────────────────────────────────────────────────────────\n\n public async mint(params: MintParams, options?: EngineOpOptions): Promise<SphereToken> {\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const data = params.value ? await SpherePaymentData.fromValue(params.value).encode() : null;\n const transferId = this.resolveTransferId(options);\n const opIndex = this.resolveOpIndex(options);\n\n // #692 F13 — E.1: HKDF-derived salt (→ tokenId → stateId) + tokenType make a\n // re-call with the same transferId rebuild the byte-identical mint. The salt\n // gets its own 'mint' field domain: 'salt' is indexed by split-OUTPUT ordinal\n // under the same transferId, so ('salt', opIndex) would collide with output\n // #opIndex of a sibling split (see RealizationField).\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, {\n data,\n tokenType: new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, 'tokenType')),\n salt: TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, 'mint')),\n });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // The same idempotent submit-then-always-probe primitive as transfer/split (E.2):\n // OK-match = mine (resume), mismatch = typed conflict, clean reject = submit error,\n // inconclusive = ProofUnconfirmedError (keep-open) — never inferred from the status.\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Mint certification failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return wrapToken(token);\n }\n\n public async mintDataToken(params: MintDataTokenParams, options?: EngineOpOptions): Promise<SphereToken> {\n assertMintableData(params.data);\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const tokenType = params.tokenType ? new TokenType(params.tokenType) : TokenType.generate();\n // A deterministic salt yields a stable, terms-derived tokenId (TokenId.fromSalt).\n const salt = params.salt ? TokenSalt.fromBytes(params.salt) : TokenSalt.generate();\n\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, { data: params.data, tokenType, salt });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // #692 F13: the caller's deterministic salt already makes the re-call byte-identical;\n // routing through the probe primitive makes the re-call actually RECOVER (E.2).\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Data-token mint failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return wrapToken(token);\n }\n\n public buildNftMint(params: BuildNftMintParams): Promise<NftMintPlan> {\n return planNftMint(this.deps, params);\n }\n\n public async transfer(params: TransferParams, options?: EngineOpOptions): Promise<SphereToken> {\n this.assertOwned(params.token);\n const transferId = this.resolveTransferId(options);\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n // E.1 deterministic realization: same transferId + inputs ⇒ byte-identical\n // transaction, so an interrupted transfer can be rebuilt and resumed (AC-E1/E2).\n const stateMask = StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'stateMask'),\n );\n\n const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask, {\n data: params.data ?? null,\n });\n const unlockScript = await SignaturePredicateUnlockScript.create(transferTx, this.deps.signingService);\n const certificationData = await CertificationData.fromTransaction(transferTx, unlockScript);\n\n const proof = await this.submitAndAwaitProof(\n certificationData,\n transferTx,\n 'Transfer certification failed',\n 'TRANSFER_FAILED',\n options,\n );\n const certified = await transferTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const transferred = await params.token.sdkToken.transfer(certified, this.deps.verificationContext);\n return wrapToken(transferred);\n }\n\n public async split(params: SplitParams, options?: EngineOpOptions): Promise<SplitResult> {\n this.assertOwned(params.token);\n if (params.outputs.length === 0) {\n throw new SphereError('Split requires at least one output', 'VALIDATION_ERROR');\n }\n // `TokenSplit.split` below is handed `decodeSpherePaymentData`, which reads only\n // the tag-39050 envelope; without this an unreadable source dies inside the SDK\n // with a bare CborError naming neither token nor cause. A coinless token cannot\n // be split by construction, so this never refuses a legitimate split.\n if (params.token.value === null) {\n throw new SphereError(\n `Cannot split token ${params.token.blob.tokenId}: its genesis payload carries no ` +\n `value this SDK can read (envelope: ${params.token.valueEnvelope}). A coinless ` +\n 'token can only be transferred whole.',\n 'VALIDATION_ERROR',\n );\n }\n const transferId = this.resolveTransferId(options);\n\n // E.1 deterministic realization: per-output HKDF salts make every output's\n // mint transaction (and its salt-derived tokenId) reproducible from the\n // wallet key + transferId.\n const requests = params.outputs.map((o, i) =>\n SplitTokenRequest.create(\n SignaturePredicate.create(o.recipientPubkey),\n SpherePaymentData.create(PaymentAssetCollection.create(sphereAssetToSdk(o.coinId, o.amount)), o.data ?? null),\n TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, i, 'salt')),\n ),\n );\n\n // Value conservation is enforced inside the SDK split (root.value === source value).\n // E.1: the burn state mask is HKDF-derived, so the whole split — burn leg\n // included — is rebuildable from the wallet key + transferId (crash resume).\n const split = await TokenSplit.split(params.token.sdkToken, decodeSpherePaymentData, requests, {\n burnStateMask: StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'burn'),\n ),\n });\n\n // 1. Resolve the burnt token: from a durable checkpoint on resume, else burn now and persist\n // the checkpoint BEFORE any mint submit (E.4 — the burn proof is the one non-re-derivable\n // split input; a mint certified against proof bytes that were never stored strands #501).\n const burntToken = await this.resolveBurntToken({ params, split, transferId, options });\n\n // 2. Mint every output IN PARALLEL (#684), each justified by the burnt token + its\n // own split proofs. The mints are independent legs off the ONE already-certified,\n // already-checkpointed burn (step 1, outside this fan-out — E.4 burn-before-mint\n // is unchanged), so they carry no ordering constraint among themselves.\n //\n // MONEY-SAFETY, identical to the prior sequential loop: `allSettled` waits for\n // EVERY leg (no leg abandoned mid-submit) and rethrows the LOWEST-index rejection,\n // which is the error the sequential loop surfaced — so keep-open classification is\n // unchanged. On failure the intent stays OPEN and resume re-runs all legs from the\n // durable checkpoint; an already-certified leg is recovered idempotently (#631/E.2),\n // so legs this fan-out submitted early are never lost. MAX_MINT_CONCURRENCY paces it.\n const settled: PromiseSettledResult<SphereToken>[] = [];\n for (let start = 0; start < split.tokens.length; start += MAX_MINT_CONCURRENCY) {\n const batch = split.tokens.slice(start, start + MAX_MINT_CONCURRENCY);\n settled.push(\n ...(await Promise.allSettled(\n batch.map((token) => this.mintSplitOutput(token, burntToken, options)),\n )),\n );\n }\n // Every leg has settled. Aggregate with a KEEP-OPEN BIAS. The old sequential loop never\n // submitted a later leg once an earlier one failed, so surfacing the first failure could\n // never orphan a certified sibling. THIS fan-out submits every leg, so a lower-index CLEAN\n // failure can coexist with a higher-index leg that already CERTIFIED (fulfilled) or MAY have\n // (a keep-open rejection). Surfacing the lowest-index CLEAN error in that case would let\n // PaymentsModule abort the intent (its committed-source set is still empty here) and strand\n // the certified sibling with no checkpoint recovery (Codex P1 on #684). So, in order:\n // 1. If ANY leg rejected keep-open (ProofUnconfirmed / SplitCheckpointLost / the E.4 pair),\n // surface that verbatim (lowest-index) so its specific keep-open type drives\n // PaymentsModule's classification exactly as before.\n // 2. Else (ANY clean rejection, whether or not a sibling certified) the BURN is already\n // committed + checkpointed (resolveBurntToken, above), so the source is spent on-chain.\n // Convert to a keep-open ProofUnconfirmedError (cause = the clean failure): a plain\n // abortable error would let PaymentsModule abort the intent and STRAND the whole source\n // value (the burn cannot be undone; an aborted intent never re-runs). Keep-open so resume\n // re-runs ALL legs idempotently from the burn checkpoint (HKDF-deterministic stateId → the\n // aggregator returns the existing proof; #631/E.2/E.3). A clean mint reject after a valid,\n // value-conserving burn is transient (e.g. a shard reconfiguration), never permanent.\n const keepOpenRejection = settled.find(\n (r): r is PromiseRejectedResult => r.status === 'rejected' && isKeepOpenSplitError(r.reason),\n );\n if (keepOpenRejection !== undefined) {\n throw keepOpenRejection.reason;\n }\n const firstRejected = settled.findIndex((r) => r.status === 'rejected');\n if (firstRejected !== -1) {\n const cleanReason = (settled[firstRejected] as PromiseRejectedResult).reason;\n // 3. Else (every rejection is clean — none keep-open) the burn is STILL committed +\n // checkpointed (resolveBurntToken, above), whether or not a sibling certified. Surfacing\n // a plain abortable clean error would let PaymentsModule abort the intent and STRAND the\n // entire source value — the burn cannot be undone and an aborted intent never re-runs. So\n // EVERY post-burn mint failure is keep-open: resume re-runs all legs idempotently from the\n // burn checkpoint. (A clean mint reject after a valid, value-conserving burn is transient —\n // e.g. a shard reconfiguration — not a permanent validation failure; keep-open leaves the\n // funds RECOVERABLE, abort loses them.)\n throw new ProofUnconfirmedError(\n settled.some((r) => r.status === 'fulfilled')\n ? 'a split mint leg certified while a sibling leg failed — keep the intent open; resume ' +\n 'completes all legs idempotently from the burn checkpoint (#684 parallel fan-out)'\n : 'every split mint leg failed after the burn certified — keep the intent open; resume ' +\n 're-runs all legs idempotently from the burn checkpoint (post-burn must never abort)',\n cleanReason,\n );\n }\n const outputs = settled.map((r) => (r as PromiseFulfilledResult<SphereToken>).value);\n return { outputs };\n }\n\n /**\n * E.4 burnt-token resolution. With a checkpoint store: `get` → rebuild from the STORED proof on\n * resume; else a leg-0 pre-flight probe (a certified leaf with no checkpoint is unrecoverable),\n * then burn, persist the checkpoint (durable-ack gated), and adopt the authoritative stored\n * bytes. Without a store: burn as before (a documented residual for fully-local compositions).\n */\n private async resolveBurntToken(ctx: SplitContext): Promise<Token> {\n const store = ctx.options?.checkpointStore;\n const opIndex = this.resolveOpIndex(ctx.options);\n const source = ctx.params.token.sdkToken;\n if (store === undefined) {\n return (await this.burnSource(ctx)).burntToken;\n }\n const stored = await store.get(ctx.transferId, opIndex);\n if (stored !== null) {\n return burntTokenFromCheckpoint(this.deps, stored, ctx.split.burn.transaction, source);\n }\n await this.assertNoLegStranded(ctx);\n const { burntToken, burnProof } = await this.burnSource(ctx);\n const envelope = await encodeCheckpoint(ctx.split.burn.transaction, burnProof, burntToken);\n // The durable-ack gate: `put` resolving IS the ack, and NO mint has been submitted yet.\n let authoritative: Uint8Array;\n try {\n authoritative = await store.put(ctx.transferId, opIndex, envelope);\n } catch (err) {\n throw new CheckpointPersistFailedError(\n 'split burn certified but its checkpoint could not be persisted — keep the intent open and resume',\n err,\n );\n }\n // Decode-from-stored discipline: mint from the AUTHORITATIVE bytes (ours, or a racing resumer's\n // that won the slot), never the pre-store in-memory burnt token — so concurrent resumers agree.\n return burntTokenFromCheckpoint(this.deps, authoritative, ctx.split.burn.transaction, source);\n }\n\n /** Burn the source: certify the burn transfer and append it -> burntToken (+ its proof). */\n private async burnSource(ctx: SplitContext): Promise<{ burntToken: Token; burnProof: InclusionProof }> {\n const burnTx = ctx.split.burn.transaction;\n const burnUnlock = await SignaturePredicateUnlockScript.create(burnTx, this.deps.signingService);\n const burnCert = await CertificationData.fromTransaction(burnTx, burnUnlock);\n const burnProof = await this.submitAndAwaitProof(burnCert, burnTx, 'Split burn failed', 'TRANSFER_FAILED', ctx.options);\n const burnCertified = await burnTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, burnProof);\n const burntToken = await ctx.params.token.sdkToken.transfer(burnCertified, this.deps.verificationContext);\n return { burntToken, burnProof };\n }\n\n /**\n * Pre-flight (no-checkpoint path): if ANY mint leaf is already certified on-chain while the\n * checkpoint is missing, the burn proof is genuinely unrecoverable — fail BEFORE any re-burn. A\n * mint's stateId is justification-INDEPENDENT (only the source state hash + salt-derived mask),\n * so a probe mint with a null justification derives the true on-chain key. Every leg is probed,\n * so correctness does NOT depend on the mint loop certifying leg 0 first (E.4 step 3).\n */\n private async assertNoLegStranded(ctx: SplitContext): Promise<void> {\n // #684: probe every leg's stateId IN PARALLEL — read-only getInclusionProof calls,\n // order-independent (it throws if ANY leg is already certified). Promise.all rejects\n // on the first stranded leg, same as the prior sequential loop.\n await Promise.all(\n ctx.split.tokens.map(async (leg) => {\n const data = await leg.paymentData.encode();\n const probe = await MintTransaction.create(leg.networkId, leg.recipient, {\n data,\n tokenType: leg.tokenType,\n salt: leg.salt,\n justification: null,\n });\n const response = await this.deps.client.getInclusionProof(await StateId.fromTransaction(probe));\n // v3: a null `inclusionProof` IS \"not certified yet\"; a present one always\n // describes a real leaf, so there is no longer a field to misread here.\n if (response.inclusionProof !== null) {\n throw new SplitCheckpointLostError(\n 'a split mint leaf is certified on-chain but no burn checkpoint exists — outputs are unrecoverable',\n );\n }\n }),\n );\n }\n\n /** One split output: build the justification from the burnt token, submit, certify, wrap. */\n private async mintSplitOutput(\n splitToken: SplitToken,\n burntToken: Token,\n options?: EngineOpOptions,\n ): Promise<SphereToken> {\n const data = await splitToken.paymentData.encode();\n const justification = SplitMintJustification.create(burntToken, splitToken.proofs).toCBOR();\n const mintTx = await MintTransaction.create(splitToken.networkId, splitToken.recipient, {\n data,\n tokenType: splitToken.tokenType,\n salt: splitToken.salt,\n justification,\n });\n const certData = await CertificationData.fromMintTransaction(mintTx);\n const proof = await this.submitSplitMintLeg(certData, mintTx, options);\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return wrapToken(token);\n }\n\n /**\n * Submit one split-mint leg. A `TRANSACTION_HASH_MISMATCH` on a mint leg is NOT a foreign spend\n * (its stateId is HKDF-derived from `(seed, transferId)`, so only a seed-holder under THIS\n * transferId could have certified a different leaf): the stored checkpoint no longer reproduces\n * the certified leaf → keep-open `SplitCheckpointLostError`, never the abort-and-re-plan\n * `TransferConflictError` (E.2/E.4 split-mint arm).\n */\n private async submitSplitMintLeg(\n certData: CertificationData,\n mintTx: MintTransaction,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n try {\n return await this.submitAndAwaitProof(certData, mintTx, 'Split mint failed', 'AGGREGATOR_ERROR', options);\n } catch (err) {\n if (err instanceof TransferConflictError) {\n throw new SplitCheckpointLostError(\n 'a split mint leg no longer matches its certified leaf — the burn checkpoint is stale or lost',\n err,\n );\n }\n throw err;\n }\n }\n\n // ── verification ─────────────────────────────────────────────────────────────\n\n public async verify(token: SphereToken, _options?: EngineOpOptions): Promise<EngineVerifyResult> {\n // Both verifiers produce the same aggregated result; the worker one only\n // moves the independent per-transfer work off this thread.\n const result = this.deps.tokenVerifier\n ? await this.deps.tokenVerifier.verify(token.sdkToken, this.deps.verificationContext)\n : await token.sdkToken.verify(this.deps.verificationContext);\n return result.status === VerificationStatus.OK ? { ok: true } : { ok: false, reason: String(result.status) };\n }\n\n public isOwnedBy(token: SphereToken, pubkey: Uint8Array): boolean {\n const owner = token.sdkToken.latestTransaction.recipient;\n const claimed = EncodedPredicate.fromPredicate(SignaturePredicate.create(pubkey));\n return EncodedPredicate.equals(owner, claimed);\n }\n\n public async isSpent(token: SphereToken, _options?: EngineOpOptions): Promise<boolean> {\n // The token's current state id = what a future transfer would spend. Derive it via a\n // probe transfer (never submitted) — StateId depends only on the source's lock script\n // and state hash, not on the recipient or state mask.\n const probe = await TransferTransaction.create(\n token.sdkToken,\n SignaturePredicate.create(this.deps.signingService.publicKey),\n StateMask.fromBytes(new Uint8Array(32)),\n );\n const stateId = await StateId.fromTransaction(probe);\n const response = await this.deps.client.getInclusionProof(stateId);\n // Consumed iff the aggregator answers with a PROOF. Reporting an UNSPENT state\n // as spent destroys a live token via the fail-closed recovery gates.\n return response.inclusionProof !== null;\n }\n\n // ── serialization ────────────────────────────────────────────────────────────\n\n /** @inheritDoc — SDK-derived (Token.fromCBOR → latestTransaction.calculateStateHash().imprint). */\n public deliveryKeys(blobBytes: Uint8Array): Promise<{ tokenId: string; stateHash: string }> {\n return deriveDeliveryKeys(blobBytes);\n }\n\n public encodeToken(token: SphereToken): TokenBlob {\n return token.blob;\n }\n\n public async decodeToken(blob: TokenBlob): Promise<SphereToken> {\n const sdkToken = await Token.fromCBOR(blob.token);\n if (sdkToken.genesis.networkId.id !== this.deps.networkId.id) {\n throw new SphereError(\n `Token network mismatch: token is on network ${sdkToken.genesis.networkId.id}, ` +\n `engine on ${this.deps.networkId.id}`,\n 'VALIDATION_ERROR',\n );\n }\n return wrapToken(sdkToken);\n }\n\n // ── internals ────────────────────────────────────────────────────────────────\n\n /**\n * The effective realization seed for one transfer/split (Part E). A caller\n * that wants resumability supplies a pre-persisted UUIDv4 (sdk-changes E.3);\n * otherwise one is generated here — same derivation path, just non-resumable.\n * The canonical-lowercase-UUID check also keeps the HKDF info string\n * unambiguous (no ':' injection, no case-variant double derivations).\n */\n /** Validated op ordinal (§8.1 mask domain separation across ops of one send). */\n private resolveOpIndex(options?: EngineOpOptions): number {\n const opIndex = options?.opIndex ?? 0;\n if (!Number.isInteger(opIndex) || opIndex < 0) {\n throw new SphereError(`opIndex must be a non-negative integer, got ${String(opIndex)}`, 'VALIDATION_ERROR');\n }\n return opIndex;\n }\n\n private resolveTransferId(options?: EngineOpOptions): string {\n const transferId = options?.transferId ?? randomUUID();\n if (!TRANSFER_ID_RE.test(transferId)) {\n throw new SphereError(\n `transferId must be a canonical lowercase UUID string, got \"${transferId}\"`,\n 'VALIDATION_ERROR',\n );\n }\n return transferId;\n }\n\n /**\n * E.2 — status-agnostic idempotent submit with conflict detection\n * (sdk-changes E.2, ARCHITECTURE §8.1).\n *\n * Submit the certification request and treat ANY outcome — success status,\n * error status, or a response-parse throw (the live gateway may still emit\n * statuses this SDK no longer parses, e.g. the transitional STATE_ID_EXISTS)\n * — as \"a certification for this state may already exist\". Then ALWAYS fetch\n * the inclusion proof and match-verify it against the rebuilt transaction\n * (`waitInclusionProof` only returns an OK-verified proof):\n *\n * - match (OK) → proceed; this is how an interrupted\n * attempt with the same transferId resumes;\n * - mismatch (hash ≠ rebuilt tx) → `TransferConflictError`: the source was\n * consumed by a DIFFERENT transaction (lost\n * race) — never applied, never retried;\n * - no proof & the submit failed → the original submit error (a genuine\n * failure, not a resume case).\n */\n private async submitAndAwaitProof(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n const deadline = certificationDeadline(\n this.proofTimeoutMs,\n options?.signal,\n `${failLabel}: not certified`\n );\n try {\n return await this.submitThenProve(certificationData, transaction, failLabel, failCode, deadline.signal);\n } finally {\n deadline.dispose();\n }\n }\n\n /** One certification attempt under one deadline: the metered submit retries\n * transient answers instead of falling through to a proof that cannot exist. */\n private async submitThenProve(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n signal: AbortSignal,\n ): Promise<InclusionProof> {\n let submitError: unknown = null;\n // True ONLY for a KNOWN validation-reject status: a PROVEN clean pre-certification\n // reject. Everything else stays INDETERMINATE (keep-open, #631) — including any\n // submit that was RETRIED, since the earlier POST may already have been processed\n // server-side, which is what sawAmbiguousAttempt latches (#747 review).\n let submitRejectedCleanly = false;\n try {\n const { value: response, retried } = await retryTransient(\n async () => {\n const answer = await this.deps.client.submitCertificationRequest(certificationData);\n // A booting gateway is \"ask again\", not a certification failure — see\n // TransientSubmitAnswer. Everything else, known or unknown, keeps the\n // status-agnostic treatment below.\n if (String(answer.status) === String(CertificationStatus.SERVICE_NOT_READY)) {\n throw new TransientSubmitAnswer(String(answer.status));\n }\n return answer;\n },\n signal,\n this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS,\n );\n if (response.status !== CertificationStatus.SUCCESS) {\n submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);\n submitRejectedCleanly = !retried && CLEAN_REJECT_STATUSES.has(response.status);\n }\n } catch (err) {\n submitError = err ?? new SphereError(`${failLabel}: submit failed`, failCode);\n }\n\n try {\n return await awaitProofBounded(\n {\n client: this.deps.client,\n trustBase: this.deps.trustBase,\n predicateVerifier: this.deps.predicateVerifier,\n unicityCertificateVerifier: this.deps.unicityCertificateVerifier,\n intervalMs: this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS, // #683\n },\n transaction,\n signal,\n );\n } catch (err) {\n throw certificationFailure(err, failLabel, submitError, submitRejectedCleanly);\n }\n }\n\n\n /**\n * One inclusion-proof wait, with the deadline OWNED here (#739) so it is bounded\n * and configurable rather than the SDK's fixed default. A hit throws, and the\n * caller maps it to ProofUnconfirmedError (keep-open) — the correct posture,\n * since the spend may be on-chain.\n */\n /** Fail fast if this engine's key does not own the token's current state. */\n private assertOwned(token: SphereToken): void {\n if (!this.isOwnedBy(token, this.deps.signingService.publicKey)) {\n throw new SphereError('Cannot transfer a token not owned by this engine identity', 'VALIDATION_ERROR');\n }\n }\n\n /**\n * Terminate the verification worker pool, if this engine was configured with\n * one. Idempotent — the pool's dispose only touches workers it spawned.\n */\n public dispose(): void {\n this.deps.tokenVerifier?.dispose();\n }\n\n}\n","// P3b: the E.4 split checkpoint store over the §16 intent-progress endpoints.\n// ENCRYPT ONCE: ciphertext is persisted to ScopedKV BEFORE the first POST and\n// every retry re-POSTs the byte-identical envelope (a fresh AEAD nonce would\n// break the slot's content idempotency). put() resolves with the STORED\n// envelope's plaintext — the slot winner's bytes (insert-once, first-write-wins).\n\nimport { SphereError } from '../../core/errors';\nimport { decryptFieldBytes, encryptFieldBytes } from '../../core/field-encryption';\nimport { progressSignMessage } from '../../core/wallet-api-protocol';\nimport { SplitCheckpointLostError, type SplitCheckpointStore } from '../../token-engine';\nimport { STORE_KEYS, type ScopedKV } from '../../modules/payments-v2/stores';\nimport type { WalletApiV2Client } from './client';\n\nexport type CheckpointClient = Pick<WalletApiV2Client, 'postProgress' | 'getProgress'>;\n\n/** The signed §16 message binding a progress append to its exact envelope bytes. */\nexport { progressSignMessage as progressMessage } from '../../core/wallet-api-protocol';\n\nconst utf8 = (text: string): Uint8Array => new TextEncoder().encode(text);\n\nexport interface WalletApiSplitCheckpointStoreConfig {\n client: CheckpointClient;\n kv: ScopedKV;\n /** S6 self-scoped field key (`deriveFieldEncryptionKey`). */\n fieldKey: Uint8Array;\n /** Signs the wallet-api.progress.v1 message with the chain key. */\n signProgress: (message: string) => string | Promise<string>;\n}\n\nexport class WalletApiSplitCheckpointStore implements SplitCheckpointStore {\n constructor(private readonly config: WalletApiSplitCheckpointStoreConfig) {}\n\n private cacheKey(transferId: string, opIndex: number): string {\n return `${STORE_KEYS.checkpointCache}:${transferId}:${String(opIndex)}`;\n }\n\n private aad(transferId: string, opIndex: number): Uint8Array {\n return utf8(`${transferId}:${String(opIndex)}`);\n }\n\n async put(transferId: string, opIndex: number, bytes: Uint8Array): Promise<Uint8Array> {\n const { kv, fieldKey } = this.config;\n const aad = this.aad(transferId, opIndex);\n const cacheKey = this.cacheKey(transferId, opIndex);\n let envelope = await kv.get<string>(cacheKey);\n if (envelope === null) {\n envelope = encryptFieldBytes(fieldKey, bytes, aad);\n await kv.set(cacheKey, envelope);\n }\n const record = await this.post(transferId, opIndex, envelope);\n return this.open(record.payload, aad);\n }\n\n /** §5.1 restore (CheckpointReseeder): re-POST the cached ciphertext byte-identical; false = none cached. */\n async reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean> {\n const envelope = await this.config.kv.get<string>(this.cacheKey(transferId, opIndex));\n if (envelope === null) return false;\n await this.post(transferId, opIndex, envelope);\n return true;\n }\n\n /** The ONE signed progress-append path put() and reseedCheckpoint() share. */\n private async post(\n transferId: string,\n opIndex: number,\n envelope: string\n ): Promise<{ opIndex: number; payload: string; createdAt: string }> {\n const signature = await this.config.signProgress(progressSignMessage(transferId, opIndex, envelope));\n return this.config.client.postProgress(transferId, opIndex, envelope, signature);\n }\n\n async get(transferId: string, opIndex: number): Promise<Uint8Array | null> {\n const records = await this.config.client.getProgress(transferId);\n const record = records.find((r) => r.opIndex === opIndex);\n if (record === undefined) return null;\n return this.open(record.payload, this.aad(transferId, opIndex));\n }\n\n private open(envelope: string, aad: Uint8Array): Uint8Array {\n try {\n return decryptFieldBytes(this.config.fieldKey, envelope, aad);\n } catch (err) {\n if (err instanceof SphereError && err.code === 'DECRYPTION_ERROR') {\n throw new SplitCheckpointLostError(\n 'split checkpoint record could not be decrypted (tampered or mis-served)',\n err\n );\n }\n throw err;\n }\n }\n}\n"],"mappings":"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","names":["isLE","abytes","anumber","bytesToHex","concatBytes","hexToBytes","isBytes","randomBytes","abytes","concatBytes","_0n","_1n","_0n","_1n","_1n","_0n","_1n","anumber","_0n","_1n","abytes","isLE","_1n","isLE","abytes","_0n","_1n","_1n","_0n","_1n","isLE","_0n","_2n","_0n","_1n","abytes","_3n","_4n","CURVE_ORDER","concatBytes","hexToBytes","endo","bytesToHex","randomBytes","abytes","isBytes","hmac","CURVE_ORDER","_2n","_1n","Signature","r","s","hexToBytes","concatBytes","bytesToHex","_0n","_2n","_3n","sha256","hexToBytes","bytesToHex","sha256","isBytes","abool","anumber","abytes","aexists","aoutput","clean","createView","abytes","isLE","anumber","abool","createView","copyBytes","randomBytes","anumber","abool","abytes","copyBytes","clean","copyBytes","abytes","clean","aexists","aoutput","abytes","clean","randomBytes","hexToBytes","bytesToHex"]}
|