@cardanowall/sdk-ts 0.5.0 → 0.6.0
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/dist/client/index.cjs +3 -1
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/conformance/cli.cjs +6 -6
- package/dist/conformance/cli.cjs.map +1 -1
- package/dist/conformance/cli.js +6 -6
- package/dist/conformance/cli.js.map +1 -1
- package/dist/identity/index.cjs.map +1 -1
- package/dist/identity/index.js.map +1 -1
- package/dist/index.cjs +9 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/dist/verifier/index.cjs +6 -6
- package/dist/verifier/index.cjs.map +1 -1
- package/dist/verifier/index.js +6 -6
- package/dist/verifier/index.js.map +1 -1
- package/package.json +3 -3
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../crypto-core/src/cbor/canonical.ts","../../../crypto-core/src/sig/ed25519.ts","../../../crypto-core/src/cose/sign1.ts","../../../crypto-core/src/hash/sha-256.ts","../../../crypto-core/src/hash/blake2b-256.ts","../../../crypto-core/src/hash/merkle-sha2-256.ts","../../../poe-standard/src/schema.ts","../../../poe-standard/src/encoder.ts","../../../poe-standard/src/error-codes.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/utils.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/_crystals.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/ml-kem.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/hybrid.ts","../../../crypto-core/src/aead/chacha20-poly1305.ts","../../../crypto-core/src/kem/mlkem768x25519.ts","../../../crypto-core/src/kem/x25519.ts","../../../crypto-core/src/kdf/hkdf.ts","../../../crypto-core/src/sealed-poe/errors.ts","../../../crypto-core/src/sealed-poe/stream.ts","../../../crypto-core/src/sealed-poe/transcript.ts","../../../crypto-core/src/sealed-poe/wrap.ts","../../../crypto-core/src/sealed-poe/passphrase-normalize.ts","../../../poe-standard/src/validator.ts","../../src/client/off-host-sign.ts","../../src/client/http-error.ts","../../src/client/batch-empty-error.ts","../../src/client/batch-too-large-error.ts","../../src/client/forbidden-error.ts","../../src/client/idempotency-conflict-error.ts","../../src/client/insufficient-funds-error.ts","../../src/client/insufficient-scope-error.ts","../../src/client/internal-server-error.ts","../../src/client/invalid-body-error.ts","../../src/client/malformed-cbor-error.ts","../../src/client/not-found-error.ts","../../src/client/quote-already-consumed-error.ts","../../src/client/quote-expired-error.ts","../../src/client/quote-not-found-error.ts","../../src/client/rate-limited-error.ts","../../src/client/record-not-found-error.ts","../../src/client/service-unavailable-error.ts","../../src/client/unauthorized-error.ts","../../src/client/validation-failed-error.ts","../../src/client/parse-http-error.ts","../../src/client/http-helpers.ts","../../src/client/account.ts","../../src/client/invalid-client-config-error.ts","../../src/hex.ts","../../src/client/partial-upload-error.ts","../../../crypto-core/src/merkle/leaves-list.ts","../../src/client/resumable-source.ts","../../src/client/resumable-upload.ts","../../src/client/publish.ts","../../src/client/poe.ts","../../src/client/records.ts","../../src/client/label-309-client.ts"],"names":["encodeCanonicalCbor","encode","sortCoreDeterministic","nobleSha256","blake2b","sha256","out","randb","abytes_","opts","N","Q","F","ROOT_OF_UNITY","z","shake256","abytes","sha3_256","concatBytes","x25519","hashes","NONCE_LENGTH","randomBytes","EMPTY_BYTES","readString","DIGEST_LENGTH","bytesToHex","ED25519_PUBLIC_KEY_LENGTH","ED25519_SIGNATURE_LENGTH","X25519_PUBLIC_KEY_LENGTH","MLKEM768X25519_PUBLIC_KEY_LENGTH","cloneToOwnedBuffer","readJson","parseRetryAfter","throwIfNotOk","buildJsonHeaders","buildMultipartHeaders","buildHeaders"],"mappings":"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","file":"index.js","sourcesContent":["import { cdeDecodeOptions, decode, encode } from 'cbor2';\nimport { sortCoreDeterministic } from 'cbor2/sorts';\n\nimport { CanonicalCborError } from './errors';\n\nexport type CanonicalCborValue =\n | null\n | boolean\n | number\n | bigint\n | string\n | Uint8Array\n | readonly CanonicalCborValue[]\n | { readonly [key: string]: CanonicalCborValue }\n | ReadonlyMap<string | number, CanonicalCborValue>;\n\nexport function encodeCanonicalCbor(value: CanonicalCborValue): Uint8Array {\n return encode(value, {\n cde: true,\n collapseBigInts: true,\n rejectDuplicateKeys: true,\n sortKeys: sortCoreDeterministic,\n });\n}\n\nexport function decodeCanonicalCbor(bytes: Uint8Array): unknown {\n try {\n return decode(bytes, {\n ...cdeDecodeOptions,\n rejectStreaming: true,\n rejectDuplicateKeys: true,\n // A Label 309 record carries integers, byte/text strings, arrays, maps and\n // `null` — and nothing else. Without these rejections the major-type-7\n // surface leaks into the decoder: a float16/32/64 that happens to hold an\n // integral value (e.g. 1.0) silently decodes to the integer 1 and passes\n // a `z.literal(1)` / Number.isInteger schema check, so two byte strings\n // that are NOT byte-identical canonicalise to the same record. That\n // breaks the cross-implementation parity invariant (the Python twin\n // already rejects non-integer `v` / `enc.scheme` outright). Reject the\n // whole non-record surface — floats, negative zero, undefined, and\n // non-{true,false,null} simple values — so any such input surfaces as\n // MALFORMED_CBOR via mapDecodeError rather than decoding to a look-alike.\n rejectFloats: true,\n rejectNegativeZero: true,\n rejectUndefined: true,\n rejectSimple: true,\n });\n } catch (cause) {\n throw mapDecodeError(cause);\n }\n}\n\nfunction mapDecodeError(cause: unknown): CanonicalCborError {\n const message = cause instanceof Error ? cause.message : String(cause);\n const lower = message.toLowerCase();\n // Every canonical-decode violation collapses to the single public taxonomy\n // code MALFORMED_CBOR: indefinite-length (streaming) items, duplicate keys,\n // non-canonical (unsorted) key ordering, non-minimal integer encodings, and\n // invalid UTF-8 in text strings. cbor2 raises the SAME \"Duplicate or out of\n // order key\" message for both true duplicates AND distinct-but-unsorted keys,\n // so the two are indistinguishable by message — and per the Label 309 taxonomy\n // both belong under MALFORMED_CBOR anyway. The specific cause survives in the\n // human-readable message below; for indefinite-length we state it explicitly\n // so the diagnostic is not lost when the code is collapsed.\n const isIndefinite = lower.includes('streaming') || lower.includes('indefinite');\n const detail = isIndefinite\n ? `indefinite-length items are not permitted in canonical CBOR: ${message}`\n : message;\n return new CanonicalCborError('MALFORMED_CBOR', `cbor decode failed: ${detail}`, { cause });\n}\n","import * as ed from '@noble/ed25519';\nimport { sha512 } from '@noble/hashes/sha2.js';\n\ned.hashes.sha512 = sha512;\n\n// Ed25519 group order L (= 2^252 + 27742317777372353535851937790883648493).\nconst L = ed.Point.CURVE().n;\n\nexport interface SignEd25519Opts {\n readonly seed: Uint8Array;\n readonly message: Uint8Array;\n}\n\nexport interface VerifyEd25519Opts {\n readonly publicKey: Uint8Array;\n readonly message: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface GetPublicKeyEd25519Opts {\n readonly seed: Uint8Array;\n}\n\nexport function signEd25519(opts: SignEd25519Opts): Uint8Array {\n return ed.sign(opts.message, opts.seed);\n}\n\n// Little-endian 32-byte scalar → bigint.\nfunction leBytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n value = (value << 8n) | BigInt(bytes[i]!);\n }\n return value;\n}\n\n// Strict (non-cofactored) Ed25519 verification per RFC 8032 §5.1.7, matching\n// libsodium/PyNaCl `crypto_sign_verify_detached` and ed25519-dalek\n// `verify_strict`. The cofactor-less check rejects every small-order /\n// torsion-component edge case in the C2SP/CCTV corpus, which noble's\n// `{ zip215: false }` mode does NOT (it remains cofactored: it checks\n// `[8]([S]B - [k]A - R) == 0`, accepting torsion components).\n//\n// The verification equation is the unscaled `[S]B == R + [k]A`, rewritten as\n// `[S]B - [k]A - R == identity`. We reject S >= L (non-canonical scalar) and\n// any small-order A or R up front, so a torsion component can never be smuggled\n// through the cofactor multiplication the cofactored variant performs.\nexport function verifyEd25519(opts: VerifyEd25519Opts): boolean {\n const { signature, message, publicKey } = opts;\n if (signature.length !== 64 || publicKey.length !== 32) return false;\n\n // S = LE(sig[32..64]); reject if not a canonical scalar (S >= L).\n const S = leBytesToBigInt(signature.subarray(32, 64));\n if (S >= L) return false;\n\n // Decode A (public key) and R (sig[0..32]) with the canonical (non-zip215)\n // point encoding; a non-canonical encoding throws and rejects.\n let A: ed.Point;\n let R: ed.Point;\n try {\n A = ed.Point.fromBytes(publicKey);\n R = ed.Point.fromBytes(signature.subarray(0, 32));\n } catch {\n return false;\n }\n\n // Reject small-order (cofactor-torsion) A or R: this is exactly the strictness\n // that distinguishes verify_strict from the cofactored check.\n if (A.isSmallOrder() || R.isSmallOrder()) return false;\n\n // k = SHA-512(R || A || M) reduced mod L.\n const k =\n leBytesToBigInt(ed.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;\n\n // Accept iff [S]B - [k]A - R == identity. `multiplyUnsafe` returns the\n // identity for a 0 scalar, but guard explicitly to avoid relying on that.\n const sB = S === 0n ? ed.Point.ZERO : ed.Point.BASE.multiplyUnsafe(S);\n const kA = k === 0n ? ed.Point.ZERO : A.multiplyUnsafe(k);\n return sB.subtract(kA).subtract(R).is0();\n}\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nexport function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array {\n return ed.getPublicKey(opts.seed);\n}\n","import {\n decodeCanonicalCbor,\n encodeCanonicalCbor,\n type CanonicalCborValue,\n} from '../cbor/canonical';\nimport { CanonicalCborError } from '../cbor/errors';\nimport { blake2b224 } from '../hash/blake2b-256';\nimport { signEd25519, verifyEd25519 } from '../sig/ed25519';\nimport { compareCt } from '../util/compare-ct';\n\nimport { CoseVerifyError, type CoseVerifyResult } from './errors';\n\nexport type CoseHeader = Map<number | string, unknown>;\n\n// Label 309 v1 domain separator embedded as a prefix on `Sig_structure[3]`\n// (`to_sign`). The separator is\n// NOT placed in `Sig_structure[2]` (`external_aad`) because CIP-30 `signData`\n// — the only realistic wallet-signing path on Cardano — explicitly forbids a\n// non-empty `external_aad`. Pinning the prefix into the payload preserves the\n// anti-replay property while keeping wallet-produced signatures byte-identical\n// to verifier-side recomputation.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX = 'cardano-poe-record-sig-v1' as const;\n// Composer path-2 wallet flow consumes the prefix bytes directly\n// to assemble `toSign = prefix || canonical_cbor(record_body)` BEFORE calling\n// `walletSignData` (the wallet's `signData()` receives this concatenation as\n// its `payload` argument verbatim per CIP-30). The bytes constant is exported\n// so a composer can build the input without re-encoding the prefix at every\n// call site.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES = new TextEncoder().encode(\n CARDANO_POE_SIG_DOMAIN_PREFIX,\n);\n\n// Fail-fast: the prefix length is byte-pinned at 25 UTF-8 bytes. A different\n// runtime encoding would silently break round-tripping\n// against the reference vectors.\nif (CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length !== 25) {\n throw new Error(\n `cardano-poe-record-sig-v1 prefix must encode to exactly 25 UTF-8 bytes, got ${CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length}`,\n );\n}\n\nconst EMPTY_BYTES = new Uint8Array(0);\n\nexport interface CoseSign1Decoded {\n readonly protectedHeader: CoseHeader;\n // preserved for Sig_structure reconstruction — never re-encode the decoded header map (RFC 9052 §4.4)\n readonly protectedBytes: Uint8Array;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport interface BuildSigStructureArgs {\n readonly context: 'Signature1';\n readonly bodyProtectedBytes: Uint8Array;\n readonly externalAad: Uint8Array;\n readonly payload: Uint8Array;\n}\n\n// Raw RFC 9052 §4.4 Sig_structure builder. General-purpose: callers control\n// `external_aad` and `payload` exactly. For Label 309 record signing use\n// `buildLabel309SigStructure` instead — it enforces the Label 309 record-signature invariants.\nexport function buildSigStructure(args: BuildSigStructureArgs): Uint8Array {\n return encodeCanonicalCbor([\n args.context,\n args.bodyProtectedBytes,\n args.externalAad,\n args.payload,\n ] as readonly CanonicalCborValue[]);\n}\n\nexport interface BuildLabel309SigStructureArgs {\n readonly bodyProtectedBytes: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed.\n readonly recordBodyCbor: Uint8Array;\n}\n\n// Label 309 v1 specialisation of `Sig_structure` (RFC 9052 §4.4 base structure):\n// to_sign = utf8(\"cardano-poe-record-sig-v1\") || canonical_cbor(record_body_minus_sigs)\n// Sig_structure = [ \"Signature1\", body_protected, h'' (empty), to_sign ]\n// Always forces `external_aad = h''` (empty bstr) — the CIP-30 wallet path\n// cannot carry a non-empty `external_aad`, so the domain separator lives in\n// `Sig_structure[3]` rather than `Sig_structure[2]`.\nexport function buildLabel309SigStructure(args: BuildLabel309SigStructureArgs): Uint8Array {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.recordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.recordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n return buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: args.bodyProtectedBytes,\n externalAad: EMPTY_BYTES,\n payload: toSign,\n });\n}\n\nexport interface EncodeCoseSign1Args {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport function encodeCoseSign1(args: EncodeCoseSign1Args): Uint8Array {\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n return encodeCanonicalCbor([\n protectedBytes,\n args.unprotectedHeader as CanonicalCborValue,\n args.payload,\n args.signature,\n ] as readonly CanonicalCborValue[]);\n}\n\n// cbor2's decoder returns Map for integer-keyed maps but plain Object for empty\n// or string-keyed maps; normalise both representations to Map.\nfunction asCoseHeader(value: unknown): CoseHeader | null {\n if (value instanceof Map) return value as CoseHeader;\n if (value !== null && typeof value === 'object' && (value as object).constructor === Object) {\n return new Map(Object.entries(value as Record<string, unknown>));\n }\n return null;\n}\n\nexport function decodeCoseSign1(bytes: Uint8Array): CoseSign1Decoded {\n let arr: unknown;\n try {\n arr = decodeCanonicalCbor(bytes);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'cose decode failed', { cause });\n }\n if (!Array.isArray(arr) || arr.length !== 4) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'expected 4-element array');\n }\n const [protectedBytesRaw, unprotectedRaw, payloadRaw, signatureRaw] = arr;\n if (!(protectedBytesRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected_bytes must be bytes');\n }\n const unprotectedHeader = asCoseHeader(unprotectedRaw);\n if (unprotectedHeader === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'unprotected header must be map');\n }\n if (payloadRaw !== null && !(payloadRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'payload must be bytes or null');\n }\n if (!(signatureRaw instanceof Uint8Array) || signatureRaw.length !== 64) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'signature must be 64 bytes');\n }\n let protectedHeader: CoseHeader;\n if (protectedBytesRaw.length === 0) {\n protectedHeader = new Map();\n } else {\n let decodedProtected: unknown;\n try {\n decodedProtected = decodeCanonicalCbor(protectedBytesRaw);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header decode failed', { cause });\n }\n const ph = asCoseHeader(decodedProtected);\n if (ph === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header must decode to map');\n }\n // Empty protected header MUST encode as the single byte 0x40 (zero-length bstr),\n // not 0x41 0xA0 (a 1-byte bstr containing an empty CBOR map). RFC 9052 §3 +\n // Label 309 canonical-CBOR mandate.\n if (ph.size === 0) {\n throw new CoseVerifyError(\n 'MALFORMED_SIG_COSE',\n 'empty protected header must encode as 0x40 (zero-length bstr), not as an empty map',\n );\n }\n protectedHeader = ph;\n }\n return {\n protectedHeader,\n protectedBytes: protectedBytesRaw,\n unprotectedHeader,\n payload: payloadRaw,\n signature: signatureRaw,\n };\n}\n\nexport type CoseSign1BuildErrorCode = 'SIGNER_NOT_PROVIDED' | 'SIGNER_AND_SEED_BOTH_PROVIDED';\n\nexport class CoseSign1BuildError extends Error {\n readonly code: CoseSign1BuildErrorCode;\n\n constructor(code: CoseSign1BuildErrorCode, message: string) {\n super(message);\n this.name = 'CoseSign1BuildError';\n this.code = code;\n }\n}\n\nexport interface CoseSign1Label309BuildArgs {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n // Canonical CBOR of the record body with `sigs` removed. The\n // builder prepends the 25-byte UTF-8 domain prefix `cardano-poe-record-sig-v1`\n // internally — callers MUST NOT pre-concatenate it.\n readonly recordBodyCbor: Uint8Array;\n // EITHER the raw 32-byte Ed25519 seed (used by KAT tests, Python parity, and\n // the off-host signing helper) OR an injected signer closure that signs the\n // assembled Sig_structure bytes (composer-side use — keeps the private key\n // inside the unlock-store closure so it never escapes scope).\n // Exactly one of the two MUST be provided; mutual exclusion enforced at\n // runtime via CoseSign1BuildError.\n readonly signerSecretKey?: Uint8Array;\n readonly signer?: (sigStructureBytes: Uint8Array) => Uint8Array;\n}\n\n// Label 309 v1 record-signature builder:\n// 1. compute `to_sign = utf8(\"cardano-poe-record-sig-v1\") || recordBodyCbor`\n// 2. Sig_structure = [ \"Signature1\", bodyProtected, h'', to_sign ]\n// 3. Ed25519-sign Sig_structure (via seed OR injected closure)\n// 4. emit COSE_Sign1 with payload = CBOR null (detached signature, mandatory)\nexport function coseSign1Label309Build(args: CoseSign1Label309BuildArgs): Uint8Array {\n if (args.signerSecretKey === undefined && args.signer === undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n 'coseSign1Label309Build requires either signerSecretKey or signer',\n );\n }\n if (args.signerSecretKey !== undefined && args.signer !== undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_AND_SEED_BOTH_PROVIDED',\n 'coseSign1Label309Build accepts signerSecretKey XOR signer (not both)',\n );\n }\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n const sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: protectedBytes,\n recordBodyCbor: args.recordBodyCbor,\n });\n let signature: Uint8Array;\n if (args.signer !== undefined) {\n signature = args.signer(sigStructureBytes);\n if (!(signature instanceof Uint8Array) || signature.length !== 64) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n `injected signer must return a 64-byte Uint8Array; got ${signature instanceof Uint8Array ? `${signature.length}-byte Uint8Array` : typeof signature}`,\n );\n }\n } else {\n signature = signEd25519({ seed: args.signerSecretKey!, message: sigStructureBytes });\n }\n return encodeCoseSign1({\n protectedHeader: args.protectedHeader,\n unprotectedHeader: args.unprotectedHeader,\n payload: null,\n signature,\n });\n}\n\nexport interface CoseSign1Label309VerifyArgs {\n readonly message: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed (verifier-recomputed;\n // the 25-byte UTF-8 prefix is prepended internally — callers\n // MUST NOT pre-concatenate it).\n readonly detachedRecordBodyCbor: Uint8Array;\n // Optional out-of-band signer key (path-2 wallet path resolves the key from\n // `sigs[i].cose_key`). Path-1 records carry the 32-byte raw Ed25519 pubkey\n // in the protected header at label 4 (`kid`) and need no out-of-band hint.\n readonly expectedSignerKey?: Uint8Array;\n}\n\n// Label 309 v1 record-signature verifier:\n// - Decode COSE_Sign1\n// - Reject COSE_Sign1[2] != CBOR null (attached payload — including h'') as\n// MALFORMED_SIG_COSE_SIGN1\n// - Recompute to_sign = utf8(\"cardano-poe-record-sig-v1\") || detachedRecordBodyCbor\n// - Sig_structure = [ \"Signature1\", protectedBytes, h'', to_sign ]\n// - Strict Ed25519 verify (RFC 8032 §5.1.7 — `zip215: false` per ed25519.ts)\n//\n// The verifier does NOT accept an `externalAad` argument: Label 309 v1 pins\n// `external_aad = h''` and any deviation would either silently weaken the\n// domain separator or quietly accept malformed records. If a future CIP\n// revision re-enables external_aad, this helper takes a v-bump.\nexport function coseSign1Label309Verify(args: CoseSign1Label309VerifyArgs): CoseVerifyResult {\n let decoded: CoseSign1Decoded;\n try {\n decoded = decodeCoseSign1(args.message);\n } catch (e) {\n if (e instanceof CoseVerifyError) {\n return { ok: false, error: { code: e.code, message: 'errors.cose.malformed' } };\n }\n if (e instanceof CanonicalCborError) {\n return {\n ok: false,\n error: { code: 'MALFORMED_SIG_COSE', message: 'errors.cose.malformed_cbor' },\n };\n }\n throw e;\n }\n // Label 309 v1 mandate: COSE_Sign1[2] (payload field) MUST be CBOR `null` (0xF6).\n // Any non-null payload — including a zero-length byte string `h''` — MUST\n // be rejected as MALFORMED_SIG_COSE_SIGN1.\n if (decoded.payload !== null) {\n return {\n ok: false,\n error: {\n code: 'MALFORMED_SIG_COSE_SIGN1',\n message: 'errors.cose.attached_payload_forbidden',\n },\n };\n }\n const alg = decoded.protectedHeader.get(1);\n if (typeof alg !== 'number' || alg !== -8) {\n return {\n ok: false,\n error: { code: 'UNSUPPORTED_SIG_ALG', message: 'errors.cose.unsupported_alg' },\n };\n }\n const kidRaw = decoded.protectedHeader.get(4);\n let signerKey: Uint8Array | undefined;\n if (kidRaw instanceof Uint8Array && kidRaw.length === 32) {\n signerKey = kidRaw;\n } else if (args.expectedSignerKey instanceof Uint8Array && args.expectedSignerKey.length === 32) {\n signerKey = args.expectedSignerKey;\n }\n if (signerKey === undefined) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_unresolved' },\n };\n }\n // When both a protected-header kid AND an expectedSignerKey are provided,\n // require they agree (constant-time). A protected kid that disagrees with\n // the caller's out-of-band binding is a misuse, not a transient mismatch.\n if (\n kidRaw instanceof Uint8Array &&\n kidRaw.length === 32 &&\n args.expectedSignerKey instanceof Uint8Array &&\n args.expectedSignerKey.length === 32 &&\n !compareCt(kidRaw, args.expectedSignerKey)\n ) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_mismatch' },\n };\n }\n // CIP-8 `hashed = true` mode (the wallet-signed path-2 variant). The unprotected\n // header carries the literal text key `\"hashed\"` with boolean value `true`\n // (text-keyed CBOR maps decode to `Map<string, unknown>` via cbor2). When\n // set, both producer and verifier build `Sig_structure[3] = Blake2b-224(to_sign)`\n // (28-byte digest of the FULL `to_sign` payload including the 25-byte\n // domain prefix). When absent or false, the standard non-hashed path\n // applies unchanged.\n const hashedFlag = decoded.unprotectedHeader.get('hashed');\n let sigStructureBytes: Uint8Array;\n if (hashedFlag === true) {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.detachedRecordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.detachedRecordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n const hashedPayload = blake2b224(toSign);\n sigStructureBytes = buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: decoded.protectedBytes,\n externalAad: EMPTY_BYTES,\n payload: hashedPayload,\n });\n } else {\n sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: decoded.protectedBytes,\n recordBodyCbor: args.detachedRecordBodyCbor,\n });\n }\n const valid = verifyEd25519({\n publicKey: signerKey,\n message: sigStructureBytes,\n signature: decoded.signature,\n });\n if (!valid) {\n return {\n ok: false,\n error: { code: 'SIGNATURE_INVALID', message: 'errors.cose.signature_invalid' },\n };\n }\n return { ok: true, signerKey, alg };\n}\n","import { createSHA256 } from 'hash-wasm';\nimport { sha256 as nobleSha256 } from '@noble/hashes/sha2.js';\n\nexport function sha256(input: Uint8Array): Uint8Array {\n return nobleSha256(input);\n}\n\n/**\n * Stream a source through an incremental SHA-256 and return the 32-byte digest,\n * never holding more than one chunk in memory. Use this when the input is too\n * large to buffer (a multi-gigabyte file read in slices), where `sha256(input)`\n * would force the whole input into a single array first.\n */\nexport async function sha256Stream(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const hasher = await createSHA256();\n hasher.init();\n for await (const chunk of source) {\n hasher.update(chunk);\n }\n return hasher.digest('binary') as Uint8Array;\n}\n","import { blake2b } from '@noble/hashes/blake2.js';\n\nexport function blake2b256(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 32 });\n}\n\n// CIP-19 stake-address derivation, used for the wallet path-2 signer binding,\n// requires the 28-byte BLAKE2b digest of the signer's Ed25519 public key.\n// The Cardano ledger encodes stake addresses as\n// `network_header_byte || Blake2b-224(stake_vk)`\n// per CIP-19, so this output length is fixed by spec.\nexport function blake2b224(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 28 });\n}\n","// RFC 9162 §2.1.1 binary Merkle tree under SHA-256.\n// This implements the algorithm tier identified on the wire as the\n// `rfc9162-sha256` OPT-INFO; the record's `merkle[]` field carries the proof.\n//\n// Construction (RFC 9162 §2.1.1):\n// - Single leaf: MTH({d_0}) = SHA-256(0x00 || d_0)\n// - Internal node: MTH(L) = SHA-256(0x01 || MTH(L[0:k]) || MTH(L[k:n]))\n// where k = largest power of 2 strictly less than n.\n// - Empty trees (n == 0) are FORBIDDEN.\n// - The 0x00 leaf / 0x01 internal prefixes prevent the CVE-2012-2459\n// leaf-vs-internal collision family.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { compareCt } from '../util/compare-ct';\n\nexport const MERKLE_ALG_ID = 'rfc9162-sha256' as const;\n\nconst LEAF_PREFIX = 0x00;\nconst NODE_PREFIX = 0x01;\nconst DIGEST_LENGTH = 32;\n\nfunction validateLeaves(leaves: ReadonlyArray<Uint8Array>, fnName: string): void {\n if (leaves.length === 0) {\n throw new Error(`${fnName}: empty leaf list (n == 0 is forbidden by RFC 9162 §2.1.1)`);\n }\n for (let i = 0; i < leaves.length; i++) {\n const leaf = leaves[i];\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) {\n throw new Error(\n `${fnName}: leaf[${i}] must be a Uint8Array(${DIGEST_LENGTH}); got length ${\n leaf instanceof Uint8Array ? leaf.length : 'non-Uint8Array'\n }`,\n );\n }\n }\n}\n\nexport function merkleSha2256Root(leaves: ReadonlyArray<Uint8Array>): Uint8Array {\n validateLeaves(leaves, 'merkleSha2256Root');\n return mthRecursive(leaves, 0, leaves.length);\n}\n\nexport function merkleSha2256InclusionProof(\n leaves: ReadonlyArray<Uint8Array>,\n index: number,\n): Uint8Array[] {\n validateLeaves(leaves, 'merkleSha2256InclusionProof');\n if (!Number.isInteger(index) || index < 0 || index >= leaves.length) {\n throw new Error(\n `merkleSha2256InclusionProof: index ${index} out of range [0, ${leaves.length})`,\n );\n }\n return auditPath(leaves, index, 0, leaves.length);\n}\n\n/**\n * Verify an inclusion proof per RFC 9162 §2.1.3.2 (iterative form).\n *\n * `proof` is ordered leaf-to-root: `proof[0]` is the sibling at the leaf\n * level, `proof[m-1]` is the top-level sibling. The fold uses the\n * `sn`/`fn` tracking from RFC 9162: `sn` is the leaf index within the\n * current subtree, `fn` is (subtree_size - 1). At each step, `sn` odd\n * OR `sn == fn` means the current node is a right child (sibling on\n * the left); otherwise it is a left child (sibling on the right).\n * Both shift right by one each iteration. This handles non-power-of-2\n * sizes including the \"promote a lone right subtree\" cases.\n */\nexport function merkleSha2256VerifyInclusion(\n leaf: Uint8Array,\n index: number,\n treeSize: number,\n proof: ReadonlyArray<Uint8Array>,\n root: Uint8Array,\n): boolean {\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) return false;\n if (!(root instanceof Uint8Array) || root.length !== DIGEST_LENGTH) return false;\n if (\n !Number.isInteger(index) ||\n !Number.isInteger(treeSize) ||\n treeSize < 1 ||\n index < 0 ||\n index >= treeSize\n ) {\n return false;\n }\n for (let i = 0; i < proof.length; i++) {\n const sibling = proof[i];\n if (!(sibling instanceof Uint8Array) || sibling.length !== DIGEST_LENGTH) {\n return false;\n }\n }\n\n if (treeSize === 1) {\n if (proof.length !== 0 || index !== 0) return false;\n return compareCt(hashLeaf(leaf), root);\n }\n\n let h = hashLeaf(leaf);\n let sn = index;\n let fn = treeSize - 1;\n for (let i = 0; i < proof.length; i++) {\n if (fn === 0) return false;\n const sibling = proof[i] as Uint8Array;\n if ((sn & 1) === 1 || sn === fn) {\n h = hashNode(sibling, h);\n while ((sn & 1) === 0 && sn !== 0) {\n sn >>>= 1;\n fn >>>= 1;\n }\n } else {\n h = hashNode(h, sibling);\n }\n sn >>>= 1;\n fn >>>= 1;\n }\n if (fn !== 0) return false;\n return compareCt(h, root);\n}\n\nfunction largestPow2Lt(n: number): number {\n let k = 1;\n while (k * 2 < n) k *= 2;\n return k;\n}\n\nfunction hashLeaf(d: Uint8Array): Uint8Array {\n const buf = new Uint8Array(1 + d.length);\n buf[0] = LEAF_PREFIX;\n buf.set(d, 1);\n return sha256(buf);\n}\n\nfunction hashNode(left: Uint8Array, right: Uint8Array): Uint8Array {\n const buf = new Uint8Array(1 + left.length + right.length);\n buf[0] = NODE_PREFIX;\n buf.set(left, 1);\n buf.set(right, 1 + left.length);\n return sha256(buf);\n}\n\nfunction mthRecursive(leaves: ReadonlyArray<Uint8Array>, start: number, end: number): Uint8Array {\n const n = end - start;\n if (n === 1) {\n return hashLeaf(leaves[start] as Uint8Array);\n }\n const k = largestPow2Lt(n);\n const left = mthRecursive(leaves, start, start + k);\n const right = mthRecursive(leaves, start + k, end);\n return hashNode(left, right);\n}\n\nfunction auditPath(\n leaves: ReadonlyArray<Uint8Array>,\n i: number,\n start: number,\n end: number,\n): Uint8Array[] {\n const n = end - start;\n if (n === 1) return [];\n const k = largestPow2Lt(n);\n if (i < k) {\n const subPath = auditPath(leaves, i, start, start + k);\n subPath.push(mthRecursive(leaves, start + k, end));\n return subPath;\n }\n const subPath = auditPath(leaves, i - k, start + k, end);\n subPath.push(mthRecursive(leaves, start, start + k));\n return subPath;\n}\n","// Label 309 v1 PoE record Zod schemas.\n//\n// Scope: structural shape gate over the DECODED record body. The schema\n// enforces per-field CBOR types (every map position rejects a CBOR byte\n// string — see the text-keyed-map gate below), the fixed byte lengths a field\n// can assert in isolation (32-byte `supersedes`, 32-byte `slots_mac`, the\n// 16..64-byte passphrase salt), closed-map invariants (`items[i]`,\n// `merkle[i]`, `sigs[i]`, `passphrase`), and the `v == 1` literal.\n// Cross-field rules (content-hash binding under `enc`, slots/passphrase\n// exclusivity, `crit[]` shape, registry membership of algorithm identifiers,\n// COSE_Sign1 structural decode, URI shape, non-empty-array rules, integer\n// ranges) fire in `validator.ts` so each violation emits its precise\n// canonical code rather than a generic schema mismatch.\n//\n// Every logical byte string is a SINGLE CBOR byte string and every URI is a\n// SINGLE text string: record-body fields carry no 64-byte cap and no chunk\n// wrappers. The ledger's 64-byte metadata-string cap is satisfied by the\n// whole-body transport chunk array alone (see `carriage.ts`), which is\n// reassembled before the validator ever sees the body.\n\nimport { z } from 'zod';\n\n// =============================================================================\n// Text-keyed-map gate\n// =============================================================================\n//\n// Every map position in the record grammar is a CBOR text-keyed map. The\n// canonical decoder surfaces such a map as a plain object — but a CBOR byte\n// string surfaces as a Uint8Array, which is ALSO an object to Zod, so an\n// ungated object schema would walk its byte indices as if they were map keys\n// and mis-report one unknown-key issue per byte plus a missing-required issue\n// per absent field. The gate runs ahead of the map schema and fails a byte\n// string with a SINGLE issue at the position itself — the same one-issue\n// rejection every other non-map CBOR shape already receives from the object\n// parser; the validator's issue mapper then lifts it to the position's\n// canonical code by path. (`z.record` positions need no gate: Zod's record\n// parser rejects a Uint8Array outright. A map carrying non-text keys decodes\n// to a `Map` and is handled by the validator's pre-guard, not here.)\nfunction textKeyedMap<S extends z.ZodType>(inner: S) {\n return z\n .custom<unknown>((value) => !(value instanceof Uint8Array), {\n message: 'CBOR byte string present where a text-keyed map is required',\n })\n .pipe(inner);\n}\n\n// =============================================================================\n// Hashes map\n// =============================================================================\n//\n// `hashes` is a non-empty CBOR map keyed by content-hash algorithm identifier\n// (a text string from the content-hash registry) with the 32-byte digest as\n// value. The canonical decoder surfaces a text-keyed CBOR map as a plain JS\n// object — `z.record` admits any string key here. Registry membership\n// (`UNSUPPORTED_HASH_ALG`), per-algorithm digest length\n// (`HASH_DIGEST_LENGTH_MISMATCH`), and the non-empty rule live in the\n// validator's domain pass.\n\nexport const HashDigestSchema = z.instanceof(Uint8Array);\n\nexport const HashesMapSchema = z.record(z.string(), HashDigestSchema);\nexport type HashesMap = z.infer<typeof HashesMapSchema>;\n\n// =============================================================================\n// URIs\n// =============================================================================\n//\n// One absolute URI in a single text string. Absolute-URI / fragment / scheme\n// / per-scheme body rules (`INVALID_URI`) are domain checks.\n\nexport const UriSchema = z.string();\nexport type Uri = z.infer<typeof UriSchema>;\n\n// =============================================================================\n// Top-level `merkle[]`\n// =============================================================================\n//\n// Each commit is a closed map `{alg, root, leaf_count, ? uris}`. `alg` is open\n// (registry membership → `UNSUPPORTED_MERKLE_COMMIT_ALG` in the domain pass).\n// `leaf_count` is a CBOR unsigned integer pinned to `1 .. 2^32 − 1`, handled\n// as an EXACT integer: the canonical decoder surfaces values above 2^53 − 1 as\n// `bigint`, so the schema admits both representations and the domain pass\n// enforces the range (`SCHEMA_MERKLE_LEAF_COUNT_INVALID`) without ever\n// rounding through a float.\n\nexport const MerkleCommitSchema = textKeyedMap(\n z\n .object({\n alg: z.string(),\n root: z.instanceof(Uint8Array),\n leaf_count: z.union([z.number().int(), z.bigint()]),\n uris: z.array(UriSchema).optional(),\n })\n .strict(),\n);\nexport type MerkleCommit = z.infer<typeof MerkleCommitSchema>;\n\n// =============================================================================\n// Encryption envelope\n// =============================================================================\n//\n// The wire `enc` value is a CHOICE between two readings, mirroring the\n// grammar's `enc = enc-scheme-1 / enc-opaque`:\n//\n// - the scheme-1 shape — the closed map this revision defines, applied by\n// the validator only when `scheme`, `kem`, and `aead` are ALL supported\n// identifiers;\n// - the opaque reading — `scheme` (any CBOR unsigned integer) plus\n// arbitrary text-keyed bounded metadata, the degrade-to-opaque escape\n// hatch for envelopes under identifiers this implementation does not\n// support (`ENC_UNSUPPORTED`).\n//\n// The choice is not a discriminator: a `scheme: 1` envelope that fails the\n// scheme-1 shape is rejected with its typed code, never reclassified as\n// opaque. The validator therefore keeps `enc` as `unknown` at the item layer\n// and dispatches on raw `scheme` / `kem` / `aead` support before applying\n// `EncScheme1Schema`.\n\n// Per-slot recipient entry. The slot shape is KEM-driven:\n//\n// - x25519: `{ epk: bstr(32), wrap: bstr(48) }` — `epk` is the\n// ephemeral X25519 public key.\n// - mlkem768x25519: `{ kem_ct: bstr(1120), wrap: bstr(48) }` — `kem_ct` is\n// the single 1120-byte X-Wing encapsulation; there is NO per-slot `epk`\n// on the hybrid path (the X25519 ephemeral is the trailing 32 bytes of\n// `kem_ct`).\n//\n// The schema is deliberately PERMISSIVE: all three fields are optional and\n// `.strict()` is not applied, because the required shape depends on the\n// envelope-level `kem`, which a slot cannot see in isolation. The KEM-driven\n// gate in the validator emits the precise codes (`KEM_EPK_LENGTH_MISMATCH`,\n// `KEM_CT_LENGTH_MISMATCH`, `WRAP_LENGTH_MISMATCH`, `ENC_SLOT_INVALID_SHAPE`)\n// against the RAW decoded slot key set, so cross-KEM contamination and stray\n// keys are rejected even though the schema strips nothing here.\nexport const SlotSchema = textKeyedMap(\n z.object({\n epk: z.instanceof(Uint8Array).optional(),\n kem_ct: z.instanceof(Uint8Array).optional(),\n wrap: z.instanceof(Uint8Array).optional(),\n }),\n);\nexport type Slot = z.infer<typeof SlotSchema>;\n\n// Argon2id params `{m, t, p}` — a closed map of CBOR unsigned integers in the\n// pinned `0 .. 2^32 − 1` exact-integer range. The closed-map rule, the range,\n// and the floor checks all emit their codes in the validator's domain pass;\n// this schema is the public convenience type for producers.\nexport const Argon2idParamsSchema = textKeyedMap(\n z\n .object({\n m: z.union([z.number().int(), z.bigint()]),\n t: z.union([z.number().int(), z.bigint()]),\n p: z.union([z.number().int(), z.bigint()]),\n })\n .strict(),\n);\nexport type Argon2idParams = z.infer<typeof Argon2idParamsSchema>;\n\n// Passphrase block. `alg` is open (registry membership →\n// `ENC_PASSPHRASE_ALG_UNSUPPORTED` in the domain pass); `params` is open here\n// (the domain pass narrows on the registered `alg` and emits\n// `SCHEMA_UNKNOWN_FIELD` / `SCHEMA_MISSING_REQUIRED` / `SCHEMA_TYPE_MISMATCH`\n// / the floor and ceiling codes per sub-field). Salt length bounds are\n// schema-layer refinements carrying their dedicated codes.\nexport const PassphraseBlockSchema = textKeyedMap(\n z\n .object({\n alg: z.string(),\n salt: z.instanceof(Uint8Array).superRefine((bytes, ctx) => {\n if (bytes.length < 16) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message: `passphrase.salt length ${bytes.length} < 16`,\n params: { code: 'ENC_PASSPHRASE_SALT_TOO_SHORT' },\n });\n } else if (bytes.length > 64) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message: `passphrase.salt length ${bytes.length} > 64`,\n params: { code: 'ENC_PASSPHRASE_SALT_TOO_LONG' },\n });\n }\n }),\n params: z.record(z.string(), z.unknown()),\n })\n .strict(),\n);\nexport type PassphraseBlock = z.infer<typeof PassphraseBlockSchema>;\n\n// The typed scheme-1 envelope arm. Applied by the validator only when\n// `scheme` / `kem` / `aead` are all supported identifiers; under an\n// unsupported identifier the envelope takes the opaque reading instead and\n// this schema never runs. The map is CLOSED (`.strict()`): an unknown key in\n// a supported envelope is `SCHEMA_UNKNOWN_FIELD`, never a reason to fall back\n// to the opaque reading. Cross-field key-path invariants (exclusivity,\n// `slots` ↔ `slots_mac` ↔ `kem`, non-empty `slots`) are domain checks.\nexport const EncScheme1Schema = textKeyedMap(\n z\n .object({\n scheme: z.literal(1),\n aead: z.string(),\n kem: z.string().optional(),\n nonce: z.instanceof(Uint8Array),\n slots: z.array(SlotSchema).optional(),\n slots_mac: z\n .instanceof(Uint8Array)\n .refine((b) => b.length === 32, {\n params: { code: 'ENC_SLOTS_MAC_INVALID_LENGTH' },\n })\n .optional(),\n passphrase: PassphraseBlockSchema.optional(),\n })\n .strict(),\n);\nexport type EncScheme1 = z.infer<typeof EncScheme1Schema>;\n\n// The opaque reading: `scheme` is the only structurally required key (any\n// CBOR unsigned integer — `bigint` admits values above 2^53), and every other\n// text-keyed entry is unconstrained bounded metadata. A verifier escape\n// hatch, never a producer surface.\nexport const EncOpaqueSchema = textKeyedMap(\n z.looseObject({\n scheme: z.union([z.number().int().nonnegative(), z.bigint().nonnegative()]),\n }),\n);\nexport type EncOpaque = z.infer<typeof EncOpaqueSchema>;\n\nexport const EncryptionEnvelopeSchema = z.union([EncScheme1Schema, EncOpaqueSchema]);\nexport type EncryptionEnvelope = z.infer<typeof EncryptionEnvelopeSchema>;\n\n// =============================================================================\n// Item entry\n// =============================================================================\n\nexport const ItemEntrySchema = textKeyedMap(\n z\n .object({\n hashes: HashesMapSchema,\n uris: z.array(UriSchema).optional(),\n // Captured as `unknown`: the envelope is a union whose disposition\n // (typed scheme-1 vs opaque) depends on identifier support, so the\n // validator's domain pass — not this schema — narrows it.\n enc: z.unknown().optional(),\n })\n .strict(),\n);\nexport type ItemEntry = z.infer<typeof ItemEntrySchema>;\n\n// =============================================================================\n// Sig entry\n// =============================================================================\n//\n// Closed CBOR map `{cose_sign1, ? cose_key}`. Each value is a SINGLE byte\n// string carrying the CBOR-encoded COSE_Sign1 / COSE_Key. Canonical CBOR\n// map-key sort (RFC 8949 §4.2.1, bytewise lex on encoded keys) places\n// `cose_key` before `cose_sign1`; schema property order is irrelevant.\nexport const SigEntrySchema = textKeyedMap(\n z\n .object({\n cose_key: z.instanceof(Uint8Array).optional(),\n cose_sign1: z.instanceof(Uint8Array),\n })\n .strict(),\n);\nexport type SigEntry = z.infer<typeof SigEntrySchema>;\n\n// =============================================================================\n// Supersedence\n// =============================================================================\n\nexport const SupersedesSchema = z.instanceof(Uint8Array).refine((b) => b.length === 32, {\n params: { code: 'SUPERSEDES_TX_INVALID_LENGTH' },\n});\nexport type Supersedes = z.infer<typeof SupersedesSchema>;\n\n// =============================================================================\n// Top-level record\n// =============================================================================\n//\n// `v == 1` is a literal — a future major (`v: 2`) MUST be rejected with\n// `SCHEMA_INVALID_LITERAL`. `z.literal(1)` preserves the narrow `1` type for\n// the inferred `PoeRecord[\"v\"]` and emits Zod's `invalid_value` code, which\n// the validator's mapper lifts to `SCHEMA_INVALID_LITERAL`.\n//\n// `looseObject` admits extension keys; the validator's domain pass rejects\n// unknown keys that match neither extension namespace with\n// `SCHEMA_UNKNOWN_FIELD`.\nexport const VersionLiteralSchema = z.literal(1);\n\nexport const PoeRecordSchema = textKeyedMap(\n z.looseObject({\n v: VersionLiteralSchema,\n items: z.array(ItemEntrySchema).optional(),\n merkle: z.array(MerkleCommitSchema).optional(),\n supersedes: SupersedesSchema.optional(),\n sigs: z.array(SigEntrySchema).optional(),\n crit: z.array(z.string()).optional(),\n }),\n);\nexport type PoeRecord = z.infer<typeof PoeRecordSchema>;\n\n// =============================================================================\n// Closed top-level base-key registry\n// =============================================================================\n//\n// Used by the validator's domain pass to distinguish unknown-typo keys from\n// well-formed extension keys.\nexport const TOP_LEVEL_BASE_KEYS: ReadonlySet<string> = new Set([\n 'v',\n 'items',\n 'merkle',\n 'supersedes',\n 'sigs',\n 'crit',\n]);\n\n// Extension-key namespaces: `^x-.+` (vendor / experimental) and `^[a-z]+-.+`\n// (companion namespace), with control characters (U+0000–U+001F,\n// U+007F–U+009F) rejected ANYWHERE in the key — including a trailing newline,\n// so `x-note\\n` and `x-a\\nb` are both outside the namespace. The suffix\n// character class spells the exclusion out rather than relying on `.`\n// semantics, the literal `x-` / `[a-z]+-` prefixes admit no control\n// characters by construction, and `$` in JavaScript matches only at the true\n// end of the string, so a trailing newline cannot hide behind the anchor.\n// eslint-disable-next-line no-control-regex -- the control-character exclusion IS the admissibility rule\nexport const EXTENSION_KEY_VENDOR_RE = /^x-[^\\u0000-\\u001f\\u007f-\\u009f]+$/;\n// eslint-disable-next-line no-control-regex -- the control-character exclusion IS the admissibility rule\nexport const EXTENSION_KEY_COMPANION_RE = /^[a-z]+-[^\\u0000-\\u001f\\u007f-\\u009f]+$/;\n\nexport function isExtensionKey(k: string): boolean {\n return EXTENSION_KEY_VENDOR_RE.test(k) || EXTENSION_KEY_COMPANION_RE.test(k);\n}\n","// Label 309 v1 record encoder.\n//\n// Produces canonical CBOR bytes per RFC 8949 §4.2.1 deterministic encoding —\n// definite lengths, bytewise-lexicographically sorted map keys, no duplicate\n// keys, shortest-form integers. The canonical layer\n// (`@cardanowall/crypto-core/cbor`) owns those rules, so this module's job is\n// only to project the typed record onto the CBOR value algebra.\n//\n// That projection is the identity: under the Label 309 wire shapes every\n// record field already IS its CBOR value — `hashes` is a text-keyed map of\n// byte-string digests, each URI is a single text string, `kem_ct` /\n// `cose_sign1` / `cose_key` are single byte strings, and the canonical\n// encoder derives map-key order itself. The only transformation performed\n// here is dropping `undefined` optionals (a JS-only artefact with no CBOR\n// counterpart — left in place it would encode as the `undefined` simple\n// value, which the canonical profile forbids) and, for the signing body,\n// removing `sigs`.\n//\n// Round-trip property: for every record `R` the validator accepts,\n// validatePoeRecord(encodePoeRecord(R)).valid === true\n// and the decoded record is `R` (modulo CBOR-canonical key order).\n\nimport { encodeCanonicalCbor, type CanonicalCborValue } from '@cardanowall/crypto-core/cbor';\n\nimport type { PoeRecord } from './schema';\n\n/** Canonical CBOR bytes of the full record body — the bytes the chunk-array\n * transport carries on chain (see `carriage.ts`). */\nexport function encodePoeRecord(record: PoeRecord): Uint8Array {\n return encodeCanonicalCbor(toCborValue(record, /* includeSigs */ true));\n}\n\n/**\n * Canonical CBOR bytes of the record body **with `sigs` removed** — the body\n * a record-level signature covers. Producers prepend the 25-byte UTF-8 domain\n * prefix `cardano-poe-record-sig-v1` before invoking Ed25519 (the crypto-core\n * helper `buildLabel309SigStructure` handles the prefix and the\n * `Sig_structure` wrapping). Extension keys are part of the signed body and\n * pass through verbatim.\n */\nexport function encodeRecordBodyForSigning(record: PoeRecord): Uint8Array {\n return encodeCanonicalCbor(toCborValue(record, /* includeSigs */ false));\n}\n\nfunction toCborValue(record: PoeRecord, includeSigs: boolean): CanonicalCborValue {\n const out: { [key: string]: CanonicalCborValue } = {};\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) continue;\n if (!includeSigs && key === 'sigs') continue;\n out[key] = stripUndefined(value as CanonicalCborValue);\n }\n return out;\n}\n\n// Drop `undefined`-valued properties recursively. A typed record reaches the\n// encoder with its optional fields either absent or explicitly `undefined`;\n// CBOR has no counterpart for the latter (cbor2 would emit the major-type-7\n// `undefined` simple value, which the canonical profile rejects on decode),\n// so both spell \"absent\" on the wire.\nfunction stripUndefined(value: CanonicalCborValue): CanonicalCborValue {\n if (value === null || typeof value !== 'object' || value instanceof Uint8Array) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((element) => stripUndefined(element));\n }\n if (value instanceof Map) {\n const out = new Map<string | number, CanonicalCborValue>();\n for (const [k, v] of value) {\n if (v === undefined) continue;\n out.set(k, stripUndefined(v));\n }\n return out;\n }\n const out: { [key: string]: CanonicalCborValue } = {};\n for (const [k, v] of Object.entries(value)) {\n if (v === undefined) continue;\n out[k] = stripUndefined(v as CanonicalCborValue);\n }\n return out;\n}\n","// Label 309 v1 error-code catalogue — the TypeScript projection of the\n// machine-readable registry (`error-codes.json` in the Label 309 distribution).\n//\n// Three layers emit these codes:\n// - Part A — the structural validator (`validatePoeRecord`): a pure\n// function over the reassembled CBOR record body.\n// - carriage — the pre-validator transport step that reassembles the\n// label-309 chunk array (`reassembleLabel309Value`).\n// - Part B — the public / recipient verifier (chain resolution,\n// signature verification, content fetch, decryption).\n// Re-exported here so downstream verifiers dispatch on a\n// single `ErrorCode` union.\n//\n// Codes are SCREAMING_SNAKE_CASE and MUST match the canonical catalogue\n// byte-exact across the TS/PY/RS implementations — no lowercase synonyms,\n// no parser-internal codes, no free-form reason strings.\n//\n// `ERROR_CODES` preserves the registry's entry order. That order is\n// load-bearing: issues sharing an identical path tie-break by the order in\n// which their codes appear in the registry, so the list below doubles as the\n// cross-implementation sort key (`errorCodeRegistryIndex`).\n\nexport const ERROR_CODES = [\n 'MALFORMED_CBOR',\n 'SCHEMA_TYPE_MISMATCH',\n 'SCHEMA_MISSING_REQUIRED',\n 'SCHEMA_UNKNOWN_FIELD',\n 'SCHEMA_INVALID_LITERAL',\n 'SCHEMA_EMPTY_RECORD',\n 'HASH_DIGEST_LENGTH_MISMATCH',\n 'UNSUPPORTED_HASH_ALG',\n 'UNSUPPORTED_MERKLE_COMMIT_ALG',\n 'SCHEMA_MERKLE_LEAF_COUNT_INVALID',\n 'INVALID_URI',\n 'CHUNK_TOO_LARGE',\n 'UNAUTHENTICATED_CIPHER_FORBIDDEN',\n 'UNSUPPORTED_AEAD_ALG',\n 'NONCE_LENGTH_MISMATCH',\n 'UNSUPPORTED_ENVELOPE_SCHEME',\n 'ENC_UNSUPPORTED',\n 'ENC_SLOTS_EMPTY',\n 'ENC_SLOT_INVALID_SHAPE',\n 'UNSUPPORTED_KEM_ALG',\n 'ENC_KEM_REQUIRED',\n 'KEM_EPK_LENGTH_MISMATCH',\n 'KEM_CT_LENGTH_MISMATCH',\n 'WRAP_LENGTH_MISMATCH',\n 'ENC_SLOTS_MAC_INVALID_LENGTH',\n 'ENC_SLOTS_MAC_REQUIRED',\n 'ENC_SLOTS_REQUIRED',\n 'ENC_SLOTS_DUPLICATE_KEM_MATERIAL',\n 'ENC_SLOTS_TOO_MANY',\n 'ENC_ENVELOPE_TOO_LARGE',\n 'ENC_EXCLUSIVITY_VIOLATION',\n 'ENC_NO_KEY_PATH',\n 'ENC_REQUIRES_CONTENT_HASH',\n 'ENC_PASSPHRASE_ALG_UNSUPPORTED',\n 'ENC_PASSPHRASE_SALT_TOO_SHORT',\n 'ENC_PASSPHRASE_SALT_TOO_LONG',\n 'ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW',\n 'ENC_PASSPHRASE_PARAMS_EXCEED_POLICY',\n 'MALFORMED_SIG_COSE_SIGN1',\n 'SIGNATURE_UNSUPPORTED',\n 'SIG_ENTRY_INVALID_SHAPE',\n 'SIG_ENTRY_KID_COSE_KEY_CONFLICT',\n 'SIG_PRIVATE_KEY_LEAKED',\n 'SUPERSEDES_TX_INVALID_LENGTH',\n 'EXTENSION_UNSUPPORTED_CRITICAL',\n 'CRIT_SHAPE_INVALID',\n 'TX_NOT_FOUND',\n 'PROVIDER_UNAVAILABLE',\n 'TX_INTEGRITY_MISMATCH',\n 'METADATA_NOT_FOUND',\n 'INSUFFICIENT_CONFIRMATIONS',\n 'SIGNATURE_INVALID',\n 'SIGNER_KEY_UNRESOLVED',\n 'WALLET_ADDRESS_MISMATCH',\n 'URI_TARGET_FORBIDDEN',\n 'URI_INTEGRITY_MISMATCH',\n 'URI_PROVIDER_INTEGRITY_MISMATCH',\n 'URI_FETCH_FAILED',\n 'CONTENT_UNAVAILABLE',\n 'CONTENT_FETCH_LIMIT_EXCEEDED',\n 'CIPHERTEXT_UNAVAILABLE',\n 'SERVICE_INDEPENDENCE_VIOLATION',\n 'WRONG_DECRYPTION_INPUT_SHAPE',\n 'WRONG_RECIPIENT_KEY',\n 'TAMPERED_HEADER',\n 'TAMPERED_CIPHERTEXT',\n 'KDF_DERIVATION_FAILED',\n 'ENC_PASSPHRASE_UNNORMALIZABLE',\n 'ENC_PASSPHRASE_EMPTY',\n 'SCHEMA_MERKLE_LEAF_COUNT_MISMATCH',\n 'SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED',\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'MERKLE_ROOT_MISMATCH',\n 'MERKLE_LEAVES_UNAVAILABLE',\n 'MERKLE_UNSUPPORTED',\n 'OUT_OF_PROFILE_SKIPPED',\n] as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[number];\n\n// =============================================================================\n// Emitting layer (`part` in the registry)\n// =============================================================================\n\nexport type ErrorCodePart = 'A' | 'B' | 'carriage';\n\nexport const ERROR_CODE_PART: Readonly<Record<ErrorCode, ErrorCodePart>> = Object.freeze({\n MALFORMED_CBOR: 'A',\n SCHEMA_TYPE_MISMATCH: 'A',\n SCHEMA_MISSING_REQUIRED: 'A',\n SCHEMA_UNKNOWN_FIELD: 'A',\n SCHEMA_INVALID_LITERAL: 'A',\n SCHEMA_EMPTY_RECORD: 'A',\n HASH_DIGEST_LENGTH_MISMATCH: 'A',\n UNSUPPORTED_HASH_ALG: 'A',\n UNSUPPORTED_MERKLE_COMMIT_ALG: 'A',\n SCHEMA_MERKLE_LEAF_COUNT_INVALID: 'A',\n INVALID_URI: 'A',\n CHUNK_TOO_LARGE: 'carriage',\n UNAUTHENTICATED_CIPHER_FORBIDDEN: 'A',\n UNSUPPORTED_AEAD_ALG: 'A',\n NONCE_LENGTH_MISMATCH: 'A',\n UNSUPPORTED_ENVELOPE_SCHEME: 'A',\n ENC_UNSUPPORTED: 'A',\n ENC_SLOTS_EMPTY: 'A',\n ENC_SLOT_INVALID_SHAPE: 'A',\n UNSUPPORTED_KEM_ALG: 'A',\n ENC_KEM_REQUIRED: 'A',\n KEM_EPK_LENGTH_MISMATCH: 'A',\n KEM_CT_LENGTH_MISMATCH: 'A',\n WRAP_LENGTH_MISMATCH: 'A',\n ENC_SLOTS_MAC_INVALID_LENGTH: 'A',\n ENC_SLOTS_MAC_REQUIRED: 'A',\n ENC_SLOTS_REQUIRED: 'A',\n ENC_SLOTS_DUPLICATE_KEM_MATERIAL: 'A',\n ENC_SLOTS_TOO_MANY: 'A',\n ENC_ENVELOPE_TOO_LARGE: 'A',\n ENC_EXCLUSIVITY_VIOLATION: 'A',\n ENC_NO_KEY_PATH: 'A',\n ENC_REQUIRES_CONTENT_HASH: 'A',\n ENC_PASSPHRASE_ALG_UNSUPPORTED: 'A',\n ENC_PASSPHRASE_SALT_TOO_SHORT: 'A',\n ENC_PASSPHRASE_SALT_TOO_LONG: 'A',\n ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW: 'A',\n ENC_PASSPHRASE_PARAMS_EXCEED_POLICY: 'A',\n MALFORMED_SIG_COSE_SIGN1: 'A',\n SIGNATURE_UNSUPPORTED: 'A',\n SIG_ENTRY_INVALID_SHAPE: 'A',\n SIG_ENTRY_KID_COSE_KEY_CONFLICT: 'A',\n SIG_PRIVATE_KEY_LEAKED: 'A',\n SUPERSEDES_TX_INVALID_LENGTH: 'A',\n EXTENSION_UNSUPPORTED_CRITICAL: 'A',\n CRIT_SHAPE_INVALID: 'A',\n TX_NOT_FOUND: 'B',\n PROVIDER_UNAVAILABLE: 'B',\n TX_INTEGRITY_MISMATCH: 'B',\n METADATA_NOT_FOUND: 'B',\n INSUFFICIENT_CONFIRMATIONS: 'B',\n SIGNATURE_INVALID: 'B',\n SIGNER_KEY_UNRESOLVED: 'B',\n WALLET_ADDRESS_MISMATCH: 'B',\n URI_TARGET_FORBIDDEN: 'B',\n URI_INTEGRITY_MISMATCH: 'B',\n URI_PROVIDER_INTEGRITY_MISMATCH: 'B',\n URI_FETCH_FAILED: 'B',\n CONTENT_UNAVAILABLE: 'B',\n CONTENT_FETCH_LIMIT_EXCEEDED: 'B',\n CIPHERTEXT_UNAVAILABLE: 'B',\n SERVICE_INDEPENDENCE_VIOLATION: 'B',\n WRONG_DECRYPTION_INPUT_SHAPE: 'B',\n WRONG_RECIPIENT_KEY: 'B',\n TAMPERED_HEADER: 'B',\n TAMPERED_CIPHERTEXT: 'B',\n KDF_DERIVATION_FAILED: 'B',\n ENC_PASSPHRASE_UNNORMALIZABLE: 'B',\n ENC_PASSPHRASE_EMPTY: 'B',\n SCHEMA_MERKLE_LEAF_COUNT_MISMATCH: 'B',\n SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED: 'B',\n SCHEMA_MERKLE_LEAVES_MALFORMED: 'B',\n MERKLE_ROOT_MISMATCH: 'B',\n MERKLE_LEAVES_UNAVAILABLE: 'B',\n MERKLE_UNSUPPORTED: 'B',\n OUT_OF_PROFILE_SKIPPED: 'B',\n});\n\n// Layer-filtered views, in registry order. The structural validator emits only\n// Part A codes; the carriage (transport) step emits only the carriage code;\n// the verifier layer emits Part B codes (and re-runs the first two layers).\nexport const STRUCTURAL_ERROR_CODES: ReadonlyArray<ErrorCode> = Object.freeze(\n ERROR_CODES.filter((code) => ERROR_CODE_PART[code] === 'A'),\n);\nexport const CARRIAGE_ERROR_CODES: ReadonlyArray<ErrorCode> = Object.freeze(\n ERROR_CODES.filter((code) => ERROR_CODE_PART[code] === 'carriage'),\n);\nexport const VERIFIER_ERROR_CODES: ReadonlyArray<ErrorCode> = Object.freeze(\n ERROR_CODES.filter((code) => ERROR_CODE_PART[code] === 'B'),\n);\n\nexport type StructuralErrorCode = ErrorCode;\nexport type VerifierErrorCode = ErrorCode;\n\n// =============================================================================\n// Severity\n// =============================================================================\n//\n// `error` fails the record; `warning` is a non-fatal runtime anomaly; `info`\n// is a deliberate non-failing disposition. Four codes carry DUAL severity —\n// the map records their DEFAULT reading, and a strict context promotes them\n// to `error`:\n// - ENC_UNSUPPORTED — info by default; error for the recipient\n// role / strict sealed-crypto mode.\n// - MERKLE_LEAVES_UNAVAILABLE — warning beside a verified content\n// commitment; error when its absence leaves\n// the record with no verified commitment.\n// - MERKLE_UNSUPPORTED — info beside a validated items[] claim;\n// error on a merkle-only record.\n// - OUT_OF_PROFILE_SKIPPED — info in render mode; error in strict\n// end-to-end mode.\n// No layer may soften an `error` into a `warning` to make a record pass.\n\nexport type Severity = 'error' | 'warning' | 'info';\n\nexport const SEVERITY: Readonly<Record<ErrorCode, Severity>> = Object.freeze({\n MALFORMED_CBOR: 'error',\n SCHEMA_TYPE_MISMATCH: 'error',\n SCHEMA_MISSING_REQUIRED: 'error',\n SCHEMA_UNKNOWN_FIELD: 'error',\n SCHEMA_INVALID_LITERAL: 'error',\n SCHEMA_EMPTY_RECORD: 'error',\n HASH_DIGEST_LENGTH_MISMATCH: 'error',\n UNSUPPORTED_HASH_ALG: 'error',\n UNSUPPORTED_MERKLE_COMMIT_ALG: 'error',\n SCHEMA_MERKLE_LEAF_COUNT_INVALID: 'error',\n INVALID_URI: 'error',\n CHUNK_TOO_LARGE: 'error',\n UNAUTHENTICATED_CIPHER_FORBIDDEN: 'error',\n UNSUPPORTED_AEAD_ALG: 'error',\n NONCE_LENGTH_MISMATCH: 'error',\n UNSUPPORTED_ENVELOPE_SCHEME: 'error',\n ENC_UNSUPPORTED: 'info',\n ENC_SLOTS_EMPTY: 'error',\n ENC_SLOT_INVALID_SHAPE: 'error',\n UNSUPPORTED_KEM_ALG: 'error',\n ENC_KEM_REQUIRED: 'error',\n KEM_EPK_LENGTH_MISMATCH: 'error',\n KEM_CT_LENGTH_MISMATCH: 'error',\n WRAP_LENGTH_MISMATCH: 'error',\n ENC_SLOTS_MAC_INVALID_LENGTH: 'error',\n ENC_SLOTS_MAC_REQUIRED: 'error',\n ENC_SLOTS_REQUIRED: 'error',\n ENC_SLOTS_DUPLICATE_KEM_MATERIAL: 'error',\n ENC_SLOTS_TOO_MANY: 'error',\n ENC_ENVELOPE_TOO_LARGE: 'error',\n ENC_EXCLUSIVITY_VIOLATION: 'error',\n ENC_NO_KEY_PATH: 'error',\n ENC_REQUIRES_CONTENT_HASH: 'error',\n ENC_PASSPHRASE_ALG_UNSUPPORTED: 'error',\n ENC_PASSPHRASE_SALT_TOO_SHORT: 'error',\n ENC_PASSPHRASE_SALT_TOO_LONG: 'error',\n ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW: 'error',\n ENC_PASSPHRASE_PARAMS_EXCEED_POLICY: 'error',\n MALFORMED_SIG_COSE_SIGN1: 'error',\n SIGNATURE_UNSUPPORTED: 'info',\n SIG_ENTRY_INVALID_SHAPE: 'error',\n SIG_ENTRY_KID_COSE_KEY_CONFLICT: 'error',\n SIG_PRIVATE_KEY_LEAKED: 'error',\n SUPERSEDES_TX_INVALID_LENGTH: 'error',\n EXTENSION_UNSUPPORTED_CRITICAL: 'error',\n CRIT_SHAPE_INVALID: 'error',\n TX_NOT_FOUND: 'error',\n PROVIDER_UNAVAILABLE: 'error',\n TX_INTEGRITY_MISMATCH: 'error',\n METADATA_NOT_FOUND: 'error',\n INSUFFICIENT_CONFIRMATIONS: 'info',\n SIGNATURE_INVALID: 'error',\n SIGNER_KEY_UNRESOLVED: 'error',\n WALLET_ADDRESS_MISMATCH: 'error',\n URI_TARGET_FORBIDDEN: 'error',\n URI_INTEGRITY_MISMATCH: 'error',\n URI_PROVIDER_INTEGRITY_MISMATCH: 'warning',\n URI_FETCH_FAILED: 'warning',\n CONTENT_UNAVAILABLE: 'error',\n CONTENT_FETCH_LIMIT_EXCEEDED: 'error',\n CIPHERTEXT_UNAVAILABLE: 'error',\n SERVICE_INDEPENDENCE_VIOLATION: 'error',\n WRONG_DECRYPTION_INPUT_SHAPE: 'error',\n WRONG_RECIPIENT_KEY: 'error',\n TAMPERED_HEADER: 'error',\n TAMPERED_CIPHERTEXT: 'error',\n KDF_DERIVATION_FAILED: 'error',\n ENC_PASSPHRASE_UNNORMALIZABLE: 'error',\n ENC_PASSPHRASE_EMPTY: 'error',\n SCHEMA_MERKLE_LEAF_COUNT_MISMATCH: 'error',\n SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED: 'error',\n SCHEMA_MERKLE_LEAVES_MALFORMED: 'error',\n MERKLE_ROOT_MISMATCH: 'error',\n MERKLE_LEAVES_UNAVAILABLE: 'warning',\n MERKLE_UNSUPPORTED: 'info',\n OUT_OF_PROFILE_SKIPPED: 'info',\n});\n\n// Codes whose severity is context-dependent. `SEVERITY` records the default\n// reading; the promoting context escalates to `error`.\nexport const DUAL_SEVERITY_CODES: ReadonlySet<ErrorCode> = new Set<ErrorCode>([\n 'ENC_UNSUPPORTED',\n 'MERKLE_LEAVES_UNAVAILABLE',\n 'MERKLE_UNSUPPORTED',\n 'OUT_OF_PROFILE_SKIPPED',\n]);\n\nexport function severityOf(code: ErrorCode): Severity {\n return SEVERITY[code];\n}\n\n// Position of a code in the canonical registry. Issues that carry an\n// identical path are ordered by this index, so every implementation sorts an\n// issue list identically.\nconst REGISTRY_INDEX: ReadonlyMap<ErrorCode, number> = new Map(\n ERROR_CODES.map((code, index) => [code, index]),\n);\n\nexport function errorCodeRegistryIndex(code: ErrorCode): number {\n return REGISTRY_INDEX.get(code) as number;\n}\n","/**\n * Utilities for hex, bytearray and number handling.\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport {\n type CHash,\n type TypedArray,\n abytes,\n abytes as abytes_,\n concatBytes,\n isLE,\n randomBytes as randb,\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 * Asserts that a value is a byte array and optionally checks its length.\n * Returns the original reference unchanged on success, and currently also accepts Node `Buffer`\n * values through the upstream validator.\n * This helper throws on malformed input, so APIs that must return `false` need to guard lengths\n * before decoding or before calling it.\n * @example\n * Validate that a value is a byte array with the expected length.\n * ```ts\n * abytes(new Uint8Array([1]), 1);\n * ```\n */\nconst abytesDoc: typeof abytes = abytes;\nexport { abytesDoc as abytes };\n/**\n * Concatenates byte arrays into a new `Uint8Array`.\n * Zero arguments return an empty `Uint8Array`.\n * Invalid segments throw before allocation because each argument is validated first.\n * @example\n * Concatenate two byte arrays into one result.\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nconst concatBytesDoc: typeof concatBytes = concatBytes;\nexport { concatBytesDoc as concatBytes };\n/**\n * Returns cryptographically secure random bytes.\n * Requires `globalThis.crypto.getRandomValues` and throws if that API is unavailable.\n * `bytesLength` is validated by the upstream helper as a non-negative integer before allocation,\n * so negative and fractional values both throw instead of truncating through JS `ToIndex`.\n * @param bytesLength - Number of random bytes to generate.\n * @returns Fresh random bytes.\n * @example\n * Generate a fresh random seed.\n * ```ts\n * const seed = randomBytes(4);\n * ```\n */\nexport const randomBytes: typeof randb = randb;\n\n/**\n * Compares two byte arrays in a length-constant way for equal lengths.\n * Unequal lengths return `false` immediately, and there is no runtime type validation.\n * @param a - First byte array.\n * @param b - Second byte array.\n * @returns Whether both arrays contain the same bytes.\n * @example\n * Compare two byte arrays for equality.\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/**\n * Copies bytes into a fresh `Uint8Array`.\n * Returns a detached plain `Uint8Array` after validating that the input is real bytes.\n * @param bytes - Source bytes.\n * @returns Copy of the input bytes.\n * @example\n * Copy bytes into a fresh array.\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 * Byte-swaps each 64-bit lane in place.\n * Falcon's exact binary64 tables are stored as little-endian byte payloads, so BE runtimes need\n * this boundary helper before aliasing them as host `Float64Array` lanes.\n * @param arr - Byte buffer whose length is a multiple of 8.\n * @returns The same buffer after in-place 64-bit lane byte swaps.\n * @example\n * Byte-swap one 64-bit lane in place.\n * ```ts\n * byteSwap64(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]));\n * ```\n */\nexport function byteSwap64<T extends ArrayBufferView>(arr: T): T {\n const bytes = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n for (let i = 0; i < bytes.length; i += 8) {\n const a0 = bytes[i + 0];\n const a1 = bytes[i + 1];\n const a2 = bytes[i + 2];\n const a3 = bytes[i + 3];\n bytes[i + 0] = bytes[i + 7];\n bytes[i + 1] = bytes[i + 6];\n bytes[i + 2] = bytes[i + 5];\n bytes[i + 3] = bytes[i + 4];\n bytes[i + 4] = a3;\n bytes[i + 5] = a2;\n bytes[i + 6] = a1;\n bytes[i + 7] = a0;\n }\n return arr;\n}\n/**\n * Byte-swaps 64-bit lanes on big-endian runtimes and returns the input unchanged on little-endian.\n * This keeps Falcon's binary64 tables in canonical little-endian order before aliasing them as\n * `Float64Array` lanes on the current host.\n * @param arr - Buffer to pass through or swap in place.\n * @returns The same buffer, normalized for Falcon's little-endian table layout.\n * @example\n * Normalize one host-endian buffer for Falcon's float tables.\n * ```ts\n * baswap64If(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]));\n * ```\n */\nexport const baswap64If: <T extends ArrayBufferView>(arr: T) => T = isLE\n ? (arr) => arr\n : byteSwap64;\n\n/** Shared key-generation surface for signers and KEMs. */\nexport type CryptoKeys = {\n /** Optional metadata about the algorithm family or variant. */\n info?: { type?: string };\n /** Public byte lengths for the exported key material. */\n lengths: { seed?: number; publicKey?: number; secretKey?: 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?: TArg<Uint8Array>) => {\n secretKey: TRet<Uint8Array>;\n publicKey: TRet<Uint8Array>;\n };\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: TArg<Uint8Array>) => TRet<Uint8Array>;\n};\n\n/** Verification options shared by the signature APIs. */\nexport type VerOpts = {\n /** Optional application-defined context string. */\n context?: Uint8Array;\n};\n/** Signing options shared by the signature APIs. */\nexport type SigOpts = VerOpts & {\n // Compatibility with @noble/curves: false to disable, enabled by default, user can pass U8A\n /** Optional extra entropy or `false` to disable randomized signing. */\n extraEntropy?: Uint8Array | false;\n};\n\n/**\n * Validates that an options bag is a plain object.\n * @param opts - Options object to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validate that an options bag is a plain object.\n * ```ts\n * validateOpts({});\n * ```\n */\nexport function validateOpts(opts: object): void {\n // Arrays silently passed here before, but these call sites expect named option-bag fields.\n if (Object.prototype.toString.call(opts) !== '[object Object]')\n throw new TypeError('expected valid options object');\n}\n\n/**\n * Validates common verification options.\n * `context` itself is validated with `abytes(...)`, and individual algorithms may narrow support\n * further after this shared plain-object gate.\n * @param opts - Verification options. See {@link VerOpts}.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validate common verification options.\n * ```ts\n * validateVerOpts({ context: new Uint8Array([1]) });\n * ```\n */\nexport function validateVerOpts(opts: TArg<VerOpts>): void {\n validateOpts(opts);\n if (opts.context !== undefined) abytes(opts.context, undefined, 'opts.context');\n}\n\n/**\n * Validates common signing options.\n * `extraEntropy` is validated with `abytes(...)`; exact lengths and extra algorithm-specific\n * restrictions are enforced later by callers.\n * @param opts - Signing options. See {@link SigOpts}.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validate common signing options.\n * ```ts\n * validateSigOpts({ extraEntropy: new Uint8Array([1]) });\n * ```\n */\nexport function validateSigOpts(opts: TArg<SigOpts>): void {\n validateVerOpts(opts);\n if (opts.extraEntropy !== false && opts.extraEntropy !== undefined)\n abytes(opts.extraEntropy, undefined, 'opts.extraEntropy');\n}\n\n/** Generic signature interface with key generation, signing, and verification. */\nexport type Signer = CryptoKeys & {\n /** Public byte lengths for signatures and signing randomness. */\n lengths: { signRand?: number; signature?: number };\n /**\n * Sign one message.\n * @param msg - Message bytes to sign.\n * @param secretKey - Secret key bytes.\n * @param opts - Optional signing options.\n * @returns Signature bytes.\n */\n sign: (\n msg: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts?: TArg<SigOpts>\n ) => TRet<Uint8Array>;\n /**\n * Verify one signature.\n * @param sig - Signature bytes.\n * @param msg - Signed message bytes.\n * @param publicKey - Public key bytes.\n * @param opts - Optional verification options.\n * @returns `true` when the signature is valid, `false` when all inputs are well-formed but the\n * signature check does not pass. Some implementations also treat malformed signature encodings as\n * a verification failure and return `false`.\n * @throws On malformed API arguments or unsupported verification options.\n */\n verify: (\n sig: TArg<Uint8Array>,\n msg: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>,\n opts?: TArg<VerOpts>\n ) => boolean;\n};\n\n/** Generic key encapsulation mechanism interface. */\nexport type KEM = CryptoKeys & {\n /** Public byte lengths for ciphertexts and optional message randomness. */\n lengths: { cipherText?: number; msg?: number; msgRand?: number };\n /**\n * Encapsulate one shared secret to a recipient public key.\n * @param publicKey - Recipient public key bytes.\n * @param msg - Optional caller-provided randomness/message seed.\n * @returns Ciphertext plus shared secret.\n */\n encapsulate: (\n publicKey: TArg<Uint8Array>,\n msg?: TArg<Uint8Array>\n ) => {\n cipherText: TRet<Uint8Array>;\n sharedSecret: TRet<Uint8Array>;\n };\n /**\n * Recover the shared secret from a ciphertext and recipient secret key.\n * @param cipherText - Ciphertext bytes.\n * @param secretKey - Recipient secret key bytes.\n * @returns Decapsulated shared secret.\n */\n decapsulate: (cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>) => TRet<Uint8Array>;\n};\n\n/** Bidirectional encoder/decoder interface. */\nexport interface Coder<F, T> {\n /**\n * Serialize one value.\n * @param from - Value to encode.\n * @returns Encoded representation.\n */\n encode(from: F): T;\n /**\n * Parse one serialized value.\n * @param to - Encoded representation.\n * @returns Decoded value.\n */\n decode(to: T): F;\n}\n\n/** Encoder/decoder interface specialized for byte arrays. */\nexport interface BytesCoder<T> extends Coder<T, Uint8Array> {\n /**\n * Serialize one value into bytes.\n * @param data - Value to encode.\n * @returns Encoded bytes.\n */\n encode: (data: T) => Uint8Array;\n /**\n * Parse one byte array into a value.\n * @param bytes - Encoded bytes.\n * @returns Decoded value.\n */\n decode: (bytes: Uint8Array) => T;\n}\n\n/** Fixed-length byte encoder/decoder. */\nexport type BytesCoderLen<T> = BytesCoder<T> & { bytesLen: number };\n\n// nano-packed, because struct encoding is hard.\ntype UnCoder<T> = T extends BytesCoder<infer U> ? U : never;\ntype SplitOut<T extends (number | BytesCoderLen<any>)[]> = {\n [K in keyof T]: T[K] extends number ? Uint8Array : UnCoder<T[K]>;\n};\n/**\n * Builds a fixed-layout coder from byte lengths and nested coders.\n * Raw-length fields decode as zero-copy `subarray(...)` views, and nested coders may preserve that\n * aliasing too. Nested coder `encode(...)` results are treated as owned scratch: `splitCoder`\n * copies them into the output and then zeroizes them with `fill(0)`. If a nested encoder forwards\n * caller-owned bytes, it must do so only after detaching them into a disposable copy.\n * @param label - Label used in validation errors.\n * @param lengths - Field lengths or nested coders.\n * @returns Composite fixed-length coder.\n * @example\n * Build a fixed-layout coder from byte lengths and nested coders.\n * ```ts\n * splitCoder('demo', 1, 2).encode([new Uint8Array([1]), new Uint8Array([2, 3])]);\n * ```\n */\nexport function splitCoder<T extends (number | BytesCoderLen<any>)[]>(\n label: string,\n ...lengths: T\n): TRet<BytesCoder<SplitOut<T>> & { bytesLen: number }> {\n const getLength = (c: TArg<number | BytesCoderLen<any>>) =>\n typeof c === 'number' ? c : (c as BytesCoderLen<any>).bytesLen;\n const bytesLen: number = lengths.reduce((sum: number, a) => sum + getLength(a), 0);\n return {\n bytesLen,\n encode: (bufs: T) => {\n const res = new Uint8Array(bytesLen);\n for (let i = 0, pos = 0; i < lengths.length; i++) {\n const c = lengths[i];\n const l = getLength(c);\n const b: Uint8Array = typeof c === 'number' ? (bufs[i] as any) : c.encode(bufs[i]);\n abytes_(b, l, label);\n res.set(b, pos);\n if (typeof c !== 'number') b.fill(0); // clean\n pos += l;\n }\n return res;\n },\n decode: (buf: TArg<Uint8Array>) => {\n abytes_(buf, bytesLen, label);\n const res = [];\n for (const c of lengths) {\n const l = getLength(c);\n const b = buf.subarray(0, l);\n res.push(typeof c === 'number' ? b : c.decode(b));\n buf = buf.subarray(l);\n }\n return res as SplitOut<T>;\n },\n } as any;\n}\n// nano-packed.array (fixed size)\n/**\n * Builds a fixed-length vector coder from another fixed-length coder.\n * Element decoding receives `subarray(...)` views, so aliasing depends on the element coder.\n * Element coder `encode(...)` results are treated as owned scratch: `vecCoder` copies them into\n * the output and then zeroizes them with `fill(0)`. If an element encoder forwards caller-owned\n * bytes, it must do so only after detaching them into a disposable copy. `vecCoder` also trusts\n * the `BytesCoderLen` contract: each encoded element must already be exactly `c.bytesLen` bytes.\n * @param c - Element coder.\n * @param vecLen - Number of elements in the vector.\n * @returns Fixed-length vector coder.\n * @example\n * Build a fixed-length vector coder from another fixed-length coder.\n * ```ts\n * vecCoder(\n * { bytesLen: 1, encode: (n: number) => Uint8Array.of(n), decode: (b: Uint8Array) => b[0] || 0 },\n * 2\n * ).encode([1, 2]);\n * ```\n */\nexport function vecCoder<T>(c: TArg<BytesCoderLen<T>>, vecLen: number): TRet<BytesCoderLen<T[]>> {\n const coder = c as BytesCoderLen<T>;\n const bytesLen = vecLen * coder.bytesLen;\n return {\n bytesLen,\n encode: (u: TArg<T[]>): TRet<Uint8Array> => {\n if (u.length !== vecLen)\n throw new RangeError(`vecCoder.encode: wrong length=${u.length}. Expected: ${vecLen}`);\n const res = new Uint8Array(bytesLen);\n for (let i = 0, pos = 0; i < u.length; i++) {\n const b = coder.encode(u[i] as T);\n res.set(b, pos);\n b.fill(0); // clean\n pos += b.length;\n }\n return res as TRet<Uint8Array>;\n },\n decode: (a: TArg<Uint8Array>): TRet<T[]> => {\n abytes_(a, bytesLen);\n const r: T[] = [];\n for (let i = 0; i < a.length; i += coder.bytesLen)\n r.push(coder.decode(a.subarray(i, i + coder.bytesLen)));\n return r as TRet<T[]>;\n },\n } as any;\n}\n\n/**\n * Overwrites supported typed-array inputs with zeroes in place.\n * Accepts direct typed arrays and one-level arrays of them.\n * @param list - Typed arrays or one-level lists of typed arrays to clear.\n * @example\n * Overwrite typed arrays with zeroes.\n * ```ts\n * const buf = Uint8Array.of(1, 2, 3);\n * cleanBytes(buf);\n * ```\n */\nexport function cleanBytes(...list: (TypedArray | TypedArray[])[]): void {\n for (const t of list) {\n if (Array.isArray(t)) for (const b of t) b.fill(0);\n else t.fill(0);\n }\n}\n\n/**\n * Creates a 32-bit mask with the lowest `bits` bits set.\n * @param bits - Number of low bits to keep.\n * @returns Bit mask with `bits` ones.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Create a low-bit mask for packed-field operations.\n * ```ts\n * const mask = getMask(4);\n * ```\n */\nexport function getMask(bits: number): number {\n if (!Number.isSafeInteger(bits) || bits < 0 || bits > 32)\n throw new RangeError(`expected bits in [0..32], got ${bits}`);\n // JS shifts are modulo 32, so bit 32 needs an explicit full-width mask.\n return bits === 32 ? 0xffffffff : ~(-1 << bits) >>> 0;\n}\n\n/** Shared empty byte array used as the default context. */\nexport const EMPTY: TRet<Uint8Array> = /* @__PURE__ */ Uint8Array.of();\n\n/**\n * Builds the domain-separated message payload for the pure sign/verify paths.\n * Context length `255` is valid; only `ctx.length > 255` is rejected.\n * @param msg - Message bytes.\n * @param ctx - Optional context bytes.\n * @returns Domain-separated message payload.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Build the domain-separated payload before direct signing.\n * ```ts\n * const payload = getMessage(new Uint8Array([1, 2]));\n * ```\n */\nexport function getMessage(msg: TArg<Uint8Array>, ctx: TArg<Uint8Array> = EMPTY): TRet<Uint8Array> {\n abytes_(msg);\n abytes_(ctx);\n if (ctx.length > 255) throw new RangeError('context should be 255 bytes or less');\n return concatBytes(new Uint8Array([0, ctx.length]), ctx, msg);\n}\n\n// DER tag+length plus the shared NIST hash OID arc 2.16.840.1.101.3.4.2.* used by the\n// FIPS 204 / FIPS 205 pre-hash wrappers; the final byte selects SHA-256, SHA-512, SHAKE128,\n// SHAKE256, or another approved hash/XOF under that subtree.\n// 06 09 60 86 48 01 65 03 04 02\nconst oidNistP = /* @__PURE__ */ Uint8Array.from([6, 9, 0x60, 0x86, 0x48, 1, 0x65, 3, 4, 2]);\n\n/**\n * Validates that a hash exposes a NIST hash OID and enough collision resistance.\n * Current accepted surface is broader than the FIPS algorithm tables: any hash/XOF under the NIST\n * `2.16.840.1.101.3.4.2.*` subtree is accepted if its effective `outputLen` is strong enough.\n * XOF callers must pass a callable whose `outputLen` matches the digest length they actually intend\n * to sign; bare `shake128` / `shake256` defaults are too short for the stronger prehash modes.\n * @param hash - Hash function to validate.\n * @param requiredStrength - Minimum required collision-resistance strength in bits.\n * @throws If the hash metadata or collision resistance is insufficient. {@link Error}\n * @example\n * Validate that a hash exposes a NIST hash OID and enough collision resistance.\n * ```ts\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { checkHash } from '@noble/post-quantum/utils.js';\n * checkHash(sha256, 128);\n * ```\n */\nexport function checkHash(hash: CHash, requiredStrength: number = 0): void {\n if (!hash.oid || !equalBytes(hash.oid.subarray(0, 10), oidNistP))\n throw new Error('hash.oid is invalid: expected NIST hash');\n // FIPS 204 / FIPS 205 require both collision and second-preimage strength; for approved NIST\n // hashes/XOFs under this OID subtree, the collision bound from the configured digest length is\n // the tighter runtime check, so enforce that lower bound here.\n const collisionResistance = (hash.outputLen * 8) / 2;\n if (requiredStrength > collisionResistance) {\n throw new Error(\n 'Pre-hash security strength too low: ' +\n collisionResistance +\n ', required: ' +\n requiredStrength\n );\n }\n}\n\n/**\n * Builds the domain-separated prehash payload for the prehash sign/verify paths.\n * Callers are expected to vet `hash.oid` first, e.g. via `checkHash(...)`; calling this helper\n * directly with a hash object that lacks `oid` currently throws later inside `concatBytes(...)`.\n * Context length `255` is valid; only `ctx.length > 255` is rejected.\n * @param hash - Prehash function.\n * @param msg - Message bytes.\n * @param ctx - Optional context bytes.\n * @returns Domain-separated prehash payload.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Build the domain-separated prehash payload for external hashing.\n * ```ts\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { getMessagePrehash } from '@noble/post-quantum/utils.js';\n * getMessagePrehash(sha256, new Uint8Array([1, 2]));\n * ```\n */\nexport function getMessagePrehash(\n hash: CHash,\n msg: TArg<Uint8Array>,\n ctx: TArg<Uint8Array> = EMPTY\n): TRet<Uint8Array> {\n abytes_(msg);\n abytes_(ctx);\n if (ctx.length > 255) throw new RangeError('context should be 255 bytes or less');\n const hashed = hash(msg);\n return concatBytes(new Uint8Array([1, ctx.length]), ctx, hash.oid!, hashed);\n}\n","/**\n * Internal methods for lattice-based ML-KEM and ML-DSA.\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { FFTCore, reverseBits } from '@noble/curves/abstract/fft.js';\nimport { shake128, shake256 } from '@noble/hashes/sha3.js';\nimport type { TypedArray } from '@noble/hashes/utils.js';\nimport {\n type BytesCoderLen,\n cleanBytes,\n type Coder,\n getMask,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/** Extendable-output reader used by the CRYSTALS implementations. */\nexport type XOF = (\n seed: Uint8Array,\n blockLen?: number\n) => {\n /**\n * Read diagnostic counters for the current XOF session.\n * @returns Current call and XOF block counters.\n */\n stats: () => { calls: number; xofs: number };\n /**\n * Select one `(x, y)` coordinate pair and get a block reader for it.\n * Only one coordinate stream is live at a time: a later `get(...)` call rebinds the shared\n * SHAKE state and invalidates older readers.\n * Each squeeze aliases one mutable internal output buffer, so callers must copy blocks they\n * want to retain before the next read.\n * @param x - First matrix coordinate.\n * @param y - Second matrix coordinate.\n * @returns Lazy block reader for that coordinate pair.\n */\n get: (x: number, y: number) => () => Uint8Array; // return block aligned to blockLen and 3\n /** Wipe any buffered state once the reader is no longer needed. */\n clean: () => void;\n};\n\n/** CRYSTALS (ml-kem, ml-dsa) options */\n/** Shared polynomial and NTT parameters for CRYSTALS algorithms. */\nexport type CrystalOpts<T extends TypedArray> = {\n /**\n * Allocate one zeroed polynomial/vector container.\n * @param n - Number of coefficients to allocate.\n * @returns Fresh typed container.\n */\n newPoly: TypedCons<T>;\n /** Polynomial size, typically `256`. */\n N: number;\n /** Prime modulus used for all coefficient arithmetic. */\n Q: number;\n /** Inverse transform normalization factor:\n * `256**-1 mod q` for Dilithium, `128**-1 mod q` for Kyber.\n */\n F: number;\n /** Principal root of unity for the transform domain. */\n ROOT_OF_UNITY: number;\n /** Number of bits used for bit-reversal ordering. */\n brvBits: number;\n /** `true` for Kyber/ML-KEM mode, `false` for Dilithium/ML-DSA mode. */\n isKyber: boolean;\n};\n\n/** Constructor function for typed polynomial containers. */\nexport type TypedCons<T extends TypedArray> = (n: number) => T;\n\ntype Crystals<T extends TypedArray> = {\n mod: (a: number, modulo?: number) => number;\n smod: (a: number, modulo?: number) => number;\n nttZetas: T;\n NTT: {\n /** Forward transform in place. Mutates and returns `r`. */\n encode: (r: T) => T;\n /** Inverse transform in place. Mutates and returns `r`. */\n decode: (r: T) => T;\n };\n bitsCoder: (d: number, c: Coder<number, number>) => BytesCoderLen<T>;\n};\n\n/**\n * Creates shared modular arithmetic, NTT, and packing helpers for CRYSTALS schemes.\n * @param opts - Polynomial and transform parameters. See {@link CrystalOpts}.\n * @returns CRYSTALS arithmetic and encoding helpers.\n * @example\n * Create shared modular arithmetic and NTT helpers for a CRYSTALS parameter set.\n * ```ts\n * const crystals = genCrystals({\n * newPoly: (n) => new Uint16Array(n),\n * N: 256,\n * Q: 3329,\n * F: 3303,\n * ROOT_OF_UNITY: 17,\n * brvBits: 7,\n * isKyber: true,\n * });\n * const reduced = crystals.mod(-1);\n * ```\n */\nexport const genCrystals = <T extends TypedArray>(opts: CrystalOpts<T>): TRet<Crystals<T>> => {\n // isKyber: true means Kyber, false means Dilithium\n const { newPoly, N, Q, F, ROOT_OF_UNITY, brvBits, isKyber } = opts;\n // Normalize JS `%` into the canonical Z_m representative `[0, modulo-1]` expected by\n // FIPS 203 §2.3 / FIPS 204 §2.3 before downstream mod-q arithmetic.\n const mod = (a: number, modulo = Q): number => {\n const result = a % modulo | 0;\n return (result >= 0 ? result | 0 : (modulo + result) | 0) | 0;\n };\n // FIPS 204 §7.4 uses the centered `mod ±` representative for low bits, keeping the\n // positive midpoint when `modulo` is even.\n // Center to `[-floor((modulo-1)/2), floor(modulo/2)]`.\n const smod = (a: number, modulo = Q): number => {\n const r = mod(a, modulo) | 0;\n return (r > modulo >> 1 ? (r - modulo) | 0 : r) | 0;\n };\n // Kyber uses the FIPS 203 Appendix A `BitRev_7` table here via the first 128 entries, while\n // Dilithium uses the FIPS 204 §7.5 / Appendix B `BitRev_8` zetas table over all 256 entries.\n function getZettas() {\n const out = newPoly(N);\n for (let i = 0; i < N; i++) {\n const b = reverseBits(i, brvBits);\n const p = BigInt(ROOT_OF_UNITY) ** BigInt(b) % BigInt(Q);\n out[i] = Number(p) | 0;\n }\n return out;\n }\n const nttZetas = getZettas();\n\n // Number-Theoretic Transform\n // Explained: https://electricdusk.com/ntt.html\n\n // Kyber has slightly different params, since there is no 512th primitive root of unity mod q,\n // only 256th primitive root of unity mod. Which also complicates MultiplyNTT.\n\n const field = {\n add: (a: number, b: number) => mod((a | 0) + (b | 0)) | 0,\n sub: (a: number, b: number) => mod((a | 0) - (b | 0)) | 0,\n mul: (a: number, b: number) => mod((a | 0) * (b | 0)) | 0,\n inv: (_a: number) => {\n throw new Error('not implemented');\n },\n };\n const nttOpts = {\n N,\n roots: nttZetas as any,\n invertButterflies: true,\n skipStages: isKyber ? 1 : 0,\n brp: false,\n };\n const dif = FFTCore(field, { dit: false, ...nttOpts });\n const dit = FFTCore(field, { dit: true, ...nttOpts });\n const NTT = {\n encode: (r: T): T => {\n return dif(r) as any;\n },\n decode: (r: T): T => {\n dit(r as any);\n // The inverse-NTT normalization factor is family-specific: FIPS 203 Algorithm 10 line 14\n // uses `128^-1 mod q` for Kyber, while FIPS 204 Algorithm 42 lines 21-23 use `256^-1 mod q`.\n // kyber uses 128 here, because brv && stuff\n for (let i = 0; i < r.length; i++) r[i] = mod(F * r[i]);\n return r;\n },\n };\n // Pack one little-endian `d`-bit word per coefficient, matching FIPS 203 ByteEncode /\n // ByteDecode and the FIPS 204 BitsToBytes-based polynomial packing helpers.\n const bitsCoder = (d: number, c: Coder<number, number>): TRet<BytesCoderLen<T>> => {\n const mask = getMask(d);\n const bytesLen = d * (N / 8);\n return {\n bytesLen,\n encode: (poly_: TArg<T>): TRet<Uint8Array> => {\n const poly = poly_ as T;\n const r = new Uint8Array(bytesLen);\n for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < poly.length; i++) {\n buf |= (c.encode(poly[i]) & mask) << bufLen;\n bufLen += d;\n for (; bufLen >= 8; bufLen -= 8, buf >>= 8) r[pos++] = buf & getMask(bufLen);\n }\n return r as TRet<Uint8Array>;\n },\n decode: (bytes: TArg<Uint8Array>): TRet<T> => {\n const r = newPoly(N);\n for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < bytes.length; i++) {\n buf |= bytes[i] << bufLen;\n bufLen += 8;\n for (; bufLen >= d; bufLen -= d, buf >>= d) r[pos++] = c.decode(buf & mask);\n }\n return r as TRet<T>;\n },\n } as TRet<BytesCoderLen<T>>;\n };\n\n return {\n mod,\n smod,\n nttZetas: nttZetas as TRet<T>,\n NTT: {\n encode: (r: TArg<T>): TRet<T> => NTT.encode(r as T) as TRet<T>,\n decode: (r: TArg<T>): TRet<T> => NTT.decode(r as T) as TRet<T>,\n },\n bitsCoder: bitsCoder as TRet<Crystals<T>>['bitsCoder'],\n };\n};\n\nconst createXofShake =\n (shake: typeof shake128): TRet<XOF> =>\n (seed: TArg<Uint8Array>, blockLen?: number) => {\n if (!blockLen) blockLen = shake.blockLen;\n // Optimizations that won't mater:\n // - cached seed update (two .update(), on start and on the end)\n // - another cache which cloned into working copy\n\n // Faster than multiple updates, since seed less than blockLen\n const _seed = new Uint8Array(seed.length + 2);\n _seed.set(seed);\n const seedLen = seed.length;\n const buf = new Uint8Array(blockLen); // == shake128.blockLen\n let h = shake.create({});\n let calls = 0;\n let xofs = 0;\n return {\n stats: () => ({ calls, xofs }),\n get: (x: number, y: number) => {\n // Rebind to `seed || x || y` so callers can implement the spec's per-coordinate\n // SHAKE inputs like `rho || j || i` and `rho || IntegerToBytes(counter, 2)`.\n _seed[seedLen + 0] = x;\n _seed[seedLen + 1] = y;\n h.destroy();\n h = shake.create({}).update(_seed);\n calls++;\n return () => {\n xofs++;\n return h.xofInto(buf) as TRet<Uint8Array>;\n };\n },\n clean: () => {\n h.destroy();\n cleanBytes(buf, _seed);\n },\n };\n };\n\n/**\n * SHAKE128-based extendable-output reader factory used by ML-KEM.\n * `get(x, y)` selects one coordinate pair at a time; calling it again invalidates previously\n * returned readers, and each squeeze reuses one mutable internal output buffer.\n * @param seed - Seed bytes for the reader.\n * @param blockLen - Optional output block length.\n * @returns Stateful XOF reader.\n * @example\n * Build the ML-KEM SHAKE128 matrix expander and read one block.\n * ```ts\n * import { randomBytes } from '@noble/post-quantum/utils.js';\n * import { XOF128 } from '@noble/post-quantum/_crystals.js';\n * const reader = XOF128(randomBytes(32));\n * const block = reader.get(0, 0)();\n * ```\n */\nexport const XOF128: TRet<XOF> = /* @__PURE__ */ createXofShake(shake128);\n/**\n * SHAKE256-based extendable-output reader factory used by ML-DSA.\n * `get(x, y)` appends raw one-byte coordinates to the seed, invalidates previously returned\n * readers, and reuses one mutable internal output buffer for each squeeze.\n * @param seed - Seed bytes for the reader.\n * @param blockLen - Optional output block length.\n * @returns Stateful XOF reader.\n * @example\n * Build the ML-DSA SHAKE256 coefficient expander and read one block.\n * ```ts\n * import { randomBytes } from '@noble/post-quantum/utils.js';\n * import { XOF256 } from '@noble/post-quantum/_crystals.js';\n * const reader = XOF256(randomBytes(32));\n * const block = reader.get(0, 0)();\n * ```\n */\nexport const XOF256: TRet<XOF> = /* @__PURE__ */ createXofShake(shake256);\n","/**\n * ML-KEM: Module Lattice-based Key Encapsulation Mechanism from\n * [FIPS-203](https://csrc.nist.gov/pubs/fips/203/ipd). A.k.a. CRYSTALS-Kyber.\n *\n * Key encapsulation is similar to DH / ECDH (think X25519), with important differences:\n * * Unlike in ECDH, we can't verify if it was \"Bob\" who've sent the shared secret\n * * Unlike ECDH, it is probabalistic and relies on quality of randomness (CSPRNG).\n * * Decapsulation never throws an error, even when shared secret was\n * encrypted by a different public key. It will just return a different shared secret.\n *\n * There are some concerns with regards to security: see\n * [djb blog](https://blog.cr.yp.to/20231003-countcorrectly.html) and\n * [mailing list](https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/W2VOzy0wz_E).\n *\n * Has similar internals to ML-DSA, but their keys and params are different.\n *\n * Check out [official site](https://www.pq-crystals.org/kyber/resources.shtml),\n * [repo](https://github.com/pq-crystals/kyber),\n * [spec](https://datatracker.ietf.org/doc/draft-cfrg-schwabe-kyber/).\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { sha3_256, sha3_512, shake256 } from '@noble/hashes/sha3.js';\nimport { type CHash, swap32IfBE, u32 } from '@noble/hashes/utils.js';\nimport { genCrystals, type XOF, XOF128 } from './_crystals.ts';\nimport {\n abytes,\n cleanBytes,\n type Coder,\n copyBytes,\n equalBytes,\n getMask,\n type KEM,\n randomBytes,\n splitCoder,\n type TArg,\n type TRet,\n vecCoder,\n} from './utils.ts';\n\n/** Key encapsulation mechanism interface */\n\nconst N = 256; // Kyber (not FIPS-203) supports different lengths, but all std modes were using 256\nconst Q = 3329; // 13*(2**8)+1, modulo prime\nconst F = 3303; // 3303 ≡ 128**(−1) mod q (FIPS-203)\nconst ROOT_OF_UNITY = 17; // ζ = 17 ∈ Zq is a primitive 256-th root of unity modulo Q. ζ**128 ≡−1\n// treeshake: keep genCrystals behind the object so PARAMS-only bundles can drop it entirely.\n// Shared CRYSTALS helper in the ML-KEM branch: Kyber mode, 7-bit bit-reversal,\n// and Uint16Array polys because current coefficients stay reduced modulo q.\nconst crystals = /* @__PURE__ */ genCrystals({\n N,\n Q,\n F,\n ROOT_OF_UNITY,\n newPoly: (n: number): TRet<Uint16Array> => new Uint16Array(n) as TRet<Uint16Array>,\n brvBits: 7,\n isKyber: true,\n});\n\n/** FIPS 203: 7. Parameter Sets */\n/** Public ML-KEM parameter-set description. */\nexport type KEMParam = {\n /** Polynomial size. */\n N: number;\n /** Module rank. */\n K: number;\n /** Prime modulus. */\n Q: number;\n /** CBD parameter used for secret-key noise. */\n ETA1: number;\n /** CBD parameter used for error noise. */\n ETA2: number;\n /** Compression width for the `u` vector. */\n du: number;\n /** Compression width for the `v` polynomial. */\n dv: number;\n /** Required strength of the randomness source in bits. */\n RBGstrength: number;\n};\n/** Internal params of ML-KEM versions */\n// prettier-ignore\n/** Built-in ML-KEM parameter presets keyed by the public export names\n * `ml_kem512` / `ml_kem768` / `ml_kem1024`.\n * `RBGstrength` is Table 2's required randomness-source strength in bits,\n * not a generic security label.\n */\nexport const PARAMS: Record<string, KEMParam> = /* @__PURE__ */ (() =>\n Object.freeze({\n 512: Object.freeze({ N, Q, K: 2, ETA1: 3, ETA2: 2, du: 10, dv: 4, RBGstrength: 128 }),\n 768: Object.freeze({ N, Q, K: 3, ETA1: 2, ETA2: 2, du: 10, dv: 4, RBGstrength: 192 }),\n 1024: Object.freeze({ N, Q, K: 4, ETA1: 2, ETA2: 2, du: 11, dv: 5, RBGstrength: 256 }),\n } as const))();\n\n// FIPS-203: compress/decompress\nconst compress = (d: number): Coder<number, number> => {\n // d=12 is the ByteEncode12/ByteDecode12 path, not lossy compression.\n // ByteDecode12 interprets each 12-bit word modulo q; without that reduction the public-key\n // modulus check in encapsulate() becomes a no-op for malformed coefficients like 4095.\n if (d >= 12) return { encode: (i: number) => i, decode: (i: number) => (i >= Q ? i - Q : i) };\n // Comments map to python implementation in RFC (draft-cfrg-schwabe-kyber)\n // const round = (i: number) => Math.floor(i + 0.5) | 0;\n const a = 2 ** (d - 1);\n return {\n // This only matches standalone Compress_d after bitsCoder masks the result into Z_(2^d).\n encode: (i: number) => ((i << d) + Q / 2) / Q,\n // const decompress = (i: number) => round((Q / 2 ** d) * i);\n decode: (i: number) => (i * Q + a) >>> d,\n };\n};\n\n// Raw ByteEncode_d / ByteDecode_d from FIPS 203 operate on d-bit words directly.\n// That differs from `polyCoder(d)` for d<12, where noble folds packing together with the lossy\n// ciphertext compression step used by u/v. Tests that exercise the spec's raw packing surface need\n// this exact non-lossy variant instead.\nconst byteCoder = (d: number) =>\n crystals.bitsCoder(\n d,\n d === 12\n ? { encode: (i: number) => i, decode: (i: number) => (i >= Q ? i - Q : i) }\n : { encode: (i: number) => i, decode: (i: number) => i }\n );\n\n// NOTE: we merge encoding and compress because it is faster, also both require same d param\n// d=12 is the ByteEncode12/ByteDecode12 path rather than compression, and caller-side\n// public-key modulus checks route through this helper's decode/encode roundtrip.\n// Converts between bytes and d-bits compressed representation.\n// Kinda like convertRadix2 from @scure/base.\n// decode(encode(t)) == t, but there is loss of information on encode(decode(t))\nconst polyCoder = (d: number) => (d === 12 ? byteCoder(12) : crystals.bitsCoder(d, compress(d)));\n\n// Poly is mod Q, so 12 bits\ntype Poly = Uint16Array;\n\nfunction polyAdd(a_: TArg<Poly>, b_: TArg<Poly>) {\n const a = a_ as Poly;\n const b = b_ as Poly;\n // Mutates `a` in place; callers must pass two N=256 polynomials.\n for (let i = 0; i < N; i++) a[i] = crystals.mod(a[i] + b[i]); // a += b\n}\nfunction polySub(a_: TArg<Poly>, b_: TArg<Poly>) {\n const a = a_ as Poly;\n const b = b_ as Poly;\n // Mutates `a` in place; callers must pass two N=256 polynomials.\n for (let i = 0; i < N; i++) a[i] = crystals.mod(a[i] - b[i]); // a -= b\n}\n\n// FIPS-203: Computes the product of two degree-one polynomials with respect to a quadratic modulus\nfunction BaseCaseMultiply(a0: number, a1: number, b0: number, b1: number, zeta: number) {\n // `zeta` here is Algorithm 11's γ = ζ^(2BitRev_7(i)+1).\n const c0 = crystals.mod(a1 * b1 * zeta + a0 * b0);\n const c1 = crystals.mod(a0 * b1 + a1 * b0);\n return { c0, c1 };\n}\n\n// FIPS-203: Computes the product (in the ring Tq) of two NTT representations.\n// Works in place on `f`; `g` is read-only and both inputs must already be in NTT form.\nfunction MultiplyNTTs(f_: TArg<Poly>, g_: TArg<Poly>): TRet<Poly> {\n const f = f_ as Poly;\n const g = g_ as Poly;\n for (let i = 0; i < N / 2; i++) {\n let z = crystals.nttZetas[64 + (i >> 1)];\n if (i & 1) z = -z;\n const { c0, c1 } = BaseCaseMultiply(f[2 * i + 0], f[2 * i + 1], g[2 * i + 0], g[2 * i + 1], z);\n f[2 * i + 0] = c0;\n f[2 * i + 1] = c1;\n }\n return f as TRet<Poly>;\n}\n\ntype PRF = (l: number, key: Uint8Array, nonce: number) => Uint8Array;\n\ntype XofGet = ReturnType<ReturnType<XOF>['get']>;\n\ntype KyberOpts = KEMParam & {\n HASH256: CHash;\n HASH512: CHash;\n KDF: CHash<any, { dkLen?: number }>;\n XOF: XOF; // (seed: Uint8Array, len: number, x: number, y: number) => Uint8Array;\n PRF: PRF;\n};\n\n// Return poly in NTT representation\nfunction SampleNTT(xof_: TArg<XofGet>): TRet<Poly> {\n const xof = xof_ as XofGet;\n // The reader must already bind the Algorithm 7 seed||j||i bytes\n // and return block lengths divisible by 3.\n const r: Poly = new Uint16Array(N);\n for (let j = 0; j < N; ) {\n const b = xof();\n if (b.length % 3) throw new Error('SampleNTT: unaligned block');\n for (let i = 0; j < N && i + 3 <= b.length; i += 3) {\n const d1 = ((b[i + 0] >> 0) | (b[i + 1] << 8)) & 0xfff;\n const d2 = ((b[i + 1] >> 4) | (b[i + 2] << 4)) & 0xfff;\n if (d1 < Q) r[j++] = d1;\n if (j < N && d2 < Q) r[j++] = d2;\n }\n }\n return r as TRet<Poly>;\n}\n\n// Sampling from the centered binomial distribution\n// Returns poly with small coefficients (noise/errors) stored modulo q in ordinary coefficient form.\n// Current callers only use Table 2 eta values {2,3} and PRF outputs of exactly 64*eta bytes.\nconst sampleCBDBytes = (buf: TArg<Uint8Array>, eta: number): TRet<Poly> => {\n const r: Poly = new Uint16Array(N);\n // CBD consumes the PRF bitstream in little-endian byte order; normalize the word view on BE,\n // then swap it back so callers still observe `buf` as read-only.\n const b32 = u32(buf);\n swap32IfBE(b32);\n let len = 0;\n for (let i = 0, p = 0, bb = 0, t0 = 0; i < b32.length; i++) {\n let b = b32[i];\n for (let j = 0; j < 32; j++) {\n bb += b & 1;\n b >>= 1;\n len += 1;\n if (len === eta) {\n t0 = bb;\n bb = 0;\n } else if (len === 2 * eta) {\n r[p++] = crystals.mod(t0 - bb);\n bb = 0;\n len = 0;\n }\n }\n }\n swap32IfBE(b32);\n if (len) throw new Error(`sampleCBD: leftover bits: ${len}`);\n return r as TRet<Poly>;\n};\n\nfunction sampleCBD(\n PRF_: TArg<PRF>,\n seed: TArg<Uint8Array>,\n nonce: number,\n eta: number\n): TRet<Poly> {\n const PRF = PRF_ as PRF;\n return sampleCBDBytes(PRF((eta * N) / 4, seed, nonce), eta);\n}\n\n// K-PKE\n// Internal ML-KEM subroutine only: exact 32-byte `seed` / `msg` inputs\n// come from Algorithms 13-15, and the helper mutates decoded temporary\n// polynomials in place while leaving caller byte arrays unchanged.\nconst genKPKE = (opts_: TArg<KyberOpts>) => {\n const opts = opts_ as KyberOpts;\n const { K, PRF, XOF, HASH512, ETA1, ETA2, du, dv } = opts;\n const poly1 = polyCoder(1);\n const polyV = polyCoder(dv);\n const polyU = polyCoder(du);\n const publicCoder = splitCoder('publicKey', vecCoder(polyCoder(12), K), 32);\n const secretCoder = vecCoder(polyCoder(12), K);\n const cipherCoder = splitCoder('ciphertext', vecCoder(polyU, K), polyV);\n const seedCoder = splitCoder('seed', 32, 32);\n return {\n secretCoder,\n lengths: {\n secretKey: secretCoder.bytesLen,\n publicKey: publicCoder.bytesLen,\n cipherText: cipherCoder.bytesLen,\n },\n keygen: (seed: TArg<Uint8Array>) => {\n abytes(seed, 32, 'seed');\n const seedDst = new Uint8Array(33);\n seedDst.set(seed);\n // FIPS 203 Algorithm 13 appends the parameter-set byte `k`\n // before `G(d || k)`, so expanding the same 32-byte seed\n // under a different ML-KEM parameter set yields unrelated keys.\n seedDst[32] = K;\n const seedHash = HASH512(seedDst);\n\n const [rho, sigma] = seedCoder.decode(seedHash);\n const sHat: Poly[] = [];\n const tHat: Poly[] = [];\n for (let i = 0; i < K; i++) sHat.push(crystals.NTT.encode(sampleCBD(PRF, sigma, i, ETA1)));\n const x = XOF(rho);\n for (let i = 0; i < K; i++) {\n const e = crystals.NTT.encode(sampleCBD(PRF, sigma, K + i, ETA1));\n for (let j = 0; j < K; j++) {\n const aji = SampleNTT(x.get(j, i)); // A[i][j], inplace\n polyAdd(e, MultiplyNTTs(aji, sHat[j]));\n }\n tHat.push(e); // t ← A ◦ s + e\n }\n x.clean();\n const res = {\n publicKey: publicCoder.encode([tHat, rho]),\n secretKey: secretCoder.encode(sHat),\n };\n cleanBytes(rho, sigma, sHat, tHat, seedDst, seedHash);\n return res;\n },\n encrypt: (\n publicKey: TArg<Uint8Array>,\n msg: TArg<Uint8Array>,\n seed: TArg<Uint8Array>\n ): TRet<Uint8Array> => {\n const [tHat, rho] = publicCoder.decode(publicKey);\n const rHat = [];\n for (let i = 0; i < K; i++) rHat.push(crystals.NTT.encode(sampleCBD(PRF, seed, i, ETA1)));\n const x = XOF(rho);\n const tmp2 = new Uint16Array(N);\n const u = [];\n for (let i = 0; i < K; i++) {\n const e1 = sampleCBD(PRF, seed, K + i, ETA2);\n const tmp = new Uint16Array(N);\n for (let j = 0; j < K; j++) {\n const aij = SampleNTT(x.get(i, j)); // A[j][i], inplace transpose access\n polyAdd(tmp, MultiplyNTTs(aij, rHat[j])); // t += aij * rHat[j]\n }\n polyAdd(e1, crystals.NTT.decode(tmp)); // e1 += tmp\n u.push(e1);\n polyAdd(tmp2, MultiplyNTTs(tHat[i], rHat[i])); // t2 += tHat[i] * rHat[i]\n cleanBytes(tmp);\n }\n x.clean();\n const e2 = sampleCBD(PRF, seed, 2 * K, ETA2);\n polyAdd(e2, crystals.NTT.decode(tmp2)); // e2 += tmp2\n const v = poly1.decode(msg); // encode plaintext m into polynomial v\n polyAdd(v, e2); // v += e2\n cleanBytes(tHat, rHat, tmp2, e2);\n return cipherCoder.encode([u, v]) as TRet<Uint8Array>;\n },\n decrypt: (cipherText: TArg<Uint8Array>, privateKey: TArg<Uint8Array>): TRet<Uint8Array> => {\n const [u, v] = cipherCoder.decode(cipherText);\n const sk = secretCoder.decode(privateKey); // s ← ByteDecode_12(dkPKE)\n const tmp = new Uint16Array(N);\n // tmp += sk[i] * u[i]\n for (let i = 0; i < K; i++) polyAdd(tmp, MultiplyNTTs(sk[i], crystals.NTT.encode(u[i])));\n polySub(v, crystals.NTT.decode(tmp)); // w = v' - tmp\n cleanBytes(tmp, sk, u);\n return poly1.encode(v) as TRet<Uint8Array>;\n },\n };\n};\n\n/**\n * Public ML-KEM wrapper over the internal K-PKE subroutine.\n * `keygen(seed)` and `encapsulate(publicKey, msg)` are deterministic/test-oriented hooks that map\n * more directly to Algorithms 16-17 than to the pure no-input / random-internal Algorithms 19-20.\n * decapsulate() tries to follow the Algorithms 18/21 implicit-reject structure as closely as\n * practical here by re-encrypting, comparing ciphertexts, returning `Khat` on match or `Kbar` on\n * mismatch, and zeroizing the non-returned shared-secret candidate; JS/JIT still provides no\n * constant-time guarantees for that path.\n */\nfunction createKyber(opts: TArg<KyberOpts>): TRet<KEM> {\n const rawOpts = opts as KyberOpts;\n const KPKE = genKPKE(rawOpts);\n const { HASH256, HASH512, KDF } = rawOpts;\n const { secretCoder: KPKESecretCoder, lengths } = KPKE;\n const secretCoder = splitCoder('secretKey', lengths.secretKey, lengths.publicKey, 32, 32);\n const msgLen = 32;\n const seedLen = 64;\n const kemLengths = Object.freeze({\n ...lengths,\n seed: 64,\n msg: msgLen,\n msgRand: msgLen,\n secretKey: secretCoder.bytesLen,\n });\n return Object.freeze({\n info: Object.freeze({ type: 'ml-kem' }),\n lengths: kemLengths,\n keygen: (seed: TArg<Uint8Array> = randomBytes(seedLen)) => {\n abytes(seed, seedLen, 'seed');\n const { publicKey, secretKey: sk } = KPKE.keygen(seed.subarray(0, 32));\n const publicKeyHash = HASH256(publicKey);\n // (dkPKE||ek||H(ek)||z)\n const secretKey = secretCoder.encode([sk, publicKey, publicKeyHash, seed.subarray(32)]);\n cleanBytes(sk, publicKeyHash);\n return {\n publicKey: publicKey as TRet<Uint8Array>,\n secretKey: secretKey as TRet<Uint8Array>,\n };\n },\n getPublicKey: (secretKey: TArg<Uint8Array>): TRet<Uint8Array> => {\n const [_sk, publicKey, _publicKeyHash, _z] = secretCoder.decode(secretKey);\n return Uint8Array.from(publicKey) as TRet<Uint8Array>;\n },\n encapsulate: (publicKey: TArg<Uint8Array>, msg: TArg<Uint8Array> = randomBytes(msgLen)) => {\n abytes(publicKey, lengths.publicKey, 'publicKey');\n abytes(msg, msgLen, 'message');\n\n // FIPS-203 includes additional verification check for modulus\n const eke = publicKey.subarray(0, 384 * opts.K);\n // Copy because of inplace encoding\n const ek = KPKESecretCoder.encode(KPKESecretCoder.decode(copyBytes(eke)));\n // (Modulus check.) Perform the computation ek ← ByteEncode12(ByteDecode12(eke)).\n // If ek = ̸ eke, the input is invalid. (See Section 4.2.1.)\n if (!equalBytes(ek, eke)) {\n cleanBytes(ek);\n throw new Error('ML-KEM.encapsulate: wrong publicKey modulus');\n }\n cleanBytes(ek);\n // derive randomness\n const kr = HASH512.create().update(msg).update(HASH256(publicKey)).digest();\n const cipherText = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64));\n cleanBytes(kr.subarray(32));\n return {\n cipherText: cipherText as TRet<Uint8Array>,\n sharedSecret: kr.subarray(0, 32) as TRet<Uint8Array>,\n };\n },\n decapsulate: (cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>): TRet<Uint8Array> => {\n abytes(secretKey, secretCoder.bytesLen, 'secretKey'); // 768*k + 96\n abytes(cipherText, lengths.cipherText, 'cipherText'); // 32(du*k + dv)\n // test ← H(dk[384𝑘 ∶ 768𝑘 + 32])) .\n const k768 = secretCoder.bytesLen - 96;\n const start = k768 + 32;\n const test = HASH256(secretKey.subarray(k768 / 2, start));\n // If test ≠ dk[768𝑘 + 32 ∶ 768𝑘 + 64], then input checking has failed.\n if (!equalBytes(test, secretKey.subarray(start, start + 32)))\n throw new Error('invalid secretKey: hash check failed');\n const [sk, publicKey, publicKeyHash, z] = secretCoder.decode(secretKey);\n const msg = KPKE.decrypt(cipherText, sk);\n // derive randomness, Khat, rHat = G(mHat || h)\n const kr = HASH512.create().update(msg).update(publicKeyHash).digest();\n const Khat = kr.subarray(0, 32);\n // re-encrypt using the derived randomness\n const cipherText2 = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64));\n // if ciphertexts do not match, “implicitly reject”\n const isValid = equalBytes(cipherText, cipherText2);\n const Kbar = KDF.create({ dkLen: 32 }).update(z).update(cipherText).digest();\n cleanBytes(msg, cipherText2, !isValid ? Khat : Kbar);\n return (isValid ? Khat : Kbar) as TRet<Uint8Array>;\n },\n });\n}\n\n// FIPS 203's PRF_eta binding: current callers use only 32-byte keys, one-byte nonces,\n// and dkLen values {128, 192}; out-of-range nonce numbers still wrap modulo 256 here.\nfunction shakePRF(dkLen: number, key: TArg<Uint8Array>, nonce: number): TRet<Uint8Array> {\n return shake256\n .create({ dkLen })\n .update(key)\n .update(new Uint8Array([nonce]))\n .digest() as TRet<Uint8Array>;\n}\n\n// Fixed ML-KEM hash/XOF bindings. `KDF` here is the spec's fixed 32-byte `J` call,\n// and swapping any field changes the scheme rather than tuning an internal dependency.\nconst opts = /* @__PURE__ */ (() => ({\n HASH256: sha3_256,\n HASH512: sha3_512,\n KDF: shake256,\n XOF: XOF128,\n PRF: shakePRF,\n}))();\n// Parameter-set instantiation step for the spec's \"ML-KEM-x\" names; current correctness relies\n// on the internal PARAMS rows rather than local validation of arbitrary KEMParam objects.\nconst mk = (params: KEMParam) =>\n createKyber({\n ...opts,\n ...params,\n });\n\n/**\n * ML-KEM-512: Table 2 row `k=2, η1=3, η2=2, du=10, dv=4`; Table 3 sizes `800/1632/768/32`.\n * The ASD lifecycle note here is external policy guidance, not a FIPS 203 requirement.\n */\nexport const ml_kem512: TRet<KEM> = /* @__PURE__ */ (() => mk(PARAMS[512]))();\n/**\n * ML-KEM-768: Table 2 row `k=3, η1=2, η2=2, du=10, dv=4`; Table 3 sizes `1184/2400/1088/32`.\n * The ASD lifecycle note here is external policy guidance, not a FIPS 203 requirement.\n */\nexport const ml_kem768: TRet<KEM> = /* @__PURE__ */ (() => mk(PARAMS[768]))();\n/**\n * ML-KEM-1024: Table 2 row `k=4, η1=2, η2=2, du=11, dv=5`; Table 3 sizes `1568/3168/1568/32`.\n * The ASD lifecycle note here is external policy guidance, not a FIPS 203 requirement.\n */\nexport const ml_kem1024: TRet<KEM> = /* @__PURE__ */ (() => mk(PARAMS[1024]))();\n\n// NOTE: for tests only, don't use. This keeps the exact internal ML-KEM math surfaces available\n// without re-implementing them in separate test code.\nexport const __tests: any = /* @__PURE__ */ (() =>\n Object.freeze({\n Compress_d: (x: number, d: number) => {\n if (d < 1 || d > 11) throw new Error(`Compress_d: expected d in [1..11], got ${d}`);\n return compress(d).encode(x) & getMask(d);\n },\n Decompress_d: (y: number, d: number) => {\n if (d < 1 || d > 11) throw new Error(`Decompress_d: expected d in [1..11], got ${d}`);\n return compress(d).decode(y);\n },\n ByteEncode_d: (F: TArg<Uint16Array>, d: number) => {\n if (d < 1 || d > 12) throw new Error(`ByteEncode_d: expected d in [1..12], got ${d}`);\n return byteCoder(d).encode(F as TRet<Uint16Array>);\n },\n ByteDecode_d: (B: TArg<Uint8Array>, d: number) => {\n if (d < 1 || d > 12) throw new Error(`ByteDecode_d: expected d in [1..12], got ${d}`);\n return byteCoder(d).decode(B);\n },\n NTT: (f: TArg<Uint16Array>) => crystals.NTT.encode(Uint16Array.from(f)),\n NTT_inv: (fHat: TArg<Uint16Array>) => crystals.NTT.decode(Uint16Array.from(fHat)),\n MultiplyNTTs: (fHat: TArg<Uint16Array>, gHat: TArg<Uint16Array>) =>\n MultiplyNTTs(Uint16Array.from(fHat), Uint16Array.from(gHat)),\n SamplePolyCBD: (B: TArg<Uint8Array>, eta: number) => {\n abytes(B, 64 * eta, 'B');\n return sampleCBDBytes(B, eta);\n },\n SampleNTT: (B: TArg<Uint8Array>) => {\n abytes(B, 34, 'B');\n const xof = XOF128(B.subarray(0, 32));\n try {\n return SampleNTT(xof.get(B[32], B[33]));\n } finally {\n xof.clean();\n }\n },\n }))();\n","/**\n * Post-Quantum Hybrid Cryptography\n *\n * The current implementation is flawed and likely redundant. We should offer\n * a small, generic API to compose hybrid schemes instead of reimplementing\n * protocol-specific logic (SSH, GPG, etc.) with ad hoc encodings.\n *\n * 1. Core Issues\n * - sign/verify: implemented as two separate operations with different keys.\n * - EC getSharedSecret: could be refactored into a proper KEM.\n * - Multiple calls: keys, signatures, and shared secrets could be\n * concatenated to reduce the number of API invocations.\n * - Reinvention: most libraries add strange domain separations and\n * encodings instead of simple byte concatenation.\n *\n * 2. API Goals\n * - Provide primitives to build hybrids generically.\n * - Avoid embedding SSH- or GPG-specific formats in the core API.\n *\n * 3. Edge Cases\n * • Variable-length signatures:\n * - DER-encoded (Weierstrass curves).\n * - Falcon (unpadded).\n * - Concatenation works only if length is fixed; otherwise a length\n * prefix is required (but that breaks compatibility).\n *\n * • getSharedSecret:\n * - Default: non-KEM (authenticated ECDH).\n * - KEM conversion: generate a random SK to remove implicit auth.\n *\n * 4. Common Pitfalls\n * - Seed expansion:\n * • Expanding a small seed into multiple keys reduces entropy.\n * • API should allow identity mapping (no expansion).\n *\n * - Skipping full point encoding:\n * • Some omit the compression byte (parity) for WebCrypto compatibility.\n * • Better: hash the raw secret; coordinate output is already non-uniform.\n * • Some curves (e.g., X448) produce secrets that must be re-hashed to match\n * symmetric-key lengths.\n *\n * - Combiner inconsistencies:\n * • Different domain separations and encodings across libraries.\n * • Should live at the application layer, since key lengths vary.\n *\n * 5. Protocol Examples\n * - SSH:\n * • Concatenate keys.\n * • Combiner: SHA-512.\n *\n * - GPG:\n * • Concatenate keys.\n * • Combiner:\n * SHA3-256(kemShare || ecdhShare || ciphertext || pubKey || algId || domSep || len(domSep))\n *\n * - TLS:\n * • Transcript-based derivation (HKDF).\n *\n * 6. Relevant Specs & Implementations\n * - IETF Hybrid KEM drafts:\n * • draft-irtf-cfrg-hybrid-kems\n * • draft-connolly-cfrg-xwing-kem\n * • draft-westerbaan-tls-xyber768d00\n *\n * - PQC Libraries:\n * • superdilithium (cyph/pqcrypto.js) – low adoption.\n * • hybrid-pqc (DogeProtocol, quantumcoinproject) – complex encodings.\n *\n * 7. Signatures\n * - Ed25519: fixed-size, easy to support.\n * - Variable-size: introduces custom format requirements; best left to\n * higher-level code.\n *\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { type EdDSA } from '@noble/curves/abstract/edwards.js';\nimport { type MontgomeryECDH } from '@noble/curves/abstract/montgomery.js';\nimport { type ECDSA } from '@noble/curves/abstract/weierstrass.js';\nimport { x25519 } from '@noble/curves/ed25519.js';\nimport { p256, p384 } from '@noble/curves/nist.js';\nimport {\n asciiToBytes,\n bytesToNumberBE,\n bytesToNumberLE,\n concatBytes,\n numberToBytesBE,\n} from '@noble/curves/utils.js';\nimport { expand, extract } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { sha3_256, shake256 } from '@noble/hashes/sha3.js';\nimport { abytes, ahash, anumber, type CHash, type CHashXOF } from '@noble/hashes/utils.js';\nimport { ml_kem1024, ml_kem768 } from './ml-kem.ts';\nimport {\n cleanBytes,\n copyBytes,\n randomBytes,\n splitCoder,\n validateSigOpts,\n validateVerOpts,\n type CryptoKeys,\n type KEM,\n type Signer,\n type TArg,\n type TRet,\n} from './utils.ts';\n\ntype CurveAll = ECDSA | EdDSA | MontgomeryECDH;\ntype CurveECDH = ECDSA | MontgomeryECDH;\ntype CurveSign = ECDSA | EdDSA;\n\n// Can re-use if decide to signatures support, on other hand getSecretKey is specific and ugly\nfunction ecKeygen(curve: CurveAll, allowZeroKey: boolean = false) {\n const lengths = curve.lengths;\n let keygen = curve.keygen;\n if (allowZeroKey) {\n // Only the ECDSA/Weierstrass branch uses raw scalar-byte secret keys here. Edwards seeds are\n // hashed/pruned and Montgomery keys are clamped byte strings, so forcing Point.Fn semantics on\n // those curves would change key construction instead of just relaxing scalar range handling.\n if (!('getSharedSecret' in curve && 'sign' in curve && 'verify' in curve))\n throw new Error('allowZeroKey requires a Weierstrass curve');\n // This legacy flag is really \"skip the +1 shift\" for vector matching, not \"accept scalar 0\".\n // It swaps seeded Weierstrass keygen from reduction into [1, ORDER) to direct reduction into\n // [0, ORDER), which preserves exact reduced bytes but still leaves scalar 0 invalid.\n // This is ugly, but we need to return exact results here.\n const wCurve = curve as ECDSA;\n const Fn = wCurve.Point.Fn;\n // Unlike noble-curves' seeded Weierstrass keygen, this path removes the post-reduction +1.\n // That is enough to match exact reduced-vector bytes, but an all-zero seed still reduces to\n // scalar 0 here and getPublicKey(secretKey) throws instead of \"allowing zero\".\n keygen = (seed: TArg<Uint8Array> = randomBytes(lengths.seed)) => {\n abytes(seed, lengths.seed!, 'seed');\n const seedScalar = Fn.isLE ? bytesToNumberLE(seed) : bytesToNumberBE(seed);\n // Reduce directly into [0, ORDER); scalar 0 still stays invalid.\n const secretKey = Fn.toBytes(Fn.create(seedScalar));\n return {\n secretKey: secretKey as TRet<Uint8Array>,\n publicKey: curve.getPublicKey(secretKey) as TRet<Uint8Array>,\n };\n };\n }\n return {\n lengths: { secretKey: lengths.secretKey, publicKey: lengths.publicKey, seed: lengths.seed },\n keygen: (seed?: TArg<Uint8Array>) =>\n keygen(seed) as TRet<{\n secretKey: Uint8Array;\n publicKey: Uint8Array;\n }>,\n getPublicKey: (secretKey: TArg<Uint8Array>) =>\n curve.getPublicKey(secretKey) as TRet<Uint8Array>,\n };\n}\n\n/**\n * Wraps an ECDH-capable curve as a KEM.\n * Shared secrets stay in the wrapped curve's raw ECDH byte format with no built-in KDF.\n * On SEC 1 / Weierstrass curves, that means the compressed shared-point body without the\n * 1-byte `0x02` / `0x03` prefix.\n * The X25519 path also leaves RFC 7748's optional all-zero shared-secret check to callers.\n * @param curve - Curve with `getSharedSecret`.\n * @param allowZeroKey - Legacy vector-matching toggle for Weierstrass keygen.\n * On Weierstrass curves this removes the usual post-reduction `+1` shift, changing seeded scalar\n * reduction from `[1, ORDER)` to direct reduction into `[0, ORDER)`. It does not make scalar zero\n * valid: an all-zero seed still derives scalar `0` and throws in `curve.getPublicKey(...)`.\n * Only supported on Weierstrass/ECDSA curves.\n * @returns KEM wrapper over the curve.\n * @throws If the curve does not expose `getSharedSecret`. {@link Error}\n * @example\n * Wrap an ECDH-capable curve as a generic KEM.\n * ```ts\n * import { x25519 } from '@noble/curves/ed25519.js';\n * import { ecdhKem } from '@noble/post-quantum/hybrid.js';\n * const kem = ecdhKem(x25519);\n * const publicKeyLen = kem.lengths.publicKey;\n * ```\n */\nexport function ecdhKem(curve: CurveECDH, allowZeroKey: boolean = false): TRet<KEM> {\n const kg = ecKeygen(curve, allowZeroKey);\n if (!curve.getSharedSecret) throw new Error('wrong curve'); // ed25519 doesn't have one!\n return {\n lengths: { ...kg.lengths, msg: kg.lengths.seed, cipherText: kg.lengths.publicKey },\n keygen: kg.keygen,\n getPublicKey: kg.getPublicKey,\n encapsulate(\n publicKey: TArg<Uint8Array>,\n rand: TArg<Uint8Array> = randomBytes(curve.lengths.seed)\n ) {\n // Some curve.keygen(seed) paths reuse the provided seed buffer as secretKey; detach caller\n // randomness first so cleanBytes() only wipes wrapper-owned material.\n const seed = copyBytes(rand);\n let ek: Uint8Array | undefined = undefined;\n try {\n ek = this.keygen(seed).secretKey;\n const sharedSecret = this.decapsulate(publicKey, ek);\n const cipherText = curve.getPublicKey(ek) as TRet<Uint8Array>;\n return { sharedSecret, cipherText };\n } finally {\n // Invalid peer public keys can make decapsulation throw; wipe both the detached seed and\n // derived ephemeral secret key even when encapsulation aborts before returning.\n cleanBytes(seed);\n if (ek) cleanBytes(ek);\n }\n },\n decapsulate(cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>) {\n const res = curve.getSharedSecret(secretKey, cipherText);\n return (curve.lengths.publicKeyHasPrefix ? res.subarray(1) : res) as TRet<Uint8Array>;\n },\n };\n}\n\n/**\n * Wraps a curve signer as a generic `Signer`.\n * Signatures stay in the wrapped curve's native byte encoding.\n * This wrapper does not normalize or document which per-curve signing options are meaningful.\n * @param curve - Curve with `sign` and `verify`.\n * @param allowZeroKey - Legacy vector-matching toggle for Weierstrass keygen.\n * On Weierstrass curves this removes the usual post-reduction `+1` shift, changing seeded scalar\n * reduction from `[1, ORDER)` to direct reduction into `[0, ORDER)`. It does not make scalar zero\n * valid: an all-zero seed still derives scalar `0` and throws in `curve.getPublicKey(...)`.\n * Only supported on Weierstrass/ECDSA curves.\n * @returns Signer wrapper over the curve.\n * @throws If the curve does not expose `sign` and `verify`. {@link Error}\n * @example\n * Wrap a curve signer as a generic signer.\n * ```ts\n * import { ed25519 } from '@noble/curves/ed25519.js';\n * import { ecSigner } from '@noble/post-quantum/hybrid.js';\n * const signer = ecSigner(ed25519);\n * const sigLen = signer.lengths.signature;\n * ```\n */\nexport function ecSigner(curve: CurveSign, allowZeroKey: boolean = false): TRet<Signer> {\n const kg = ecKeygen(curve, allowZeroKey);\n if (!curve.sign || !curve.verify) throw new Error('wrong curve'); // ed25519 doesn't have one!\n return {\n lengths: { ...kg.lengths, signature: curve.lengths.signature, signRand: 0 },\n keygen: kg.keygen,\n getPublicKey: kg.getPublicKey,\n sign: (message, secretKey, opts = {}) => {\n validateSigOpts(opts);\n // This generic wrapper intentionally keeps the Signer contract to message + key only.\n // Backend-specific knobs like ECDSA extraEntropy or Ed25519ctx context cannot be forwarded\n // uniformly through combineSigners(), so callers that need them must use the curve directly.\n if (opts.extraEntropy !== undefined)\n throw new Error(\n 'ecSigner does not support extraEntropy; use the underlying curve directly'\n );\n if (opts.context !== undefined)\n throw new Error('ecSigner does not support context; use the underlying curve directly');\n return curve.sign(message, secretKey) as TRet<Uint8Array>;\n },\n /** Verify one wrapped curve signature.\n * Returns the wrapped curve's `verify()` result for well-formed inputs. Throws on unsupported\n * generic opts and lets wrapped-curve malformed-input errors escape unchanged.\n */\n verify: (signature, message, publicKey, opts = {}) => {\n validateVerOpts(opts);\n if (opts.context !== undefined)\n throw new Error('ecSigner does not support context; use the underlying curve directly');\n return curve.verify(signature, message, publicKey);\n },\n };\n}\n\nfunction splitLengths<K extends string, T extends { lengths: Partial<Record<K, number>> }>(\n lst: T[],\n name: K\n) {\n // Preserve caller order exactly; raw numeric fields still decode as splitCoder() subarray views.\n return splitCoder(\n name,\n ...lst.map((i) => {\n if (typeof i.lengths[name] !== 'number') throw new Error('wrong length: ' + name);\n return i.lengths[name];\n })\n );\n}\n\n/** Seed-expansion callback used by the hybrid combiners. */\nexport type ExpandSeed = (seed: TArg<Uint8Array>, len: number) => TRet<Uint8Array>;\ntype XOF = CHashXOF<any, { dkLen: number }>;\n\n// It is XOF for most cases, but can be more complex!\n/**\n * Adapts an XOF into an `ExpandSeed` callback.\n * The returned callback interprets its second argument as an output byte length passed as `dkLen`.\n * @param xof - Extendable-output hash function.\n * @returns Seed expander using `dkLen`.\n * @example\n * Adapt an XOF into a seed expander.\n * ```ts\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { expandSeedXof } from '@noble/post-quantum/hybrid.js';\n * const expandSeed = expandSeedXof(shake256);\n * const seed = expandSeed(new Uint8Array([1]), 4);\n * ```\n */\nexport function expandSeedXof(xof: TArg<XOF>): TRet<ExpandSeed> {\n // Forward the caller seed directly: XOFs are expected to treat inputs as read-only, and this\n // adapter only translates the requested byte length into the hash API's `dkLen` option.\n return ((seed: TArg<Uint8Array>, seedLen: number): TRet<Uint8Array> =>\n (xof as XOF)(seed, { dkLen: seedLen }) as TRet<Uint8Array>) as TRet<ExpandSeed>;\n}\n\n/** Combines public keys, ciphertexts, and shared secrets into one shared secret. */\nexport type Combiner = (\n publicKeys: TArg<Uint8Array[]>,\n cipherTexts: TArg<Uint8Array[]>,\n sharedSecrets: TArg<Uint8Array[]>\n) => TRet<Uint8Array>;\n\nfunction combineKeys(\n realSeedLen: number | undefined, // how much bytes expandSeed expects\n expandSeed_: TArg<ExpandSeed>,\n ...ck_: TArg<CryptoKeys[]>\n) {\n const expandSeed = expandSeed_ as ExpandSeed;\n const ck = ck_ as CryptoKeys[];\n const seedCoder = splitLengths(ck, 'seed');\n const pkCoder = splitLengths(ck, 'publicKey');\n // Allows to use identity functions for combiner/expandSeed\n if (realSeedLen === undefined) realSeedLen = seedCoder.bytesLen;\n anumber(realSeedLen);\n function expandDecapsulationKey(seed: TArg<Uint8Array>): TRet<{\n secretKey: Uint8Array[];\n publicKey: Uint8Array[];\n }> {\n abytes(seed, realSeedLen!);\n const expandedRaw = expandSeed(seed, seedCoder.bytesLen);\n // Identity/subarray expanders can hand back caller-owned seed storage. Detach those outputs so\n // later cleanup can wipe the expanded schedule without mutating the caller's root seed bytes.\n const expandedSeed = expandedRaw.buffer === seed.buffer ? copyBytes(expandedRaw) : expandedRaw;\n const expanded: Uint8Array[] = [];\n const keySecret: Uint8Array[] = [];\n const secretKey: Uint8Array[] = [];\n const publicKey: Uint8Array[] = [];\n let ok = false;\n try {\n // seedCoder.decode() returns zero-copy slices into expandedSeed and can throw before child\n // keygen() runs, so keep the raw expanded buffer separate and copy each child seed before any\n // later cleanup wipes the shared backing bytes.\n for (const part of seedCoder.decode(expandedSeed)) expanded.push(copyBytes(part));\n for (let i = 0; i < ck.length; i++) {\n const keys = ck[i].keygen(expanded[i]);\n keySecret.push(keys.secretKey);\n secretKey.push(copyBytes(keys.secretKey));\n publicKey.push(keys.publicKey);\n }\n ok = true;\n return { secretKey, publicKey } as TRet<{\n secretKey: Uint8Array[];\n publicKey: Uint8Array[];\n }>;\n } finally {\n // Child keygen() can throw after deriving only a prefix of the composite key schedule. Keep\n // the exported copies on success, but wipe all temporary and partially built secret material\n // on either path so failures do not strand derived child seeds in memory.\n cleanBytes(expandedSeed, expanded, keySecret);\n if (!ok) cleanBytes(secretKey);\n }\n }\n return {\n info: { lengths: { seed: realSeedLen, publicKey: pkCoder.bytesLen, secretKey: realSeedLen } },\n getPublicKey(secretKey: TArg<Uint8Array>) {\n // Composite secret keys are root seeds, so public-key derivation reruns key expansion from\n // that seed instead of decoding a packed child-secret-key structure.\n return this.keygen(secretKey).publicKey as TRet<Uint8Array>;\n },\n keygen(seed: TArg<Uint8Array> = randomBytes(realSeedLen)) {\n const { publicKey: pk, secretKey } = expandDecapsulationKey(seed);\n try {\n const publicKey = pkCoder.encode(pk) as TRet<Uint8Array>;\n return { secretKey: seed as TRet<Uint8Array>, publicKey };\n } finally {\n cleanBytes(pk);\n // The exported secretKey is the caller/root seed itself; child secret keys are internal\n // expansion outputs that are cleaned whether encoding succeeds or throws.\n cleanBytes(secretKey);\n }\n },\n expandDecapsulationKey,\n realSeedLen,\n };\n}\n\n// This generic function that combines multiple KEMs into single one\n/**\n * Combines multiple KEMs into one composite KEM.\n * @param realSeedLen - Input seed length expected by `expandSeed`.\n * @param realMsgLen - Shared-secret length returned by `combiner`.\n * @param expandSeed - Seed expander used to derive per-KEM seeds.\n * @param combiner - Combines the per-KEM outputs into one shared secret.\n * @param kems - KEM implementations to combine.\n * @returns Composite KEM.\n * @example\n * Combine multiple KEMs into one composite KEM.\n * ```ts\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { combineKEMS, expandSeedXof } from '@noble/post-quantum/hybrid.js';\n * import { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n * const hybrid = combineKEMS(\n * 32,\n * 32,\n * expandSeedXof(shake256),\n * (_pk, _ct, sharedSecrets) => sharedSecrets[0],\n * ml_kem768,\n * ml_kem768\n * );\n * const { publicKey } = hybrid.keygen();\n * ```\n */\nexport function combineKEMS(\n realSeedLen: number | undefined, // how much bytes expandSeed expects\n realMsgLen: number | undefined, // how much bytes combiner returns\n expandSeed: TArg<ExpandSeed>,\n combiner: TArg<Combiner>,\n ...kems: TArg<KEM[]>\n): TRet<KEM> {\n const rawCombiner = combiner as Combiner;\n const rawKems = kems as KEM[];\n const keys = combineKeys(realSeedLen, expandSeed, ...rawKems);\n const ctCoder = splitLengths(rawKems, 'cipherText');\n const pkCoder = splitLengths(rawKems, 'publicKey');\n const msgCoder = splitLengths(rawKems, 'msg');\n if (realMsgLen === undefined) realMsgLen = msgCoder.bytesLen;\n anumber(realMsgLen);\n const lengths = Object.freeze({\n ...keys.info.lengths,\n msg: realMsgLen,\n msgRand: msgCoder.bytesLen,\n cipherText: ctCoder.bytesLen,\n });\n return Object.freeze({\n lengths,\n getPublicKey: keys.getPublicKey,\n keygen: keys.keygen,\n encapsulate(\n pk: TArg<Uint8Array>,\n randomness: TArg<Uint8Array> = randomBytes(msgCoder.bytesLen)\n ) {\n const pks = pkCoder.decode(pk);\n const rand = msgCoder.decode(randomness);\n const sharedSecret: Uint8Array[] = [];\n const cipherText: Uint8Array[] = [];\n try {\n for (let i = 0; i < rawKems.length; i++) {\n const enc = rawKems[i].encapsulate(pks[i], rand[i]);\n sharedSecret.push(enc.sharedSecret);\n cipherText.push(enc.cipherText);\n }\n return {\n // Detach the combiner result before cleanup: a caller-provided combiner may alias one of\n // the child sharedSecret buffers, and those child buffers are zeroized immediately below.\n sharedSecret: copyBytes(rawCombiner(pks, cipherText, sharedSecret)),\n cipherText: ctCoder.encode(cipherText) as TRet<Uint8Array>,\n };\n } finally {\n // Child encapsulation or combiner failures can happen after some components already\n // returned secret material; zeroize whatever was produced before propagating the error.\n cleanBytes(sharedSecret, cipherText);\n }\n },\n decapsulate(ct: TArg<Uint8Array>, seed: TArg<Uint8Array>) {\n const cts = ctCoder.decode(ct);\n const { publicKey, secretKey } = keys.expandDecapsulationKey(seed);\n const sharedSecret = rawKems.map((i, j) => i.decapsulate(cts[j], secretKey[j]));\n try {\n // Detach the decapsulation result before cleanup: the combiner may hand back one of the\n // child shared-secret buffers, and those temporary buffers are zeroized below.\n return copyBytes(rawCombiner(publicKey, cts, sharedSecret));\n } finally {\n // Decapsulation only needs the expanded child secret keys and child shared secrets for this\n // call; keep the caller/root seed intact, but wipe all derived material even on errors.\n cleanBytes(secretKey, sharedSecret);\n }\n },\n });\n}\n// There is no specs for this, but can be useful\n// realSeedLen: how much bytes expandSeed expects.\n/**\n * Combines multiple signers into one composite signer.\n * @param realSeedLen - Input seed length expected by `expandSeed`.\n * @param expandSeed - Seed expander used to derive per-signer seeds.\n * @param signers - Signers to combine.\n * @returns Composite signer.\n * @example\n * Combine multiple signers into one composite signer.\n * ```ts\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { combineSigners, expandSeedXof } from '@noble/post-quantum/hybrid.js';\n * import { ml_dsa44 } from '@noble/post-quantum/ml-dsa.js';\n * const hybrid = combineSigners(32, expandSeedXof(shake256), ml_dsa44, ml_dsa44);\n * const { publicKey } = hybrid.keygen();\n * ```\n */\nexport function combineSigners(\n realSeedLen: number | undefined,\n expandSeed: TArg<ExpandSeed>,\n ...signers: TArg<Signer[]>\n): TRet<Signer> {\n const rawSigners = signers as Signer[];\n const keys = combineKeys(realSeedLen, expandSeed, ...rawSigners);\n const sigCoder = splitLengths(rawSigners, 'signature');\n const pkCoder = splitLengths(rawSigners, 'publicKey');\n return {\n lengths: { ...keys.info.lengths, signature: sigCoder.bytesLen, signRand: 0 },\n getPublicKey: keys.getPublicKey,\n keygen: keys.keygen,\n sign(message, seed, opts = {}) {\n validateSigOpts(opts);\n // This generic wrapper intentionally keeps the composite signer contract to message + root\n // seed only. Per-signer opts like context or extraEntropy cannot be preserved uniformly\n // across mixed backends, so callers that need them must use the underlying signer directly.\n if (opts.extraEntropy !== undefined)\n throw new Error(\n 'combineSigners does not support extraEntropy; use the underlying signer directly'\n );\n if (opts.context !== undefined)\n throw new Error(\n 'combineSigners does not support context; use the underlying signer directly'\n );\n const { secretKey } = keys.expandDecapsulationKey(seed);\n try {\n const sigs = rawSigners.map((i, j) => i.sign(message, secretKey[j]));\n return sigCoder.encode(sigs) as TRet<Uint8Array>;\n } finally {\n // Composite secret keys are root seeds; the per-signer child secret keys are temporary\n // expansion outputs and must not stay live after the combined signature is produced.\n cleanBytes(secretKey);\n }\n },\n /** Verify one combined signature.\n * Returns `false` when the aggregate signature/publicKey decode succeeds but any child verify\n * check fails. Throws on unsupported generic opts or malformed aggregate encodings.\n */\n verify: (signature, message, publicKey, opts = {}) => {\n validateVerOpts(opts);\n if (opts.context !== undefined)\n throw new Error(\n 'combineSigners does not support context; use the underlying signer directly'\n );\n const pks = pkCoder.decode(publicKey);\n const sigs = sigCoder.decode(signature);\n for (let i = 0; i < rawSigners.length; i++) {\n if (!rawSigners[i].verify(sigs[i], message, pks[i])) return false;\n }\n return true;\n },\n };\n}\n\n/**\n * Builds a QSF hybrid KEM preset from a PQ KEM and an elliptic-curve KEM.\n * The combined shared-secret length follows `kdf.outputLen`; the built-in presets use 32-byte\n * SHA3-256 output, while custom `kdf` choices inherit their own digest size.\n * Its combiner hashes `ss0 || ss1 || ct1 || pk1 || label`, not the full\n * `(c1, c2, ek1, ek2)` example input shape from SP 800-227 equation (15).\n * Labels are encoded with `asciiToBytes()`, so non-ASCII labels are rejected.\n * @param label - Domain-separation label.\n * @param pqc - Post-quantum KEM.\n * @param curveKEM - Classical curve KEM.\n * @param xof - XOF used for seed expansion.\n * @param kdf - Hash used for the final combiner.\n * @returns Hybrid KEM.\n * @example\n * Build a QSF hybrid KEM preset from a PQ KEM and an elliptic-curve KEM.\n * ```ts\n * import { p256 } from '@noble/curves/nist.js';\n * import { sha3_256, shake256 } from '@noble/hashes/sha3.js';\n * import { QSF, ecdhKem } from '@noble/post-quantum/hybrid.js';\n * import { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n * const kem = QSF('example', ml_kem768, ecdhKem(p256, true), shake256, sha3_256);\n * const publicKeyLen = kem.lengths.publicKey;\n * ```\n */\nexport function QSF(\n label: string,\n pqc: TArg<KEM>,\n curveKEM: TArg<KEM>,\n xof: TArg<XOF>,\n kdf: CHash\n): TRet<KEM> {\n ahash(xof);\n ahash(kdf);\n return combineKEMS(\n 32,\n kdf.outputLen,\n expandSeedXof(xof),\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) =>\n kdf(concatBytes(ss[0], ss[1], ct[1], pk[1], asciiToBytes(label))),\n pqc,\n curveKEM\n );\n}\n\n/** QSF preset combining ML-KEM-768 with P-256. */\nexport const QSF_ml_kem768_p256: TRet<KEM> = /* @__PURE__ */ (() =>\n QSF(\n 'QSF-KEM(ML-KEM-768,P-256)-XOF(SHAKE256)-KDF(SHA3-256)',\n ml_kem768,\n ecdhKem(p256, true),\n shake256,\n sha3_256\n ))();\n/** QSF preset combining ML-KEM-1024 with P-384. */\nexport const QSF_ml_kem1024_p384: TRet<KEM> = /* @__PURE__ */ (() =>\n QSF(\n 'QSF-KEM(ML-KEM-1024,P-384)-XOF(SHAKE256)-KDF(SHA3-256)',\n ml_kem1024,\n ecdhKem(p384, true),\n shake256,\n sha3_256\n ))();\n\n/**\n * Builds the \"KitchenSink\" hybrid KEM combiner.\n * The current builder always derives a fixed 32-byte output,\n * regardless of the hash's native output size.\n * Its HKDF extract step uses implicit zero salt with IKM\n * `hybrid_prk || ss0 || ss1 || ct0 || pk0 || ct1 || pk1 || label`.\n * Its HKDF expand step fixes `info` to `len || 'shared_secret' || ''`.\n * Labels are encoded with `asciiToBytes()`, so non-ASCII labels are rejected.\n * @param label - Domain-separation label.\n * @param pqc - Post-quantum KEM.\n * @param curveKEM - Classical curve KEM.\n * @param xof - XOF used for seed expansion.\n * @param hash - Hash used for HKDF extraction and expansion.\n * @returns Hybrid KEM.\n * @example\n * Build the \"KitchenSink\" hybrid KEM combiner.\n * ```ts\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { createKitchenSink, ecdhKem } from '@noble/post-quantum/hybrid.js';\n * import { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n * import { x25519 } from '@noble/curves/ed25519.js';\n * const kem = createKitchenSink('example', ml_kem768, ecdhKem(x25519), shake256, sha256);\n * const publicKeyLen = kem.lengths.publicKey;\n * ```\n */\nexport function createKitchenSink(\n label: string,\n pqc: TArg<KEM>,\n curveKEM: TArg<KEM>,\n xof: TArg<XOF>,\n hash: CHash\n): TRet<KEM> {\n ahash(xof);\n ahash(hash);\n return combineKEMS(\n 32,\n 32,\n expandSeedXof(xof),\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) => {\n const preimage = concatBytes(ss[0], ss[1], ct[0], pk[0], ct[1], pk[1], asciiToBytes(label));\n const len = 32;\n const ikm = concatBytes(asciiToBytes('hybrid_prk'), preimage);\n const prk = extract(hash, ikm);\n const info = concatBytes(\n numberToBytesBE(len, 2),\n asciiToBytes('shared_secret'),\n asciiToBytes('')\n );\n const res = expand(hash, prk, info, len);\n cleanBytes(prk, info, ikm, preimage);\n return res;\n },\n pqc,\n curveKEM\n );\n}\n\n// Internal alias only: this stays exactly `ecdhKem(x25519)`\n// and inherits that wrapper's mutation/oracle behavior.\nconst x25519kem = /* @__PURE__ */ ecdhKem(x25519);\n/** KitchenSink preset combining ML-KEM-768 with X25519.\n * Caller randomness splits into 32 ML-KEM coins plus a 32-byte X25519 ephemeral-secret seed.\n */\nexport const KitchenSink_ml_kem768_x25519: TRet<KEM> = /* @__PURE__ */ (() =>\n createKitchenSink(\n 'KitchenSink-KEM(ML-KEM-768,X25519)-XOF(SHAKE256)-KDF(HKDF-SHA-256)',\n ml_kem768,\n x25519kem,\n shake256,\n sha256\n ))();\n\n// Always X25519 and ML-KEM - 768, no point to export\n/** X25519 + ML-KEM-768 hybrid preset.\n * Uses the hard-coded domain-separation label `\\\\.//^\\\\` and hashes only `ct1 || pk1`\n * from the X25519 side in addition to the two component shared secrets.\n */\nexport const ml_kem768_x25519: TRet<KEM> = /* @__PURE__ */ (() =>\n combineKEMS(\n 32,\n 32,\n expandSeedXof(shake256),\n // Awesome label, so much escaping hell in a single line.\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) =>\n sha3_256(concatBytes(ss[0], ss[1], ct[1], pk[1], asciiToBytes('\\\\.//^\\\\'))),\n ml_kem768,\n x25519kem\n ))();\n\n/**\n * Internal SEC 1-style KEM wrapper for NIST curves.\n * `nseed` is only the rejection-sampling byte budget for deriving one nonzero scalar:\n * current presets use `128` bytes for P-256 and `48` bytes for P-384.\n * `decapsulate()` returns the uncompressed shared point body `x || y` without the `0x04`\n * prefix, not the SEC 1 `x_P`-only primitive output, because current hybrid combiners hash\n * both coordinates.\n */\nfunction nistCurveKem(curve: ECDSA, scalarLen: number, elemLen: number, nseed: number): TRet<KEM> {\n const Fn = curve.Point.Fn;\n if (!Fn) throw new Error('no Point.Fn');\n // Scan scalar-sized windows until one decodes to a nonzero scalar in `[1, n-1]`; if every\n // window is zero or out of range, fail instead of silently reducing modulo `n`.\n function rejectionSampling(seed: TArg<Uint8Array>): TRet<{\n secretKey: Uint8Array;\n publicKey: Uint8Array;\n }> {\n let sk: bigint;\n for (let start = 0, end = scalarLen; ; start = end, end += scalarLen) {\n if (end > seed.length) throw new Error('rejection sampling failed');\n sk = Fn.fromBytes(seed.subarray(start, end), true);\n if (Fn.isValidNot0(sk)) break;\n }\n const secretKey = Fn.toBytes(Fn.create(sk));\n const publicKey = curve.getPublicKey(secretKey, false);\n return { secretKey, publicKey } as TRet<{\n secretKey: Uint8Array;\n publicKey: Uint8Array;\n }>;\n }\n\n return {\n lengths: {\n secretKey: scalarLen,\n publicKey: elemLen,\n seed: nseed,\n msg: nseed,\n cipherText: elemLen,\n },\n keygen(seed: TArg<Uint8Array> = randomBytes(nseed)) {\n abytes(seed, nseed, 'seed');\n return rejectionSampling(seed);\n },\n getPublicKey(secretKey: TArg<Uint8Array>) {\n return curve.getPublicKey(secretKey, false) as TRet<Uint8Array>;\n },\n encapsulate(publicKey: TArg<Uint8Array>, rand: TArg<Uint8Array> = randomBytes(nseed)) {\n abytes(rand, nseed, 'rand');\n let ek: Uint8Array | undefined = undefined;\n try {\n ek = rejectionSampling(rand).secretKey;\n const sharedSecret = this.decapsulate(publicKey, ek);\n const cipherText = curve.getPublicKey(ek, false) as TRet<Uint8Array>;\n return { sharedSecret, cipherText };\n } finally {\n // Rejection-sampled NIST-curve ephemeral secret keys are temporary encapsulation state and\n // must be wiped even if peer-key validation or shared-secret derivation throws.\n if (ek) cleanBytes(ek);\n }\n },\n decapsulate(cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>) {\n const full = curve.getSharedSecret(secretKey, cipherText);\n return full.subarray(1) as TRet<Uint8Array>;\n },\n };\n}\n\n/**\n * Internal ML-KEM + NIST-curve combiner.\n * `nseed` controls only the curve-side rejection-sampling budget; it is expanded from the\n * 32-byte root seed and is not itself part of the exported secret-key length.\n * The domain-separation `label` is used only in the final `sha3_256` combiner, not in\n * `shake256(seed, { dkLen: 64 + nseed })`,\n * and the combiner hashes `ss0 || ss1 || ct1 || pk1 || label`.\n */\nfunction concreteHybridKem(\n label: string,\n mlkem: TArg<KEM>,\n curve: ECDSA,\n nseed: number\n): TRet<KEM> {\n const { secretKey: scalarLen, publicKeyUncompressed: elemLen } = curve.lengths;\n if (!scalarLen || !elemLen) throw new Error('wrong curve');\n const curveKem = nistCurveKem(curve, scalarLen, elemLen, nseed);\n const mlkemSeedLen = 64;\n const totalSeedLen = mlkemSeedLen + nseed;\n\n return combineKEMS(\n 32,\n 32,\n (seed: TArg<Uint8Array>): TRet<Uint8Array> => {\n abytes(seed, 32);\n const expanded = shake256(seed, { dkLen: totalSeedLen });\n const mlkemSeed = expanded.subarray(0, mlkemSeedLen);\n const curveSeed = expanded.subarray(mlkemSeedLen, totalSeedLen);\n return concatBytes(mlkemSeed, curveSeed) as TRet<Uint8Array>;\n },\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) =>\n sha3_256(concatBytes(ss[0], ss[1], ct[1], pk[1], asciiToBytes(label))),\n mlkem,\n curveKem\n );\n}\n\n/** P-256 + ML-KEM-768 hybrid preset. */\nexport const ml_kem768_p256: TRet<KEM> = /* @__PURE__ */ (() =>\n concreteHybridKem('MLKEM768-P256', ml_kem768, p256, 128))();\n\n/** P-384 + ML-KEM-1024 hybrid preset. */\nexport const ml_kem1024_p384: TRet<KEM> = /* @__PURE__ */ (() =>\n concreteHybridKem('MLKEM1024-P384', ml_kem1024, p384, 48))();\n\n// Legacy aliases\n/** Legacy alias for `ml_kem768_x25519`. */\nexport const XWing: TRet<KEM> = /* @__PURE__ */ (() => ml_kem768_x25519)();\n/** Legacy alias for `ml_kem768_x25519`. */\nexport const MLKEM768X25519: TRet<KEM> = /* @__PURE__ */ (() => ml_kem768_x25519)();\n/** Legacy alias for `ml_kem768_p256`. */\nexport const MLKEM768P256: TRet<KEM> = /* @__PURE__ */ (() => ml_kem768_p256)();\n/** Legacy alias for `ml_kem1024_p384`. */\nexport const MLKEM1024P384: TRet<KEM> = /* @__PURE__ */ (() => ml_kem1024_p384)();\n/** Legacy alias for `QSF_ml_kem768_p256`. */\nexport const QSFMLKEM768P256: TRet<KEM> = /* @__PURE__ */ (() => QSF_ml_kem768_p256)();\n/** Legacy alias for `QSF_ml_kem1024_p384`. */\nexport const QSFMLKEM1024P384: TRet<KEM> = /* @__PURE__ */ (() => QSF_ml_kem1024_p384)();\n/** Legacy alias for `KitchenSink_ml_kem768_x25519`. */\nexport const KitchenSinkMLKEM768X25519: TRet<KEM> = /* @__PURE__ */ (() =>\n KitchenSink_ml_kem768_x25519)();\n","import { chacha20poly1305 } from '@noble/ciphers/chacha.js';\n\nimport { AeadVerificationError } from './errors';\n\nexport interface ChaCha20Poly1305EncryptOpts {\n readonly key: Uint8Array;\n readonly nonce: Uint8Array;\n readonly aad: Uint8Array;\n readonly plaintext: Uint8Array;\n}\n\nexport interface ChaCha20Poly1305DecryptOpts {\n readonly key: Uint8Array;\n readonly nonce: Uint8Array;\n readonly aad: Uint8Array;\n readonly ciphertext: Uint8Array;\n}\n\nexport function chacha20Poly1305Encrypt(opts: ChaCha20Poly1305EncryptOpts): Uint8Array {\n return chacha20poly1305(opts.key, opts.nonce, opts.aad).encrypt(opts.plaintext);\n}\n\nexport function chacha20Poly1305Decrypt(opts: ChaCha20Poly1305DecryptOpts): Uint8Array {\n try {\n return chacha20poly1305(opts.key, opts.nonce, opts.aad).decrypt(opts.ciphertext);\n } catch (cause) {\n throw new AeadVerificationError('chacha20-poly1305 decrypt failed', { cause });\n }\n}\n","import { XWing } from '@noble/post-quantum/hybrid.js';\n\n// X-Wing (ML-KEM-768 + X25519) hybrid KEM per draft-connolly-cfrg-xwing-kem-10.\n// `XWing` is @noble/post-quantum's alias for `ml_kem768_x25519`. We expose it\n// through opts-object wrappers that pin the wire lengths and map noble's field\n// names onto the project's vocabulary.\n//\n// Unlike the bare X25519 KEM, there is no contributory-behaviour rejection to\n// translate: X-Wing combines the ML-KEM and X25519 shared secrets through a\n// SHA3-256 combiner that also binds the X25519 ephemeral and recipient public\n// keys, and ML-KEM's implicit rejection already yields a constant-work\n// pseudorandom secret on a malformed ciphertext. Decapsulation therefore never\n// throws on attacker-supplied wire data — a wrong shared secret is the correct,\n// indistinguishable failure mode, and callers MUST treat it as a non-match\n// rather than expecting an exception.\n\nexport const MLKEM768X25519_PUBLIC_KEY_LENGTH = 1216 as const;\nexport const MLKEM768X25519_ENC_LENGTH = 1120 as const;\nexport const MLKEM768X25519_SHARED_SECRET_LENGTH = 32 as const;\nexport const MLKEM768X25519_SEED_LENGTH = 32 as const;\nexport const MLKEM768X25519_ESEED_LENGTH = 64 as const;\n\nexport interface Mlkem768X25519KeyPair {\n // The 32-byte root seed IS the secret key: the ML-KEM coins and the X25519\n // scalar are re-expanded from it via SHAKE-256 at decapsulation. (Later X-Wing\n // drafts also define an optional expanded decapsulation-key form; we keep the\n // seed-only key, which the draft-10 Appendix C vectors still pin.)\n readonly secretSeed: Uint8Array;\n readonly publicKey: Uint8Array;\n}\n\nexport interface Mlkem768X25519EncapsulateOpts {\n readonly publicKey: Uint8Array;\n // Optional 64-byte encapsulation randomness (msgRand). When supplied the\n // ciphertext and shared secret are fully deterministic; a 32-byte value is\n // rejected by noble, so we pin the length here too.\n readonly eseed?: Uint8Array;\n}\n\nexport interface Mlkem768X25519Encapsulation {\n readonly enc: Uint8Array;\n readonly ss: Uint8Array;\n}\n\nexport interface Mlkem768X25519DecapsulateOpts {\n readonly secretSeed: Uint8Array;\n readonly enc: Uint8Array;\n}\n\nexport function mlkem768x25519Keygen(seed: Uint8Array): Mlkem768X25519KeyPair {\n if (seed.length !== MLKEM768X25519_SEED_LENGTH) {\n throw new Error(\n `mlkem768x25519 seed must be ${MLKEM768X25519_SEED_LENGTH} bytes, got ${seed.length}`,\n );\n }\n const { secretKey, publicKey } = XWing.keygen(seed);\n return { secretSeed: secretKey, publicKey };\n}\n\nexport function mlkem768x25519Encapsulate(\n opts: Mlkem768X25519EncapsulateOpts,\n): Mlkem768X25519Encapsulation {\n if (opts.publicKey.length !== MLKEM768X25519_PUBLIC_KEY_LENGTH) {\n throw new Error(\n `mlkem768x25519 public key must be ${MLKEM768X25519_PUBLIC_KEY_LENGTH} bytes, got ${opts.publicKey.length}`,\n );\n }\n if (opts.eseed !== undefined && opts.eseed.length !== MLKEM768X25519_ESEED_LENGTH) {\n throw new Error(\n `mlkem768x25519 eseed must be ${MLKEM768X25519_ESEED_LENGTH} bytes, got ${opts.eseed.length}`,\n );\n }\n const { cipherText, sharedSecret } = XWing.encapsulate(opts.publicKey, opts.eseed);\n return { enc: cipherText, ss: sharedSecret };\n}\n\nexport function mlkem768x25519Decapsulate(opts: Mlkem768X25519DecapsulateOpts): Uint8Array {\n // Pre-check both lengths before calling noble: decapsulation must perform a\n // constant amount of work for any caller-supplied ciphertext (implicit\n // rejection), which requires the inputs to be the exact expected sizes.\n if (opts.secretSeed.length !== MLKEM768X25519_SEED_LENGTH) {\n throw new Error(\n `mlkem768x25519 secret seed must be ${MLKEM768X25519_SEED_LENGTH} bytes, got ${opts.secretSeed.length}`,\n );\n }\n if (opts.enc.length !== MLKEM768X25519_ENC_LENGTH) {\n throw new Error(\n `mlkem768x25519 enc must be ${MLKEM768X25519_ENC_LENGTH} bytes, got ${opts.enc.length}`,\n );\n }\n // noble's signature is decapsulate(cipherText, secretKey) — ciphertext first.\n return XWing.decapsulate(opts.enc, opts.secretSeed);\n}\n","import { x25519 } from '@noble/curves/ed25519.js';\n\n// RFC 7748 §6.1 contributory-behaviour rejection: a small-order (low-order)\n// Montgomery `u` coordinate makes the X25519 shared secret all-zero, which\n// @noble/curves refuses with `Error: invalid private or public key received`.\n// We rethrow that as a *typed* error so callers can distinguish a structurally\n// valid-but-malicious peer public key (a property of attacker-supplied wire\n// data — trial-decrypt MUST treat the slot as a non-match, not crash) from\n// genuine caller misuse such as a wrong-length key (which @noble raises as a\n// RangeError and which we deliberately let propagate untouched).\nexport class X25519LowOrderPointError extends Error {\n readonly code = 'X25519_LOW_ORDER_POINT' as const;\n constructor(options?: { cause?: unknown }) {\n super('x25519 ECDH rejected: peer public key is a small-order point', options);\n this.name = 'X25519LowOrderPointError';\n }\n}\n\n// @noble/curves v2 signals a small-order/all-zero shared secret with this exact\n// message. Matching on it (rather than the broad Error class) keeps unrelated\n// failures — e.g. a future internal assertion — surfacing as themselves.\nconst NOBLE_LOW_ORDER_MESSAGE = 'invalid private or public key received';\n\nexport interface X25519KeyPair {\n readonly secretKey: Uint8Array;\n readonly publicKey: Uint8Array;\n}\n\nexport interface X25519PublicKeyOpts {\n readonly secretKey: Uint8Array;\n}\n\nexport interface X25519EcdhOpts {\n readonly secretKey: Uint8Array;\n readonly theirPublicKey: Uint8Array;\n}\n\nexport function x25519Keygen(): X25519KeyPair {\n return x25519.keygen();\n}\n\nexport function x25519PublicKey(opts: X25519PublicKeyOpts): Uint8Array {\n return x25519.getPublicKey(opts.secretKey);\n}\n\nexport function x25519Ecdh(opts: X25519EcdhOpts): Uint8Array {\n try {\n return x25519.getSharedSecret(opts.secretKey, opts.theirPublicKey);\n } catch (e) {\n // Translate ONLY the contributory-check rejection into our typed error.\n // A wrong-length key throws a RangeError from @noble's length assertion;\n // that is caller misuse, not malicious wire data, so it must propagate.\n if (e instanceof Error && e.message === NOBLE_LOW_ORDER_MESSAGE) {\n throw new X25519LowOrderPointError({ cause: e });\n }\n throw e;\n }\n}\n","import { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nexport interface HkdfSha256Opts {\n readonly ikm: Uint8Array;\n readonly salt: Uint8Array;\n readonly info: Uint8Array;\n readonly length: number;\n}\n\nexport function hkdfSha256(opts: HkdfSha256Opts): Uint8Array {\n return hkdf(sha256, opts.ikm, opts.salt, opts.info, opts.length);\n}\n","// Sealed-PoE construction error taxonomy (wire-shape + partitioning-oracle\n// pre-checks + caller-input validation).\n//\n// Codes whose concept exists in the wire error-code registry reuse the registry\n// string verbatim (UNSUPPORTED_ENVELOPE_SCHEME, UNSUPPORTED_AEAD_ALG,\n// ENC_PASSPHRASE_EMPTY, ...), so a consumer correlating construction failures\n// with validator/verifier reports sees one vocabulary. Conditions that exist\n// only at the construction API boundary (raw caller-input lengths, deterministic\n// test-override mismatches) carry construction-local names with no wire\n// counterpart.\n\nexport type EciesSealedPoeErrorCode =\n // Wire-registry codes (same concept, same string).\n | 'ENC_SLOTS_EMPTY'\n | 'ENC_SLOTS_MAC_INVALID_LENGTH'\n | 'ENC_SLOTS_DUPLICATE_KEM_MATERIAL'\n | 'ENC_SLOTS_TOO_MANY'\n | 'ENC_ENVELOPE_TOO_LARGE'\n | 'ENC_REQUIRES_CONTENT_HASH'\n | 'ENC_PASSPHRASE_EMPTY'\n | 'ENC_PASSPHRASE_UNNORMALIZABLE'\n | 'ENC_PASSPHRASE_ALG_UNSUPPORTED'\n | 'ENC_PASSPHRASE_SALT_TOO_SHORT'\n | 'ENC_PASSPHRASE_SALT_TOO_LONG'\n | 'ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW'\n | 'KEM_EPK_LENGTH_MISMATCH'\n | 'KEM_CT_LENGTH_MISMATCH'\n | 'NONCE_LENGTH_MISMATCH'\n | 'WRAP_LENGTH_MISMATCH'\n | 'UNSUPPORTED_ENVELOPE_SCHEME'\n | 'UNSUPPORTED_AEAD_ALG'\n | 'UNSUPPORTED_KEM_ALG'\n | 'KDF_DERIVATION_FAILED'\n // Construction-local codes (no wire counterpart).\n | 'INVALID_CEK_LENGTH'\n | 'INVALID_EPHEMERAL_SECRET_LENGTH'\n | 'EPHEMERAL_SECRETS_COUNT_MISMATCH'\n | 'INVALID_RECIPIENT_KEY'\n | 'INVALID_PASSPHRASE_PARAMS'\n | 'PASSPHRASE_INPUT_TOO_LONG';\n\nexport class EciesSealedPoeError extends Error {\n readonly code: EciesSealedPoeErrorCode;\n\n constructor(code: EciesSealedPoeErrorCode, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'EciesSealedPoeError';\n this.code = code;\n }\n}\n","// chacha20-poly1305-stream64k: the segmented STREAM content format for sealed\n// PoE (the age v1 STREAM layout).\n//\n// cipher : ChaCha20-Poly1305 (RFC 8439; 12-byte nonce, 16-byte tag)\n// chunk size : 65536 plaintext bytes per non-final chunk\n// chunk nonce : uint88_be(counter) || final_flag — counter starts at 0,\n// +1 per chunk; final_flag is 0x01 on the final chunk,\n// 0x00 otherwise\n// per-chunk AAD : empty (all context binds transitively through the\n// payload_key, whose CEK is committed by slots_mac or the\n// passphrase commitment header)\n// final chunk : 0..65536 plaintext bytes; zero-length only when the whole\n// plaintext is empty (an empty plaintext is exactly one\n// zero-length final chunk — a lone 16-byte tag)\n//\n// The counter nonces are safe because the payload_key is single-use (a fresh\n// CEK salted by the envelope-unique enc.nonce), so no two streams ever share a\n// (key, nonce) pair. The final flag domain-separates the last chunk, which is\n// what makes truncation detectable.\n//\n// Layout violations — a tag failure, a truncated stream, data after the final\n// chunk, a non-final chunk shorter than CHUNK_SIZE, a zero-length final chunk\n// on a non-empty stream — all surface as StreamTamperedError; the caller maps\n// it to the single generic decryption failure. Each chunk's tag is verified\n// before that chunk's plaintext is released, but the whole-plaintext hash\n// recheck is post-hoc: incremental consumers MUST treat released bytes as\n// tentative until it passes.\n\nimport { chacha20Poly1305Decrypt, chacha20Poly1305Encrypt } from '../aead/chacha20-poly1305';\nimport { AeadVerificationError } from '../aead/errors';\n\n// Pinned format constants. The 88-bit counter admits at most 2^88 chunks, far\n// above any realisable payload, so the format imposes no cryptographic payload\n// ceiling — the practical maximum is a deployment denial-of-service policy, not\n// a wire constant.\nexport const CHUNK_SIZE = 65536;\nexport const TAG_SIZE = 16;\n\nconst NONCE_LENGTH = 12;\nconst COUNTER_LENGTH = 11;\nconst SEALED_CHUNK_SIZE = CHUNK_SIZE + TAG_SIZE;\nconst PAYLOAD_KEY_LENGTH = 32;\nconst EMPTY_AAD: Uint8Array = new Uint8Array(0);\n\n// Authenticated-decryption failure of the stream: a chunk tag did not verify or\n// the chunk layout violates the format rules. Callers surface it as the single\n// generic decryption failure (the TAMPERED_CIPHERTEXT outcome).\nexport class StreamTamperedError extends Error {\n readonly code = 'TAMPERED_CIPHERTEXT' as const;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'StreamTamperedError';\n }\n}\n\n// Shared chunk-nonce state machine: an 11-byte big-endian counter followed by\n// the final-flag byte. The counter increments once per chunk; using a chunk\n// machine after its final chunk is a caller error, never silently accepted.\nclass ChunkNonce {\n private readonly nonce = new Uint8Array(NONCE_LENGTH);\n private finished = false;\n\n next(final: boolean): Uint8Array {\n if (this.finished) {\n throw new Error('STREAM: no chunks may follow the final chunk');\n }\n if (final) {\n this.finished = true;\n this.nonce[COUNTER_LENGTH] = 0x01;\n }\n const out = this.nonce.slice();\n this.increment();\n return out;\n }\n\n get done(): boolean {\n return this.finished;\n }\n\n private increment(): void {\n for (let i = COUNTER_LENGTH - 1; i >= 0; i--) {\n const v = ((this.nonce[i] as number) + 1) & 0xff;\n this.nonce[i] = v;\n if (v !== 0) return;\n }\n // 2^88 chunks exhausted — unreachable for any realisable payload.\n throw new Error('STREAM: chunk counter overflow');\n }\n}\n\nfunction assertPayloadKey(payloadKey: Uint8Array): void {\n if (payloadKey.length !== PAYLOAD_KEY_LENGTH) {\n throw new Error(\n `STREAM: payloadKey MUST be exactly ${PAYLOAD_KEY_LENGTH} bytes, got ${payloadKey.length}`,\n );\n }\n}\n\n// Incremental sealer. Feed plaintext chunk by chunk: every non-final chunk MUST\n// be exactly CHUNK_SIZE bytes; the final chunk carries 0..CHUNK_SIZE bytes, and\n// a zero-length final chunk is admissible only as the sole chunk of an empty\n// plaintext.\nexport class StreamSealer {\n private readonly payloadKey: Uint8Array;\n private readonly nonce = new ChunkNonce();\n private chunkIndex = 0;\n\n constructor(payloadKey: Uint8Array) {\n assertPayloadKey(payloadKey);\n this.payloadKey = payloadKey;\n }\n\n sealChunk(plaintext: Uint8Array, final: boolean): Uint8Array {\n if (!final && plaintext.length !== CHUNK_SIZE) {\n throw new Error(\n `STREAM: non-final chunk MUST carry exactly ${CHUNK_SIZE} plaintext bytes, got ${plaintext.length}`,\n );\n }\n if (final && plaintext.length > CHUNK_SIZE) {\n throw new Error(\n `STREAM: final chunk MUST carry at most ${CHUNK_SIZE} plaintext bytes, got ${plaintext.length}`,\n );\n }\n if (final && plaintext.length === 0 && this.chunkIndex > 0) {\n throw new Error(\n 'STREAM: a zero-length final chunk is admissible only for an empty plaintext',\n );\n }\n const sealed = chacha20Poly1305Encrypt({\n key: this.payloadKey,\n nonce: this.nonce.next(final),\n aad: EMPTY_AAD,\n plaintext,\n });\n this.chunkIndex += 1;\n return sealed;\n }\n}\n\n// Incremental opener. Feed sealed chunks in order with the expected final flag;\n// each chunk's plaintext is released only after its tag verifies (and is still\n// tentative until the caller's whole-plaintext hash recheck passes). Chunk\n// boundaries are the caller's responsibility in incremental use; `streamOpen`\n// derives them from the blob length.\nexport class StreamOpener {\n private readonly payloadKey: Uint8Array;\n private readonly nonce = new ChunkNonce();\n private chunkIndex = 0;\n\n constructor(payloadKey: Uint8Array) {\n assertPayloadKey(payloadKey);\n this.payloadKey = payloadKey;\n }\n\n openChunk(sealedChunk: Uint8Array, final: boolean): Uint8Array {\n if (sealedChunk.length < TAG_SIZE) {\n throw new StreamTamperedError(\n `STREAM: sealed chunk shorter than the ${TAG_SIZE}-byte tag floor`,\n );\n }\n if (!final && sealedChunk.length !== SEALED_CHUNK_SIZE) {\n throw new StreamTamperedError(\n `STREAM: non-final sealed chunk MUST be exactly ${SEALED_CHUNK_SIZE} bytes, got ${sealedChunk.length}`,\n );\n }\n if (final && sealedChunk.length > SEALED_CHUNK_SIZE) {\n throw new StreamTamperedError(\n `STREAM: final sealed chunk MUST be at most ${SEALED_CHUNK_SIZE} bytes, got ${sealedChunk.length}`,\n );\n }\n if (final && sealedChunk.length === TAG_SIZE && this.chunkIndex > 0) {\n throw new StreamTamperedError('STREAM: zero-length final chunk on a non-empty stream');\n }\n let plaintext: Uint8Array;\n try {\n plaintext = chacha20Poly1305Decrypt({\n key: this.payloadKey,\n nonce: this.nonce.next(final),\n aad: EMPTY_AAD,\n ciphertext: sealedChunk,\n });\n } catch (e) {\n if (!(e instanceof AeadVerificationError)) throw e;\n throw new StreamTamperedError(`STREAM: chunk ${this.chunkIndex} tag verification failed`, {\n cause: e,\n });\n }\n this.chunkIndex += 1;\n return plaintext;\n }\n}\n\n// Whole-buffer seal: split the plaintext into CHUNK_SIZE chunks (an empty\n// plaintext is exactly one zero-length final chunk) and concatenate the sealed\n// chunks.\nexport function streamSeal(args: { payloadKey: Uint8Array; plaintext: Uint8Array }): Uint8Array {\n const { plaintext } = args;\n const sealer = new StreamSealer(args.payloadKey);\n const chunkCount = Math.max(1, Math.ceil(plaintext.length / CHUNK_SIZE));\n const out = new Uint8Array(plaintext.length + chunkCount * TAG_SIZE);\n let offset = 0;\n for (let i = 0; i < chunkCount; i++) {\n const final = i === chunkCount - 1;\n const chunk = plaintext.subarray(\n i * CHUNK_SIZE,\n Math.min((i + 1) * CHUNK_SIZE, plaintext.length),\n );\n const sealed = sealer.sealChunk(chunk, final);\n out.set(sealed, offset);\n offset += sealed.length;\n }\n return out;\n}\n\n// Whole-buffer open. The chunk boundaries are fully determined by the blob\n// length: every non-final sealed chunk is exactly SEALED_CHUNK_SIZE bytes and\n// the final sealed chunk is whatever remains (TAG_SIZE..SEALED_CHUNK_SIZE). A\n// blob below the 16-byte floor, a tail that cannot form a well-formed final\n// chunk, or a zero-length final chunk on a non-empty stream is malformed before\n// any tag is checked. Truncation that removes the final chunk leaves a stream\n// whose last chunk was sealed with the 0x00 flag but is opened with the 0x01\n// flag nonce, so its tag fails — the final-flag byte is the truncation\n// detector.\nexport function streamOpen(args: { payloadKey: Uint8Array; ciphertext: Uint8Array }): Uint8Array {\n const { ciphertext } = args;\n const total = ciphertext.length;\n if (total < TAG_SIZE) {\n throw new StreamTamperedError(\n `STREAM: ciphertext shorter than the ${TAG_SIZE}-byte single-tag floor`,\n );\n }\n const rem = total % SEALED_CHUNK_SIZE;\n let nonFinalCount: number;\n let finalSealedLength: number;\n if (rem === 0) {\n nonFinalCount = total / SEALED_CHUNK_SIZE - 1;\n finalSealedLength = SEALED_CHUNK_SIZE;\n } else if (rem >= TAG_SIZE) {\n nonFinalCount = (total - rem) / SEALED_CHUNK_SIZE;\n finalSealedLength = rem;\n } else {\n throw new StreamTamperedError('STREAM: trailing bytes cannot form a well-formed final chunk');\n }\n if (nonFinalCount > 0 && finalSealedLength === TAG_SIZE) {\n throw new StreamTamperedError('STREAM: zero-length final chunk on a non-empty stream');\n }\n\n const opener = new StreamOpener(args.payloadKey);\n const out = new Uint8Array(nonFinalCount * CHUNK_SIZE + finalSealedLength - TAG_SIZE);\n let readOffset = 0;\n let writeOffset = 0;\n for (let i = 0; i < nonFinalCount; i++) {\n const plaintext = opener.openChunk(\n ciphertext.subarray(readOffset, readOffset + SEALED_CHUNK_SIZE),\n false,\n );\n out.set(plaintext, writeOffset);\n readOffset += SEALED_CHUNK_SIZE;\n writeOffset += CHUNK_SIZE;\n }\n const finalPlaintext = opener.openChunk(ciphertext.subarray(readOffset), true);\n out.set(finalPlaintext, writeOffset);\n return out;\n}\n","// Shared, byte-critical pieces of the sealed-PoE construction that the producer\n// (wrap / passphrase seal) and every verifier (unwrap, trial-decrypt,\n// passphrase open) MUST compute byte-for-byte identically:\n//\n// 1. The item-hashes digest `hashes_hash`.\n// 2. The slots transcript, its SHA-256 `slots_hash`, and the CEK-keyed\n// `slots_mac`.\n// 3. The passphrase transcript, its SHA-256 `pw_hash`, and the CEK-keyed\n// in-ciphertext `commitment`.\n// 4. The content `payload_key` derivations (both key paths).\n// 5. Both per-slot KEK HKDF salts (classical and hybrid).\n//\n// Keeping these in one module is the interop guarantee: a single divergence in\n// the canonical encoding silently yields a `slots_mac`, a commitment, or an\n// AEAD tag that another implementation cannot reproduce, with no typed error to\n// localise the fault. There is exactly one shared implementation, imported by\n// both sides.\n\nimport { hmac } from '@noble/hashes/hmac.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { encodeCanonicalCbor, type CanonicalCborValue } from '../cbor/canonical';\nimport { hkdfSha256 } from '../kdf/hkdf';\n\nimport { EciesSealedPoeError } from './errors';\nimport type { Mlkem768X25519Slot, SealedKem, X25519Slot } from './wrap';\n\n// Internal domain-separation labels. Each is exact ASCII with no terminator and\n// no length prefix; each is a fixed constant of the scheme, never serialised on\n// the wire and never registry-selectable. The byte-length invariants below keep\n// the SCREAMING_SNAKE constants in sync with the ASCII literals every conformant\n// verifier hashes against.\n\n// SHA-256 prefix for the item-hashes digest `hashes_hash`.\nexport const CARDANO_POE_ITEM_HASHES_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-item-hashes-v1',\n);\n// SHA-256 prefix for the slots-transcript hash `slots_hash`.\nexport const CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-slots-transcript-v1',\n);\n// SHA-256 prefix for the passphrase-transcript hash `pw_hash`.\nexport const CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-passphrase-transcript-v1',\n);\n// HKDF info for the slot-set MAC key.\nexport const CARDANO_POE_HKDF_INFO_SLOTS_MAC: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-slots-mac-v1',\n);\n// HKDF info for the passphrase commitment MAC key.\nexport const CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-passphrase-mac-v1',\n);\n// HKDF info for the slots-path content `payload_key`.\nexport const CARDANO_POE_HKDF_INFO_PAYLOAD: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-payload-v1',\n);\n// HKDF info for the passphrase-path content `payload_key`.\nexport const CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-payload-passphrase-v1',\n);\n// SHA-256 prefix for the classical (x25519) per-slot KEK HKDF salt.\nexport const CARDANO_POE_X25519_KEK_SALT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-x25519-kek-salt-v1',\n);\n// SHA-256 prefix for the hybrid (X-Wing) per-slot KEK HKDF salt.\nexport const CARDANO_POE_XWING_KEK_SALT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-xwing-kek-salt-v1',\n);\n\nif (CARDANO_POE_ITEM_HASHES_PREFIX.length !== 26) {\n throw new Error('CARDANO_POE_ITEM_HASHES_PREFIX byte-length invariant violated (expected 26)');\n}\nif (CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX.length !== 31) {\n throw new Error(\n 'CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX byte-length invariant violated (expected 31)',\n );\n}\nif (CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX.length !== 36) {\n throw new Error(\n 'CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX byte-length invariant violated (expected 36)',\n );\n}\nif (CARDANO_POE_HKDF_INFO_SLOTS_MAC.length !== 24) {\n throw new Error('CARDANO_POE_HKDF_INFO_SLOTS_MAC byte-length invariant violated (expected 24)');\n}\nif (CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC.length !== 29) {\n throw new Error(\n 'CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC byte-length invariant violated (expected 29)',\n );\n}\nif (CARDANO_POE_HKDF_INFO_PAYLOAD.length !== 22) {\n throw new Error('CARDANO_POE_HKDF_INFO_PAYLOAD byte-length invariant violated (expected 22)');\n}\nif (CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE.length !== 33) {\n throw new Error(\n 'CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE byte-length invariant violated (expected 33)',\n );\n}\nif (CARDANO_POE_X25519_KEK_SALT_PREFIX.length !== 30) {\n throw new Error(\n 'CARDANO_POE_X25519_KEK_SALT_PREFIX byte-length invariant violated (expected 30)',\n );\n}\nif (CARDANO_POE_XWING_KEK_SALT_PREFIX.length !== 29) {\n throw new Error('CARDANO_POE_XWING_KEK_SALT_PREFIX byte-length invariant violated (expected 29)');\n}\n\n// Scheme-fixed constant pinning the passphrase normalization profile the CEK was\n// derived under. Fed into the passphrase transcript; never serialised on the\n// wire.\nexport const CARDANO_POE_PW_NORM_PROFILE = 'cardano-poe-pw-norm-v1' as const;\n\n// Verifier-side resource bounds a public parser MUST enforce BEFORE invoking any\n// KEM/AEAD primitive, so a malformed envelope cannot drive unbounded work. Both\n// are deployment-pinned reference constants (not wire fields); deployments MAY\n// tighten them. They sit far above the ~16 KiB Cardano transaction-metadata\n// ceiling that bounds honest records, so a conformant record never trips them.\n//\n// • MAX_SLOTS — the maximum slot count; an envelope with more slots is\n// rejected outright.\n// • MAX_DECODED_ENVELOPE_BYTES — a backstop on the decoded envelope's\n// aggregate byte size (nonce + slots_mac + every per-slot wire field),\n// bounding the work even before the slot-count cap would.\nexport const MAX_SLOTS = 1024;\nexport const MAX_DECODED_ENVELOPE_BYTES = 65536;\n\nconst EMPTY_SALT: Uint8Array = new Uint8Array(0);\n\n// The item's plaintext-hash claim: registered algorithm identifier → digest\n// bytes, exactly as carried in the record body. Both key paths bind this map\n// (via `hashes_hash`) into their commitment, so an envelope spliced onto an\n// item with a different hash claim is rejected before any ciphertext work.\nexport type ItemHashes = Readonly<Record<string, Uint8Array>>;\n\nfunction labelledSha256(prefix: Uint8Array, ...parts: ReadonlyArray<Uint8Array>): Uint8Array {\n let total = prefix.length;\n for (const p of parts) total += p.length;\n const message = new Uint8Array(total);\n message.set(prefix, 0);\n let offset = prefix.length;\n for (const p of parts) {\n message.set(p, offset);\n offset += p.length;\n }\n return sha256(message);\n}\n\n// SHA-256(\"cardano-poe-item-hashes-v1\" || canonicalEncode(item.hashes)).\n// The hashes map is encoded exactly as it appears in the record body\n// (registry-identifier keys → digest byte strings, canonical key order). An\n// `enc`-bearing item MUST declare at least one content hash — the ciphertext is\n// bound to the plaintext only through that digest — so an empty map is rejected\n// here, on both the producer and the verifier side.\nexport function itemHashesHash(hashes: ItemHashes): Uint8Array {\n if (Object.keys(hashes).length === 0) {\n throw new EciesSealedPoeError(\n 'ENC_REQUIRES_CONTENT_HASH',\n 'hashes MUST carry at least one content-hash entry',\n );\n }\n return labelledSha256(CARDANO_POE_ITEM_HASHES_PREFIX, encodeCanonicalCbor(hashes));\n}\n\n// SHA-256(\"cardano-poe-slots-transcript-v1\" || canonicalEncode(SLOTS_TRANSCRIPT)).\n// SLOTS_TRANSCRIPT is the closed seven-key map binding the cross-KEM header\n// fields (scheme, path, aead, kem, nonce) and the item's hash claim\n// (hashes_hash) to the on-wire slot set, so a relay that flips any header field\n// — or splices the envelope onto a different item — yields a different\n// `slots_hash` and the MAC fails. Computed ONCE per envelope and held constant\n// across the recipient trial-decrypt loop. The map keys are a SET — their wire\n// order is fixed by the canonical-encode sort, never hand-arranged here.\nexport function computeSlotsHash(args: {\n aead: string;\n kem: SealedKem;\n nonce: Uint8Array;\n slots: ReadonlyArray<X25519Slot | Mlkem768X25519Slot>;\n hashesHash: Uint8Array;\n}): Uint8Array {\n // The slot array is re-stated as explicit closed two-key maps (never the raw\n // caller objects), so an extra property on a caller's slot value can never\n // leak into the committed bytes.\n const slots: CanonicalCborValue =\n args.kem === 'x25519'\n ? (args.slots as ReadonlyArray<X25519Slot>).map((s) => ({ epk: s.epk, wrap: s.wrap }))\n : (args.slots as ReadonlyArray<Mlkem768X25519Slot>).map((s) => ({\n kem_ct: s.kem_ct,\n wrap: s.wrap,\n }));\n const transcript: CanonicalCborValue = {\n scheme: 1,\n path: 'slots',\n aead: args.aead,\n kem: args.kem,\n nonce: args.nonce,\n slots,\n hashes_hash: args.hashesHash,\n };\n return labelledSha256(CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX, encodeCanonicalCbor(transcript));\n}\n\n// SHA-256(\"cardano-poe-passphrase-transcript-v1\" || canonicalEncode(PASSPHRASE_TRANSCRIPT)).\n// PASSPHRASE_TRANSCRIPT is the closed six-key map (with `passphrase` itself a\n// closed sub-map) binding the header fields, the Argon2id parameters, the\n// normalization profile, and the item's hash claim into the in-ciphertext\n// commitment. There is NO `kem` key on this path. The `normalization` value is\n// the scheme-fixed profile constant, pinned into the transcript and never\n// serialised on the wire.\nexport function computePassphraseHash(args: {\n aead: string;\n nonce: Uint8Array;\n hashesHash: Uint8Array;\n salt: Uint8Array;\n params: { m: number; t: number; p: number };\n}): Uint8Array {\n const transcript: CanonicalCborValue = {\n scheme: 1,\n path: 'passphrase',\n aead: args.aead,\n nonce: args.nonce,\n hashes_hash: args.hashesHash,\n passphrase: {\n alg: 'argon2id',\n salt: args.salt,\n params: { m: args.params.m, t: args.params.t, p: args.params.p },\n normalization: CARDANO_POE_PW_NORM_PROFILE,\n },\n };\n return labelledSha256(CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX, encodeCanonicalCbor(transcript));\n}\n\n// Slot-set MAC: HMAC-SHA-256 keyed by an HKDF leaf of the CEK over the 32-byte\n// `slots_hash`. Pre-hashing the transcript only changes the HMAC message from\n// the full transcript to its SHA-256, leaving the CEK-keyed commitment intact.\n// The fixed 32-byte HKDF key structurally excludes the HMAC over-block-length\n// key ambiguity.\nexport function computeSlotsMac(args: { cek: Uint8Array; slotsHash: Uint8Array }): Uint8Array {\n const macKey = hkdfSha256({\n ikm: args.cek,\n salt: EMPTY_SALT,\n info: CARDANO_POE_HKDF_INFO_SLOTS_MAC,\n length: 32,\n });\n return hmac(sha256, macKey, args.slotsHash);\n}\n\n// Passphrase-path key commitment: HMAC-SHA-256 keyed by an HKDF leaf of the CEK\n// over the 32-byte `pw_hash`. Prepended inside the ciphertext blob (never an\n// on-chain field), so testing a passphrase guess requires possession of the\n// blob itself.\nexport function computePassphraseCommitment(args: {\n cek: Uint8Array;\n pwHash: Uint8Array;\n}): Uint8Array {\n const macKey = hkdfSha256({\n ikm: args.cek,\n salt: EMPTY_SALT,\n info: CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC,\n length: 32,\n });\n return hmac(sha256, macKey, args.pwHash);\n}\n\n// Slots-path content key: HKDF-SHA-256(ikm=CEK, salt=enc.nonce, info=payload-v1).\n// The content is encrypted under this leaf of the CEK, never under the CEK\n// directly, so the wrap layer and the content layer never key the same primitive\n// on the same bytes. The envelope-unique nonce salt makes the key single-use,\n// which is what keeps the STREAM counter nonces collision-free.\nexport function slotsPayloadKey(args: { cek: Uint8Array; nonce: Uint8Array }): Uint8Array {\n return hkdfSha256({\n ikm: args.cek,\n salt: args.nonce,\n info: CARDANO_POE_HKDF_INFO_PAYLOAD,\n length: 32,\n });\n}\n\n// Passphrase-path content key: HKDF-SHA-256(ikm=CEK, salt=enc.nonce,\n// info=payload-passphrase-v1).\nexport function passphrasePayloadKey(args: { cek: Uint8Array; nonce: Uint8Array }): Uint8Array {\n return hkdfSha256({\n ikm: args.cek,\n salt: args.nonce,\n info: CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE,\n length: 32,\n });\n}\n\n// Classical (x25519) per-slot KEK salt:\n// SHA-256(\"cardano-poe-x25519-kek-salt-v1\" || enc.nonce || epk || pub_R).\n// The slot's own ephemeral anchors the KEK to a slot-unique value, `pub_R`\n// binds it to the specific recipient (defeating confused-deputy relay of the\n// ephemeral against a different recipient), and the envelope-unique `enc.nonce`\n// anchors it to one envelope — a CSPRNG failure that repeats KEM randomness\n// across records degrades to mere linkability instead of reproducing a\n// (KEK, zero-nonce) wrap pair.\nexport function x25519KekSalt(args: {\n nonce: Uint8Array;\n epk: Uint8Array;\n pubR: Uint8Array;\n}): Uint8Array {\n return labelledSha256(CARDANO_POE_X25519_KEK_SALT_PREFIX, args.nonce, args.epk, args.pubR);\n}\n\n// Hybrid (mlkem768x25519) per-slot KEK salt:\n// SHA-256(\"cardano-poe-xwing-kek-salt-v1\" || enc.nonce || kem_ct || pub_R).\n// `kem_ct` is the slot's 1120-byte X-Wing ciphertext exactly as carried on the\n// wire and `pub_R` the 1216-byte X-Wing recipient public key — the same three\n// bindings as the classical salt, computed outside the KEM over the slot's own\n// wire bytes so it holds X-Wing as a black box.\nexport function xwingKekSalt(args: {\n nonce: Uint8Array;\n kemCt: Uint8Array;\n pubR: Uint8Array;\n}): Uint8Array {\n return labelledSha256(CARDANO_POE_XWING_KEK_SALT_PREFIX, args.nonce, args.kemCt, args.pubR);\n}\n","// Multi-recipient sealed-PoE wrap (age-style KEM-then-wrap slots + segmented\n// STREAM content). Wire-field names are fixed by the standard: scheme, aead,\n// kem, nonce, slots, slots_mac.\n//\n// Two KEM branches share one envelope shape, discriminated on the envelope-level\n// `kem` field:\n//\n// • kem: 'x25519' — classical age-style ECIES. Per-slot epk(32) + wrap(48).\n// • kem: 'mlkem768x25519' — X-Wing hybrid (ML-KEM-768 + X25519). Per-slot the\n// 1120-byte X-Wing ciphertext as a single byte\n// string (`kem_ct`) + wrap(48). No per-slot epk.\n//\n// The slot type is a discriminated union so every consumer is forced — at compile\n// time — to branch on the KEM before touching kem-specific fields.\n\nimport { randomBytes } from '@noble/ciphers/utils.js';\n\nimport { chacha20Poly1305Encrypt } from '../aead/chacha20-poly1305';\nimport {\n mlkem768x25519Encapsulate,\n MLKEM768X25519_ENC_LENGTH,\n MLKEM768X25519_ESEED_LENGTH,\n MLKEM768X25519_PUBLIC_KEY_LENGTH,\n} from '../kem/mlkem768x25519';\nimport { x25519Ecdh, x25519PublicKey } from '../kem/x25519';\nimport { hkdfSha256 } from '../kdf/hkdf';\n\nimport { EciesSealedPoeError } from './errors';\nimport { streamSeal } from './stream';\nimport {\n computeSlotsHash,\n computeSlotsMac,\n itemHashesHash,\n slotsPayloadKey,\n x25519KekSalt,\n xwingKekSalt,\n type ItemHashes,\n} from './transcript';\n\n// The envelope-level KEM discriminator.\nexport type SealedKem = 'x25519' | 'mlkem768x25519';\n\n// The sole registered content format under enc.scheme 1: ChaCha20-Poly1305 in\n// the 64 KiB segmented STREAM layout. Producers MUST emit this identifier\n// byte-exact.\nexport const SEALED_POE_AEAD = 'chacha20-poly1305-stream64k' as const;\n\n// HKDF info strings — fixed protocol labels for KEK derivation. Each doubles as\n// the per-slot wrap AEAD AAD (never empty AAD). Byte-length invariants enforce\n// that the SCREAMING_SNAKE constants stay in sync with the ASCII literals every\n// conformant verifier hashes against.\nexport const CARDANO_POE_HKDF_INFO_KEK: Uint8Array = new TextEncoder().encode('cardano-poe-kek-v1');\n// Hybrid (X-Wing) per-slot KEK label. Distinct from the classical label so a\n// KEK derived under one KEM can never collide with the other.\nexport const CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-kek-mlkem768x25519-v1',\n);\n\nconst ZERO_NONCE_12: Uint8Array = new Uint8Array(12);\nconst X25519_PUBLIC_KEY_LENGTH = 32 as const;\nconst X25519_SECRET_KEY_LENGTH = 32 as const;\nconst CEK_LENGTH = 32 as const;\nconst NONCE_LENGTH = 24 as const;\nconst WRAP_LENGTH = 48 as const;\nconst SLOTS_MAC_LENGTH = 32 as const;\n\nif (CARDANO_POE_HKDF_INFO_KEK.length !== 18) {\n throw new Error('CARDANO_POE_HKDF_INFO_KEK byte-length invariant violated (expected 18)');\n}\nif (CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519.length !== 33) {\n throw new Error(\n 'CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519 byte-length invariant violated (expected 33)',\n );\n}\nif (ZERO_NONCE_12.length !== 12) {\n throw new Error('ZERO_NONCE_12 byte-length invariant violated (expected 12)');\n}\n\n// Classical per-slot wire shape: { epk: bstr(32), wrap: bstr(48) }.\nexport interface X25519Slot {\n readonly epk: Uint8Array;\n readonly wrap: Uint8Array;\n}\n\n// Hybrid per-slot wire shape: { kem_ct: bstr(1120), wrap: bstr(48) }. `kem_ct`\n// is the X-Wing ciphertext as a single byte string. There is NO per-slot epk\n// (the X25519 ephemeral is the trailing 32 bytes of kem_ct) and NO per-slot kem\n// field — the KEM identifier is hoisted to envelope scope (every slot shares it).\nexport interface Mlkem768X25519Slot {\n readonly kem_ct: Uint8Array;\n readonly wrap: Uint8Array;\n}\n\n// Sealed envelope wire shape (discriminated on `kem`).\nexport type SealedEnvelope =\n | {\n readonly scheme: 1;\n readonly aead: typeof SEALED_POE_AEAD;\n readonly kem: 'x25519';\n readonly nonce: Uint8Array;\n readonly slots: ReadonlyArray<X25519Slot>;\n readonly slots_mac: Uint8Array;\n }\n | {\n readonly scheme: 1;\n readonly aead: typeof SEALED_POE_AEAD;\n readonly kem: 'mlkem768x25519';\n readonly nonce: Uint8Array;\n readonly slots: ReadonlyArray<Mlkem768X25519Slot>;\n readonly slots_mac: Uint8Array;\n };\n\nexport interface SealedPoeOutput {\n readonly envelope: SealedEnvelope;\n readonly ciphertext: Uint8Array;\n}\n\nexport interface WrapArgs {\n readonly plaintext: Uint8Array;\n // The item's plaintext-hash claim (registered algorithm id → digest bytes).\n // Its labelled digest is bound into the slots transcript, so the on-chain\n // slots_mac match also confirms the envelope belongs to this hash claim.\n readonly hashes: ItemHashes;\n readonly recipientPublicKeys: ReadonlyArray<Uint8Array>;\n // KEM branch selector. Defaults to 'x25519' for the classical path. The\n // recipient public-key length is validated against the chosen KEM.\n readonly kem?: SealedKem;\n readonly cek?: Uint8Array;\n readonly nonce?: Uint8Array;\n // Deterministic X25519 ephemeral scalars — x25519 branch only.\n readonly ephemeralSecrets?: ReadonlyArray<Uint8Array>;\n // Deterministic X-Wing encapsulation randomness (64 bytes each) — hybrid\n // branch only. One per recipient, parallel to recipientPublicKeys.\n readonly eseeds?: ReadonlyArray<Uint8Array>;\n readonly skipShuffle?: boolean;\n}\n\n// Anonymity invariant: wire ordering MUST NOT encode \"primary\n// recipient first\". A CSPRNG-keyed Fisher-Yates shuffle uniformly permutes the\n// slot array so trial-decrypt order leaks no recipient identity. The\n// slot-set HMAC is computed AFTER this shuffle, binding the on-wire order.\n//\n// Draw an unbiased index in [0, m) from a CSPRNG uint32 via rejection sampling.\n// A plain `u32 % m` skews toward the low residues whenever `m` does not divide\n// 2^32 evenly: the values [0, 2^32 mod m) each occur one extra time. This\n// function exists purely to produce a UNIFORM permutation, so the bias — though\n// cryptographically negligible — is exactly the property we cannot tolerate.\n// We reject any draw landing in the final partial block [limit, 2^32) and\n// redraw, leaving only the residues that map uniformly onto [0, m).\n// Exported so the rejection-bound arithmetic can be asserted directly in tests\n// without relying on a flaky statistical-distribution check.\nexport function uniformIndexBelow(m: number): number {\n // 2^32 mod m, computed without overflowing the 32-bit space.\n const limit = 0x1_0000_0000 - (0x1_0000_0000 % m);\n const buf = new Uint32Array(1);\n let x: number;\n do {\n crypto.getRandomValues(buf);\n x = buf[0] as number;\n } while (x >= limit);\n return x % m;\n}\n\nfunction csprngShuffle<T>(arr: T[]): void {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = uniformIndexBelow(i + 1);\n const tmp = arr[i] as T;\n arr[i] = arr[j] as T;\n arr[j] = tmp;\n }\n}\n\n// Wrap the CEK for one classical recipient: age-style ECIES stanza with the\n// labelled-hash KEK salt binding nonce, epk, and pub_R.\nfunction wrapSlotX25519(args: {\n pubR: Uint8Array;\n privEph: Uint8Array | undefined;\n cek: Uint8Array;\n nonce: Uint8Array;\n slotIdx: number;\n}): X25519Slot {\n const privEph = args.privEph ?? randomBytes(X25519_SECRET_KEY_LENGTH);\n if (privEph.length !== X25519_SECRET_KEY_LENGTH) {\n throw new EciesSealedPoeError(\n 'INVALID_EPHEMERAL_SECRET_LENGTH',\n `ephemeralSecrets[${args.slotIdx}] MUST be exactly ${X25519_SECRET_KEY_LENGTH} bytes, got ${privEph.length}`,\n );\n }\n const epk = x25519PublicKey({ secretKey: privEph });\n const shared = x25519Ecdh({ secretKey: privEph, theirPublicKey: args.pubR });\n const kek = hkdfSha256({\n ikm: shared,\n salt: x25519KekSalt({ nonce: args.nonce, epk, pubR: args.pubR }),\n info: CARDANO_POE_HKDF_INFO_KEK,\n length: 32,\n });\n // Per-slot wrap AAD MUST be the 18-byte ASCII literal of the KEK info\n // string (never empty AAD).\n const wrap = chacha20Poly1305Encrypt({\n key: kek,\n nonce: ZERO_NONCE_12,\n aad: CARDANO_POE_HKDF_INFO_KEK,\n plaintext: args.cek,\n });\n if (wrap.length !== WRAP_LENGTH) {\n throw new Error(`internal: wrap.length=${wrap.length}, expected ${WRAP_LENGTH}`);\n }\n return { epk, wrap };\n}\n\n// Wrap the CEK for one hybrid recipient: X-Wing encapsulation → HKDF → AEAD.\n// The KEK info label doubles as the wrap AEAD AAD, mirroring the classical path.\nfunction wrapSlotMlkem768X25519(args: {\n pubR: Uint8Array;\n eseed: Uint8Array | undefined;\n cek: Uint8Array;\n nonce: Uint8Array;\n}): Mlkem768X25519Slot {\n const { enc, ss } = mlkem768x25519Encapsulate({\n publicKey: args.pubR,\n ...(args.eseed !== undefined ? { eseed: args.eseed } : {}),\n });\n if (enc.length !== MLKEM768X25519_ENC_LENGTH) {\n throw new Error(`internal: enc.length=${enc.length}, expected ${MLKEM768X25519_ENC_LENGTH}`);\n }\n // The hybrid KEK salt binds the envelope nonce, the slot's own X-Wing\n // ciphertext, and the recipient public key, mirroring the classical salt: the\n // ciphertext anchors the KEK to a slot-unique value and `pub_R` binds it to\n // the specific recipient. It is computed outside the KEM, over the slot's wire\n // bytes, so it holds X-Wing as a black-box KEM.\n const kek = hkdfSha256({\n ikm: ss,\n salt: xwingKekSalt({ nonce: args.nonce, kemCt: enc, pubR: args.pubR }),\n info: CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519,\n length: 32,\n });\n const wrap = chacha20Poly1305Encrypt({\n key: kek,\n nonce: ZERO_NONCE_12,\n aad: CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519,\n plaintext: args.cek,\n });\n if (wrap.length !== WRAP_LENGTH) {\n throw new Error(`internal: wrap.length=${wrap.length}, expected ${WRAP_LENGTH}`);\n }\n return { kem_ct: enc, wrap };\n}\n\nexport function eciesSealedPoeWrap(args: WrapArgs): SealedPoeOutput {\n const { plaintext, recipientPublicKeys } = args;\n const kem: SealedKem = args.kem ?? 'x25519';\n const n = recipientPublicKeys.length;\n\n // The hash-claim digest is computed before any KEM/AEAD work: an item without\n // a content hash cannot be sealed (the ciphertext is bound to the plaintext\n // only through that digest).\n const hashesHash = itemHashesHash(args.hashes);\n\n // There is no fixed upper bound on slot count; the producer SDK polices the\n // per-record byte budget. Only the lower bound is enforced here.\n if (n < 1) {\n throw new EciesSealedPoeError(\n 'ENC_SLOTS_EMPTY',\n `recipientPublicKeys.length=${n} must be >= 1`,\n );\n }\n\n const expectedPubLen =\n kem === 'x25519' ? X25519_PUBLIC_KEY_LENGTH : MLKEM768X25519_PUBLIC_KEY_LENGTH;\n for (let i = 0; i < n; i++) {\n const pub = recipientPublicKeys[i];\n if (pub === undefined || pub.length !== expectedPubLen) {\n throw new EciesSealedPoeError(\n 'KEM_EPK_LENGTH_MISMATCH',\n `recipientPublicKeys[${i}] MUST be exactly ${expectedPubLen} bytes for kem='${kem}'`,\n );\n }\n }\n\n if (kem === 'x25519') {\n if (args.eseeds !== undefined) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n \"eseeds is an X-Wing (mlkem768x25519) override and MUST NOT be supplied for kem='x25519'\",\n );\n }\n if (args.ephemeralSecrets !== undefined && args.ephemeralSecrets.length !== n) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n `ephemeralSecrets.length=${args.ephemeralSecrets.length} must match recipientPublicKeys.length=${n}`,\n );\n }\n } else {\n if (args.ephemeralSecrets !== undefined) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n \"ephemeralSecrets is an X25519 override and MUST NOT be supplied for kem='mlkem768x25519'\",\n );\n }\n if (args.eseeds !== undefined) {\n if (args.eseeds.length !== n) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n `eseeds.length=${args.eseeds.length} must match recipientPublicKeys.length=${n}`,\n );\n }\n for (let i = 0; i < n; i++) {\n const eseed = args.eseeds[i]!;\n if (eseed.length !== MLKEM768X25519_ESEED_LENGTH) {\n throw new EciesSealedPoeError(\n 'INVALID_EPHEMERAL_SECRET_LENGTH',\n `eseeds[${i}] MUST be exactly ${MLKEM768X25519_ESEED_LENGTH} bytes, got ${eseed.length}`,\n );\n }\n }\n }\n }\n\n const cek = args.cek ?? randomBytes(CEK_LENGTH);\n const nonce = args.nonce ?? randomBytes(NONCE_LENGTH);\n if (cek.length !== CEK_LENGTH) {\n throw new EciesSealedPoeError(\n 'INVALID_CEK_LENGTH',\n `cek MUST be exactly ${CEK_LENGTH} bytes, got ${cek.length}`,\n );\n }\n if (nonce.length !== NONCE_LENGTH) {\n throw new EciesSealedPoeError(\n 'NONCE_LENGTH_MISMATCH',\n `nonce MUST be exactly ${NONCE_LENGTH} bytes, got ${nonce.length}`,\n );\n }\n\n let envelope: SealedEnvelope;\n if (kem === 'x25519') {\n const slots: X25519Slot[] = [];\n for (let i = 0; i < n; i++) {\n slots.push(\n wrapSlotX25519({\n pubR: recipientPublicKeys[i]!,\n privEph: args.ephemeralSecrets ? (args.ephemeralSecrets[i] as Uint8Array) : undefined,\n cek,\n nonce,\n slotIdx: i,\n }),\n );\n }\n // Anonymity invariant (see csprngShuffle comment). The transcript is built\n // AFTER the shuffle so the MAC binds the on-wire slot order.\n if (args.skipShuffle !== true) {\n csprngShuffle(slots);\n }\n const slotsHash = computeSlotsHash({\n aead: SEALED_POE_AEAD,\n kem: 'x25519',\n nonce,\n slots,\n hashesHash,\n });\n envelope = {\n scheme: 1,\n aead: SEALED_POE_AEAD,\n kem: 'x25519',\n nonce,\n slots,\n slots_mac: sizedSlotsMac(cek, slotsHash),\n };\n } else {\n const slots: Mlkem768X25519Slot[] = [];\n for (let i = 0; i < n; i++) {\n slots.push(\n wrapSlotMlkem768X25519({\n pubR: recipientPublicKeys[i]!,\n eseed: args.eseeds ? (args.eseeds[i] as Uint8Array) : undefined,\n cek,\n nonce,\n }),\n );\n }\n if (args.skipShuffle !== true) {\n csprngShuffle(slots);\n }\n const slotsHash = computeSlotsHash({\n aead: SEALED_POE_AEAD,\n kem: 'mlkem768x25519',\n nonce,\n slots,\n hashesHash,\n });\n envelope = {\n scheme: 1,\n aead: SEALED_POE_AEAD,\n kem: 'mlkem768x25519',\n nonce,\n slots,\n slots_mac: sizedSlotsMac(cek, slotsHash),\n };\n }\n\n // Content is encrypted under a derived `payload_key` (a separate HKDF leaf of\n // the CEK salted by the envelope-unique nonce), never under the CEK directly,\n // in the segmented STREAM format. There is no content AAD: the content binds\n // to the header transitively — payload_key derives from the CEK, and the CEK\n // is committed to the full header (including hashes_hash) by slots_mac.\n const ciphertext = streamSeal({\n payloadKey: slotsPayloadKey({ cek, nonce }),\n plaintext,\n });\n\n return { envelope, ciphertext };\n}\n\nfunction sizedSlotsMac(cek: Uint8Array, slotsHash: Uint8Array): Uint8Array {\n const slotsMac = computeSlotsMac({ cek, slotsHash });\n if (slotsMac.length !== SLOTS_MAC_LENGTH) {\n throw new Error(`internal: slots_mac.length=${slotsMac.length}, expected ${SLOTS_MAC_LENGTH}`);\n }\n return slotsMac;\n}\n","// cardano-poe-pw-norm-v1: the normative passphrase normalization profile.\n//\n// Two implementations MUST derive a byte-identical CEK from the same\n// passphrase, so the normalization applied before Argon2id is pinned, in\n// order:\n//\n// 1. Bound the raw input (a pre-KDF denial-of-service backstop).\n// 2. NFKC under the pinned Unicode 16.0.0 tables. Input the pinned tables\n// cannot normalize stably — an unpaired surrogate, or a code point that\n// Unicode 16.0 leaves unassigned (a later Unicode version may give it a\n// decomposition and silently change the derived key) — is rejected.\n// 3. Collapse every maximal run of White_Space characters to one U+0020.\n// 4. Trim leading/trailing U+0020.\n// 5. Reject the empty result — a whitespace-only passphrase normalizes to\n// zero bytes, which Argon2id would silently accept, keying the record to\n// a CEK any party can derive.\n// 6. UTF-8-encode; those bytes are the Argon2id password input.\n//\n// Every Unicode-sensitive step resolves against the pinned Unicode 16.0.0\n// data — the NFKC tables and the White_Space property both — never the host\n// engine, whose tables float with its Unicode version.\n\nimport { Nfkc16Error, isWhiteSpace16, nfkc16 } from '../unicode/nfkc16';\nimport { EciesSealedPoeError } from './errors';\n\n// Reference bound on the RAW UTF-8 byte length of a passphrase, enforced before\n// any normalization or hashing work. A deployment-pinned constant, not a wire\n// field; deployments MAY tighten it.\nexport const MAX_PASSPHRASE_INPUT_BYTES = 4096;\n\nconst UTF8 = new TextEncoder();\n\n// One code-point pass implementing profile steps 3 + 4: each maximal\n// White_Space run becomes a single U+0020, and a leading or trailing run is\n// dropped entirely (never emitted), which is exactly collapse-then-trim.\n// `isWhiteSpace16` is the pinned Unicode 16.0 White_Space property —\n// deliberately NOT JavaScript's `\\s`, which also matches U+FEFF, a character\n// the property (and therefore the profile) does not treat as whitespace.\nfunction collapseAndTrimWhiteSpace(input: string): string {\n let out = '';\n let pendingRun = false;\n for (const ch of input) {\n if (isWhiteSpace16(ch.codePointAt(0) as number)) {\n pendingRun = true;\n continue;\n }\n if (pendingRun && out.length > 0) {\n out += ' ';\n }\n pendingRun = false;\n out += ch;\n }\n return out;\n}\n\n// Apply the cardano-poe-pw-norm-v1 profile and return the exact Argon2id\n// password bytes. Throws PASSPHRASE_INPUT_TOO_LONG when the raw input exceeds\n// the pre-normalization bound, ENC_PASSPHRASE_UNNORMALIZABLE when the input\n// cannot normalize stably under Unicode 16.0 (an unpaired surrogate or an\n// unassigned code point), and ENC_PASSPHRASE_EMPTY when the normalized result\n// is the empty string.\nexport function normalizePassphrase(passphrase: string): Uint8Array {\n const rawBytes = UTF8.encode(passphrase);\n if (rawBytes.length > MAX_PASSPHRASE_INPUT_BYTES) {\n throw new EciesSealedPoeError(\n 'PASSPHRASE_INPUT_TOO_LONG',\n `passphrase raw UTF-8 length ${rawBytes.length} exceeds MAX_PASSPHRASE_INPUT_BYTES=${MAX_PASSPHRASE_INPUT_BYTES}`,\n );\n }\n let folded: string;\n try {\n folded = nfkc16(passphrase);\n } catch (error) {\n if (error instanceof Nfkc16Error) {\n throw new EciesSealedPoeError('ENC_PASSPHRASE_UNNORMALIZABLE', error.message, {\n cause: error,\n });\n }\n throw error;\n }\n const normalized = collapseAndTrimWhiteSpace(folded);\n if (normalized.length === 0) {\n throw new EciesSealedPoeError(\n 'ENC_PASSPHRASE_EMPTY',\n 'passphrase normalizes to the empty string',\n );\n }\n return UTF8.encode(normalized);\n}\n","// Label 309 v1 structural validator (the Part A structural-validation role).\n//\n// Pure function over the reassembled CBOR record body — performs no I/O,\n// opens no socket, verifies no signature cryptographically, decodes no\n// ciphertext. Chain resolution, URI fetching, decryption, and\n// confirmation-depth checks are the verifier's concern (the Part B role).\n// The transport chunk array is reassembled BEFORE this function runs (see\n// `carriage.ts`); the carriage codes (`CHUNK_TOO_LARGE`, the transport\n// `MALFORMED_CBOR` reuse) are emitted by that step, not here.\n//\n// Pipeline:\n// Step 1 Canonical CBOR decode — `decodeCanonicalCbor` surfaces malformed /\n// non-canonical / duplicate-key / indefinite-length inputs as the\n// single MALFORMED_CBOR code.\n// Step 2 Schema parse — the closed Zod shapes in `./schema.ts`; the mapper\n// below lifts each Zod issue to its canonical structural code.\n// Step 3 Domain checks — cross-field rules, registry membership, URI shape\n// (the offline CID profile), the encryption-envelope union\n// (typed scheme-1 vs the degrade-to-opaque reading), `sigs[i]`\n// COSE_Sign1 structural decode, `crit[]` shape, exact-integer\n// range enforcement.\n// Step 4 Result emission — every collected issue is sorted (path\n// segment-wise, registry-order tie-break) and the record is valid\n// iff no error-severity issue is present.\n//\n// The validator NEVER throws — failure paths route through the discriminated\n// `ValidationResult` union so callers handle errors as data, and its output\n// is deterministic for any given `(bytes, options)` pair.\n\nimport { z } from 'zod';\n\nimport {\n decodeCanonicalCbor,\n encodeCanonicalCbor,\n type CanonicalCborValue,\n} from '@cardanowall/crypto-core/cbor';\nimport { CoseVerifyError, decodeCoseSign1 } from '@cardanowall/crypto-core/cose';\n// The verifier resource bounds the sealed-PoE unwrap layer enforces. Importing\n// the same constants, rather than re-declaring them, makes the structural\n// validator and the unwrap layer default to identical thresholds. Both are\n// deployment-pinned reference values, not wire fields — `ValidatorOptions`\n// overrides them per deployment.\nimport { MAX_DECODED_ENVELOPE_BYTES, MAX_SLOTS } from '@cardanowall/crypto-core/sealed-poe';\n\nimport { SEVERITY, errorCodeRegistryIndex, type ErrorCode, type Severity } from './error-codes';\nimport {\n EncScheme1Schema,\n isExtensionKey,\n PoeRecordSchema,\n TOP_LEVEL_BASE_KEYS,\n type EncScheme1,\n type ItemEntry,\n type MerkleCommit,\n type PassphraseBlock,\n type PoeRecord,\n type SigEntry,\n type Slot,\n} from './schema';\n\n// =============================================================================\n// Registries (closed catalogue of this implementation)\n// =============================================================================\n\n// Content-hash algorithm registry. Map value = digest length.\nconst HASH_ALG_LENGTHS: Readonly<Record<string, number>> = {\n 'sha2-256': 32,\n 'blake2b-256': 32,\n};\n\n// Merkle list-commitment algorithm registry. Map value = root length.\nconst MERKLE_COMMIT_ALG_LENGTHS: Readonly<Record<string, number>> = {\n 'rfc9162-sha256': 32,\n};\n\n// Content-format (AEAD) registry. Value = the registered `enc.nonce` length.\nconst AEAD_NONCE_LENGTHS: Readonly<Record<string, number>> = {\n 'chacha20-poly1305-stream64k': 24,\n};\n\n// Unauthenticated-cipher family. An `enc.aead` naming any of these is rejected\n// with `UNAUTHENTICATED_CIPHER_FORBIDDEN` in EVERY role — a forbidden\n// primitive is a recognised hazard, not an unknown identifier, so it never\n// takes the degrade-to-opaque reading. Two arms:\n// - block-cipher modes with no integrity (`cbc`, `ctr`, `ecb`, `cfb`,\n// `ofb`) appearing as a delimited token, matching every key-size spelling\n// (`aes-cbc`, `aes-256-cbc`, `des-ede3-cbc`, …);\n// - legacy stream/block ciphers as a leading token (`rc4`, `des`, `3des`).\n// The token delimiters keep authenticated AEADs (`aes-256-gcm`,\n// `chacha20-poly1305-stream64k`) from matching.\nconst UNAUTHENTICATED_CIPHER_RE =\n /(?:^|[-_])(?:cbc|ctr|ecb|cfb|ofb)(?:[-_]|$)|^(?:rc4|des|3des)(?:[-_]|$)/i;\n\n// KEM registry, expressed as a per-KEM slot DESCRIPTOR. Each registered KEM\n// pins the exact recipient-slot shape:\n//\n// - x25519: `{ epk: bstr(32), wrap: bstr(48) }` — classical\n// ephemeral-static X25519.\n// - mlkem768x25519: `{ kem_ct: bstr(1120), wrap: bstr(48) }` — the X-Wing\n// hybrid; the encapsulation is a SINGLE 1120-byte byte string and there\n// is NO per-slot `epk` (the X25519 ephemeral is the trailing 32 bytes of\n// `kem_ct`).\n//\n// A descriptor declares the slot's ciphertext-bearing field and its exact\n// byte length; `wrap` is 48 bytes for every KEM (32-byte CEK + 16-byte AEAD\n// tag). The validator branches on the descriptor so adding a future KEM is a\n// registry edit, not a new code path.\ntype KemSlotField = 'epk' | 'kem_ct';\ninterface KemSlotDescriptor {\n readonly field: KemSlotField;\n readonly fieldLength: number;\n readonly wrapLength: number;\n}\nconst KEM_SLOT_DESCRIPTORS: Readonly<Record<string, KemSlotDescriptor>> = {\n x25519: { field: 'epk', fieldLength: 32, wrapLength: 48 },\n mlkem768x25519: { field: 'kem_ct', fieldLength: 1120, wrapLength: 48 },\n};\n\nconst KEM_FIELD_LENGTH_CODE: Readonly<Record<KemSlotField, ErrorCode>> = {\n epk: 'KEM_EPK_LENGTH_MISMATCH',\n kem_ct: 'KEM_CT_LENGTH_MISMATCH',\n};\n\n// Passphrase KDF registry.\nconst PASSPHRASE_KDF_ALGS: ReadonlySet<string> = new Set(['argon2id']);\n\n// Signature-algorithm registry: COSE `alg` labels. `-8` (EdDSA, pinned to\n// Ed25519) is the mandatory baseline; `-19` (Ed25519 fully-specified) is\n// verified identically when accepted. Anything else is tagged\n// `SIGNATURE_UNSUPPORTED` (info-severity) — signatures are optional, so an\n// unrecognised algorithm never fails the record by itself.\nconst KNOWN_SIG_ALG_IDS: ReadonlySet<number> = new Set([-8, -19]);\n\n// Every numeric wire field is a CBOR unsigned integer pinned to this range\n// and handled as an EXACT integer (the canonical decoder surfaces values\n// above 2^53 − 1 as `bigint`, so no precision is ever lost before the range\n// check rejects).\nconst UINT32_MAX = 0xffff_ffff;\n\n// =============================================================================\n// Options\n// =============================================================================\n\nexport type ValidatorRole = 'public' | 'recipient_or_strict';\n\nexport interface Argon2ParamsCeiling {\n readonly m: number;\n readonly t: number;\n readonly p: number;\n}\n\n// The reference deployment ceiling on Argon2id work factors — a verifier-side\n// denial-of-service backstop (a 64 GiB `m` must not be able to stall a\n// decrypt-on-paste consumer), enforced by default and distinct from the\n// normative floors. Ceilings are deployment policy, not a wire rule: override\n// per deployment, or pass `passphraseParamsCeiling: null` to disable.\nexport const DEFAULT_PASSPHRASE_PARAMS_CEILING: Argon2ParamsCeiling = Object.freeze({\n m: 2_097_152, // KiB = 2 GiB\n t: 16,\n p: 8,\n});\n\nexport interface ValidatorOptions {\n /**\n * Names of the critical extensions this validator implements. Default: the\n * empty set — a default-configured validator therefore fails every\n * `crit`-bearing record with `EXTENSION_UNSUPPORTED_CRITICAL`, by design.\n */\n readonly supportedCriticalExtensions?: ReadonlySet<string>;\n /**\n * The validation reading for dual-severity envelope dispositions.\n * `public` (default): an envelope under an unsupported `scheme` / `kem` /\n * `aead` degrades to opaque and `ENC_UNSUPPORTED` is informational.\n * `recipient_or_strict` (the recipient verifier and strict sealed-crypto\n * mode): the same condition is a hard reject — `ENC_UNSUPPORTED` escalates\n * to `error` and co-fires with the identifier-specific `UNSUPPORTED_*`\n * code.\n */\n readonly role?: ValidatorRole;\n /** Slot-count resource bound (reference bound 1024; deployments MAY tighten). */\n readonly maxSlots?: number;\n /** Decoded-envelope byte resource bound (reference bound 65536). */\n readonly maxEncEnvelopeBytes?: number;\n /**\n * Upper policy ceiling on Argon2id parameters\n * (`ENC_PASSPHRASE_PARAMS_EXCEED_POLICY`). Defaults to\n * `DEFAULT_PASSPHRASE_PARAMS_CEILING`; `null` disables the ceiling.\n */\n readonly passphraseParamsCeiling?: Argon2ParamsCeiling | null;\n}\n\ninterface ResolvedOptions {\n readonly supportedCriticalExtensions: ReadonlySet<string>;\n readonly role: ValidatorRole;\n readonly maxSlots: number;\n readonly maxEncEnvelopeBytes: number;\n readonly passphraseParamsCeiling: Argon2ParamsCeiling | null;\n}\n\nconst EMPTY_EXTENSION_SET: ReadonlySet<string> = new Set();\n\nfunction resolveOptions(options?: ValidatorOptions): ResolvedOptions {\n return {\n supportedCriticalExtensions: options?.supportedCriticalExtensions ?? EMPTY_EXTENSION_SET,\n role: options?.role ?? 'public',\n maxSlots: options?.maxSlots ?? MAX_SLOTS,\n maxEncEnvelopeBytes: options?.maxEncEnvelopeBytes ?? MAX_DECODED_ENVELOPE_BYTES,\n passphraseParamsCeiling:\n options?.passphraseParamsCeiling === undefined\n ? DEFAULT_PASSPHRASE_PARAMS_CEILING\n : options.passphraseParamsCeiling,\n };\n}\n\n// =============================================================================\n// Result types\n// =============================================================================\n\nexport interface ValidationIssue {\n /**\n * Segments from the record root: text map keys and integer array indices\n * (e.g. `[\"items\", 0, \"hashes\", \"sha2-256\"]`). A dotted string is a display\n * rendering only — the segment list is the API form, so map keys containing\n * `.` need no escaping.\n */\n readonly path: ReadonlyArray<string | number>;\n readonly code: ErrorCode;\n readonly severity: Severity;\n readonly message: string;\n}\n\nexport type ValidationResult =\n | {\n readonly valid: true;\n readonly record: PoeRecord;\n readonly warnings?: ReadonlyArray<ValidationIssue>;\n readonly info?: ReadonlyArray<ValidationIssue>;\n }\n | { readonly valid: false; readonly issues: ReadonlyArray<ValidationIssue> };\n\n// =============================================================================\n// Public entry point\n// =============================================================================\n\nexport function validatePoeRecord(bytes: Uint8Array, options?: ValidatorOptions): ValidationResult {\n const opts = resolveOptions(options);\n\n // Step 1 — canonical CBOR decode. Every decode failure surfaces as the\n // single MALFORMED_CBOR code: malformed/truncated bytes, indefinite-length\n // (streaming) encodings, non-canonical map-key ordering, duplicate map\n // keys, non-minimal integers, and invalid UTF-8. There is no separate\n // duplicate-key code — canonical-decode rejection covers it.\n let decoded: unknown;\n try {\n decoded = decodeCanonicalCbor(bytes);\n } catch (cause) {\n return {\n valid: false,\n issues: [\n {\n code: 'MALFORMED_CBOR',\n path: [],\n message: cause instanceof Error ? cause.message : String(cause),\n severity: 'error',\n },\n ],\n };\n }\n\n // Step 2 pre-guard — non-text map keys. Every map at a typed grammar\n // position is text-keyed; the canonical decoder surfaces a map carrying any\n // non-text key as a `Map` (an all-text-key map decodes to a plain object).\n // A `Map` is still a JS object, so an object schema run over it would read\n // its (absent) named properties and mis-report every required field as\n // missing — the violation is detected here instead and attributed at the\n // containing map as SCHEMA_TYPE_MISMATCH, foreclosing the parse the same\n // way any other unparseable shape does.\n const nonTextKeyIssues = collectNonTextKeyMapIssues(decoded);\n if (nonTextKeyIssues.length > 0) {\n return { valid: false, issues: sortIssues(nonTextKeyIssues) };\n }\n\n // Step 2 — schema parse. A failed parse forecloses the domain pass (there\n // is no typed record to walk); its issues are emitted sorted.\n const parse = PoeRecordSchema.safeParse(decoded);\n if (!parse.success) {\n return { valid: false, issues: sortIssues(mapZodIssues(parse.error.issues, decoded)) };\n }\n\n // Step 3 — domain checks. Issues of every severity are collected together;\n // no error-severity issue stops the walk.\n const record = parse.data;\n const issues: ValidationIssue[] = [];\n\n checkContentCommitmentPresence(record, issues);\n\n // `crit[]` shape rules run before the per-entry support check.\n const decodedTopKeys = topLevelKeysOf(decoded);\n checkCrit(record, decodedTopKeys, opts.supportedCriticalExtensions, issues);\n\n // Unknown top-level fields: keys outside the base set that match neither\n // extension-key namespace (typos, control-character keys).\n for (const key of decodedTopKeys) {\n if (TOP_LEVEL_BASE_KEYS.has(key)) continue;\n if (isExtensionKey(key)) continue;\n issues.push(issueOf('SCHEMA_UNKNOWN_FIELD', [key], `unknown top-level field: ${key}`));\n }\n\n const items = record.items ?? [];\n for (let i = 0; i < items.length; i++) {\n const item = items[i]!;\n checkItemHashes(item, i, issues);\n if (item.uris !== undefined) checkUris(item.uris, ['items', i, 'uris'], issues);\n if (item.enc !== undefined) checkItemEnc(item, i, opts, issues);\n }\n\n const merkle = record.merkle ?? [];\n for (let i = 0; i < merkle.length; i++) {\n checkMerkleCommit(merkle[i]!, i, issues);\n }\n\n if (record.sigs !== undefined) {\n if (record.sigs.length === 0) {\n issues.push(\n issueOf('SCHEMA_TYPE_MISMATCH', ['sigs'], 'sigs[] must be non-empty when present'),\n );\n }\n for (let i = 0; i < record.sigs.length; i++) {\n checkSigEntry(record.sigs[i]!, i, issues);\n }\n }\n\n // Step 4 — result emission. The full issue list is sorted once (path\n // segment-wise, registry-order tie-break); the record is valid iff no\n // error-severity issue is present, and warnings / info never fail it.\n const sorted = sortIssues(issues);\n if (sorted.some((issue) => issue.severity === 'error')) {\n return { valid: false, issues: sorted };\n }\n const warnings = sorted.filter((issue) => issue.severity === 'warning');\n const info = sorted.filter((issue) => issue.severity === 'info');\n const result: {\n valid: true;\n record: PoeRecord;\n warnings?: ReadonlyArray<ValidationIssue>;\n info?: ReadonlyArray<ValidationIssue>;\n } = { valid: true, record };\n if (warnings.length > 0) result.warnings = warnings;\n if (info.length > 0) result.info = info;\n return result;\n}\n\n// =============================================================================\n// Step 2 helpers — Zod issue → structural-code mapping\n// =============================================================================\n\n// Lift a Zod issue list to canonical structural issues. An\n// `unrecognized_keys` issue names every stray key of one closed map in a\n// single Zod issue; it is expanded here into one canonical issue per key,\n// attributed at the key itself — the same per-key attribution the domain\n// pass uses for closed maps it walks by hand.\nfunction mapZodIssues(\n zissues: ReadonlyArray<z.core.$ZodIssue>,\n decodedRoot?: unknown,\n): ValidationIssue[] {\n const out: ValidationIssue[] = [];\n for (const zissue of zissues) {\n if (zissue.code === 'unrecognized_keys') {\n for (const key of zissue.keys) {\n const path = [...(zissue.path as ReadonlyArray<string | number>), key];\n const code = unknownKeyCode(path);\n out.push(issueOf(code, path, `unrecognized key '${key}' in a closed map`));\n }\n continue;\n }\n out.push(mapZodIssue(zissue, decodedRoot));\n }\n return out;\n}\n\n// The canonical code for a stray key, by position: a stray key inside a\n// `sigs[i]` entry violates the sig-entry closed-map rule; everywhere else a\n// stray key in a closed map is the generic SCHEMA_UNKNOWN_FIELD. (Slot maps\n// never reach this dispatch — their schema is permissive and the KEM-driven\n// domain gate emits ENC_SLOT_INVALID_SHAPE for stray slot keys.)\nfunction unknownKeyCode(path: ReadonlyArray<string | number>): ErrorCode {\n if (path.length >= 2 && path[0] === 'sigs' && typeof path[1] === 'number') {\n return 'SIG_ENTRY_INVALID_SHAPE';\n }\n return 'SCHEMA_UNKNOWN_FIELD';\n}\n\n// Non-text-key detection over the typed grammar positions reachable from the\n// record root: the root map, each `items[i]` / `merkle[i]` / `sigs[i]` entry,\n// and the `hashes` / `enc` maps inside an item. Positions inside extension\n// values are deliberately NOT walked — extension values admit any CBOR value\n// the canonical profile allows, integer-keyed maps included. The interior of\n// a supported `enc` envelope is scanned by the envelope dispatch itself (the\n// opaque reading likewise admits arbitrary extension values).\nfunction collectNonTextKeyMapIssues(decoded: unknown): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const flag = (path: ReadonlyArray<string | number>): void => {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n path,\n 'CBOR map carries a non-text key where a text-keyed map is required',\n ),\n );\n };\n if (decoded instanceof Map) {\n flag([]);\n return issues;\n }\n if (decoded === null || typeof decoded !== 'object' || Array.isArray(decoded)) return issues;\n const record = decoded as Record<string, unknown>;\n for (const field of ['items', 'merkle', 'sigs'] as const) {\n const entries = record[field];\n if (!Array.isArray(entries)) continue;\n entries.forEach((entry, i) => {\n if (entry instanceof Map) {\n flag([field, i]);\n return;\n }\n if (field !== 'items' || entry === null || typeof entry !== 'object') return;\n const item = entry as Record<string, unknown>;\n if (item['hashes'] instanceof Map) flag([field, i, 'hashes']);\n if (item['enc'] instanceof Map) flag([field, i, 'enc']);\n });\n }\n return issues;\n}\n\nfunction mapZodIssue(zissue: z.core.$ZodIssue, decodedRoot?: unknown): ValidationIssue {\n const path = zissue.path as ReadonlyArray<string | number>;\n // Refinements with an explicit `params.code` win unconditionally — they are\n // the canonical taxonomy code attached at schema-definition time\n // (SUPERSEDES_TX_INVALID_LENGTH, ENC_SLOTS_MAC_INVALID_LENGTH, the salt\n // bounds).\n const explicit = (zissue as { params?: { code?: string } }).params?.code as ErrorCode | undefined;\n if (explicit !== undefined) {\n return issueOf(explicit, path, zissue.message);\n }\n\n const valueAtIssue = valueAtPath(decodedRoot, path);\n\n // A CBOR map carrying any non-text key decodes to a `Map` (an all-text-key\n // map decodes to a plain object), and every registered map position in the\n // grammar is text-keyed — so a `Map` anywhere a registered map is expected\n // is a non-text-key violation, reported as SCHEMA_TYPE_MISMATCH at the\n // containing map regardless of which position it sits in.\n if (valueAtIssue instanceof Map) {\n return issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n path,\n 'CBOR map carries a non-text key where a text-keyed map is required',\n );\n }\n\n // Path-based dispatch:\n // `sigs[i]…` → SIG_ENTRY_INVALID_SHAPE (the sig-entry closed-map rule)\n // a slot element or a field within a slot → ENC_SLOT_INVALID_SHAPE\n // `v` literal mismatch / missing → SCHEMA_INVALID_LITERAL vs\n // SCHEMA_MISSING_REQUIRED.\n const inSigsEntry = path.length >= 2 && path[0] === 'sigs' && typeof path[1] === 'number';\n\n // The typed envelope parse runs with the `enc` map as its root, so a slot\n // issue arrives with the relative path `slots[j]…`; `checkItemEnc` prefixes\n // the `items[i].enc` segments afterwards. (The top-level record parse never\n // descends into `enc` — the item schema holds it as `unknown` for the\n // typed-vs-opaque dispatch.)\n const isInSlotEntry = path.length >= 2 && path[0] === 'slots' && typeof path[1] === 'number';\n\n const isMissing = valueAtIssue === undefined;\n\n switch (zissue.code) {\n case 'invalid_type':\n if (isInSlotEntry) return issueOf('ENC_SLOT_INVALID_SHAPE', path, zissue.message);\n if (isMissing) {\n if (inSigsEntry) return issueOf('SIG_ENTRY_INVALID_SHAPE', path, zissue.message);\n return issueOf('SCHEMA_MISSING_REQUIRED', path, zissue.message);\n }\n if (inSigsEntry) return issueOf('SIG_ENTRY_INVALID_SHAPE', path, zissue.message);\n return issueOf('SCHEMA_TYPE_MISMATCH', path, zissue.message);\n case 'invalid_value':\n // `z.literal(1)` emits `invalid_value` for both a missing field AND a\n // present-but-wrong value; disambiguate via the runtime value.\n if (isMissing) return issueOf('SCHEMA_MISSING_REQUIRED', path, zissue.message);\n return issueOf('SCHEMA_INVALID_LITERAL', path, zissue.message);\n case 'invalid_union':\n case 'invalid_format':\n case 'too_big':\n case 'too_small':\n case 'invalid_key':\n case 'invalid_element':\n case 'custom':\n default:\n if (isInSlotEntry) return issueOf('ENC_SLOT_INVALID_SHAPE', path, zissue.message);\n if (inSigsEntry) return issueOf('SIG_ENTRY_INVALID_SHAPE', path, zissue.message);\n return issueOf('SCHEMA_TYPE_MISMATCH', path, zissue.message);\n }\n}\n\n// =============================================================================\n// Step 3 helpers — domain checks\n// =============================================================================\n\n// Content-commitment rule: a record MUST carry at least one of `items[]` or\n// `merkle[]` non-empty (SCHEMA_EMPTY_RECORD when both are empty or absent).\n// When exactly one of them is present-but-empty beside a non-empty sibling,\n// the empty array itself violates its `1*` cardinality.\nfunction checkContentCommitmentPresence(record: PoeRecord, issues: ValidationIssue[]): void {\n const itemsLen = record.items?.length ?? 0;\n const merkleLen = record.merkle?.length ?? 0;\n if (itemsLen === 0 && merkleLen === 0) {\n issues.push(\n issueOf(\n 'SCHEMA_EMPTY_RECORD',\n [],\n 'record must carry at least one of items[] or merkle[] non-empty',\n ),\n );\n return;\n }\n if (record.items !== undefined && itemsLen === 0) {\n issues.push(\n issueOf('SCHEMA_TYPE_MISMATCH', ['items'], 'items[] must be non-empty when present'),\n );\n }\n if (record.merkle !== undefined && merkleLen === 0) {\n issues.push(\n issueOf('SCHEMA_TYPE_MISMATCH', ['merkle'], 'merkle[] must be non-empty when present'),\n );\n }\n}\n\n// Hash-map: non-empty, registry membership, per-algorithm digest length.\nfunction checkItemHashes(item: ItemEntry, idx: number, issues: ValidationIssue[]): void {\n const entries = Object.entries(item.hashes);\n if (entries.length === 0) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n ['items', idx, 'hashes'],\n 'hashes must be a non-empty CBOR map of <alg-id> -> <digest>',\n ),\n );\n return;\n }\n for (const [alg, digest] of entries) {\n if (!(alg in HASH_ALG_LENGTHS)) {\n issues.push(\n issueOf('UNSUPPORTED_HASH_ALG', ['items', idx, 'hashes', alg], `unknown hash alg: ${alg}`),\n );\n continue;\n }\n const expected = HASH_ALG_LENGTHS[alg]!;\n if (digest.length !== expected) {\n issues.push(\n issueOf(\n 'HASH_DIGEST_LENGTH_MISMATCH',\n ['items', idx, 'hashes', alg],\n `hashes['${alg}'] digest length ${digest.length} != ${expected}`,\n ),\n );\n }\n }\n}\n\n// URI shape: each entry is one absolute URI in a single text string.\nfunction checkUris(\n uris: ReadonlyArray<string>,\n basePath: ReadonlyArray<string | number>,\n issues: ValidationIssue[],\n): void {\n if (uris.length === 0) {\n issues.push(issueOf('SCHEMA_TYPE_MISMATCH', basePath, 'uris[] must be non-empty when present'));\n return;\n }\n uris.forEach((uri, ui) => checkOneUri(uri, [...basePath, ui], issues));\n}\n\nfunction checkOneUri(\n uri: string,\n path: ReadonlyArray<string | number>,\n issues: ValidationIssue[],\n): void {\n // Absolute URI, no fragment, scheme in `{ar://, ipfs://}`.\n if (uri.includes('#')) {\n issues.push(\n issueOf('INVALID_URI', path, \"URI contains a fragment identifier ('#'), which is forbidden\"),\n );\n return;\n }\n const sepIdx = uri.indexOf('://');\n if (sepIdx <= 0 || !/^[a-z][a-z0-9+.-]*$/i.test(uri.slice(0, sepIdx))) {\n issues.push(\n issueOf('INVALID_URI', path, 'URI is not absolute (missing scheme://hierarchical-part)'),\n );\n return;\n }\n // RFC 3986 §3.1: the scheme is case-insensitive, so case-fold the SCHEME\n // ONLY, then ALWAYS validate the body. The body is matched verbatim — a\n // base64url Arweave txid and a base58btc CID are case-significant.\n const scheme = uri.slice(0, sepIdx).toLowerCase();\n const rest = uri.slice(sepIdx + '://'.length);\n if (scheme === 'ar') {\n if (!/^[A-Za-z0-9_-]{43}$/.test(rest)) {\n issues.push(\n issueOf(\n 'INVALID_URI',\n path,\n 'ar:// URI does not match `^ar://[A-Za-z0-9_-]{43}$` (43-char base64url txid, no path/query/fragment)',\n ),\n );\n }\n return;\n }\n if (scheme === 'ipfs') {\n // Full offline CID parse (not a prefix heuristic).\n const slashIdx = rest.indexOf('/');\n const cid = slashIdx === -1 ? rest : rest.slice(0, slashIdx);\n if (!validateCidProfile(cid)) {\n issues.push(\n issueOf('INVALID_URI', path, 'ipfs:// URI is not a valid CID under the Label 309 profile'),\n );\n }\n return;\n }\n issues.push(\n issueOf('INVALID_URI', path, 'unsupported URI scheme; v1 PoE URI set is {ar://, ipfs://}'),\n );\n}\n\n// =============================================================================\n// Encryption envelope — the typed-vs-opaque union\n// =============================================================================\n//\n// `enc = enc-scheme-1 / enc-opaque`. The disposition is decided by identifier\n// support, never by shape success:\n//\n// - When `scheme`, `kem`, and `aead` are ALL supported identifiers, the\n// envelope is held to the full scheme-1 shape and key-path rules; an\n// envelope that fails them is rejected with its typed code, never\n// reclassified as opaque.\n// - When any of the three names an identifier this implementation does not\n// support, the envelope becomes OPAQUE: no shape, length, or key-path\n// rule is applied against an unknown identifier; the item is tagged\n// ENC_UNSUPPORTED (info in the public reading; error co-firing with the\n// identifier-specific UNSUPPORTED_* code in the recipient role / strict\n// sealed-crypto mode).\n// - Carve-out: an `aead` naming a forbidden unauthenticated cipher family\n// is rejected UNAUTHENTICATED_CIPHER_FORBIDDEN in every role — a\n// recognised hazard, not an unknown identifier.\n//\n// The content-hash binding (ENC_REQUIRES_CONTENT_HASH) inspects the item's\n// `hashes` map, not the envelope, so it applies even under an opaque\n// envelope.\n\nfunction checkItemEnc(\n item: ItemEntry,\n idx: number,\n opts: ResolvedOptions,\n issues: ValidationIssue[],\n): void {\n const encPath: ReadonlyArray<string | number> = ['items', idx, 'enc'];\n\n // Content-hash binding: an `enc`-bearing item MUST commit to at least one\n // REGISTERED content hash — the ciphertext is otherwise bound to no\n // plaintext digest. A presence check, not a non-empty check: `{md5: …}`\n // fails it (and MAY co-fire with UNSUPPORTED_HASH_ALG on the same item).\n const hasContentHash = Object.keys(item.hashes).some((alg) => alg in HASH_ALG_LENGTHS);\n if (!hasContentHash) {\n issues.push(\n issueOf(\n 'ENC_REQUIRES_CONTENT_HASH',\n encPath,\n 'item carries `enc` but `hashes` has no registered content-hash entry (sha2-256 or blake2b-256)',\n ),\n );\n }\n\n // The pre-guard has already rejected an `enc` that decoded to a `Map`\n // (non-text keys), so a well-typed envelope arrives here as a plain object.\n const rawEnc = item.enc;\n if (\n rawEnc === null ||\n typeof rawEnc !== 'object' ||\n Array.isArray(rawEnc) ||\n rawEnc instanceof Uint8Array\n ) {\n issues.push(issueOf('SCHEMA_TYPE_MISMATCH', encPath, 'enc must be a CBOR map'));\n return;\n }\n const enc = rawEnc as Record<string, unknown>;\n\n // Decoded-envelope byte resource bound — a generic decode limit that\n // applies in every reading, opaque included. Canonical decode → canonical\n // encode is byte-identical, so re-encoding the decoded envelope measures\n // exactly the wire bytes of the `enc` subtree.\n const envelopeBytes = encodeCanonicalCbor(rawEnc as CanonicalCborValue).length;\n if (envelopeBytes > opts.maxEncEnvelopeBytes) {\n issues.push(\n issueOf(\n 'ENC_ENVELOPE_TOO_LARGE',\n encPath,\n `decoded envelope is ${envelopeBytes} bytes; the resource bound is ${opts.maxEncEnvelopeBytes}`,\n ),\n );\n }\n\n // `scheme` is structurally required in BOTH readings, as a CBOR unsigned\n // integer (the opaque grammar admits any uint; the typed grammar pins 1).\n const scheme = enc['scheme'];\n if (scheme === undefined) {\n issues.push(\n issueOf('SCHEMA_MISSING_REQUIRED', [...encPath, 'scheme'], 'enc.scheme is required'),\n );\n return;\n }\n if (!isUint(scheme)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...encPath, 'scheme'],\n 'enc.scheme must be a CBOR unsigned integer',\n ),\n );\n return;\n }\n\n // Forbidden-cipher carve-out: rejected in every role, never opaque.\n const aead = enc['aead'];\n if (typeof aead === 'string' && UNAUTHENTICATED_CIPHER_RE.test(aead)) {\n issues.push(\n issueOf(\n 'UNAUTHENTICATED_CIPHER_FORBIDDEN',\n [...encPath, 'aead'],\n `'${aead}' is an unauthenticated cipher; Label 309 mandates an authenticated (AEAD) cipher`,\n ),\n );\n return;\n }\n\n // Unknown-envelope rule: collect every identifier outside the implemented\n // set. A non-text `kem` / `aead` is not an identifier at all — it is a type\n // violation of whichever reading applies, handled by the typed pass below.\n const kem = enc['kem'];\n const unsupported: Array<{ field: 'scheme' | 'kem' | 'aead'; code: ErrorCode; id: string }> = [];\n if (!(typeof scheme === 'number' && scheme === 1)) {\n unsupported.push({ field: 'scheme', code: 'UNSUPPORTED_ENVELOPE_SCHEME', id: String(scheme) });\n }\n if (typeof kem === 'string' && !(kem in KEM_SLOT_DESCRIPTORS)) {\n unsupported.push({ field: 'kem', code: 'UNSUPPORTED_KEM_ALG', id: kem });\n }\n if (typeof aead === 'string' && !(aead in AEAD_NONCE_LENGTHS)) {\n unsupported.push({ field: 'aead', code: 'UNSUPPORTED_AEAD_ALG', id: aead });\n }\n if (unsupported.length > 0) {\n // Degrade to opaque: the envelope is bounded metadata only. No shape,\n // length, nonce, slot, or key-path rule may be applied against an\n // unknown identifier.\n const named = unsupported.map((u) => `${u.field}=${u.id}`).join(', ');\n const message =\n `envelope uses identifiers this implementation does not support (${named}); ` +\n 'the envelope is opaque and only the content-hash claim is validated';\n if (opts.role === 'recipient_or_strict') {\n issues.push({ code: 'ENC_UNSUPPORTED', path: encPath, message, severity: 'error' });\n for (const u of unsupported) {\n issues.push(\n issueOf(u.code, [...encPath, u.field], `enc.${u.field} '${u.id}' is not supported`),\n );\n }\n } else {\n issues.push({ code: 'ENC_UNSUPPORTED', path: encPath, message, severity: 'info' });\n }\n return;\n }\n\n // Fully supported identifiers → the typed scheme-1 pass is mandatory.\n // Non-text-key maps inside the typed envelope (a slot, the passphrase\n // block, its params) are rejected first, at the containing map — the same\n // pre-guard rule the record level applies, scoped here because only the\n // typed reading constrains the envelope interior.\n const internalMapIssues = encInternalNonTextKeyIssues(enc, encPath);\n if (internalMapIssues.length > 0) {\n issues.push(...internalMapIssues);\n return;\n }\n const encParse = EncScheme1Schema.safeParse(rawEnc);\n if (!encParse.success) {\n for (const mapped of mapZodIssues(encParse.error.issues, rawEnc)) {\n issues.push({ ...mapped, path: [...encPath, ...mapped.path] });\n }\n return;\n }\n checkScheme1Envelope(encParse.data, rawEnc, encPath, opts, issues);\n}\n\n// Non-text-key maps at the typed envelope's interior positions: each slot,\n// the passphrase block, and its `params` map.\nfunction encInternalNonTextKeyIssues(\n enc: Record<string, unknown>,\n encPath: ReadonlyArray<string | number>,\n): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const flag = (path: ReadonlyArray<string | number>): void => {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n path,\n 'CBOR map carries a non-text key where a text-keyed map is required',\n ),\n );\n };\n const slots = enc['slots'];\n if (Array.isArray(slots)) {\n slots.forEach((slot, i) => {\n if (slot instanceof Map) flag([...encPath, 'slots', i]);\n });\n }\n const passphrase = enc['passphrase'];\n if (passphrase instanceof Map) {\n flag([...encPath, 'passphrase']);\n } else if (passphrase !== null && typeof passphrase === 'object' && !Array.isArray(passphrase)) {\n const params = (passphrase as Record<string, unknown>)['params'];\n if (params instanceof Map) flag([...encPath, 'passphrase', 'params']);\n }\n return issues;\n}\n\nfunction checkScheme1Envelope(\n enc: EncScheme1,\n rawEnc: object,\n encPath: ReadonlyArray<string | number>,\n opts: ResolvedOptions,\n issues: ValidationIssue[],\n): void {\n // Nonce length is registered per content format (24 bytes for\n // chacha20-poly1305-stream64k). Checked only under a supported `aead` —\n // which is guaranteed on this path.\n const expectedNonceLen = AEAD_NONCE_LENGTHS[enc.aead]!;\n if (enc.nonce.length !== expectedNonceLen) {\n issues.push(\n issueOf(\n 'NONCE_LENGTH_MISMATCH',\n [...encPath, 'nonce'],\n `nonce length ${enc.nonce.length} != ${expectedNonceLen} for ${enc.aead}`,\n ),\n );\n }\n\n // Key-path cross-field rules. Exactly one of `slots` / `passphrase` is\n // present; `passphrase` forbids `kem`, `slots`, and `slots_mac`; `slots`\n // requires both `kem` and `slots_mac`; `slots_mac` binds nothing without\n // `slots`. Each independent rule emits its own code — they co-fire where\n // several apply.\n const hasSlots = enc.slots !== undefined;\n const hasSlotsMac = enc.slots_mac !== undefined;\n const hasPassphrase = enc.passphrase !== undefined;\n const hasKem = enc.kem !== undefined;\n\n if (hasPassphrase && (hasSlots || hasSlotsMac || hasKem)) {\n issues.push(\n issueOf(\n 'ENC_EXCLUSIVITY_VIOLATION',\n encPath,\n 'enc.passphrase is mutually exclusive with kem / slots / slots_mac; exactly one key path is allowed',\n ),\n );\n }\n if (hasSlots && !hasSlotsMac) {\n issues.push(\n issueOf('ENC_SLOTS_MAC_REQUIRED', encPath, 'enc.slots present but enc.slots_mac absent'),\n );\n }\n if (hasSlotsMac && !hasSlots) {\n issues.push(\n issueOf('ENC_SLOTS_REQUIRED', encPath, 'enc.slots_mac present but enc.slots absent'),\n );\n }\n if (hasSlots && !hasKem) {\n issues.push(issueOf('ENC_KEM_REQUIRED', encPath, 'enc.slots present but enc.kem absent'));\n }\n if (!hasSlots && !hasPassphrase) {\n issues.push(\n issueOf(\n 'ENC_NO_KEY_PATH',\n encPath,\n 'enc requires either slots or passphrase — no on-chain key path otherwise',\n ),\n );\n }\n\n if (hasSlots) {\n const slots = enc.slots!;\n if (slots.length < 1) {\n issues.push(\n issueOf('ENC_SLOTS_EMPTY', [...encPath, 'slots'], 'slots[] must carry at least one slot'),\n );\n } else if (slots.length > opts.maxSlots) {\n // Slot-count resource bound: reject before walking any slot, so a\n // hostile record cannot drive unbounded per-slot work.\n issues.push(\n issueOf(\n 'ENC_SLOTS_TOO_MANY',\n [...encPath, 'slots'],\n `slots length ${slots.length} exceeds the slot-count bound ${opts.maxSlots}`,\n ),\n );\n } else if (hasKem) {\n // The descriptor exists — `kem` is registered on this path.\n const descriptor = KEM_SLOT_DESCRIPTORS[enc.kem!]!;\n const rawSlotKeys = rawSlotKeySets(rawEnc);\n // Per-slot KEK uniqueness: the zero-nonce per-slot wrap is safe only\n // because each slot draws fresh KEM randomness; two slots sharing the\n // same encapsulation material would derive the same KEK. Reject the\n // repeat before any cryptographic layer would.\n const seenKemMaterial = new Set<string>();\n slots.forEach((slot, si) => {\n const slotPath = [...encPath, 'slots', si] as const;\n checkSlotShape(\n slot,\n rawSlotKeys[si] ?? new Set<string>(),\n descriptor,\n enc.kem!,\n slotPath,\n issues,\n );\n const material = descriptor.field === 'epk' ? slot.epk : slot.kem_ct;\n if (material !== undefined) {\n const key = bytesToHex(material);\n if (seenKemMaterial.has(key)) {\n issues.push(\n issueOf(\n 'ENC_SLOTS_DUPLICATE_KEM_MATERIAL',\n [...slotPath, descriptor.field],\n `slot ${si} ${descriptor.field} duplicates an earlier slot — per-slot KEK uniqueness is violated`,\n ),\n );\n } else {\n seenKemMaterial.add(key);\n }\n }\n });\n }\n }\n\n if (hasPassphrase) {\n checkPassphraseBlock(enc.passphrase!, [...encPath, 'passphrase'], opts, issues);\n }\n}\n\n// KEM-driven per-slot shape gate. The descriptor for the declared envelope\n// `kem` pins which ciphertext-bearing field MUST be present at what exact\n// length, and forbids everything else: the other KEM's field, any stray key\n// (a slot is a CLOSED 2-key map), and a missing required field all surface\n// as ENC_SLOT_INVALID_SHAPE. `rawKeys` is the slot's key set exactly as it\n// appeared on the wire, so the permissive slot schema cannot mask a foreign\n// field.\nconst SLOT_KEY_UNIVERSE: ReadonlySet<string> = new Set(['epk', 'kem_ct', 'wrap']);\n\nfunction checkSlotShape(\n slot: Slot,\n rawKeys: ReadonlySet<string>,\n descriptor: KemSlotDescriptor,\n kem: string,\n slotPath: ReadonlyArray<string | number>,\n issues: ValidationIssue[],\n): void {\n const foreignField: KemSlotField = descriptor.field === 'epk' ? 'kem_ct' : 'epk';\n if (rawKeys.has(foreignField)) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, foreignField],\n `slot carries '${foreignField}' but kem='${kem}' expects '${descriptor.field}'`,\n ),\n );\n }\n for (const key of rawKeys) {\n if (!SLOT_KEY_UNIVERSE.has(key)) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, key],\n `slot carries unexpected key '${key}'; a slot is a 2-key map {${descriptor.field}, wrap}`,\n ),\n );\n }\n }\n\n const ctField = descriptor.field === 'epk' ? slot.epk : slot.kem_ct;\n if (ctField === undefined) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, descriptor.field],\n `slot for kem='${kem}' is missing required '${descriptor.field}'`,\n ),\n );\n } else if (ctField.length !== descriptor.fieldLength) {\n issues.push(\n issueOf(\n KEM_FIELD_LENGTH_CODE[descriptor.field],\n [...slotPath, descriptor.field],\n `slot.${descriptor.field} length ${ctField.length} != ${descriptor.fieldLength} for ${kem}`,\n ),\n );\n }\n\n if (slot.wrap === undefined) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, 'wrap'],\n `slot for kem='${kem}' is missing required 'wrap'`,\n ),\n );\n } else if (slot.wrap.length !== descriptor.wrapLength) {\n issues.push(\n issueOf(\n 'WRAP_LENGTH_MISMATCH',\n [...slotPath, 'wrap'],\n `slot.wrap length ${slot.wrap.length} != ${descriptor.wrapLength}`,\n ),\n );\n }\n}\n\n// Passphrase block: KDF registry membership, then the registered algorithm's\n// CLOSED parameter map with exact-integer range, floors, and the deployment\n// ceiling. Salt bounds are schema refinements and have already fired.\nfunction checkPassphraseBlock(\n pp: PassphraseBlock,\n ppPath: ReadonlyArray<string | number>,\n opts: ResolvedOptions,\n issues: ValidationIssue[],\n): void {\n if (!PASSPHRASE_KDF_ALGS.has(pp.alg)) {\n issues.push(\n issueOf(\n 'ENC_PASSPHRASE_ALG_UNSUPPORTED',\n [...ppPath, 'alg'],\n `unknown passphrase kdf alg: ${pp.alg}`,\n ),\n );\n return; // no algorithm-specific params rule can apply\n }\n\n // argon2id: `params` is the CLOSED map of exactly {m, t, p}.\n const paramsPath = [...ppPath, 'params'] as const;\n const params = pp.params;\n for (const key of Object.keys(params)) {\n if (key !== 'm' && key !== 't' && key !== 'p') {\n issues.push(\n issueOf(\n 'SCHEMA_UNKNOWN_FIELD',\n [...paramsPath, key],\n `unknown argon2id params field: ${key}`,\n ),\n );\n }\n }\n\n const floors = { m: 65_536, t: 3, p: 1 } as const;\n const ceiling = opts.passphraseParamsCeiling;\n for (const name of ['m', 't', 'p'] as const) {\n const value: unknown = params[name];\n if (value === undefined) {\n issues.push(\n issueOf(\n 'SCHEMA_MISSING_REQUIRED',\n [...paramsPath, name],\n `argon2id params.${name} is required`,\n ),\n );\n continue;\n }\n // Exact-integer discipline: values above 2^53 − 1 arrive as `bigint`,\n // so an out-of-range value is rejected without precision loss.\n if (!isUint(value)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...paramsPath, name],\n `argon2id params.${name} must be a CBOR unsigned integer`,\n ),\n );\n continue;\n }\n if (!uintWithin(value, 0, UINT32_MAX)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...paramsPath, name],\n `argon2id params.${name} exceeds the pinned wire range 0 .. 2^32 - 1`,\n ),\n );\n continue;\n }\n const num = Number(value);\n if (num < floors[name]) {\n issues.push(\n issueOf(\n 'ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW',\n [...paramsPath, name],\n `argon2id requires ${name} >= ${floors[name]}`,\n ),\n );\n continue;\n }\n if (ceiling !== null && num > ceiling[name]) {\n issues.push(\n issueOf(\n 'ENC_PASSPHRASE_PARAMS_EXCEED_POLICY',\n [...paramsPath, name],\n `argon2id params.${name} = ${num} exceeds the deployment ceiling ${ceiling[name]}`,\n ),\n );\n }\n }\n}\n\n// Extract the per-slot RAW key sets from the decoded `enc` value, so the\n// closed-slot rule sees keys the permissive slot schema does not model. The\n// canonical decoder yields a plain object for a text-keyed CBOR map and a\n// `Map` for a map carrying any non-text key.\nfunction rawSlotKeySets(rawEnc: object): ReadonlyArray<ReadonlySet<string>> {\n const slots = (rawEnc as Record<string, unknown>)['slots'];\n if (!Array.isArray(slots)) return [];\n return slots.map((slot) => {\n const keys = new Set<string>();\n if (slot instanceof Map) {\n for (const k of slot.keys()) if (typeof k === 'string') keys.add(k);\n } else if (typeof slot === 'object' && slot !== null) {\n for (const k of Object.keys(slot as Record<string, unknown>)) keys.add(k);\n }\n return keys;\n });\n}\n\n// =============================================================================\n// Merkle commitments\n// =============================================================================\n\nfunction checkMerkleCommit(commit: MerkleCommit, idx: number, issues: ValidationIssue[]): void {\n const basePath: ReadonlyArray<string | number> = ['merkle', idx];\n if (!(commit.alg in MERKLE_COMMIT_ALG_LENGTHS)) {\n issues.push(\n issueOf(\n 'UNSUPPORTED_MERKLE_COMMIT_ALG',\n [...basePath, 'alg'],\n `unknown merkle commitment alg: ${commit.alg}`,\n ),\n );\n } else {\n const expected = MERKLE_COMMIT_ALG_LENGTHS[commit.alg]!;\n if (commit.root.length !== expected) {\n issues.push(\n issueOf(\n 'HASH_DIGEST_LENGTH_MISMATCH',\n [...basePath, 'root'],\n `merkle entry root length ${commit.root.length} != ${expected} for ${commit.alg}`,\n ),\n );\n }\n }\n\n // `leaf_count` is REQUIRED and pinned to `1 .. 2^32 − 1`, compared as an\n // exact integer: the decoder surfaces values above 2^53 − 1 as `bigint`,\n // so 2^53 + 1 cannot round to a boundary value before rejection. A\n // negative value is a CBOR type violation (nint where uint is required),\n // distinct from an out-of-range unsigned value.\n const leafCount = commit.leaf_count;\n if (!isUint(leafCount)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...basePath, 'leaf_count'],\n 'leaf_count must be a CBOR unsigned integer',\n ),\n );\n } else if (!uintWithin(leafCount, 1, UINT32_MAX)) {\n issues.push(\n issueOf(\n 'SCHEMA_MERKLE_LEAF_COUNT_INVALID',\n [...basePath, 'leaf_count'],\n `leaf_count ${String(leafCount)} is outside the pinned range 1 .. 2^32 - 1`,\n ),\n );\n }\n\n if (commit.uris !== undefined) {\n checkUris(commit.uris, [...basePath, 'uris'], issues);\n }\n}\n\n// =============================================================================\n// Record-level signature entries\n// =============================================================================\n\nfunction checkSigEntry(entry: SigEntry, idx: number, issues: ValidationIssue[]): void {\n // Path-2 `cose_key` private-material guard runs FIRST: a leaked private\n // scalar must be named even when the COSE_Sign1 is also malformed.\n if (entry.cose_key !== undefined) {\n const keyIssue = inspectCoseKey(entry.cose_key, idx);\n if (keyIssue !== null) {\n issues.push(keyIssue);\n return;\n }\n }\n\n let cose: ReturnType<typeof decodeCoseSign1>;\n try {\n cose = decodeCoseSign1(entry.cose_sign1);\n } catch (cause) {\n issues.push(\n issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', idx],\n cause instanceof CoseVerifyError || cause instanceof Error ? cause.message : String(cause),\n ),\n );\n return;\n }\n\n // Detached-only: the COSE_Sign1 payload MUST be CBOR null. An attached\n // payload — even zero-length — is rejected; a producer chaining a CIP-30\n // signData result must null the payload before embedding.\n if (cose.payload !== null) {\n issues.push(\n issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', idx],\n 'COSE_Sign1 payload must be null (detached); attached form forbidden',\n ),\n );\n return;\n }\n\n // Signature-algorithm registry check (info severity — signatures are\n // optional, so an unrecognised algorithm never fails the record alone).\n const alg = cose.protectedHeader.get(1);\n if (typeof alg !== 'number' || !KNOWN_SIG_ALG_IDS.has(alg)) {\n issues.push(\n issueOf(\n 'SIGNATURE_UNSUPPORTED',\n ['sigs', idx],\n `COSE_Sign1 protected alg ${String(alg)} not in {-8, -19}`,\n ),\n );\n }\n\n // Path-1 (32-byte protected-header `kid`) and path-2 (`cose_key` sidecar)\n // are mutually exclusive.\n const protectedKid = cose.protectedHeader.get(4);\n if (\n protectedKid instanceof Uint8Array &&\n protectedKid.length === 32 &&\n entry.cose_key !== undefined\n ) {\n issues.push(\n issueOf(\n 'SIG_ENTRY_KID_COSE_KEY_CONFLICT',\n ['sigs', idx],\n 'sigs[i] carries both a 32-byte protected `kid` (path 1) and an inline `cose_key` (path 2); paths are mutually exclusive',\n ),\n );\n }\n}\n\n// COSE_Key inspector (path-2 `sigs[i].cose_key` blob). Two structural checks:\n// 1. Private-material guard (FIRST). COSE_Key label `-4` (the private\n// scalar `d` for OKP / EC2 per RFC 9052 §7.1) → SIG_PRIVATE_KEY_LEAKED.\n// Publishing a private key on the permanent ledger is catastrophic and\n// irreversible, so this is a load-bearing producer-side preflight.\n// 2. Positive-shape guard: `kty = 1` (OKP), `crv = 6` (Ed25519), and a\n// 32-byte `-2` (x). Any failure → MALFORMED_SIG_COSE_SIGN1.\nfunction inspectCoseKey(keyBytes: Uint8Array, i: number): ValidationIssue | null {\n let decoded: unknown;\n try {\n decoded = decodeCanonicalCbor(keyBytes);\n } catch (cause) {\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key failed to decode as cbor<COSE_Key>: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n\n // A COSE_Key map is int-keyed, so the canonical decoder surfaces it as a\n // `Map`; a text-keyed look-alike arrives as a plain object and fails the\n // label lookups below.\n const getLabel = (label: number): unknown => {\n if (decoded instanceof Map) return decoded.get(label);\n return undefined;\n };\n const hasLabel = (label: number): boolean => {\n if (decoded instanceof Map) return decoded.has(label);\n return false;\n };\n\n if (hasLabel(-4)) {\n return issueOf(\n 'SIG_PRIVATE_KEY_LEAKED',\n ['sigs', i, 'cose_key'],\n 'cose_key carries COSE_Key private-key material (label -4, the OKP/EC2 private scalar d); publishing a private key on the permanent ledger is forbidden',\n );\n }\n\n const kty = getLabel(1);\n if (kty !== 1) {\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key COSE_Key kty (label 1) must be 1 (OKP); got ${String(kty)}`,\n );\n }\n const crv = getLabel(-1);\n if (crv !== 6) {\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key COSE_Key crv (label -1) must be 6 (Ed25519); got ${String(crv)}`,\n );\n }\n const x = getLabel(-2);\n if (!(x instanceof Uint8Array) || x.length !== 32) {\n const got = x instanceof Uint8Array ? `${x.length}-byte bstr` : typeof x;\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key COSE_Key label -2 must be a 32-byte byte string (Ed25519 public key); got ${got}`,\n );\n }\n return null;\n}\n\n// =============================================================================\n// `crit[]` shape + critical-extension support\n// =============================================================================\n\nfunction checkCrit(\n record: PoeRecord,\n decodedTopKeys: ReadonlySet<string>,\n supportedCriticalExtensions: ReadonlySet<string>,\n issues: ValidationIssue[],\n): void {\n if (!Array.isArray(record.crit)) return;\n // `crit` has `1*` cardinality: an empty array is a malformed shape.\n if (record.crit.length === 0) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n ['crit'],\n 'crit[] must carry at least one entry when present',\n ),\n );\n return;\n }\n const seen = new Set<string>();\n for (let i = 0; i < record.crit.length; i++) {\n const critName = record.crit[i]!;\n let reason: string | null = null;\n if (TOP_LEVEL_BASE_KEYS.has(critName)) {\n reason = `'${critName}' is a base key and MUST NOT appear in crit[]`;\n } else if (!isExtensionKey(critName)) {\n reason = `'${critName}' does not match the extension-key form (^x-.+ or ^[a-z]+-.+, no control characters)`;\n } else if (!decodedTopKeys.has(critName)) {\n reason = `'${critName}' is named in crit but absent from the record map`;\n } else if (seen.has(critName)) {\n reason = `'${critName}' appears more than once in crit[]`;\n }\n seen.add(critName);\n if (reason !== null) {\n issues.push(issueOf('CRIT_SHAPE_INVALID', ['crit', i], reason));\n continue;\n }\n // Shape-valid entry: accepted iff this validator implements the named\n // extension. The default supported set is empty, so a default-configured\n // validator fails every `crit`-bearing record — by design.\n if (!supportedCriticalExtensions.has(critName)) {\n issues.push(\n issueOf(\n 'EXTENSION_UNSUPPORTED_CRITICAL',\n ['crit', i],\n `crit lists extension '${critName}' that this validator does not implement`,\n ),\n );\n }\n }\n}\n\nfunction topLevelKeysOf(decoded: unknown): Set<string> {\n if (decoded === null || typeof decoded !== 'object') return new Set();\n if (decoded instanceof Map) {\n const out = new Set<string>();\n for (const k of decoded.keys()) {\n if (typeof k === 'string') out.add(k);\n }\n return out;\n }\n return new Set(Object.keys(decoded as Record<string, unknown>));\n}\n\n// =============================================================================\n// Label 309 CID profile\n// =============================================================================\n//\n// Accept CIDv0 (`Qm` prefix, 46-char base58btc, sha2-256 multihash) and\n// CIDv1 (multibase prefix + version 0x01 + codec + multihash) per the\n// closed profile:\n// - Multibase: b, B, f, F, z\n// - Multicodec: 0x55 (raw), 0x70 (dag-pb), 0x71 (dag-cbor)\n// - Multihash: 0x12 (sha2-256, 32 B), 0xb220 (blake2b-256, 32 B)\n//\n// Returns true iff the CID conforms to the Label 309 profile.\n\nconst ACCEPTED_CIDV1_MULTIBASE: ReadonlySet<string> = new Set(['b', 'B', 'f', 'F', 'z']);\n\nconst ACCEPTED_MULTICODECS: ReadonlySet<number> = new Set([0x55, 0x70, 0x71]);\n\n// Multihash table: code → digest length (bytes).\nconst ACCEPTED_MULTIHASHES: ReadonlyMap<number, number> = new Map([\n [0x12, 32],\n [0xb220, 32],\n]);\n\nexport function validateCidProfile(cid: string): boolean {\n if (cid.length === 0) return false;\n // CIDv0: a base58btc-encoded sha2-256 multihash. Decode the WHOLE string\n // and verify the multihash prefix (0x12 = sha2-256, 0x20 = 32-byte digest)\n // and total length (34 bytes); a `Qm` prefix alone is not sufficient.\n if (cid.startsWith('Qm')) {\n let decoded: Uint8Array;\n try {\n decoded = decodeBase58btc(cid);\n } catch {\n return false;\n }\n return decoded.length === 34 && decoded[0] === 0x12 && decoded[1] === 0x20;\n }\n // CIDv1: multibase + binary CID body.\n const mbPrefix = cid[0]!;\n if (!ACCEPTED_CIDV1_MULTIBASE.has(mbPrefix)) return false;\n let bytes: Uint8Array;\n try {\n bytes = decodeMultibase(mbPrefix, cid.slice(1));\n } catch {\n return false;\n }\n if (bytes.length < 4) return false;\n // CIDv1 layout: <version varint> <multicodec varint> <multihash>\n const versionParse = readVarint(bytes, 0);\n if (versionParse === null || versionParse.value !== 1) return false;\n const codecParse = readVarint(bytes, versionParse.next);\n if (codecParse === null) return false;\n if (!ACCEPTED_MULTICODECS.has(codecParse.value)) return false;\n const mhParse = readVarint(bytes, codecParse.next);\n if (mhParse === null) return false;\n const lenParse = readVarint(bytes, mhParse.next);\n if (lenParse === null) return false;\n const digestLen = lenParse.value;\n const expectedLen = ACCEPTED_MULTIHASHES.get(mhParse.value);\n if (expectedLen === undefined || digestLen !== expectedLen) return false;\n if (lenParse.next + digestLen !== bytes.length) return false;\n return true;\n}\n\nfunction readVarint(bytes: Uint8Array, start: number): { value: number; next: number } | null {\n let value = 0;\n let shift = 0;\n let i = start;\n while (i < bytes.length) {\n const b = bytes[i]!;\n value |= (b & 0x7f) << shift;\n i++;\n if ((b & 0x80) === 0) return { value, next: i };\n shift += 7;\n if (shift > 28) return null; // overflow guard; the profile uses ≤ 16-bit codes\n }\n return null;\n}\n\n// Multibase decoders for the closed set the CID profile admits.\nfunction decodeMultibase(prefix: string, body: string): Uint8Array {\n switch (prefix) {\n case 'b':\n return decodeBase32(body.toLowerCase(), 'rfc4648-lower');\n case 'B':\n return decodeBase32(body.toUpperCase(), 'rfc4648-upper');\n case 'f':\n return decodeBase16(body.toLowerCase());\n case 'F':\n return decodeBase16(body.toUpperCase());\n case 'z':\n return decodeBase58btc(body);\n default:\n throw new Error(`unsupported multibase prefix ${prefix}`);\n }\n}\n\nconst BASE16_LOWER = '0123456789abcdef';\nconst BASE16_UPPER = '0123456789ABCDEF';\n\nfunction decodeBase16(s: string): Uint8Array {\n if (s.length % 2 !== 0) throw new Error('base16: odd-length');\n const out = new Uint8Array(s.length / 2);\n const alphabet = s === s.toLowerCase() ? BASE16_LOWER : BASE16_UPPER;\n for (let i = 0; i < out.length; i++) {\n const hi = alphabet.indexOf(s[i * 2]!);\n const lo = alphabet.indexOf(s[i * 2 + 1]!);\n if (hi < 0 || lo < 0) throw new Error(`base16: non-hex char at ${i * 2}`);\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nconst BASE32_RFC4648_LOWER = 'abcdefghijklmnopqrstuvwxyz234567';\nconst BASE32_RFC4648_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n\nfunction decodeBase32(s: string, variant: 'rfc4648-lower' | 'rfc4648-upper'): Uint8Array {\n const alphabet = variant === 'rfc4648-lower' ? BASE32_RFC4648_LOWER : BASE32_RFC4648_UPPER;\n // Multibase strips padding per spec; accept either form for robustness.\n const trimmed = s.replace(/=+$/, '');\n const out: number[] = [];\n let buf = 0;\n let bits = 0;\n for (const ch of trimmed) {\n const idx = alphabet.indexOf(ch);\n if (idx < 0) throw new Error(`base32: invalid char '${ch}'`);\n buf = (buf << 5) | idx;\n bits += 5;\n if (bits >= 8) {\n bits -= 8;\n out.push((buf >> bits) & 0xff);\n }\n }\n return Uint8Array.from(out);\n}\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\nfunction decodeBase58btc(s: string): Uint8Array {\n if (s.length === 0) return new Uint8Array(0);\n let zeros = 0;\n while (zeros < s.length && s[zeros] === '1') zeros++;\n const size = Math.floor(((s.length - zeros) * 733) / 1000) + 1;\n const b256 = new Uint8Array(size);\n let length = 0;\n for (let i = zeros; i < s.length; i++) {\n const ch = s[i]!;\n const carryIdx = BASE58_ALPHABET.indexOf(ch);\n if (carryIdx < 0) throw new Error(`base58: invalid char '${ch}'`);\n let carry = carryIdx;\n let k = 0;\n for (let j = size - 1; (carry !== 0 || k < length) && j >= 0; j--, k++) {\n carry += 58 * b256[j]!;\n b256[j] = carry % 256;\n carry = Math.floor(carry / 256);\n }\n length = k;\n }\n let it = size - length;\n while (it < size && b256[it] === 0) it++;\n const out = new Uint8Array(zeros + (size - it));\n let j = zeros;\n while (it < size) {\n out[j++] = b256[it++]!;\n }\n return out;\n}\n\n// Hex rendering for byte-equality keys (the duplicate-KEM-material set).\nfunction bytesToHex(bytes: Uint8Array): string {\n let out = '';\n for (const b of bytes) out += b.toString(16).padStart(2, '0');\n return out;\n}\n\n// =============================================================================\n// Exact-integer helpers\n// =============================================================================\n\n// A CBOR unsigned integer as the canonical decoder surfaces it: a\n// non-negative `number` for values up to 2^53 − 1, a non-negative `bigint`\n// above (exact in both representations). A negative value is a different\n// CBOR major type and is never a uint.\nfunction isUint(value: unknown): value is number | bigint {\n if (typeof value === 'number') return Number.isInteger(value) && value >= 0;\n if (typeof value === 'bigint') return value >= 0n;\n return false;\n}\n\nfunction uintWithin(value: number | bigint, min: number, max: number): boolean {\n if (typeof value === 'bigint') return value >= BigInt(min) && value <= BigInt(max);\n return value >= min && value <= max;\n}\n\n// =============================================================================\n// Issue construction and deterministic ordering\n// =============================================================================\n\nfunction issueOf(\n code: ErrorCode,\n path: ReadonlyArray<string | number>,\n message: string,\n): ValidationIssue {\n return { code, path, message, severity: SEVERITY[code] };\n}\n\nconst PATH_UTF8 = new TextEncoder();\n\n// Bytewise comparison of the UTF-8 encodings — the only collation that is\n// byte-stable across runs and across language implementations (no locale\n// tables, no UTF-16 code-unit artefacts for non-BMP keys).\nfunction compareTextSegments(a: string, b: string): number {\n const ab = PATH_UTF8.encode(a);\n const bb = PATH_UTF8.encode(b);\n const n = Math.min(ab.length, bb.length);\n for (let i = 0; i < n; i++) {\n const d = ab[i]! - bb[i]!;\n if (d !== 0) return d;\n }\n return ab.length - bb.length;\n}\n\n// Segment-wise path order: integer segments compare numerically, text\n// segments compare by UTF-8 bytes, an integer segment orders before a text\n// segment where the kinds differ, and a strict prefix orders before its\n// extensions. Issues on an identical path tie-break by the position of their\n// code in the canonical error-code registry.\nfunction compareIssues(a: ValidationIssue, b: ValidationIssue): number {\n const ap = a.path;\n const bp = b.path;\n const n = Math.min(ap.length, bp.length);\n for (let i = 0; i < n; i++) {\n const x = ap[i]!;\n const y = bp[i]!;\n const xIsNum = typeof x === 'number';\n const yIsNum = typeof y === 'number';\n if (xIsNum !== yIsNum) return xIsNum ? -1 : 1;\n if (xIsNum && yIsNum) {\n if (x !== y) return (x as number) < (y as number) ? -1 : 1;\n } else {\n const d = compareTextSegments(x as string, y as string);\n if (d !== 0) return d;\n }\n }\n if (ap.length !== bp.length) return ap.length - bp.length;\n return errorCodeRegistryIndex(a.code) - errorCodeRegistryIndex(b.code);\n}\n\nfunction sortIssues(issues: ReadonlyArray<ValidationIssue>): ValidationIssue[] {\n return [...issues].sort(compareIssues);\n}\n\nfunction valueAtPath(root: unknown, path: ReadonlyArray<string | number>): unknown {\n let cur: unknown = root;\n for (const seg of path) {\n if (cur === null || cur === undefined) return undefined;\n if (cur instanceof Map) {\n cur = cur.get(seg);\n continue;\n }\n if (typeof cur !== 'object') return undefined;\n cur = (cur as Record<string | number, unknown>)[seg];\n }\n return cur;\n}\n","// Label 309 v1 off-host signing helper. The signing key never leaves the user\n// device — this module touches only the public-data inputs (record bytes +\n// pubkey) and the public-data output (the 64-byte Ed25519 signature). The\n// integrator's signer callback owns the private key material.\n//\n// Wire-format invariants enforced by this module:\n// - Sig_structure carries the 25-byte UTF-8 domain prefix\n// `cardano-poe-record-sig-v1` with `external_aad = h''` (RFC 9052 §4.4\n// under the CIP-30 compatibility constraint).\n// - COSE_Sign1 (RFC 9052 §4.2) has a detached payload: COSE_Sign1[2] = CBOR\n// null. CIP-8 `hashed = true` mode places the literal text key\n// `\"hashed\"` in the unprotected header.\n// - Path-1 `kid-as-public-key` convention: 32-byte raw Ed25519 pubkey in\n// protected header label 4; path-1 / path-2 are mutually exclusive on\n// the wire.\n// - `sigs[i].cose_sign1` is a SINGLE byte string carrying the whole\n// COSE_Sign1; the only chunking in the format is the whole-body\n// transport array under metadata label 309.\n//\n// Use cases (the four integration shapes this surface is intended for):\n// 1. AWS KMS `Sign` over the returned Sig_structure bytes — wrap KMS as\n// `(bytes) => Promise<signature>`.\n// 2. Google Cloud HSM — same `(bytes) => Promise<signature>` shape.\n// 3. YubiHSM — local hardware-backed signer; same shape via the YubiHSM SDK.\n// 4. Air-gapped offline signer — transport the Sig_structure bytes via QR /\n// USB / sneakernet to the offline workstation; transport the 64-byte\n// Ed25519 signature back.\n//\n// This module is PATH-1 ONLY. The CIP-30 wallet path (path-2) is handled\n// separately — adding a `cose_key` sidecar here would violate the path-1 /\n// path-2 mutual-exclusion rule (SIG_ENTRY_KID_COSE_KEY_CONFLICT).\n//\n// Hashed-mode (`prepareSigStructureHashed` / `assembleCoseSign1Hashed`) is\n// DISCOURAGED for software off-host signers (AWS KMS, GCP HSM, YubiHSM —\n// each accepts arbitrary-length input) — use the non-hashed mode instead.\n// Hashed mode exists only for hardware co-signers with limited screen /\n// buffer. The verifier MUST recognise the `\"hashed\": true` unprotected-header\n// flag and substitute `Sig_structure[3]` with `Blake2b-224(to_sign)` before\n// strict Ed25519 verification.\n//\n// Privacy contract: the SDK never sees, stores, logs, or transmits any byte\n// string that contains the integrator's Ed25519 private signing key. The\n// integrator's signer handles the seed; this module touches only the 32-byte\n// public key and the 64-byte signature (both public data).\n//\n// The Python SDK carries the same builder (snake_case function names);\n// byte-identical outputs across the two are enforced by a shared\n// known-answer-test corpus.\n\nimport { encodeCanonicalCbor, type CanonicalCborValue } from '@cardanowall/crypto-core/cbor';\nimport {\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES,\n buildLabel309SigStructure,\n buildSigStructure,\n encodeCoseSign1,\n type CoseHeader,\n} from '@cardanowall/crypto-core/cose';\nimport { blake2b224 } from '@cardanowall/crypto-core/hash';\nimport {\n encodeRecordBodyForSigning,\n type PoeRecord,\n type SigEntry,\n} from '@cardanowall/poe-standard';\n\nconst EMPTY_BYTES = new Uint8Array(0);\nconst ED25519_PUBLIC_KEY_LENGTH = 32;\nconst ED25519_SIGNATURE_LENGTH = 64;\n\n// Copy into a freshly allocated buffer so the emitted `sigs[i]` entry owns its\n// bytes (and satisfies the schema's `Uint8Array<ArrayBuffer>` requirement).\nfunction cloneToOwnedBuffer(src: Uint8Array): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(new ArrayBuffer(src.length));\n out.set(src);\n return out;\n}\n\nexport type OffHostSignErrorCode = 'INVALID_PUBKEY_LENGTH' | 'INVALID_SIGNATURE_LENGTH';\n\nexport class OffHostSignError extends Error {\n readonly code: OffHostSignErrorCode;\n\n constructor(code: OffHostSignErrorCode, message: string) {\n super(message);\n this.name = 'OffHostSignError';\n this.code = code;\n }\n}\n\nexport interface PrepareSigStructureArgs {\n readonly record: PoeRecord;\n readonly signerPubkey: Uint8Array;\n}\n\nexport interface PrepareSigStructureResult {\n readonly sigStructureBytes: Uint8Array;\n readonly protectedHeaderBytes: Uint8Array;\n}\n\nexport interface PrepareSigStructureHashedResult extends PrepareSigStructureResult {\n readonly toSignHashBytes: Uint8Array;\n}\n\nexport interface AssembleCoseSign1Args {\n readonly record: PoeRecord;\n readonly signerPubkey: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface AssembleCoseSign1Result {\n readonly coseSign1Bytes: Uint8Array;\n readonly sigEntry: SigEntry;\n}\n\n// `to_sign = utf8(\"cardano-poe-record-sig-v1\") || canonical_cbor(record_body_minus_sigs)`.\n// The first 25 bytes are byte-pinned to the prefix constant; bytes 25..end\n// are the canonical CBOR of the record body with `sigs` removed.\nexport function buildToSign(record: PoeRecord): Uint8Array {\n const body = encodeRecordBodyForSigning(record);\n const out = new Uint8Array(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + body.length);\n out.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n out.set(body, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n return out;\n}\n\n// Path-1 protected header canonical CBOR for `{1: -8, 4: <signerPubkey>}`.\n// Always 38 bytes: `a2 01 27 04 58 20 || <32-byte pubkey>`.\nfunction encodePath1ProtectedHeader(signerPubkey: Uint8Array): {\n protectedHeader: CoseHeader;\n protectedHeaderBytes: Uint8Array;\n} {\n const protectedHeader: CoseHeader = new Map<number | string, unknown>([\n [1, -8],\n [4, signerPubkey],\n ]);\n const protectedHeaderBytes = encodeCanonicalCbor(protectedHeader as CanonicalCborValue);\n return { protectedHeader, protectedHeaderBytes };\n}\n\n// Returns the full `Sig_structure = [ \"Signature1\", protected_bytes, h'', to_sign ]`\n// canonical-CBOR bytes that the off-host signer feeds verbatim to Ed25519.\n// `protectedHeaderBytes` is exposed so integrators can byte-compare against\n// fixtures (always 38 bytes for the path-1 `{1:-8, 4:<pub>}` map).\nexport function prepareSigStructure(args: PrepareSigStructureArgs): PrepareSigStructureResult {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n const { protectedHeaderBytes } = encodePath1ProtectedHeader(args.signerPubkey);\n const recordBodyCbor = encodeRecordBodyForSigning(args.record);\n const sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: protectedHeaderBytes,\n recordBodyCbor,\n });\n return { sigStructureBytes, protectedHeaderBytes };\n}\n\n// Assembles `COSE_Sign1 = [ protected_bytes, unprotected_map, null, signature ]`\n// (detached payload, `alg = -8`, protected `kid = signerPubkey`) and emits a\n// path-1-only `{cose_sign1}` `sigs[i]` entry carrying the whole blob as one\n// byte string.\nexport function assembleCoseSign1(args: AssembleCoseSign1Args): AssembleCoseSign1Result {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n if (args.signature.length !== ED25519_SIGNATURE_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_SIGNATURE_LENGTH',\n `signature must be 64 bytes (Ed25519 raw signature), got ${args.signature.length}`,\n );\n }\n const { protectedHeader } = encodePath1ProtectedHeader(args.signerPubkey);\n const coseSign1Bytes = encodeCoseSign1({\n protectedHeader,\n unprotectedHeader: new Map(),\n payload: null,\n signature: args.signature,\n });\n const sigEntry: SigEntry = { cose_sign1: cloneToOwnedBuffer(coseSign1Bytes) };\n return { coseSign1Bytes, sigEntry };\n}\n\n// CIP-8 `hashed = true` companion. Substitutes `Sig_structure[3]` with\n// `Blake2b-224(to_sign)`. The hash covers the ENTIRE `to_sign` payload\n// (i.e. `utf8(prefix) || record_body_cbor`) — keeping the 25-byte domain\n// separator inside the hash boundary preserves cross-protocol replay\n// protection even in hashed mode.\n//\n// DISCOURAGED for software off-host signers; use only for hardware co-signers\n// with screen / buffer constraints.\nexport function prepareSigStructureHashed(\n args: PrepareSigStructureArgs,\n): PrepareSigStructureHashedResult {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n const { protectedHeaderBytes } = encodePath1ProtectedHeader(args.signerPubkey);\n const toSign = buildToSign(args.record);\n const toSignHashBytes = blake2b224(toSign);\n const sigStructureBytes = buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: protectedHeaderBytes,\n externalAad: EMPTY_BYTES,\n payload: toSignHashBytes,\n });\n return { sigStructureBytes, protectedHeaderBytes, toSignHashBytes };\n}\n\n// Assemble hashed-mode COSE_Sign1. The unprotected header carries\n// `\"hashed\": true` (text key), signalling to the verifier that the\n// Blake2b-224 substitution applies.\nexport function assembleCoseSign1Hashed(args: AssembleCoseSign1Args): AssembleCoseSign1Result {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n if (args.signature.length !== ED25519_SIGNATURE_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_SIGNATURE_LENGTH',\n `signature must be 64 bytes (Ed25519 raw signature), got ${args.signature.length}`,\n );\n }\n const { protectedHeader } = encodePath1ProtectedHeader(args.signerPubkey);\n const unprotectedHeader: CoseHeader = new Map<number | string, unknown>([['hashed', true]]);\n const coseSign1Bytes = encodeCoseSign1({\n protectedHeader,\n unprotectedHeader,\n payload: null,\n signature: args.signature,\n });\n const sigEntry: SigEntry = { cose_sign1: cloneToOwnedBuffer(coseSign1Bytes) };\n return { coseSign1Bytes, sigEntry };\n}\n","// RFC 7807 `application/problem+json` envelope and the typed error class\n// hierarchy the SDK throws on every non-2xx response.\n//\n// Every Label 309 gateway `/api/v1/*` route emits the canonical shape:\n//\n// Content-Type: application/problem+json\n// {\n// \"type\": \"about:blank\",\n// \"title\": \"Payment Required\",\n// \"status\": 402,\n// \"detail\": \"Required $0.18 for this publish; balance is $0.05.\",\n// \"code\": \"insufficient-funds\",\n// \"trace_id\": \"01977c...\",\n// \"errors\": [{\"field\": \"items.0.hashes\", \"code\": \"invalid_type\", \"detail\": \"...\"}],\n// <extension members per RFC 7807 §3.2, e.g. balance_usd_micros / required_usd_micros>\n// }\n//\n// Field semantics:\n// - `code` is lowercase-kebab. Consumers dispatch on `code`; the SDK already\n// dispatches on `code` to pick the most-specific subclass.\n// - `status` matches the HTTP status. `httpStatus` is a convenience alias.\n// - `errors[]` carries per-field validation errors (Zod-derived on the\n// server). `field` is the dotted JSON path; empty string denotes a\n// body-level issue.\n// - `trace_id` is echoed on the `X-Request-Id` response header for log\n// correlation. Use `err.traceId` when filing bug reports (the SDK\n// surfaces it as the camelCase `traceId` property — only the wire field\n// is snake_case, to match the rest of the API surface).\n// - Extension members (anything outside the canonical seven fields) are\n// surfaced on `err.extensions`. Typed subclasses project the relevant\n// extension fields onto camelCase getters (e.g. `top_up_url` → `topUpUrl`).\n\n/** RFC 7807 per-field error entry. */\nexport interface ProblemErrorEntry {\n /** Dotted JSON path of the offending field; empty for body-level errors. */\n readonly field: string;\n /** Stable lowercase-kebab (or Zod issue) code for the specific failure. */\n readonly code: string;\n /** Human-readable explanation of this individual field error. */\n readonly detail: string;\n}\n\n/**\n * RFC 7807 `application/problem+json` document as emitted by every Label 309\n * gateway `/api/v1/*` route.\n *\n * Canonical fields (`type`, `title`, `status`, `detail`, `code`, `trace_id`)\n * are always present. `errors` is present on validation responses.\n * `instance` is optional per RFC 7807 §3.1.\n *\n * Additional top-level fields are RFC 7807 §3.2 extension members and are\n * preserved verbatim on `Label309HttpError.extensions`.\n */\nexport interface ProblemDetails {\n readonly type: string;\n readonly title: string;\n readonly status: number;\n readonly detail: string;\n readonly code: string;\n readonly trace_id: string;\n readonly errors?: ReadonlyArray<ProblemErrorEntry>;\n readonly instance?: string;\n /** RFC 7807 §3.2 extension members. */\n readonly [extension: string]: unknown;\n}\n\n/** The set of canonical RFC 7807 fields, used to split extensions cleanly. */\nconst CANONICAL_PROBLEM_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'title',\n 'status',\n 'detail',\n 'code',\n 'trace_id',\n 'errors',\n 'instance',\n]);\n\n/**\n * Pull RFC 7807 §3.2 extension members out of a problem document. The result\n * is a fresh object containing every top-level key that is NOT one of the\n * canonical fields above.\n */\nexport function extractProblemExtensions(problem: ProblemDetails): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(problem)) {\n if (!CANONICAL_PROBLEM_KEYS.has(key)) {\n out[key] = value;\n }\n }\n return out;\n}\n\nexport interface Label309HttpErrorInit {\n /** The verbatim problem document. */\n readonly problem: ProblemDetails;\n /** Pre-split extension members. Computed from `problem` when omitted. */\n readonly extensions?: Record<string, unknown>;\n /** Value of the `X-Request-Id` response header. Falls back to `problem.trace_id`. */\n readonly requestId?: string | undefined;\n /** Value of the `Retry-After` response header (seconds), if present. */\n readonly retryAfterSeconds?: number | undefined;\n}\n\n/**\n * Parent class for every typed SDK HTTP error. Carries the full RFC 7807\n * problem document plus headers (`X-Request-Id`, `Retry-After`) relevant for\n * retry logic and log correlation.\n *\n * Consumers can dispatch on:\n * - `err.code` — lowercase-kebab problem code\n * - `err.httpStatus` — HTTP status (= `err.problem.status`)\n * - `instanceof <SpecificError>` — see the subclasses re-exported from\n * `@cardanowall/sdk-ts`\n */\nexport class Label309HttpError extends Error {\n public readonly problem: ProblemDetails;\n public readonly code: string;\n public readonly httpStatus: number;\n public readonly title: string;\n public readonly detail: string;\n public readonly type: string;\n public readonly traceId: string;\n public readonly instance: string | undefined;\n public readonly errors: ReadonlyArray<ProblemErrorEntry> | undefined;\n public readonly extensions: Record<string, unknown>;\n public readonly requestId: string;\n public readonly retryAfterSeconds: number | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init.problem.detail || `${init.problem.title} (HTTP ${init.problem.status})`);\n this.name = 'Label309HttpError';\n this.problem = init.problem;\n this.code = init.problem.code;\n this.httpStatus = init.problem.status;\n this.title = init.problem.title;\n this.detail = init.problem.detail;\n this.type = init.problem.type;\n this.traceId = init.problem.trace_id;\n this.instance = init.problem.instance;\n this.errors = init.problem.errors;\n this.extensions = init.extensions ?? extractProblemExtensions(init.problem);\n // X-Request-Id falls back to the in-body trace_id so callers always have a\n // correlation handle even when the header is stripped by a proxy.\n this.requestId = init.requestId ?? init.problem.trace_id;\n this.retryAfterSeconds = init.retryAfterSeconds;\n }\n}\n","// 400 batch-empty — the `records[]` array on `/api/v1/poe/publish-batch` was\n// empty. The batch endpoint requires at least one record.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class BatchEmptyError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'BatchEmptyError';\n }\n}\n","// 400 batch-too-large — the `records[]` array on `/api/v1/poe/publish-batch`\n// carries more entries than the per-call ceiling (max 50).\n//\n// Wire-format extension members:\n// { \"max\": <int>, \"got\": <int> }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readInt(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nexport class BatchTooLargeError extends Label309HttpError {\n public readonly max: number | undefined;\n public readonly got: number | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'BatchTooLargeError';\n this.max = readInt(this.extensions['max']);\n this.got = readInt(this.extensions['got']);\n }\n}\n","// 403 Forbidden — the caller is authenticated but lacks permission. Covers\n// the generic `forbidden` code plus the edge-proxy `csrf-invalid` flavour;\n// scope-specific failures surface as `InsufficientScopeError` instead.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class ForbiddenError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'ForbiddenError';\n }\n}\n","// 409 idempotency-key-conflict — the supplied `Idempotency-Key` has been\n// seen before with a different request body within its 24h TTL window.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class IdempotencyConflictError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'IdempotencyConflictError';\n }\n}\n","// 402 insufficient-funds — the caller's balance with the gateway is below the\n// cost of the requested operation. This is the generic paid-gateway \"balance\n// too low\" signal; how a particular gateway prices operations and tops up\n// balances is its own concern.\n//\n// Wire-format extension members (RFC 7807 §3.2). Money fields land as decimal\n// strings so JSON parsing preserves bigint precision in callers that parse to\n// Number by default:\n//\n// {\n// \"balance_usd_micros\": \"<decimal string>\",\n// \"required_usd_micros\": \"<decimal string>\",\n// \"top_up_url\": \"<gateway-provided URL, optional>\"\n// }\n//\n// Field-name mapping (wire → SDK):\n// balance_usd_micros → balanceUsdMicros (string → bigint)\n// required_usd_micros → requiredUsdMicros (string → bigint)\n// top_up_url → topUpUrl (snake_case → camelCase)\n//\n// Idempotency contract: a 402 is \"non-committing\" — the gateway does NOT cache\n// the response under the request's Idempotency-Key. After raising the balance,\n// the SDK consumer MAY retry with the SAME Idempotency-Key within the gateway's\n// TTL window; the handler runs fresh and (assuming the balance now suffices)\n// the retry returns 202 with a freshly assigned `id`.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readBigIntString(value: unknown): bigint | undefined {\n if (typeof value !== 'string') return undefined;\n if (!/^-?[0-9]+$/.test(value)) return undefined;\n try {\n return BigInt(value);\n } catch {\n return undefined;\n }\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class InsufficientFundsError extends Label309HttpError {\n public readonly balanceUsdMicros: bigint | undefined;\n public readonly requiredUsdMicros: bigint | undefined;\n public readonly topUpUrl: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InsufficientFundsError';\n this.balanceUsdMicros = readBigIntString(this.extensions['balance_usd_micros']);\n this.requiredUsdMicros = readBigIntString(this.extensions['required_usd_micros']);\n this.topUpUrl = readString(this.extensions['top_up_url']);\n }\n}\n","// 403 insufficient-scope — the API key authenticated but does not grant the\n// scope required for the endpoint.\n//\n// Wire-format extension members:\n// { \"required\": [\"poe:create\"], \"granted\": [\"poe:read\", \"account:read\"] }\n//\n// Both arrays are surfaced verbatim on the typed error. `requiredScope` is a\n// convenience for the common single-scope case (the server emits a one-element\n// `required` array today).\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readScopeArray(value: unknown): ReadonlyArray<string> {\n if (!Array.isArray(value)) return [];\n return value.filter((entry): entry is string => typeof entry === 'string');\n}\n\nexport class InsufficientScopeError extends Label309HttpError {\n public readonly requiredScopes: ReadonlyArray<string>;\n public readonly grantedScopes: ReadonlyArray<string>;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InsufficientScopeError';\n this.requiredScopes = readScopeArray(this.extensions['required']);\n this.grantedScopes = readScopeArray(this.extensions['granted']);\n }\n\n /** Convenience for the single-scope case; first entry of `requiredScopes`. */\n get requiredScope(): string | undefined {\n return this.requiredScopes[0];\n }\n}\n","// 500 internal-error — unexpected server-side failure. The detail message\n// is deliberately generic; correlate the failure via `err.traceId` in\n// server logs.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class InternalServerError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InternalServerError';\n }\n}\n","// 400 invalid-body — the request body was structurally malformed (e.g. not\n// valid JSON, or a higher-level shape check failed before Zod ran). Schema\n// validation failures emit `validation-failed` (→ `ValidationFailedError`)\n// instead.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class InvalidBodyError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InvalidBodyError';\n }\n}\n","// 400 malformed-cbor — the `record_bytes` payload could not be parsed as\n// canonical CBOR per the Label 309 deterministic encoding rules.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class MalformedCborError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'MalformedCborError';\n }\n}\n","// 404 not-found — generic missing-resource response. Domain-specific 404s\n// (notably `record-not-found`) deserialise to their own subclass.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class NotFoundError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'NotFoundError';\n }\n}\n","// 409 quote-already-consumed — the publish quote referenced by `quote_id`\n// has already been used by a prior /publish call. Quotes are single-use; a\n// freshly-issued quote covers exactly one PoE submission. The caller should\n// request a fresh quote via POST /api/v1/poe/quote and retry.\n//\n// Wire-format extension members (RFC 7807 §3.2):\n// { \"quote_id\": \"<uuid>\" }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class QuoteAlreadyConsumedError extends Label309HttpError {\n public readonly quoteId: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'QuoteAlreadyConsumedError';\n this.quoteId = readString(this.extensions['quote_id']);\n }\n}\n","// 410 quote-expired — the publish quote referenced by `quote_id` exceeded\n// its TTL (15 minutes from issuance) before /publish consumed it. The\n// caller should request a fresh quote via POST /api/v1/poe/quote and retry.\n//\n// Wire-format extension members (RFC 7807 §3.2):\n// { \"quote_id\": \"<uuid>\" }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class QuoteExpiredError extends Label309HttpError {\n public readonly quoteId: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'QuoteExpiredError';\n this.quoteId = readString(this.extensions['quote_id']);\n }\n}\n","// 404 quote-not-found — the supplied `quote_id` does not exist for the\n// authenticated account. Either the UUID is wrong, or the quote belongs to\n// a different account (the server enforces account scoping on quote rows).\n//\n// Wire-format extension members (RFC 7807 §3.2):\n// { \"quote_id\": \"<uuid>\" }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class QuoteNotFoundError extends Label309HttpError {\n public readonly quoteId: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'QuoteNotFoundError';\n this.quoteId = readString(this.extensions['quote_id']);\n }\n}\n","// 429 rate-limited — the caller exceeded the per-key request quota.\n//\n// The retry hint lives on the standard `Retry-After` HTTP response header\n// (RFC 9110 §10.2.3). The SDK parses it into `retryAfterSeconds` on the\n// thrown error; the value is undefined if the header is absent or\n// non-numeric. Per RFC 7807, no retry hint appears in the problem body.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class RateLimitedError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'RateLimitedError';\n }\n}\n","// 404 record-not-found — no Label 309 record is registered for the requested\n// tx_hash.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class RecordNotFoundError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'RecordNotFoundError';\n }\n}\n","// 503 service-unavailable — temporary inability to serve the request. The\n// retry hint, if any, is on the standard `Retry-After` header — surfaced on\n// `err.retryAfterSeconds`.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class ServiceUnavailableError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'ServiceUnavailableError';\n }\n}\n","// 401 Unauthorized — caller is not authenticated. The server emits this when\n// the `Authorization: Bearer` header is missing, malformed, or names a\n// revoked / unknown API key.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class UnauthorizedError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'UnauthorizedError';\n }\n}\n","// 400 validation-failed — the request body parsed as JSON but failed the\n// route's schema check. The per-field issues live on `err.errors[]` (Zod\n// issue codes; e.g. `invalid_type`, `too_small`, `custom`).\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class ValidationFailedError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'ValidationFailedError';\n }\n}\n","// Decodes an RFC 7807 `application/problem+json` body into the most-specific\n// `Label309HttpError` subclass.\n//\n// Dispatch order:\n// 1. By `code` (lowercase-kebab) — preferred. Each registered code maps to a\n// named subclass with typed projections of its extension members.\n// 2. By HTTP status, when the body is missing/non-conforming. In that case\n// we synthesise a minimal `ProblemDetails` so consumers always see a\n// well-formed `err.problem`.\n//\n// The dispatcher is intentionally exhaustive over the codes the API emits;\n// codes the SDK doesn't recognise fall through to the parent\n// `Label309HttpError` with the verbatim problem document.\n// Forward-compatibility: a server can introduce new codes without breaking\n// older SDKs — consumers either catch the parent class or dispatch on\n// `err.code` directly.\n\nimport { BatchEmptyError } from './batch-empty-error';\nimport { BatchTooLargeError } from './batch-too-large-error';\nimport { ForbiddenError } from './forbidden-error';\nimport {\n Label309HttpError,\n extractProblemExtensions,\n type ProblemDetails,\n type ProblemErrorEntry,\n} from './http-error';\nimport { IdempotencyConflictError } from './idempotency-conflict-error';\nimport { InsufficientFundsError } from './insufficient-funds-error';\nimport { InsufficientScopeError } from './insufficient-scope-error';\nimport { InternalServerError } from './internal-server-error';\nimport { InvalidBodyError } from './invalid-body-error';\nimport { MalformedCborError } from './malformed-cbor-error';\nimport { NotFoundError } from './not-found-error';\nimport { QuoteAlreadyConsumedError } from './quote-already-consumed-error';\nimport { QuoteExpiredError } from './quote-expired-error';\nimport { QuoteNotFoundError } from './quote-not-found-error';\nimport { RateLimitedError } from './rate-limited-error';\nimport { RecordNotFoundError } from './record-not-found-error';\nimport { ServiceUnavailableError } from './service-unavailable-error';\nimport { UnauthorizedError } from './unauthorized-error';\nimport { ValidationFailedError } from './validation-failed-error';\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction asProblemErrorEntries(value: unknown): readonly ProblemErrorEntry[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const out: ProblemErrorEntry[] = [];\n for (const entry of value) {\n if (entry === null || typeof entry !== 'object') continue;\n const e = entry as Record<string, unknown>;\n out.push({\n field: typeof e['field'] === 'string' ? e['field'] : '',\n code: typeof e['code'] === 'string' ? e['code'] : '',\n detail: typeof e['detail'] === 'string' ? e['detail'] : '',\n });\n }\n return out;\n}\n\n/** Synthesise a minimal `ProblemDetails` for non-conforming bodies. */\nfunction synthesiseProblem(httpStatus: number, requestId: string | undefined): ProblemDetails {\n const code = `http-${httpStatus}`;\n return {\n type: `about:blank`,\n title: `HTTP ${httpStatus}`,\n status: httpStatus,\n detail: `Server returned HTTP ${httpStatus} without a problem+json body.`,\n code,\n trace_id: requestId ?? '',\n };\n}\n\nfunction toProblemDetails(\n httpStatus: number,\n body: unknown,\n requestId: string | undefined,\n): ProblemDetails {\n if (body === null || typeof body !== 'object') {\n return synthesiseProblem(httpStatus, requestId);\n }\n const b = body as Record<string, unknown>;\n // Heuristic: a real RFC 7807 body has at minimum `code` and `status` or\n // `title`. If neither is present we treat the body as non-conforming.\n const code = asString(b['code']);\n const status = asNumber(b['status']) ?? httpStatus;\n const title = asString(b['title']);\n if (code === undefined && title === undefined) {\n return synthesiseProblem(httpStatus, requestId);\n }\n const errors = asProblemErrorEntries(b['errors']);\n // Preserve every top-level field. `code`/`title`/`status` fall back when\n // the server omitted them; everything else flows through verbatim as\n // RFC 7807 §3.2 extension members.\n const base: Record<string, unknown> = {\n ...b,\n // RFC 7807 §4.2: `about:blank` is the default when no type URI is supplied.\n // The client is gateway-agnostic, so it must not invent a vendor-specific\n // problem-type namespace; the machine-readable discriminator is `code`.\n type: asString(b['type']) ?? 'about:blank',\n title: title ?? `HTTP ${status}`,\n status,\n detail: asString(b['detail']) ?? '',\n code: code ?? `http-${status}`,\n trace_id: asString(b['trace_id']) ?? requestId ?? '',\n };\n if (errors !== undefined) base['errors'] = errors;\n return base as ProblemDetails;\n}\n\nexport interface ParseHttpErrorArgs {\n readonly httpStatus: number;\n readonly body: unknown;\n /** `X-Request-Id` header from the response, when available. */\n readonly requestId?: string | undefined;\n /** `Retry-After` header from the response, parsed as integer seconds. */\n readonly retryAfterSeconds?: number | undefined;\n}\n\nexport function parseHttpError(args: ParseHttpErrorArgs): Label309HttpError {\n const problem = toProblemDetails(args.httpStatus, args.body, args.requestId);\n const extensions = extractProblemExtensions(problem);\n const init = {\n problem,\n extensions,\n requestId: args.requestId,\n retryAfterSeconds: args.retryAfterSeconds,\n } as const;\n\n switch (problem.code) {\n case 'unauthorized':\n return new UnauthorizedError(init);\n case 'forbidden':\n case 'csrf-invalid':\n return new ForbiddenError(init);\n case 'insufficient-scope':\n return new InsufficientScopeError(init);\n // The three 402 funding/affordability failures are one condition to a\n // caller: the account cannot fund the operation. `insufficient-funds` is the\n // balance shortfall; `insufficient-storage-credit` is the storage funding\n // source being out of credit; `no-funding-grant` is the absence of any\n // funding source entitling the account beyond the free window. All three\n // surface as the same funding error so a caller routes the user to top up\n // without branching on the code.\n case 'insufficient-funds':\n case 'insufficient-storage-credit':\n case 'no-funding-grant':\n return new InsufficientFundsError(init);\n case 'quote-expired':\n return new QuoteExpiredError(init);\n case 'quote-not-found':\n return new QuoteNotFoundError(init);\n case 'quote-already-consumed':\n return new QuoteAlreadyConsumedError(init);\n case 'not-found':\n return new NotFoundError(init);\n case 'record-not-found':\n return new RecordNotFoundError(init);\n case 'idempotency-key-conflict':\n return new IdempotencyConflictError(init);\n case 'rate-limited':\n return new RateLimitedError(init);\n case 'validation-failed':\n return new ValidationFailedError(init);\n case 'invalid-body':\n return new InvalidBodyError(init);\n case 'malformed-cbor':\n return new MalformedCborError(init);\n case 'batch-too-large':\n return new BatchTooLargeError(init);\n case 'batch-empty':\n return new BatchEmptyError(init);\n case 'internal-error':\n return new InternalServerError(init);\n // A gateway that prices on a live FX oracle may surface a transient\n // `fx-stale` pricing outage; to a vendor-neutral client that is just a\n // temporary inability to serve, i.e. a service-unavailable condition.\n case 'service-unavailable':\n case 'fx-stale':\n return new ServiceUnavailableError(init);\n default:\n return new Label309HttpError(init);\n }\n}\n","// Shared response-handling helpers for the HTTP client namespaces (poe,\n// records, account). They parse the body, lift `X-Request-Id` /\n// `Retry-After`, and throw a typed `Label309HttpError` on non-2xx the same\n// way, so the logic lives here once.\n\nimport { parseHttpError } from './parse-http-error';\n\n/** Parse a JSON response body; returns `null` for empty or non-JSON bodies. */\nexport async function readJson(response: Response): Promise<unknown> {\n const text = await response.text();\n if (text.length === 0) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\n/** Parse the `Retry-After` header as integer seconds; `undefined` when absent or non-numeric. */\nexport function parseRetryAfter(header: string | null): number | undefined {\n if (header === null) return undefined;\n const parsed = Number(header);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Throw the most-specific `Label309HttpError` subclass on a non-2xx\n * response (decoding the RFC 7807 body, request id, and retry-after); no-op on\n * 2xx so callers can `await throwIfNotOk(res)` before reading the success body.\n */\nexport async function throwIfNotOk(response: Response): Promise<void> {\n if (response.ok) return;\n const body = await readJson(response);\n const requestId = response.headers.get('x-request-id') ?? undefined;\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n throw parseHttpError({ httpStatus: response.status, body, requestId, retryAfterSeconds });\n}\n","// `client.account.*` wraps the account read surface:\n//\n// GET /api/v1/account/balance → account.balance()\n//\n// Auth is required (Bearer with `account:read` scope, or a session cookie when\n// the gateway is browser-fronted). The configured API key is forwarded as\n// `Authorization: Bearer …`.\n//\n// The balance is USD micro-cents carried as a decimal string on the wire\n// (`balance_usd_micros`). The SDK preserves it verbatim as a string —\n// `AccountBalance.balanceUsdMicros` — and never coerces it to a JS number, so\n// the bigint value survives without precision loss.\n\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport type { AccountBalance, FetchImpl } from './types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nfunction buildHeaders(apiKey: string | undefined): Headers {\n const headers = new Headers({\n 'content-type': 'application/json',\n accept: 'application/json',\n });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n return headers;\n}\n\ninterface AccountBalanceWire {\n readonly balance_usd_micros: string;\n}\n\nexport class AccountNamespace {\n private readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * Fetch the caller's current prepaid USD balance.\n *\n * Returns `{ balanceUsdMicros }`, the gateway's `balance_usd_micros` field\n * (USD micro-cents as a decimal string). The string is preserved verbatim —\n * never parsed into a number — so no precision is lost. An account with no\n * ledger activity yet reads `\"0\"`.\n *\n * Requires authentication: 401 (UnauthorizedError) when anonymous, 403\n * (InsufficientScopeError) when the Bearer key lacks the `account:read`\n * scope.\n */\n async balance(): Promise<AccountBalance> {\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/account/balance`, {\n method: 'GET',\n headers: buildHeaders(this.config.apiKey),\n });\n await throwIfNotOk(response);\n const body = (await readJson(response)) as AccountBalanceWire;\n return { balanceUsdMicros: body.balance_usd_micros };\n }\n}\n","// Raised synchronously from the Label309Client constructor when the config\n// cannot be resolved into a usable gateway target. The single trigger: a\n// missing or empty `baseUrl`. The client is gateway-agnostic and has no default\n// deployment, so a base URL must always be supplied. The `apiKey` is an opaque\n// bearer token and is never the cause of this error.\n\nexport class InvalidClientConfigError extends Error {\n public readonly code = 'INVALID_CLIENT_CONFIG' as const;\n constructor(message: string) {\n super(message);\n this.name = 'InvalidClientConfigError';\n }\n}\n","// Lowercase, no-`0x`-prefix hex encoder shared across the SDK. Single\n// implementation so the verifier, the wire serialiser, and the publish client\n// all emit byte-identical hex (the Python parity twin and the cross-language\n// fixtures depend on this exact form).\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n","// Raised by the high-level helpers (`publishSealed`, `publishMerkle`) when\n// one or more files uploaded via /poe/uploads come back with `ok: false`.\n//\n// The error carries the full `UploadsResponse` so callers can:\n// - retry just the failed indices (use `failedIndices` to subset their input)\n// - inspect per-file `error.code` / `error.detail` for diagnostics\n// - see which files DID land (already-uploaded files are billed and the\n// URIs remain valid; reuploading them would double-charge)\n\nimport type { UploadFailureEntry, UploadsResponse } from './types';\n\nexport class PartialUploadError extends Error {\n public readonly response: UploadsResponse;\n public readonly failed: ReadonlyArray<UploadFailureEntry>;\n\n constructor(response: UploadsResponse) {\n const failed = response.uploads.filter((u): u is UploadFailureEntry => u.ok === false);\n super(\n `${failed.length} of ${response.uploads.length} upload(s) failed: ${failed\n .map((f) => `[${f.idx}] ${f.error.code} — ${f.error.detail}`)\n .join('; ')}`,\n );\n this.name = 'PartialUploadError';\n this.response = response;\n this.failed = failed;\n }\n\n /** Convenience: the `idx` of every failed entry, in input order. */\n get failedIndices(): ReadonlyArray<number> {\n return this.failed.map((f) => f.idx);\n }\n}\n","// Canonical-CBOR codec for the off-chain Merkle leaves-list artefact.\n// The on-chain `merkle[]` field binds to this file via `uris[]` / `leaf_count`;\n// the file itself carries the full leaf set. Canonical CBOR is RFC 8949 §4.2.1.\n//\n// CDDL:\n//\n// leaves-list = {\n// \"format\": \"cardano-poe-merkle-leaves-v1\",\n// \"tree_alg\": \"rfc9162-sha256\",\n// \"root\": bytes .size 32,\n// \"leaves\": [ + bytes .size 32 ],\n// \"leaf_count\": uint,\n// ? \"leaf_alg\": tstr,\n// }\n//\n// Canonical ordering is bytewise-lexicographic on encoded map keys (RFC 8949\n// §4.2.1) so the wire-key order is fixed by `cde:true` regardless of insertion\n// order: root (4B) < format (6B) < leaves (6B) < leaf_alg (8B) < tree_alg (8B)\n// < leaf_count (10B).\n\nimport { decodeCanonicalCbor, encodeCanonicalCbor } from '../cbor/canonical';\nimport { compareCt } from '../util/compare-ct';\nimport { merkleSha2256Root } from '../hash/merkle-sha2-256';\n\nexport const LEAVES_LIST_FORMAT_V1 = 'cardano-poe-merkle-leaves-v1' as const;\nconst TREE_ALG_RFC9162 = 'rfc9162-sha256' as const;\nconst DIGEST_LENGTH = 32;\nconst REGISTERED_FORMATS = new Set<string>([LEAVES_LIST_FORMAT_V1]);\n\nexport type MerkleLeavesListErrorCode =\n | 'SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED'\n | 'SCHEMA_MERKLE_LEAVES_MALFORMED'\n | 'SCHEMA_MERKLE_LEAF_COUNT_MISMATCH'\n | 'MERKLE_ROOT_MISMATCH';\n\nexport class MerkleLeavesListError extends Error {\n readonly code: MerkleLeavesListErrorCode;\n constructor(code: MerkleLeavesListErrorCode, message?: string) {\n super(message ? `${code}: ${message}` : code);\n this.code = code;\n this.name = 'MerkleLeavesListError';\n }\n}\n\nexport interface EncodeLeavesListArgs {\n readonly leaves: ReadonlyArray<Uint8Array>;\n readonly root: Uint8Array;\n readonly leafAlg?: string;\n}\n\nexport interface DecodedLeavesList {\n readonly format: typeof LEAVES_LIST_FORMAT_V1;\n readonly treeAlg: typeof TREE_ALG_RFC9162;\n readonly root: Uint8Array;\n readonly leaves: Uint8Array[];\n readonly leafCount: number;\n readonly leafAlg?: string;\n}\n\nexport function encodeLeavesList(args: EncodeLeavesListArgs): Uint8Array {\n if (!(args.root instanceof Uint8Array) || args.root.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `root must be a Uint8Array(${DIGEST_LENGTH})`,\n );\n }\n if (args.leaves.length < 1) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaves array must be non-empty',\n );\n }\n const leavesCopy: Uint8Array[] = [];\n for (let i = 0; i < args.leaves.length; i++) {\n const leaf = args.leaves[i];\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `leaves[${i}] must be a Uint8Array(${DIGEST_LENGTH})`,\n );\n }\n leavesCopy.push(leaf);\n }\n if (args.leafAlg !== undefined && typeof args.leafAlg !== 'string') {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_alg must be a string when present',\n );\n }\n const map: Record<string, unknown> = {\n format: LEAVES_LIST_FORMAT_V1,\n tree_alg: TREE_ALG_RFC9162,\n root: args.root,\n leaves: leavesCopy,\n leaf_count: leavesCopy.length,\n };\n if (args.leafAlg !== undefined) {\n map['leaf_alg'] = args.leafAlg;\n }\n return encodeCanonicalCbor(map as never);\n}\n\nexport function decodeLeavesList(bytes: Uint8Array): DecodedLeavesList {\n const decoded = decodeCanonicalCbor(bytes);\n if (typeof decoded !== 'object' || decoded === null || Array.isArray(decoded)) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaves-list MUST be a CBOR map',\n );\n }\n const m = decoded as Record<string, unknown>;\n\n const format = m['format'];\n if (typeof format !== 'string') {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'format must be a text string',\n );\n }\n if (!REGISTERED_FORMATS.has(format)) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED',\n `format '${format}' is not in the registered set`,\n );\n }\n\n const treeAlg = m['tree_alg'];\n if (treeAlg !== TREE_ALG_RFC9162) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `tree_alg '${String(treeAlg)}' is not '${TREE_ALG_RFC9162}'`,\n );\n }\n\n const root = m['root'];\n if (!(root instanceof Uint8Array) || root.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `root must be a ${DIGEST_LENGTH}-byte byte string`,\n );\n }\n\n const leavesRaw = m['leaves'];\n if (!Array.isArray(leavesRaw) || leavesRaw.length < 1) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaves must be a non-empty array',\n );\n }\n const leaves: Uint8Array[] = [];\n for (let i = 0; i < leavesRaw.length; i++) {\n const leaf = leavesRaw[i];\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `leaves[${i}] must be a ${DIGEST_LENGTH}-byte byte string`,\n );\n }\n leaves.push(leaf);\n }\n\n const leafCountRaw = m['leaf_count'];\n let leafCount: number;\n if (typeof leafCountRaw === 'number' && Number.isInteger(leafCountRaw) && leafCountRaw >= 0) {\n leafCount = leafCountRaw;\n } else if (typeof leafCountRaw === 'bigint' && leafCountRaw >= 0n) {\n if (leafCountRaw > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_count exceeds Number.MAX_SAFE_INTEGER',\n );\n }\n leafCount = Number(leafCountRaw);\n } else {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_count must be a non-negative CBOR uint',\n );\n }\n if (leaves.length !== leafCount) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAF_COUNT_MISMATCH',\n `leaves.length (${leaves.length}) != leaf_count (${leafCount})`,\n );\n }\n\n let leafAlg: string | undefined;\n if (m['leaf_alg'] !== undefined) {\n if (typeof m['leaf_alg'] !== 'string') {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_alg must be a text string when present',\n );\n }\n leafAlg = m['leaf_alg'];\n }\n\n const recomputed = merkleSha2256Root(leaves);\n if (!compareCt(recomputed, root)) {\n throw new MerkleLeavesListError(\n 'MERKLE_ROOT_MISMATCH',\n 'leaves recompute does not match declared root',\n );\n }\n\n const out: DecodedLeavesList = {\n format: LEAVES_LIST_FORMAT_V1,\n treeAlg: TREE_ALG_RFC9162,\n root,\n leaves,\n leafCount,\n ...(leafAlg !== undefined ? { leafAlg } : {}),\n };\n return out;\n}\n","// A runtime-neutral view of the bytes a resumable upload reads from. The\n// helper needs three things from its source and nothing else:\n//\n// 1. the total byte length (declared to the gateway at session create),\n// 2. an ordered byte stream over the whole input (to compute the whole-file\n// SHA-256 without buffering it), and\n// 3. random-access slices by byte range (to read one chunk at a time).\n//\n// A browser `Blob`/`File` satisfies all three natively (`.size`, `.stream()`,\n// `.slice()`), and streams from disk rather than loading into memory. On the\n// server the same contract is met by a byte array, a filesystem path, or a Node\n// readable stream — each adapted to the same `ResumableSource` shape here, so\n// the protocol driver never branches on the runtime.\n\n// `node:fs/promises` is imported lazily, never at module top level: this package\n// is browser-safe and apps bundle it for the browser, so a static `node:` import\n// would pull a Node builtin into every browser build and break it. Only the\n// filesystem-path source actually needs it, and that branch runs only in Node;\n// the Blob/File/Uint8Array sources (the browser cases) never reach this loader.\ntype FsPromisesOpen = (typeof import('node:fs/promises'))['open'];\n\nlet openHandlePromise: Promise<FsPromisesOpen> | undefined;\nasync function loadOpen(): Promise<FsPromisesOpen> {\n // Cache the dynamic import so repeated path-source reads share one resolution.\n if (openHandlePromise === undefined) {\n openHandlePromise = import('node:fs/promises').then((fs) => fs.open);\n }\n return openHandlePromise;\n}\n\n/** The runtime-neutral source contract the resumable uploader drives. */\nexport interface ResumableSource {\n /** Total number of bytes in the input. */\n readonly size: number;\n /**\n * Read the half-open byte range `[start, end)`. May resolve synchronously or\n * asynchronously; callers always `await` the result. The returned array owns\n * its bytes (callers may transfer it into a request body).\n */\n slice(start: number, end: number): Uint8Array | Promise<Uint8Array>;\n /**\n * An ordered async stream over the whole input, used once to compute the\n * whole-file digest. Implementations stream in bounded chunks so a multi-GB\n * input is never materialised in full.\n */\n stream(): AsyncIterable<Uint8Array>;\n}\n\n/**\n * Any value `toResumableSource` knows how to adapt:\n * - a `ResumableSource` (passed through),\n * - a browser `Blob`/`File` (uses native `.slice()`/`.stream()`),\n * - a `Uint8Array`/`Buffer` (in-memory bytes),\n * - a filesystem path string (read in bounded slices, never fully buffered).\n */\nexport type ResumableSourceInput = ResumableSource | Blob | Uint8Array | string;\n\n// Default stream chunk for the whole-file hash pass. Independent of the upload\n// chunk size: this only bounds the hashing read buffer, so a small value keeps\n// peak memory low without affecting wire behaviour.\nconst HASH_STREAM_CHUNK_BYTES = 1024 * 1024;\n\nfunction isResumableSource(value: unknown): value is ResumableSource {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as ResumableSource).size === 'number' &&\n typeof (value as ResumableSource).slice === 'function' &&\n typeof (value as ResumableSource).stream === 'function' &&\n // A Blob/File shares all three members but exposes `.arrayBuffer`; exclude it\n // here so the adapter contract is unambiguous regardless of check order. A\n // Blob is handled by its own branch, which adapts `.slice`/`.stream` to bytes.\n typeof (value as { arrayBuffer?: unknown }).arrayBuffer !== 'function'\n );\n}\n\n// A `Blob` is detected structurally (not via `instanceof Blob`) so the check\n// holds across realms and runtimes that expose a Blob-shaped object without the\n// same constructor identity.\nfunction isBlobLike(value: unknown): value is Blob {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Blob).size === 'number' &&\n typeof (value as Blob).slice === 'function' &&\n typeof (value as Blob).arrayBuffer === 'function'\n );\n}\n\nasync function blobSlice(blob: Blob, start: number, end: number): Promise<Uint8Array> {\n return new Uint8Array(await blob.slice(start, end).arrayBuffer());\n}\n\nasync function* blobStream(blob: Blob): AsyncIterable<Uint8Array> {\n // `Blob.stream()` yields from disk in the browser and from the in-memory\n // buffer in Node; either way it never copies the whole blob into one array.\n const reader = blob.stream().getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) yield value as Uint8Array;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction fromBlob(blob: Blob): ResumableSource {\n return {\n size: blob.size,\n slice: (start, end) => blobSlice(blob, start, end),\n stream: () => blobStream(blob),\n };\n}\n\nfunction fromBytes(bytes: Uint8Array): ResumableSource {\n return {\n size: bytes.byteLength,\n slice: (start, end) => bytes.subarray(start, end),\n stream: async function* () {\n for (let offset = 0; offset < bytes.byteLength; offset += HASH_STREAM_CHUNK_BYTES) {\n yield bytes.subarray(offset, Math.min(offset + HASH_STREAM_CHUNK_BYTES, bytes.byteLength));\n }\n },\n };\n}\n\nasync function fromPath(path: string): Promise<ResumableSource> {\n const open = await loadOpen();\n // Read each slice with a positional read so the file is never buffered whole;\n // the whole-file hash pass streams it in bounded chunks for the same reason.\n const sliceAt = async (start: number, end: number): Promise<Uint8Array> => {\n const length = end - start;\n if (length <= 0) return new Uint8Array(0);\n const handle = await open(path, 'r');\n try {\n const buffer = new Uint8Array(length);\n // A single positional read may return fewer bytes than requested (a short\n // read is allowed by the OS even mid-file), so loop until the slice is\n // filled or we hit real EOF. Emitting a short chunk for a non-final index\n // would corrupt the assembled file, since the gateway places each chunk at\n // its deterministic offset; only the final chunk may legitimately be short.\n let filled = 0;\n while (filled < length) {\n const { bytesRead } = await handle.read(buffer, filled, length - filled, start + filled);\n if (bytesRead === 0) break; // real EOF: the file is shorter than declared\n filled += bytesRead;\n }\n return filled === length ? buffer : buffer.subarray(0, filled);\n } finally {\n await handle.close();\n }\n };\n const streamFile = async function* (): AsyncIterable<Uint8Array> {\n const handle = await open(path, 'r');\n try {\n const buffer = new Uint8Array(HASH_STREAM_CHUNK_BYTES);\n let position = 0;\n for (;;) {\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);\n if (bytesRead === 0) break;\n position += bytesRead;\n // Copy out the filled prefix; the buffer is reused on the next read.\n yield buffer.slice(0, bytesRead);\n }\n } finally {\n await handle.close();\n }\n };\n const { size } = await statSize(path);\n return { size, slice: sliceAt, stream: streamFile };\n}\n\nasync function statSize(path: string): Promise<{ size: number }> {\n const open = await loadOpen();\n // `readFile().byteLength` would buffer the whole file; use the handle's stat\n // instead so a large file's size is read without touching its bytes.\n const handle = await open(path, 'r');\n try {\n const stats = await handle.stat();\n return { size: stats.size };\n } finally {\n await handle.close();\n }\n}\n\n/**\n * Adapt any supported input to the runtime-neutral {@link ResumableSource}\n * contract. Returns a promise because a filesystem-path source must stat the\n * file before its size is known. Throws `TypeError` for unsupported inputs.\n *\n * The path branch is the only one that touches `node:fs`; a browser caller\n * passes a `Blob`/`File` or `Uint8Array` and never reaches it.\n */\nexport async function toResumableSource(input: ResumableSourceInput): Promise<ResumableSource> {\n if (typeof input === 'string') return fromPath(input);\n if (input instanceof Uint8Array) return fromBytes(input);\n // A `Blob`/`File` is checked BEFORE the generic `ResumableSource` shape: a Blob\n // also has `.size`/`.slice`/`.stream`, but its `.slice` returns a `Blob` (not a\n // `Uint8Array`) and its `.stream` is a `ReadableStream`, so passing it through\n // as a `ResumableSource` would hand the uploader Blobs where it expects byte\n // arrays. `isBlobLike` keys on `.arrayBuffer`, which a real adapter never has.\n if (isBlobLike(input)) return fromBlob(input);\n if (isResumableSource(input)) return input;\n throw new TypeError(\n 'uploadResumable: unsupported source. Pass a Blob/File, a Uint8Array, a ' +\n 'filesystem path string, or a ResumableSource.',\n );\n}\n","// Threshold-gated resumable upload driver.\n//\n// A file at or below `threshold` is sent with the existing single-shot\n// `uploads()` call, unchanged. A larger file is uploaded as a content-addressed\n// session: the helper hashes the whole file once (streaming, so a multi-GB file\n// is never buffered), creates a session, PUTs each fixed-size chunk (several in\n// parallel, retrying a failed chunk), then completes — polling the shared\n// attempt endpoint if completion is accepted asynchronously. Both paths converge\n// on one `ar://` URI.\n//\n// The chunk size is the server's call: the create response returns the\n// authoritative `chunk_bytes` and a `max_chunk_bytes` ceiling, and the helper\n// recomputes its grid from those rather than from what it requested. So a\n// deployment behind a stricter proxy cap is honoured without an SDK release.\n\nimport { sha256, sha256Stream } from '@cardanowall/crypto-core/hash';\n\nimport { Label309HttpError } from './http-error';\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport { toResumableSource, type ResumableSource } from './resumable-source';\nimport type {\n FetchImpl,\n StorageTarget,\n UploadResumableInput,\n UploadResumableResult,\n UploadSessionChunkResponse,\n UploadSessionCompleteResponse,\n UploadSessionCreateResponse,\n UploadSessionDeduplicatedResponse,\n UploadSessionStatus,\n UploadAttemptStatus,\n UploadAttemptCommitted,\n UploadAttemptReleased,\n} from './types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\n// Single-shot uploads() of one blob, returning the resolved URI. Imported as a\n// callback so the driver does not depend on the PoeNamespace class shape.\nexport type SingleShotUpload = (args: {\n readonly target: StorageTarget;\n readonly bytes: Uint8Array;\n readonly idempotencyKey?: string;\n readonly signal?: AbortSignal;\n}) => Promise<{ readonly uri: string; readonly sha256: string; readonly bytes: number }>;\n\n// ~48 MiB. Sits comfortably under a 100 MB CDN body cap AND under stricter\n// nginx/proxy defaults below it, so a single chunk PUT clears the smallest\n// common single-request ceiling. Both the switch-to-chunked threshold and the\n// requested chunk size default here; the server's max_chunk_bytes always wins.\nexport const DEFAULT_RESUMABLE_THRESHOLD_BYTES = 50_331_648;\nexport const DEFAULT_RESUMABLE_CHUNK_BYTES = 50_331_648;\nconst DEFAULT_PARALLELISM = 4;\nconst DEFAULT_MAX_CHUNK_RETRIES = 4;\nconst DEFAULT_CONTENT_TYPE = 'application/octet-stream';\nconst DEFAULT_TARGET: StorageTarget = 'arweave';\nconst ATTEMPT_POLL_INTERVAL_MS = 1000;\nconst ATTEMPT_POLL_MAX_ATTEMPTS = 600;\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\n// Standards-only base64 (RFC 4648) over raw bytes, used for the per-chunk\n// `Digest: sha-256=<base64>` header. A hand-rolled encoder keeps the helper free\n// of any runtime-specific path (`btoa` is DOM-only, `Buffer` is Node-only).\nconst B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nfunction bytesToBase64(bytes: Uint8Array): string {\n let out = '';\n let i = 0;\n for (; i + 2 < bytes.length; i += 3) {\n const n = (bytes[i]! << 16) | (bytes[i + 1]! << 8) | bytes[i + 2]!;\n out +=\n B64_ALPHABET[(n >> 18) & 63]! +\n B64_ALPHABET[(n >> 12) & 63]! +\n B64_ALPHABET[(n >> 6) & 63]! +\n B64_ALPHABET[n & 63]!;\n }\n const rem = bytes.length - i;\n if (rem === 1) {\n const n = bytes[i]! << 16;\n out += B64_ALPHABET[(n >> 18) & 63]! + B64_ALPHABET[(n >> 12) & 63]! + '==';\n } else if (rem === 2) {\n const n = (bytes[i]! << 16) | (bytes[i + 1]! << 8);\n out +=\n B64_ALPHABET[(n >> 18) & 63]! +\n B64_ALPHABET[(n >> 12) & 63]! +\n B64_ALPHABET[(n >> 6) & 63]! +\n '=';\n }\n return out;\n}\n\nfunction jsonHeaders(config: ResolvedConfig, idempotencyKey?: string): Headers {\n const headers = new Headers({ 'content-type': 'application/json', accept: 'application/json' });\n if (config.apiKey !== undefined) headers.set('authorization', `Bearer ${config.apiKey}`);\n if (idempotencyKey !== undefined) headers.set('idempotency-key', idempotencyKey);\n return headers;\n}\n\nfunction octetHeaders(config: ResolvedConfig, length: number, digestBase64: string): Headers {\n const headers = new Headers({\n 'content-type': 'application/octet-stream',\n accept: 'application/json',\n 'content-length': String(length),\n digest: `sha-256=${digestBase64}`,\n });\n if (config.apiKey !== undefined) headers.set('authorization', `Bearer ${config.apiKey}`);\n return headers;\n}\n\nconst SESSIONS_PATH = '/api/v1/poe/uploads/sessions';\n\nfunction chunkRange(index: number, chunkBytes: number, totalBytes: number): [number, number] {\n const start = index * chunkBytes;\n return [start, Math.min(start + chunkBytes, totalBytes)];\n}\n\nfunction missingIndices(received: ReadonlyArray<number>, chunkCount: number): number[] {\n const have = new Set(received);\n const out: number[] = [];\n for (let i = 0; i < chunkCount; i++) if (!have.has(i)) out.push(i);\n return out;\n}\n\n/**\n * The authoritative set of chunk indices to send for a resumed session. The\n * server's `missing` set is the source of truth; `received` is only a progress\n * signal. A gateway that omits `missing` (older deployments) falls back to the\n * gap derived from `received` so resume still works.\n */\nfunction serverMissing(status: UploadSessionStatus): ReadonlyArray<number> {\n if (Array.isArray(status.missing)) return status.missing;\n return missingIndices(status.received, status.chunk_count);\n}\n\n/** Whole-file SHA-256 (hex) over the source, streamed so a large file is never buffered. */\nasync function hashWholeFile(source: ResumableSource): Promise<string> {\n return bytesToHex(await sha256Stream(source.stream()));\n}\n\nasync function createSession(\n config: ResolvedConfig,\n body: {\n target: StorageTarget;\n sha256: string;\n total_bytes: number;\n chunk_bytes: number;\n content_type: string;\n },\n signal: AbortSignal | undefined,\n): Promise<UploadSessionCreateResponse | UploadSessionDeduplicatedResponse> {\n const response = await config.fetch(`${config.baseUrl}${SESSIONS_PATH}`, {\n method: 'POST',\n headers: jsonHeaders(config),\n body: JSON.stringify(body),\n ...(signal ? { signal } : {}),\n });\n // A 402 funding error is surfaced through the typed-error path like any other\n // non-2xx; the dedup short-circuit arrives as a 200 and is read below.\n await throwIfNotOk(response);\n return (await readJson(response)) as\n | UploadSessionCreateResponse\n | UploadSessionDeduplicatedResponse;\n}\n\nasync function getSessionStatus(\n config: ResolvedConfig,\n sessionId: string,\n signal: AbortSignal | undefined,\n): Promise<UploadSessionStatus> {\n const response = await config.fetch(\n `${config.baseUrl}${SESSIONS_PATH}/${encodeURIComponent(sessionId)}`,\n {\n method: 'GET',\n headers: jsonHeaders(config),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadSessionStatus;\n}\n\nasync function putChunk(\n config: ResolvedConfig,\n sessionId: string,\n index: number,\n bytes: Uint8Array,\n signal: AbortSignal | undefined,\n): Promise<UploadSessionChunkResponse> {\n const digest = bytesToBase64(sha256(bytes));\n const response = await config.fetch(\n `${config.baseUrl}${SESSIONS_PATH}/${encodeURIComponent(sessionId)}/chunks/${index}`,\n {\n method: 'PUT',\n headers: octetHeaders(config, bytes.byteLength, digest),\n // A Blob body streams without copying; a matching-digest re-PUT is an\n // idempotent 200 server-side, so a retried chunk is always safe.\n body: new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadSessionChunkResponse;\n}\n\nasync function completeSession(\n config: ResolvedConfig,\n sessionId: string,\n idempotencyKey: string,\n signal: AbortSignal | undefined,\n): Promise<UploadSessionCompleteResponse> {\n const response = await config.fetch(\n `${config.baseUrl}${SESSIONS_PATH}/${encodeURIComponent(sessionId)}/complete`,\n {\n method: 'POST',\n headers: jsonHeaders(config, idempotencyKey),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadSessionCompleteResponse;\n}\n\nasync function pollAttempt(\n config: ResolvedConfig,\n attemptId: string,\n signal: AbortSignal | undefined,\n): Promise<UploadAttemptCommitted | UploadAttemptReleased> {\n for (let attempt = 0; attempt < ATTEMPT_POLL_MAX_ATTEMPTS; attempt++) {\n const response = await config.fetch(\n `${config.baseUrl}/api/v1/poe/uploads/attempts/${encodeURIComponent(attemptId)}`,\n {\n method: 'GET',\n headers: jsonHeaders(config),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n const status = (await readJson(response)) as UploadAttemptStatus;\n // `reserved` is the only in-flight state; `committed` and `released` are\n // terminal and returned to the caller to resolve.\n if (status.state !== 'reserved') return status;\n await delay(ATTEMPT_POLL_INTERVAL_MS, signal);\n }\n throw new ResumableUploadError(\n 'ATTEMPT_POLL_TIMEOUT',\n `upload attempt ${attemptId} did not reach a terminal state in time`,\n );\n}\n\nfunction delay(ms: number, signal: AbortSignal | undefined): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signalReason(signal));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(signalReason(signal));\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nfunction signalReason(signal: AbortSignal | undefined): Error {\n const reason = signal?.reason;\n return reason instanceof Error ? reason : new ResumableUploadError('ABORTED', 'upload aborted');\n}\n\nexport class ResumableUploadError extends Error {\n readonly code:\n | 'SHA256_MISMATCH'\n | 'SESSION_FAILED'\n | 'ATTEMPT_FAILED'\n | 'ATTEMPT_POLL_TIMEOUT'\n | 'CHUNK_UPLOAD_FAILED'\n | 'ABORTED';\n\n constructor(code: ResumableUploadError['code'], message: string) {\n super(message);\n this.name = 'ResumableUploadError';\n this.code = code;\n }\n}\n\n/** Upload `missing` chunk indices with bounded parallelism, retrying each on failure. */\nasync function uploadChunks(\n config: ResolvedConfig,\n sessionId: string,\n source: ResumableSource,\n chunkBytes: number,\n totalBytes: number,\n missing: ReadonlyArray<number>,\n parallelism: number,\n maxRetries: number,\n signal: AbortSignal | undefined,\n): Promise<void> {\n let cursor = 0;\n const workers: Promise<void>[] = [];\n const lanes = Math.max(1, Math.min(parallelism, missing.length || 1));\n for (let lane = 0; lane < lanes; lane++) {\n workers.push(\n (async () => {\n for (;;) {\n if (signal?.aborted) throw signalReason(signal);\n const next = cursor++;\n if (next >= missing.length) return;\n const index = missing[next]!;\n const [start, end] = chunkRange(index, chunkBytes, totalBytes);\n const bytes = await source.slice(start, end);\n await putChunkWithRetry(config, sessionId, index, bytes, maxRetries, signal);\n }\n })(),\n );\n }\n await Promise.all(workers);\n}\n\nasync function putChunkWithRetry(\n config: ResolvedConfig,\n sessionId: string,\n index: number,\n bytes: Uint8Array,\n maxRetries: number,\n signal: AbortSignal | undefined,\n): Promise<void> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (signal?.aborted) throw signalReason(signal);\n try {\n await putChunk(config, sessionId, index, bytes, signal);\n return;\n } catch (err) {\n if (signal?.aborted) throw signalReason(signal);\n // A deterministic client-side 4xx (e.g. 400 chunk-size-mismatch, 400\n // chunk-digest-mismatch, 409 chunk-conflict) cannot be fixed by resending\n // the same bytes: fail fast and surface the real problem rather than\n // burning retries and masking it as CHUNK_UPLOAD_FAILED. Only transient\n // failures (network errors, 5xx, 429, 408) are worth a retry. A\n // matching-digest re-PUT is an idempotent 200 server-side, so a retried\n // transient chunk is always safe.\n if (isTerminalChunkError(err)) throw err;\n lastError = err;\n if (attempt < maxRetries) {\n // Exponential backoff (250ms, 500ms, 1s, ...) capped at 8s.\n await delay(Math.min(250 * 2 ** attempt, 8000), signal);\n }\n }\n }\n throw new ResumableUploadError(\n 'CHUNK_UPLOAD_FAILED',\n `chunk ${index} failed after ${maxRetries + 1} attempt(s): ${\n lastError instanceof Error ? lastError.message : String(lastError)\n }`,\n );\n}\n\n/**\n * Drive a single-file upload, choosing single-shot vs the chunked session flow\n * by size. See {@link UploadResumableInput} for the options.\n */\nexport async function uploadResumable(\n config: ResolvedConfig,\n singleShot: SingleShotUpload,\n input: UploadResumableInput,\n): Promise<UploadResumableResult> {\n const source = await toResumableSource(input.source);\n const target = input.target ?? DEFAULT_TARGET;\n const threshold = input.threshold ?? DEFAULT_RESUMABLE_THRESHOLD_BYTES;\n const totalBytes = source.size;\n\n // Small file (or no resume requested): the unchanged single-shot path. The\n // whole file is small enough to read once into memory for the multipart body.\n if (totalBytes <= threshold && input.sessionId === undefined) {\n const bytes = await source.slice(0, totalBytes);\n const result = await singleShot({\n target,\n bytes,\n ...(input.idempotencyKey !== undefined ? { idempotencyKey: input.idempotencyKey } : {}),\n ...(input.signal ? { signal: input.signal } : {}),\n });\n return {\n uri: result.uri,\n sha256: result.sha256,\n bytes: result.bytes,\n deduplicated: false,\n mode: 'single-shot',\n };\n }\n\n return runSession(config, source, target, totalBytes, input);\n}\n\nasync function runSession(\n config: ResolvedConfig,\n source: ResumableSource,\n target: StorageTarget,\n totalBytes: number,\n input: UploadResumableInput,\n): Promise<UploadResumableResult> {\n const signal = input.signal;\n\n let sessionId: string;\n let chunkBytes: number;\n let missing: ReadonlyArray<number>;\n // The declared whole-file SHA-256 (hex) the session is content-addressed by.\n // On a fresh create it is computed once over the local source; on resume it is\n // ADOPTED from the server status, never recomputed. It drives both the\n // completion idempotency key and the result `sha256`.\n let declaredSha256: string;\n // The total the chunk grid is sliced against. On a fresh create this is the\n // local source size (which the gateway echoes back, since we just declared it).\n // On resume it is the server's `total_bytes`: a source that grew between\n // attempts must not redraw the grid, or the final chunk would over-read past\n // the originally declared length and contradict the digest.\n let gridTotalBytes: number;\n\n if (input.sessionId !== undefined) {\n // Resume: a session is content-addressed, so its declared digest, total, and\n // chunk grid all live server-side. Adopt the server status as authoritative\n // and NEVER re-hash the local source — re-reading a multi-GB file on every\n // resume defeats the point, and a local file that changed since create would\n // yield a digest that disagrees with the actually-uploaded bounded bytes.\n const status = await getSessionStatus(config, input.sessionId, signal);\n if (status.state === 'completed' && status.uri !== null) {\n return {\n uri: status.uri,\n sha256: status.sha256,\n bytes: status.total_bytes,\n deduplicated: false,\n mode: 'chunked',\n };\n }\n if (status.state === 'failed' || status.state === 'expired') {\n throw new ResumableUploadError(\n 'SESSION_FAILED',\n `cannot resume session ${input.sessionId} in state '${status.state}'`,\n );\n }\n sessionId = status.session_id;\n declaredSha256 = status.sha256;\n chunkBytes = status.chunk_bytes;\n // The server's declared total is authoritative for the chunk grid, not the\n // live local source size. The original create fixed `total_bytes`, the whole-\n // file digest, and the index<->offset mapping together; bounding the final\n // chunk against the server total keeps the last slice the exact declared\n // remainder even if the underlying source has since grown.\n gridTotalBytes = status.total_bytes;\n // The server's `missing` set is authoritative for which indices to send: it\n // is the source of truth for what the gateway holds, where `received` is\n // only a progress signal. Re-deriving the gap from `received` would diverge\n // if the server's grid ever differs from ours (e.g. a chunk it dropped after\n // acking, or a window it expresses differently).\n missing = serverMissing(status);\n } else {\n // Fresh create: this is the only path that reads the whole source to compute\n // the declared digest, streamed so a multi-GB file is never buffered.\n declaredSha256 = await hashWholeFile(source);\n const requestedChunkBytes = input.chunkBytes ?? DEFAULT_RESUMABLE_CHUNK_BYTES;\n const created = await createSession(\n config,\n {\n target,\n sha256: declaredSha256,\n total_bytes: totalBytes,\n chunk_bytes: requestedChunkBytes,\n content_type: input.contentType ?? DEFAULT_CONTENT_TYPE,\n },\n signal,\n );\n // Create-time dedup: the bytes already exist; nothing is uploaded.\n if ('deduplicated' in created) {\n return {\n uri: created.uri,\n sha256: created.sha256,\n bytes: created.bytes,\n deduplicated: true,\n mode: 'chunked',\n };\n }\n sessionId = created.session_id;\n // Honour the server's authoritative chunk size (it may clamp to its ceiling).\n chunkBytes = created.chunk_bytes;\n gridTotalBytes = totalBytes;\n // A fresh create has no `missing` field and an empty `received`, so every\n // index is outstanding.\n missing = missingIndices(created.received, created.chunk_count);\n }\n\n if (missing.length > 0) {\n await uploadChunks(\n config,\n sessionId,\n source,\n chunkBytes,\n gridTotalBytes,\n missing,\n input.parallelism ?? DEFAULT_PARALLELISM,\n input.maxChunkRetries ?? DEFAULT_MAX_CHUNK_RETRIES,\n signal,\n );\n }\n\n return finishSession(config, sessionId, declaredSha256, input);\n}\n\n// Drive /complete to a terminal result. On a 409 incomplete-upload, the server's\n// status is re-fetched and the still-missing chunks are resent against the\n// server-authoritative grid (`status.chunk_bytes` / `status.total_bytes`), so the\n// completion path never trusts a stale local size.\nasync function finishSession(\n config: ResolvedConfig,\n sessionId: string,\n declaredSha256: string,\n input: UploadResumableInput,\n): Promise<UploadResumableResult> {\n const signal = input.signal;\n // The completion key is the caller's promise of sameness; default it to the\n // session's declared digest (computed on create, adopted from server status on\n // resume) so a re-invocation replays the recorded terminal result.\n const idempotencyKey = input.idempotencyKey ?? `resumable-${declaredSha256}`;\n\n // A 409 incomplete-upload means the server is missing chunks (e.g. a write was\n // dropped after the bit flipped client-side): GET the gap, resend it, retry.\n const COMPLETE_RETRIES = 2;\n for (let attempt = 0; attempt <= COMPLETE_RETRIES; attempt++) {\n try {\n const completion = await completeSession(config, sessionId, idempotencyKey, signal);\n if ('ok' in completion) {\n return {\n uri: completion.uri,\n sha256: completion.sha256,\n bytes: completion.bytes,\n // The server sends the number 0 for a dedup-on-commit (the bytes were\n // already stored, so nothing was charged); compare numerically.\n deduplicated: completion.charged_usd_micros === 0,\n mode: 'chunked',\n };\n }\n return resolveAccepted(config, completion.attempt_id, signal);\n } catch (err) {\n if (attempt < COMPLETE_RETRIES && isIncompleteUpload(err)) {\n const status = await getSessionStatus(config, sessionId, signal);\n const stillMissing = serverMissing(status);\n if (stillMissing.length === 0) continue; // racing assembly; retry complete\n await uploadChunks(\n config,\n sessionId,\n await toResumableSource(input.source),\n status.chunk_bytes,\n // Re-bound the resend grid against the server's declared total too, so a\n // source that grew during the upload cannot over-read the final chunk.\n status.total_bytes,\n stillMissing,\n input.parallelism ?? DEFAULT_PARALLELISM,\n input.maxChunkRetries ?? DEFAULT_MAX_CHUNK_RETRIES,\n signal,\n );\n continue;\n }\n throw err;\n }\n }\n // Loop exhaustion means the gateway kept reporting an incomplete upload\n // despite resending the missing chunks.\n throw new ResumableUploadError(\n 'SESSION_FAILED',\n `session ${sessionId} could not be completed after resending missing chunks`,\n );\n}\n\nasync function resolveAccepted(\n config: ResolvedConfig,\n attemptId: string,\n signal: AbortSignal | undefined,\n): Promise<UploadResumableResult> {\n const status = await pollAttempt(config, attemptId, signal);\n // `released` is the terminal failure; surface the server's reason.\n if (status.state === 'released') {\n throw new ResumableUploadError(\n 'ATTEMPT_FAILED',\n `upload attempt ${attemptId} was released: ${status.reason}`,\n );\n }\n // `committed` is the terminal success and MUST carry a uri; a committed\n // attempt without one is a server contract violation, not a silent success.\n if (status.uri.length === 0) {\n throw new ResumableUploadError(\n 'ATTEMPT_FAILED',\n `upload attempt ${attemptId} committed without a uri`,\n );\n }\n return {\n uri: status.uri,\n sha256: status.sha256,\n bytes: status.bytes,\n // A committed attempt that charged nothing deduped against bytes already\n // stored for this account on this backend.\n deduplicated: status.charged_usd_micros === 0,\n mode: 'chunked',\n };\n}\n\n/**\n * Whether a chunk-PUT error is the caller's fault (terminal) rather than a\n * transient server/transport hiccup worth retrying. A definitive client-side\n * 4xx is terminal — a conflicting digest, a size mismatch, an\n * unauthorised/forbidden caller, an expired or missing session — and resending\n * the same bytes cannot fix it. 408 (request timeout) and 429 (rate limited)\n * are transient; any non-HTTP error (a network/egress failure) is transient\n * too, since the request never reached a definitive verdict.\n */\nfunction isTerminalChunkError(err: unknown): boolean {\n if (!(err instanceof Label309HttpError)) return false;\n const status = err.httpStatus;\n return status >= 400 && status < 500 && status !== 408 && status !== 429;\n}\n\nfunction isIncompleteUpload(err: unknown): boolean {\n // The typed HTTP error carries the RFC 7807 `code`; an incomplete upload at\n // /complete is a 409 with code `incomplete-upload`.\n return (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as { code: unknown }).code === 'incomplete-upload'\n );\n}\n","// High-level publish helpers — collapse the new uploads + publish flow into\n// single calls for the three common shapes:\n//\n// 1. `publishContent({content, signer?})` — anchor a single content blob by\n// its `sha2-256` (or `blake2b-256`) digest. No Arweave, no /uploads —\n// the record is constructed entirely client-side and posted directly to\n// /publish.\n//\n// 2. `publishSealed({content, recipients, signer?})` — encrypt the content\n// to the recipient X25519 public keys (age-style sealed envelope),\n// upload the ciphertext to Arweave via /uploads, build a Label 309 record\n// with the resulting `ar://` URI, sign, and post to /publish.\n//\n// 3. `publishMerkle({leaves, signer?})` — anchor an arbitrary number of leaf\n// hashes under a single RFC 9162 §2.1.1 root, with the leaves-list CBOR\n// uploaded to Arweave via /uploads. The Merkle root + leaf_count are\n// bound into the on-chain record via `merkle[0]`.\n//\n// Signer architecture: the SDK does NOT hold identity keys (privacy contract\n// in `off-host-sign.ts`). The helpers take an optional `Signer` that owns the\n// Ed25519 private key (in-memory `@noble/ed25519`, AWS KMS, GCP HSM, …). The\n// helper builds the canonical `Sig_structure`, hands the bytes to the signer,\n// and never sees the private key. When `signer` is omitted the record\n// publishes unsigned (conformance profile `core` for hash-only;\n// `sealed` for sealed envelopes).\n\nimport {\n sha256,\n blake2b256,\n merkleSha2256Root,\n MERKLE_ALG_ID,\n} from '@cardanowall/crypto-core/hash';\nimport { encodeLeavesList } from '@cardanowall/crypto-core/merkle';\nimport { eciesSealedPoeWrap } from '@cardanowall/crypto-core/sealed-poe';\nimport {\n encodePoeRecord,\n type EncryptionEnvelope,\n type MerkleCommit,\n type PoeRecord,\n} from '@cardanowall/poe-standard';\n\nimport { assembleCoseSign1, prepareSigStructure } from './off-host-sign';\nimport { PartialUploadError } from './partial-upload-error';\nimport { parseHttpError } from './parse-http-error';\nimport {\n uploadResumable,\n DEFAULT_RESUMABLE_THRESHOLD_BYTES,\n type SingleShotUpload,\n} from './resumable-upload';\nimport type {\n FetchImpl,\n PublishContentInput,\n PublishMerkleInput,\n PublishMerkleResponse,\n PublishPrehashedInput,\n PublishResponse,\n PublishSealedInput,\n Signer,\n StorageTarget,\n SupportedHashAlg,\n UploadsResponse,\n UploadSuccessEntry,\n} from './types';\n\nconst ED25519_PUBLIC_KEY_LENGTH = 32;\nconst ED25519_SIGNATURE_LENGTH = 64;\nconst X25519_PUBLIC_KEY_LENGTH = 32;\nconst MLKEM768X25519_PUBLIC_KEY_LENGTH = 1216;\nconst LEAF_DIGEST_LENGTH = 32;\nconst STORAGE_TARGET_ARWEAVE = 'arweave' as const;\n\nexport interface ResolvedPublishConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nexport class PublishError extends Error {\n readonly code:\n | 'INVALID_SIGNER_PUBKEY'\n | 'INVALID_SIGNER_SIGNATURE'\n | 'INVALID_LEAVES'\n | 'INVALID_DIGEST'\n | 'INVALID_RECIPIENT'\n | 'UNSUPPORTED_HASH_ALG';\n\n constructor(code: PublishError['code'], message: string) {\n super(message);\n this.name = 'PublishError';\n this.code = code;\n }\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new PublishError('INVALID_LEAVES', `hex string has odd length: ${hex.length}`);\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n if (Number.isNaN(byte)) {\n throw new PublishError('INVALID_LEAVES', `invalid hex byte at offset ${i * 2}`);\n }\n out[i] = byte;\n }\n return out;\n}\n\nfunction toBytes(content: Uint8Array | string): Uint8Array {\n if (typeof content === 'string') return new TextEncoder().encode(content);\n return content;\n}\n\n// Allocate a fresh Uint8Array (with a concrete ArrayBuffer backing, not\n// ArrayBufferLike) so the result satisfies the strict `Uint8Array<ArrayBuffer>`\n// generic that Zod infers for hash-digest schemas. @noble/hashes returns the\n// generic `Uint8Array<ArrayBufferLike>` shape; an explicit clone collapses it\n// to the strict variant without `as` casts.\nfunction cloneToOwnedBuffer(src: Uint8Array): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(new ArrayBuffer(src.length));\n out.set(src);\n return out;\n}\n\nfunction hashContent(bytes: Uint8Array, alg: SupportedHashAlg): Uint8Array<ArrayBuffer> {\n if (alg === 'sha2-256') return cloneToOwnedBuffer(sha256(bytes));\n if (alg === 'blake2b-256') return cloneToOwnedBuffer(blake2b256(bytes));\n throw new PublishError(\n 'UNSUPPORTED_HASH_ALG',\n `hashAlg must be 'sha2-256' or 'blake2b-256', got '${alg as string}'`,\n );\n}\n\nfunction assertSigner(signer: Signer): void {\n if (\n !(signer.signerPubkey instanceof Uint8Array) ||\n signer.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH\n ) {\n throw new PublishError(\n 'INVALID_SIGNER_PUBKEY',\n `signer.signerPubkey must be a Uint8Array(${ED25519_PUBLIC_KEY_LENGTH})`,\n );\n }\n if (typeof signer.sign !== 'function') {\n throw new PublishError('INVALID_SIGNER_PUBKEY', 'signer.sign must be a function');\n }\n}\n\nfunction buildJsonHeaders(apiKey: string | undefined, idempotencyKey?: string): Headers {\n const headers = new Headers({ 'content-type': 'application/json', accept: 'application/json' });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n if (idempotencyKey !== undefined) headers.set('idempotency-key', idempotencyKey);\n return headers;\n}\n\nfunction buildMultipartHeaders(apiKey: string | undefined, idempotencyKey?: string): Headers {\n const headers = new Headers({ accept: 'application/json' });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n if (idempotencyKey !== undefined) headers.set('idempotency-key', idempotencyKey);\n return headers;\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n const text = await response.text();\n if (text.length === 0) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (header === null) return undefined;\n const parsed = Number(header);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nasync function throwIfNotOk(response: Response): Promise<void> {\n if (response.ok) return;\n const body = await readJson(response);\n const requestId = response.headers.get('x-request-id') ?? undefined;\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n throw parseHttpError({ httpStatus: response.status, body, requestId, retryAfterSeconds });\n}\n\n/**\n * Sign a record path-1 (in-memory Ed25519 / KMS / HSM) and return the final\n * canonical-CBOR bytes ready for /publish. The signature is embedded into\n * the record's `sigs[]` field — the wire `signatures` parameter on /publish\n * is reserved for the path-2 wallet flow (CIP-30 cose_key sidecar).\n */\nasync function signAndEncodeRecord(record: PoeRecord, signer: Signer): Promise<Uint8Array> {\n const { sigStructureBytes } = prepareSigStructure({\n record,\n signerPubkey: signer.signerPubkey,\n });\n const signature = await signer.sign(sigStructureBytes);\n if (!(signature instanceof Uint8Array) || signature.length !== ED25519_SIGNATURE_LENGTH) {\n throw new PublishError(\n 'INVALID_SIGNER_SIGNATURE',\n `signer.sign() must return a Uint8Array(${ED25519_SIGNATURE_LENGTH}); got length ${\n signature instanceof Uint8Array ? signature.length : 'non-Uint8Array'\n }`,\n );\n }\n const { sigEntry } = assembleCoseSign1({\n record,\n signerPubkey: signer.signerPubkey,\n signature,\n });\n const signed: PoeRecord = { ...record, sigs: [sigEntry] };\n return encodePoeRecord(signed);\n}\n\nasync function encodeRecord(record: PoeRecord, signer: Signer | undefined): Promise<Uint8Array> {\n if (signer === undefined) return encodePoeRecord(record);\n return signAndEncodeRecord(record, signer);\n}\n\nasync function postPublish(\n config: ResolvedPublishConfig,\n recordBytesHex: string,\n quoteId: string,\n idempotencyKey: string | undefined,\n): Promise<PublishResponse> {\n const body = { record: recordBytesHex, quote_id: quoteId };\n const response = await config.fetch(`${config.baseUrl}/api/v1/poe/publish`, {\n method: 'POST',\n headers: buildJsonHeaders(config.apiKey, idempotencyKey),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n const parsed = (await readJson(response)) as Omit<PublishResponse, 'dedup_hit'>;\n return { ...parsed, dedup_hit: response.status === 200 };\n}\n\n// Single-shot multipart upload of one blob, resolving its `ar://` URI. Backs\n// the small-blob branch of `uploadBlob` and the resumable helper's\n// below-threshold fast path.\nconst singleShotUpload =\n (config: ResolvedPublishConfig): SingleShotUpload =>\n async ({ target, bytes, idempotencyKey, signal }) => {\n const form = new FormData();\n form.append('target', target);\n form.append(\n 'file_0',\n new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n 'file_0.bin',\n );\n const response = await config.fetch(`${config.baseUrl}/api/v1/poe/uploads`, {\n method: 'POST',\n headers: buildMultipartHeaders(config.apiKey, idempotencyKey),\n body: form,\n ...(signal ? { signal } : {}),\n });\n await throwIfNotOk(response);\n const result = (await readJson(response)) as UploadsResponse;\n const entry = result.uploads[0];\n if (entry === undefined || entry.ok === false) {\n throw new PartialUploadError(result);\n }\n const ok = entry as UploadSuccessEntry;\n return { uri: ok.uri, sha256: ok.sha256, bytes: ok.bytes };\n };\n\n// Upload one blob (sealed ciphertext or Merkle leaves-list) and return its\n// `ar://` URI. A blob at or below the resumable threshold takes the unchanged\n// single-shot multipart path; a larger blob transparently uses the resumable\n// session flow so a multi-GB ciphertext clears CDN/proxy single-request caps.\n// Both paths end at the same URI, so the publisher helpers' signatures and\n// on-chain record shape are unaffected by the blob's size.\nasync function uploadBlob(\n config: ResolvedPublishConfig,\n bytes: Uint8Array,\n idempotencyKey: string | undefined,\n): Promise<string> {\n const target: StorageTarget = STORAGE_TARGET_ARWEAVE;\n if (bytes.byteLength <= DEFAULT_RESUMABLE_THRESHOLD_BYTES) {\n const single = await singleShotUpload(config)({\n target,\n bytes,\n ...(idempotencyKey !== undefined ? { idempotencyKey } : {}),\n });\n return single.uri;\n }\n const result = await uploadResumable(config, singleShotUpload(config), {\n target,\n source: bytes,\n ...(idempotencyKey !== undefined ? { idempotencyKey } : {}),\n });\n return result.uri;\n}\n\n/**\n * Hash-only PoE — anchor a single content blob's digest, optionally with\n * one path-1 signature. No Arweave, no /uploads.\n */\nexport async function publishContent(\n config: ResolvedPublishConfig,\n input: PublishContentInput,\n): Promise<PublishResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n const hashAlg: SupportedHashAlg = input.hashAlg ?? 'sha2-256';\n const contentBytes = toBytes(input.content);\n const digest = hashContent(contentBytes, hashAlg);\n\n const record: PoeRecord = {\n v: 1,\n items: [{ hashes: { [hashAlg]: digest } }],\n };\n const recordBytes = await encodeRecord(record, input.signer);\n return postPublish(config, bytesToHex(recordBytes), input.quoteId, input.idempotencyKey);\n}\n\n// `sha2-256` and `blake2b-256` both produce 32-byte digests. Kept as a\n// per-alg map for forward-compat when wider hash registries land.\nconst DIGEST_BYTE_LENGTH: Record<SupportedHashAlg, number> = {\n 'sha2-256': 32,\n 'blake2b-256': 32,\n};\n\n/**\n * Hash-already-computed PoE — anchor a precomputed content digest (the user\n * already has it), optionally signed. The SDK does not re-hash; it\n * constructs a single-item record with the supplied digests in\n * `items[0].hashes`.\n */\nexport async function publishPrehashed(\n config: ResolvedPublishConfig,\n input: PublishPrehashedInput,\n): Promise<PublishResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n const entries = Object.entries(input.hashes) as Array<[SupportedHashAlg, string | undefined]>;\n const present = entries.filter(([, hex]) => typeof hex === 'string' && hex.length > 0) as Array<\n [SupportedHashAlg, string]\n >;\n if (present.length === 0) {\n throw new PublishError(\n 'INVALID_DIGEST',\n 'publishPrehashed requires at least one digest in `hashes`',\n );\n }\n const decoded: Record<string, Uint8Array<ArrayBuffer>> = {};\n for (const [alg, hex] of present) {\n if (!(alg in DIGEST_BYTE_LENGTH)) {\n throw new PublishError(\n 'UNSUPPORTED_HASH_ALG',\n `unsupported hash algorithm '${alg as string}' (expected 'sha2-256' or 'blake2b-256')`,\n );\n }\n const bytes = hexToBytes(hex);\n const expected = DIGEST_BYTE_LENGTH[alg];\n if (bytes.length !== expected) {\n throw new PublishError(\n 'INVALID_DIGEST',\n `hashes[${alg}] must be a ${expected}-byte digest (got ${bytes.length} bytes)`,\n );\n }\n decoded[alg] = cloneToOwnedBuffer(bytes);\n }\n\n const record: PoeRecord = {\n v: 1,\n items: [{ hashes: decoded }],\n };\n const recordBytes = await encodeRecord(record, input.signer);\n return postPublish(config, bytesToHex(recordBytes), input.quoteId, input.idempotencyKey);\n}\n\n/**\n * Sealed-PoE: encrypt content to N X25519 recipients (age-style envelope),\n * upload the ciphertext to Arweave, build a single-item record with the\n * resulting `ar://` URI and the sealed envelope in `items[0].enc`, sign\n * (optional), and post to /publish.\n *\n * The plaintext content-hash is bound into `items[0].hashes` so any verifier\n * that successfully decrypts the ciphertext can reconstruct the plaintext\n * and prove the chain of custody from the on-chain hash to the decrypted\n * bytes.\n */\nexport async function publishSealed(\n config: ResolvedPublishConfig,\n input: PublishSealedInput,\n): Promise<PublishResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n if (input.recipients.length < 1) {\n throw new PublishError(\n 'INVALID_RECIPIENT',\n 'publishSealed requires at least one recipient public key',\n );\n }\n // Default to the post-quantum-safe X-Wing hybrid KEM; x25519 is the explicit\n // classical opt-out. The recipient length guard is KEM-aware: 32 B for\n // x25519, 1216 B for the hybrid path.\n const kem = input.kem ?? 'mlkem768x25519';\n const expectedRecipientLength =\n kem === 'x25519' ? X25519_PUBLIC_KEY_LENGTH : MLKEM768X25519_PUBLIC_KEY_LENGTH;\n for (let i = 0; i < input.recipients.length; i++) {\n const pub = input.recipients[i]!;\n if (!(pub instanceof Uint8Array) || pub.length !== expectedRecipientLength) {\n throw new PublishError(\n 'INVALID_RECIPIENT',\n `recipients[${i}] must be a ${expectedRecipientLength}-byte public key for kem='${kem}'`,\n );\n }\n }\n\n const hashAlg: SupportedHashAlg = input.hashAlg ?? 'sha2-256';\n const plaintext = toBytes(input.content);\n const plaintextDigest = hashContent(plaintext, hashAlg);\n const hashes = { [hashAlg]: plaintextDigest };\n\n // Encrypt the plaintext to the recipient public keys under the chosen KEM.\n // The item's plaintext-hash claim is bound into the slots transcript, so\n // the envelope cannot later be spliced onto a different hashes map.\n const sealed = eciesSealedPoeWrap({\n plaintext,\n hashes,\n recipientPublicKeys: input.recipients.map((r) => r),\n kem,\n });\n\n // Upload the ciphertext to Arweave (resumable for large ciphertexts).\n const uri = await uploadBlob(config, sealed.ciphertext, input.idempotencyKey);\n\n // Build the sealed record: one item with the plaintext-bind hash, the\n // `ar://<tx>` URI of the ciphertext, and the discriminated envelope shape.\n // Narrow on the envelope `kem` to emit the correct per-slot fields:\n // classical slots carry `{ epk, wrap }`, hybrid slots carry the single\n // 1120-byte `{ kem_ct, wrap }`.\n const env = sealed.envelope;\n const slots =\n env.kem === 'mlkem768x25519'\n ? env.slots.map((s) => ({\n kem_ct: cloneToOwnedBuffer(s.kem_ct),\n wrap: cloneToOwnedBuffer(s.wrap),\n }))\n : env.slots.map((s) => ({\n epk: cloneToOwnedBuffer(s.epk),\n wrap: cloneToOwnedBuffer(s.wrap),\n }));\n const envelope: EncryptionEnvelope = {\n scheme: 1,\n aead: env.aead,\n kem: env.kem,\n nonce: cloneToOwnedBuffer(env.nonce),\n slots,\n slots_mac: cloneToOwnedBuffer(env.slots_mac),\n };\n\n const record: PoeRecord = {\n v: 1,\n items: [\n {\n hashes,\n uris: [uri],\n enc: envelope,\n },\n ],\n };\n const recordBytes = await encodeRecord(record, input.signer);\n return postPublish(config, bytesToHex(recordBytes), input.quoteId, input.idempotencyKey);\n}\n\n/**\n * Merkle batch publish via /uploads + /publish — N leaves under one\n * transaction. The leaves-list CBOR is uploaded to Arweave as a single\n * blob; the on-chain record carries\n * `merkle[0] = { alg: 'rfc9162-sha256', root, leaf_count, uris: [ar://<tx>] }`.\n *\n * Only `sha2-256` leaves are supported because `rfc9162-sha256` is the only\n * registered tree algorithm and its underlying hash is SHA-256 (32-byte\n * leaves).\n */\nexport async function publishMerkle(\n config: ResolvedPublishConfig,\n input: PublishMerkleInput,\n): Promise<PublishMerkleResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n if (input.hashAlg !== undefined && input.hashAlg !== 'sha2-256') {\n throw new PublishError(\n 'UNSUPPORTED_HASH_ALG',\n `publishMerkle only supports 'sha2-256' leaves; got '${input.hashAlg as string}'`,\n );\n }\n if (input.leaves.length < 1) {\n throw new PublishError('INVALID_LEAVES', 'publishMerkle requires at least one leaf hash');\n }\n\n const leaves: Uint8Array[] = input.leaves.map((leaf, idx) => {\n const bytes = typeof leaf === 'string' ? hexToBytes(leaf) : leaf;\n if (!(bytes instanceof Uint8Array) || bytes.length !== LEAF_DIGEST_LENGTH) {\n throw new PublishError(\n 'INVALID_LEAVES',\n `leaves[${idx}] must be a ${LEAF_DIGEST_LENGTH}-byte sha2-256 digest`,\n );\n }\n return bytes;\n });\n\n const root = cloneToOwnedBuffer(merkleSha2256Root(leaves));\n const leavesListCbor = encodeLeavesList({ leaves, root });\n\n // Upload the leaves-list to Arweave (resumable for large leaves-lists).\n const uri = await uploadBlob(config, leavesListCbor, input.idempotencyKey);\n\n // Build the on-chain record with the resulting `ar://` URI.\n const merkleEntry: MerkleCommit = {\n alg: MERKLE_ALG_ID,\n root,\n leaf_count: leaves.length,\n uris: [uri],\n };\n const record: PoeRecord = { v: 1, merkle: [merkleEntry] };\n const recordBytes = await encodeRecord(record, input.signer);\n const published = await postPublish(\n config,\n bytesToHex(recordBytes),\n input.quoteId,\n input.idempotencyKey,\n );\n\n return {\n id: published.id,\n tx_hash: published.tx_hash,\n status: published.status,\n root: bytesToHex(root),\n leaf_count: leaves.length,\n ar_uri: uri,\n balance_after_usd_micros: published.balance_after_usd_micros,\n };\n}\n","// Low-level wrappers over the public mutating /api/v1/poe/* surface:\n//\n// POST /api/v1/poe/quote — lock a USD price for a publish\n// POST /api/v1/poe/uploads — multipart binary upload to a backend\n// POST /api/v1/poe/publish — single finalised record (JSON)\n// POST /api/v1/poe/publish-batch — 1..50 finalised records (JSON)\n//\n// Plus high-level helpers that compose the above into common flows:\n//\n// publishContent({content, quoteId, signer?}) — hash-only\n// publishPrehashed({hashes, quoteId, signer?}) — caller already holds digest\n// publishSealed({content, recipients, quoteId, signer?}) — encrypt + uploads + publish\n// publishMerkle({leaves, quoteId, signer?}) — uploads + publish, Merkle root\n\nimport { bytesToHex } from '../hex';\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport { PartialUploadError } from './partial-upload-error';\nimport {\n publishContent as publishContentImpl,\n publishMerkle as publishMerkleImpl,\n publishPrehashed as publishPrehashedImpl,\n publishSealed as publishSealedImpl,\n type ResolvedPublishConfig,\n} from './publish';\nimport { uploadResumable as uploadResumableImpl, type SingleShotUpload } from './resumable-upload';\nimport type {\n FetchImpl,\n PublishBatchInput,\n PublishBatchResponse,\n PublishContentInput,\n PublishInput,\n PublishMerkleInput,\n PublishMerkleResponse,\n PublishPrehashedInput,\n PublishResponse,\n PublishSealedInput,\n QuoteInput,\n QuoteResponse,\n UploadResumableInput,\n UploadResumableResult,\n UploadSuccessEntry,\n UploadsInput,\n UploadsResponse,\n} from './types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nfunction buildJsonHeaders(args: {\n apiKey: string | undefined;\n idempotencyKey?: string | undefined;\n}): Headers {\n const headers = new Headers({ 'content-type': 'application/json', accept: 'application/json' });\n if (args.apiKey !== undefined) headers.set('authorization', `Bearer ${args.apiKey}`);\n if (args.idempotencyKey !== undefined) headers.set('idempotency-key', args.idempotencyKey);\n return headers;\n}\n\nfunction buildMultipartHeaders(args: {\n apiKey: string | undefined;\n idempotencyKey?: string | undefined;\n}): Headers {\n // Do NOT set content-type — the runtime emits the multipart boundary header\n // automatically when the body is a FormData. Forcing it here would emit a\n // boundary-less content-type that the server rejects.\n const headers = new Headers({ accept: 'application/json' });\n if (args.apiKey !== undefined) headers.set('authorization', `Bearer ${args.apiKey}`);\n if (args.idempotencyKey !== undefined) headers.set('idempotency-key', args.idempotencyKey);\n return headers;\n}\n\nfunction toHex(record: Uint8Array | string): string {\n return typeof record === 'string' ? record : bytesToHex(record);\n}\n\nexport class PoeNamespace {\n private readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * Request an opaque price lock for an upcoming /publish call. The gateway\n * prices the described publish from the supplied byte counts, records the\n * lock, and returns a sealed price token: `quote_id`, the total `amount` in\n * `currency`, and an `expires_at`. The gateway's pricing internals are\n * deliberately NOT part of the response.\n *\n * `amount` is a decimal string; promote it to `BigInt` (or a decimal type)\n * at the application boundary if you need exact arithmetic.\n *\n * Pass the returned `quote_id` to `publish()` (or one of the high-level\n * `publishContent` / `publishSealed` / `publishMerkle` helpers).\n */\n async quote(input: QuoteInput): Promise<QuoteResponse> {\n const body = {\n record_bytes: input.recordBytes,\n recipient_count: input.recipientCount,\n file_bytes_total: input.fileBytesTotal,\n };\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/quote`, {\n method: 'POST',\n headers: buildJsonHeaders({ apiKey: this.config.apiKey }),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n return (await readJson(response)) as QuoteResponse;\n }\n\n /**\n * Upload 1..32 binary files to a storage backend. Returns one entry per file\n * — successful entries carry the `ar://` URI + content hash, failed entries\n * carry an error code / detail so the caller can retry just the failed\n * indices.\n *\n * Billing: free. The storage cost is part of the publish quote (POST\n * /api/v1/poe/quote → POST /api/v1/poe/publish) and is debited once at\n * publish time against the locked price snapshot.\n *\n * On HTTP-level failure (auth, rate limit, malformed request) this throws\n * a typed `Label309HttpError` subclass. Per-file failures inside a 200\n * response are NOT thrown by `uploads()` itself — the response body is\n * returned verbatim so the caller can decide how to react. The\n * higher-level helpers (`publishSealed`, `publishMerkle`) treat any failed\n * file as a `PartialUploadError`.\n */\n async uploads(input: UploadsInput): Promise<UploadsResponse> {\n const form = new FormData();\n form.append('target', input.target);\n for (let idx = 0; idx < input.data.length; idx++) {\n const bytes = input.data[idx]!;\n // Uint8Array is a valid Blob source in every runtime that ships\n // FormData (browser, undici, node 20+); cast through `unknown` keeps\n // strict-mode TS happy without dragging in lib.dom.iterable.d.ts here.\n form.append(\n `file_${idx}`,\n new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n `file_${idx}.bin`,\n );\n }\n const headers = buildMultipartHeaders({\n apiKey: this.config.apiKey,\n idempotencyKey: input.idempotencyKey,\n });\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/uploads`, {\n method: 'POST',\n headers,\n body: form,\n });\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadsResponse;\n }\n\n /**\n * Upload a single file of any size, choosing the ingress path by size.\n *\n * A file at or below `threshold` (default ~48 MiB) is sent with the unchanged\n * single-shot `uploads()` multipart call. A larger file is uploaded as a\n * resumable, content-addressed session: the helper streams the whole-file\n * SHA-256 once (never buffering a multi-GB file), creates a session, PUTs each\n * chunk (several in parallel, retrying a failed chunk), then completes —\n * polling the shared attempt endpoint when completion is accepted\n * asynchronously. Both paths converge on one `ar://` URI.\n *\n * The chunk size is the server's authoritative `chunk_bytes` from the create\n * response, clamped to its `max_chunk_bytes` ceiling; the client's `chunkBytes`\n * is only a request. A create-time dedup hit returns the existing URI without\n * uploading; a `402` funding error is surfaced as a typed error.\n *\n * The `source` works in both runtimes: a `Blob`/`File` in the browser, a\n * `Uint8Array`, a filesystem path string, or a pre-adapted `ResumableSource`\n * on the server. To resume an interrupted upload, pass the prior `sessionId`;\n * the helper GETs its status and uploads only the missing chunks.\n */\n async uploadResumable(input: UploadResumableInput): Promise<UploadResumableResult> {\n return uploadResumableImpl(this.config, this.singleShotUpload, input);\n }\n\n /**\n * Upload exactly one blob via the single-shot multipart route and resolve its\n * `ar://` URI. Backs the small-file branch of `uploadResumable`; it shares the\n * `uploads()` wire shape but takes one blob and an optional abort signal, and\n * surfaces a per-file failure as a `PartialUploadError` (the resumable helper\n * promises a single resolved URI, unlike the raw `uploads()` passthrough).\n */\n private readonly singleShotUpload: SingleShotUpload = async ({\n target,\n bytes,\n idempotencyKey,\n signal,\n }) => {\n const form = new FormData();\n form.append('target', target);\n form.append(\n 'file_0',\n new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n 'file_0.bin',\n );\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/uploads`, {\n method: 'POST',\n headers: buildMultipartHeaders({ apiKey: this.config.apiKey, idempotencyKey }),\n body: form,\n ...(signal ? { signal } : {}),\n });\n await throwIfNotOk(response);\n const result = (await readJson(response)) as UploadsResponse;\n const entry = result.uploads[0];\n if (entry === undefined || entry.ok === false) {\n throw new PartialUploadError(result);\n }\n const ok = entry as UploadSuccessEntry;\n return { uri: ok.uri, sha256: ok.sha256, bytes: ok.bytes };\n };\n\n /**\n * Submit a single finalised canonical-CBOR record to Cardano. Caller is\n * responsible for constructing the record bytes (use `publishContent` /\n * `publishSealed` / `publishMerkle` for the assisted flows) and for\n * acquiring a `quote_id` via `quote()` first.\n *\n * Returns 202 (`dedup_hit: false`) on freshly enqueued records, or 200\n * (`dedup_hit: true`) when the same record bytes were previously submitted\n * by this account. Dedup hits debit nothing.\n */\n async publish(input: PublishInput): Promise<PublishResponse> {\n const body: { record: string; quote_id: string; signatures?: ReadonlyArray<unknown> } = {\n record: toHex(input.record),\n quote_id: input.quoteId,\n };\n if (input.signatures !== undefined) body.signatures = input.signatures;\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/publish`, {\n method: 'POST',\n headers: buildJsonHeaders({\n apiKey: this.config.apiKey,\n idempotencyKey: input.idempotencyKey,\n }),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n const parsed = (await readJson(response)) as Omit<PublishResponse, 'dedup_hit'>;\n return { ...parsed, dedup_hit: response.status === 200 };\n }\n\n /**\n * Submit 1..50 finalised records as independent Cardano transactions.\n * Each entry carries its own `quote_id` — request quotes ahead of time\n * with one `quote()` call per record. Returns 200 with `results[]` —\n * successful entries land alongside failed ones; per-record errors do NOT\n * roll back the batch.\n */\n async publishBatch(input: PublishBatchInput): Promise<PublishBatchResponse> {\n const body = {\n records: input.records.map((r) => ({\n record: toHex(r.record),\n quote_id: r.quoteId,\n ...(r.signatures !== undefined ? { signatures: r.signatures } : {}),\n })),\n };\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/publish-batch`, {\n method: 'POST',\n headers: buildJsonHeaders({\n apiKey: this.config.apiKey,\n idempotencyKey: input.idempotencyKey,\n }),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n return (await readJson(response)) as PublishBatchResponse;\n }\n\n /**\n * High-level hash-only publish: hash the supplied content, build a\n * single-item Label 309 record, optionally sign it with the caller-supplied\n * signer, and submit. No Arweave, no storage round-trip — anchors the\n * digest only.\n */\n async publishContent(input: PublishContentInput): Promise<PublishResponse> {\n return publishContentImpl(this.config as ResolvedPublishConfig, input);\n }\n\n /**\n * Hash-already-computed publish: caller already holds the digest(s) — e.g.\n * the CLI `--hash <hex>` mode, an air-gapped offline hashing flow, or any\n * pipeline that proxies digests from another tool. No client-side hashing.\n */\n async publishPrehashed(input: PublishPrehashedInput): Promise<PublishResponse> {\n return publishPrehashedImpl(this.config as ResolvedPublishConfig, input);\n }\n\n /**\n * Sealed-PoE: encrypt the supplied content to the recipient X25519 public\n * keys (age-style sealed envelope), upload the ciphertext to Arweave via\n * /uploads, build a Label 309 record with the resulting `ar://` URI, sign\n * it (optional), and submit via /publish.\n *\n * The sender SHOULD include their own X25519 public key in `recipients`\n * to retain decrypt access — the SDK does NOT inject the sender silently.\n */\n async publishSealed(input: PublishSealedInput): Promise<PublishResponse> {\n return publishSealedImpl(this.config as ResolvedPublishConfig, input);\n }\n\n /**\n * Merkle batch publish: compute the RFC 9162 §2.1.1 root over N\n * caller-supplied 32-byte leaf hashes, upload the canonical leaves-list\n * CBOR to Arweave via /uploads, bind the root + leaf_count into\n * `merkle[0]` of an on-chain record, optionally sign, and submit.\n *\n * Returns the on-chain id + tx hash + root + leaf count + the canonical\n * `ar://<tx>` URI of the leaves-list. Anyone with that URI can later\n * fetch the leaves-list, recompute the root, and prove inclusion of any\n * leaf via `merkleSha2256VerifyInclusion`.\n */\n async publishMerkle(input: PublishMerkleInput): Promise<PublishMerkleResponse> {\n return publishMerkleImpl(this.config as ResolvedPublishConfig, input);\n }\n}\n","// `client.records.*` wraps the open-standard indexer read surface:\n//\n// GET /api/v1/records → records.list(input?)\n// GET /api/v1/records/{tx_hash} → records.get(txHash)\n// POST /api/v1/records/{tx_hash}/verify → records.verify(txHash, input)\n//\n// The PoE namespace owns the mutation methods (uploads, publish,\n// publishBatch + the high-level publishContent/publishSealed/publishMerkle\n// helpers); reads and verifications live here under Records — same tag\n// grouping the OpenAPI registry uses (`tags: ['Records']` on these\n// operationIds).\n//\n// Auth is optional: chain data is public. When an API key is configured the\n// SDK forwards it as `Authorization: Bearer …` so owner-only fields\n// (currently just `account_id`) surface for the caller's own rows, and so the\n// `sealed` list filter can resolve records addressed to the caller.\n\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport type {\n FetchImpl,\n PoeVerifyInput,\n RecordResource,\n RecordsListInput,\n RecordsListResponse,\n} from './types';\nimport type { VerifyReport } from '../verifier/types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nfunction buildHeaders(apiKey: string | undefined): Headers {\n const headers = new Headers({\n 'content-type': 'application/json',\n accept: 'application/json',\n });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n return headers;\n}\n\n/**\n * Derive the chain tip from a record page as `max(block_height +\n * num_confirmations - 1)` over the rows that carry a block height. Returns\n * `null` for an empty page or one with no anchored rows.\n */\nfunction deriveTipBlockHeight(records: ReadonlyArray<RecordResource>): number | null {\n let tip: number | null = null;\n for (const r of records) {\n if (r.block_height === null) continue;\n const candidate = r.block_height + r.num_confirmations - 1;\n tip = tip === null ? candidate : Math.max(tip, candidate);\n }\n return tip;\n}\n\nexport class RecordsNamespace {\n private readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * List records as a paginated `RecordsListResponse` whose `data[]` entries\n * are the same `RecordResource` projection `get()` returns.\n *\n * Pass `{ sealed: true }` to restrict the page to sealed records addressed\n * to the authenticated caller (the gateway resolves the recipient from the\n * bearer identity); omit it to list every record the caller may read. Page\n * with `{ cursor: previous.next_cursor }` until `has_more` is false.\n */\n async list(input?: RecordsListInput): Promise<RecordsListResponse> {\n const params = new URLSearchParams();\n if (input?.sealed === true) params.set('sealed', 'true');\n if (input?.limit !== undefined) params.set('limit', String(input.limit));\n if (input?.cursor !== undefined && input.cursor !== null) {\n params.set('cursor', input.cursor);\n }\n const query = params.toString();\n const url = `${this.config.baseUrl}/api/v1/records${query === '' ? '' : `?${query}`}`;\n const response = await this.config.fetch(url, {\n method: 'GET',\n headers: buildHeaders(this.config.apiKey),\n });\n await throwIfNotOk(response);\n const page = (await readJson(response)) as RecordsListResponse;\n // A gateway that reports `tip_block_height` populates confirmation data\n // directly; otherwise derive it from the page rows so sealed-record sync\n // has a tip to compute confirmation depth against.\n if (page.tip_block_height === undefined || page.tip_block_height === null) {\n return { ...page, tip_block_height: deriveTipBlockHeight(page.data) };\n }\n return page;\n }\n\n /**\n * Fetch a record by Cardano transaction hash. Returns the JSON\n * `RecordResource` projection — same shape every `records.list` page entry\n * carries inside `data[]`.\n *\n * 404 (RecordNotFoundError) on tx_hashes the indexer has not seen, OR on\n * un-anchored rows when the caller is not their owner (oracle-safe\n * indistinguishable response per the route's privacy invariant).\n */\n async get(txHash: string): Promise<RecordResource> {\n const response = await this.config.fetch(\n `${this.config.baseUrl}/api/v1/records/${encodeURIComponent(txHash)}`,\n {\n method: 'GET',\n headers: buildHeaders(this.config.apiKey),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as RecordResource;\n }\n\n /**\n * Run the canonical Label 309 verifier against the record at `txHash`.\n * Returns the same `VerifyReport` shape the standalone verifier emits —\n * `VerifyReport` IS the wire body of this endpoint, with no transformer in\n * between.\n *\n * Auth required (Bearer with `poe:read` scope, or NextAuth session\n * cookie). This is the hosted PUBLIC verifier: it accepts no decryption\n * credentials, and sealed items report as unverifiable without decryption.\n * To verify as a recipient (decrypt + plaintext-hash recheck), run the\n * `verifier` module locally with its `decryption` input — keys never leave\n * the process. Optional `fetch_content: false` skips content re-fetching;\n * affected claims report `not_checked`.\n */\n async verify(txHash: string, input?: PoeVerifyInput): Promise<VerifyReport> {\n const response = await this.config.fetch(\n `${this.config.baseUrl}/api/v1/records/${encodeURIComponent(txHash)}/verify`,\n {\n method: 'POST',\n headers: buildHeaders(this.config.apiKey),\n body: JSON.stringify(input ?? {}),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as VerifyReport;\n }\n}\n","import { AccountNamespace } from './account';\nimport { InvalidClientConfigError } from './invalid-client-config-error';\nimport { PoeNamespace } from './poe';\nimport { RecordsNamespace } from './records';\nimport type { Label309ClientConfig, FetchImpl } from './types';\n\nfunction resolveFetch(provided: FetchImpl | undefined): FetchImpl {\n if (provided !== undefined) return provided;\n if (typeof globalThis.fetch === 'function') {\n // Bind to preserve `this` inside Node/browser fetch implementations.\n return globalThis.fetch.bind(globalThis);\n }\n throw new Error(\n 'Label309Client: no fetch implementation available. Pass `fetch` in the config or run on a platform with globalThis.fetch.',\n );\n}\n\n/**\n * Resolves the gateway base URL the client targets.\n *\n * `baseUrl` is REQUIRED and is used verbatim — the client is gateway-agnostic\n * and binds to no particular deployment. A missing or empty `baseUrl` is a\n * configuration error: there is nowhere to send requests. Trailing slashes are\n * stripped so callers may pass `https://gw.example.com/` or\n * `https://gw.example.com` interchangeably.\n *\n * The `apiKey`, when present, is an OPAQUE bearer token forwarded verbatim as\n * `Authorization: Bearer <apiKey>`. It is never parsed, validated, or used to\n * infer the URL — any Label 309 gateway may issue keys in its own format. Omit it\n * for anonymous read-only usage.\n */\nfunction resolveBaseUrl(config: Label309ClientConfig): string {\n const baseUrl = config.baseUrl?.trim();\n if (baseUrl === undefined || baseUrl === '') {\n throw new InvalidClientConfigError(\n 'Label309Client: baseUrl is required. Pass the base URL of the Label 309 ' +\n 'gateway you are targeting (e.g. https://gateway.example.com).',\n );\n }\n return baseUrl.replace(/\\/$/, '');\n}\n\nexport class Label309Client {\n public readonly poe: PoeNamespace;\n public readonly records: RecordsNamespace;\n public readonly account: AccountNamespace;\n\n /**\n * Construct a client against a Label 309 gateway.\n *\n * `config.baseUrl` is required — there is no default deployment. The\n * `config.apiKey`, when supplied, is an opaque bearer token sent verbatim as\n * `Authorization: Bearer <apiKey>`; omit it for anonymous read-only access.\n *\n * PoE submissions debit the gateway's own balance model. Acquire a price lock\n * via `client.poe.quote(...)` first; the resulting `quote_id` is consumed by\n * the publish call.\n */\n constructor(config: Label309ClientConfig) {\n const fetchImpl = resolveFetch(config.fetch);\n const baseUrl = resolveBaseUrl(config);\n const resolved = { apiKey: config.apiKey, baseUrl, fetch: fetchImpl };\n this.poe = new PoeNamespace(resolved);\n this.records = new RecordsNamespace(resolved);\n this.account = new AccountNamespace(resolved);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../crypto-core/src/cbor/canonical.ts","../../../crypto-core/src/sig/ed25519.ts","../../../crypto-core/src/cose/sign1.ts","../../../crypto-core/src/hash/sha-256.ts","../../../crypto-core/src/hash/blake2b-256.ts","../../../crypto-core/src/hash/merkle-sha2-256.ts","../../../poe-standard/src/schema.ts","../../../poe-standard/src/encoder.ts","../../../poe-standard/src/error-codes.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/utils.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/_crystals.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/ml-kem.ts","../../../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/src/hybrid.ts","../../../crypto-core/src/aead/chacha20-poly1305.ts","../../../crypto-core/src/kem/mlkem768x25519.ts","../../../crypto-core/src/kem/x25519.ts","../../../crypto-core/src/kdf/hkdf.ts","../../../crypto-core/src/sealed-poe/errors.ts","../../../crypto-core/src/sealed-poe/stream.ts","../../../crypto-core/src/sealed-poe/transcript.ts","../../../crypto-core/src/sealed-poe/wrap.ts","../../../crypto-core/src/sealed-poe/passphrase-normalize.ts","../../../poe-standard/src/validator.ts","../../src/client/off-host-sign.ts","../../src/client/http-error.ts","../../src/client/batch-empty-error.ts","../../src/client/batch-too-large-error.ts","../../src/client/forbidden-error.ts","../../src/client/idempotency-conflict-error.ts","../../src/client/insufficient-funds-error.ts","../../src/client/insufficient-scope-error.ts","../../src/client/internal-server-error.ts","../../src/client/invalid-body-error.ts","../../src/client/malformed-cbor-error.ts","../../src/client/not-found-error.ts","../../src/client/quote-already-consumed-error.ts","../../src/client/quote-expired-error.ts","../../src/client/quote-not-found-error.ts","../../src/client/rate-limited-error.ts","../../src/client/record-not-found-error.ts","../../src/client/service-unavailable-error.ts","../../src/client/unauthorized-error.ts","../../src/client/validation-failed-error.ts","../../src/client/parse-http-error.ts","../../src/client/http-helpers.ts","../../src/client/account.ts","../../src/client/invalid-client-config-error.ts","../../src/hex.ts","../../src/client/partial-upload-error.ts","../../../crypto-core/src/merkle/leaves-list.ts","../../src/client/resumable-source.ts","../../src/client/resumable-upload.ts","../../src/client/publish.ts","../../src/client/poe.ts","../../src/client/records.ts","../../src/client/label-309-client.ts"],"names":["encodeCanonicalCbor","encode","sortCoreDeterministic","nobleSha256","blake2b","sha256","out","randb","abytes_","opts","N","Q","F","ROOT_OF_UNITY","z","shake256","abytes","sha3_256","concatBytes","x25519","hashes","NONCE_LENGTH","randomBytes","EMPTY_BYTES","readString","DIGEST_LENGTH","bytesToHex","ED25519_PUBLIC_KEY_LENGTH","ED25519_SIGNATURE_LENGTH","X25519_PUBLIC_KEY_LENGTH","MLKEM768X25519_PUBLIC_KEY_LENGTH","cloneToOwnedBuffer","readJson","parseRetryAfter","throwIfNotOk","buildJsonHeaders","buildMultipartHeaders","buildHeaders"],"mappings":"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","file":"index.js","sourcesContent":["import { cdeDecodeOptions, decode, encode } from 'cbor2';\nimport { sortCoreDeterministic } from 'cbor2/sorts';\n\nimport { CanonicalCborError } from './errors';\n\nexport type CanonicalCborValue =\n | null\n | boolean\n | number\n | bigint\n | string\n | Uint8Array\n | readonly CanonicalCborValue[]\n | { readonly [key: string]: CanonicalCborValue }\n | ReadonlyMap<string | number, CanonicalCborValue>;\n\nexport function encodeCanonicalCbor(value: CanonicalCborValue): Uint8Array {\n return encode(value, {\n cde: true,\n collapseBigInts: true,\n rejectDuplicateKeys: true,\n sortKeys: sortCoreDeterministic,\n });\n}\n\nexport function decodeCanonicalCbor(bytes: Uint8Array): unknown {\n try {\n return decode(bytes, {\n ...cdeDecodeOptions,\n rejectStreaming: true,\n rejectDuplicateKeys: true,\n // A Label 309 record carries integers, byte/text strings, arrays, maps and\n // `null` — and nothing else. Without these rejections the major-type-7\n // surface leaks into the decoder: a float16/32/64 that happens to hold an\n // integral value (e.g. 1.0) silently decodes to the integer 1 and passes\n // a `z.literal(1)` / Number.isInteger schema check, so two byte strings\n // that are NOT byte-identical canonicalise to the same record. That\n // breaks the cross-implementation parity invariant (the Python twin\n // already rejects non-integer `v` / `enc.scheme` outright). Reject the\n // whole non-record surface — floats, negative zero, undefined, and\n // non-{true,false,null} simple values — so any such input surfaces as\n // MALFORMED_CBOR via mapDecodeError rather than decoding to a look-alike.\n rejectFloats: true,\n rejectNegativeZero: true,\n rejectUndefined: true,\n rejectSimple: true,\n });\n } catch (cause) {\n throw mapDecodeError(cause);\n }\n}\n\nfunction mapDecodeError(cause: unknown): CanonicalCborError {\n const message = cause instanceof Error ? cause.message : String(cause);\n const lower = message.toLowerCase();\n // Every canonical-decode violation collapses to the single public taxonomy\n // code MALFORMED_CBOR: indefinite-length (streaming) items, duplicate keys,\n // non-canonical (unsorted) key ordering, non-minimal integer encodings, and\n // invalid UTF-8 in text strings. cbor2 raises the SAME \"Duplicate or out of\n // order key\" message for both true duplicates AND distinct-but-unsorted keys,\n // so the two are indistinguishable by message — and per the Label 309 taxonomy\n // both belong under MALFORMED_CBOR anyway. The specific cause survives in the\n // human-readable message below; for indefinite-length we state it explicitly\n // so the diagnostic is not lost when the code is collapsed.\n const isIndefinite = lower.includes('streaming') || lower.includes('indefinite');\n const detail = isIndefinite\n ? `indefinite-length items are not permitted in canonical CBOR: ${message}`\n : message;\n return new CanonicalCborError('MALFORMED_CBOR', `cbor decode failed: ${detail}`, { cause });\n}\n","import * as ed from '@noble/ed25519';\nimport { sha512 } from '@noble/hashes/sha2.js';\n\ned.hashes.sha512 = sha512;\n\n// Ed25519 group order L (= 2^252 + 27742317777372353535851937790883648493).\nconst L = ed.Point.CURVE().n;\n\nexport interface SignEd25519Opts {\n readonly seed: Uint8Array;\n readonly message: Uint8Array;\n}\n\nexport interface VerifyEd25519Opts {\n readonly publicKey: Uint8Array;\n readonly message: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface GetPublicKeyEd25519Opts {\n readonly seed: Uint8Array;\n}\n\nexport function signEd25519(opts: SignEd25519Opts): Uint8Array {\n return ed.sign(opts.message, opts.seed);\n}\n\n// Little-endian 32-byte scalar → bigint.\nfunction leBytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n value = (value << 8n) | BigInt(bytes[i]!);\n }\n return value;\n}\n\n// Strict (non-cofactored) Ed25519 verification per RFC 8032 §5.1.7, matching\n// libsodium/PyNaCl `crypto_sign_verify_detached` and ed25519-dalek\n// `verify_strict`. The cofactor-less check rejects every small-order /\n// torsion-component edge case in the C2SP/CCTV corpus, which noble's\n// `{ zip215: false }` mode does NOT (it remains cofactored: it checks\n// `[8]([S]B - [k]A - R) == 0`, accepting torsion components).\n//\n// The verification equation is the unscaled `[S]B == R + [k]A`, rewritten as\n// `[S]B - [k]A - R == identity`. We reject S >= L (non-canonical scalar) and\n// any small-order A or R up front, so a torsion component can never be smuggled\n// through the cofactor multiplication the cofactored variant performs.\nexport function verifyEd25519(opts: VerifyEd25519Opts): boolean {\n const { signature, message, publicKey } = opts;\n if (signature.length !== 64 || publicKey.length !== 32) return false;\n\n // S = LE(sig[32..64]); reject if not a canonical scalar (S >= L).\n const S = leBytesToBigInt(signature.subarray(32, 64));\n if (S >= L) return false;\n\n // Decode A (public key) and R (sig[0..32]) with the canonical (non-zip215)\n // point encoding; a non-canonical encoding throws and rejects.\n let A: ed.Point;\n let R: ed.Point;\n try {\n A = ed.Point.fromBytes(publicKey);\n R = ed.Point.fromBytes(signature.subarray(0, 32));\n } catch {\n return false;\n }\n\n // Reject small-order (cofactor-torsion) A or R: this is exactly the strictness\n // that distinguishes verify_strict from the cofactored check.\n if (A.isSmallOrder() || R.isSmallOrder()) return false;\n\n // k = SHA-512(R || A || M) reduced mod L.\n const k =\n leBytesToBigInt(ed.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;\n\n // Accept iff [S]B - [k]A - R == identity. `multiplyUnsafe` returns the\n // identity for a 0 scalar, but guard explicitly to avoid relying on that.\n const sB = S === 0n ? ed.Point.ZERO : ed.Point.BASE.multiplyUnsafe(S);\n const kA = k === 0n ? ed.Point.ZERO : A.multiplyUnsafe(k);\n return sB.subtract(kA).subtract(R).is0();\n}\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nexport function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array {\n return ed.getPublicKey(opts.seed);\n}\n","import {\n decodeCanonicalCbor,\n encodeCanonicalCbor,\n type CanonicalCborValue,\n} from '../cbor/canonical';\nimport { CanonicalCborError } from '../cbor/errors';\nimport { blake2b224 } from '../hash/blake2b-256';\nimport { signEd25519, verifyEd25519 } from '../sig/ed25519';\nimport { compareCt } from '../util/compare-ct';\n\nimport { CoseVerifyError, type CoseVerifyResult } from './errors';\n\nexport type CoseHeader = Map<number | string, unknown>;\n\n// Label 309 v1 domain separator embedded as a prefix on `Sig_structure[3]`\n// (`to_sign`). The separator is\n// NOT placed in `Sig_structure[2]` (`external_aad`) because CIP-30 `signData`\n// — the only realistic wallet-signing path on Cardano — explicitly forbids a\n// non-empty `external_aad`. Pinning the prefix into the payload preserves the\n// anti-replay property while keeping wallet-produced signatures byte-identical\n// to verifier-side recomputation.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX = 'cardano-poe-record-sig-v1' as const;\n// Composer path-2 wallet flow consumes the prefix bytes directly\n// to assemble `toSign = prefix || canonical_cbor(record_body)` BEFORE calling\n// `walletSignData` (the wallet's `signData()` receives this concatenation as\n// its `payload` argument verbatim per CIP-30). The bytes constant is exported\n// so a composer can build the input without re-encoding the prefix at every\n// call site.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES = new TextEncoder().encode(\n CARDANO_POE_SIG_DOMAIN_PREFIX,\n);\n\n// Fail-fast: the prefix length is byte-pinned at 25 UTF-8 bytes. A different\n// runtime encoding would silently break round-tripping\n// against the reference vectors.\nif (CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length !== 25) {\n throw new Error(\n `cardano-poe-record-sig-v1 prefix must encode to exactly 25 UTF-8 bytes, got ${CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length}`,\n );\n}\n\nconst EMPTY_BYTES = new Uint8Array(0);\n\nexport interface CoseSign1Decoded {\n readonly protectedHeader: CoseHeader;\n // preserved for Sig_structure reconstruction — never re-encode the decoded header map (RFC 9052 §4.4)\n readonly protectedBytes: Uint8Array;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport interface BuildSigStructureArgs {\n readonly context: 'Signature1';\n readonly bodyProtectedBytes: Uint8Array;\n readonly externalAad: Uint8Array;\n readonly payload: Uint8Array;\n}\n\n// Raw RFC 9052 §4.4 Sig_structure builder. General-purpose: callers control\n// `external_aad` and `payload` exactly. For Label 309 record signing use\n// `buildLabel309SigStructure` instead — it enforces the Label 309 record-signature invariants.\nexport function buildSigStructure(args: BuildSigStructureArgs): Uint8Array {\n return encodeCanonicalCbor([\n args.context,\n args.bodyProtectedBytes,\n args.externalAad,\n args.payload,\n ] as readonly CanonicalCborValue[]);\n}\n\nexport interface BuildLabel309SigStructureArgs {\n readonly bodyProtectedBytes: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed.\n readonly recordBodyCbor: Uint8Array;\n}\n\n// Label 309 v1 specialisation of `Sig_structure` (RFC 9052 §4.4 base structure):\n// to_sign = utf8(\"cardano-poe-record-sig-v1\") || canonical_cbor(record_body_minus_sigs)\n// Sig_structure = [ \"Signature1\", body_protected, h'' (empty), to_sign ]\n// Always forces `external_aad = h''` (empty bstr) — the CIP-30 wallet path\n// cannot carry a non-empty `external_aad`, so the domain separator lives in\n// `Sig_structure[3]` rather than `Sig_structure[2]`.\nexport function buildLabel309SigStructure(args: BuildLabel309SigStructureArgs): Uint8Array {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.recordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.recordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n return buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: args.bodyProtectedBytes,\n externalAad: EMPTY_BYTES,\n payload: toSign,\n });\n}\n\nexport interface EncodeCoseSign1Args {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport function encodeCoseSign1(args: EncodeCoseSign1Args): Uint8Array {\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n return encodeCanonicalCbor([\n protectedBytes,\n args.unprotectedHeader as CanonicalCborValue,\n args.payload,\n args.signature,\n ] as readonly CanonicalCborValue[]);\n}\n\n// cbor2's decoder returns Map for integer-keyed maps but plain Object for empty\n// or string-keyed maps; normalise both representations to Map.\nfunction asCoseHeader(value: unknown): CoseHeader | null {\n if (value instanceof Map) return value as CoseHeader;\n if (value !== null && typeof value === 'object' && (value as object).constructor === Object) {\n return new Map(Object.entries(value as Record<string, unknown>));\n }\n return null;\n}\n\nexport function decodeCoseSign1(bytes: Uint8Array): CoseSign1Decoded {\n let arr: unknown;\n try {\n arr = decodeCanonicalCbor(bytes);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'cose decode failed', { cause });\n }\n if (!Array.isArray(arr) || arr.length !== 4) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'expected 4-element array');\n }\n const [protectedBytesRaw, unprotectedRaw, payloadRaw, signatureRaw] = arr;\n if (!(protectedBytesRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected_bytes must be bytes');\n }\n const unprotectedHeader = asCoseHeader(unprotectedRaw);\n if (unprotectedHeader === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'unprotected header must be map');\n }\n if (payloadRaw !== null && !(payloadRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'payload must be bytes or null');\n }\n if (!(signatureRaw instanceof Uint8Array) || signatureRaw.length !== 64) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'signature must be 64 bytes');\n }\n let protectedHeader: CoseHeader;\n if (protectedBytesRaw.length === 0) {\n protectedHeader = new Map();\n } else {\n let decodedProtected: unknown;\n try {\n decodedProtected = decodeCanonicalCbor(protectedBytesRaw);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header decode failed', { cause });\n }\n const ph = asCoseHeader(decodedProtected);\n if (ph === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header must decode to map');\n }\n // Empty protected header MUST encode as the single byte 0x40 (zero-length bstr),\n // not 0x41 0xA0 (a 1-byte bstr containing an empty CBOR map). RFC 9052 §3 +\n // Label 309 canonical-CBOR mandate.\n if (ph.size === 0) {\n throw new CoseVerifyError(\n 'MALFORMED_SIG_COSE',\n 'empty protected header must encode as 0x40 (zero-length bstr), not as an empty map',\n );\n }\n protectedHeader = ph;\n }\n return {\n protectedHeader,\n protectedBytes: protectedBytesRaw,\n unprotectedHeader,\n payload: payloadRaw,\n signature: signatureRaw,\n };\n}\n\nexport type CoseSign1BuildErrorCode = 'SIGNER_NOT_PROVIDED' | 'SIGNER_AND_SEED_BOTH_PROVIDED';\n\nexport class CoseSign1BuildError extends Error {\n readonly code: CoseSign1BuildErrorCode;\n\n constructor(code: CoseSign1BuildErrorCode, message: string) {\n super(message);\n this.name = 'CoseSign1BuildError';\n this.code = code;\n }\n}\n\nexport interface CoseSign1Label309BuildArgs {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n // Canonical CBOR of the record body with `sigs` removed. The\n // builder prepends the 25-byte UTF-8 domain prefix `cardano-poe-record-sig-v1`\n // internally — callers MUST NOT pre-concatenate it.\n readonly recordBodyCbor: Uint8Array;\n // EITHER the raw 32-byte Ed25519 seed (used by KAT tests, Python parity, and\n // the off-host signing helper) OR an injected signer closure that signs the\n // assembled Sig_structure bytes (composer-side use — keeps the private key\n // inside the unlock-store closure so it never escapes scope).\n // Exactly one of the two MUST be provided; mutual exclusion enforced at\n // runtime via CoseSign1BuildError.\n readonly signerSecretKey?: Uint8Array;\n readonly signer?: (sigStructureBytes: Uint8Array) => Uint8Array;\n}\n\n// Label 309 v1 record-signature builder:\n// 1. compute `to_sign = utf8(\"cardano-poe-record-sig-v1\") || recordBodyCbor`\n// 2. Sig_structure = [ \"Signature1\", bodyProtected, h'', to_sign ]\n// 3. Ed25519-sign Sig_structure (via seed OR injected closure)\n// 4. emit COSE_Sign1 with payload = CBOR null (detached signature, mandatory)\nexport function coseSign1Label309Build(args: CoseSign1Label309BuildArgs): Uint8Array {\n if (args.signerSecretKey === undefined && args.signer === undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n 'coseSign1Label309Build requires either signerSecretKey or signer',\n );\n }\n if (args.signerSecretKey !== undefined && args.signer !== undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_AND_SEED_BOTH_PROVIDED',\n 'coseSign1Label309Build accepts signerSecretKey XOR signer (not both)',\n );\n }\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n const sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: protectedBytes,\n recordBodyCbor: args.recordBodyCbor,\n });\n let signature: Uint8Array;\n if (args.signer !== undefined) {\n signature = args.signer(sigStructureBytes);\n if (!(signature instanceof Uint8Array) || signature.length !== 64) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n `injected signer must return a 64-byte Uint8Array; got ${signature instanceof Uint8Array ? `${signature.length}-byte Uint8Array` : typeof signature}`,\n );\n }\n } else {\n signature = signEd25519({ seed: args.signerSecretKey!, message: sigStructureBytes });\n }\n return encodeCoseSign1({\n protectedHeader: args.protectedHeader,\n unprotectedHeader: args.unprotectedHeader,\n payload: null,\n signature,\n });\n}\n\nexport interface CoseSign1Label309VerifyArgs {\n readonly message: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed (verifier-recomputed;\n // the 25-byte UTF-8 prefix is prepended internally — callers\n // MUST NOT pre-concatenate it).\n readonly detachedRecordBodyCbor: Uint8Array;\n // Optional out-of-band signer key (path-2 wallet path resolves the key from\n // `sigs[i].cose_key`). Path-1 records carry the 32-byte raw Ed25519 pubkey\n // in the protected header at label 4 (`kid`) and need no out-of-band hint.\n readonly expectedSignerKey?: Uint8Array;\n}\n\n// Label 309 v1 record-signature verifier:\n// - Decode COSE_Sign1\n// - Reject COSE_Sign1[2] != CBOR null (attached payload — including h'') as\n// MALFORMED_SIG_COSE_SIGN1\n// - Recompute to_sign = utf8(\"cardano-poe-record-sig-v1\") || detachedRecordBodyCbor\n// - Sig_structure = [ \"Signature1\", protectedBytes, h'', to_sign ]\n// - Strict Ed25519 verify (RFC 8032 §5.1.7 — `zip215: false` per ed25519.ts)\n//\n// The verifier does NOT accept an `externalAad` argument: Label 309 v1 pins\n// `external_aad = h''` and any deviation would either silently weaken the\n// domain separator or quietly accept malformed records. If a future CIP\n// revision re-enables external_aad, this helper takes a v-bump.\nexport function coseSign1Label309Verify(args: CoseSign1Label309VerifyArgs): CoseVerifyResult {\n let decoded: CoseSign1Decoded;\n try {\n decoded = decodeCoseSign1(args.message);\n } catch (e) {\n if (e instanceof CoseVerifyError) {\n return { ok: false, error: { code: e.code, message: 'errors.cose.malformed' } };\n }\n if (e instanceof CanonicalCborError) {\n return {\n ok: false,\n error: { code: 'MALFORMED_SIG_COSE', message: 'errors.cose.malformed_cbor' },\n };\n }\n throw e;\n }\n // Label 309 v1 mandate: COSE_Sign1[2] (payload field) MUST be CBOR `null` (0xF6).\n // Any non-null payload — including a zero-length byte string `h''` — MUST\n // be rejected as MALFORMED_SIG_COSE_SIGN1.\n if (decoded.payload !== null) {\n return {\n ok: false,\n error: {\n code: 'MALFORMED_SIG_COSE_SIGN1',\n message: 'errors.cose.attached_payload_forbidden',\n },\n };\n }\n const alg = decoded.protectedHeader.get(1);\n if (typeof alg !== 'number' || alg !== -8) {\n return {\n ok: false,\n error: { code: 'UNSUPPORTED_SIG_ALG', message: 'errors.cose.unsupported_alg' },\n };\n }\n const kidRaw = decoded.protectedHeader.get(4);\n let signerKey: Uint8Array | undefined;\n if (kidRaw instanceof Uint8Array && kidRaw.length === 32) {\n signerKey = kidRaw;\n } else if (args.expectedSignerKey instanceof Uint8Array && args.expectedSignerKey.length === 32) {\n signerKey = args.expectedSignerKey;\n }\n if (signerKey === undefined) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_unresolved' },\n };\n }\n // When both a protected-header kid AND an expectedSignerKey are provided,\n // require they agree (constant-time). A protected kid that disagrees with\n // the caller's out-of-band binding is a misuse, not a transient mismatch.\n if (\n kidRaw instanceof Uint8Array &&\n kidRaw.length === 32 &&\n args.expectedSignerKey instanceof Uint8Array &&\n args.expectedSignerKey.length === 32 &&\n !compareCt(kidRaw, args.expectedSignerKey)\n ) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_mismatch' },\n };\n }\n // CIP-8 `hashed = true` mode (the wallet-signed path-2 variant). The unprotected\n // header carries the literal text key `\"hashed\"` with boolean value `true`\n // (text-keyed CBOR maps decode to `Map<string, unknown>` via cbor2). When\n // set, both producer and verifier build `Sig_structure[3] = Blake2b-224(to_sign)`\n // (28-byte digest of the FULL `to_sign` payload including the 25-byte\n // domain prefix). When absent or false, the standard non-hashed path\n // applies unchanged.\n const hashedFlag = decoded.unprotectedHeader.get('hashed');\n let sigStructureBytes: Uint8Array;\n if (hashedFlag === true) {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.detachedRecordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.detachedRecordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n const hashedPayload = blake2b224(toSign);\n sigStructureBytes = buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: decoded.protectedBytes,\n externalAad: EMPTY_BYTES,\n payload: hashedPayload,\n });\n } else {\n sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: decoded.protectedBytes,\n recordBodyCbor: args.detachedRecordBodyCbor,\n });\n }\n const valid = verifyEd25519({\n publicKey: signerKey,\n message: sigStructureBytes,\n signature: decoded.signature,\n });\n if (!valid) {\n return {\n ok: false,\n error: { code: 'SIGNATURE_INVALID', message: 'errors.cose.signature_invalid' },\n };\n }\n return { ok: true, signerKey, alg };\n}\n","import { createSHA256 } from 'hash-wasm';\nimport { sha256 as nobleSha256 } from '@noble/hashes/sha2.js';\n\nexport function sha256(input: Uint8Array): Uint8Array {\n return nobleSha256(input);\n}\n\n/**\n * Stream a source through an incremental SHA-256 and return the 32-byte digest,\n * never holding more than one chunk in memory. Use this when the input is too\n * large to buffer (a multi-gigabyte file read in slices), where `sha256(input)`\n * would force the whole input into a single array first.\n */\nexport async function sha256Stream(source: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const hasher = await createSHA256();\n hasher.init();\n for await (const chunk of source) {\n hasher.update(chunk);\n }\n return hasher.digest('binary') as Uint8Array;\n}\n","import { blake2b } from '@noble/hashes/blake2.js';\n\nexport function blake2b256(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 32 });\n}\n\n// CIP-19 stake-address derivation, used for the wallet path-2 signer binding,\n// requires the 28-byte BLAKE2b digest of the signer's Ed25519 public key.\n// The Cardano ledger encodes stake addresses as\n// `network_header_byte || Blake2b-224(stake_vk)`\n// per CIP-19, so this output length is fixed by spec.\nexport function blake2b224(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 28 });\n}\n","// RFC 9162 §2.1.1 binary Merkle tree under SHA-256.\n// This implements the algorithm tier identified on the wire as the\n// `rfc9162-sha256` OPT-INFO; the record's `merkle[]` field carries the proof.\n//\n// Construction (RFC 9162 §2.1.1):\n// - Single leaf: MTH({d_0}) = SHA-256(0x00 || d_0)\n// - Internal node: MTH(L) = SHA-256(0x01 || MTH(L[0:k]) || MTH(L[k:n]))\n// where k = largest power of 2 strictly less than n.\n// - Empty trees (n == 0) are FORBIDDEN.\n// - The 0x00 leaf / 0x01 internal prefixes prevent the CVE-2012-2459\n// leaf-vs-internal collision family.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { compareCt } from '../util/compare-ct';\n\nexport const MERKLE_ALG_ID = 'rfc9162-sha256' as const;\n\nconst LEAF_PREFIX = 0x00;\nconst NODE_PREFIX = 0x01;\nconst DIGEST_LENGTH = 32;\n\nfunction validateLeaves(leaves: ReadonlyArray<Uint8Array>, fnName: string): void {\n if (leaves.length === 0) {\n throw new Error(`${fnName}: empty leaf list (n == 0 is forbidden by RFC 9162 §2.1.1)`);\n }\n for (let i = 0; i < leaves.length; i++) {\n const leaf = leaves[i];\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) {\n throw new Error(\n `${fnName}: leaf[${i}] must be a Uint8Array(${DIGEST_LENGTH}); got length ${\n leaf instanceof Uint8Array ? leaf.length : 'non-Uint8Array'\n }`,\n );\n }\n }\n}\n\nexport function merkleSha2256Root(leaves: ReadonlyArray<Uint8Array>): Uint8Array {\n validateLeaves(leaves, 'merkleSha2256Root');\n return mthRecursive(leaves, 0, leaves.length);\n}\n\nexport function merkleSha2256InclusionProof(\n leaves: ReadonlyArray<Uint8Array>,\n index: number,\n): Uint8Array[] {\n validateLeaves(leaves, 'merkleSha2256InclusionProof');\n if (!Number.isInteger(index) || index < 0 || index >= leaves.length) {\n throw new Error(\n `merkleSha2256InclusionProof: index ${index} out of range [0, ${leaves.length})`,\n );\n }\n return auditPath(leaves, index, 0, leaves.length);\n}\n\n/**\n * Verify an inclusion proof per RFC 9162 §2.1.3.2 (iterative form).\n *\n * `proof` is ordered leaf-to-root: `proof[0]` is the sibling at the leaf\n * level, `proof[m-1]` is the top-level sibling. The fold uses the\n * `sn`/`fn` tracking from RFC 9162: `sn` is the leaf index within the\n * current subtree, `fn` is (subtree_size - 1). At each step, `sn` odd\n * OR `sn == fn` means the current node is a right child (sibling on\n * the left); otherwise it is a left child (sibling on the right).\n * Both shift right by one each iteration. This handles non-power-of-2\n * sizes including the \"promote a lone right subtree\" cases.\n */\nexport function merkleSha2256VerifyInclusion(\n leaf: Uint8Array,\n index: number,\n treeSize: number,\n proof: ReadonlyArray<Uint8Array>,\n root: Uint8Array,\n): boolean {\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) return false;\n if (!(root instanceof Uint8Array) || root.length !== DIGEST_LENGTH) return false;\n if (\n !Number.isInteger(index) ||\n !Number.isInteger(treeSize) ||\n treeSize < 1 ||\n index < 0 ||\n index >= treeSize\n ) {\n return false;\n }\n for (let i = 0; i < proof.length; i++) {\n const sibling = proof[i];\n if (!(sibling instanceof Uint8Array) || sibling.length !== DIGEST_LENGTH) {\n return false;\n }\n }\n\n if (treeSize === 1) {\n if (proof.length !== 0 || index !== 0) return false;\n return compareCt(hashLeaf(leaf), root);\n }\n\n let h = hashLeaf(leaf);\n let sn = index;\n let fn = treeSize - 1;\n for (let i = 0; i < proof.length; i++) {\n if (fn === 0) return false;\n const sibling = proof[i] as Uint8Array;\n if ((sn & 1) === 1 || sn === fn) {\n h = hashNode(sibling, h);\n while ((sn & 1) === 0 && sn !== 0) {\n sn >>>= 1;\n fn >>>= 1;\n }\n } else {\n h = hashNode(h, sibling);\n }\n sn >>>= 1;\n fn >>>= 1;\n }\n if (fn !== 0) return false;\n return compareCt(h, root);\n}\n\nfunction largestPow2Lt(n: number): number {\n let k = 1;\n while (k * 2 < n) k *= 2;\n return k;\n}\n\nfunction hashLeaf(d: Uint8Array): Uint8Array {\n const buf = new Uint8Array(1 + d.length);\n buf[0] = LEAF_PREFIX;\n buf.set(d, 1);\n return sha256(buf);\n}\n\nfunction hashNode(left: Uint8Array, right: Uint8Array): Uint8Array {\n const buf = new Uint8Array(1 + left.length + right.length);\n buf[0] = NODE_PREFIX;\n buf.set(left, 1);\n buf.set(right, 1 + left.length);\n return sha256(buf);\n}\n\nfunction mthRecursive(leaves: ReadonlyArray<Uint8Array>, start: number, end: number): Uint8Array {\n const n = end - start;\n if (n === 1) {\n return hashLeaf(leaves[start] as Uint8Array);\n }\n const k = largestPow2Lt(n);\n const left = mthRecursive(leaves, start, start + k);\n const right = mthRecursive(leaves, start + k, end);\n return hashNode(left, right);\n}\n\nfunction auditPath(\n leaves: ReadonlyArray<Uint8Array>,\n i: number,\n start: number,\n end: number,\n): Uint8Array[] {\n const n = end - start;\n if (n === 1) return [];\n const k = largestPow2Lt(n);\n if (i < k) {\n const subPath = auditPath(leaves, i, start, start + k);\n subPath.push(mthRecursive(leaves, start + k, end));\n return subPath;\n }\n const subPath = auditPath(leaves, i - k, start + k, end);\n subPath.push(mthRecursive(leaves, start, start + k));\n return subPath;\n}\n","// Label 309 v1 PoE record Zod schemas.\n//\n// Scope: structural shape gate over the DECODED record body. The schema\n// enforces per-field CBOR types (every map position rejects a CBOR byte\n// string — see the text-keyed-map gate below), the fixed byte lengths a field\n// can assert in isolation (32-byte `supersedes`, 32-byte `slots_mac`, the\n// 16..64-byte passphrase salt), closed-map invariants (`items[i]`,\n// `merkle[i]`, `sigs[i]`, `passphrase`), and the `v == 1` literal.\n// Cross-field rules (content-hash binding under `enc`, slots/passphrase\n// exclusivity, `crit[]` shape, registry membership of algorithm identifiers,\n// COSE_Sign1 structural decode, URI shape, non-empty-array rules, integer\n// ranges) fire in `validator.ts` so each violation emits its precise\n// canonical code rather than a generic schema mismatch.\n//\n// Every logical byte string is a SINGLE CBOR byte string and every URI is a\n// SINGLE text string: record-body fields carry no 64-byte cap and no chunk\n// wrappers. The ledger's 64-byte metadata-string cap is satisfied by the\n// whole-body transport chunk array alone (see `carriage.ts`), which is\n// reassembled before the validator ever sees the body.\n\nimport { z } from 'zod';\n\n// =============================================================================\n// Text-keyed-map gate\n// =============================================================================\n//\n// Every map position in the record grammar is a CBOR text-keyed map. The\n// canonical decoder surfaces such a map as a plain object — but a CBOR byte\n// string surfaces as a Uint8Array, which is ALSO an object to Zod, so an\n// ungated object schema would walk its byte indices as if they were map keys\n// and mis-report one unknown-key issue per byte plus a missing-required issue\n// per absent field. The gate runs ahead of the map schema and fails a byte\n// string with a SINGLE issue at the position itself — the same one-issue\n// rejection every other non-map CBOR shape already receives from the object\n// parser; the validator's issue mapper then lifts it to the position's\n// canonical code by path. (`z.record` positions need no gate: Zod's record\n// parser rejects a Uint8Array outright. A map carrying non-text keys decodes\n// to a `Map` and is handled by the validator's pre-guard, not here.)\nfunction textKeyedMap<S extends z.ZodType>(inner: S) {\n return z\n .custom<unknown>((value) => !(value instanceof Uint8Array), {\n message: 'CBOR byte string present where a text-keyed map is required',\n })\n .pipe(inner);\n}\n\n// =============================================================================\n// Hashes map\n// =============================================================================\n//\n// `hashes` is a non-empty CBOR map keyed by content-hash algorithm identifier\n// (a text string from the content-hash registry) with the 32-byte digest as\n// value. The canonical decoder surfaces a text-keyed CBOR map as a plain JS\n// object — `z.record` admits any string key here. Registry membership\n// (`UNSUPPORTED_HASH_ALG`), per-algorithm digest length\n// (`HASH_DIGEST_LENGTH_MISMATCH`), and the non-empty rule live in the\n// validator's domain pass.\n\nexport const HashDigestSchema = z.instanceof(Uint8Array);\n\nexport const HashesMapSchema = z.record(z.string(), HashDigestSchema);\nexport type HashesMap = z.infer<typeof HashesMapSchema>;\n\n// =============================================================================\n// URIs\n// =============================================================================\n//\n// One absolute URI in a single text string. Absolute-URI / fragment / scheme\n// / per-scheme body rules (`INVALID_URI`) are domain checks.\n\nexport const UriSchema = z.string();\nexport type Uri = z.infer<typeof UriSchema>;\n\n// =============================================================================\n// Top-level `merkle[]`\n// =============================================================================\n//\n// Each commit is a closed map `{alg, root, leaf_count, ? uris}`. `alg` is open\n// (registry membership → `UNSUPPORTED_MERKLE_COMMIT_ALG` in the domain pass).\n// `leaf_count` is a CBOR unsigned integer pinned to `1 .. 2^32 − 1`, handled\n// as an EXACT integer: the canonical decoder surfaces values above 2^53 − 1 as\n// `bigint`, so the schema admits both representations and the domain pass\n// enforces the range (`SCHEMA_MERKLE_LEAF_COUNT_INVALID`) without ever\n// rounding through a float.\n\nexport const MerkleCommitSchema = textKeyedMap(\n z\n .object({\n alg: z.string(),\n root: z.instanceof(Uint8Array),\n leaf_count: z.union([z.number().int(), z.bigint()]),\n uris: z.array(UriSchema).optional(),\n })\n .strict(),\n);\nexport type MerkleCommit = z.infer<typeof MerkleCommitSchema>;\n\n// =============================================================================\n// Encryption envelope\n// =============================================================================\n//\n// The wire `enc` value is a CHOICE between two readings, mirroring the\n// grammar's `enc = enc-scheme-1 / enc-opaque`:\n//\n// - the scheme-1 shape — the closed map this revision defines, applied by\n// the validator only when `scheme`, `kem`, and `aead` are ALL supported\n// identifiers;\n// - the opaque reading — `scheme` (any CBOR unsigned integer) plus\n// arbitrary text-keyed bounded metadata, the degrade-to-opaque escape\n// hatch for envelopes under identifiers this implementation does not\n// support (`ENC_UNSUPPORTED`).\n//\n// The choice is not a discriminator: a `scheme: 1` envelope that fails the\n// scheme-1 shape is rejected with its typed code, never reclassified as\n// opaque. The validator therefore keeps `enc` as `unknown` at the item layer\n// and dispatches on raw `scheme` / `kem` / `aead` support before applying\n// `EncScheme1Schema`.\n\n// Per-slot recipient entry. The slot shape is KEM-driven:\n//\n// - x25519: `{ epk: bstr(32), wrap: bstr(48) }` — `epk` is the\n// ephemeral X25519 public key.\n// - mlkem768x25519: `{ kem_ct: bstr(1120), wrap: bstr(48) }` — `kem_ct` is\n// the single 1120-byte X-Wing encapsulation; there is NO per-slot `epk`\n// on the hybrid path (the X25519 ephemeral is the trailing 32 bytes of\n// `kem_ct`).\n//\n// The schema is deliberately PERMISSIVE: all three fields are optional and\n// `.strict()` is not applied, because the required shape depends on the\n// envelope-level `kem`, which a slot cannot see in isolation. The KEM-driven\n// gate in the validator emits the precise codes (`KEM_EPK_LENGTH_MISMATCH`,\n// `KEM_CT_LENGTH_MISMATCH`, `WRAP_LENGTH_MISMATCH`, `ENC_SLOT_INVALID_SHAPE`)\n// against the RAW decoded slot key set, so cross-KEM contamination and stray\n// keys are rejected even though the schema strips nothing here.\nexport const SlotSchema = textKeyedMap(\n z.object({\n epk: z.instanceof(Uint8Array).optional(),\n kem_ct: z.instanceof(Uint8Array).optional(),\n wrap: z.instanceof(Uint8Array).optional(),\n }),\n);\nexport type Slot = z.infer<typeof SlotSchema>;\n\n// Argon2id params `{m, t, p}` — a closed map of CBOR unsigned integers in the\n// pinned `0 .. 2^32 − 1` exact-integer range. The closed-map rule, the range,\n// and the floor checks all emit their codes in the validator's domain pass;\n// this schema is the public convenience type for producers.\nexport const Argon2idParamsSchema = textKeyedMap(\n z\n .object({\n m: z.union([z.number().int(), z.bigint()]),\n t: z.union([z.number().int(), z.bigint()]),\n p: z.union([z.number().int(), z.bigint()]),\n })\n .strict(),\n);\nexport type Argon2idParams = z.infer<typeof Argon2idParamsSchema>;\n\n// Passphrase block. `alg` is open (registry membership →\n// `ENC_PASSPHRASE_ALG_UNSUPPORTED` in the domain pass); `params` is open here\n// (the domain pass narrows on the registered `alg` and emits\n// `SCHEMA_UNKNOWN_FIELD` / `SCHEMA_MISSING_REQUIRED` / `SCHEMA_TYPE_MISMATCH`\n// / the floor and ceiling codes per sub-field). Salt length bounds are\n// schema-layer refinements carrying their dedicated codes.\nexport const PassphraseBlockSchema = textKeyedMap(\n z\n .object({\n alg: z.string(),\n salt: z.instanceof(Uint8Array).superRefine((bytes, ctx) => {\n if (bytes.length < 16) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message: `passphrase.salt length ${bytes.length} < 16`,\n params: { code: 'ENC_PASSPHRASE_SALT_TOO_SHORT' },\n });\n } else if (bytes.length > 64) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message: `passphrase.salt length ${bytes.length} > 64`,\n params: { code: 'ENC_PASSPHRASE_SALT_TOO_LONG' },\n });\n }\n }),\n params: z.record(z.string(), z.unknown()),\n })\n .strict(),\n);\nexport type PassphraseBlock = z.infer<typeof PassphraseBlockSchema>;\n\n// The typed scheme-1 envelope arm. Applied by the validator only when\n// `scheme` / `kem` / `aead` are all supported identifiers; under an\n// unsupported identifier the envelope takes the opaque reading instead and\n// this schema never runs. The map is CLOSED (`.strict()`): an unknown key in\n// a supported envelope is `SCHEMA_UNKNOWN_FIELD`, never a reason to fall back\n// to the opaque reading. Cross-field key-path invariants (exclusivity,\n// `slots` ↔ `slots_mac` ↔ `kem`, non-empty `slots`) are domain checks.\nexport const EncScheme1Schema = textKeyedMap(\n z\n .object({\n scheme: z.literal(1),\n aead: z.string(),\n kem: z.string().optional(),\n nonce: z.instanceof(Uint8Array),\n slots: z.array(SlotSchema).optional(),\n slots_mac: z\n .instanceof(Uint8Array)\n .refine((b) => b.length === 32, {\n params: { code: 'ENC_SLOTS_MAC_INVALID_LENGTH' },\n })\n .optional(),\n passphrase: PassphraseBlockSchema.optional(),\n })\n .strict(),\n);\nexport type EncScheme1 = z.infer<typeof EncScheme1Schema>;\n\n// The opaque reading: `scheme` is the only structurally required key (any\n// CBOR unsigned integer — `bigint` admits values above 2^53), and every other\n// text-keyed entry is unconstrained bounded metadata. A verifier escape\n// hatch, never a producer surface.\nexport const EncOpaqueSchema = textKeyedMap(\n z.looseObject({\n scheme: z.union([z.number().int().nonnegative(), z.bigint().nonnegative()]),\n }),\n);\nexport type EncOpaque = z.infer<typeof EncOpaqueSchema>;\n\nexport const EncryptionEnvelopeSchema = z.union([EncScheme1Schema, EncOpaqueSchema]);\nexport type EncryptionEnvelope = z.infer<typeof EncryptionEnvelopeSchema>;\n\n// =============================================================================\n// Item entry\n// =============================================================================\n\nexport const ItemEntrySchema = textKeyedMap(\n z\n .object({\n hashes: HashesMapSchema,\n uris: z.array(UriSchema).optional(),\n // Captured as `unknown`: the envelope is a union whose disposition\n // (typed scheme-1 vs opaque) depends on identifier support, so the\n // validator's domain pass — not this schema — narrows it.\n enc: z.unknown().optional(),\n })\n .strict(),\n);\nexport type ItemEntry = z.infer<typeof ItemEntrySchema>;\n\n// =============================================================================\n// Sig entry\n// =============================================================================\n//\n// Closed CBOR map `{cose_sign1, ? cose_key}`. Each value is a SINGLE byte\n// string carrying the CBOR-encoded COSE_Sign1 / COSE_Key. Canonical CBOR\n// map-key sort (RFC 8949 §4.2.1, bytewise lex on encoded keys) places\n// `cose_key` before `cose_sign1`; schema property order is irrelevant.\nexport const SigEntrySchema = textKeyedMap(\n z\n .object({\n cose_key: z.instanceof(Uint8Array).optional(),\n cose_sign1: z.instanceof(Uint8Array),\n })\n .strict(),\n);\nexport type SigEntry = z.infer<typeof SigEntrySchema>;\n\n// =============================================================================\n// Supersedence\n// =============================================================================\n\nexport const SupersedesSchema = z.instanceof(Uint8Array).refine((b) => b.length === 32, {\n params: { code: 'SUPERSEDES_TX_INVALID_LENGTH' },\n});\nexport type Supersedes = z.infer<typeof SupersedesSchema>;\n\n// =============================================================================\n// Top-level record\n// =============================================================================\n//\n// `v == 1` is a literal — a future major (`v: 2`) MUST be rejected with\n// `SCHEMA_INVALID_LITERAL`. `z.literal(1)` preserves the narrow `1` type for\n// the inferred `PoeRecord[\"v\"]` and emits Zod's `invalid_value` code, which\n// the validator's mapper lifts to `SCHEMA_INVALID_LITERAL`.\n//\n// `looseObject` admits extension keys; the validator's domain pass rejects\n// unknown keys that match neither extension namespace with\n// `SCHEMA_UNKNOWN_FIELD`.\nexport const VersionLiteralSchema = z.literal(1);\n\nexport const PoeRecordSchema = textKeyedMap(\n z.looseObject({\n v: VersionLiteralSchema,\n items: z.array(ItemEntrySchema).optional(),\n merkle: z.array(MerkleCommitSchema).optional(),\n supersedes: SupersedesSchema.optional(),\n sigs: z.array(SigEntrySchema).optional(),\n crit: z.array(z.string()).optional(),\n }),\n);\nexport type PoeRecord = z.infer<typeof PoeRecordSchema>;\n\n// =============================================================================\n// Closed top-level base-key registry\n// =============================================================================\n//\n// Used by the validator's domain pass to distinguish unknown-typo keys from\n// well-formed extension keys.\nexport const TOP_LEVEL_BASE_KEYS: ReadonlySet<string> = new Set([\n 'v',\n 'items',\n 'merkle',\n 'supersedes',\n 'sigs',\n 'crit',\n]);\n\n// Extension-key namespaces: `^x-.+` (vendor / experimental) and `^[a-z]+-.+`\n// (companion namespace), with control characters (U+0000–U+001F,\n// U+007F–U+009F) rejected ANYWHERE in the key — including a trailing newline,\n// so `x-note\\n` and `x-a\\nb` are both outside the namespace. The suffix\n// character class spells the exclusion out rather than relying on `.`\n// semantics, the literal `x-` / `[a-z]+-` prefixes admit no control\n// characters by construction, and `$` in JavaScript matches only at the true\n// end of the string, so a trailing newline cannot hide behind the anchor.\n// eslint-disable-next-line no-control-regex -- the control-character exclusion IS the admissibility rule\nexport const EXTENSION_KEY_VENDOR_RE = /^x-[^\\u0000-\\u001f\\u007f-\\u009f]+$/;\n// eslint-disable-next-line no-control-regex -- the control-character exclusion IS the admissibility rule\nexport const EXTENSION_KEY_COMPANION_RE = /^[a-z]+-[^\\u0000-\\u001f\\u007f-\\u009f]+$/;\n\nexport function isExtensionKey(k: string): boolean {\n return EXTENSION_KEY_VENDOR_RE.test(k) || EXTENSION_KEY_COMPANION_RE.test(k);\n}\n","// Label 309 v1 record encoder.\n//\n// Produces canonical CBOR bytes per RFC 8949 §4.2.1 deterministic encoding —\n// definite lengths, bytewise-lexicographically sorted map keys, no duplicate\n// keys, shortest-form integers. The canonical layer\n// (`@cardanowall/crypto-core/cbor`) owns those rules, so this module's job is\n// only to project the typed record onto the CBOR value algebra.\n//\n// That projection is the identity: under the Label 309 wire shapes every\n// record field already IS its CBOR value — `hashes` is a text-keyed map of\n// byte-string digests, each URI is a single text string, `kem_ct` /\n// `cose_sign1` / `cose_key` are single byte strings, and the canonical\n// encoder derives map-key order itself. The only transformation performed\n// here is dropping `undefined` optionals (a JS-only artefact with no CBOR\n// counterpart — left in place it would encode as the `undefined` simple\n// value, which the canonical profile forbids) and, for the signing body,\n// removing `sigs`.\n//\n// Round-trip property: for every record `R` the validator accepts,\n// validatePoeRecord(encodePoeRecord(R)).valid === true\n// and the decoded record is `R` (modulo CBOR-canonical key order).\n\nimport { encodeCanonicalCbor, type CanonicalCborValue } from '@cardanowall/crypto-core/cbor';\n\nimport type { PoeRecord } from './schema';\n\n/** Canonical CBOR bytes of the full record body — the bytes the chunk-array\n * transport carries on chain (see `carriage.ts`). */\nexport function encodePoeRecord(record: PoeRecord): Uint8Array {\n return encodeCanonicalCbor(toCborValue(record, /* includeSigs */ true));\n}\n\n/**\n * Canonical CBOR bytes of the record body **with `sigs` removed** — the body\n * a record-level signature covers. Producers prepend the 25-byte UTF-8 domain\n * prefix `cardano-poe-record-sig-v1` before invoking Ed25519 (the crypto-core\n * helper `buildLabel309SigStructure` handles the prefix and the\n * `Sig_structure` wrapping). Extension keys are part of the signed body and\n * pass through verbatim.\n */\nexport function encodeRecordBodyForSigning(record: PoeRecord): Uint8Array {\n return encodeCanonicalCbor(toCborValue(record, /* includeSigs */ false));\n}\n\nfunction toCborValue(record: PoeRecord, includeSigs: boolean): CanonicalCborValue {\n const out: { [key: string]: CanonicalCborValue } = {};\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) continue;\n if (!includeSigs && key === 'sigs') continue;\n out[key] = stripUndefined(value as CanonicalCborValue);\n }\n return out;\n}\n\n// Drop `undefined`-valued properties recursively. A typed record reaches the\n// encoder with its optional fields either absent or explicitly `undefined`;\n// CBOR has no counterpart for the latter (cbor2 would emit the major-type-7\n// `undefined` simple value, which the canonical profile rejects on decode),\n// so both spell \"absent\" on the wire.\nfunction stripUndefined(value: CanonicalCborValue): CanonicalCborValue {\n if (value === null || typeof value !== 'object' || value instanceof Uint8Array) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((element) => stripUndefined(element));\n }\n if (value instanceof Map) {\n const out = new Map<string | number, CanonicalCborValue>();\n for (const [k, v] of value) {\n if (v === undefined) continue;\n out.set(k, stripUndefined(v));\n }\n return out;\n }\n const out: { [key: string]: CanonicalCborValue } = {};\n for (const [k, v] of Object.entries(value)) {\n if (v === undefined) continue;\n out[k] = stripUndefined(v as CanonicalCborValue);\n }\n return out;\n}\n","// Label 309 v1 error-code catalogue — the TypeScript projection of the\n// machine-readable registry (`error-codes.json` in the Label 309 distribution).\n//\n// Three layers emit these codes:\n// - Part A — the structural validator (`validatePoeRecord`): a pure\n// function over the reassembled CBOR record body.\n// - carriage — the pre-validator transport step that reassembles the\n// label-309 chunk array (`reassembleLabel309Value`).\n// - Part B — the public / recipient verifier (chain resolution,\n// signature verification, content fetch, decryption).\n// Re-exported here so downstream verifiers dispatch on a\n// single `ErrorCode` union.\n//\n// Codes are SCREAMING_SNAKE_CASE and MUST match the canonical catalogue\n// byte-exact across the TS/PY/RS implementations — no lowercase synonyms,\n// no parser-internal codes, no free-form reason strings.\n//\n// `ERROR_CODES` preserves the registry's entry order. That order is\n// load-bearing: issues sharing an identical path tie-break by the order in\n// which their codes appear in the registry, so the list below doubles as the\n// cross-implementation sort key (`errorCodeRegistryIndex`).\n\nexport const ERROR_CODES = [\n 'MALFORMED_CBOR',\n 'SCHEMA_TYPE_MISMATCH',\n 'SCHEMA_MISSING_REQUIRED',\n 'SCHEMA_UNKNOWN_FIELD',\n 'SCHEMA_INVALID_LITERAL',\n 'SCHEMA_EMPTY_RECORD',\n 'HASH_DIGEST_LENGTH_MISMATCH',\n 'UNSUPPORTED_HASH_ALG',\n 'UNSUPPORTED_MERKLE_COMMIT_ALG',\n 'SCHEMA_MERKLE_LEAF_COUNT_INVALID',\n 'INVALID_URI',\n 'CHUNK_TOO_LARGE',\n 'UNAUTHENTICATED_CIPHER_FORBIDDEN',\n 'UNSUPPORTED_AEAD_ALG',\n 'NONCE_LENGTH_MISMATCH',\n 'UNSUPPORTED_ENVELOPE_SCHEME',\n 'ENC_UNSUPPORTED',\n 'ENC_SLOTS_EMPTY',\n 'ENC_SLOT_INVALID_SHAPE',\n 'UNSUPPORTED_KEM_ALG',\n 'ENC_KEM_REQUIRED',\n 'KEM_EPK_LENGTH_MISMATCH',\n 'KEM_CT_LENGTH_MISMATCH',\n 'WRAP_LENGTH_MISMATCH',\n 'ENC_SLOTS_MAC_INVALID_LENGTH',\n 'ENC_SLOTS_MAC_REQUIRED',\n 'ENC_SLOTS_REQUIRED',\n 'ENC_SLOTS_DUPLICATE_KEM_MATERIAL',\n 'ENC_SLOTS_TOO_MANY',\n 'ENC_ENVELOPE_TOO_LARGE',\n 'ENC_EXCLUSIVITY_VIOLATION',\n 'ENC_NO_KEY_PATH',\n 'ENC_REQUIRES_CONTENT_HASH',\n 'ENC_PASSPHRASE_ALG_UNSUPPORTED',\n 'ENC_PASSPHRASE_SALT_TOO_SHORT',\n 'ENC_PASSPHRASE_SALT_TOO_LONG',\n 'ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW',\n 'ENC_PASSPHRASE_PARAMS_EXCEED_POLICY',\n 'MALFORMED_SIG_COSE_SIGN1',\n 'SIGNATURE_UNSUPPORTED',\n 'SIG_ENTRY_INVALID_SHAPE',\n 'SIG_ENTRY_KID_COSE_KEY_CONFLICT',\n 'SIG_PRIVATE_KEY_LEAKED',\n 'SUPERSEDES_TX_INVALID_LENGTH',\n 'EXTENSION_UNSUPPORTED_CRITICAL',\n 'CRIT_SHAPE_INVALID',\n 'TX_NOT_FOUND',\n 'PROVIDER_UNAVAILABLE',\n 'TX_INTEGRITY_MISMATCH',\n 'METADATA_NOT_FOUND',\n 'INSUFFICIENT_CONFIRMATIONS',\n 'SIGNATURE_INVALID',\n 'SIGNER_KEY_UNRESOLVED',\n 'WALLET_ADDRESS_MISMATCH',\n 'URI_TARGET_FORBIDDEN',\n 'URI_INTEGRITY_MISMATCH',\n 'URI_PROVIDER_INTEGRITY_MISMATCH',\n 'URI_FETCH_FAILED',\n 'CONTENT_UNAVAILABLE',\n 'CONTENT_FETCH_LIMIT_EXCEEDED',\n 'CIPHERTEXT_UNAVAILABLE',\n 'SERVICE_INDEPENDENCE_VIOLATION',\n 'WRONG_DECRYPTION_INPUT_SHAPE',\n 'WRONG_RECIPIENT_KEY',\n 'TAMPERED_HEADER',\n 'TAMPERED_CIPHERTEXT',\n 'KDF_DERIVATION_FAILED',\n 'ENC_PASSPHRASE_UNNORMALIZABLE',\n 'ENC_PASSPHRASE_EMPTY',\n 'SCHEMA_MERKLE_LEAF_COUNT_MISMATCH',\n 'SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED',\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'MERKLE_ROOT_MISMATCH',\n 'MERKLE_LEAVES_UNAVAILABLE',\n 'MERKLE_UNSUPPORTED',\n 'OUT_OF_PROFILE_SKIPPED',\n] as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[number];\n\n// =============================================================================\n// Emitting layer (`part` in the registry)\n// =============================================================================\n\nexport type ErrorCodePart = 'A' | 'B' | 'carriage';\n\nexport const ERROR_CODE_PART: Readonly<Record<ErrorCode, ErrorCodePart>> = Object.freeze({\n MALFORMED_CBOR: 'A',\n SCHEMA_TYPE_MISMATCH: 'A',\n SCHEMA_MISSING_REQUIRED: 'A',\n SCHEMA_UNKNOWN_FIELD: 'A',\n SCHEMA_INVALID_LITERAL: 'A',\n SCHEMA_EMPTY_RECORD: 'A',\n HASH_DIGEST_LENGTH_MISMATCH: 'A',\n UNSUPPORTED_HASH_ALG: 'A',\n UNSUPPORTED_MERKLE_COMMIT_ALG: 'A',\n SCHEMA_MERKLE_LEAF_COUNT_INVALID: 'A',\n INVALID_URI: 'A',\n CHUNK_TOO_LARGE: 'carriage',\n UNAUTHENTICATED_CIPHER_FORBIDDEN: 'A',\n UNSUPPORTED_AEAD_ALG: 'A',\n NONCE_LENGTH_MISMATCH: 'A',\n UNSUPPORTED_ENVELOPE_SCHEME: 'A',\n ENC_UNSUPPORTED: 'A',\n ENC_SLOTS_EMPTY: 'A',\n ENC_SLOT_INVALID_SHAPE: 'A',\n UNSUPPORTED_KEM_ALG: 'A',\n ENC_KEM_REQUIRED: 'A',\n KEM_EPK_LENGTH_MISMATCH: 'A',\n KEM_CT_LENGTH_MISMATCH: 'A',\n WRAP_LENGTH_MISMATCH: 'A',\n ENC_SLOTS_MAC_INVALID_LENGTH: 'A',\n ENC_SLOTS_MAC_REQUIRED: 'A',\n ENC_SLOTS_REQUIRED: 'A',\n ENC_SLOTS_DUPLICATE_KEM_MATERIAL: 'A',\n ENC_SLOTS_TOO_MANY: 'A',\n ENC_ENVELOPE_TOO_LARGE: 'A',\n ENC_EXCLUSIVITY_VIOLATION: 'A',\n ENC_NO_KEY_PATH: 'A',\n ENC_REQUIRES_CONTENT_HASH: 'A',\n ENC_PASSPHRASE_ALG_UNSUPPORTED: 'A',\n ENC_PASSPHRASE_SALT_TOO_SHORT: 'A',\n ENC_PASSPHRASE_SALT_TOO_LONG: 'A',\n ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW: 'A',\n ENC_PASSPHRASE_PARAMS_EXCEED_POLICY: 'A',\n MALFORMED_SIG_COSE_SIGN1: 'A',\n SIGNATURE_UNSUPPORTED: 'A',\n SIG_ENTRY_INVALID_SHAPE: 'A',\n SIG_ENTRY_KID_COSE_KEY_CONFLICT: 'A',\n SIG_PRIVATE_KEY_LEAKED: 'A',\n SUPERSEDES_TX_INVALID_LENGTH: 'A',\n EXTENSION_UNSUPPORTED_CRITICAL: 'A',\n CRIT_SHAPE_INVALID: 'A',\n TX_NOT_FOUND: 'B',\n PROVIDER_UNAVAILABLE: 'B',\n TX_INTEGRITY_MISMATCH: 'B',\n METADATA_NOT_FOUND: 'B',\n INSUFFICIENT_CONFIRMATIONS: 'B',\n SIGNATURE_INVALID: 'B',\n SIGNER_KEY_UNRESOLVED: 'B',\n WALLET_ADDRESS_MISMATCH: 'B',\n URI_TARGET_FORBIDDEN: 'B',\n URI_INTEGRITY_MISMATCH: 'B',\n URI_PROVIDER_INTEGRITY_MISMATCH: 'B',\n URI_FETCH_FAILED: 'B',\n CONTENT_UNAVAILABLE: 'B',\n CONTENT_FETCH_LIMIT_EXCEEDED: 'B',\n CIPHERTEXT_UNAVAILABLE: 'B',\n SERVICE_INDEPENDENCE_VIOLATION: 'B',\n WRONG_DECRYPTION_INPUT_SHAPE: 'B',\n WRONG_RECIPIENT_KEY: 'B',\n TAMPERED_HEADER: 'B',\n TAMPERED_CIPHERTEXT: 'B',\n KDF_DERIVATION_FAILED: 'B',\n ENC_PASSPHRASE_UNNORMALIZABLE: 'B',\n ENC_PASSPHRASE_EMPTY: 'B',\n SCHEMA_MERKLE_LEAF_COUNT_MISMATCH: 'B',\n SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED: 'B',\n SCHEMA_MERKLE_LEAVES_MALFORMED: 'B',\n MERKLE_ROOT_MISMATCH: 'B',\n MERKLE_LEAVES_UNAVAILABLE: 'B',\n MERKLE_UNSUPPORTED: 'B',\n OUT_OF_PROFILE_SKIPPED: 'B',\n});\n\n// Layer-filtered views, in registry order. The structural validator emits only\n// Part A codes; the carriage (transport) step emits only the carriage code;\n// the verifier layer emits Part B codes (and re-runs the first two layers).\nexport const STRUCTURAL_ERROR_CODES: ReadonlyArray<ErrorCode> = Object.freeze(\n ERROR_CODES.filter((code) => ERROR_CODE_PART[code] === 'A'),\n);\nexport const CARRIAGE_ERROR_CODES: ReadonlyArray<ErrorCode> = Object.freeze(\n ERROR_CODES.filter((code) => ERROR_CODE_PART[code] === 'carriage'),\n);\nexport const VERIFIER_ERROR_CODES: ReadonlyArray<ErrorCode> = Object.freeze(\n ERROR_CODES.filter((code) => ERROR_CODE_PART[code] === 'B'),\n);\n\nexport type StructuralErrorCode = ErrorCode;\nexport type VerifierErrorCode = ErrorCode;\n\n// =============================================================================\n// Severity\n// =============================================================================\n//\n// `error` fails the record; `warning` is a non-fatal runtime anomaly; `info`\n// is a deliberate non-failing disposition. Four codes carry DUAL severity —\n// the map records their DEFAULT reading, and a strict context promotes them\n// to `error`:\n// - ENC_UNSUPPORTED — info by default; error for the recipient\n// role / strict sealed-crypto mode.\n// - MERKLE_LEAVES_UNAVAILABLE — warning beside a verified content\n// commitment; error when its absence leaves\n// the record with no verified commitment.\n// - MERKLE_UNSUPPORTED — info beside a validated items[] claim;\n// error on a merkle-only record.\n// - OUT_OF_PROFILE_SKIPPED — info in render mode; error in strict\n// end-to-end mode.\n// No layer may soften an `error` into a `warning` to make a record pass.\n\nexport type Severity = 'error' | 'warning' | 'info';\n\nexport const SEVERITY: Readonly<Record<ErrorCode, Severity>> = Object.freeze({\n MALFORMED_CBOR: 'error',\n SCHEMA_TYPE_MISMATCH: 'error',\n SCHEMA_MISSING_REQUIRED: 'error',\n SCHEMA_UNKNOWN_FIELD: 'error',\n SCHEMA_INVALID_LITERAL: 'error',\n SCHEMA_EMPTY_RECORD: 'error',\n HASH_DIGEST_LENGTH_MISMATCH: 'error',\n UNSUPPORTED_HASH_ALG: 'error',\n UNSUPPORTED_MERKLE_COMMIT_ALG: 'error',\n SCHEMA_MERKLE_LEAF_COUNT_INVALID: 'error',\n INVALID_URI: 'error',\n CHUNK_TOO_LARGE: 'error',\n UNAUTHENTICATED_CIPHER_FORBIDDEN: 'error',\n UNSUPPORTED_AEAD_ALG: 'error',\n NONCE_LENGTH_MISMATCH: 'error',\n UNSUPPORTED_ENVELOPE_SCHEME: 'error',\n ENC_UNSUPPORTED: 'info',\n ENC_SLOTS_EMPTY: 'error',\n ENC_SLOT_INVALID_SHAPE: 'error',\n UNSUPPORTED_KEM_ALG: 'error',\n ENC_KEM_REQUIRED: 'error',\n KEM_EPK_LENGTH_MISMATCH: 'error',\n KEM_CT_LENGTH_MISMATCH: 'error',\n WRAP_LENGTH_MISMATCH: 'error',\n ENC_SLOTS_MAC_INVALID_LENGTH: 'error',\n ENC_SLOTS_MAC_REQUIRED: 'error',\n ENC_SLOTS_REQUIRED: 'error',\n ENC_SLOTS_DUPLICATE_KEM_MATERIAL: 'error',\n ENC_SLOTS_TOO_MANY: 'error',\n ENC_ENVELOPE_TOO_LARGE: 'error',\n ENC_EXCLUSIVITY_VIOLATION: 'error',\n ENC_NO_KEY_PATH: 'error',\n ENC_REQUIRES_CONTENT_HASH: 'error',\n ENC_PASSPHRASE_ALG_UNSUPPORTED: 'error',\n ENC_PASSPHRASE_SALT_TOO_SHORT: 'error',\n ENC_PASSPHRASE_SALT_TOO_LONG: 'error',\n ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW: 'error',\n ENC_PASSPHRASE_PARAMS_EXCEED_POLICY: 'error',\n MALFORMED_SIG_COSE_SIGN1: 'error',\n SIGNATURE_UNSUPPORTED: 'info',\n SIG_ENTRY_INVALID_SHAPE: 'error',\n SIG_ENTRY_KID_COSE_KEY_CONFLICT: 'error',\n SIG_PRIVATE_KEY_LEAKED: 'error',\n SUPERSEDES_TX_INVALID_LENGTH: 'error',\n EXTENSION_UNSUPPORTED_CRITICAL: 'error',\n CRIT_SHAPE_INVALID: 'error',\n TX_NOT_FOUND: 'error',\n PROVIDER_UNAVAILABLE: 'error',\n TX_INTEGRITY_MISMATCH: 'error',\n METADATA_NOT_FOUND: 'error',\n INSUFFICIENT_CONFIRMATIONS: 'info',\n SIGNATURE_INVALID: 'error',\n SIGNER_KEY_UNRESOLVED: 'error',\n WALLET_ADDRESS_MISMATCH: 'error',\n URI_TARGET_FORBIDDEN: 'error',\n URI_INTEGRITY_MISMATCH: 'error',\n URI_PROVIDER_INTEGRITY_MISMATCH: 'warning',\n URI_FETCH_FAILED: 'warning',\n CONTENT_UNAVAILABLE: 'error',\n CONTENT_FETCH_LIMIT_EXCEEDED: 'error',\n CIPHERTEXT_UNAVAILABLE: 'error',\n SERVICE_INDEPENDENCE_VIOLATION: 'error',\n WRONG_DECRYPTION_INPUT_SHAPE: 'error',\n WRONG_RECIPIENT_KEY: 'error',\n TAMPERED_HEADER: 'error',\n TAMPERED_CIPHERTEXT: 'error',\n KDF_DERIVATION_FAILED: 'error',\n ENC_PASSPHRASE_UNNORMALIZABLE: 'error',\n ENC_PASSPHRASE_EMPTY: 'error',\n SCHEMA_MERKLE_LEAF_COUNT_MISMATCH: 'error',\n SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED: 'error',\n SCHEMA_MERKLE_LEAVES_MALFORMED: 'error',\n MERKLE_ROOT_MISMATCH: 'error',\n MERKLE_LEAVES_UNAVAILABLE: 'warning',\n MERKLE_UNSUPPORTED: 'info',\n OUT_OF_PROFILE_SKIPPED: 'info',\n});\n\n// Codes whose severity is context-dependent. `SEVERITY` records the default\n// reading; the promoting context escalates to `error`.\nexport const DUAL_SEVERITY_CODES: ReadonlySet<ErrorCode> = new Set<ErrorCode>([\n 'ENC_UNSUPPORTED',\n 'MERKLE_LEAVES_UNAVAILABLE',\n 'MERKLE_UNSUPPORTED',\n 'OUT_OF_PROFILE_SKIPPED',\n]);\n\nexport function severityOf(code: ErrorCode): Severity {\n return SEVERITY[code];\n}\n\n// Position of a code in the canonical registry. Issues that carry an\n// identical path are ordered by this index, so every implementation sorts an\n// issue list identically.\nconst REGISTRY_INDEX: ReadonlyMap<ErrorCode, number> = new Map(\n ERROR_CODES.map((code, index) => [code, index]),\n);\n\nexport function errorCodeRegistryIndex(code: ErrorCode): number {\n return REGISTRY_INDEX.get(code) as number;\n}\n","/**\n * Utilities for hex, bytearray and number handling.\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport {\n type CHash,\n type TypedArray,\n abytes,\n abytes as abytes_,\n concatBytes,\n isLE,\n randomBytes as randb,\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 * Asserts that a value is a byte array and optionally checks its length.\n * Returns the original reference unchanged on success, and currently also accepts Node `Buffer`\n * values through the upstream validator.\n * This helper throws on malformed input, so APIs that must return `false` need to guard lengths\n * before decoding or before calling it.\n * @example\n * Validate that a value is a byte array with the expected length.\n * ```ts\n * abytes(new Uint8Array([1]), 1);\n * ```\n */\nconst abytesDoc: typeof abytes = abytes;\nexport { abytesDoc as abytes };\n/**\n * Concatenates byte arrays into a new `Uint8Array`.\n * Zero arguments return an empty `Uint8Array`.\n * Invalid segments throw before allocation because each argument is validated first.\n * @example\n * Concatenate two byte arrays into one result.\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nconst concatBytesDoc: typeof concatBytes = concatBytes;\nexport { concatBytesDoc as concatBytes };\n/**\n * Returns cryptographically secure random bytes.\n * Requires `globalThis.crypto.getRandomValues` and throws if that API is unavailable.\n * `bytesLength` is validated by the upstream helper as a non-negative integer before allocation,\n * so negative and fractional values both throw instead of truncating through JS `ToIndex`.\n * @param bytesLength - Number of random bytes to generate.\n * @returns Fresh random bytes.\n * @example\n * Generate a fresh random seed.\n * ```ts\n * const seed = randomBytes(4);\n * ```\n */\nexport const randomBytes: typeof randb = randb;\n\n/**\n * Compares two byte arrays in a length-constant way for equal lengths.\n * Unequal lengths return `false` immediately, and there is no runtime type validation.\n * @param a - First byte array.\n * @param b - Second byte array.\n * @returns Whether both arrays contain the same bytes.\n * @example\n * Compare two byte arrays for equality.\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/**\n * Copies bytes into a fresh `Uint8Array`.\n * Returns a detached plain `Uint8Array` after validating that the input is real bytes.\n * @param bytes - Source bytes.\n * @returns Copy of the input bytes.\n * @example\n * Copy bytes into a fresh array.\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 * Byte-swaps each 64-bit lane in place.\n * Falcon's exact binary64 tables are stored as little-endian byte payloads, so BE runtimes need\n * this boundary helper before aliasing them as host `Float64Array` lanes.\n * @param arr - Byte buffer whose length is a multiple of 8.\n * @returns The same buffer after in-place 64-bit lane byte swaps.\n * @example\n * Byte-swap one 64-bit lane in place.\n * ```ts\n * byteSwap64(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]));\n * ```\n */\nexport function byteSwap64<T extends ArrayBufferView>(arr: T): T {\n const bytes = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n for (let i = 0; i < bytes.length; i += 8) {\n const a0 = bytes[i + 0];\n const a1 = bytes[i + 1];\n const a2 = bytes[i + 2];\n const a3 = bytes[i + 3];\n bytes[i + 0] = bytes[i + 7];\n bytes[i + 1] = bytes[i + 6];\n bytes[i + 2] = bytes[i + 5];\n bytes[i + 3] = bytes[i + 4];\n bytes[i + 4] = a3;\n bytes[i + 5] = a2;\n bytes[i + 6] = a1;\n bytes[i + 7] = a0;\n }\n return arr;\n}\n/**\n * Byte-swaps 64-bit lanes on big-endian runtimes and returns the input unchanged on little-endian.\n * This keeps Falcon's binary64 tables in canonical little-endian order before aliasing them as\n * `Float64Array` lanes on the current host.\n * @param arr - Buffer to pass through or swap in place.\n * @returns The same buffer, normalized for Falcon's little-endian table layout.\n * @example\n * Normalize one host-endian buffer for Falcon's float tables.\n * ```ts\n * baswap64If(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]));\n * ```\n */\nexport const baswap64If: <T extends ArrayBufferView>(arr: T) => T = isLE\n ? (arr) => arr\n : byteSwap64;\n\n/** Shared key-generation surface for signers and KEMs. */\nexport type CryptoKeys = {\n /** Optional metadata about the algorithm family or variant. */\n info?: { type?: string };\n /** Public byte lengths for the exported key material. */\n lengths: { seed?: number; publicKey?: number; secretKey?: 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?: TArg<Uint8Array>) => {\n secretKey: TRet<Uint8Array>;\n publicKey: TRet<Uint8Array>;\n };\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: TArg<Uint8Array>) => TRet<Uint8Array>;\n};\n\n/** Verification options shared by the signature APIs. */\nexport type VerOpts = {\n /** Optional application-defined context string. */\n context?: Uint8Array;\n};\n/** Signing options shared by the signature APIs. */\nexport type SigOpts = VerOpts & {\n // Compatibility with @noble/curves: false to disable, enabled by default, user can pass U8A\n /** Optional extra entropy or `false` to disable randomized signing. */\n extraEntropy?: Uint8Array | false;\n};\n\n/**\n * Validates that an options bag is a plain object.\n * @param opts - Options object to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validate that an options bag is a plain object.\n * ```ts\n * validateOpts({});\n * ```\n */\nexport function validateOpts(opts: object): void {\n // Arrays silently passed here before, but these call sites expect named option-bag fields.\n if (Object.prototype.toString.call(opts) !== '[object Object]')\n throw new TypeError('expected valid options object');\n}\n\n/**\n * Validates common verification options.\n * `context` itself is validated with `abytes(...)`, and individual algorithms may narrow support\n * further after this shared plain-object gate.\n * @param opts - Verification options. See {@link VerOpts}.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validate common verification options.\n * ```ts\n * validateVerOpts({ context: new Uint8Array([1]) });\n * ```\n */\nexport function validateVerOpts(opts: TArg<VerOpts>): void {\n validateOpts(opts);\n if (opts.context !== undefined) abytes(opts.context, undefined, 'opts.context');\n}\n\n/**\n * Validates common signing options.\n * `extraEntropy` is validated with `abytes(...)`; exact lengths and extra algorithm-specific\n * restrictions are enforced later by callers.\n * @param opts - Signing options. See {@link SigOpts}.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validate common signing options.\n * ```ts\n * validateSigOpts({ extraEntropy: new Uint8Array([1]) });\n * ```\n */\nexport function validateSigOpts(opts: TArg<SigOpts>): void {\n validateVerOpts(opts);\n if (opts.extraEntropy !== false && opts.extraEntropy !== undefined)\n abytes(opts.extraEntropy, undefined, 'opts.extraEntropy');\n}\n\n/** Generic signature interface with key generation, signing, and verification. */\nexport type Signer = CryptoKeys & {\n /** Public byte lengths for signatures and signing randomness. */\n lengths: { signRand?: number; signature?: number };\n /**\n * Sign one message.\n * @param msg - Message bytes to sign.\n * @param secretKey - Secret key bytes.\n * @param opts - Optional signing options.\n * @returns Signature bytes.\n */\n sign: (\n msg: TArg<Uint8Array>,\n secretKey: TArg<Uint8Array>,\n opts?: TArg<SigOpts>\n ) => TRet<Uint8Array>;\n /**\n * Verify one signature.\n * @param sig - Signature bytes.\n * @param msg - Signed message bytes.\n * @param publicKey - Public key bytes.\n * @param opts - Optional verification options.\n * @returns `true` when the signature is valid, `false` when all inputs are well-formed but the\n * signature check does not pass. Some implementations also treat malformed signature encodings as\n * a verification failure and return `false`.\n * @throws On malformed API arguments or unsupported verification options.\n */\n verify: (\n sig: TArg<Uint8Array>,\n msg: TArg<Uint8Array>,\n publicKey: TArg<Uint8Array>,\n opts?: TArg<VerOpts>\n ) => boolean;\n};\n\n/** Generic key encapsulation mechanism interface. */\nexport type KEM = CryptoKeys & {\n /** Public byte lengths for ciphertexts and optional message randomness. */\n lengths: { cipherText?: number; msg?: number; msgRand?: number };\n /**\n * Encapsulate one shared secret to a recipient public key.\n * @param publicKey - Recipient public key bytes.\n * @param msg - Optional caller-provided randomness/message seed.\n * @returns Ciphertext plus shared secret.\n */\n encapsulate: (\n publicKey: TArg<Uint8Array>,\n msg?: TArg<Uint8Array>\n ) => {\n cipherText: TRet<Uint8Array>;\n sharedSecret: TRet<Uint8Array>;\n };\n /**\n * Recover the shared secret from a ciphertext and recipient secret key.\n * @param cipherText - Ciphertext bytes.\n * @param secretKey - Recipient secret key bytes.\n * @returns Decapsulated shared secret.\n */\n decapsulate: (cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>) => TRet<Uint8Array>;\n};\n\n/** Bidirectional encoder/decoder interface. */\nexport interface Coder<F, T> {\n /**\n * Serialize one value.\n * @param from - Value to encode.\n * @returns Encoded representation.\n */\n encode(from: F): T;\n /**\n * Parse one serialized value.\n * @param to - Encoded representation.\n * @returns Decoded value.\n */\n decode(to: T): F;\n}\n\n/** Encoder/decoder interface specialized for byte arrays. */\nexport interface BytesCoder<T> extends Coder<T, Uint8Array> {\n /**\n * Serialize one value into bytes.\n * @param data - Value to encode.\n * @returns Encoded bytes.\n */\n encode: (data: T) => Uint8Array;\n /**\n * Parse one byte array into a value.\n * @param bytes - Encoded bytes.\n * @returns Decoded value.\n */\n decode: (bytes: Uint8Array) => T;\n}\n\n/** Fixed-length byte encoder/decoder. */\nexport type BytesCoderLen<T> = BytesCoder<T> & { bytesLen: number };\n\n// nano-packed, because struct encoding is hard.\ntype UnCoder<T> = T extends BytesCoder<infer U> ? U : never;\ntype SplitOut<T extends (number | BytesCoderLen<any>)[]> = {\n [K in keyof T]: T[K] extends number ? Uint8Array : UnCoder<T[K]>;\n};\n/**\n * Builds a fixed-layout coder from byte lengths and nested coders.\n * Raw-length fields decode as zero-copy `subarray(...)` views, and nested coders may preserve that\n * aliasing too. Nested coder `encode(...)` results are treated as owned scratch: `splitCoder`\n * copies them into the output and then zeroizes them with `fill(0)`. If a nested encoder forwards\n * caller-owned bytes, it must do so only after detaching them into a disposable copy.\n * @param label - Label used in validation errors.\n * @param lengths - Field lengths or nested coders.\n * @returns Composite fixed-length coder.\n * @example\n * Build a fixed-layout coder from byte lengths and nested coders.\n * ```ts\n * splitCoder('demo', 1, 2).encode([new Uint8Array([1]), new Uint8Array([2, 3])]);\n * ```\n */\nexport function splitCoder<T extends (number | BytesCoderLen<any>)[]>(\n label: string,\n ...lengths: T\n): TRet<BytesCoder<SplitOut<T>> & { bytesLen: number }> {\n const getLength = (c: TArg<number | BytesCoderLen<any>>) =>\n typeof c === 'number' ? c : (c as BytesCoderLen<any>).bytesLen;\n const bytesLen: number = lengths.reduce((sum: number, a) => sum + getLength(a), 0);\n return {\n bytesLen,\n encode: (bufs: T) => {\n const res = new Uint8Array(bytesLen);\n for (let i = 0, pos = 0; i < lengths.length; i++) {\n const c = lengths[i];\n const l = getLength(c);\n const b: Uint8Array = typeof c === 'number' ? (bufs[i] as any) : c.encode(bufs[i]);\n abytes_(b, l, label);\n res.set(b, pos);\n if (typeof c !== 'number') b.fill(0); // clean\n pos += l;\n }\n return res;\n },\n decode: (buf: TArg<Uint8Array>) => {\n abytes_(buf, bytesLen, label);\n const res = [];\n for (const c of lengths) {\n const l = getLength(c);\n const b = buf.subarray(0, l);\n res.push(typeof c === 'number' ? b : c.decode(b));\n buf = buf.subarray(l);\n }\n return res as SplitOut<T>;\n },\n } as any;\n}\n// nano-packed.array (fixed size)\n/**\n * Builds a fixed-length vector coder from another fixed-length coder.\n * Element decoding receives `subarray(...)` views, so aliasing depends on the element coder.\n * Element coder `encode(...)` results are treated as owned scratch: `vecCoder` copies them into\n * the output and then zeroizes them with `fill(0)`. If an element encoder forwards caller-owned\n * bytes, it must do so only after detaching them into a disposable copy. `vecCoder` also trusts\n * the `BytesCoderLen` contract: each encoded element must already be exactly `c.bytesLen` bytes.\n * @param c - Element coder.\n * @param vecLen - Number of elements in the vector.\n * @returns Fixed-length vector coder.\n * @example\n * Build a fixed-length vector coder from another fixed-length coder.\n * ```ts\n * vecCoder(\n * { bytesLen: 1, encode: (n: number) => Uint8Array.of(n), decode: (b: Uint8Array) => b[0] || 0 },\n * 2\n * ).encode([1, 2]);\n * ```\n */\nexport function vecCoder<T>(c: TArg<BytesCoderLen<T>>, vecLen: number): TRet<BytesCoderLen<T[]>> {\n const coder = c as BytesCoderLen<T>;\n const bytesLen = vecLen * coder.bytesLen;\n return {\n bytesLen,\n encode: (u: TArg<T[]>): TRet<Uint8Array> => {\n if (u.length !== vecLen)\n throw new RangeError(`vecCoder.encode: wrong length=${u.length}. Expected: ${vecLen}`);\n const res = new Uint8Array(bytesLen);\n for (let i = 0, pos = 0; i < u.length; i++) {\n const b = coder.encode(u[i] as T);\n res.set(b, pos);\n b.fill(0); // clean\n pos += b.length;\n }\n return res as TRet<Uint8Array>;\n },\n decode: (a: TArg<Uint8Array>): TRet<T[]> => {\n abytes_(a, bytesLen);\n const r: T[] = [];\n for (let i = 0; i < a.length; i += coder.bytesLen)\n r.push(coder.decode(a.subarray(i, i + coder.bytesLen)));\n return r as TRet<T[]>;\n },\n } as any;\n}\n\n/**\n * Overwrites supported typed-array inputs with zeroes in place.\n * Accepts direct typed arrays and one-level arrays of them.\n * @param list - Typed arrays or one-level lists of typed arrays to clear.\n * @example\n * Overwrite typed arrays with zeroes.\n * ```ts\n * const buf = Uint8Array.of(1, 2, 3);\n * cleanBytes(buf);\n * ```\n */\nexport function cleanBytes(...list: (TypedArray | TypedArray[])[]): void {\n for (const t of list) {\n if (Array.isArray(t)) for (const b of t) b.fill(0);\n else t.fill(0);\n }\n}\n\n/**\n * Creates a 32-bit mask with the lowest `bits` bits set.\n * @param bits - Number of low bits to keep.\n * @returns Bit mask with `bits` ones.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Create a low-bit mask for packed-field operations.\n * ```ts\n * const mask = getMask(4);\n * ```\n */\nexport function getMask(bits: number): number {\n if (!Number.isSafeInteger(bits) || bits < 0 || bits > 32)\n throw new RangeError(`expected bits in [0..32], got ${bits}`);\n // JS shifts are modulo 32, so bit 32 needs an explicit full-width mask.\n return bits === 32 ? 0xffffffff : ~(-1 << bits) >>> 0;\n}\n\n/** Shared empty byte array used as the default context. */\nexport const EMPTY: TRet<Uint8Array> = /* @__PURE__ */ Uint8Array.of();\n\n/**\n * Builds the domain-separated message payload for the pure sign/verify paths.\n * Context length `255` is valid; only `ctx.length > 255` is rejected.\n * @param msg - Message bytes.\n * @param ctx - Optional context bytes.\n * @returns Domain-separated message payload.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Build the domain-separated payload before direct signing.\n * ```ts\n * const payload = getMessage(new Uint8Array([1, 2]));\n * ```\n */\nexport function getMessage(msg: TArg<Uint8Array>, ctx: TArg<Uint8Array> = EMPTY): TRet<Uint8Array> {\n abytes_(msg);\n abytes_(ctx);\n if (ctx.length > 255) throw new RangeError('context should be 255 bytes or less');\n return concatBytes(new Uint8Array([0, ctx.length]), ctx, msg);\n}\n\n// DER tag+length plus the shared NIST hash OID arc 2.16.840.1.101.3.4.2.* used by the\n// FIPS 204 / FIPS 205 pre-hash wrappers; the final byte selects SHA-256, SHA-512, SHAKE128,\n// SHAKE256, or another approved hash/XOF under that subtree.\n// 06 09 60 86 48 01 65 03 04 02\nconst oidNistP = /* @__PURE__ */ Uint8Array.from([6, 9, 0x60, 0x86, 0x48, 1, 0x65, 3, 4, 2]);\n\n/**\n * Validates that a hash exposes a NIST hash OID and enough collision resistance.\n * Current accepted surface is broader than the FIPS algorithm tables: any hash/XOF under the NIST\n * `2.16.840.1.101.3.4.2.*` subtree is accepted if its effective `outputLen` is strong enough.\n * XOF callers must pass a callable whose `outputLen` matches the digest length they actually intend\n * to sign; bare `shake128` / `shake256` defaults are too short for the stronger prehash modes.\n * @param hash - Hash function to validate.\n * @param requiredStrength - Minimum required collision-resistance strength in bits.\n * @throws If the hash metadata or collision resistance is insufficient. {@link Error}\n * @example\n * Validate that a hash exposes a NIST hash OID and enough collision resistance.\n * ```ts\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { checkHash } from '@noble/post-quantum/utils.js';\n * checkHash(sha256, 128);\n * ```\n */\nexport function checkHash(hash: CHash, requiredStrength: number = 0): void {\n if (!hash.oid || !equalBytes(hash.oid.subarray(0, 10), oidNistP))\n throw new Error('hash.oid is invalid: expected NIST hash');\n // FIPS 204 / FIPS 205 require both collision and second-preimage strength; for approved NIST\n // hashes/XOFs under this OID subtree, the collision bound from the configured digest length is\n // the tighter runtime check, so enforce that lower bound here.\n const collisionResistance = (hash.outputLen * 8) / 2;\n if (requiredStrength > collisionResistance) {\n throw new Error(\n 'Pre-hash security strength too low: ' +\n collisionResistance +\n ', required: ' +\n requiredStrength\n );\n }\n}\n\n/**\n * Builds the domain-separated prehash payload for the prehash sign/verify paths.\n * Callers are expected to vet `hash.oid` first, e.g. via `checkHash(...)`; calling this helper\n * directly with a hash object that lacks `oid` currently throws later inside `concatBytes(...)`.\n * Context length `255` is valid; only `ctx.length > 255` is rejected.\n * @param hash - Prehash function.\n * @param msg - Message bytes.\n * @param ctx - Optional context bytes.\n * @returns Domain-separated prehash payload.\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Build the domain-separated prehash payload for external hashing.\n * ```ts\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { getMessagePrehash } from '@noble/post-quantum/utils.js';\n * getMessagePrehash(sha256, new Uint8Array([1, 2]));\n * ```\n */\nexport function getMessagePrehash(\n hash: CHash,\n msg: TArg<Uint8Array>,\n ctx: TArg<Uint8Array> = EMPTY\n): TRet<Uint8Array> {\n abytes_(msg);\n abytes_(ctx);\n if (ctx.length > 255) throw new RangeError('context should be 255 bytes or less');\n const hashed = hash(msg);\n return concatBytes(new Uint8Array([1, ctx.length]), ctx, hash.oid!, hashed);\n}\n","/**\n * Internal methods for lattice-based ML-KEM and ML-DSA.\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { FFTCore, reverseBits } from '@noble/curves/abstract/fft.js';\nimport { shake128, shake256 } from '@noble/hashes/sha3.js';\nimport type { TypedArray } from '@noble/hashes/utils.js';\nimport {\n type BytesCoderLen,\n cleanBytes,\n type Coder,\n getMask,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/** Extendable-output reader used by the CRYSTALS implementations. */\nexport type XOF = (\n seed: Uint8Array,\n blockLen?: number\n) => {\n /**\n * Read diagnostic counters for the current XOF session.\n * @returns Current call and XOF block counters.\n */\n stats: () => { calls: number; xofs: number };\n /**\n * Select one `(x, y)` coordinate pair and get a block reader for it.\n * Only one coordinate stream is live at a time: a later `get(...)` call rebinds the shared\n * SHAKE state and invalidates older readers.\n * Each squeeze aliases one mutable internal output buffer, so callers must copy blocks they\n * want to retain before the next read.\n * @param x - First matrix coordinate.\n * @param y - Second matrix coordinate.\n * @returns Lazy block reader for that coordinate pair.\n */\n get: (x: number, y: number) => () => Uint8Array; // return block aligned to blockLen and 3\n /** Wipe any buffered state once the reader is no longer needed. */\n clean: () => void;\n};\n\n/** CRYSTALS (ml-kem, ml-dsa) options */\n/** Shared polynomial and NTT parameters for CRYSTALS algorithms. */\nexport type CrystalOpts<T extends TypedArray> = {\n /**\n * Allocate one zeroed polynomial/vector container.\n * @param n - Number of coefficients to allocate.\n * @returns Fresh typed container.\n */\n newPoly: TypedCons<T>;\n /** Polynomial size, typically `256`. */\n N: number;\n /** Prime modulus used for all coefficient arithmetic. */\n Q: number;\n /** Inverse transform normalization factor:\n * `256**-1 mod q` for Dilithium, `128**-1 mod q` for Kyber.\n */\n F: number;\n /** Principal root of unity for the transform domain. */\n ROOT_OF_UNITY: number;\n /** Number of bits used for bit-reversal ordering. */\n brvBits: number;\n /** `true` for Kyber/ML-KEM mode, `false` for Dilithium/ML-DSA mode. */\n isKyber: boolean;\n};\n\n/** Constructor function for typed polynomial containers. */\nexport type TypedCons<T extends TypedArray> = (n: number) => T;\n\ntype Crystals<T extends TypedArray> = {\n mod: (a: number, modulo?: number) => number;\n smod: (a: number, modulo?: number) => number;\n nttZetas: T;\n NTT: {\n /** Forward transform in place. Mutates and returns `r`. */\n encode: (r: T) => T;\n /** Inverse transform in place. Mutates and returns `r`. */\n decode: (r: T) => T;\n };\n bitsCoder: (d: number, c: Coder<number, number>) => BytesCoderLen<T>;\n};\n\n/**\n * Creates shared modular arithmetic, NTT, and packing helpers for CRYSTALS schemes.\n * @param opts - Polynomial and transform parameters. See {@link CrystalOpts}.\n * @returns CRYSTALS arithmetic and encoding helpers.\n * @example\n * Create shared modular arithmetic and NTT helpers for a CRYSTALS parameter set.\n * ```ts\n * const crystals = genCrystals({\n * newPoly: (n) => new Uint16Array(n),\n * N: 256,\n * Q: 3329,\n * F: 3303,\n * ROOT_OF_UNITY: 17,\n * brvBits: 7,\n * isKyber: true,\n * });\n * const reduced = crystals.mod(-1);\n * ```\n */\nexport const genCrystals = <T extends TypedArray>(opts: CrystalOpts<T>): TRet<Crystals<T>> => {\n // isKyber: true means Kyber, false means Dilithium\n const { newPoly, N, Q, F, ROOT_OF_UNITY, brvBits, isKyber } = opts;\n // Normalize JS `%` into the canonical Z_m representative `[0, modulo-1]` expected by\n // FIPS 203 §2.3 / FIPS 204 §2.3 before downstream mod-q arithmetic.\n const mod = (a: number, modulo = Q): number => {\n const result = a % modulo | 0;\n return (result >= 0 ? result | 0 : (modulo + result) | 0) | 0;\n };\n // FIPS 204 §7.4 uses the centered `mod ±` representative for low bits, keeping the\n // positive midpoint when `modulo` is even.\n // Center to `[-floor((modulo-1)/2), floor(modulo/2)]`.\n const smod = (a: number, modulo = Q): number => {\n const r = mod(a, modulo) | 0;\n return (r > modulo >> 1 ? (r - modulo) | 0 : r) | 0;\n };\n // Kyber uses the FIPS 203 Appendix A `BitRev_7` table here via the first 128 entries, while\n // Dilithium uses the FIPS 204 §7.5 / Appendix B `BitRev_8` zetas table over all 256 entries.\n function getZettas() {\n const out = newPoly(N);\n for (let i = 0; i < N; i++) {\n const b = reverseBits(i, brvBits);\n const p = BigInt(ROOT_OF_UNITY) ** BigInt(b) % BigInt(Q);\n out[i] = Number(p) | 0;\n }\n return out;\n }\n const nttZetas = getZettas();\n\n // Number-Theoretic Transform\n // Explained: https://electricdusk.com/ntt.html\n\n // Kyber has slightly different params, since there is no 512th primitive root of unity mod q,\n // only 256th primitive root of unity mod. Which also complicates MultiplyNTT.\n\n const field = {\n add: (a: number, b: number) => mod((a | 0) + (b | 0)) | 0,\n sub: (a: number, b: number) => mod((a | 0) - (b | 0)) | 0,\n mul: (a: number, b: number) => mod((a | 0) * (b | 0)) | 0,\n inv: (_a: number) => {\n throw new Error('not implemented');\n },\n };\n const nttOpts = {\n N,\n roots: nttZetas as any,\n invertButterflies: true,\n skipStages: isKyber ? 1 : 0,\n brp: false,\n };\n const dif = FFTCore(field, { dit: false, ...nttOpts });\n const dit = FFTCore(field, { dit: true, ...nttOpts });\n const NTT = {\n encode: (r: T): T => {\n return dif(r) as any;\n },\n decode: (r: T): T => {\n dit(r as any);\n // The inverse-NTT normalization factor is family-specific: FIPS 203 Algorithm 10 line 14\n // uses `128^-1 mod q` for Kyber, while FIPS 204 Algorithm 42 lines 21-23 use `256^-1 mod q`.\n // kyber uses 128 here, because brv && stuff\n for (let i = 0; i < r.length; i++) r[i] = mod(F * r[i]);\n return r;\n },\n };\n // Pack one little-endian `d`-bit word per coefficient, matching FIPS 203 ByteEncode /\n // ByteDecode and the FIPS 204 BitsToBytes-based polynomial packing helpers.\n const bitsCoder = (d: number, c: Coder<number, number>): TRet<BytesCoderLen<T>> => {\n const mask = getMask(d);\n const bytesLen = d * (N / 8);\n return {\n bytesLen,\n encode: (poly_: TArg<T>): TRet<Uint8Array> => {\n const poly = poly_ as T;\n const r = new Uint8Array(bytesLen);\n for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < poly.length; i++) {\n buf |= (c.encode(poly[i]) & mask) << bufLen;\n bufLen += d;\n for (; bufLen >= 8; bufLen -= 8, buf >>= 8) r[pos++] = buf & getMask(bufLen);\n }\n return r as TRet<Uint8Array>;\n },\n decode: (bytes: TArg<Uint8Array>): TRet<T> => {\n const r = newPoly(N);\n for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < bytes.length; i++) {\n buf |= bytes[i] << bufLen;\n bufLen += 8;\n for (; bufLen >= d; bufLen -= d, buf >>= d) r[pos++] = c.decode(buf & mask);\n }\n return r as TRet<T>;\n },\n } as TRet<BytesCoderLen<T>>;\n };\n\n return {\n mod,\n smod,\n nttZetas: nttZetas as TRet<T>,\n NTT: {\n encode: (r: TArg<T>): TRet<T> => NTT.encode(r as T) as TRet<T>,\n decode: (r: TArg<T>): TRet<T> => NTT.decode(r as T) as TRet<T>,\n },\n bitsCoder: bitsCoder as TRet<Crystals<T>>['bitsCoder'],\n };\n};\n\nconst createXofShake =\n (shake: typeof shake128): TRet<XOF> =>\n (seed: TArg<Uint8Array>, blockLen?: number) => {\n if (!blockLen) blockLen = shake.blockLen;\n // Optimizations that won't mater:\n // - cached seed update (two .update(), on start and on the end)\n // - another cache which cloned into working copy\n\n // Faster than multiple updates, since seed less than blockLen\n const _seed = new Uint8Array(seed.length + 2);\n _seed.set(seed);\n const seedLen = seed.length;\n const buf = new Uint8Array(blockLen); // == shake128.blockLen\n let h = shake.create({});\n let calls = 0;\n let xofs = 0;\n return {\n stats: () => ({ calls, xofs }),\n get: (x: number, y: number) => {\n // Rebind to `seed || x || y` so callers can implement the spec's per-coordinate\n // SHAKE inputs like `rho || j || i` and `rho || IntegerToBytes(counter, 2)`.\n _seed[seedLen + 0] = x;\n _seed[seedLen + 1] = y;\n h.destroy();\n h = shake.create({}).update(_seed);\n calls++;\n return () => {\n xofs++;\n return h.xofInto(buf) as TRet<Uint8Array>;\n };\n },\n clean: () => {\n h.destroy();\n cleanBytes(buf, _seed);\n },\n };\n };\n\n/**\n * SHAKE128-based extendable-output reader factory used by ML-KEM.\n * `get(x, y)` selects one coordinate pair at a time; calling it again invalidates previously\n * returned readers, and each squeeze reuses one mutable internal output buffer.\n * @param seed - Seed bytes for the reader.\n * @param blockLen - Optional output block length.\n * @returns Stateful XOF reader.\n * @example\n * Build the ML-KEM SHAKE128 matrix expander and read one block.\n * ```ts\n * import { randomBytes } from '@noble/post-quantum/utils.js';\n * import { XOF128 } from '@noble/post-quantum/_crystals.js';\n * const reader = XOF128(randomBytes(32));\n * const block = reader.get(0, 0)();\n * ```\n */\nexport const XOF128: TRet<XOF> = /* @__PURE__ */ createXofShake(shake128);\n/**\n * SHAKE256-based extendable-output reader factory used by ML-DSA.\n * `get(x, y)` appends raw one-byte coordinates to the seed, invalidates previously returned\n * readers, and reuses one mutable internal output buffer for each squeeze.\n * @param seed - Seed bytes for the reader.\n * @param blockLen - Optional output block length.\n * @returns Stateful XOF reader.\n * @example\n * Build the ML-DSA SHAKE256 coefficient expander and read one block.\n * ```ts\n * import { randomBytes } from '@noble/post-quantum/utils.js';\n * import { XOF256 } from '@noble/post-quantum/_crystals.js';\n * const reader = XOF256(randomBytes(32));\n * const block = reader.get(0, 0)();\n * ```\n */\nexport const XOF256: TRet<XOF> = /* @__PURE__ */ createXofShake(shake256);\n","/**\n * ML-KEM: Module Lattice-based Key Encapsulation Mechanism from\n * [FIPS-203](https://csrc.nist.gov/pubs/fips/203/ipd). A.k.a. CRYSTALS-Kyber.\n *\n * Key encapsulation is similar to DH / ECDH (think X25519), with important differences:\n * * Unlike in ECDH, we can't verify if it was \"Bob\" who've sent the shared secret\n * * Unlike ECDH, it is probabalistic and relies on quality of randomness (CSPRNG).\n * * Decapsulation never throws an error, even when shared secret was\n * encrypted by a different public key. It will just return a different shared secret.\n *\n * There are some concerns with regards to security: see\n * [djb blog](https://blog.cr.yp.to/20231003-countcorrectly.html) and\n * [mailing list](https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/W2VOzy0wz_E).\n *\n * Has similar internals to ML-DSA, but their keys and params are different.\n *\n * Check out [official site](https://www.pq-crystals.org/kyber/resources.shtml),\n * [repo](https://github.com/pq-crystals/kyber),\n * [spec](https://datatracker.ietf.org/doc/draft-cfrg-schwabe-kyber/).\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { sha3_256, sha3_512, shake256 } from '@noble/hashes/sha3.js';\nimport { type CHash, swap32IfBE, u32 } from '@noble/hashes/utils.js';\nimport { genCrystals, type XOF, XOF128 } from './_crystals.ts';\nimport {\n abytes,\n cleanBytes,\n type Coder,\n copyBytes,\n equalBytes,\n getMask,\n type KEM,\n randomBytes,\n splitCoder,\n type TArg,\n type TRet,\n vecCoder,\n} from './utils.ts';\n\n/** Key encapsulation mechanism interface */\n\nconst N = 256; // Kyber (not FIPS-203) supports different lengths, but all std modes were using 256\nconst Q = 3329; // 13*(2**8)+1, modulo prime\nconst F = 3303; // 3303 ≡ 128**(−1) mod q (FIPS-203)\nconst ROOT_OF_UNITY = 17; // ζ = 17 ∈ Zq is a primitive 256-th root of unity modulo Q. ζ**128 ≡−1\n// treeshake: keep genCrystals behind the object so PARAMS-only bundles can drop it entirely.\n// Shared CRYSTALS helper in the ML-KEM branch: Kyber mode, 7-bit bit-reversal,\n// and Uint16Array polys because current coefficients stay reduced modulo q.\nconst crystals = /* @__PURE__ */ genCrystals({\n N,\n Q,\n F,\n ROOT_OF_UNITY,\n newPoly: (n: number): TRet<Uint16Array> => new Uint16Array(n) as TRet<Uint16Array>,\n brvBits: 7,\n isKyber: true,\n});\n\n/** FIPS 203: 7. Parameter Sets */\n/** Public ML-KEM parameter-set description. */\nexport type KEMParam = {\n /** Polynomial size. */\n N: number;\n /** Module rank. */\n K: number;\n /** Prime modulus. */\n Q: number;\n /** CBD parameter used for secret-key noise. */\n ETA1: number;\n /** CBD parameter used for error noise. */\n ETA2: number;\n /** Compression width for the `u` vector. */\n du: number;\n /** Compression width for the `v` polynomial. */\n dv: number;\n /** Required strength of the randomness source in bits. */\n RBGstrength: number;\n};\n/** Internal params of ML-KEM versions */\n// prettier-ignore\n/** Built-in ML-KEM parameter presets keyed by the public export names\n * `ml_kem512` / `ml_kem768` / `ml_kem1024`.\n * `RBGstrength` is Table 2's required randomness-source strength in bits,\n * not a generic security label.\n */\nexport const PARAMS: Record<string, KEMParam> = /* @__PURE__ */ (() =>\n Object.freeze({\n 512: Object.freeze({ N, Q, K: 2, ETA1: 3, ETA2: 2, du: 10, dv: 4, RBGstrength: 128 }),\n 768: Object.freeze({ N, Q, K: 3, ETA1: 2, ETA2: 2, du: 10, dv: 4, RBGstrength: 192 }),\n 1024: Object.freeze({ N, Q, K: 4, ETA1: 2, ETA2: 2, du: 11, dv: 5, RBGstrength: 256 }),\n } as const))();\n\n// FIPS-203: compress/decompress\nconst compress = (d: number): Coder<number, number> => {\n // d=12 is the ByteEncode12/ByteDecode12 path, not lossy compression.\n // ByteDecode12 interprets each 12-bit word modulo q; without that reduction the public-key\n // modulus check in encapsulate() becomes a no-op for malformed coefficients like 4095.\n if (d >= 12) return { encode: (i: number) => i, decode: (i: number) => (i >= Q ? i - Q : i) };\n // Comments map to python implementation in RFC (draft-cfrg-schwabe-kyber)\n // const round = (i: number) => Math.floor(i + 0.5) | 0;\n const a = 2 ** (d - 1);\n return {\n // This only matches standalone Compress_d after bitsCoder masks the result into Z_(2^d).\n encode: (i: number) => ((i << d) + Q / 2) / Q,\n // const decompress = (i: number) => round((Q / 2 ** d) * i);\n decode: (i: number) => (i * Q + a) >>> d,\n };\n};\n\n// Raw ByteEncode_d / ByteDecode_d from FIPS 203 operate on d-bit words directly.\n// That differs from `polyCoder(d)` for d<12, where noble folds packing together with the lossy\n// ciphertext compression step used by u/v. Tests that exercise the spec's raw packing surface need\n// this exact non-lossy variant instead.\nconst byteCoder = (d: number) =>\n crystals.bitsCoder(\n d,\n d === 12\n ? { encode: (i: number) => i, decode: (i: number) => (i >= Q ? i - Q : i) }\n : { encode: (i: number) => i, decode: (i: number) => i }\n );\n\n// NOTE: we merge encoding and compress because it is faster, also both require same d param\n// d=12 is the ByteEncode12/ByteDecode12 path rather than compression, and caller-side\n// public-key modulus checks route through this helper's decode/encode roundtrip.\n// Converts between bytes and d-bits compressed representation.\n// Kinda like convertRadix2 from @scure/base.\n// decode(encode(t)) == t, but there is loss of information on encode(decode(t))\nconst polyCoder = (d: number) => (d === 12 ? byteCoder(12) : crystals.bitsCoder(d, compress(d)));\n\n// Poly is mod Q, so 12 bits\ntype Poly = Uint16Array;\n\nfunction polyAdd(a_: TArg<Poly>, b_: TArg<Poly>) {\n const a = a_ as Poly;\n const b = b_ as Poly;\n // Mutates `a` in place; callers must pass two N=256 polynomials.\n for (let i = 0; i < N; i++) a[i] = crystals.mod(a[i] + b[i]); // a += b\n}\nfunction polySub(a_: TArg<Poly>, b_: TArg<Poly>) {\n const a = a_ as Poly;\n const b = b_ as Poly;\n // Mutates `a` in place; callers must pass two N=256 polynomials.\n for (let i = 0; i < N; i++) a[i] = crystals.mod(a[i] - b[i]); // a -= b\n}\n\n// FIPS-203: Computes the product of two degree-one polynomials with respect to a quadratic modulus\nfunction BaseCaseMultiply(a0: number, a1: number, b0: number, b1: number, zeta: number) {\n // `zeta` here is Algorithm 11's γ = ζ^(2BitRev_7(i)+1).\n const c0 = crystals.mod(a1 * b1 * zeta + a0 * b0);\n const c1 = crystals.mod(a0 * b1 + a1 * b0);\n return { c0, c1 };\n}\n\n// FIPS-203: Computes the product (in the ring Tq) of two NTT representations.\n// Works in place on `f`; `g` is read-only and both inputs must already be in NTT form.\nfunction MultiplyNTTs(f_: TArg<Poly>, g_: TArg<Poly>): TRet<Poly> {\n const f = f_ as Poly;\n const g = g_ as Poly;\n for (let i = 0; i < N / 2; i++) {\n let z = crystals.nttZetas[64 + (i >> 1)];\n if (i & 1) z = -z;\n const { c0, c1 } = BaseCaseMultiply(f[2 * i + 0], f[2 * i + 1], g[2 * i + 0], g[2 * i + 1], z);\n f[2 * i + 0] = c0;\n f[2 * i + 1] = c1;\n }\n return f as TRet<Poly>;\n}\n\ntype PRF = (l: number, key: Uint8Array, nonce: number) => Uint8Array;\n\ntype XofGet = ReturnType<ReturnType<XOF>['get']>;\n\ntype KyberOpts = KEMParam & {\n HASH256: CHash;\n HASH512: CHash;\n KDF: CHash<any, { dkLen?: number }>;\n XOF: XOF; // (seed: Uint8Array, len: number, x: number, y: number) => Uint8Array;\n PRF: PRF;\n};\n\n// Return poly in NTT representation\nfunction SampleNTT(xof_: TArg<XofGet>): TRet<Poly> {\n const xof = xof_ as XofGet;\n // The reader must already bind the Algorithm 7 seed||j||i bytes\n // and return block lengths divisible by 3.\n const r: Poly = new Uint16Array(N);\n for (let j = 0; j < N; ) {\n const b = xof();\n if (b.length % 3) throw new Error('SampleNTT: unaligned block');\n for (let i = 0; j < N && i + 3 <= b.length; i += 3) {\n const d1 = ((b[i + 0] >> 0) | (b[i + 1] << 8)) & 0xfff;\n const d2 = ((b[i + 1] >> 4) | (b[i + 2] << 4)) & 0xfff;\n if (d1 < Q) r[j++] = d1;\n if (j < N && d2 < Q) r[j++] = d2;\n }\n }\n return r as TRet<Poly>;\n}\n\n// Sampling from the centered binomial distribution\n// Returns poly with small coefficients (noise/errors) stored modulo q in ordinary coefficient form.\n// Current callers only use Table 2 eta values {2,3} and PRF outputs of exactly 64*eta bytes.\nconst sampleCBDBytes = (buf: TArg<Uint8Array>, eta: number): TRet<Poly> => {\n const r: Poly = new Uint16Array(N);\n // CBD consumes the PRF bitstream in little-endian byte order; normalize the word view on BE,\n // then swap it back so callers still observe `buf` as read-only.\n const b32 = u32(buf);\n swap32IfBE(b32);\n let len = 0;\n for (let i = 0, p = 0, bb = 0, t0 = 0; i < b32.length; i++) {\n let b = b32[i];\n for (let j = 0; j < 32; j++) {\n bb += b & 1;\n b >>= 1;\n len += 1;\n if (len === eta) {\n t0 = bb;\n bb = 0;\n } else if (len === 2 * eta) {\n r[p++] = crystals.mod(t0 - bb);\n bb = 0;\n len = 0;\n }\n }\n }\n swap32IfBE(b32);\n if (len) throw new Error(`sampleCBD: leftover bits: ${len}`);\n return r as TRet<Poly>;\n};\n\nfunction sampleCBD(\n PRF_: TArg<PRF>,\n seed: TArg<Uint8Array>,\n nonce: number,\n eta: number\n): TRet<Poly> {\n const PRF = PRF_ as PRF;\n return sampleCBDBytes(PRF((eta * N) / 4, seed, nonce), eta);\n}\n\n// K-PKE\n// Internal ML-KEM subroutine only: exact 32-byte `seed` / `msg` inputs\n// come from Algorithms 13-15, and the helper mutates decoded temporary\n// polynomials in place while leaving caller byte arrays unchanged.\nconst genKPKE = (opts_: TArg<KyberOpts>) => {\n const opts = opts_ as KyberOpts;\n const { K, PRF, XOF, HASH512, ETA1, ETA2, du, dv } = opts;\n const poly1 = polyCoder(1);\n const polyV = polyCoder(dv);\n const polyU = polyCoder(du);\n const publicCoder = splitCoder('publicKey', vecCoder(polyCoder(12), K), 32);\n const secretCoder = vecCoder(polyCoder(12), K);\n const cipherCoder = splitCoder('ciphertext', vecCoder(polyU, K), polyV);\n const seedCoder = splitCoder('seed', 32, 32);\n return {\n secretCoder,\n lengths: {\n secretKey: secretCoder.bytesLen,\n publicKey: publicCoder.bytesLen,\n cipherText: cipherCoder.bytesLen,\n },\n keygen: (seed: TArg<Uint8Array>) => {\n abytes(seed, 32, 'seed');\n const seedDst = new Uint8Array(33);\n seedDst.set(seed);\n // FIPS 203 Algorithm 13 appends the parameter-set byte `k`\n // before `G(d || k)`, so expanding the same 32-byte seed\n // under a different ML-KEM parameter set yields unrelated keys.\n seedDst[32] = K;\n const seedHash = HASH512(seedDst);\n\n const [rho, sigma] = seedCoder.decode(seedHash);\n const sHat: Poly[] = [];\n const tHat: Poly[] = [];\n for (let i = 0; i < K; i++) sHat.push(crystals.NTT.encode(sampleCBD(PRF, sigma, i, ETA1)));\n const x = XOF(rho);\n for (let i = 0; i < K; i++) {\n const e = crystals.NTT.encode(sampleCBD(PRF, sigma, K + i, ETA1));\n for (let j = 0; j < K; j++) {\n const aji = SampleNTT(x.get(j, i)); // A[i][j], inplace\n polyAdd(e, MultiplyNTTs(aji, sHat[j]));\n }\n tHat.push(e); // t ← A ◦ s + e\n }\n x.clean();\n const res = {\n publicKey: publicCoder.encode([tHat, rho]),\n secretKey: secretCoder.encode(sHat),\n };\n cleanBytes(rho, sigma, sHat, tHat, seedDst, seedHash);\n return res;\n },\n encrypt: (\n publicKey: TArg<Uint8Array>,\n msg: TArg<Uint8Array>,\n seed: TArg<Uint8Array>\n ): TRet<Uint8Array> => {\n const [tHat, rho] = publicCoder.decode(publicKey);\n const rHat = [];\n for (let i = 0; i < K; i++) rHat.push(crystals.NTT.encode(sampleCBD(PRF, seed, i, ETA1)));\n const x = XOF(rho);\n const tmp2 = new Uint16Array(N);\n const u = [];\n for (let i = 0; i < K; i++) {\n const e1 = sampleCBD(PRF, seed, K + i, ETA2);\n const tmp = new Uint16Array(N);\n for (let j = 0; j < K; j++) {\n const aij = SampleNTT(x.get(i, j)); // A[j][i], inplace transpose access\n polyAdd(tmp, MultiplyNTTs(aij, rHat[j])); // t += aij * rHat[j]\n }\n polyAdd(e1, crystals.NTT.decode(tmp)); // e1 += tmp\n u.push(e1);\n polyAdd(tmp2, MultiplyNTTs(tHat[i], rHat[i])); // t2 += tHat[i] * rHat[i]\n cleanBytes(tmp);\n }\n x.clean();\n const e2 = sampleCBD(PRF, seed, 2 * K, ETA2);\n polyAdd(e2, crystals.NTT.decode(tmp2)); // e2 += tmp2\n const v = poly1.decode(msg); // encode plaintext m into polynomial v\n polyAdd(v, e2); // v += e2\n cleanBytes(tHat, rHat, tmp2, e2);\n return cipherCoder.encode([u, v]) as TRet<Uint8Array>;\n },\n decrypt: (cipherText: TArg<Uint8Array>, privateKey: TArg<Uint8Array>): TRet<Uint8Array> => {\n const [u, v] = cipherCoder.decode(cipherText);\n const sk = secretCoder.decode(privateKey); // s ← ByteDecode_12(dkPKE)\n const tmp = new Uint16Array(N);\n // tmp += sk[i] * u[i]\n for (let i = 0; i < K; i++) polyAdd(tmp, MultiplyNTTs(sk[i], crystals.NTT.encode(u[i])));\n polySub(v, crystals.NTT.decode(tmp)); // w = v' - tmp\n cleanBytes(tmp, sk, u);\n return poly1.encode(v) as TRet<Uint8Array>;\n },\n };\n};\n\n/**\n * Public ML-KEM wrapper over the internal K-PKE subroutine.\n * `keygen(seed)` and `encapsulate(publicKey, msg)` are deterministic/test-oriented hooks that map\n * more directly to Algorithms 16-17 than to the pure no-input / random-internal Algorithms 19-20.\n * decapsulate() tries to follow the Algorithms 18/21 implicit-reject structure as closely as\n * practical here by re-encrypting, comparing ciphertexts, returning `Khat` on match or `Kbar` on\n * mismatch, and zeroizing the non-returned shared-secret candidate; JS/JIT still provides no\n * constant-time guarantees for that path.\n */\nfunction createKyber(opts: TArg<KyberOpts>): TRet<KEM> {\n const rawOpts = opts as KyberOpts;\n const KPKE = genKPKE(rawOpts);\n const { HASH256, HASH512, KDF } = rawOpts;\n const { secretCoder: KPKESecretCoder, lengths } = KPKE;\n const secretCoder = splitCoder('secretKey', lengths.secretKey, lengths.publicKey, 32, 32);\n const msgLen = 32;\n const seedLen = 64;\n const kemLengths = Object.freeze({\n ...lengths,\n seed: 64,\n msg: msgLen,\n msgRand: msgLen,\n secretKey: secretCoder.bytesLen,\n });\n return Object.freeze({\n info: Object.freeze({ type: 'ml-kem' }),\n lengths: kemLengths,\n keygen: (seed: TArg<Uint8Array> = randomBytes(seedLen)) => {\n abytes(seed, seedLen, 'seed');\n const { publicKey, secretKey: sk } = KPKE.keygen(seed.subarray(0, 32));\n const publicKeyHash = HASH256(publicKey);\n // (dkPKE||ek||H(ek)||z)\n const secretKey = secretCoder.encode([sk, publicKey, publicKeyHash, seed.subarray(32)]);\n cleanBytes(sk, publicKeyHash);\n return {\n publicKey: publicKey as TRet<Uint8Array>,\n secretKey: secretKey as TRet<Uint8Array>,\n };\n },\n getPublicKey: (secretKey: TArg<Uint8Array>): TRet<Uint8Array> => {\n const [_sk, publicKey, _publicKeyHash, _z] = secretCoder.decode(secretKey);\n return Uint8Array.from(publicKey) as TRet<Uint8Array>;\n },\n encapsulate: (publicKey: TArg<Uint8Array>, msg: TArg<Uint8Array> = randomBytes(msgLen)) => {\n abytes(publicKey, lengths.publicKey, 'publicKey');\n abytes(msg, msgLen, 'message');\n\n // FIPS-203 includes additional verification check for modulus\n const eke = publicKey.subarray(0, 384 * opts.K);\n // Copy because of inplace encoding\n const ek = KPKESecretCoder.encode(KPKESecretCoder.decode(copyBytes(eke)));\n // (Modulus check.) Perform the computation ek ← ByteEncode12(ByteDecode12(eke)).\n // If ek = ̸ eke, the input is invalid. (See Section 4.2.1.)\n if (!equalBytes(ek, eke)) {\n cleanBytes(ek);\n throw new Error('ML-KEM.encapsulate: wrong publicKey modulus');\n }\n cleanBytes(ek);\n // derive randomness\n const kr = HASH512.create().update(msg).update(HASH256(publicKey)).digest();\n const cipherText = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64));\n cleanBytes(kr.subarray(32));\n return {\n cipherText: cipherText as TRet<Uint8Array>,\n sharedSecret: kr.subarray(0, 32) as TRet<Uint8Array>,\n };\n },\n decapsulate: (cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>): TRet<Uint8Array> => {\n abytes(secretKey, secretCoder.bytesLen, 'secretKey'); // 768*k + 96\n abytes(cipherText, lengths.cipherText, 'cipherText'); // 32(du*k + dv)\n // test ← H(dk[384𝑘 ∶ 768𝑘 + 32])) .\n const k768 = secretCoder.bytesLen - 96;\n const start = k768 + 32;\n const test = HASH256(secretKey.subarray(k768 / 2, start));\n // If test ≠ dk[768𝑘 + 32 ∶ 768𝑘 + 64], then input checking has failed.\n if (!equalBytes(test, secretKey.subarray(start, start + 32)))\n throw new Error('invalid secretKey: hash check failed');\n const [sk, publicKey, publicKeyHash, z] = secretCoder.decode(secretKey);\n const msg = KPKE.decrypt(cipherText, sk);\n // derive randomness, Khat, rHat = G(mHat || h)\n const kr = HASH512.create().update(msg).update(publicKeyHash).digest();\n const Khat = kr.subarray(0, 32);\n // re-encrypt using the derived randomness\n const cipherText2 = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64));\n // if ciphertexts do not match, “implicitly reject”\n const isValid = equalBytes(cipherText, cipherText2);\n const Kbar = KDF.create({ dkLen: 32 }).update(z).update(cipherText).digest();\n cleanBytes(msg, cipherText2, !isValid ? Khat : Kbar);\n return (isValid ? Khat : Kbar) as TRet<Uint8Array>;\n },\n });\n}\n\n// FIPS 203's PRF_eta binding: current callers use only 32-byte keys, one-byte nonces,\n// and dkLen values {128, 192}; out-of-range nonce numbers still wrap modulo 256 here.\nfunction shakePRF(dkLen: number, key: TArg<Uint8Array>, nonce: number): TRet<Uint8Array> {\n return shake256\n .create({ dkLen })\n .update(key)\n .update(new Uint8Array([nonce]))\n .digest() as TRet<Uint8Array>;\n}\n\n// Fixed ML-KEM hash/XOF bindings. `KDF` here is the spec's fixed 32-byte `J` call,\n// and swapping any field changes the scheme rather than tuning an internal dependency.\nconst opts = /* @__PURE__ */ (() => ({\n HASH256: sha3_256,\n HASH512: sha3_512,\n KDF: shake256,\n XOF: XOF128,\n PRF: shakePRF,\n}))();\n// Parameter-set instantiation step for the spec's \"ML-KEM-x\" names; current correctness relies\n// on the internal PARAMS rows rather than local validation of arbitrary KEMParam objects.\nconst mk = (params: KEMParam) =>\n createKyber({\n ...opts,\n ...params,\n });\n\n/**\n * ML-KEM-512: Table 2 row `k=2, η1=3, η2=2, du=10, dv=4`; Table 3 sizes `800/1632/768/32`.\n * The ASD lifecycle note here is external policy guidance, not a FIPS 203 requirement.\n */\nexport const ml_kem512: TRet<KEM> = /* @__PURE__ */ (() => mk(PARAMS[512]))();\n/**\n * ML-KEM-768: Table 2 row `k=3, η1=2, η2=2, du=10, dv=4`; Table 3 sizes `1184/2400/1088/32`.\n * The ASD lifecycle note here is external policy guidance, not a FIPS 203 requirement.\n */\nexport const ml_kem768: TRet<KEM> = /* @__PURE__ */ (() => mk(PARAMS[768]))();\n/**\n * ML-KEM-1024: Table 2 row `k=4, η1=2, η2=2, du=11, dv=5`; Table 3 sizes `1568/3168/1568/32`.\n * The ASD lifecycle note here is external policy guidance, not a FIPS 203 requirement.\n */\nexport const ml_kem1024: TRet<KEM> = /* @__PURE__ */ (() => mk(PARAMS[1024]))();\n\n// NOTE: for tests only, don't use. This keeps the exact internal ML-KEM math surfaces available\n// without re-implementing them in separate test code.\nexport const __tests: any = /* @__PURE__ */ (() =>\n Object.freeze({\n Compress_d: (x: number, d: number) => {\n if (d < 1 || d > 11) throw new Error(`Compress_d: expected d in [1..11], got ${d}`);\n return compress(d).encode(x) & getMask(d);\n },\n Decompress_d: (y: number, d: number) => {\n if (d < 1 || d > 11) throw new Error(`Decompress_d: expected d in [1..11], got ${d}`);\n return compress(d).decode(y);\n },\n ByteEncode_d: (F: TArg<Uint16Array>, d: number) => {\n if (d < 1 || d > 12) throw new Error(`ByteEncode_d: expected d in [1..12], got ${d}`);\n return byteCoder(d).encode(F as TRet<Uint16Array>);\n },\n ByteDecode_d: (B: TArg<Uint8Array>, d: number) => {\n if (d < 1 || d > 12) throw new Error(`ByteDecode_d: expected d in [1..12], got ${d}`);\n return byteCoder(d).decode(B);\n },\n NTT: (f: TArg<Uint16Array>) => crystals.NTT.encode(Uint16Array.from(f)),\n NTT_inv: (fHat: TArg<Uint16Array>) => crystals.NTT.decode(Uint16Array.from(fHat)),\n MultiplyNTTs: (fHat: TArg<Uint16Array>, gHat: TArg<Uint16Array>) =>\n MultiplyNTTs(Uint16Array.from(fHat), Uint16Array.from(gHat)),\n SamplePolyCBD: (B: TArg<Uint8Array>, eta: number) => {\n abytes(B, 64 * eta, 'B');\n return sampleCBDBytes(B, eta);\n },\n SampleNTT: (B: TArg<Uint8Array>) => {\n abytes(B, 34, 'B');\n const xof = XOF128(B.subarray(0, 32));\n try {\n return SampleNTT(xof.get(B[32], B[33]));\n } finally {\n xof.clean();\n }\n },\n }))();\n","/**\n * Post-Quantum Hybrid Cryptography\n *\n * The current implementation is flawed and likely redundant. We should offer\n * a small, generic API to compose hybrid schemes instead of reimplementing\n * protocol-specific logic (SSH, GPG, etc.) with ad hoc encodings.\n *\n * 1. Core Issues\n * - sign/verify: implemented as two separate operations with different keys.\n * - EC getSharedSecret: could be refactored into a proper KEM.\n * - Multiple calls: keys, signatures, and shared secrets could be\n * concatenated to reduce the number of API invocations.\n * - Reinvention: most libraries add strange domain separations and\n * encodings instead of simple byte concatenation.\n *\n * 2. API Goals\n * - Provide primitives to build hybrids generically.\n * - Avoid embedding SSH- or GPG-specific formats in the core API.\n *\n * 3. Edge Cases\n * • Variable-length signatures:\n * - DER-encoded (Weierstrass curves).\n * - Falcon (unpadded).\n * - Concatenation works only if length is fixed; otherwise a length\n * prefix is required (but that breaks compatibility).\n *\n * • getSharedSecret:\n * - Default: non-KEM (authenticated ECDH).\n * - KEM conversion: generate a random SK to remove implicit auth.\n *\n * 4. Common Pitfalls\n * - Seed expansion:\n * • Expanding a small seed into multiple keys reduces entropy.\n * • API should allow identity mapping (no expansion).\n *\n * - Skipping full point encoding:\n * • Some omit the compression byte (parity) for WebCrypto compatibility.\n * • Better: hash the raw secret; coordinate output is already non-uniform.\n * • Some curves (e.g., X448) produce secrets that must be re-hashed to match\n * symmetric-key lengths.\n *\n * - Combiner inconsistencies:\n * • Different domain separations and encodings across libraries.\n * • Should live at the application layer, since key lengths vary.\n *\n * 5. Protocol Examples\n * - SSH:\n * • Concatenate keys.\n * • Combiner: SHA-512.\n *\n * - GPG:\n * • Concatenate keys.\n * • Combiner:\n * SHA3-256(kemShare || ecdhShare || ciphertext || pubKey || algId || domSep || len(domSep))\n *\n * - TLS:\n * • Transcript-based derivation (HKDF).\n *\n * 6. Relevant Specs & Implementations\n * - IETF Hybrid KEM drafts:\n * • draft-irtf-cfrg-hybrid-kems\n * • draft-connolly-cfrg-xwing-kem\n * • draft-westerbaan-tls-xyber768d00\n *\n * - PQC Libraries:\n * • superdilithium (cyph/pqcrypto.js) – low adoption.\n * • hybrid-pqc (DogeProtocol, quantumcoinproject) – complex encodings.\n *\n * 7. Signatures\n * - Ed25519: fixed-size, easy to support.\n * - Variable-size: introduces custom format requirements; best left to\n * higher-level code.\n *\n * @module\n */\n/*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */\nimport { type EdDSA } from '@noble/curves/abstract/edwards.js';\nimport { type MontgomeryECDH } from '@noble/curves/abstract/montgomery.js';\nimport { type ECDSA } from '@noble/curves/abstract/weierstrass.js';\nimport { x25519 } from '@noble/curves/ed25519.js';\nimport { p256, p384 } from '@noble/curves/nist.js';\nimport {\n asciiToBytes,\n bytesToNumberBE,\n bytesToNumberLE,\n concatBytes,\n numberToBytesBE,\n} from '@noble/curves/utils.js';\nimport { expand, extract } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { sha3_256, shake256 } from '@noble/hashes/sha3.js';\nimport { abytes, ahash, anumber, type CHash, type CHashXOF } from '@noble/hashes/utils.js';\nimport { ml_kem1024, ml_kem768 } from './ml-kem.ts';\nimport {\n cleanBytes,\n copyBytes,\n randomBytes,\n splitCoder,\n validateSigOpts,\n validateVerOpts,\n type CryptoKeys,\n type KEM,\n type Signer,\n type TArg,\n type TRet,\n} from './utils.ts';\n\ntype CurveAll = ECDSA | EdDSA | MontgomeryECDH;\ntype CurveECDH = ECDSA | MontgomeryECDH;\ntype CurveSign = ECDSA | EdDSA;\n\n// Can re-use if decide to signatures support, on other hand getSecretKey is specific and ugly\nfunction ecKeygen(curve: CurveAll, allowZeroKey: boolean = false) {\n const lengths = curve.lengths;\n let keygen = curve.keygen;\n if (allowZeroKey) {\n // Only the ECDSA/Weierstrass branch uses raw scalar-byte secret keys here. Edwards seeds are\n // hashed/pruned and Montgomery keys are clamped byte strings, so forcing Point.Fn semantics on\n // those curves would change key construction instead of just relaxing scalar range handling.\n if (!('getSharedSecret' in curve && 'sign' in curve && 'verify' in curve))\n throw new Error('allowZeroKey requires a Weierstrass curve');\n // This legacy flag is really \"skip the +1 shift\" for vector matching, not \"accept scalar 0\".\n // It swaps seeded Weierstrass keygen from reduction into [1, ORDER) to direct reduction into\n // [0, ORDER), which preserves exact reduced bytes but still leaves scalar 0 invalid.\n // This is ugly, but we need to return exact results here.\n const wCurve = curve as ECDSA;\n const Fn = wCurve.Point.Fn;\n // Unlike noble-curves' seeded Weierstrass keygen, this path removes the post-reduction +1.\n // That is enough to match exact reduced-vector bytes, but an all-zero seed still reduces to\n // scalar 0 here and getPublicKey(secretKey) throws instead of \"allowing zero\".\n keygen = (seed: TArg<Uint8Array> = randomBytes(lengths.seed)) => {\n abytes(seed, lengths.seed!, 'seed');\n const seedScalar = Fn.isLE ? bytesToNumberLE(seed) : bytesToNumberBE(seed);\n // Reduce directly into [0, ORDER); scalar 0 still stays invalid.\n const secretKey = Fn.toBytes(Fn.create(seedScalar));\n return {\n secretKey: secretKey as TRet<Uint8Array>,\n publicKey: curve.getPublicKey(secretKey) as TRet<Uint8Array>,\n };\n };\n }\n return {\n lengths: { secretKey: lengths.secretKey, publicKey: lengths.publicKey, seed: lengths.seed },\n keygen: (seed?: TArg<Uint8Array>) =>\n keygen(seed) as TRet<{\n secretKey: Uint8Array;\n publicKey: Uint8Array;\n }>,\n getPublicKey: (secretKey: TArg<Uint8Array>) =>\n curve.getPublicKey(secretKey) as TRet<Uint8Array>,\n };\n}\n\n/**\n * Wraps an ECDH-capable curve as a KEM.\n * Shared secrets stay in the wrapped curve's raw ECDH byte format with no built-in KDF.\n * On SEC 1 / Weierstrass curves, that means the compressed shared-point body without the\n * 1-byte `0x02` / `0x03` prefix.\n * The X25519 path also leaves RFC 7748's optional all-zero shared-secret check to callers.\n * @param curve - Curve with `getSharedSecret`.\n * @param allowZeroKey - Legacy vector-matching toggle for Weierstrass keygen.\n * On Weierstrass curves this removes the usual post-reduction `+1` shift, changing seeded scalar\n * reduction from `[1, ORDER)` to direct reduction into `[0, ORDER)`. It does not make scalar zero\n * valid: an all-zero seed still derives scalar `0` and throws in `curve.getPublicKey(...)`.\n * Only supported on Weierstrass/ECDSA curves.\n * @returns KEM wrapper over the curve.\n * @throws If the curve does not expose `getSharedSecret`. {@link Error}\n * @example\n * Wrap an ECDH-capable curve as a generic KEM.\n * ```ts\n * import { x25519 } from '@noble/curves/ed25519.js';\n * import { ecdhKem } from '@noble/post-quantum/hybrid.js';\n * const kem = ecdhKem(x25519);\n * const publicKeyLen = kem.lengths.publicKey;\n * ```\n */\nexport function ecdhKem(curve: CurveECDH, allowZeroKey: boolean = false): TRet<KEM> {\n const kg = ecKeygen(curve, allowZeroKey);\n if (!curve.getSharedSecret) throw new Error('wrong curve'); // ed25519 doesn't have one!\n return {\n lengths: { ...kg.lengths, msg: kg.lengths.seed, cipherText: kg.lengths.publicKey },\n keygen: kg.keygen,\n getPublicKey: kg.getPublicKey,\n encapsulate(\n publicKey: TArg<Uint8Array>,\n rand: TArg<Uint8Array> = randomBytes(curve.lengths.seed)\n ) {\n // Some curve.keygen(seed) paths reuse the provided seed buffer as secretKey; detach caller\n // randomness first so cleanBytes() only wipes wrapper-owned material.\n const seed = copyBytes(rand);\n let ek: Uint8Array | undefined = undefined;\n try {\n ek = this.keygen(seed).secretKey;\n const sharedSecret = this.decapsulate(publicKey, ek);\n const cipherText = curve.getPublicKey(ek) as TRet<Uint8Array>;\n return { sharedSecret, cipherText };\n } finally {\n // Invalid peer public keys can make decapsulation throw; wipe both the detached seed and\n // derived ephemeral secret key even when encapsulation aborts before returning.\n cleanBytes(seed);\n if (ek) cleanBytes(ek);\n }\n },\n decapsulate(cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>) {\n const res = curve.getSharedSecret(secretKey, cipherText);\n return (curve.lengths.publicKeyHasPrefix ? res.subarray(1) : res) as TRet<Uint8Array>;\n },\n };\n}\n\n/**\n * Wraps a curve signer as a generic `Signer`.\n * Signatures stay in the wrapped curve's native byte encoding.\n * This wrapper does not normalize or document which per-curve signing options are meaningful.\n * @param curve - Curve with `sign` and `verify`.\n * @param allowZeroKey - Legacy vector-matching toggle for Weierstrass keygen.\n * On Weierstrass curves this removes the usual post-reduction `+1` shift, changing seeded scalar\n * reduction from `[1, ORDER)` to direct reduction into `[0, ORDER)`. It does not make scalar zero\n * valid: an all-zero seed still derives scalar `0` and throws in `curve.getPublicKey(...)`.\n * Only supported on Weierstrass/ECDSA curves.\n * @returns Signer wrapper over the curve.\n * @throws If the curve does not expose `sign` and `verify`. {@link Error}\n * @example\n * Wrap a curve signer as a generic signer.\n * ```ts\n * import { ed25519 } from '@noble/curves/ed25519.js';\n * import { ecSigner } from '@noble/post-quantum/hybrid.js';\n * const signer = ecSigner(ed25519);\n * const sigLen = signer.lengths.signature;\n * ```\n */\nexport function ecSigner(curve: CurveSign, allowZeroKey: boolean = false): TRet<Signer> {\n const kg = ecKeygen(curve, allowZeroKey);\n if (!curve.sign || !curve.verify) throw new Error('wrong curve'); // ed25519 doesn't have one!\n return {\n lengths: { ...kg.lengths, signature: curve.lengths.signature, signRand: 0 },\n keygen: kg.keygen,\n getPublicKey: kg.getPublicKey,\n sign: (message, secretKey, opts = {}) => {\n validateSigOpts(opts);\n // This generic wrapper intentionally keeps the Signer contract to message + key only.\n // Backend-specific knobs like ECDSA extraEntropy or Ed25519ctx context cannot be forwarded\n // uniformly through combineSigners(), so callers that need them must use the curve directly.\n if (opts.extraEntropy !== undefined)\n throw new Error(\n 'ecSigner does not support extraEntropy; use the underlying curve directly'\n );\n if (opts.context !== undefined)\n throw new Error('ecSigner does not support context; use the underlying curve directly');\n return curve.sign(message, secretKey) as TRet<Uint8Array>;\n },\n /** Verify one wrapped curve signature.\n * Returns the wrapped curve's `verify()` result for well-formed inputs. Throws on unsupported\n * generic opts and lets wrapped-curve malformed-input errors escape unchanged.\n */\n verify: (signature, message, publicKey, opts = {}) => {\n validateVerOpts(opts);\n if (opts.context !== undefined)\n throw new Error('ecSigner does not support context; use the underlying curve directly');\n return curve.verify(signature, message, publicKey);\n },\n };\n}\n\nfunction splitLengths<K extends string, T extends { lengths: Partial<Record<K, number>> }>(\n lst: T[],\n name: K\n) {\n // Preserve caller order exactly; raw numeric fields still decode as splitCoder() subarray views.\n return splitCoder(\n name,\n ...lst.map((i) => {\n if (typeof i.lengths[name] !== 'number') throw new Error('wrong length: ' + name);\n return i.lengths[name];\n })\n );\n}\n\n/** Seed-expansion callback used by the hybrid combiners. */\nexport type ExpandSeed = (seed: TArg<Uint8Array>, len: number) => TRet<Uint8Array>;\ntype XOF = CHashXOF<any, { dkLen: number }>;\n\n// It is XOF for most cases, but can be more complex!\n/**\n * Adapts an XOF into an `ExpandSeed` callback.\n * The returned callback interprets its second argument as an output byte length passed as `dkLen`.\n * @param xof - Extendable-output hash function.\n * @returns Seed expander using `dkLen`.\n * @example\n * Adapt an XOF into a seed expander.\n * ```ts\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { expandSeedXof } from '@noble/post-quantum/hybrid.js';\n * const expandSeed = expandSeedXof(shake256);\n * const seed = expandSeed(new Uint8Array([1]), 4);\n * ```\n */\nexport function expandSeedXof(xof: TArg<XOF>): TRet<ExpandSeed> {\n // Forward the caller seed directly: XOFs are expected to treat inputs as read-only, and this\n // adapter only translates the requested byte length into the hash API's `dkLen` option.\n return ((seed: TArg<Uint8Array>, seedLen: number): TRet<Uint8Array> =>\n (xof as XOF)(seed, { dkLen: seedLen }) as TRet<Uint8Array>) as TRet<ExpandSeed>;\n}\n\n/** Combines public keys, ciphertexts, and shared secrets into one shared secret. */\nexport type Combiner = (\n publicKeys: TArg<Uint8Array[]>,\n cipherTexts: TArg<Uint8Array[]>,\n sharedSecrets: TArg<Uint8Array[]>\n) => TRet<Uint8Array>;\n\nfunction combineKeys(\n realSeedLen: number | undefined, // how much bytes expandSeed expects\n expandSeed_: TArg<ExpandSeed>,\n ...ck_: TArg<CryptoKeys[]>\n) {\n const expandSeed = expandSeed_ as ExpandSeed;\n const ck = ck_ as CryptoKeys[];\n const seedCoder = splitLengths(ck, 'seed');\n const pkCoder = splitLengths(ck, 'publicKey');\n // Allows to use identity functions for combiner/expandSeed\n if (realSeedLen === undefined) realSeedLen = seedCoder.bytesLen;\n anumber(realSeedLen);\n function expandDecapsulationKey(seed: TArg<Uint8Array>): TRet<{\n secretKey: Uint8Array[];\n publicKey: Uint8Array[];\n }> {\n abytes(seed, realSeedLen!);\n const expandedRaw = expandSeed(seed, seedCoder.bytesLen);\n // Identity/subarray expanders can hand back caller-owned seed storage. Detach those outputs so\n // later cleanup can wipe the expanded schedule without mutating the caller's root seed bytes.\n const expandedSeed = expandedRaw.buffer === seed.buffer ? copyBytes(expandedRaw) : expandedRaw;\n const expanded: Uint8Array[] = [];\n const keySecret: Uint8Array[] = [];\n const secretKey: Uint8Array[] = [];\n const publicKey: Uint8Array[] = [];\n let ok = false;\n try {\n // seedCoder.decode() returns zero-copy slices into expandedSeed and can throw before child\n // keygen() runs, so keep the raw expanded buffer separate and copy each child seed before any\n // later cleanup wipes the shared backing bytes.\n for (const part of seedCoder.decode(expandedSeed)) expanded.push(copyBytes(part));\n for (let i = 0; i < ck.length; i++) {\n const keys = ck[i].keygen(expanded[i]);\n keySecret.push(keys.secretKey);\n secretKey.push(copyBytes(keys.secretKey));\n publicKey.push(keys.publicKey);\n }\n ok = true;\n return { secretKey, publicKey } as TRet<{\n secretKey: Uint8Array[];\n publicKey: Uint8Array[];\n }>;\n } finally {\n // Child keygen() can throw after deriving only a prefix of the composite key schedule. Keep\n // the exported copies on success, but wipe all temporary and partially built secret material\n // on either path so failures do not strand derived child seeds in memory.\n cleanBytes(expandedSeed, expanded, keySecret);\n if (!ok) cleanBytes(secretKey);\n }\n }\n return {\n info: { lengths: { seed: realSeedLen, publicKey: pkCoder.bytesLen, secretKey: realSeedLen } },\n getPublicKey(secretKey: TArg<Uint8Array>) {\n // Composite secret keys are root seeds, so public-key derivation reruns key expansion from\n // that seed instead of decoding a packed child-secret-key structure.\n return this.keygen(secretKey).publicKey as TRet<Uint8Array>;\n },\n keygen(seed: TArg<Uint8Array> = randomBytes(realSeedLen)) {\n const { publicKey: pk, secretKey } = expandDecapsulationKey(seed);\n try {\n const publicKey = pkCoder.encode(pk) as TRet<Uint8Array>;\n return { secretKey: seed as TRet<Uint8Array>, publicKey };\n } finally {\n cleanBytes(pk);\n // The exported secretKey is the caller/root seed itself; child secret keys are internal\n // expansion outputs that are cleaned whether encoding succeeds or throws.\n cleanBytes(secretKey);\n }\n },\n expandDecapsulationKey,\n realSeedLen,\n };\n}\n\n// This generic function that combines multiple KEMs into single one\n/**\n * Combines multiple KEMs into one composite KEM.\n * @param realSeedLen - Input seed length expected by `expandSeed`.\n * @param realMsgLen - Shared-secret length returned by `combiner`.\n * @param expandSeed - Seed expander used to derive per-KEM seeds.\n * @param combiner - Combines the per-KEM outputs into one shared secret.\n * @param kems - KEM implementations to combine.\n * @returns Composite KEM.\n * @example\n * Combine multiple KEMs into one composite KEM.\n * ```ts\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { combineKEMS, expandSeedXof } from '@noble/post-quantum/hybrid.js';\n * import { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n * const hybrid = combineKEMS(\n * 32,\n * 32,\n * expandSeedXof(shake256),\n * (_pk, _ct, sharedSecrets) => sharedSecrets[0],\n * ml_kem768,\n * ml_kem768\n * );\n * const { publicKey } = hybrid.keygen();\n * ```\n */\nexport function combineKEMS(\n realSeedLen: number | undefined, // how much bytes expandSeed expects\n realMsgLen: number | undefined, // how much bytes combiner returns\n expandSeed: TArg<ExpandSeed>,\n combiner: TArg<Combiner>,\n ...kems: TArg<KEM[]>\n): TRet<KEM> {\n const rawCombiner = combiner as Combiner;\n const rawKems = kems as KEM[];\n const keys = combineKeys(realSeedLen, expandSeed, ...rawKems);\n const ctCoder = splitLengths(rawKems, 'cipherText');\n const pkCoder = splitLengths(rawKems, 'publicKey');\n const msgCoder = splitLengths(rawKems, 'msg');\n if (realMsgLen === undefined) realMsgLen = msgCoder.bytesLen;\n anumber(realMsgLen);\n const lengths = Object.freeze({\n ...keys.info.lengths,\n msg: realMsgLen,\n msgRand: msgCoder.bytesLen,\n cipherText: ctCoder.bytesLen,\n });\n return Object.freeze({\n lengths,\n getPublicKey: keys.getPublicKey,\n keygen: keys.keygen,\n encapsulate(\n pk: TArg<Uint8Array>,\n randomness: TArg<Uint8Array> = randomBytes(msgCoder.bytesLen)\n ) {\n const pks = pkCoder.decode(pk);\n const rand = msgCoder.decode(randomness);\n const sharedSecret: Uint8Array[] = [];\n const cipherText: Uint8Array[] = [];\n try {\n for (let i = 0; i < rawKems.length; i++) {\n const enc = rawKems[i].encapsulate(pks[i], rand[i]);\n sharedSecret.push(enc.sharedSecret);\n cipherText.push(enc.cipherText);\n }\n return {\n // Detach the combiner result before cleanup: a caller-provided combiner may alias one of\n // the child sharedSecret buffers, and those child buffers are zeroized immediately below.\n sharedSecret: copyBytes(rawCombiner(pks, cipherText, sharedSecret)),\n cipherText: ctCoder.encode(cipherText) as TRet<Uint8Array>,\n };\n } finally {\n // Child encapsulation or combiner failures can happen after some components already\n // returned secret material; zeroize whatever was produced before propagating the error.\n cleanBytes(sharedSecret, cipherText);\n }\n },\n decapsulate(ct: TArg<Uint8Array>, seed: TArg<Uint8Array>) {\n const cts = ctCoder.decode(ct);\n const { publicKey, secretKey } = keys.expandDecapsulationKey(seed);\n const sharedSecret = rawKems.map((i, j) => i.decapsulate(cts[j], secretKey[j]));\n try {\n // Detach the decapsulation result before cleanup: the combiner may hand back one of the\n // child shared-secret buffers, and those temporary buffers are zeroized below.\n return copyBytes(rawCombiner(publicKey, cts, sharedSecret));\n } finally {\n // Decapsulation only needs the expanded child secret keys and child shared secrets for this\n // call; keep the caller/root seed intact, but wipe all derived material even on errors.\n cleanBytes(secretKey, sharedSecret);\n }\n },\n });\n}\n// There is no specs for this, but can be useful\n// realSeedLen: how much bytes expandSeed expects.\n/**\n * Combines multiple signers into one composite signer.\n * @param realSeedLen - Input seed length expected by `expandSeed`.\n * @param expandSeed - Seed expander used to derive per-signer seeds.\n * @param signers - Signers to combine.\n * @returns Composite signer.\n * @example\n * Combine multiple signers into one composite signer.\n * ```ts\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { combineSigners, expandSeedXof } from '@noble/post-quantum/hybrid.js';\n * import { ml_dsa44 } from '@noble/post-quantum/ml-dsa.js';\n * const hybrid = combineSigners(32, expandSeedXof(shake256), ml_dsa44, ml_dsa44);\n * const { publicKey } = hybrid.keygen();\n * ```\n */\nexport function combineSigners(\n realSeedLen: number | undefined,\n expandSeed: TArg<ExpandSeed>,\n ...signers: TArg<Signer[]>\n): TRet<Signer> {\n const rawSigners = signers as Signer[];\n const keys = combineKeys(realSeedLen, expandSeed, ...rawSigners);\n const sigCoder = splitLengths(rawSigners, 'signature');\n const pkCoder = splitLengths(rawSigners, 'publicKey');\n return {\n lengths: { ...keys.info.lengths, signature: sigCoder.bytesLen, signRand: 0 },\n getPublicKey: keys.getPublicKey,\n keygen: keys.keygen,\n sign(message, seed, opts = {}) {\n validateSigOpts(opts);\n // This generic wrapper intentionally keeps the composite signer contract to message + root\n // seed only. Per-signer opts like context or extraEntropy cannot be preserved uniformly\n // across mixed backends, so callers that need them must use the underlying signer directly.\n if (opts.extraEntropy !== undefined)\n throw new Error(\n 'combineSigners does not support extraEntropy; use the underlying signer directly'\n );\n if (opts.context !== undefined)\n throw new Error(\n 'combineSigners does not support context; use the underlying signer directly'\n );\n const { secretKey } = keys.expandDecapsulationKey(seed);\n try {\n const sigs = rawSigners.map((i, j) => i.sign(message, secretKey[j]));\n return sigCoder.encode(sigs) as TRet<Uint8Array>;\n } finally {\n // Composite secret keys are root seeds; the per-signer child secret keys are temporary\n // expansion outputs and must not stay live after the combined signature is produced.\n cleanBytes(secretKey);\n }\n },\n /** Verify one combined signature.\n * Returns `false` when the aggregate signature/publicKey decode succeeds but any child verify\n * check fails. Throws on unsupported generic opts or malformed aggregate encodings.\n */\n verify: (signature, message, publicKey, opts = {}) => {\n validateVerOpts(opts);\n if (opts.context !== undefined)\n throw new Error(\n 'combineSigners does not support context; use the underlying signer directly'\n );\n const pks = pkCoder.decode(publicKey);\n const sigs = sigCoder.decode(signature);\n for (let i = 0; i < rawSigners.length; i++) {\n if (!rawSigners[i].verify(sigs[i], message, pks[i])) return false;\n }\n return true;\n },\n };\n}\n\n/**\n * Builds a QSF hybrid KEM preset from a PQ KEM and an elliptic-curve KEM.\n * The combined shared-secret length follows `kdf.outputLen`; the built-in presets use 32-byte\n * SHA3-256 output, while custom `kdf` choices inherit their own digest size.\n * Its combiner hashes `ss0 || ss1 || ct1 || pk1 || label`, not the full\n * `(c1, c2, ek1, ek2)` example input shape from SP 800-227 equation (15).\n * Labels are encoded with `asciiToBytes()`, so non-ASCII labels are rejected.\n * @param label - Domain-separation label.\n * @param pqc - Post-quantum KEM.\n * @param curveKEM - Classical curve KEM.\n * @param xof - XOF used for seed expansion.\n * @param kdf - Hash used for the final combiner.\n * @returns Hybrid KEM.\n * @example\n * Build a QSF hybrid KEM preset from a PQ KEM and an elliptic-curve KEM.\n * ```ts\n * import { p256 } from '@noble/curves/nist.js';\n * import { sha3_256, shake256 } from '@noble/hashes/sha3.js';\n * import { QSF, ecdhKem } from '@noble/post-quantum/hybrid.js';\n * import { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n * const kem = QSF('example', ml_kem768, ecdhKem(p256, true), shake256, sha3_256);\n * const publicKeyLen = kem.lengths.publicKey;\n * ```\n */\nexport function QSF(\n label: string,\n pqc: TArg<KEM>,\n curveKEM: TArg<KEM>,\n xof: TArg<XOF>,\n kdf: CHash\n): TRet<KEM> {\n ahash(xof);\n ahash(kdf);\n return combineKEMS(\n 32,\n kdf.outputLen,\n expandSeedXof(xof),\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) =>\n kdf(concatBytes(ss[0], ss[1], ct[1], pk[1], asciiToBytes(label))),\n pqc,\n curveKEM\n );\n}\n\n/** QSF preset combining ML-KEM-768 with P-256. */\nexport const QSF_ml_kem768_p256: TRet<KEM> = /* @__PURE__ */ (() =>\n QSF(\n 'QSF-KEM(ML-KEM-768,P-256)-XOF(SHAKE256)-KDF(SHA3-256)',\n ml_kem768,\n ecdhKem(p256, true),\n shake256,\n sha3_256\n ))();\n/** QSF preset combining ML-KEM-1024 with P-384. */\nexport const QSF_ml_kem1024_p384: TRet<KEM> = /* @__PURE__ */ (() =>\n QSF(\n 'QSF-KEM(ML-KEM-1024,P-384)-XOF(SHAKE256)-KDF(SHA3-256)',\n ml_kem1024,\n ecdhKem(p384, true),\n shake256,\n sha3_256\n ))();\n\n/**\n * Builds the \"KitchenSink\" hybrid KEM combiner.\n * The current builder always derives a fixed 32-byte output,\n * regardless of the hash's native output size.\n * Its HKDF extract step uses implicit zero salt with IKM\n * `hybrid_prk || ss0 || ss1 || ct0 || pk0 || ct1 || pk1 || label`.\n * Its HKDF expand step fixes `info` to `len || 'shared_secret' || ''`.\n * Labels are encoded with `asciiToBytes()`, so non-ASCII labels are rejected.\n * @param label - Domain-separation label.\n * @param pqc - Post-quantum KEM.\n * @param curveKEM - Classical curve KEM.\n * @param xof - XOF used for seed expansion.\n * @param hash - Hash used for HKDF extraction and expansion.\n * @returns Hybrid KEM.\n * @example\n * Build the \"KitchenSink\" hybrid KEM combiner.\n * ```ts\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { shake256 } from '@noble/hashes/sha3.js';\n * import { createKitchenSink, ecdhKem } from '@noble/post-quantum/hybrid.js';\n * import { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n * import { x25519 } from '@noble/curves/ed25519.js';\n * const kem = createKitchenSink('example', ml_kem768, ecdhKem(x25519), shake256, sha256);\n * const publicKeyLen = kem.lengths.publicKey;\n * ```\n */\nexport function createKitchenSink(\n label: string,\n pqc: TArg<KEM>,\n curveKEM: TArg<KEM>,\n xof: TArg<XOF>,\n hash: CHash\n): TRet<KEM> {\n ahash(xof);\n ahash(hash);\n return combineKEMS(\n 32,\n 32,\n expandSeedXof(xof),\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) => {\n const preimage = concatBytes(ss[0], ss[1], ct[0], pk[0], ct[1], pk[1], asciiToBytes(label));\n const len = 32;\n const ikm = concatBytes(asciiToBytes('hybrid_prk'), preimage);\n const prk = extract(hash, ikm);\n const info = concatBytes(\n numberToBytesBE(len, 2),\n asciiToBytes('shared_secret'),\n asciiToBytes('')\n );\n const res = expand(hash, prk, info, len);\n cleanBytes(prk, info, ikm, preimage);\n return res;\n },\n pqc,\n curveKEM\n );\n}\n\n// Internal alias only: this stays exactly `ecdhKem(x25519)`\n// and inherits that wrapper's mutation/oracle behavior.\nconst x25519kem = /* @__PURE__ */ ecdhKem(x25519);\n/** KitchenSink preset combining ML-KEM-768 with X25519.\n * Caller randomness splits into 32 ML-KEM coins plus a 32-byte X25519 ephemeral-secret seed.\n */\nexport const KitchenSink_ml_kem768_x25519: TRet<KEM> = /* @__PURE__ */ (() =>\n createKitchenSink(\n 'KitchenSink-KEM(ML-KEM-768,X25519)-XOF(SHAKE256)-KDF(HKDF-SHA-256)',\n ml_kem768,\n x25519kem,\n shake256,\n sha256\n ))();\n\n// Always X25519 and ML-KEM - 768, no point to export\n/** X25519 + ML-KEM-768 hybrid preset.\n * Uses the hard-coded domain-separation label `\\\\.//^\\\\` and hashes only `ct1 || pk1`\n * from the X25519 side in addition to the two component shared secrets.\n */\nexport const ml_kem768_x25519: TRet<KEM> = /* @__PURE__ */ (() =>\n combineKEMS(\n 32,\n 32,\n expandSeedXof(shake256),\n // Awesome label, so much escaping hell in a single line.\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) =>\n sha3_256(concatBytes(ss[0], ss[1], ct[1], pk[1], asciiToBytes('\\\\.//^\\\\'))),\n ml_kem768,\n x25519kem\n ))();\n\n/**\n * Internal SEC 1-style KEM wrapper for NIST curves.\n * `nseed` is only the rejection-sampling byte budget for deriving one nonzero scalar:\n * current presets use `128` bytes for P-256 and `48` bytes for P-384.\n * `decapsulate()` returns the uncompressed shared point body `x || y` without the `0x04`\n * prefix, not the SEC 1 `x_P`-only primitive output, because current hybrid combiners hash\n * both coordinates.\n */\nfunction nistCurveKem(curve: ECDSA, scalarLen: number, elemLen: number, nseed: number): TRet<KEM> {\n const Fn = curve.Point.Fn;\n if (!Fn) throw new Error('no Point.Fn');\n // Scan scalar-sized windows until one decodes to a nonzero scalar in `[1, n-1]`; if every\n // window is zero or out of range, fail instead of silently reducing modulo `n`.\n function rejectionSampling(seed: TArg<Uint8Array>): TRet<{\n secretKey: Uint8Array;\n publicKey: Uint8Array;\n }> {\n let sk: bigint;\n for (let start = 0, end = scalarLen; ; start = end, end += scalarLen) {\n if (end > seed.length) throw new Error('rejection sampling failed');\n sk = Fn.fromBytes(seed.subarray(start, end), true);\n if (Fn.isValidNot0(sk)) break;\n }\n const secretKey = Fn.toBytes(Fn.create(sk));\n const publicKey = curve.getPublicKey(secretKey, false);\n return { secretKey, publicKey } as TRet<{\n secretKey: Uint8Array;\n publicKey: Uint8Array;\n }>;\n }\n\n return {\n lengths: {\n secretKey: scalarLen,\n publicKey: elemLen,\n seed: nseed,\n msg: nseed,\n cipherText: elemLen,\n },\n keygen(seed: TArg<Uint8Array> = randomBytes(nseed)) {\n abytes(seed, nseed, 'seed');\n return rejectionSampling(seed);\n },\n getPublicKey(secretKey: TArg<Uint8Array>) {\n return curve.getPublicKey(secretKey, false) as TRet<Uint8Array>;\n },\n encapsulate(publicKey: TArg<Uint8Array>, rand: TArg<Uint8Array> = randomBytes(nseed)) {\n abytes(rand, nseed, 'rand');\n let ek: Uint8Array | undefined = undefined;\n try {\n ek = rejectionSampling(rand).secretKey;\n const sharedSecret = this.decapsulate(publicKey, ek);\n const cipherText = curve.getPublicKey(ek, false) as TRet<Uint8Array>;\n return { sharedSecret, cipherText };\n } finally {\n // Rejection-sampled NIST-curve ephemeral secret keys are temporary encapsulation state and\n // must be wiped even if peer-key validation or shared-secret derivation throws.\n if (ek) cleanBytes(ek);\n }\n },\n decapsulate(cipherText: TArg<Uint8Array>, secretKey: TArg<Uint8Array>) {\n const full = curve.getSharedSecret(secretKey, cipherText);\n return full.subarray(1) as TRet<Uint8Array>;\n },\n };\n}\n\n/**\n * Internal ML-KEM + NIST-curve combiner.\n * `nseed` controls only the curve-side rejection-sampling budget; it is expanded from the\n * 32-byte root seed and is not itself part of the exported secret-key length.\n * The domain-separation `label` is used only in the final `sha3_256` combiner, not in\n * `shake256(seed, { dkLen: 64 + nseed })`,\n * and the combiner hashes `ss0 || ss1 || ct1 || pk1 || label`.\n */\nfunction concreteHybridKem(\n label: string,\n mlkem: TArg<KEM>,\n curve: ECDSA,\n nseed: number\n): TRet<KEM> {\n const { secretKey: scalarLen, publicKeyUncompressed: elemLen } = curve.lengths;\n if (!scalarLen || !elemLen) throw new Error('wrong curve');\n const curveKem = nistCurveKem(curve, scalarLen, elemLen, nseed);\n const mlkemSeedLen = 64;\n const totalSeedLen = mlkemSeedLen + nseed;\n\n return combineKEMS(\n 32,\n 32,\n (seed: TArg<Uint8Array>): TRet<Uint8Array> => {\n abytes(seed, 32);\n const expanded = shake256(seed, { dkLen: totalSeedLen });\n const mlkemSeed = expanded.subarray(0, mlkemSeedLen);\n const curveSeed = expanded.subarray(mlkemSeedLen, totalSeedLen);\n return concatBytes(mlkemSeed, curveSeed) as TRet<Uint8Array>;\n },\n (pk: TArg<Uint8Array[]>, ct: TArg<Uint8Array[]>, ss: TArg<Uint8Array[]>) =>\n sha3_256(concatBytes(ss[0], ss[1], ct[1], pk[1], asciiToBytes(label))),\n mlkem,\n curveKem\n );\n}\n\n/** P-256 + ML-KEM-768 hybrid preset. */\nexport const ml_kem768_p256: TRet<KEM> = /* @__PURE__ */ (() =>\n concreteHybridKem('MLKEM768-P256', ml_kem768, p256, 128))();\n\n/** P-384 + ML-KEM-1024 hybrid preset. */\nexport const ml_kem1024_p384: TRet<KEM> = /* @__PURE__ */ (() =>\n concreteHybridKem('MLKEM1024-P384', ml_kem1024, p384, 48))();\n\n// Legacy aliases\n/** Legacy alias for `ml_kem768_x25519`. */\nexport const XWing: TRet<KEM> = /* @__PURE__ */ (() => ml_kem768_x25519)();\n/** Legacy alias for `ml_kem768_x25519`. */\nexport const MLKEM768X25519: TRet<KEM> = /* @__PURE__ */ (() => ml_kem768_x25519)();\n/** Legacy alias for `ml_kem768_p256`. */\nexport const MLKEM768P256: TRet<KEM> = /* @__PURE__ */ (() => ml_kem768_p256)();\n/** Legacy alias for `ml_kem1024_p384`. */\nexport const MLKEM1024P384: TRet<KEM> = /* @__PURE__ */ (() => ml_kem1024_p384)();\n/** Legacy alias for `QSF_ml_kem768_p256`. */\nexport const QSFMLKEM768P256: TRet<KEM> = /* @__PURE__ */ (() => QSF_ml_kem768_p256)();\n/** Legacy alias for `QSF_ml_kem1024_p384`. */\nexport const QSFMLKEM1024P384: TRet<KEM> = /* @__PURE__ */ (() => QSF_ml_kem1024_p384)();\n/** Legacy alias for `KitchenSink_ml_kem768_x25519`. */\nexport const KitchenSinkMLKEM768X25519: TRet<KEM> = /* @__PURE__ */ (() =>\n KitchenSink_ml_kem768_x25519)();\n","import { chacha20poly1305 } from '@noble/ciphers/chacha.js';\n\nimport { AeadVerificationError } from './errors';\n\nexport interface ChaCha20Poly1305EncryptOpts {\n readonly key: Uint8Array;\n readonly nonce: Uint8Array;\n readonly aad: Uint8Array;\n readonly plaintext: Uint8Array;\n}\n\nexport interface ChaCha20Poly1305DecryptOpts {\n readonly key: Uint8Array;\n readonly nonce: Uint8Array;\n readonly aad: Uint8Array;\n readonly ciphertext: Uint8Array;\n}\n\nexport function chacha20Poly1305Encrypt(opts: ChaCha20Poly1305EncryptOpts): Uint8Array {\n return chacha20poly1305(opts.key, opts.nonce, opts.aad).encrypt(opts.plaintext);\n}\n\nexport function chacha20Poly1305Decrypt(opts: ChaCha20Poly1305DecryptOpts): Uint8Array {\n try {\n return chacha20poly1305(opts.key, opts.nonce, opts.aad).decrypt(opts.ciphertext);\n } catch (cause) {\n throw new AeadVerificationError('chacha20-poly1305 decrypt failed', { cause });\n }\n}\n","import { XWing } from '@noble/post-quantum/hybrid.js';\n\n// X-Wing (ML-KEM-768 + X25519) hybrid KEM per draft-connolly-cfrg-xwing-kem-10.\n// `XWing` is @noble/post-quantum's alias for `ml_kem768_x25519`. We expose it\n// through opts-object wrappers that pin the wire lengths and map noble's field\n// names onto the project's vocabulary.\n//\n// Unlike the bare X25519 KEM, there is no contributory-behaviour rejection to\n// translate: X-Wing combines the ML-KEM and X25519 shared secrets through a\n// SHA3-256 combiner that also binds the X25519 ephemeral and recipient public\n// keys, and ML-KEM's implicit rejection already yields a constant-work\n// pseudorandom secret on a malformed ciphertext. Decapsulation therefore never\n// throws on attacker-supplied wire data — a wrong shared secret is the correct,\n// indistinguishable failure mode, and callers MUST treat it as a non-match\n// rather than expecting an exception.\n\nexport const MLKEM768X25519_PUBLIC_KEY_LENGTH = 1216 as const;\nexport const MLKEM768X25519_ENC_LENGTH = 1120 as const;\nexport const MLKEM768X25519_SHARED_SECRET_LENGTH = 32 as const;\nexport const MLKEM768X25519_SEED_LENGTH = 32 as const;\nexport const MLKEM768X25519_ESEED_LENGTH = 64 as const;\n\nexport interface Mlkem768X25519KeyPair {\n // The 32-byte root seed IS the secret key: the ML-KEM coins and the X25519\n // scalar are re-expanded from it via SHAKE-256 at decapsulation. (Later X-Wing\n // drafts also define an optional expanded decapsulation-key form; we keep the\n // seed-only key, which the draft-10 Appendix C vectors still pin.)\n readonly secretSeed: Uint8Array;\n readonly publicKey: Uint8Array;\n}\n\nexport interface Mlkem768X25519EncapsulateOpts {\n readonly publicKey: Uint8Array;\n // Optional 64-byte encapsulation randomness (msgRand). When supplied the\n // ciphertext and shared secret are fully deterministic; a 32-byte value is\n // rejected by noble, so we pin the length here too.\n readonly eseed?: Uint8Array;\n}\n\nexport interface Mlkem768X25519Encapsulation {\n readonly enc: Uint8Array;\n readonly ss: Uint8Array;\n}\n\nexport interface Mlkem768X25519DecapsulateOpts {\n readonly secretSeed: Uint8Array;\n readonly enc: Uint8Array;\n}\n\nexport function mlkem768x25519Keygen(seed: Uint8Array): Mlkem768X25519KeyPair {\n if (seed.length !== MLKEM768X25519_SEED_LENGTH) {\n throw new Error(\n `mlkem768x25519 seed must be ${MLKEM768X25519_SEED_LENGTH} bytes, got ${seed.length}`,\n );\n }\n const { secretKey, publicKey } = XWing.keygen(seed);\n return { secretSeed: secretKey, publicKey };\n}\n\nexport function mlkem768x25519Encapsulate(\n opts: Mlkem768X25519EncapsulateOpts,\n): Mlkem768X25519Encapsulation {\n if (opts.publicKey.length !== MLKEM768X25519_PUBLIC_KEY_LENGTH) {\n throw new Error(\n `mlkem768x25519 public key must be ${MLKEM768X25519_PUBLIC_KEY_LENGTH} bytes, got ${opts.publicKey.length}`,\n );\n }\n if (opts.eseed !== undefined && opts.eseed.length !== MLKEM768X25519_ESEED_LENGTH) {\n throw new Error(\n `mlkem768x25519 eseed must be ${MLKEM768X25519_ESEED_LENGTH} bytes, got ${opts.eseed.length}`,\n );\n }\n const { cipherText, sharedSecret } = XWing.encapsulate(opts.publicKey, opts.eseed);\n return { enc: cipherText, ss: sharedSecret };\n}\n\nexport function mlkem768x25519Decapsulate(opts: Mlkem768X25519DecapsulateOpts): Uint8Array {\n // Pre-check both lengths before calling noble: decapsulation must perform a\n // constant amount of work for any caller-supplied ciphertext (implicit\n // rejection), which requires the inputs to be the exact expected sizes.\n if (opts.secretSeed.length !== MLKEM768X25519_SEED_LENGTH) {\n throw new Error(\n `mlkem768x25519 secret seed must be ${MLKEM768X25519_SEED_LENGTH} bytes, got ${opts.secretSeed.length}`,\n );\n }\n if (opts.enc.length !== MLKEM768X25519_ENC_LENGTH) {\n throw new Error(\n `mlkem768x25519 enc must be ${MLKEM768X25519_ENC_LENGTH} bytes, got ${opts.enc.length}`,\n );\n }\n // noble's signature is decapsulate(cipherText, secretKey) — ciphertext first.\n return XWing.decapsulate(opts.enc, opts.secretSeed);\n}\n","import { x25519 } from '@noble/curves/ed25519.js';\n\n// RFC 7748 §6.1 contributory-behaviour rejection: a small-order (low-order)\n// Montgomery `u` coordinate makes the X25519 shared secret all-zero, which\n// @noble/curves refuses with `Error: invalid private or public key received`.\n// We rethrow that as a *typed* error so callers can distinguish a structurally\n// valid-but-malicious peer public key (a property of attacker-supplied wire\n// data — trial-decrypt MUST treat the slot as a non-match, not crash) from\n// genuine caller misuse such as a wrong-length key (which @noble raises as a\n// RangeError and which we deliberately let propagate untouched).\nexport class X25519LowOrderPointError extends Error {\n readonly code = 'X25519_LOW_ORDER_POINT' as const;\n constructor(options?: { cause?: unknown }) {\n super('x25519 ECDH rejected: peer public key is a small-order point', options);\n this.name = 'X25519LowOrderPointError';\n }\n}\n\n// @noble/curves v2 signals a small-order/all-zero shared secret with this exact\n// message. Matching on it (rather than the broad Error class) keeps unrelated\n// failures — e.g. a future internal assertion — surfacing as themselves.\nconst NOBLE_LOW_ORDER_MESSAGE = 'invalid private or public key received';\n\nexport interface X25519KeyPair {\n readonly secretKey: Uint8Array;\n readonly publicKey: Uint8Array;\n}\n\nexport interface X25519PublicKeyOpts {\n readonly secretKey: Uint8Array;\n}\n\nexport interface X25519EcdhOpts {\n readonly secretKey: Uint8Array;\n readonly theirPublicKey: Uint8Array;\n}\n\nexport function x25519Keygen(): X25519KeyPair {\n return x25519.keygen();\n}\n\nexport function x25519PublicKey(opts: X25519PublicKeyOpts): Uint8Array {\n return x25519.getPublicKey(opts.secretKey);\n}\n\nexport function x25519Ecdh(opts: X25519EcdhOpts): Uint8Array {\n try {\n return x25519.getSharedSecret(opts.secretKey, opts.theirPublicKey);\n } catch (e) {\n // Translate ONLY the contributory-check rejection into our typed error.\n // A wrong-length key throws a RangeError from @noble's length assertion;\n // that is caller misuse, not malicious wire data, so it must propagate.\n if (e instanceof Error && e.message === NOBLE_LOW_ORDER_MESSAGE) {\n throw new X25519LowOrderPointError({ cause: e });\n }\n throw e;\n }\n}\n","import { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nexport interface HkdfSha256Opts {\n readonly ikm: Uint8Array;\n readonly salt: Uint8Array;\n readonly info: Uint8Array;\n readonly length: number;\n}\n\nexport function hkdfSha256(opts: HkdfSha256Opts): Uint8Array {\n return hkdf(sha256, opts.ikm, opts.salt, opts.info, opts.length);\n}\n","// Sealed-PoE construction error taxonomy (wire-shape + partitioning-oracle\n// pre-checks + caller-input validation).\n//\n// Codes whose concept exists in the wire error-code registry reuse the registry\n// string verbatim (UNSUPPORTED_ENVELOPE_SCHEME, UNSUPPORTED_AEAD_ALG,\n// ENC_PASSPHRASE_EMPTY, ...), so a consumer correlating construction failures\n// with validator/verifier reports sees one vocabulary. Conditions that exist\n// only at the construction API boundary (raw caller-input lengths, deterministic\n// test-override mismatches) carry construction-local names with no wire\n// counterpart.\n\nexport type EciesSealedPoeErrorCode =\n // Wire-registry codes (same concept, same string).\n | 'ENC_SLOTS_EMPTY'\n | 'ENC_SLOTS_MAC_INVALID_LENGTH'\n | 'ENC_SLOTS_DUPLICATE_KEM_MATERIAL'\n | 'ENC_SLOTS_TOO_MANY'\n | 'ENC_ENVELOPE_TOO_LARGE'\n | 'ENC_REQUIRES_CONTENT_HASH'\n | 'ENC_PASSPHRASE_EMPTY'\n | 'ENC_PASSPHRASE_UNNORMALIZABLE'\n | 'ENC_PASSPHRASE_ALG_UNSUPPORTED'\n | 'ENC_PASSPHRASE_SALT_TOO_SHORT'\n | 'ENC_PASSPHRASE_SALT_TOO_LONG'\n | 'ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW'\n | 'KEM_EPK_LENGTH_MISMATCH'\n | 'KEM_CT_LENGTH_MISMATCH'\n | 'NONCE_LENGTH_MISMATCH'\n | 'WRAP_LENGTH_MISMATCH'\n | 'UNSUPPORTED_ENVELOPE_SCHEME'\n | 'UNSUPPORTED_AEAD_ALG'\n | 'UNSUPPORTED_KEM_ALG'\n | 'KDF_DERIVATION_FAILED'\n // Construction-local codes (no wire counterpart).\n | 'INVALID_CEK_LENGTH'\n | 'INVALID_EPHEMERAL_SECRET_LENGTH'\n | 'EPHEMERAL_SECRETS_COUNT_MISMATCH'\n | 'INVALID_RECIPIENT_KEY'\n | 'INVALID_PASSPHRASE_PARAMS'\n | 'PASSPHRASE_INPUT_TOO_LONG';\n\nexport class EciesSealedPoeError extends Error {\n readonly code: EciesSealedPoeErrorCode;\n\n constructor(code: EciesSealedPoeErrorCode, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'EciesSealedPoeError';\n this.code = code;\n }\n}\n","// chacha20-poly1305-stream64k: the segmented STREAM content format for sealed\n// PoE (the age v1 STREAM layout).\n//\n// cipher : ChaCha20-Poly1305 (RFC 8439; 12-byte nonce, 16-byte tag)\n// chunk size : 65536 plaintext bytes per non-final chunk\n// chunk nonce : uint88_be(counter) || final_flag — counter starts at 0,\n// +1 per chunk; final_flag is 0x01 on the final chunk,\n// 0x00 otherwise\n// per-chunk AAD : empty (all context binds transitively through the\n// payload_key, whose CEK is committed by slots_mac or the\n// passphrase commitment header)\n// final chunk : 0..65536 plaintext bytes; zero-length only when the whole\n// plaintext is empty (an empty plaintext is exactly one\n// zero-length final chunk — a lone 16-byte tag)\n//\n// The counter nonces are safe because the payload_key is single-use (a fresh\n// CEK salted by the envelope-unique enc.nonce), so no two streams ever share a\n// (key, nonce) pair. The final flag domain-separates the last chunk, which is\n// what makes truncation detectable.\n//\n// Layout violations — a tag failure, a truncated stream, data after the final\n// chunk, a non-final chunk shorter than CHUNK_SIZE, a zero-length final chunk\n// on a non-empty stream — all surface as StreamTamperedError; the caller maps\n// it to the single generic decryption failure. Each chunk's tag is verified\n// before that chunk's plaintext is released, but the whole-plaintext hash\n// recheck is post-hoc: incremental consumers MUST treat released bytes as\n// tentative until it passes.\n\nimport { chacha20Poly1305Decrypt, chacha20Poly1305Encrypt } from '../aead/chacha20-poly1305';\nimport { AeadVerificationError } from '../aead/errors';\n\n// Pinned format constants. The 88-bit counter admits at most 2^88 chunks, far\n// above any realisable payload, so the format imposes no cryptographic payload\n// ceiling — the practical maximum is a deployment denial-of-service policy, not\n// a wire constant.\nexport const CHUNK_SIZE = 65536;\nexport const TAG_SIZE = 16;\n\nconst NONCE_LENGTH = 12;\nconst COUNTER_LENGTH = 11;\nconst SEALED_CHUNK_SIZE = CHUNK_SIZE + TAG_SIZE;\nconst PAYLOAD_KEY_LENGTH = 32;\nconst EMPTY_AAD: Uint8Array = new Uint8Array(0);\n\n// Authenticated-decryption failure of the stream: a chunk tag did not verify or\n// the chunk layout violates the format rules. Callers surface it as the single\n// generic decryption failure (the TAMPERED_CIPHERTEXT outcome).\nexport class StreamTamperedError extends Error {\n readonly code = 'TAMPERED_CIPHERTEXT' as const;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'StreamTamperedError';\n }\n}\n\n// Shared chunk-nonce state machine: an 11-byte big-endian counter followed by\n// the final-flag byte. The counter increments once per chunk; using a chunk\n// machine after its final chunk is a caller error, never silently accepted.\nclass ChunkNonce {\n private readonly nonce = new Uint8Array(NONCE_LENGTH);\n private finished = false;\n\n next(final: boolean): Uint8Array {\n if (this.finished) {\n throw new Error('STREAM: no chunks may follow the final chunk');\n }\n if (final) {\n this.finished = true;\n this.nonce[COUNTER_LENGTH] = 0x01;\n }\n const out = this.nonce.slice();\n this.increment();\n return out;\n }\n\n get done(): boolean {\n return this.finished;\n }\n\n private increment(): void {\n for (let i = COUNTER_LENGTH - 1; i >= 0; i--) {\n const v = ((this.nonce[i] as number) + 1) & 0xff;\n this.nonce[i] = v;\n if (v !== 0) return;\n }\n // 2^88 chunks exhausted — unreachable for any realisable payload.\n throw new Error('STREAM: chunk counter overflow');\n }\n}\n\n// Predict the sealed length of a STREAM payload from its plaintext length,\n// without sealing anything. The STREAM layout adds one 16-byte tag per chunk and\n// splits the plaintext into CHUNK_SIZE-byte chunks; an empty plaintext is still\n// exactly one (zero-length) final chunk, so the chunk count has a floor of 1.\n// This is the exact inverse of `streamSeal`'s output length\n// (`plaintext.length + chunkCount * TAG_SIZE`) and lets a producer quote the\n// uploaded ciphertext size before the random CEK exists. `plaintextLength` MUST\n// be a non-negative integer.\nexport function streamSealedLength(plaintextLength: number): number {\n if (!Number.isInteger(plaintextLength) || plaintextLength < 0) {\n throw new Error(\n `STREAM: plaintextLength MUST be a non-negative integer, got ${plaintextLength}`,\n );\n }\n const chunkCount = Math.max(1, Math.ceil(plaintextLength / CHUNK_SIZE));\n return plaintextLength + chunkCount * TAG_SIZE;\n}\n\nfunction assertPayloadKey(payloadKey: Uint8Array): void {\n if (payloadKey.length !== PAYLOAD_KEY_LENGTH) {\n throw new Error(\n `STREAM: payloadKey MUST be exactly ${PAYLOAD_KEY_LENGTH} bytes, got ${payloadKey.length}`,\n );\n }\n}\n\n// Incremental sealer. Feed plaintext chunk by chunk: every non-final chunk MUST\n// be exactly CHUNK_SIZE bytes; the final chunk carries 0..CHUNK_SIZE bytes, and\n// a zero-length final chunk is admissible only as the sole chunk of an empty\n// plaintext.\nexport class StreamSealer {\n private readonly payloadKey: Uint8Array;\n private readonly nonce = new ChunkNonce();\n private chunkIndex = 0;\n\n constructor(payloadKey: Uint8Array) {\n assertPayloadKey(payloadKey);\n this.payloadKey = payloadKey;\n }\n\n sealChunk(plaintext: Uint8Array, final: boolean): Uint8Array {\n if (!final && plaintext.length !== CHUNK_SIZE) {\n throw new Error(\n `STREAM: non-final chunk MUST carry exactly ${CHUNK_SIZE} plaintext bytes, got ${plaintext.length}`,\n );\n }\n if (final && plaintext.length > CHUNK_SIZE) {\n throw new Error(\n `STREAM: final chunk MUST carry at most ${CHUNK_SIZE} plaintext bytes, got ${plaintext.length}`,\n );\n }\n if (final && plaintext.length === 0 && this.chunkIndex > 0) {\n throw new Error(\n 'STREAM: a zero-length final chunk is admissible only for an empty plaintext',\n );\n }\n const sealed = chacha20Poly1305Encrypt({\n key: this.payloadKey,\n nonce: this.nonce.next(final),\n aad: EMPTY_AAD,\n plaintext,\n });\n this.chunkIndex += 1;\n return sealed;\n }\n}\n\n// Incremental opener. Feed sealed chunks in order with the expected final flag;\n// each chunk's plaintext is released only after its tag verifies (and is still\n// tentative until the caller's whole-plaintext hash recheck passes). Chunk\n// boundaries are the caller's responsibility in incremental use; `streamOpen`\n// derives them from the blob length.\nexport class StreamOpener {\n private readonly payloadKey: Uint8Array;\n private readonly nonce = new ChunkNonce();\n private chunkIndex = 0;\n\n constructor(payloadKey: Uint8Array) {\n assertPayloadKey(payloadKey);\n this.payloadKey = payloadKey;\n }\n\n openChunk(sealedChunk: Uint8Array, final: boolean): Uint8Array {\n if (sealedChunk.length < TAG_SIZE) {\n throw new StreamTamperedError(\n `STREAM: sealed chunk shorter than the ${TAG_SIZE}-byte tag floor`,\n );\n }\n if (!final && sealedChunk.length !== SEALED_CHUNK_SIZE) {\n throw new StreamTamperedError(\n `STREAM: non-final sealed chunk MUST be exactly ${SEALED_CHUNK_SIZE} bytes, got ${sealedChunk.length}`,\n );\n }\n if (final && sealedChunk.length > SEALED_CHUNK_SIZE) {\n throw new StreamTamperedError(\n `STREAM: final sealed chunk MUST be at most ${SEALED_CHUNK_SIZE} bytes, got ${sealedChunk.length}`,\n );\n }\n if (final && sealedChunk.length === TAG_SIZE && this.chunkIndex > 0) {\n throw new StreamTamperedError('STREAM: zero-length final chunk on a non-empty stream');\n }\n let plaintext: Uint8Array;\n try {\n plaintext = chacha20Poly1305Decrypt({\n key: this.payloadKey,\n nonce: this.nonce.next(final),\n aad: EMPTY_AAD,\n ciphertext: sealedChunk,\n });\n } catch (e) {\n if (!(e instanceof AeadVerificationError)) throw e;\n throw new StreamTamperedError(`STREAM: chunk ${this.chunkIndex} tag verification failed`, {\n cause: e,\n });\n }\n this.chunkIndex += 1;\n return plaintext;\n }\n}\n\n// Whole-buffer seal: split the plaintext into CHUNK_SIZE chunks (an empty\n// plaintext is exactly one zero-length final chunk) and concatenate the sealed\n// chunks.\nexport function streamSeal(args: { payloadKey: Uint8Array; plaintext: Uint8Array }): Uint8Array {\n const { plaintext } = args;\n const sealer = new StreamSealer(args.payloadKey);\n const chunkCount = Math.max(1, Math.ceil(plaintext.length / CHUNK_SIZE));\n const out = new Uint8Array(plaintext.length + chunkCount * TAG_SIZE);\n let offset = 0;\n for (let i = 0; i < chunkCount; i++) {\n const final = i === chunkCount - 1;\n const chunk = plaintext.subarray(\n i * CHUNK_SIZE,\n Math.min((i + 1) * CHUNK_SIZE, plaintext.length),\n );\n const sealed = sealer.sealChunk(chunk, final);\n out.set(sealed, offset);\n offset += sealed.length;\n }\n return out;\n}\n\n// Whole-buffer open. The chunk boundaries are fully determined by the blob\n// length: every non-final sealed chunk is exactly SEALED_CHUNK_SIZE bytes and\n// the final sealed chunk is whatever remains (TAG_SIZE..SEALED_CHUNK_SIZE). A\n// blob below the 16-byte floor, a tail that cannot form a well-formed final\n// chunk, or a zero-length final chunk on a non-empty stream is malformed before\n// any tag is checked. Truncation that removes the final chunk leaves a stream\n// whose last chunk was sealed with the 0x00 flag but is opened with the 0x01\n// flag nonce, so its tag fails — the final-flag byte is the truncation\n// detector.\nexport function streamOpen(args: { payloadKey: Uint8Array; ciphertext: Uint8Array }): Uint8Array {\n const { ciphertext } = args;\n const total = ciphertext.length;\n if (total < TAG_SIZE) {\n throw new StreamTamperedError(\n `STREAM: ciphertext shorter than the ${TAG_SIZE}-byte single-tag floor`,\n );\n }\n const rem = total % SEALED_CHUNK_SIZE;\n let nonFinalCount: number;\n let finalSealedLength: number;\n if (rem === 0) {\n nonFinalCount = total / SEALED_CHUNK_SIZE - 1;\n finalSealedLength = SEALED_CHUNK_SIZE;\n } else if (rem >= TAG_SIZE) {\n nonFinalCount = (total - rem) / SEALED_CHUNK_SIZE;\n finalSealedLength = rem;\n } else {\n throw new StreamTamperedError('STREAM: trailing bytes cannot form a well-formed final chunk');\n }\n if (nonFinalCount > 0 && finalSealedLength === TAG_SIZE) {\n throw new StreamTamperedError('STREAM: zero-length final chunk on a non-empty stream');\n }\n\n const opener = new StreamOpener(args.payloadKey);\n const out = new Uint8Array(nonFinalCount * CHUNK_SIZE + finalSealedLength - TAG_SIZE);\n let readOffset = 0;\n let writeOffset = 0;\n for (let i = 0; i < nonFinalCount; i++) {\n const plaintext = opener.openChunk(\n ciphertext.subarray(readOffset, readOffset + SEALED_CHUNK_SIZE),\n false,\n );\n out.set(plaintext, writeOffset);\n readOffset += SEALED_CHUNK_SIZE;\n writeOffset += CHUNK_SIZE;\n }\n const finalPlaintext = opener.openChunk(ciphertext.subarray(readOffset), true);\n out.set(finalPlaintext, writeOffset);\n return out;\n}\n","// Shared, byte-critical pieces of the sealed-PoE construction that the producer\n// (wrap / passphrase seal) and every verifier (unwrap, trial-decrypt,\n// passphrase open) MUST compute byte-for-byte identically:\n//\n// 1. The item-hashes digest `hashes_hash`.\n// 2. The slots transcript, its SHA-256 `slots_hash`, and the CEK-keyed\n// `slots_mac`.\n// 3. The passphrase transcript, its SHA-256 `pw_hash`, and the CEK-keyed\n// in-ciphertext `commitment`.\n// 4. The content `payload_key` derivations (both key paths).\n// 5. Both per-slot KEK HKDF salts (classical and hybrid).\n//\n// Keeping these in one module is the interop guarantee: a single divergence in\n// the canonical encoding silently yields a `slots_mac`, a commitment, or an\n// AEAD tag that another implementation cannot reproduce, with no typed error to\n// localise the fault. There is exactly one shared implementation, imported by\n// both sides.\n\nimport { hmac } from '@noble/hashes/hmac.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { encodeCanonicalCbor, type CanonicalCborValue } from '../cbor/canonical';\nimport { hkdfSha256 } from '../kdf/hkdf';\n\nimport { EciesSealedPoeError } from './errors';\nimport type { Mlkem768X25519Slot, SealedKem, X25519Slot } from './wrap';\n\n// Internal domain-separation labels. Each is exact ASCII with no terminator and\n// no length prefix; each is a fixed constant of the scheme, never serialised on\n// the wire and never registry-selectable. The byte-length invariants below keep\n// the SCREAMING_SNAKE constants in sync with the ASCII literals every conformant\n// verifier hashes against.\n\n// SHA-256 prefix for the item-hashes digest `hashes_hash`.\nexport const CARDANO_POE_ITEM_HASHES_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-item-hashes-v1',\n);\n// SHA-256 prefix for the slots-transcript hash `slots_hash`.\nexport const CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-slots-transcript-v1',\n);\n// SHA-256 prefix for the passphrase-transcript hash `pw_hash`.\nexport const CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-passphrase-transcript-v1',\n);\n// HKDF info for the slot-set MAC key.\nexport const CARDANO_POE_HKDF_INFO_SLOTS_MAC: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-slots-mac-v1',\n);\n// HKDF info for the passphrase commitment MAC key.\nexport const CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-passphrase-mac-v1',\n);\n// HKDF info for the slots-path content `payload_key`.\nexport const CARDANO_POE_HKDF_INFO_PAYLOAD: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-payload-v1',\n);\n// HKDF info for the passphrase-path content `payload_key`.\nexport const CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-payload-passphrase-v1',\n);\n// SHA-256 prefix for the classical (x25519) per-slot KEK HKDF salt.\nexport const CARDANO_POE_X25519_KEK_SALT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-x25519-kek-salt-v1',\n);\n// SHA-256 prefix for the hybrid (X-Wing) per-slot KEK HKDF salt.\nexport const CARDANO_POE_XWING_KEK_SALT_PREFIX: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-xwing-kek-salt-v1',\n);\n\nif (CARDANO_POE_ITEM_HASHES_PREFIX.length !== 26) {\n throw new Error('CARDANO_POE_ITEM_HASHES_PREFIX byte-length invariant violated (expected 26)');\n}\nif (CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX.length !== 31) {\n throw new Error(\n 'CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX byte-length invariant violated (expected 31)',\n );\n}\nif (CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX.length !== 36) {\n throw new Error(\n 'CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX byte-length invariant violated (expected 36)',\n );\n}\nif (CARDANO_POE_HKDF_INFO_SLOTS_MAC.length !== 24) {\n throw new Error('CARDANO_POE_HKDF_INFO_SLOTS_MAC byte-length invariant violated (expected 24)');\n}\nif (CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC.length !== 29) {\n throw new Error(\n 'CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC byte-length invariant violated (expected 29)',\n );\n}\nif (CARDANO_POE_HKDF_INFO_PAYLOAD.length !== 22) {\n throw new Error('CARDANO_POE_HKDF_INFO_PAYLOAD byte-length invariant violated (expected 22)');\n}\nif (CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE.length !== 33) {\n throw new Error(\n 'CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE byte-length invariant violated (expected 33)',\n );\n}\nif (CARDANO_POE_X25519_KEK_SALT_PREFIX.length !== 30) {\n throw new Error(\n 'CARDANO_POE_X25519_KEK_SALT_PREFIX byte-length invariant violated (expected 30)',\n );\n}\nif (CARDANO_POE_XWING_KEK_SALT_PREFIX.length !== 29) {\n throw new Error('CARDANO_POE_XWING_KEK_SALT_PREFIX byte-length invariant violated (expected 29)');\n}\n\n// Scheme-fixed constant pinning the passphrase normalization profile the CEK was\n// derived under. Fed into the passphrase transcript; never serialised on the\n// wire.\nexport const CARDANO_POE_PW_NORM_PROFILE = 'cardano-poe-pw-norm-v1' as const;\n\n// Verifier-side resource bounds a public parser MUST enforce BEFORE invoking any\n// KEM/AEAD primitive, so a malformed envelope cannot drive unbounded work. Both\n// are deployment-pinned reference constants (not wire fields); deployments MAY\n// tighten them. They sit far above the ~16 KiB Cardano transaction-metadata\n// ceiling that bounds honest records, so a conformant record never trips them.\n//\n// • MAX_SLOTS — the maximum slot count; an envelope with more slots is\n// rejected outright.\n// • MAX_DECODED_ENVELOPE_BYTES — a backstop on the decoded envelope's\n// aggregate byte size (nonce + slots_mac + every per-slot wire field),\n// bounding the work even before the slot-count cap would.\nexport const MAX_SLOTS = 1024;\nexport const MAX_DECODED_ENVELOPE_BYTES = 65536;\n\nconst EMPTY_SALT: Uint8Array = new Uint8Array(0);\n\n// The item's plaintext-hash claim: registered algorithm identifier → digest\n// bytes, exactly as carried in the record body. Both key paths bind this map\n// (via `hashes_hash`) into their commitment, so an envelope spliced onto an\n// item with a different hash claim is rejected before any ciphertext work.\nexport type ItemHashes = Readonly<Record<string, Uint8Array>>;\n\nfunction labelledSha256(prefix: Uint8Array, ...parts: ReadonlyArray<Uint8Array>): Uint8Array {\n let total = prefix.length;\n for (const p of parts) total += p.length;\n const message = new Uint8Array(total);\n message.set(prefix, 0);\n let offset = prefix.length;\n for (const p of parts) {\n message.set(p, offset);\n offset += p.length;\n }\n return sha256(message);\n}\n\n// SHA-256(\"cardano-poe-item-hashes-v1\" || canonicalEncode(item.hashes)).\n// The hashes map is encoded exactly as it appears in the record body\n// (registry-identifier keys → digest byte strings, canonical key order). An\n// `enc`-bearing item MUST declare at least one content hash — the ciphertext is\n// bound to the plaintext only through that digest — so an empty map is rejected\n// here, on both the producer and the verifier side.\nexport function itemHashesHash(hashes: ItemHashes): Uint8Array {\n if (Object.keys(hashes).length === 0) {\n throw new EciesSealedPoeError(\n 'ENC_REQUIRES_CONTENT_HASH',\n 'hashes MUST carry at least one content-hash entry',\n );\n }\n return labelledSha256(CARDANO_POE_ITEM_HASHES_PREFIX, encodeCanonicalCbor(hashes));\n}\n\n// SHA-256(\"cardano-poe-slots-transcript-v1\" || canonicalEncode(SLOTS_TRANSCRIPT)).\n// SLOTS_TRANSCRIPT is the closed seven-key map binding the cross-KEM header\n// fields (scheme, path, aead, kem, nonce) and the item's hash claim\n// (hashes_hash) to the on-wire slot set, so a relay that flips any header field\n// — or splices the envelope onto a different item — yields a different\n// `slots_hash` and the MAC fails. Computed ONCE per envelope and held constant\n// across the recipient trial-decrypt loop. The map keys are a SET — their wire\n// order is fixed by the canonical-encode sort, never hand-arranged here.\nexport function computeSlotsHash(args: {\n aead: string;\n kem: SealedKem;\n nonce: Uint8Array;\n slots: ReadonlyArray<X25519Slot | Mlkem768X25519Slot>;\n hashesHash: Uint8Array;\n}): Uint8Array {\n // The slot array is re-stated as explicit closed two-key maps (never the raw\n // caller objects), so an extra property on a caller's slot value can never\n // leak into the committed bytes.\n const slots: CanonicalCborValue =\n args.kem === 'x25519'\n ? (args.slots as ReadonlyArray<X25519Slot>).map((s) => ({ epk: s.epk, wrap: s.wrap }))\n : (args.slots as ReadonlyArray<Mlkem768X25519Slot>).map((s) => ({\n kem_ct: s.kem_ct,\n wrap: s.wrap,\n }));\n const transcript: CanonicalCborValue = {\n scheme: 1,\n path: 'slots',\n aead: args.aead,\n kem: args.kem,\n nonce: args.nonce,\n slots,\n hashes_hash: args.hashesHash,\n };\n return labelledSha256(CARDANO_POE_SLOTS_TRANSCRIPT_PREFIX, encodeCanonicalCbor(transcript));\n}\n\n// SHA-256(\"cardano-poe-passphrase-transcript-v1\" || canonicalEncode(PASSPHRASE_TRANSCRIPT)).\n// PASSPHRASE_TRANSCRIPT is the closed six-key map (with `passphrase` itself a\n// closed sub-map) binding the header fields, the Argon2id parameters, the\n// normalization profile, and the item's hash claim into the in-ciphertext\n// commitment. There is NO `kem` key on this path. The `normalization` value is\n// the scheme-fixed profile constant, pinned into the transcript and never\n// serialised on the wire.\nexport function computePassphraseHash(args: {\n aead: string;\n nonce: Uint8Array;\n hashesHash: Uint8Array;\n salt: Uint8Array;\n params: { m: number; t: number; p: number };\n}): Uint8Array {\n const transcript: CanonicalCborValue = {\n scheme: 1,\n path: 'passphrase',\n aead: args.aead,\n nonce: args.nonce,\n hashes_hash: args.hashesHash,\n passphrase: {\n alg: 'argon2id',\n salt: args.salt,\n params: { m: args.params.m, t: args.params.t, p: args.params.p },\n normalization: CARDANO_POE_PW_NORM_PROFILE,\n },\n };\n return labelledSha256(CARDANO_POE_PASSPHRASE_TRANSCRIPT_PREFIX, encodeCanonicalCbor(transcript));\n}\n\n// Slot-set MAC: HMAC-SHA-256 keyed by an HKDF leaf of the CEK over the 32-byte\n// `slots_hash`. Pre-hashing the transcript only changes the HMAC message from\n// the full transcript to its SHA-256, leaving the CEK-keyed commitment intact.\n// The fixed 32-byte HKDF key structurally excludes the HMAC over-block-length\n// key ambiguity.\nexport function computeSlotsMac(args: { cek: Uint8Array; slotsHash: Uint8Array }): Uint8Array {\n const macKey = hkdfSha256({\n ikm: args.cek,\n salt: EMPTY_SALT,\n info: CARDANO_POE_HKDF_INFO_SLOTS_MAC,\n length: 32,\n });\n return hmac(sha256, macKey, args.slotsHash);\n}\n\n// Passphrase-path key commitment: HMAC-SHA-256 keyed by an HKDF leaf of the CEK\n// over the 32-byte `pw_hash`. Prepended inside the ciphertext blob (never an\n// on-chain field), so testing a passphrase guess requires possession of the\n// blob itself.\nexport function computePassphraseCommitment(args: {\n cek: Uint8Array;\n pwHash: Uint8Array;\n}): Uint8Array {\n const macKey = hkdfSha256({\n ikm: args.cek,\n salt: EMPTY_SALT,\n info: CARDANO_POE_HKDF_INFO_PASSPHRASE_MAC,\n length: 32,\n });\n return hmac(sha256, macKey, args.pwHash);\n}\n\n// Slots-path content key: HKDF-SHA-256(ikm=CEK, salt=enc.nonce, info=payload-v1).\n// The content is encrypted under this leaf of the CEK, never under the CEK\n// directly, so the wrap layer and the content layer never key the same primitive\n// on the same bytes. The envelope-unique nonce salt makes the key single-use,\n// which is what keeps the STREAM counter nonces collision-free.\nexport function slotsPayloadKey(args: { cek: Uint8Array; nonce: Uint8Array }): Uint8Array {\n return hkdfSha256({\n ikm: args.cek,\n salt: args.nonce,\n info: CARDANO_POE_HKDF_INFO_PAYLOAD,\n length: 32,\n });\n}\n\n// Passphrase-path content key: HKDF-SHA-256(ikm=CEK, salt=enc.nonce,\n// info=payload-passphrase-v1).\nexport function passphrasePayloadKey(args: { cek: Uint8Array; nonce: Uint8Array }): Uint8Array {\n return hkdfSha256({\n ikm: args.cek,\n salt: args.nonce,\n info: CARDANO_POE_HKDF_INFO_PAYLOAD_PASSPHRASE,\n length: 32,\n });\n}\n\n// Classical (x25519) per-slot KEK salt:\n// SHA-256(\"cardano-poe-x25519-kek-salt-v1\" || enc.nonce || epk || pub_R).\n// The slot's own ephemeral anchors the KEK to a slot-unique value, `pub_R`\n// binds it to the specific recipient (defeating confused-deputy relay of the\n// ephemeral against a different recipient), and the envelope-unique `enc.nonce`\n// anchors it to one envelope — a CSPRNG failure that repeats KEM randomness\n// across records degrades to mere linkability instead of reproducing a\n// (KEK, zero-nonce) wrap pair.\nexport function x25519KekSalt(args: {\n nonce: Uint8Array;\n epk: Uint8Array;\n pubR: Uint8Array;\n}): Uint8Array {\n return labelledSha256(CARDANO_POE_X25519_KEK_SALT_PREFIX, args.nonce, args.epk, args.pubR);\n}\n\n// Hybrid (mlkem768x25519) per-slot KEK salt:\n// SHA-256(\"cardano-poe-xwing-kek-salt-v1\" || enc.nonce || kem_ct || pub_R).\n// `kem_ct` is the slot's 1120-byte X-Wing ciphertext exactly as carried on the\n// wire and `pub_R` the 1216-byte X-Wing recipient public key — the same three\n// bindings as the classical salt, computed outside the KEM over the slot's own\n// wire bytes so it holds X-Wing as a black box.\nexport function xwingKekSalt(args: {\n nonce: Uint8Array;\n kemCt: Uint8Array;\n pubR: Uint8Array;\n}): Uint8Array {\n return labelledSha256(CARDANO_POE_XWING_KEK_SALT_PREFIX, args.nonce, args.kemCt, args.pubR);\n}\n","// Multi-recipient sealed-PoE wrap (age-style KEM-then-wrap slots + segmented\n// STREAM content). Wire-field names are fixed by the standard: scheme, aead,\n// kem, nonce, slots, slots_mac.\n//\n// Two KEM branches share one envelope shape, discriminated on the envelope-level\n// `kem` field:\n//\n// • kem: 'x25519' — classical age-style ECIES. Per-slot epk(32) + wrap(48).\n// • kem: 'mlkem768x25519' — X-Wing hybrid (ML-KEM-768 + X25519). Per-slot the\n// 1120-byte X-Wing ciphertext as a single byte\n// string (`kem_ct`) + wrap(48). No per-slot epk.\n//\n// The slot type is a discriminated union so every consumer is forced — at compile\n// time — to branch on the KEM before touching kem-specific fields.\n\nimport { randomBytes } from '@noble/ciphers/utils.js';\n\nimport { chacha20Poly1305Encrypt } from '../aead/chacha20-poly1305';\nimport {\n mlkem768x25519Encapsulate,\n MLKEM768X25519_ENC_LENGTH,\n MLKEM768X25519_ESEED_LENGTH,\n MLKEM768X25519_PUBLIC_KEY_LENGTH,\n} from '../kem/mlkem768x25519';\nimport { x25519Ecdh, x25519PublicKey } from '../kem/x25519';\nimport { hkdfSha256 } from '../kdf/hkdf';\n\nimport { EciesSealedPoeError } from './errors';\nimport { streamSeal } from './stream';\nimport {\n computeSlotsHash,\n computeSlotsMac,\n itemHashesHash,\n slotsPayloadKey,\n x25519KekSalt,\n xwingKekSalt,\n type ItemHashes,\n} from './transcript';\n\n// The envelope-level KEM discriminator.\nexport type SealedKem = 'x25519' | 'mlkem768x25519';\n\n// The sole registered content format under enc.scheme 1: ChaCha20-Poly1305 in\n// the 64 KiB segmented STREAM layout. Producers MUST emit this identifier\n// byte-exact.\nexport const SEALED_POE_AEAD = 'chacha20-poly1305-stream64k' as const;\n\n// HKDF info strings — fixed protocol labels for KEK derivation. Each doubles as\n// the per-slot wrap AEAD AAD (never empty AAD). Byte-length invariants enforce\n// that the SCREAMING_SNAKE constants stay in sync with the ASCII literals every\n// conformant verifier hashes against.\nexport const CARDANO_POE_HKDF_INFO_KEK: Uint8Array = new TextEncoder().encode('cardano-poe-kek-v1');\n// Hybrid (X-Wing) per-slot KEK label. Distinct from the classical label so a\n// KEK derived under one KEM can never collide with the other.\nexport const CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519: Uint8Array = new TextEncoder().encode(\n 'cardano-poe-kek-mlkem768x25519-v1',\n);\n\nconst ZERO_NONCE_12: Uint8Array = new Uint8Array(12);\nconst X25519_PUBLIC_KEY_LENGTH = 32 as const;\nconst X25519_SECRET_KEY_LENGTH = 32 as const;\nconst CEK_LENGTH = 32 as const;\nconst NONCE_LENGTH = 24 as const;\nconst WRAP_LENGTH = 48 as const;\nconst SLOTS_MAC_LENGTH = 32 as const;\n\nif (CARDANO_POE_HKDF_INFO_KEK.length !== 18) {\n throw new Error('CARDANO_POE_HKDF_INFO_KEK byte-length invariant violated (expected 18)');\n}\nif (CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519.length !== 33) {\n throw new Error(\n 'CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519 byte-length invariant violated (expected 33)',\n );\n}\nif (ZERO_NONCE_12.length !== 12) {\n throw new Error('ZERO_NONCE_12 byte-length invariant violated (expected 12)');\n}\n\n// Classical per-slot wire shape: { epk: bstr(32), wrap: bstr(48) }.\nexport interface X25519Slot {\n readonly epk: Uint8Array;\n readonly wrap: Uint8Array;\n}\n\n// Hybrid per-slot wire shape: { kem_ct: bstr(1120), wrap: bstr(48) }. `kem_ct`\n// is the X-Wing ciphertext as a single byte string. There is NO per-slot epk\n// (the X25519 ephemeral is the trailing 32 bytes of kem_ct) and NO per-slot kem\n// field — the KEM identifier is hoisted to envelope scope (every slot shares it).\nexport interface Mlkem768X25519Slot {\n readonly kem_ct: Uint8Array;\n readonly wrap: Uint8Array;\n}\n\n// Sealed envelope wire shape (discriminated on `kem`).\nexport type SealedEnvelope =\n | {\n readonly scheme: 1;\n readonly aead: typeof SEALED_POE_AEAD;\n readonly kem: 'x25519';\n readonly nonce: Uint8Array;\n readonly slots: ReadonlyArray<X25519Slot>;\n readonly slots_mac: Uint8Array;\n }\n | {\n readonly scheme: 1;\n readonly aead: typeof SEALED_POE_AEAD;\n readonly kem: 'mlkem768x25519';\n readonly nonce: Uint8Array;\n readonly slots: ReadonlyArray<Mlkem768X25519Slot>;\n readonly slots_mac: Uint8Array;\n };\n\nexport interface SealedPoeOutput {\n readonly envelope: SealedEnvelope;\n readonly ciphertext: Uint8Array;\n}\n\nexport interface WrapArgs {\n readonly plaintext: Uint8Array;\n // The item's plaintext-hash claim (registered algorithm id → digest bytes).\n // Its labelled digest is bound into the slots transcript, so the on-chain\n // slots_mac match also confirms the envelope belongs to this hash claim.\n readonly hashes: ItemHashes;\n readonly recipientPublicKeys: ReadonlyArray<Uint8Array>;\n // KEM branch selector. Defaults to 'x25519' for the classical path. The\n // recipient public-key length is validated against the chosen KEM.\n readonly kem?: SealedKem;\n readonly cek?: Uint8Array;\n readonly nonce?: Uint8Array;\n // Deterministic X25519 ephemeral scalars — x25519 branch only.\n readonly ephemeralSecrets?: ReadonlyArray<Uint8Array>;\n // Deterministic X-Wing encapsulation randomness (64 bytes each) — hybrid\n // branch only. One per recipient, parallel to recipientPublicKeys.\n readonly eseeds?: ReadonlyArray<Uint8Array>;\n readonly skipShuffle?: boolean;\n}\n\n// Anonymity invariant: wire ordering MUST NOT encode \"primary\n// recipient first\". A CSPRNG-keyed Fisher-Yates shuffle uniformly permutes the\n// slot array so trial-decrypt order leaks no recipient identity. The\n// slot-set HMAC is computed AFTER this shuffle, binding the on-wire order.\n//\n// Draw an unbiased index in [0, m) from a CSPRNG uint32 via rejection sampling.\n// A plain `u32 % m` skews toward the low residues whenever `m` does not divide\n// 2^32 evenly: the values [0, 2^32 mod m) each occur one extra time. This\n// function exists purely to produce a UNIFORM permutation, so the bias — though\n// cryptographically negligible — is exactly the property we cannot tolerate.\n// We reject any draw landing in the final partial block [limit, 2^32) and\n// redraw, leaving only the residues that map uniformly onto [0, m).\n// Exported so the rejection-bound arithmetic can be asserted directly in tests\n// without relying on a flaky statistical-distribution check.\nexport function uniformIndexBelow(m: number): number {\n // 2^32 mod m, computed without overflowing the 32-bit space.\n const limit = 0x1_0000_0000 - (0x1_0000_0000 % m);\n const buf = new Uint32Array(1);\n let x: number;\n do {\n crypto.getRandomValues(buf);\n x = buf[0] as number;\n } while (x >= limit);\n return x % m;\n}\n\nfunction csprngShuffle<T>(arr: T[]): void {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = uniformIndexBelow(i + 1);\n const tmp = arr[i] as T;\n arr[i] = arr[j] as T;\n arr[j] = tmp;\n }\n}\n\n// Wrap the CEK for one classical recipient: age-style ECIES stanza with the\n// labelled-hash KEK salt binding nonce, epk, and pub_R.\nfunction wrapSlotX25519(args: {\n pubR: Uint8Array;\n privEph: Uint8Array | undefined;\n cek: Uint8Array;\n nonce: Uint8Array;\n slotIdx: number;\n}): X25519Slot {\n const privEph = args.privEph ?? randomBytes(X25519_SECRET_KEY_LENGTH);\n if (privEph.length !== X25519_SECRET_KEY_LENGTH) {\n throw new EciesSealedPoeError(\n 'INVALID_EPHEMERAL_SECRET_LENGTH',\n `ephemeralSecrets[${args.slotIdx}] MUST be exactly ${X25519_SECRET_KEY_LENGTH} bytes, got ${privEph.length}`,\n );\n }\n const epk = x25519PublicKey({ secretKey: privEph });\n const shared = x25519Ecdh({ secretKey: privEph, theirPublicKey: args.pubR });\n const kek = hkdfSha256({\n ikm: shared,\n salt: x25519KekSalt({ nonce: args.nonce, epk, pubR: args.pubR }),\n info: CARDANO_POE_HKDF_INFO_KEK,\n length: 32,\n });\n // Per-slot wrap AAD MUST be the 18-byte ASCII literal of the KEK info\n // string (never empty AAD).\n const wrap = chacha20Poly1305Encrypt({\n key: kek,\n nonce: ZERO_NONCE_12,\n aad: CARDANO_POE_HKDF_INFO_KEK,\n plaintext: args.cek,\n });\n if (wrap.length !== WRAP_LENGTH) {\n throw new Error(`internal: wrap.length=${wrap.length}, expected ${WRAP_LENGTH}`);\n }\n return { epk, wrap };\n}\n\n// Wrap the CEK for one hybrid recipient: X-Wing encapsulation → HKDF → AEAD.\n// The KEK info label doubles as the wrap AEAD AAD, mirroring the classical path.\nfunction wrapSlotMlkem768X25519(args: {\n pubR: Uint8Array;\n eseed: Uint8Array | undefined;\n cek: Uint8Array;\n nonce: Uint8Array;\n}): Mlkem768X25519Slot {\n const { enc, ss } = mlkem768x25519Encapsulate({\n publicKey: args.pubR,\n ...(args.eseed !== undefined ? { eseed: args.eseed } : {}),\n });\n if (enc.length !== MLKEM768X25519_ENC_LENGTH) {\n throw new Error(`internal: enc.length=${enc.length}, expected ${MLKEM768X25519_ENC_LENGTH}`);\n }\n // The hybrid KEK salt binds the envelope nonce, the slot's own X-Wing\n // ciphertext, and the recipient public key, mirroring the classical salt: the\n // ciphertext anchors the KEK to a slot-unique value and `pub_R` binds it to\n // the specific recipient. It is computed outside the KEM, over the slot's wire\n // bytes, so it holds X-Wing as a black-box KEM.\n const kek = hkdfSha256({\n ikm: ss,\n salt: xwingKekSalt({ nonce: args.nonce, kemCt: enc, pubR: args.pubR }),\n info: CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519,\n length: 32,\n });\n const wrap = chacha20Poly1305Encrypt({\n key: kek,\n nonce: ZERO_NONCE_12,\n aad: CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519,\n plaintext: args.cek,\n });\n if (wrap.length !== WRAP_LENGTH) {\n throw new Error(`internal: wrap.length=${wrap.length}, expected ${WRAP_LENGTH}`);\n }\n return { kem_ct: enc, wrap };\n}\n\nexport function eciesSealedPoeWrap(args: WrapArgs): SealedPoeOutput {\n const { plaintext, recipientPublicKeys } = args;\n const kem: SealedKem = args.kem ?? 'x25519';\n const n = recipientPublicKeys.length;\n\n // The hash-claim digest is computed before any KEM/AEAD work: an item without\n // a content hash cannot be sealed (the ciphertext is bound to the plaintext\n // only through that digest).\n const hashesHash = itemHashesHash(args.hashes);\n\n // There is no fixed upper bound on slot count; the producer SDK polices the\n // per-record byte budget. Only the lower bound is enforced here.\n if (n < 1) {\n throw new EciesSealedPoeError(\n 'ENC_SLOTS_EMPTY',\n `recipientPublicKeys.length=${n} must be >= 1`,\n );\n }\n\n const expectedPubLen =\n kem === 'x25519' ? X25519_PUBLIC_KEY_LENGTH : MLKEM768X25519_PUBLIC_KEY_LENGTH;\n for (let i = 0; i < n; i++) {\n const pub = recipientPublicKeys[i];\n if (pub === undefined || pub.length !== expectedPubLen) {\n throw new EciesSealedPoeError(\n 'KEM_EPK_LENGTH_MISMATCH',\n `recipientPublicKeys[${i}] MUST be exactly ${expectedPubLen} bytes for kem='${kem}'`,\n );\n }\n }\n\n if (kem === 'x25519') {\n if (args.eseeds !== undefined) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n \"eseeds is an X-Wing (mlkem768x25519) override and MUST NOT be supplied for kem='x25519'\",\n );\n }\n if (args.ephemeralSecrets !== undefined && args.ephemeralSecrets.length !== n) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n `ephemeralSecrets.length=${args.ephemeralSecrets.length} must match recipientPublicKeys.length=${n}`,\n );\n }\n } else {\n if (args.ephemeralSecrets !== undefined) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n \"ephemeralSecrets is an X25519 override and MUST NOT be supplied for kem='mlkem768x25519'\",\n );\n }\n if (args.eseeds !== undefined) {\n if (args.eseeds.length !== n) {\n throw new EciesSealedPoeError(\n 'EPHEMERAL_SECRETS_COUNT_MISMATCH',\n `eseeds.length=${args.eseeds.length} must match recipientPublicKeys.length=${n}`,\n );\n }\n for (let i = 0; i < n; i++) {\n const eseed = args.eseeds[i]!;\n if (eseed.length !== MLKEM768X25519_ESEED_LENGTH) {\n throw new EciesSealedPoeError(\n 'INVALID_EPHEMERAL_SECRET_LENGTH',\n `eseeds[${i}] MUST be exactly ${MLKEM768X25519_ESEED_LENGTH} bytes, got ${eseed.length}`,\n );\n }\n }\n }\n }\n\n const cek = args.cek ?? randomBytes(CEK_LENGTH);\n const nonce = args.nonce ?? randomBytes(NONCE_LENGTH);\n if (cek.length !== CEK_LENGTH) {\n throw new EciesSealedPoeError(\n 'INVALID_CEK_LENGTH',\n `cek MUST be exactly ${CEK_LENGTH} bytes, got ${cek.length}`,\n );\n }\n if (nonce.length !== NONCE_LENGTH) {\n throw new EciesSealedPoeError(\n 'NONCE_LENGTH_MISMATCH',\n `nonce MUST be exactly ${NONCE_LENGTH} bytes, got ${nonce.length}`,\n );\n }\n\n let envelope: SealedEnvelope;\n if (kem === 'x25519') {\n const slots: X25519Slot[] = [];\n for (let i = 0; i < n; i++) {\n slots.push(\n wrapSlotX25519({\n pubR: recipientPublicKeys[i]!,\n privEph: args.ephemeralSecrets ? (args.ephemeralSecrets[i] as Uint8Array) : undefined,\n cek,\n nonce,\n slotIdx: i,\n }),\n );\n }\n // Anonymity invariant (see csprngShuffle comment). The transcript is built\n // AFTER the shuffle so the MAC binds the on-wire slot order.\n if (args.skipShuffle !== true) {\n csprngShuffle(slots);\n }\n const slotsHash = computeSlotsHash({\n aead: SEALED_POE_AEAD,\n kem: 'x25519',\n nonce,\n slots,\n hashesHash,\n });\n envelope = {\n scheme: 1,\n aead: SEALED_POE_AEAD,\n kem: 'x25519',\n nonce,\n slots,\n slots_mac: sizedSlotsMac(cek, slotsHash),\n };\n } else {\n const slots: Mlkem768X25519Slot[] = [];\n for (let i = 0; i < n; i++) {\n slots.push(\n wrapSlotMlkem768X25519({\n pubR: recipientPublicKeys[i]!,\n eseed: args.eseeds ? (args.eseeds[i] as Uint8Array) : undefined,\n cek,\n nonce,\n }),\n );\n }\n if (args.skipShuffle !== true) {\n csprngShuffle(slots);\n }\n const slotsHash = computeSlotsHash({\n aead: SEALED_POE_AEAD,\n kem: 'mlkem768x25519',\n nonce,\n slots,\n hashesHash,\n });\n envelope = {\n scheme: 1,\n aead: SEALED_POE_AEAD,\n kem: 'mlkem768x25519',\n nonce,\n slots,\n slots_mac: sizedSlotsMac(cek, slotsHash),\n };\n }\n\n // Content is encrypted under a derived `payload_key` (a separate HKDF leaf of\n // the CEK salted by the envelope-unique nonce), never under the CEK directly,\n // in the segmented STREAM format. There is no content AAD: the content binds\n // to the header transitively — payload_key derives from the CEK, and the CEK\n // is committed to the full header (including hashes_hash) by slots_mac.\n const ciphertext = streamSeal({\n payloadKey: slotsPayloadKey({ cek, nonce }),\n plaintext,\n });\n\n return { envelope, ciphertext };\n}\n\nfunction sizedSlotsMac(cek: Uint8Array, slotsHash: Uint8Array): Uint8Array {\n const slotsMac = computeSlotsMac({ cek, slotsHash });\n if (slotsMac.length !== SLOTS_MAC_LENGTH) {\n throw new Error(`internal: slots_mac.length=${slotsMac.length}, expected ${SLOTS_MAC_LENGTH}`);\n }\n return slotsMac;\n}\n","// cardano-poe-pw-norm-v1: the normative passphrase normalization profile.\n//\n// Two implementations MUST derive a byte-identical CEK from the same\n// passphrase, so the normalization applied before Argon2id is pinned, in\n// order:\n//\n// 1. Bound the raw input (a pre-KDF denial-of-service backstop).\n// 2. NFKC under the pinned Unicode 16.0.0 tables. Input the pinned tables\n// cannot normalize stably — an unpaired surrogate, or a code point that\n// Unicode 16.0 leaves unassigned (a later Unicode version may give it a\n// decomposition and silently change the derived key) — is rejected.\n// 3. Collapse every maximal run of White_Space characters to one U+0020.\n// 4. Trim leading/trailing U+0020.\n// 5. Reject the empty result — a whitespace-only passphrase normalizes to\n// zero bytes, which Argon2id would silently accept, keying the record to\n// a CEK any party can derive.\n// 6. UTF-8-encode; those bytes are the Argon2id password input.\n//\n// Every Unicode-sensitive step resolves against the pinned Unicode 16.0.0\n// data — the NFKC tables and the White_Space property both — never the host\n// engine, whose tables float with its Unicode version.\n\nimport { Nfkc16Error, isWhiteSpace16, nfkc16 } from '../unicode/nfkc16';\nimport { EciesSealedPoeError } from './errors';\n\n// Reference bound on the RAW UTF-8 byte length of a passphrase, enforced before\n// any normalization or hashing work. A deployment-pinned constant, not a wire\n// field; deployments MAY tighten it.\nexport const MAX_PASSPHRASE_INPUT_BYTES = 4096;\n\nconst UTF8 = new TextEncoder();\n\n// One code-point pass implementing profile steps 3 + 4: each maximal\n// White_Space run becomes a single U+0020, and a leading or trailing run is\n// dropped entirely (never emitted), which is exactly collapse-then-trim.\n// `isWhiteSpace16` is the pinned Unicode 16.0 White_Space property —\n// deliberately NOT JavaScript's `\\s`, which also matches U+FEFF, a character\n// the property (and therefore the profile) does not treat as whitespace.\nfunction collapseAndTrimWhiteSpace(input: string): string {\n let out = '';\n let pendingRun = false;\n for (const ch of input) {\n if (isWhiteSpace16(ch.codePointAt(0) as number)) {\n pendingRun = true;\n continue;\n }\n if (pendingRun && out.length > 0) {\n out += ' ';\n }\n pendingRun = false;\n out += ch;\n }\n return out;\n}\n\n// Apply the cardano-poe-pw-norm-v1 profile and return the exact Argon2id\n// password bytes. Throws PASSPHRASE_INPUT_TOO_LONG when the raw input exceeds\n// the pre-normalization bound, ENC_PASSPHRASE_UNNORMALIZABLE when the input\n// cannot normalize stably under Unicode 16.0 (an unpaired surrogate or an\n// unassigned code point), and ENC_PASSPHRASE_EMPTY when the normalized result\n// is the empty string.\nexport function normalizePassphrase(passphrase: string): Uint8Array {\n const rawBytes = UTF8.encode(passphrase);\n if (rawBytes.length > MAX_PASSPHRASE_INPUT_BYTES) {\n throw new EciesSealedPoeError(\n 'PASSPHRASE_INPUT_TOO_LONG',\n `passphrase raw UTF-8 length ${rawBytes.length} exceeds MAX_PASSPHRASE_INPUT_BYTES=${MAX_PASSPHRASE_INPUT_BYTES}`,\n );\n }\n let folded: string;\n try {\n folded = nfkc16(passphrase);\n } catch (error) {\n if (error instanceof Nfkc16Error) {\n throw new EciesSealedPoeError('ENC_PASSPHRASE_UNNORMALIZABLE', error.message, {\n cause: error,\n });\n }\n throw error;\n }\n const normalized = collapseAndTrimWhiteSpace(folded);\n if (normalized.length === 0) {\n throw new EciesSealedPoeError(\n 'ENC_PASSPHRASE_EMPTY',\n 'passphrase normalizes to the empty string',\n );\n }\n return UTF8.encode(normalized);\n}\n","// Label 309 v1 structural validator (the Part A structural-validation role).\n//\n// Pure function over the reassembled CBOR record body — performs no I/O,\n// opens no socket, verifies no signature cryptographically, decodes no\n// ciphertext. Chain resolution, URI fetching, decryption, and\n// confirmation-depth checks are the verifier's concern (the Part B role).\n// The transport chunk array is reassembled BEFORE this function runs (see\n// `carriage.ts`); the carriage codes (`CHUNK_TOO_LARGE`, the transport\n// `MALFORMED_CBOR` reuse) are emitted by that step, not here.\n//\n// Pipeline:\n// Step 1 Canonical CBOR decode — `decodeCanonicalCbor` surfaces malformed /\n// non-canonical / duplicate-key / indefinite-length inputs as the\n// single MALFORMED_CBOR code.\n// Step 2 Schema parse — the closed Zod shapes in `./schema.ts`; the mapper\n// below lifts each Zod issue to its canonical structural code.\n// Step 3 Domain checks — cross-field rules, registry membership, URI shape\n// (the offline CID profile), the encryption-envelope union\n// (typed scheme-1 vs the degrade-to-opaque reading), `sigs[i]`\n// COSE_Sign1 structural decode, `crit[]` shape, exact-integer\n// range enforcement.\n// Step 4 Result emission — every collected issue is sorted (path\n// segment-wise, registry-order tie-break) and the record is valid\n// iff no error-severity issue is present.\n//\n// The validator NEVER throws — failure paths route through the discriminated\n// `ValidationResult` union so callers handle errors as data, and its output\n// is deterministic for any given `(bytes, options)` pair.\n\nimport { z } from 'zod';\n\nimport {\n decodeCanonicalCbor,\n encodeCanonicalCbor,\n type CanonicalCborValue,\n} from '@cardanowall/crypto-core/cbor';\nimport { CoseVerifyError, decodeCoseSign1 } from '@cardanowall/crypto-core/cose';\n// The verifier resource bounds the sealed-PoE unwrap layer enforces. Importing\n// the same constants, rather than re-declaring them, makes the structural\n// validator and the unwrap layer default to identical thresholds. Both are\n// deployment-pinned reference values, not wire fields — `ValidatorOptions`\n// overrides them per deployment.\nimport { MAX_DECODED_ENVELOPE_BYTES, MAX_SLOTS } from '@cardanowall/crypto-core/sealed-poe';\n\nimport { SEVERITY, errorCodeRegistryIndex, type ErrorCode, type Severity } from './error-codes';\nimport {\n EncScheme1Schema,\n isExtensionKey,\n PoeRecordSchema,\n TOP_LEVEL_BASE_KEYS,\n type EncScheme1,\n type ItemEntry,\n type MerkleCommit,\n type PassphraseBlock,\n type PoeRecord,\n type SigEntry,\n type Slot,\n} from './schema';\n\n// =============================================================================\n// Registries (closed catalogue of this implementation)\n// =============================================================================\n\n// Content-hash algorithm registry. Map value = digest length.\nconst HASH_ALG_LENGTHS: Readonly<Record<string, number>> = {\n 'sha2-256': 32,\n 'blake2b-256': 32,\n};\n\n// Merkle list-commitment algorithm registry. Map value = root length.\nconst MERKLE_COMMIT_ALG_LENGTHS: Readonly<Record<string, number>> = {\n 'rfc9162-sha256': 32,\n};\n\n// Content-format (AEAD) registry. Value = the registered `enc.nonce` length.\nconst AEAD_NONCE_LENGTHS: Readonly<Record<string, number>> = {\n 'chacha20-poly1305-stream64k': 24,\n};\n\n// Unauthenticated-cipher family. An `enc.aead` naming any of these is rejected\n// with `UNAUTHENTICATED_CIPHER_FORBIDDEN` in EVERY role — a forbidden\n// primitive is a recognised hazard, not an unknown identifier, so it never\n// takes the degrade-to-opaque reading. Two arms:\n// - block-cipher modes with no integrity (`cbc`, `ctr`, `ecb`, `cfb`,\n// `ofb`) appearing as a delimited token, matching every key-size spelling\n// (`aes-cbc`, `aes-256-cbc`, `des-ede3-cbc`, …);\n// - legacy stream/block ciphers as a leading token (`rc4`, `des`, `3des`).\n// The token delimiters keep authenticated AEADs (`aes-256-gcm`,\n// `chacha20-poly1305-stream64k`) from matching.\nconst UNAUTHENTICATED_CIPHER_RE =\n /(?:^|[-_])(?:cbc|ctr|ecb|cfb|ofb)(?:[-_]|$)|^(?:rc4|des|3des)(?:[-_]|$)/i;\n\n// KEM registry, expressed as a per-KEM slot DESCRIPTOR. Each registered KEM\n// pins the exact recipient-slot shape:\n//\n// - x25519: `{ epk: bstr(32), wrap: bstr(48) }` — classical\n// ephemeral-static X25519.\n// - mlkem768x25519: `{ kem_ct: bstr(1120), wrap: bstr(48) }` — the X-Wing\n// hybrid; the encapsulation is a SINGLE 1120-byte byte string and there\n// is NO per-slot `epk` (the X25519 ephemeral is the trailing 32 bytes of\n// `kem_ct`).\n//\n// A descriptor declares the slot's ciphertext-bearing field and its exact\n// byte length; `wrap` is 48 bytes for every KEM (32-byte CEK + 16-byte AEAD\n// tag). The validator branches on the descriptor so adding a future KEM is a\n// registry edit, not a new code path.\ntype KemSlotField = 'epk' | 'kem_ct';\ninterface KemSlotDescriptor {\n readonly field: KemSlotField;\n readonly fieldLength: number;\n readonly wrapLength: number;\n}\nconst KEM_SLOT_DESCRIPTORS: Readonly<Record<string, KemSlotDescriptor>> = {\n x25519: { field: 'epk', fieldLength: 32, wrapLength: 48 },\n mlkem768x25519: { field: 'kem_ct', fieldLength: 1120, wrapLength: 48 },\n};\n\nconst KEM_FIELD_LENGTH_CODE: Readonly<Record<KemSlotField, ErrorCode>> = {\n epk: 'KEM_EPK_LENGTH_MISMATCH',\n kem_ct: 'KEM_CT_LENGTH_MISMATCH',\n};\n\n// Passphrase KDF registry.\nconst PASSPHRASE_KDF_ALGS: ReadonlySet<string> = new Set(['argon2id']);\n\n// Signature-algorithm registry: COSE `alg` labels. `-8` (EdDSA, pinned to\n// Ed25519) is the mandatory baseline; `-19` (Ed25519 fully-specified) is\n// verified identically when accepted. Anything else is tagged\n// `SIGNATURE_UNSUPPORTED` (info-severity) — signatures are optional, so an\n// unrecognised algorithm never fails the record by itself.\nconst KNOWN_SIG_ALG_IDS: ReadonlySet<number> = new Set([-8, -19]);\n\n// Every numeric wire field is a CBOR unsigned integer pinned to this range\n// and handled as an EXACT integer (the canonical decoder surfaces values\n// above 2^53 − 1 as `bigint`, so no precision is ever lost before the range\n// check rejects).\nconst UINT32_MAX = 0xffff_ffff;\n\n// =============================================================================\n// Options\n// =============================================================================\n\nexport type ValidatorRole = 'public' | 'recipient_or_strict';\n\nexport interface Argon2ParamsCeiling {\n readonly m: number;\n readonly t: number;\n readonly p: number;\n}\n\n// The reference deployment ceiling on Argon2id work factors — a verifier-side\n// denial-of-service backstop (a 64 GiB `m` must not be able to stall a\n// decrypt-on-paste consumer), enforced by default and distinct from the\n// normative floors. Ceilings are deployment policy, not a wire rule: override\n// per deployment, or pass `passphraseParamsCeiling: null` to disable.\nexport const DEFAULT_PASSPHRASE_PARAMS_CEILING: Argon2ParamsCeiling = Object.freeze({\n m: 2_097_152, // KiB = 2 GiB\n t: 16,\n p: 8,\n});\n\nexport interface ValidatorOptions {\n /**\n * Names of the critical extensions this validator implements. Default: the\n * empty set — a default-configured validator therefore fails every\n * `crit`-bearing record with `EXTENSION_UNSUPPORTED_CRITICAL`, by design.\n */\n readonly supportedCriticalExtensions?: ReadonlySet<string>;\n /**\n * The validation reading for dual-severity envelope dispositions.\n * `public` (default): an envelope under an unsupported `scheme` / `kem` /\n * `aead` degrades to opaque and `ENC_UNSUPPORTED` is informational.\n * `recipient_or_strict` (the recipient verifier and strict sealed-crypto\n * mode): the same condition is a hard reject — `ENC_UNSUPPORTED` escalates\n * to `error` and co-fires with the identifier-specific `UNSUPPORTED_*`\n * code.\n */\n readonly role?: ValidatorRole;\n /** Slot-count resource bound (reference bound 1024; deployments MAY tighten). */\n readonly maxSlots?: number;\n /** Decoded-envelope byte resource bound (reference bound 65536). */\n readonly maxEncEnvelopeBytes?: number;\n /**\n * Upper policy ceiling on Argon2id parameters\n * (`ENC_PASSPHRASE_PARAMS_EXCEED_POLICY`). Defaults to\n * `DEFAULT_PASSPHRASE_PARAMS_CEILING`; `null` disables the ceiling.\n */\n readonly passphraseParamsCeiling?: Argon2ParamsCeiling | null;\n}\n\ninterface ResolvedOptions {\n readonly supportedCriticalExtensions: ReadonlySet<string>;\n readonly role: ValidatorRole;\n readonly maxSlots: number;\n readonly maxEncEnvelopeBytes: number;\n readonly passphraseParamsCeiling: Argon2ParamsCeiling | null;\n}\n\nconst EMPTY_EXTENSION_SET: ReadonlySet<string> = new Set();\n\nfunction resolveOptions(options?: ValidatorOptions): ResolvedOptions {\n return {\n supportedCriticalExtensions: options?.supportedCriticalExtensions ?? EMPTY_EXTENSION_SET,\n role: options?.role ?? 'public',\n maxSlots: options?.maxSlots ?? MAX_SLOTS,\n maxEncEnvelopeBytes: options?.maxEncEnvelopeBytes ?? MAX_DECODED_ENVELOPE_BYTES,\n passphraseParamsCeiling:\n options?.passphraseParamsCeiling === undefined\n ? DEFAULT_PASSPHRASE_PARAMS_CEILING\n : options.passphraseParamsCeiling,\n };\n}\n\n// =============================================================================\n// Result types\n// =============================================================================\n\nexport interface ValidationIssue {\n /**\n * Segments from the record root: text map keys and integer array indices\n * (e.g. `[\"items\", 0, \"hashes\", \"sha2-256\"]`). A dotted string is a display\n * rendering only — the segment list is the API form, so map keys containing\n * `.` need no escaping.\n */\n readonly path: ReadonlyArray<string | number>;\n readonly code: ErrorCode;\n readonly severity: Severity;\n readonly message: string;\n}\n\nexport type ValidationResult =\n | {\n readonly valid: true;\n readonly record: PoeRecord;\n readonly warnings?: ReadonlyArray<ValidationIssue>;\n readonly info?: ReadonlyArray<ValidationIssue>;\n }\n | { readonly valid: false; readonly issues: ReadonlyArray<ValidationIssue> };\n\n// =============================================================================\n// Public entry point\n// =============================================================================\n\nexport function validatePoeRecord(bytes: Uint8Array, options?: ValidatorOptions): ValidationResult {\n const opts = resolveOptions(options);\n\n // Step 1 — canonical CBOR decode. Every decode failure surfaces as the\n // single MALFORMED_CBOR code: malformed/truncated bytes, indefinite-length\n // (streaming) encodings, non-canonical map-key ordering, duplicate map\n // keys, non-minimal integers, and invalid UTF-8. There is no separate\n // duplicate-key code — canonical-decode rejection covers it.\n let decoded: unknown;\n try {\n decoded = decodeCanonicalCbor(bytes);\n } catch (cause) {\n return {\n valid: false,\n issues: [\n {\n code: 'MALFORMED_CBOR',\n path: [],\n message: cause instanceof Error ? cause.message : String(cause),\n severity: 'error',\n },\n ],\n };\n }\n\n // Step 2 pre-guard — non-text map keys. Every map at a typed grammar\n // position is text-keyed; the canonical decoder surfaces a map carrying any\n // non-text key as a `Map` (an all-text-key map decodes to a plain object).\n // A `Map` is still a JS object, so an object schema run over it would read\n // its (absent) named properties and mis-report every required field as\n // missing — the violation is detected here instead and attributed at the\n // containing map as SCHEMA_TYPE_MISMATCH, foreclosing the parse the same\n // way any other unparseable shape does.\n const nonTextKeyIssues = collectNonTextKeyMapIssues(decoded);\n if (nonTextKeyIssues.length > 0) {\n return { valid: false, issues: sortIssues(nonTextKeyIssues) };\n }\n\n // Step 2 — schema parse. A failed parse forecloses the domain pass (there\n // is no typed record to walk); its issues are emitted sorted.\n const parse = PoeRecordSchema.safeParse(decoded);\n if (!parse.success) {\n return { valid: false, issues: sortIssues(mapZodIssues(parse.error.issues, decoded)) };\n }\n\n // Step 3 — domain checks. Issues of every severity are collected together;\n // no error-severity issue stops the walk.\n const record = parse.data;\n const issues: ValidationIssue[] = [];\n\n checkContentCommitmentPresence(record, issues);\n\n // `crit[]` shape rules run before the per-entry support check.\n const decodedTopKeys = topLevelKeysOf(decoded);\n checkCrit(record, decodedTopKeys, opts.supportedCriticalExtensions, issues);\n\n // Unknown top-level fields: keys outside the base set that match neither\n // extension-key namespace (typos, control-character keys).\n for (const key of decodedTopKeys) {\n if (TOP_LEVEL_BASE_KEYS.has(key)) continue;\n if (isExtensionKey(key)) continue;\n issues.push(issueOf('SCHEMA_UNKNOWN_FIELD', [key], `unknown top-level field: ${key}`));\n }\n\n const items = record.items ?? [];\n for (let i = 0; i < items.length; i++) {\n const item = items[i]!;\n checkItemHashes(item, i, issues);\n if (item.uris !== undefined) checkUris(item.uris, ['items', i, 'uris'], issues);\n if (item.enc !== undefined) checkItemEnc(item, i, opts, issues);\n }\n\n const merkle = record.merkle ?? [];\n for (let i = 0; i < merkle.length; i++) {\n checkMerkleCommit(merkle[i]!, i, issues);\n }\n\n if (record.sigs !== undefined) {\n if (record.sigs.length === 0) {\n issues.push(\n issueOf('SCHEMA_TYPE_MISMATCH', ['sigs'], 'sigs[] must be non-empty when present'),\n );\n }\n for (let i = 0; i < record.sigs.length; i++) {\n checkSigEntry(record.sigs[i]!, i, issues);\n }\n }\n\n // Step 4 — result emission. The full issue list is sorted once (path\n // segment-wise, registry-order tie-break); the record is valid iff no\n // error-severity issue is present, and warnings / info never fail it.\n const sorted = sortIssues(issues);\n if (sorted.some((issue) => issue.severity === 'error')) {\n return { valid: false, issues: sorted };\n }\n const warnings = sorted.filter((issue) => issue.severity === 'warning');\n const info = sorted.filter((issue) => issue.severity === 'info');\n const result: {\n valid: true;\n record: PoeRecord;\n warnings?: ReadonlyArray<ValidationIssue>;\n info?: ReadonlyArray<ValidationIssue>;\n } = { valid: true, record };\n if (warnings.length > 0) result.warnings = warnings;\n if (info.length > 0) result.info = info;\n return result;\n}\n\n// =============================================================================\n// Step 2 helpers — Zod issue → structural-code mapping\n// =============================================================================\n\n// Lift a Zod issue list to canonical structural issues. An\n// `unrecognized_keys` issue names every stray key of one closed map in a\n// single Zod issue; it is expanded here into one canonical issue per key,\n// attributed at the key itself — the same per-key attribution the domain\n// pass uses for closed maps it walks by hand.\nfunction mapZodIssues(\n zissues: ReadonlyArray<z.core.$ZodIssue>,\n decodedRoot?: unknown,\n): ValidationIssue[] {\n const out: ValidationIssue[] = [];\n for (const zissue of zissues) {\n if (zissue.code === 'unrecognized_keys') {\n for (const key of zissue.keys) {\n const path = [...(zissue.path as ReadonlyArray<string | number>), key];\n const code = unknownKeyCode(path);\n out.push(issueOf(code, path, `unrecognized key '${key}' in a closed map`));\n }\n continue;\n }\n out.push(mapZodIssue(zissue, decodedRoot));\n }\n return out;\n}\n\n// The canonical code for a stray key, by position: a stray key inside a\n// `sigs[i]` entry violates the sig-entry closed-map rule; everywhere else a\n// stray key in a closed map is the generic SCHEMA_UNKNOWN_FIELD. (Slot maps\n// never reach this dispatch — their schema is permissive and the KEM-driven\n// domain gate emits ENC_SLOT_INVALID_SHAPE for stray slot keys.)\nfunction unknownKeyCode(path: ReadonlyArray<string | number>): ErrorCode {\n if (path.length >= 2 && path[0] === 'sigs' && typeof path[1] === 'number') {\n return 'SIG_ENTRY_INVALID_SHAPE';\n }\n return 'SCHEMA_UNKNOWN_FIELD';\n}\n\n// Non-text-key detection over the typed grammar positions reachable from the\n// record root: the root map, each `items[i]` / `merkle[i]` / `sigs[i]` entry,\n// and the `hashes` / `enc` maps inside an item. Positions inside extension\n// values are deliberately NOT walked — extension values admit any CBOR value\n// the canonical profile allows, integer-keyed maps included. The interior of\n// a supported `enc` envelope is scanned by the envelope dispatch itself (the\n// opaque reading likewise admits arbitrary extension values).\nfunction collectNonTextKeyMapIssues(decoded: unknown): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const flag = (path: ReadonlyArray<string | number>): void => {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n path,\n 'CBOR map carries a non-text key where a text-keyed map is required',\n ),\n );\n };\n if (decoded instanceof Map) {\n flag([]);\n return issues;\n }\n if (decoded === null || typeof decoded !== 'object' || Array.isArray(decoded)) return issues;\n const record = decoded as Record<string, unknown>;\n for (const field of ['items', 'merkle', 'sigs'] as const) {\n const entries = record[field];\n if (!Array.isArray(entries)) continue;\n entries.forEach((entry, i) => {\n if (entry instanceof Map) {\n flag([field, i]);\n return;\n }\n if (field !== 'items' || entry === null || typeof entry !== 'object') return;\n const item = entry as Record<string, unknown>;\n if (item['hashes'] instanceof Map) flag([field, i, 'hashes']);\n if (item['enc'] instanceof Map) flag([field, i, 'enc']);\n });\n }\n return issues;\n}\n\nfunction mapZodIssue(zissue: z.core.$ZodIssue, decodedRoot?: unknown): ValidationIssue {\n const path = zissue.path as ReadonlyArray<string | number>;\n // Refinements with an explicit `params.code` win unconditionally — they are\n // the canonical taxonomy code attached at schema-definition time\n // (SUPERSEDES_TX_INVALID_LENGTH, ENC_SLOTS_MAC_INVALID_LENGTH, the salt\n // bounds).\n const explicit = (zissue as { params?: { code?: string } }).params?.code as ErrorCode | undefined;\n if (explicit !== undefined) {\n return issueOf(explicit, path, zissue.message);\n }\n\n const valueAtIssue = valueAtPath(decodedRoot, path);\n\n // A CBOR map carrying any non-text key decodes to a `Map` (an all-text-key\n // map decodes to a plain object), and every registered map position in the\n // grammar is text-keyed — so a `Map` anywhere a registered map is expected\n // is a non-text-key violation, reported as SCHEMA_TYPE_MISMATCH at the\n // containing map regardless of which position it sits in.\n if (valueAtIssue instanceof Map) {\n return issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n path,\n 'CBOR map carries a non-text key where a text-keyed map is required',\n );\n }\n\n // Path-based dispatch:\n // `sigs[i]…` → SIG_ENTRY_INVALID_SHAPE (the sig-entry closed-map rule)\n // a slot element or a field within a slot → ENC_SLOT_INVALID_SHAPE\n // `v` literal mismatch / missing → SCHEMA_INVALID_LITERAL vs\n // SCHEMA_MISSING_REQUIRED.\n const inSigsEntry = path.length >= 2 && path[0] === 'sigs' && typeof path[1] === 'number';\n\n // The typed envelope parse runs with the `enc` map as its root, so a slot\n // issue arrives with the relative path `slots[j]…`; `checkItemEnc` prefixes\n // the `items[i].enc` segments afterwards. (The top-level record parse never\n // descends into `enc` — the item schema holds it as `unknown` for the\n // typed-vs-opaque dispatch.)\n const isInSlotEntry = path.length >= 2 && path[0] === 'slots' && typeof path[1] === 'number';\n\n const isMissing = valueAtIssue === undefined;\n\n switch (zissue.code) {\n case 'invalid_type':\n if (isInSlotEntry) return issueOf('ENC_SLOT_INVALID_SHAPE', path, zissue.message);\n if (isMissing) {\n if (inSigsEntry) return issueOf('SIG_ENTRY_INVALID_SHAPE', path, zissue.message);\n return issueOf('SCHEMA_MISSING_REQUIRED', path, zissue.message);\n }\n if (inSigsEntry) return issueOf('SIG_ENTRY_INVALID_SHAPE', path, zissue.message);\n return issueOf('SCHEMA_TYPE_MISMATCH', path, zissue.message);\n case 'invalid_value':\n // `z.literal(1)` emits `invalid_value` for both a missing field AND a\n // present-but-wrong value; disambiguate via the runtime value.\n if (isMissing) return issueOf('SCHEMA_MISSING_REQUIRED', path, zissue.message);\n return issueOf('SCHEMA_INVALID_LITERAL', path, zissue.message);\n case 'invalid_union':\n case 'invalid_format':\n case 'too_big':\n case 'too_small':\n case 'invalid_key':\n case 'invalid_element':\n case 'custom':\n default:\n if (isInSlotEntry) return issueOf('ENC_SLOT_INVALID_SHAPE', path, zissue.message);\n if (inSigsEntry) return issueOf('SIG_ENTRY_INVALID_SHAPE', path, zissue.message);\n return issueOf('SCHEMA_TYPE_MISMATCH', path, zissue.message);\n }\n}\n\n// =============================================================================\n// Step 3 helpers — domain checks\n// =============================================================================\n\n// Content-commitment rule: a record MUST carry at least one of `items[]` or\n// `merkle[]` non-empty (SCHEMA_EMPTY_RECORD when both are empty or absent).\n// When exactly one of them is present-but-empty beside a non-empty sibling,\n// the empty array itself violates its `1*` cardinality.\nfunction checkContentCommitmentPresence(record: PoeRecord, issues: ValidationIssue[]): void {\n const itemsLen = record.items?.length ?? 0;\n const merkleLen = record.merkle?.length ?? 0;\n if (itemsLen === 0 && merkleLen === 0) {\n issues.push(\n issueOf(\n 'SCHEMA_EMPTY_RECORD',\n [],\n 'record must carry at least one of items[] or merkle[] non-empty',\n ),\n );\n return;\n }\n if (record.items !== undefined && itemsLen === 0) {\n issues.push(\n issueOf('SCHEMA_TYPE_MISMATCH', ['items'], 'items[] must be non-empty when present'),\n );\n }\n if (record.merkle !== undefined && merkleLen === 0) {\n issues.push(\n issueOf('SCHEMA_TYPE_MISMATCH', ['merkle'], 'merkle[] must be non-empty when present'),\n );\n }\n}\n\n// Hash-map: non-empty, registry membership, per-algorithm digest length.\nfunction checkItemHashes(item: ItemEntry, idx: number, issues: ValidationIssue[]): void {\n const entries = Object.entries(item.hashes);\n if (entries.length === 0) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n ['items', idx, 'hashes'],\n 'hashes must be a non-empty CBOR map of <alg-id> -> <digest>',\n ),\n );\n return;\n }\n for (const [alg, digest] of entries) {\n if (!(alg in HASH_ALG_LENGTHS)) {\n issues.push(\n issueOf('UNSUPPORTED_HASH_ALG', ['items', idx, 'hashes', alg], `unknown hash alg: ${alg}`),\n );\n continue;\n }\n const expected = HASH_ALG_LENGTHS[alg]!;\n if (digest.length !== expected) {\n issues.push(\n issueOf(\n 'HASH_DIGEST_LENGTH_MISMATCH',\n ['items', idx, 'hashes', alg],\n `hashes['${alg}'] digest length ${digest.length} != ${expected}`,\n ),\n );\n }\n }\n}\n\n// URI shape: each entry is one absolute URI in a single text string.\nfunction checkUris(\n uris: ReadonlyArray<string>,\n basePath: ReadonlyArray<string | number>,\n issues: ValidationIssue[],\n): void {\n if (uris.length === 0) {\n issues.push(issueOf('SCHEMA_TYPE_MISMATCH', basePath, 'uris[] must be non-empty when present'));\n return;\n }\n uris.forEach((uri, ui) => checkOneUri(uri, [...basePath, ui], issues));\n}\n\nfunction checkOneUri(\n uri: string,\n path: ReadonlyArray<string | number>,\n issues: ValidationIssue[],\n): void {\n // Absolute URI, no fragment, scheme in `{ar://, ipfs://}`.\n if (uri.includes('#')) {\n issues.push(\n issueOf('INVALID_URI', path, \"URI contains a fragment identifier ('#'), which is forbidden\"),\n );\n return;\n }\n const sepIdx = uri.indexOf('://');\n if (sepIdx <= 0 || !/^[a-z][a-z0-9+.-]*$/i.test(uri.slice(0, sepIdx))) {\n issues.push(\n issueOf('INVALID_URI', path, 'URI is not absolute (missing scheme://hierarchical-part)'),\n );\n return;\n }\n // RFC 3986 §3.1: the scheme is case-insensitive, so case-fold the SCHEME\n // ONLY, then ALWAYS validate the body. The body is matched verbatim — a\n // base64url Arweave txid and a base58btc CID are case-significant.\n const scheme = uri.slice(0, sepIdx).toLowerCase();\n const rest = uri.slice(sepIdx + '://'.length);\n if (scheme === 'ar') {\n if (!/^[A-Za-z0-9_-]{43}$/.test(rest)) {\n issues.push(\n issueOf(\n 'INVALID_URI',\n path,\n 'ar:// URI does not match `^ar://[A-Za-z0-9_-]{43}$` (43-char base64url txid, no path/query/fragment)',\n ),\n );\n }\n return;\n }\n if (scheme === 'ipfs') {\n // Full offline CID parse (not a prefix heuristic).\n const slashIdx = rest.indexOf('/');\n const cid = slashIdx === -1 ? rest : rest.slice(0, slashIdx);\n if (!validateCidProfile(cid)) {\n issues.push(\n issueOf('INVALID_URI', path, 'ipfs:// URI is not a valid CID under the Label 309 profile'),\n );\n }\n return;\n }\n issues.push(\n issueOf('INVALID_URI', path, 'unsupported URI scheme; v1 PoE URI set is {ar://, ipfs://}'),\n );\n}\n\n// =============================================================================\n// Encryption envelope — the typed-vs-opaque union\n// =============================================================================\n//\n// `enc = enc-scheme-1 / enc-opaque`. The disposition is decided by identifier\n// support, never by shape success:\n//\n// - When `scheme`, `kem`, and `aead` are ALL supported identifiers, the\n// envelope is held to the full scheme-1 shape and key-path rules; an\n// envelope that fails them is rejected with its typed code, never\n// reclassified as opaque.\n// - When any of the three names an identifier this implementation does not\n// support, the envelope becomes OPAQUE: no shape, length, or key-path\n// rule is applied against an unknown identifier; the item is tagged\n// ENC_UNSUPPORTED (info in the public reading; error co-firing with the\n// identifier-specific UNSUPPORTED_* code in the recipient role / strict\n// sealed-crypto mode).\n// - Carve-out: an `aead` naming a forbidden unauthenticated cipher family\n// is rejected UNAUTHENTICATED_CIPHER_FORBIDDEN in every role — a\n// recognised hazard, not an unknown identifier.\n//\n// The content-hash binding (ENC_REQUIRES_CONTENT_HASH) inspects the item's\n// `hashes` map, not the envelope, so it applies even under an opaque\n// envelope.\n\nfunction checkItemEnc(\n item: ItemEntry,\n idx: number,\n opts: ResolvedOptions,\n issues: ValidationIssue[],\n): void {\n const encPath: ReadonlyArray<string | number> = ['items', idx, 'enc'];\n\n // Content-hash binding: an `enc`-bearing item MUST commit to at least one\n // REGISTERED content hash — the ciphertext is otherwise bound to no\n // plaintext digest. A presence check, not a non-empty check: `{md5: …}`\n // fails it (and MAY co-fire with UNSUPPORTED_HASH_ALG on the same item).\n const hasContentHash = Object.keys(item.hashes).some((alg) => alg in HASH_ALG_LENGTHS);\n if (!hasContentHash) {\n issues.push(\n issueOf(\n 'ENC_REQUIRES_CONTENT_HASH',\n encPath,\n 'item carries `enc` but `hashes` has no registered content-hash entry (sha2-256 or blake2b-256)',\n ),\n );\n }\n\n // The pre-guard has already rejected an `enc` that decoded to a `Map`\n // (non-text keys), so a well-typed envelope arrives here as a plain object.\n const rawEnc = item.enc;\n if (\n rawEnc === null ||\n typeof rawEnc !== 'object' ||\n Array.isArray(rawEnc) ||\n rawEnc instanceof Uint8Array\n ) {\n issues.push(issueOf('SCHEMA_TYPE_MISMATCH', encPath, 'enc must be a CBOR map'));\n return;\n }\n const enc = rawEnc as Record<string, unknown>;\n\n // Decoded-envelope byte resource bound — a generic decode limit that\n // applies in every reading, opaque included. Canonical decode → canonical\n // encode is byte-identical, so re-encoding the decoded envelope measures\n // exactly the wire bytes of the `enc` subtree.\n const envelopeBytes = encodeCanonicalCbor(rawEnc as CanonicalCborValue).length;\n if (envelopeBytes > opts.maxEncEnvelopeBytes) {\n issues.push(\n issueOf(\n 'ENC_ENVELOPE_TOO_LARGE',\n encPath,\n `decoded envelope is ${envelopeBytes} bytes; the resource bound is ${opts.maxEncEnvelopeBytes}`,\n ),\n );\n }\n\n // `scheme` is structurally required in BOTH readings, as a CBOR unsigned\n // integer (the opaque grammar admits any uint; the typed grammar pins 1).\n const scheme = enc['scheme'];\n if (scheme === undefined) {\n issues.push(\n issueOf('SCHEMA_MISSING_REQUIRED', [...encPath, 'scheme'], 'enc.scheme is required'),\n );\n return;\n }\n if (!isUint(scheme)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...encPath, 'scheme'],\n 'enc.scheme must be a CBOR unsigned integer',\n ),\n );\n return;\n }\n\n // Forbidden-cipher carve-out: rejected in every role, never opaque.\n const aead = enc['aead'];\n if (typeof aead === 'string' && UNAUTHENTICATED_CIPHER_RE.test(aead)) {\n issues.push(\n issueOf(\n 'UNAUTHENTICATED_CIPHER_FORBIDDEN',\n [...encPath, 'aead'],\n `'${aead}' is an unauthenticated cipher; Label 309 mandates an authenticated (AEAD) cipher`,\n ),\n );\n return;\n }\n\n // Unknown-envelope rule: collect every identifier outside the implemented\n // set. A non-text `kem` / `aead` is not an identifier at all — it is a type\n // violation of whichever reading applies, handled by the typed pass below.\n const kem = enc['kem'];\n const unsupported: Array<{ field: 'scheme' | 'kem' | 'aead'; code: ErrorCode; id: string }> = [];\n if (!(typeof scheme === 'number' && scheme === 1)) {\n unsupported.push({ field: 'scheme', code: 'UNSUPPORTED_ENVELOPE_SCHEME', id: String(scheme) });\n }\n if (typeof kem === 'string' && !(kem in KEM_SLOT_DESCRIPTORS)) {\n unsupported.push({ field: 'kem', code: 'UNSUPPORTED_KEM_ALG', id: kem });\n }\n if (typeof aead === 'string' && !(aead in AEAD_NONCE_LENGTHS)) {\n unsupported.push({ field: 'aead', code: 'UNSUPPORTED_AEAD_ALG', id: aead });\n }\n if (unsupported.length > 0) {\n // Degrade to opaque: the envelope is bounded metadata only. No shape,\n // length, nonce, slot, or key-path rule may be applied against an\n // unknown identifier.\n const named = unsupported.map((u) => `${u.field}=${u.id}`).join(', ');\n const message =\n `envelope uses identifiers this implementation does not support (${named}); ` +\n 'the envelope is opaque and only the content-hash claim is validated';\n if (opts.role === 'recipient_or_strict') {\n issues.push({ code: 'ENC_UNSUPPORTED', path: encPath, message, severity: 'error' });\n for (const u of unsupported) {\n issues.push(\n issueOf(u.code, [...encPath, u.field], `enc.${u.field} '${u.id}' is not supported`),\n );\n }\n } else {\n issues.push({ code: 'ENC_UNSUPPORTED', path: encPath, message, severity: 'info' });\n }\n return;\n }\n\n // Fully supported identifiers → the typed scheme-1 pass is mandatory.\n // Non-text-key maps inside the typed envelope (a slot, the passphrase\n // block, its params) are rejected first, at the containing map — the same\n // pre-guard rule the record level applies, scoped here because only the\n // typed reading constrains the envelope interior.\n const internalMapIssues = encInternalNonTextKeyIssues(enc, encPath);\n if (internalMapIssues.length > 0) {\n issues.push(...internalMapIssues);\n return;\n }\n const encParse = EncScheme1Schema.safeParse(rawEnc);\n if (!encParse.success) {\n for (const mapped of mapZodIssues(encParse.error.issues, rawEnc)) {\n issues.push({ ...mapped, path: [...encPath, ...mapped.path] });\n }\n return;\n }\n checkScheme1Envelope(encParse.data, rawEnc, encPath, opts, issues);\n}\n\n// Non-text-key maps at the typed envelope's interior positions: each slot,\n// the passphrase block, and its `params` map.\nfunction encInternalNonTextKeyIssues(\n enc: Record<string, unknown>,\n encPath: ReadonlyArray<string | number>,\n): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const flag = (path: ReadonlyArray<string | number>): void => {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n path,\n 'CBOR map carries a non-text key where a text-keyed map is required',\n ),\n );\n };\n const slots = enc['slots'];\n if (Array.isArray(slots)) {\n slots.forEach((slot, i) => {\n if (slot instanceof Map) flag([...encPath, 'slots', i]);\n });\n }\n const passphrase = enc['passphrase'];\n if (passphrase instanceof Map) {\n flag([...encPath, 'passphrase']);\n } else if (passphrase !== null && typeof passphrase === 'object' && !Array.isArray(passphrase)) {\n const params = (passphrase as Record<string, unknown>)['params'];\n if (params instanceof Map) flag([...encPath, 'passphrase', 'params']);\n }\n return issues;\n}\n\nfunction checkScheme1Envelope(\n enc: EncScheme1,\n rawEnc: object,\n encPath: ReadonlyArray<string | number>,\n opts: ResolvedOptions,\n issues: ValidationIssue[],\n): void {\n // Nonce length is registered per content format (24 bytes for\n // chacha20-poly1305-stream64k). Checked only under a supported `aead` —\n // which is guaranteed on this path.\n const expectedNonceLen = AEAD_NONCE_LENGTHS[enc.aead]!;\n if (enc.nonce.length !== expectedNonceLen) {\n issues.push(\n issueOf(\n 'NONCE_LENGTH_MISMATCH',\n [...encPath, 'nonce'],\n `nonce length ${enc.nonce.length} != ${expectedNonceLen} for ${enc.aead}`,\n ),\n );\n }\n\n // Key-path cross-field rules. Exactly one of `slots` / `passphrase` is\n // present; `passphrase` forbids `kem`, `slots`, and `slots_mac`; `slots`\n // requires both `kem` and `slots_mac`; `slots_mac` binds nothing without\n // `slots`. Each independent rule emits its own code — they co-fire where\n // several apply.\n const hasSlots = enc.slots !== undefined;\n const hasSlotsMac = enc.slots_mac !== undefined;\n const hasPassphrase = enc.passphrase !== undefined;\n const hasKem = enc.kem !== undefined;\n\n if (hasPassphrase && (hasSlots || hasSlotsMac || hasKem)) {\n issues.push(\n issueOf(\n 'ENC_EXCLUSIVITY_VIOLATION',\n encPath,\n 'enc.passphrase is mutually exclusive with kem / slots / slots_mac; exactly one key path is allowed',\n ),\n );\n }\n if (hasSlots && !hasSlotsMac) {\n issues.push(\n issueOf('ENC_SLOTS_MAC_REQUIRED', encPath, 'enc.slots present but enc.slots_mac absent'),\n );\n }\n if (hasSlotsMac && !hasSlots) {\n issues.push(\n issueOf('ENC_SLOTS_REQUIRED', encPath, 'enc.slots_mac present but enc.slots absent'),\n );\n }\n if (hasSlots && !hasKem) {\n issues.push(issueOf('ENC_KEM_REQUIRED', encPath, 'enc.slots present but enc.kem absent'));\n }\n if (!hasSlots && !hasPassphrase) {\n issues.push(\n issueOf(\n 'ENC_NO_KEY_PATH',\n encPath,\n 'enc requires either slots or passphrase — no on-chain key path otherwise',\n ),\n );\n }\n\n if (hasSlots) {\n const slots = enc.slots!;\n if (slots.length < 1) {\n issues.push(\n issueOf('ENC_SLOTS_EMPTY', [...encPath, 'slots'], 'slots[] must carry at least one slot'),\n );\n } else if (slots.length > opts.maxSlots) {\n // Slot-count resource bound: reject before walking any slot, so a\n // hostile record cannot drive unbounded per-slot work.\n issues.push(\n issueOf(\n 'ENC_SLOTS_TOO_MANY',\n [...encPath, 'slots'],\n `slots length ${slots.length} exceeds the slot-count bound ${opts.maxSlots}`,\n ),\n );\n } else if (hasKem) {\n // The descriptor exists — `kem` is registered on this path.\n const descriptor = KEM_SLOT_DESCRIPTORS[enc.kem!]!;\n const rawSlotKeys = rawSlotKeySets(rawEnc);\n // Per-slot KEK uniqueness: the zero-nonce per-slot wrap is safe only\n // because each slot draws fresh KEM randomness; two slots sharing the\n // same encapsulation material would derive the same KEK. Reject the\n // repeat before any cryptographic layer would.\n const seenKemMaterial = new Set<string>();\n slots.forEach((slot, si) => {\n const slotPath = [...encPath, 'slots', si] as const;\n checkSlotShape(\n slot,\n rawSlotKeys[si] ?? new Set<string>(),\n descriptor,\n enc.kem!,\n slotPath,\n issues,\n );\n const material = descriptor.field === 'epk' ? slot.epk : slot.kem_ct;\n if (material !== undefined) {\n const key = bytesToHex(material);\n if (seenKemMaterial.has(key)) {\n issues.push(\n issueOf(\n 'ENC_SLOTS_DUPLICATE_KEM_MATERIAL',\n [...slotPath, descriptor.field],\n `slot ${si} ${descriptor.field} duplicates an earlier slot — per-slot KEK uniqueness is violated`,\n ),\n );\n } else {\n seenKemMaterial.add(key);\n }\n }\n });\n }\n }\n\n if (hasPassphrase) {\n checkPassphraseBlock(enc.passphrase!, [...encPath, 'passphrase'], opts, issues);\n }\n}\n\n// KEM-driven per-slot shape gate. The descriptor for the declared envelope\n// `kem` pins which ciphertext-bearing field MUST be present at what exact\n// length, and forbids everything else: the other KEM's field, any stray key\n// (a slot is a CLOSED 2-key map), and a missing required field all surface\n// as ENC_SLOT_INVALID_SHAPE. `rawKeys` is the slot's key set exactly as it\n// appeared on the wire, so the permissive slot schema cannot mask a foreign\n// field.\nconst SLOT_KEY_UNIVERSE: ReadonlySet<string> = new Set(['epk', 'kem_ct', 'wrap']);\n\nfunction checkSlotShape(\n slot: Slot,\n rawKeys: ReadonlySet<string>,\n descriptor: KemSlotDescriptor,\n kem: string,\n slotPath: ReadonlyArray<string | number>,\n issues: ValidationIssue[],\n): void {\n const foreignField: KemSlotField = descriptor.field === 'epk' ? 'kem_ct' : 'epk';\n if (rawKeys.has(foreignField)) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, foreignField],\n `slot carries '${foreignField}' but kem='${kem}' expects '${descriptor.field}'`,\n ),\n );\n }\n for (const key of rawKeys) {\n if (!SLOT_KEY_UNIVERSE.has(key)) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, key],\n `slot carries unexpected key '${key}'; a slot is a 2-key map {${descriptor.field}, wrap}`,\n ),\n );\n }\n }\n\n const ctField = descriptor.field === 'epk' ? slot.epk : slot.kem_ct;\n if (ctField === undefined) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, descriptor.field],\n `slot for kem='${kem}' is missing required '${descriptor.field}'`,\n ),\n );\n } else if (ctField.length !== descriptor.fieldLength) {\n issues.push(\n issueOf(\n KEM_FIELD_LENGTH_CODE[descriptor.field],\n [...slotPath, descriptor.field],\n `slot.${descriptor.field} length ${ctField.length} != ${descriptor.fieldLength} for ${kem}`,\n ),\n );\n }\n\n if (slot.wrap === undefined) {\n issues.push(\n issueOf(\n 'ENC_SLOT_INVALID_SHAPE',\n [...slotPath, 'wrap'],\n `slot for kem='${kem}' is missing required 'wrap'`,\n ),\n );\n } else if (slot.wrap.length !== descriptor.wrapLength) {\n issues.push(\n issueOf(\n 'WRAP_LENGTH_MISMATCH',\n [...slotPath, 'wrap'],\n `slot.wrap length ${slot.wrap.length} != ${descriptor.wrapLength}`,\n ),\n );\n }\n}\n\n// Passphrase block: KDF registry membership, then the registered algorithm's\n// CLOSED parameter map with exact-integer range, floors, and the deployment\n// ceiling. Salt bounds are schema refinements and have already fired.\nfunction checkPassphraseBlock(\n pp: PassphraseBlock,\n ppPath: ReadonlyArray<string | number>,\n opts: ResolvedOptions,\n issues: ValidationIssue[],\n): void {\n if (!PASSPHRASE_KDF_ALGS.has(pp.alg)) {\n issues.push(\n issueOf(\n 'ENC_PASSPHRASE_ALG_UNSUPPORTED',\n [...ppPath, 'alg'],\n `unknown passphrase kdf alg: ${pp.alg}`,\n ),\n );\n return; // no algorithm-specific params rule can apply\n }\n\n // argon2id: `params` is the CLOSED map of exactly {m, t, p}.\n const paramsPath = [...ppPath, 'params'] as const;\n const params = pp.params;\n for (const key of Object.keys(params)) {\n if (key !== 'm' && key !== 't' && key !== 'p') {\n issues.push(\n issueOf(\n 'SCHEMA_UNKNOWN_FIELD',\n [...paramsPath, key],\n `unknown argon2id params field: ${key}`,\n ),\n );\n }\n }\n\n const floors = { m: 65_536, t: 3, p: 1 } as const;\n const ceiling = opts.passphraseParamsCeiling;\n for (const name of ['m', 't', 'p'] as const) {\n const value: unknown = params[name];\n if (value === undefined) {\n issues.push(\n issueOf(\n 'SCHEMA_MISSING_REQUIRED',\n [...paramsPath, name],\n `argon2id params.${name} is required`,\n ),\n );\n continue;\n }\n // Exact-integer discipline: values above 2^53 − 1 arrive as `bigint`,\n // so an out-of-range value is rejected without precision loss.\n if (!isUint(value)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...paramsPath, name],\n `argon2id params.${name} must be a CBOR unsigned integer`,\n ),\n );\n continue;\n }\n if (!uintWithin(value, 0, UINT32_MAX)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...paramsPath, name],\n `argon2id params.${name} exceeds the pinned wire range 0 .. 2^32 - 1`,\n ),\n );\n continue;\n }\n const num = Number(value);\n if (num < floors[name]) {\n issues.push(\n issueOf(\n 'ENC_PASSPHRASE_ARGON2_PARAMS_TOO_LOW',\n [...paramsPath, name],\n `argon2id requires ${name} >= ${floors[name]}`,\n ),\n );\n continue;\n }\n if (ceiling !== null && num > ceiling[name]) {\n issues.push(\n issueOf(\n 'ENC_PASSPHRASE_PARAMS_EXCEED_POLICY',\n [...paramsPath, name],\n `argon2id params.${name} = ${num} exceeds the deployment ceiling ${ceiling[name]}`,\n ),\n );\n }\n }\n}\n\n// Extract the per-slot RAW key sets from the decoded `enc` value, so the\n// closed-slot rule sees keys the permissive slot schema does not model. The\n// canonical decoder yields a plain object for a text-keyed CBOR map and a\n// `Map` for a map carrying any non-text key.\nfunction rawSlotKeySets(rawEnc: object): ReadonlyArray<ReadonlySet<string>> {\n const slots = (rawEnc as Record<string, unknown>)['slots'];\n if (!Array.isArray(slots)) return [];\n return slots.map((slot) => {\n const keys = new Set<string>();\n if (slot instanceof Map) {\n for (const k of slot.keys()) if (typeof k === 'string') keys.add(k);\n } else if (typeof slot === 'object' && slot !== null) {\n for (const k of Object.keys(slot as Record<string, unknown>)) keys.add(k);\n }\n return keys;\n });\n}\n\n// =============================================================================\n// Merkle commitments\n// =============================================================================\n\nfunction checkMerkleCommit(commit: MerkleCommit, idx: number, issues: ValidationIssue[]): void {\n const basePath: ReadonlyArray<string | number> = ['merkle', idx];\n if (!(commit.alg in MERKLE_COMMIT_ALG_LENGTHS)) {\n issues.push(\n issueOf(\n 'UNSUPPORTED_MERKLE_COMMIT_ALG',\n [...basePath, 'alg'],\n `unknown merkle commitment alg: ${commit.alg}`,\n ),\n );\n } else {\n const expected = MERKLE_COMMIT_ALG_LENGTHS[commit.alg]!;\n if (commit.root.length !== expected) {\n issues.push(\n issueOf(\n 'HASH_DIGEST_LENGTH_MISMATCH',\n [...basePath, 'root'],\n `merkle entry root length ${commit.root.length} != ${expected} for ${commit.alg}`,\n ),\n );\n }\n }\n\n // `leaf_count` is REQUIRED and pinned to `1 .. 2^32 − 1`, compared as an\n // exact integer: the decoder surfaces values above 2^53 − 1 as `bigint`,\n // so 2^53 + 1 cannot round to a boundary value before rejection. A\n // negative value is a CBOR type violation (nint where uint is required),\n // distinct from an out-of-range unsigned value.\n const leafCount = commit.leaf_count;\n if (!isUint(leafCount)) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n [...basePath, 'leaf_count'],\n 'leaf_count must be a CBOR unsigned integer',\n ),\n );\n } else if (!uintWithin(leafCount, 1, UINT32_MAX)) {\n issues.push(\n issueOf(\n 'SCHEMA_MERKLE_LEAF_COUNT_INVALID',\n [...basePath, 'leaf_count'],\n `leaf_count ${String(leafCount)} is outside the pinned range 1 .. 2^32 - 1`,\n ),\n );\n }\n\n if (commit.uris !== undefined) {\n checkUris(commit.uris, [...basePath, 'uris'], issues);\n }\n}\n\n// =============================================================================\n// Record-level signature entries\n// =============================================================================\n\nfunction checkSigEntry(entry: SigEntry, idx: number, issues: ValidationIssue[]): void {\n // Path-2 `cose_key` private-material guard runs FIRST: a leaked private\n // scalar must be named even when the COSE_Sign1 is also malformed.\n if (entry.cose_key !== undefined) {\n const keyIssue = inspectCoseKey(entry.cose_key, idx);\n if (keyIssue !== null) {\n issues.push(keyIssue);\n return;\n }\n }\n\n let cose: ReturnType<typeof decodeCoseSign1>;\n try {\n cose = decodeCoseSign1(entry.cose_sign1);\n } catch (cause) {\n issues.push(\n issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', idx],\n cause instanceof CoseVerifyError || cause instanceof Error ? cause.message : String(cause),\n ),\n );\n return;\n }\n\n // Detached-only: the COSE_Sign1 payload MUST be CBOR null. An attached\n // payload — even zero-length — is rejected; a producer chaining a CIP-30\n // signData result must null the payload before embedding.\n if (cose.payload !== null) {\n issues.push(\n issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', idx],\n 'COSE_Sign1 payload must be null (detached); attached form forbidden',\n ),\n );\n return;\n }\n\n // Signature-algorithm registry check (info severity — signatures are\n // optional, so an unrecognised algorithm never fails the record alone).\n const alg = cose.protectedHeader.get(1);\n if (typeof alg !== 'number' || !KNOWN_SIG_ALG_IDS.has(alg)) {\n issues.push(\n issueOf(\n 'SIGNATURE_UNSUPPORTED',\n ['sigs', idx],\n `COSE_Sign1 protected alg ${String(alg)} not in {-8, -19}`,\n ),\n );\n }\n\n // Path-1 (32-byte protected-header `kid`) and path-2 (`cose_key` sidecar)\n // are mutually exclusive.\n const protectedKid = cose.protectedHeader.get(4);\n if (\n protectedKid instanceof Uint8Array &&\n protectedKid.length === 32 &&\n entry.cose_key !== undefined\n ) {\n issues.push(\n issueOf(\n 'SIG_ENTRY_KID_COSE_KEY_CONFLICT',\n ['sigs', idx],\n 'sigs[i] carries both a 32-byte protected `kid` (path 1) and an inline `cose_key` (path 2); paths are mutually exclusive',\n ),\n );\n }\n}\n\n// COSE_Key inspector (path-2 `sigs[i].cose_key` blob). Two structural checks:\n// 1. Private-material guard (FIRST). COSE_Key label `-4` (the private\n// scalar `d` for OKP / EC2 per RFC 9052 §7.1) → SIG_PRIVATE_KEY_LEAKED.\n// Publishing a private key on the permanent ledger is catastrophic and\n// irreversible, so this is a load-bearing producer-side preflight.\n// 2. Positive-shape guard: `kty = 1` (OKP), `crv = 6` (Ed25519), and a\n// 32-byte `-2` (x). Any failure → MALFORMED_SIG_COSE_SIGN1.\nfunction inspectCoseKey(keyBytes: Uint8Array, i: number): ValidationIssue | null {\n let decoded: unknown;\n try {\n decoded = decodeCanonicalCbor(keyBytes);\n } catch (cause) {\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key failed to decode as cbor<COSE_Key>: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n\n // A COSE_Key map is int-keyed, so the canonical decoder surfaces it as a\n // `Map`; a text-keyed look-alike arrives as a plain object and fails the\n // label lookups below.\n const getLabel = (label: number): unknown => {\n if (decoded instanceof Map) return decoded.get(label);\n return undefined;\n };\n const hasLabel = (label: number): boolean => {\n if (decoded instanceof Map) return decoded.has(label);\n return false;\n };\n\n if (hasLabel(-4)) {\n return issueOf(\n 'SIG_PRIVATE_KEY_LEAKED',\n ['sigs', i, 'cose_key'],\n 'cose_key carries COSE_Key private-key material (label -4, the OKP/EC2 private scalar d); publishing a private key on the permanent ledger is forbidden',\n );\n }\n\n const kty = getLabel(1);\n if (kty !== 1) {\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key COSE_Key kty (label 1) must be 1 (OKP); got ${String(kty)}`,\n );\n }\n const crv = getLabel(-1);\n if (crv !== 6) {\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key COSE_Key crv (label -1) must be 6 (Ed25519); got ${String(crv)}`,\n );\n }\n const x = getLabel(-2);\n if (!(x instanceof Uint8Array) || x.length !== 32) {\n const got = x instanceof Uint8Array ? `${x.length}-byte bstr` : typeof x;\n return issueOf(\n 'MALFORMED_SIG_COSE_SIGN1',\n ['sigs', i, 'cose_key'],\n `sigs[${i}].cose_key COSE_Key label -2 must be a 32-byte byte string (Ed25519 public key); got ${got}`,\n );\n }\n return null;\n}\n\n// =============================================================================\n// `crit[]` shape + critical-extension support\n// =============================================================================\n\nfunction checkCrit(\n record: PoeRecord,\n decodedTopKeys: ReadonlySet<string>,\n supportedCriticalExtensions: ReadonlySet<string>,\n issues: ValidationIssue[],\n): void {\n if (!Array.isArray(record.crit)) return;\n // `crit` has `1*` cardinality: an empty array is a malformed shape.\n if (record.crit.length === 0) {\n issues.push(\n issueOf(\n 'SCHEMA_TYPE_MISMATCH',\n ['crit'],\n 'crit[] must carry at least one entry when present',\n ),\n );\n return;\n }\n const seen = new Set<string>();\n for (let i = 0; i < record.crit.length; i++) {\n const critName = record.crit[i]!;\n let reason: string | null = null;\n if (TOP_LEVEL_BASE_KEYS.has(critName)) {\n reason = `'${critName}' is a base key and MUST NOT appear in crit[]`;\n } else if (!isExtensionKey(critName)) {\n reason = `'${critName}' does not match the extension-key form (^x-.+ or ^[a-z]+-.+, no control characters)`;\n } else if (!decodedTopKeys.has(critName)) {\n reason = `'${critName}' is named in crit but absent from the record map`;\n } else if (seen.has(critName)) {\n reason = `'${critName}' appears more than once in crit[]`;\n }\n seen.add(critName);\n if (reason !== null) {\n issues.push(issueOf('CRIT_SHAPE_INVALID', ['crit', i], reason));\n continue;\n }\n // Shape-valid entry: accepted iff this validator implements the named\n // extension. The default supported set is empty, so a default-configured\n // validator fails every `crit`-bearing record — by design.\n if (!supportedCriticalExtensions.has(critName)) {\n issues.push(\n issueOf(\n 'EXTENSION_UNSUPPORTED_CRITICAL',\n ['crit', i],\n `crit lists extension '${critName}' that this validator does not implement`,\n ),\n );\n }\n }\n}\n\nfunction topLevelKeysOf(decoded: unknown): Set<string> {\n if (decoded === null || typeof decoded !== 'object') return new Set();\n if (decoded instanceof Map) {\n const out = new Set<string>();\n for (const k of decoded.keys()) {\n if (typeof k === 'string') out.add(k);\n }\n return out;\n }\n return new Set(Object.keys(decoded as Record<string, unknown>));\n}\n\n// =============================================================================\n// Label 309 CID profile\n// =============================================================================\n//\n// Accept CIDv0 (`Qm` prefix, 46-char base58btc, sha2-256 multihash) and\n// CIDv1 (multibase prefix + version 0x01 + codec + multihash) per the\n// closed profile:\n// - Multibase: b, B, f, F, z\n// - Multicodec: 0x55 (raw), 0x70 (dag-pb), 0x71 (dag-cbor)\n// - Multihash: 0x12 (sha2-256, 32 B), 0xb220 (blake2b-256, 32 B)\n//\n// Returns true iff the CID conforms to the Label 309 profile.\n\nconst ACCEPTED_CIDV1_MULTIBASE: ReadonlySet<string> = new Set(['b', 'B', 'f', 'F', 'z']);\n\nconst ACCEPTED_MULTICODECS: ReadonlySet<number> = new Set([0x55, 0x70, 0x71]);\n\n// Multihash table: code → digest length (bytes).\nconst ACCEPTED_MULTIHASHES: ReadonlyMap<number, number> = new Map([\n [0x12, 32],\n [0xb220, 32],\n]);\n\nexport function validateCidProfile(cid: string): boolean {\n if (cid.length === 0) return false;\n // CIDv0: a base58btc-encoded sha2-256 multihash. Decode the WHOLE string\n // and verify the multihash prefix (0x12 = sha2-256, 0x20 = 32-byte digest)\n // and total length (34 bytes); a `Qm` prefix alone is not sufficient.\n if (cid.startsWith('Qm')) {\n let decoded: Uint8Array;\n try {\n decoded = decodeBase58btc(cid);\n } catch {\n return false;\n }\n return decoded.length === 34 && decoded[0] === 0x12 && decoded[1] === 0x20;\n }\n // CIDv1: multibase + binary CID body.\n const mbPrefix = cid[0]!;\n if (!ACCEPTED_CIDV1_MULTIBASE.has(mbPrefix)) return false;\n let bytes: Uint8Array;\n try {\n bytes = decodeMultibase(mbPrefix, cid.slice(1));\n } catch {\n return false;\n }\n if (bytes.length < 4) return false;\n // CIDv1 layout: <version varint> <multicodec varint> <multihash>\n const versionParse = readVarint(bytes, 0);\n if (versionParse === null || versionParse.value !== 1) return false;\n const codecParse = readVarint(bytes, versionParse.next);\n if (codecParse === null) return false;\n if (!ACCEPTED_MULTICODECS.has(codecParse.value)) return false;\n const mhParse = readVarint(bytes, codecParse.next);\n if (mhParse === null) return false;\n const lenParse = readVarint(bytes, mhParse.next);\n if (lenParse === null) return false;\n const digestLen = lenParse.value;\n const expectedLen = ACCEPTED_MULTIHASHES.get(mhParse.value);\n if (expectedLen === undefined || digestLen !== expectedLen) return false;\n if (lenParse.next + digestLen !== bytes.length) return false;\n return true;\n}\n\nfunction readVarint(bytes: Uint8Array, start: number): { value: number; next: number } | null {\n let value = 0;\n let shift = 0;\n let i = start;\n while (i < bytes.length) {\n const b = bytes[i]!;\n value |= (b & 0x7f) << shift;\n i++;\n if ((b & 0x80) === 0) return { value, next: i };\n shift += 7;\n if (shift > 28) return null; // overflow guard; the profile uses ≤ 16-bit codes\n }\n return null;\n}\n\n// Multibase decoders for the closed set the CID profile admits.\n//\n// The body is decoded VERBATIM against the case the prefix advertises — never\n// case-folded. RFC 4648 base32/base16 each have a distinct lower- and\n// upper-case multibase prefix (`b`/`B`, `f`/`F`); a body whose case disagrees\n// with its prefix is not a canonical CID and is rejected, not silently folded\n// into the advertised case.\nfunction decodeMultibase(prefix: string, body: string): Uint8Array {\n switch (prefix) {\n case 'b':\n return decodeBase32(body, 'rfc4648-lower');\n case 'B':\n return decodeBase32(body, 'rfc4648-upper');\n case 'f':\n return decodeBase16(body, 'lower');\n case 'F':\n return decodeBase16(body, 'upper');\n case 'z':\n return decodeBase58btc(body);\n default:\n throw new Error(`unsupported multibase prefix ${prefix}`);\n }\n}\n\nconst BASE16_LOWER = '0123456789abcdef';\nconst BASE16_UPPER = '0123456789ABCDEF';\n\nfunction decodeBase16(s: string, variant: 'lower' | 'upper'): Uint8Array {\n if (s.length % 2 !== 0) throw new Error('base16: odd-length');\n const alphabet = variant === 'lower' ? BASE16_LOWER : BASE16_UPPER;\n const out = new Uint8Array(s.length / 2);\n for (let i = 0; i < out.length; i++) {\n const hi = alphabet.indexOf(s[i * 2]!);\n const lo = alphabet.indexOf(s[i * 2 + 1]!);\n if (hi < 0 || lo < 0) throw new Error(`base16: non-hex char at ${i * 2}`);\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nconst BASE32_RFC4648_LOWER = 'abcdefghijklmnopqrstuvwxyz234567';\nconst BASE32_RFC4648_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n\nfunction decodeBase32(s: string, variant: 'rfc4648-lower' | 'rfc4648-upper'): Uint8Array {\n const alphabet = variant === 'rfc4648-lower' ? BASE32_RFC4648_LOWER : BASE32_RFC4648_UPPER;\n // Multibase strips padding per spec; accept either form for robustness.\n const trimmed = s.replace(/=+$/, '');\n const out: number[] = [];\n let buf = 0;\n let bits = 0;\n for (const ch of trimmed) {\n const idx = alphabet.indexOf(ch);\n if (idx < 0) throw new Error(`base32: invalid char '${ch}'`);\n buf = (buf << 5) | idx;\n bits += 5;\n if (bits >= 8) {\n bits -= 8;\n out.push((buf >> bits) & 0xff);\n }\n }\n return Uint8Array.from(out);\n}\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\nfunction decodeBase58btc(s: string): Uint8Array {\n if (s.length === 0) return new Uint8Array(0);\n let zeros = 0;\n while (zeros < s.length && s[zeros] === '1') zeros++;\n const size = Math.floor(((s.length - zeros) * 733) / 1000) + 1;\n const b256 = new Uint8Array(size);\n let length = 0;\n for (let i = zeros; i < s.length; i++) {\n const ch = s[i]!;\n const carryIdx = BASE58_ALPHABET.indexOf(ch);\n if (carryIdx < 0) throw new Error(`base58: invalid char '${ch}'`);\n let carry = carryIdx;\n let k = 0;\n for (let j = size - 1; (carry !== 0 || k < length) && j >= 0; j--, k++) {\n carry += 58 * b256[j]!;\n b256[j] = carry % 256;\n carry = Math.floor(carry / 256);\n }\n length = k;\n }\n let it = size - length;\n while (it < size && b256[it] === 0) it++;\n const out = new Uint8Array(zeros + (size - it));\n let j = zeros;\n while (it < size) {\n out[j++] = b256[it++]!;\n }\n return out;\n}\n\n// Hex rendering for byte-equality keys (the duplicate-KEM-material set).\nfunction bytesToHex(bytes: Uint8Array): string {\n let out = '';\n for (const b of bytes) out += b.toString(16).padStart(2, '0');\n return out;\n}\n\n// =============================================================================\n// Exact-integer helpers\n// =============================================================================\n\n// A CBOR unsigned integer as the canonical decoder surfaces it: a\n// non-negative `number` for values up to 2^53 − 1, a non-negative `bigint`\n// above (exact in both representations). A negative value is a different\n// CBOR major type and is never a uint.\nfunction isUint(value: unknown): value is number | bigint {\n if (typeof value === 'number') return Number.isInteger(value) && value >= 0;\n if (typeof value === 'bigint') return value >= 0n;\n return false;\n}\n\nfunction uintWithin(value: number | bigint, min: number, max: number): boolean {\n if (typeof value === 'bigint') return value >= BigInt(min) && value <= BigInt(max);\n return value >= min && value <= max;\n}\n\n// =============================================================================\n// Issue construction and deterministic ordering\n// =============================================================================\n\nfunction issueOf(\n code: ErrorCode,\n path: ReadonlyArray<string | number>,\n message: string,\n): ValidationIssue {\n return { code, path, message, severity: SEVERITY[code] };\n}\n\nconst PATH_UTF8 = new TextEncoder();\n\n// Bytewise comparison of the UTF-8 encodings — the only collation that is\n// byte-stable across runs and across language implementations (no locale\n// tables, no UTF-16 code-unit artefacts for non-BMP keys).\nfunction compareTextSegments(a: string, b: string): number {\n const ab = PATH_UTF8.encode(a);\n const bb = PATH_UTF8.encode(b);\n const n = Math.min(ab.length, bb.length);\n for (let i = 0; i < n; i++) {\n const d = ab[i]! - bb[i]!;\n if (d !== 0) return d;\n }\n return ab.length - bb.length;\n}\n\n// Segment-wise path order: integer segments compare numerically, text\n// segments compare by UTF-8 bytes, an integer segment orders before a text\n// segment where the kinds differ, and a strict prefix orders before its\n// extensions. Issues on an identical path tie-break by the position of their\n// code in the canonical error-code registry.\nfunction compareIssues(a: ValidationIssue, b: ValidationIssue): number {\n const ap = a.path;\n const bp = b.path;\n const n = Math.min(ap.length, bp.length);\n for (let i = 0; i < n; i++) {\n const x = ap[i]!;\n const y = bp[i]!;\n const xIsNum = typeof x === 'number';\n const yIsNum = typeof y === 'number';\n if (xIsNum !== yIsNum) return xIsNum ? -1 : 1;\n if (xIsNum && yIsNum) {\n if (x !== y) return (x as number) < (y as number) ? -1 : 1;\n } else {\n const d = compareTextSegments(x as string, y as string);\n if (d !== 0) return d;\n }\n }\n if (ap.length !== bp.length) return ap.length - bp.length;\n return errorCodeRegistryIndex(a.code) - errorCodeRegistryIndex(b.code);\n}\n\nfunction sortIssues(issues: ReadonlyArray<ValidationIssue>): ValidationIssue[] {\n return [...issues].sort(compareIssues);\n}\n\nfunction valueAtPath(root: unknown, path: ReadonlyArray<string | number>): unknown {\n let cur: unknown = root;\n for (const seg of path) {\n if (cur === null || cur === undefined) return undefined;\n if (cur instanceof Map) {\n cur = cur.get(seg);\n continue;\n }\n if (typeof cur !== 'object') return undefined;\n cur = (cur as Record<string | number, unknown>)[seg];\n }\n return cur;\n}\n","// Label 309 v1 off-host signing helper. The signing key never leaves the user\n// device — this module touches only the public-data inputs (record bytes +\n// pubkey) and the public-data output (the 64-byte Ed25519 signature). The\n// integrator's signer callback owns the private key material.\n//\n// Wire-format invariants enforced by this module:\n// - Sig_structure carries the 25-byte UTF-8 domain prefix\n// `cardano-poe-record-sig-v1` with `external_aad = h''` (RFC 9052 §4.4\n// under the CIP-30 compatibility constraint).\n// - COSE_Sign1 (RFC 9052 §4.2) has a detached payload: COSE_Sign1[2] = CBOR\n// null. CIP-8 `hashed = true` mode places the literal text key\n// `\"hashed\"` in the unprotected header.\n// - Path-1 `kid-as-public-key` convention: 32-byte raw Ed25519 pubkey in\n// protected header label 4; path-1 / path-2 are mutually exclusive on\n// the wire.\n// - `sigs[i].cose_sign1` is a SINGLE byte string carrying the whole\n// COSE_Sign1; the only chunking in the format is the whole-body\n// transport array under metadata label 309.\n//\n// Use cases (the four integration shapes this surface is intended for):\n// 1. AWS KMS `Sign` over the returned Sig_structure bytes — wrap KMS as\n// `(bytes) => Promise<signature>`.\n// 2. Google Cloud HSM — same `(bytes) => Promise<signature>` shape.\n// 3. YubiHSM — local hardware-backed signer; same shape via the YubiHSM SDK.\n// 4. Air-gapped offline signer — transport the Sig_structure bytes via QR /\n// USB / sneakernet to the offline workstation; transport the 64-byte\n// Ed25519 signature back.\n//\n// This module is PATH-1 ONLY. The CIP-30 wallet path (path-2) is handled\n// separately — adding a `cose_key` sidecar here would violate the path-1 /\n// path-2 mutual-exclusion rule (SIG_ENTRY_KID_COSE_KEY_CONFLICT).\n//\n// Hashed-mode (`prepareSigStructureHashed` / `assembleCoseSign1Hashed`) is\n// DISCOURAGED for software off-host signers (AWS KMS, GCP HSM, YubiHSM —\n// each accepts arbitrary-length input) — use the non-hashed mode instead.\n// Hashed mode exists only for hardware co-signers with limited screen /\n// buffer. The verifier MUST recognise the `\"hashed\": true` unprotected-header\n// flag and substitute `Sig_structure[3]` with `Blake2b-224(to_sign)` before\n// strict Ed25519 verification.\n//\n// Privacy contract: the SDK never sees, stores, logs, or transmits any byte\n// string that contains the integrator's Ed25519 private signing key. The\n// integrator's signer handles the seed; this module touches only the 32-byte\n// public key and the 64-byte signature (both public data).\n//\n// The Python SDK carries the same builder (snake_case function names);\n// byte-identical outputs across the two are enforced by a shared\n// known-answer-test corpus.\n\nimport { encodeCanonicalCbor, type CanonicalCborValue } from '@cardanowall/crypto-core/cbor';\nimport {\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES,\n buildLabel309SigStructure,\n buildSigStructure,\n encodeCoseSign1,\n type CoseHeader,\n} from '@cardanowall/crypto-core/cose';\nimport { blake2b224 } from '@cardanowall/crypto-core/hash';\nimport {\n encodeRecordBodyForSigning,\n type PoeRecord,\n type SigEntry,\n} from '@cardanowall/poe-standard';\n\nconst EMPTY_BYTES = new Uint8Array(0);\nconst ED25519_PUBLIC_KEY_LENGTH = 32;\nconst ED25519_SIGNATURE_LENGTH = 64;\n\n// Copy into a freshly allocated buffer so the emitted `sigs[i]` entry owns its\n// bytes (and satisfies the schema's `Uint8Array<ArrayBuffer>` requirement).\nfunction cloneToOwnedBuffer(src: Uint8Array): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(new ArrayBuffer(src.length));\n out.set(src);\n return out;\n}\n\nexport type OffHostSignErrorCode = 'INVALID_PUBKEY_LENGTH' | 'INVALID_SIGNATURE_LENGTH';\n\nexport class OffHostSignError extends Error {\n readonly code: OffHostSignErrorCode;\n\n constructor(code: OffHostSignErrorCode, message: string) {\n super(message);\n this.name = 'OffHostSignError';\n this.code = code;\n }\n}\n\nexport interface PrepareSigStructureArgs {\n readonly record: PoeRecord;\n readonly signerPubkey: Uint8Array;\n}\n\nexport interface PrepareSigStructureResult {\n readonly sigStructureBytes: Uint8Array;\n readonly protectedHeaderBytes: Uint8Array;\n}\n\nexport interface PrepareSigStructureHashedResult extends PrepareSigStructureResult {\n readonly toSignHashBytes: Uint8Array;\n}\n\nexport interface AssembleCoseSign1Args {\n readonly record: PoeRecord;\n readonly signerPubkey: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface AssembleCoseSign1Result {\n readonly coseSign1Bytes: Uint8Array;\n readonly sigEntry: SigEntry;\n}\n\n// `to_sign = utf8(\"cardano-poe-record-sig-v1\") || canonical_cbor(record_body_minus_sigs)`.\n// The first 25 bytes are byte-pinned to the prefix constant; bytes 25..end\n// are the canonical CBOR of the record body with `sigs` removed.\nexport function buildToSign(record: PoeRecord): Uint8Array {\n const body = encodeRecordBodyForSigning(record);\n const out = new Uint8Array(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + body.length);\n out.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n out.set(body, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n return out;\n}\n\n// Path-1 protected header canonical CBOR for `{1: -8, 4: <signerPubkey>}`.\n// Always 38 bytes: `a2 01 27 04 58 20 || <32-byte pubkey>`.\nfunction encodePath1ProtectedHeader(signerPubkey: Uint8Array): {\n protectedHeader: CoseHeader;\n protectedHeaderBytes: Uint8Array;\n} {\n const protectedHeader: CoseHeader = new Map<number | string, unknown>([\n [1, -8],\n [4, signerPubkey],\n ]);\n const protectedHeaderBytes = encodeCanonicalCbor(protectedHeader as CanonicalCborValue);\n return { protectedHeader, protectedHeaderBytes };\n}\n\n// Returns the full `Sig_structure = [ \"Signature1\", protected_bytes, h'', to_sign ]`\n// canonical-CBOR bytes that the off-host signer feeds verbatim to Ed25519.\n// `protectedHeaderBytes` is exposed so integrators can byte-compare against\n// fixtures (always 38 bytes for the path-1 `{1:-8, 4:<pub>}` map).\nexport function prepareSigStructure(args: PrepareSigStructureArgs): PrepareSigStructureResult {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n const { protectedHeaderBytes } = encodePath1ProtectedHeader(args.signerPubkey);\n const recordBodyCbor = encodeRecordBodyForSigning(args.record);\n const sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: protectedHeaderBytes,\n recordBodyCbor,\n });\n return { sigStructureBytes, protectedHeaderBytes };\n}\n\n// Assembles `COSE_Sign1 = [ protected_bytes, unprotected_map, null, signature ]`\n// (detached payload, `alg = -8`, protected `kid = signerPubkey`) and emits a\n// path-1-only `{cose_sign1}` `sigs[i]` entry carrying the whole blob as one\n// byte string.\nexport function assembleCoseSign1(args: AssembleCoseSign1Args): AssembleCoseSign1Result {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n if (args.signature.length !== ED25519_SIGNATURE_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_SIGNATURE_LENGTH',\n `signature must be 64 bytes (Ed25519 raw signature), got ${args.signature.length}`,\n );\n }\n const { protectedHeader } = encodePath1ProtectedHeader(args.signerPubkey);\n const coseSign1Bytes = encodeCoseSign1({\n protectedHeader,\n unprotectedHeader: new Map(),\n payload: null,\n signature: args.signature,\n });\n const sigEntry: SigEntry = { cose_sign1: cloneToOwnedBuffer(coseSign1Bytes) };\n return { coseSign1Bytes, sigEntry };\n}\n\n// CIP-8 `hashed = true` companion. Substitutes `Sig_structure[3]` with\n// `Blake2b-224(to_sign)`. The hash covers the ENTIRE `to_sign` payload\n// (i.e. `utf8(prefix) || record_body_cbor`) — keeping the 25-byte domain\n// separator inside the hash boundary preserves cross-protocol replay\n// protection even in hashed mode.\n//\n// DISCOURAGED for software off-host signers; use only for hardware co-signers\n// with screen / buffer constraints.\nexport function prepareSigStructureHashed(\n args: PrepareSigStructureArgs,\n): PrepareSigStructureHashedResult {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n const { protectedHeaderBytes } = encodePath1ProtectedHeader(args.signerPubkey);\n const toSign = buildToSign(args.record);\n const toSignHashBytes = blake2b224(toSign);\n const sigStructureBytes = buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: protectedHeaderBytes,\n externalAad: EMPTY_BYTES,\n payload: toSignHashBytes,\n });\n return { sigStructureBytes, protectedHeaderBytes, toSignHashBytes };\n}\n\n// Assemble hashed-mode COSE_Sign1. The unprotected header carries\n// `\"hashed\": true` (text key), signalling to the verifier that the\n// Blake2b-224 substitution applies.\nexport function assembleCoseSign1Hashed(args: AssembleCoseSign1Args): AssembleCoseSign1Result {\n if (args.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_PUBKEY_LENGTH',\n `signerPubkey must be 32 bytes (Ed25519 raw public key), got ${args.signerPubkey.length}`,\n );\n }\n if (args.signature.length !== ED25519_SIGNATURE_LENGTH) {\n throw new OffHostSignError(\n 'INVALID_SIGNATURE_LENGTH',\n `signature must be 64 bytes (Ed25519 raw signature), got ${args.signature.length}`,\n );\n }\n const { protectedHeader } = encodePath1ProtectedHeader(args.signerPubkey);\n const unprotectedHeader: CoseHeader = new Map<number | string, unknown>([['hashed', true]]);\n const coseSign1Bytes = encodeCoseSign1({\n protectedHeader,\n unprotectedHeader,\n payload: null,\n signature: args.signature,\n });\n const sigEntry: SigEntry = { cose_sign1: cloneToOwnedBuffer(coseSign1Bytes) };\n return { coseSign1Bytes, sigEntry };\n}\n","// RFC 7807 `application/problem+json` envelope and the typed error class\n// hierarchy the SDK throws on every non-2xx response.\n//\n// Every Label 309 gateway `/api/v1/*` route emits the canonical shape:\n//\n// Content-Type: application/problem+json\n// {\n// \"type\": \"about:blank\",\n// \"title\": \"Payment Required\",\n// \"status\": 402,\n// \"detail\": \"Required $0.18 for this publish; balance is $0.05.\",\n// \"code\": \"insufficient-funds\",\n// \"trace_id\": \"01977c...\",\n// \"errors\": [{\"field\": \"items.0.hashes\", \"code\": \"invalid_type\", \"detail\": \"...\"}],\n// <extension members per RFC 7807 §3.2, e.g. balance_usd_micros / required_usd_micros>\n// }\n//\n// Field semantics:\n// - `code` is lowercase-kebab. Consumers dispatch on `code`; the SDK already\n// dispatches on `code` to pick the most-specific subclass.\n// - `status` matches the HTTP status. `httpStatus` is a convenience alias.\n// - `errors[]` carries per-field validation errors (Zod-derived on the\n// server). `field` is the dotted JSON path; empty string denotes a\n// body-level issue.\n// - `trace_id` is echoed on the `X-Request-Id` response header for log\n// correlation. Use `err.traceId` when filing bug reports (the SDK\n// surfaces it as the camelCase `traceId` property — only the wire field\n// is snake_case, to match the rest of the API surface).\n// - Extension members (anything outside the canonical seven fields) are\n// surfaced on `err.extensions`. Typed subclasses project the relevant\n// extension fields onto camelCase getters (e.g. `top_up_url` → `topUpUrl`).\n\n/** RFC 7807 per-field error entry. */\nexport interface ProblemErrorEntry {\n /** Dotted JSON path of the offending field; empty for body-level errors. */\n readonly field: string;\n /** Stable lowercase-kebab (or Zod issue) code for the specific failure. */\n readonly code: string;\n /** Human-readable explanation of this individual field error. */\n readonly detail: string;\n}\n\n/**\n * RFC 7807 `application/problem+json` document as emitted by every Label 309\n * gateway `/api/v1/*` route.\n *\n * Canonical fields (`type`, `title`, `status`, `detail`, `code`, `trace_id`)\n * are always present. `errors` is present on validation responses.\n * `instance` is optional per RFC 7807 §3.1.\n *\n * Additional top-level fields are RFC 7807 §3.2 extension members and are\n * preserved verbatim on `Label309HttpError.extensions`.\n */\nexport interface ProblemDetails {\n readonly type: string;\n readonly title: string;\n readonly status: number;\n readonly detail: string;\n readonly code: string;\n readonly trace_id: string;\n readonly errors?: ReadonlyArray<ProblemErrorEntry>;\n readonly instance?: string;\n /** RFC 7807 §3.2 extension members. */\n readonly [extension: string]: unknown;\n}\n\n/** The set of canonical RFC 7807 fields, used to split extensions cleanly. */\nconst CANONICAL_PROBLEM_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'title',\n 'status',\n 'detail',\n 'code',\n 'trace_id',\n 'errors',\n 'instance',\n]);\n\n/**\n * Pull RFC 7807 §3.2 extension members out of a problem document. The result\n * is a fresh object containing every top-level key that is NOT one of the\n * canonical fields above.\n */\nexport function extractProblemExtensions(problem: ProblemDetails): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(problem)) {\n if (!CANONICAL_PROBLEM_KEYS.has(key)) {\n out[key] = value;\n }\n }\n return out;\n}\n\nexport interface Label309HttpErrorInit {\n /** The verbatim problem document. */\n readonly problem: ProblemDetails;\n /** Pre-split extension members. Computed from `problem` when omitted. */\n readonly extensions?: Record<string, unknown>;\n /** Value of the `X-Request-Id` response header. Falls back to `problem.trace_id`. */\n readonly requestId?: string | undefined;\n /** Value of the `Retry-After` response header (seconds), if present. */\n readonly retryAfterSeconds?: number | undefined;\n}\n\n/**\n * Parent class for every typed SDK HTTP error. Carries the full RFC 7807\n * problem document plus headers (`X-Request-Id`, `Retry-After`) relevant for\n * retry logic and log correlation.\n *\n * Consumers can dispatch on:\n * - `err.code` — lowercase-kebab problem code\n * - `err.httpStatus` — HTTP status (= `err.problem.status`)\n * - `instanceof <SpecificError>` — see the subclasses re-exported from\n * `@cardanowall/sdk-ts`\n */\nexport class Label309HttpError extends Error {\n public readonly problem: ProblemDetails;\n public readonly code: string;\n public readonly httpStatus: number;\n public readonly title: string;\n public readonly detail: string;\n public readonly type: string;\n public readonly traceId: string;\n public readonly instance: string | undefined;\n public readonly errors: ReadonlyArray<ProblemErrorEntry> | undefined;\n public readonly extensions: Record<string, unknown>;\n public readonly requestId: string;\n public readonly retryAfterSeconds: number | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init.problem.detail || `${init.problem.title} (HTTP ${init.problem.status})`);\n this.name = 'Label309HttpError';\n this.problem = init.problem;\n this.code = init.problem.code;\n this.httpStatus = init.problem.status;\n this.title = init.problem.title;\n this.detail = init.problem.detail;\n this.type = init.problem.type;\n this.traceId = init.problem.trace_id;\n this.instance = init.problem.instance;\n this.errors = init.problem.errors;\n this.extensions = init.extensions ?? extractProblemExtensions(init.problem);\n // X-Request-Id falls back to the in-body trace_id so callers always have a\n // correlation handle even when the header is stripped by a proxy.\n this.requestId = init.requestId ?? init.problem.trace_id;\n this.retryAfterSeconds = init.retryAfterSeconds;\n }\n}\n","// 400 batch-empty — the `records[]` array on `/api/v1/poe/publish-batch` was\n// empty. The batch endpoint requires at least one record.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class BatchEmptyError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'BatchEmptyError';\n }\n}\n","// 400 batch-too-large — the `records[]` array on `/api/v1/poe/publish-batch`\n// carries more entries than the per-call ceiling (max 50).\n//\n// Wire-format extension members:\n// { \"max\": <int>, \"got\": <int> }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readInt(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nexport class BatchTooLargeError extends Label309HttpError {\n public readonly max: number | undefined;\n public readonly got: number | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'BatchTooLargeError';\n this.max = readInt(this.extensions['max']);\n this.got = readInt(this.extensions['got']);\n }\n}\n","// 403 Forbidden — the caller is authenticated but lacks permission. Covers\n// the generic `forbidden` code plus the edge-proxy `csrf-invalid` flavour;\n// scope-specific failures surface as `InsufficientScopeError` instead.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class ForbiddenError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'ForbiddenError';\n }\n}\n","// 409 idempotency-key-conflict — the supplied `Idempotency-Key` has been\n// seen before with a different request body within its 24h TTL window.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class IdempotencyConflictError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'IdempotencyConflictError';\n }\n}\n","// 402 insufficient-funds — the caller's balance with the gateway is below the\n// cost of the requested operation. This is the generic paid-gateway \"balance\n// too low\" signal; how a particular gateway prices operations and tops up\n// balances is its own concern.\n//\n// Wire-format extension members (RFC 7807 §3.2). Money fields land as decimal\n// strings so JSON parsing preserves bigint precision in callers that parse to\n// Number by default:\n//\n// {\n// \"balance_usd_micros\": \"<decimal string>\",\n// \"required_usd_micros\": \"<decimal string>\",\n// \"top_up_url\": \"<gateway-provided URL, optional>\"\n// }\n//\n// Field-name mapping (wire → SDK):\n// balance_usd_micros → balanceUsdMicros (string → bigint)\n// required_usd_micros → requiredUsdMicros (string → bigint)\n// top_up_url → topUpUrl (snake_case → camelCase)\n//\n// Idempotency contract: a 402 is \"non-committing\" — the gateway does NOT cache\n// the response under the request's Idempotency-Key. After raising the balance,\n// the SDK consumer MAY retry with the SAME Idempotency-Key within the gateway's\n// TTL window; the handler runs fresh and (assuming the balance now suffices)\n// the retry returns 202 with a freshly assigned `id`.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readBigIntString(value: unknown): bigint | undefined {\n if (typeof value !== 'string') return undefined;\n if (!/^-?[0-9]+$/.test(value)) return undefined;\n try {\n return BigInt(value);\n } catch {\n return undefined;\n }\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class InsufficientFundsError extends Label309HttpError {\n public readonly balanceUsdMicros: bigint | undefined;\n public readonly requiredUsdMicros: bigint | undefined;\n public readonly topUpUrl: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InsufficientFundsError';\n this.balanceUsdMicros = readBigIntString(this.extensions['balance_usd_micros']);\n this.requiredUsdMicros = readBigIntString(this.extensions['required_usd_micros']);\n this.topUpUrl = readString(this.extensions['top_up_url']);\n }\n}\n","// 403 insufficient-scope — the API key authenticated but does not grant the\n// scope required for the endpoint.\n//\n// Wire-format extension members:\n// { \"required\": [\"poe:create\"], \"granted\": [\"poe:read\", \"account:read\"] }\n//\n// Both arrays are surfaced verbatim on the typed error. `requiredScope` is a\n// convenience for the common single-scope case (the server emits a one-element\n// `required` array today).\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readScopeArray(value: unknown): ReadonlyArray<string> {\n if (!Array.isArray(value)) return [];\n return value.filter((entry): entry is string => typeof entry === 'string');\n}\n\nexport class InsufficientScopeError extends Label309HttpError {\n public readonly requiredScopes: ReadonlyArray<string>;\n public readonly grantedScopes: ReadonlyArray<string>;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InsufficientScopeError';\n this.requiredScopes = readScopeArray(this.extensions['required']);\n this.grantedScopes = readScopeArray(this.extensions['granted']);\n }\n\n /** Convenience for the single-scope case; first entry of `requiredScopes`. */\n get requiredScope(): string | undefined {\n return this.requiredScopes[0];\n }\n}\n","// 500 internal-error — unexpected server-side failure. The detail message\n// is deliberately generic; correlate the failure via `err.traceId` in\n// server logs.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class InternalServerError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InternalServerError';\n }\n}\n","// 400 invalid-body — the request body was structurally malformed (e.g. not\n// valid JSON, or a higher-level shape check failed before Zod ran). Schema\n// validation failures emit `validation-failed` (→ `ValidationFailedError`)\n// instead.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class InvalidBodyError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'InvalidBodyError';\n }\n}\n","// 400 malformed-cbor — the `record_bytes` payload could not be parsed as\n// canonical CBOR per the Label 309 deterministic encoding rules.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class MalformedCborError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'MalformedCborError';\n }\n}\n","// 404 not-found — generic missing-resource response. Domain-specific 404s\n// (notably `record-not-found`) deserialise to their own subclass.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class NotFoundError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'NotFoundError';\n }\n}\n","// 409 quote-already-consumed — the publish quote referenced by `quote_id`\n// has already been used by a prior /publish call. Quotes are single-use; a\n// freshly-issued quote covers exactly one PoE submission. The caller should\n// request a fresh quote via POST /api/v1/poe/quote and retry.\n//\n// Wire-format extension members (RFC 7807 §3.2):\n// { \"quote_id\": \"<uuid>\" }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class QuoteAlreadyConsumedError extends Label309HttpError {\n public readonly quoteId: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'QuoteAlreadyConsumedError';\n this.quoteId = readString(this.extensions['quote_id']);\n }\n}\n","// 410 quote-expired — the publish quote referenced by `quote_id` exceeded\n// its TTL (15 minutes from issuance) before /publish consumed it. The\n// caller should request a fresh quote via POST /api/v1/poe/quote and retry.\n//\n// Wire-format extension members (RFC 7807 §3.2):\n// { \"quote_id\": \"<uuid>\" }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class QuoteExpiredError extends Label309HttpError {\n public readonly quoteId: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'QuoteExpiredError';\n this.quoteId = readString(this.extensions['quote_id']);\n }\n}\n","// 404 quote-not-found — the supplied `quote_id` does not exist for the\n// authenticated account. Either the UUID is wrong, or the quote belongs to\n// a different account (the server enforces account scoping on quote rows).\n//\n// Wire-format extension members (RFC 7807 §3.2):\n// { \"quote_id\": \"<uuid>\" }\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport class QuoteNotFoundError extends Label309HttpError {\n public readonly quoteId: string | undefined;\n\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'QuoteNotFoundError';\n this.quoteId = readString(this.extensions['quote_id']);\n }\n}\n","// 429 rate-limited — the caller exceeded the per-key request quota.\n//\n// The retry hint lives on the standard `Retry-After` HTTP response header\n// (RFC 9110 §10.2.3). The SDK parses it into `retryAfterSeconds` on the\n// thrown error; the value is undefined if the header is absent or\n// non-numeric. Per RFC 7807, no retry hint appears in the problem body.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class RateLimitedError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'RateLimitedError';\n }\n}\n","// 404 record-not-found — no Label 309 record is registered for the requested\n// tx_hash.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class RecordNotFoundError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'RecordNotFoundError';\n }\n}\n","// 503 service-unavailable — temporary inability to serve the request. The\n// retry hint, if any, is on the standard `Retry-After` header — surfaced on\n// `err.retryAfterSeconds`.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class ServiceUnavailableError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'ServiceUnavailableError';\n }\n}\n","// 401 Unauthorized — caller is not authenticated. The server emits this when\n// the `Authorization: Bearer` header is missing, malformed, or names a\n// revoked / unknown API key.\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class UnauthorizedError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'UnauthorizedError';\n }\n}\n","// 400 validation-failed — the request body parsed as JSON but failed the\n// route's schema check. The per-field issues live on `err.errors[]` (Zod\n// issue codes; e.g. `invalid_type`, `too_small`, `custom`).\n\nimport { Label309HttpError, type Label309HttpErrorInit } from './http-error';\n\nexport class ValidationFailedError extends Label309HttpError {\n constructor(init: Label309HttpErrorInit) {\n super(init);\n this.name = 'ValidationFailedError';\n }\n}\n","// Decodes an RFC 7807 `application/problem+json` body into the most-specific\n// `Label309HttpError` subclass.\n//\n// Dispatch order:\n// 1. By `code` (lowercase-kebab) — preferred. Each registered code maps to a\n// named subclass with typed projections of its extension members.\n// 2. By HTTP status, when the body is missing/non-conforming. In that case\n// we synthesise a minimal `ProblemDetails` so consumers always see a\n// well-formed `err.problem`.\n//\n// The dispatcher is intentionally exhaustive over the codes the API emits;\n// codes the SDK doesn't recognise fall through to the parent\n// `Label309HttpError` with the verbatim problem document.\n// Forward-compatibility: a server can introduce new codes without breaking\n// older SDKs — consumers either catch the parent class or dispatch on\n// `err.code` directly.\n\nimport { BatchEmptyError } from './batch-empty-error';\nimport { BatchTooLargeError } from './batch-too-large-error';\nimport { ForbiddenError } from './forbidden-error';\nimport {\n Label309HttpError,\n extractProblemExtensions,\n type ProblemDetails,\n type ProblemErrorEntry,\n} from './http-error';\nimport { IdempotencyConflictError } from './idempotency-conflict-error';\nimport { InsufficientFundsError } from './insufficient-funds-error';\nimport { InsufficientScopeError } from './insufficient-scope-error';\nimport { InternalServerError } from './internal-server-error';\nimport { InvalidBodyError } from './invalid-body-error';\nimport { MalformedCborError } from './malformed-cbor-error';\nimport { NotFoundError } from './not-found-error';\nimport { QuoteAlreadyConsumedError } from './quote-already-consumed-error';\nimport { QuoteExpiredError } from './quote-expired-error';\nimport { QuoteNotFoundError } from './quote-not-found-error';\nimport { RateLimitedError } from './rate-limited-error';\nimport { RecordNotFoundError } from './record-not-found-error';\nimport { ServiceUnavailableError } from './service-unavailable-error';\nimport { UnauthorizedError } from './unauthorized-error';\nimport { ValidationFailedError } from './validation-failed-error';\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction asProblemErrorEntries(value: unknown): readonly ProblemErrorEntry[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const out: ProblemErrorEntry[] = [];\n for (const entry of value) {\n if (entry === null || typeof entry !== 'object') continue;\n const e = entry as Record<string, unknown>;\n out.push({\n field: typeof e['field'] === 'string' ? e['field'] : '',\n code: typeof e['code'] === 'string' ? e['code'] : '',\n detail: typeof e['detail'] === 'string' ? e['detail'] : '',\n });\n }\n return out;\n}\n\n/** Synthesise a minimal `ProblemDetails` for non-conforming bodies. */\nfunction synthesiseProblem(httpStatus: number, requestId: string | undefined): ProblemDetails {\n const code = `http-${httpStatus}`;\n return {\n type: `about:blank`,\n title: `HTTP ${httpStatus}`,\n status: httpStatus,\n detail: `Server returned HTTP ${httpStatus} without a problem+json body.`,\n code,\n trace_id: requestId ?? '',\n };\n}\n\nfunction toProblemDetails(\n httpStatus: number,\n body: unknown,\n requestId: string | undefined,\n): ProblemDetails {\n if (body === null || typeof body !== 'object') {\n return synthesiseProblem(httpStatus, requestId);\n }\n const b = body as Record<string, unknown>;\n // Heuristic: a real RFC 7807 body has at minimum `code` and `status` or\n // `title`. If neither is present we treat the body as non-conforming.\n const code = asString(b['code']);\n const status = asNumber(b['status']) ?? httpStatus;\n const title = asString(b['title']);\n if (code === undefined && title === undefined) {\n return synthesiseProblem(httpStatus, requestId);\n }\n const errors = asProblemErrorEntries(b['errors']);\n // Preserve every top-level field. `code`/`title`/`status` fall back when\n // the server omitted them; everything else flows through verbatim as\n // RFC 7807 §3.2 extension members.\n const base: Record<string, unknown> = {\n ...b,\n // RFC 7807 §4.2: `about:blank` is the default when no type URI is supplied.\n // The client is gateway-agnostic, so it must not invent a vendor-specific\n // problem-type namespace; the machine-readable discriminator is `code`.\n type: asString(b['type']) ?? 'about:blank',\n title: title ?? `HTTP ${status}`,\n status,\n detail: asString(b['detail']) ?? '',\n code: code ?? `http-${status}`,\n trace_id: asString(b['trace_id']) ?? requestId ?? '',\n };\n if (errors !== undefined) base['errors'] = errors;\n return base as ProblemDetails;\n}\n\nexport interface ParseHttpErrorArgs {\n readonly httpStatus: number;\n readonly body: unknown;\n /** `X-Request-Id` header from the response, when available. */\n readonly requestId?: string | undefined;\n /** `Retry-After` header from the response, parsed as integer seconds. */\n readonly retryAfterSeconds?: number | undefined;\n}\n\nexport function parseHttpError(args: ParseHttpErrorArgs): Label309HttpError {\n const problem = toProblemDetails(args.httpStatus, args.body, args.requestId);\n const extensions = extractProblemExtensions(problem);\n const init = {\n problem,\n extensions,\n requestId: args.requestId,\n retryAfterSeconds: args.retryAfterSeconds,\n } as const;\n\n switch (problem.code) {\n case 'unauthorized':\n return new UnauthorizedError(init);\n case 'forbidden':\n case 'csrf-invalid':\n return new ForbiddenError(init);\n case 'insufficient-scope':\n return new InsufficientScopeError(init);\n // The three 402 funding/affordability failures are one condition to a\n // caller: the account cannot fund the operation. `insufficient-funds` is the\n // balance shortfall; `insufficient-storage-credit` is the storage funding\n // source being out of credit; `no-funding-grant` is the absence of any\n // funding source entitling the account beyond the free window. All three\n // surface as the same funding error so a caller routes the user to top up\n // without branching on the code.\n case 'insufficient-funds':\n case 'insufficient-storage-credit':\n case 'no-funding-grant':\n return new InsufficientFundsError(init);\n case 'quote-expired':\n return new QuoteExpiredError(init);\n case 'quote-not-found':\n return new QuoteNotFoundError(init);\n case 'quote-already-consumed':\n return new QuoteAlreadyConsumedError(init);\n case 'not-found':\n return new NotFoundError(init);\n case 'record-not-found':\n return new RecordNotFoundError(init);\n case 'idempotency-key-conflict':\n return new IdempotencyConflictError(init);\n case 'rate-limited':\n return new RateLimitedError(init);\n case 'validation-failed':\n return new ValidationFailedError(init);\n case 'invalid-body':\n return new InvalidBodyError(init);\n case 'malformed-cbor':\n return new MalformedCborError(init);\n case 'batch-too-large':\n return new BatchTooLargeError(init);\n case 'batch-empty':\n return new BatchEmptyError(init);\n case 'internal-error':\n return new InternalServerError(init);\n // A gateway that prices on a live FX oracle may surface a transient\n // `fx-stale` pricing outage; to a vendor-neutral client that is just a\n // temporary inability to serve, i.e. a service-unavailable condition.\n case 'service-unavailable':\n case 'fx-stale':\n return new ServiceUnavailableError(init);\n default:\n return new Label309HttpError(init);\n }\n}\n","// Shared response-handling helpers for the HTTP client namespaces (poe,\n// records, account). They parse the body, lift `X-Request-Id` /\n// `Retry-After`, and throw a typed `Label309HttpError` on non-2xx the same\n// way, so the logic lives here once.\n\nimport { parseHttpError } from './parse-http-error';\n\n/** Parse a JSON response body; returns `null` for empty or non-JSON bodies. */\nexport async function readJson(response: Response): Promise<unknown> {\n const text = await response.text();\n if (text.length === 0) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\n/** Parse the `Retry-After` header as integer seconds; `undefined` when absent or non-numeric. */\nexport function parseRetryAfter(header: string | null): number | undefined {\n if (header === null) return undefined;\n const parsed = Number(header);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Throw the most-specific `Label309HttpError` subclass on a non-2xx\n * response (decoding the RFC 7807 body, request id, and retry-after); no-op on\n * 2xx so callers can `await throwIfNotOk(res)` before reading the success body.\n */\nexport async function throwIfNotOk(response: Response): Promise<void> {\n if (response.ok) return;\n const body = await readJson(response);\n const requestId = response.headers.get('x-request-id') ?? undefined;\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n throw parseHttpError({ httpStatus: response.status, body, requestId, retryAfterSeconds });\n}\n","// `client.account.*` wraps the account read surface:\n//\n// GET /api/v1/account/balance → account.balance()\n//\n// Auth is required (Bearer with `account:read` scope, or a session cookie when\n// the gateway is browser-fronted). The configured API key is forwarded as\n// `Authorization: Bearer …`.\n//\n// The balance is USD micro-cents carried as a decimal string on the wire\n// (`balance_usd_micros`). The SDK preserves it verbatim as a string —\n// `AccountBalance.balanceUsdMicros` — and never coerces it to a JS number, so\n// the bigint value survives without precision loss.\n\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport type { AccountBalance, FetchImpl } from './types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nfunction buildHeaders(apiKey: string | undefined): Headers {\n const headers = new Headers({\n 'content-type': 'application/json',\n accept: 'application/json',\n });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n return headers;\n}\n\ninterface AccountBalanceWire {\n readonly balance_usd_micros: string;\n}\n\nexport class AccountNamespace {\n private readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * Fetch the caller's current prepaid USD balance.\n *\n * Returns `{ balanceUsdMicros }`, the gateway's `balance_usd_micros` field\n * (USD micro-cents as a decimal string). The string is preserved verbatim —\n * never parsed into a number — so no precision is lost. An account with no\n * ledger activity yet reads `\"0\"`.\n *\n * Requires authentication: 401 (UnauthorizedError) when anonymous, 403\n * (InsufficientScopeError) when the Bearer key lacks the `account:read`\n * scope.\n */\n async balance(): Promise<AccountBalance> {\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/account/balance`, {\n method: 'GET',\n headers: buildHeaders(this.config.apiKey),\n });\n await throwIfNotOk(response);\n const body = (await readJson(response)) as AccountBalanceWire;\n return { balanceUsdMicros: body.balance_usd_micros };\n }\n}\n","// Raised synchronously from the Label309Client constructor when the config\n// cannot be resolved into a usable gateway target. The single trigger: a\n// missing or empty `baseUrl`. The client is gateway-agnostic and has no default\n// deployment, so a base URL must always be supplied. The `apiKey` is an opaque\n// bearer token and is never the cause of this error.\n\nexport class InvalidClientConfigError extends Error {\n public readonly code = 'INVALID_CLIENT_CONFIG' as const;\n constructor(message: string) {\n super(message);\n this.name = 'InvalidClientConfigError';\n }\n}\n","// Lowercase, no-`0x`-prefix hex encoder shared across the SDK. Single\n// implementation so the verifier, the wire serialiser, and the publish client\n// all emit byte-identical hex (the Python parity twin and the cross-language\n// fixtures depend on this exact form).\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n","// Raised by the high-level helpers (`publishSealed`, `publishMerkle`) when\n// one or more files uploaded via /poe/uploads come back with `ok: false`.\n//\n// The error carries the full `UploadsResponse` so callers can:\n// - retry just the failed indices (use `failedIndices` to subset their input)\n// - inspect per-file `error.code` / `error.detail` for diagnostics\n// - see which files DID land (already-uploaded files are billed and the\n// URIs remain valid; reuploading them would double-charge)\n\nimport type { UploadFailureEntry, UploadsResponse } from './types';\n\nexport class PartialUploadError extends Error {\n public readonly response: UploadsResponse;\n public readonly failed: ReadonlyArray<UploadFailureEntry>;\n\n constructor(response: UploadsResponse) {\n const failed = response.uploads.filter((u): u is UploadFailureEntry => u.ok === false);\n super(\n `${failed.length} of ${response.uploads.length} upload(s) failed: ${failed\n .map((f) => `[${f.idx}] ${f.error.code} — ${f.error.detail}`)\n .join('; ')}`,\n );\n this.name = 'PartialUploadError';\n this.response = response;\n this.failed = failed;\n }\n\n /** Convenience: the `idx` of every failed entry, in input order. */\n get failedIndices(): ReadonlyArray<number> {\n return this.failed.map((f) => f.idx);\n }\n}\n","// Canonical-CBOR codec for the off-chain Merkle leaves-list artefact.\n// The on-chain `merkle[]` field binds to this file via `uris[]` / `leaf_count`;\n// the file itself carries the full leaf set. Canonical CBOR is RFC 8949 §4.2.1.\n//\n// CDDL:\n//\n// leaves-list = {\n// \"format\": \"cardano-poe-merkle-leaves-v1\",\n// \"tree_alg\": \"rfc9162-sha256\",\n// \"root\": bytes .size 32,\n// \"leaves\": [ + bytes .size 32 ],\n// \"leaf_count\": uint,\n// ? \"leaf_alg\": tstr,\n// }\n//\n// Canonical ordering is bytewise-lexicographic on encoded map keys (RFC 8949\n// §4.2.1) so the wire-key order is fixed by `cde:true` regardless of insertion\n// order: root (4B) < format (6B) < leaves (6B) < leaf_alg (8B) < tree_alg (8B)\n// < leaf_count (10B).\n\nimport { decodeCanonicalCbor, encodeCanonicalCbor } from '../cbor/canonical';\nimport { compareCt } from '../util/compare-ct';\nimport { merkleSha2256Root } from '../hash/merkle-sha2-256';\n\nexport const LEAVES_LIST_FORMAT_V1 = 'cardano-poe-merkle-leaves-v1' as const;\nconst TREE_ALG_RFC9162 = 'rfc9162-sha256' as const;\nconst DIGEST_LENGTH = 32;\nconst REGISTERED_FORMATS = new Set<string>([LEAVES_LIST_FORMAT_V1]);\n\nexport type MerkleLeavesListErrorCode =\n | 'SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED'\n | 'SCHEMA_MERKLE_LEAVES_MALFORMED'\n | 'SCHEMA_MERKLE_LEAF_COUNT_MISMATCH'\n | 'MERKLE_ROOT_MISMATCH';\n\nexport class MerkleLeavesListError extends Error {\n readonly code: MerkleLeavesListErrorCode;\n constructor(code: MerkleLeavesListErrorCode, message?: string) {\n super(message ? `${code}: ${message}` : code);\n this.code = code;\n this.name = 'MerkleLeavesListError';\n }\n}\n\nexport interface EncodeLeavesListArgs {\n readonly leaves: ReadonlyArray<Uint8Array>;\n readonly root: Uint8Array;\n readonly leafAlg?: string;\n}\n\nexport interface DecodedLeavesList {\n readonly format: typeof LEAVES_LIST_FORMAT_V1;\n readonly treeAlg: typeof TREE_ALG_RFC9162;\n readonly root: Uint8Array;\n readonly leaves: Uint8Array[];\n readonly leafCount: number;\n readonly leafAlg?: string;\n}\n\nexport function encodeLeavesList(args: EncodeLeavesListArgs): Uint8Array {\n if (!(args.root instanceof Uint8Array) || args.root.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `root must be a Uint8Array(${DIGEST_LENGTH})`,\n );\n }\n if (args.leaves.length < 1) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaves array must be non-empty',\n );\n }\n const leavesCopy: Uint8Array[] = [];\n for (let i = 0; i < args.leaves.length; i++) {\n const leaf = args.leaves[i];\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `leaves[${i}] must be a Uint8Array(${DIGEST_LENGTH})`,\n );\n }\n leavesCopy.push(leaf);\n }\n if (args.leafAlg !== undefined && typeof args.leafAlg !== 'string') {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_alg must be a string when present',\n );\n }\n const map: Record<string, unknown> = {\n format: LEAVES_LIST_FORMAT_V1,\n tree_alg: TREE_ALG_RFC9162,\n root: args.root,\n leaves: leavesCopy,\n leaf_count: leavesCopy.length,\n };\n if (args.leafAlg !== undefined) {\n map['leaf_alg'] = args.leafAlg;\n }\n return encodeCanonicalCbor(map as never);\n}\n\nexport function decodeLeavesList(bytes: Uint8Array): DecodedLeavesList {\n const decoded = decodeCanonicalCbor(bytes);\n if (typeof decoded !== 'object' || decoded === null || Array.isArray(decoded)) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaves-list MUST be a CBOR map',\n );\n }\n const m = decoded as Record<string, unknown>;\n\n const format = m['format'];\n if (typeof format !== 'string') {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'format must be a text string',\n );\n }\n if (!REGISTERED_FORMATS.has(format)) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_FORMAT_UNSUPPORTED',\n `format '${format}' is not in the registered set`,\n );\n }\n\n const treeAlg = m['tree_alg'];\n if (treeAlg !== TREE_ALG_RFC9162) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `tree_alg '${String(treeAlg)}' is not '${TREE_ALG_RFC9162}'`,\n );\n }\n\n const root = m['root'];\n if (!(root instanceof Uint8Array) || root.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `root must be a ${DIGEST_LENGTH}-byte byte string`,\n );\n }\n\n const leavesRaw = m['leaves'];\n if (!Array.isArray(leavesRaw) || leavesRaw.length < 1) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaves must be a non-empty array',\n );\n }\n const leaves: Uint8Array[] = [];\n for (let i = 0; i < leavesRaw.length; i++) {\n const leaf = leavesRaw[i];\n if (!(leaf instanceof Uint8Array) || leaf.length !== DIGEST_LENGTH) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n `leaves[${i}] must be a ${DIGEST_LENGTH}-byte byte string`,\n );\n }\n leaves.push(leaf);\n }\n\n const leafCountRaw = m['leaf_count'];\n let leafCount: number;\n if (typeof leafCountRaw === 'number' && Number.isInteger(leafCountRaw) && leafCountRaw >= 0) {\n leafCount = leafCountRaw;\n } else if (typeof leafCountRaw === 'bigint' && leafCountRaw >= 0n) {\n if (leafCountRaw > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_count exceeds Number.MAX_SAFE_INTEGER',\n );\n }\n leafCount = Number(leafCountRaw);\n } else {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_count must be a non-negative CBOR uint',\n );\n }\n if (leaves.length !== leafCount) {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAF_COUNT_MISMATCH',\n `leaves.length (${leaves.length}) != leaf_count (${leafCount})`,\n );\n }\n\n let leafAlg: string | undefined;\n if (m['leaf_alg'] !== undefined) {\n if (typeof m['leaf_alg'] !== 'string') {\n throw new MerkleLeavesListError(\n 'SCHEMA_MERKLE_LEAVES_MALFORMED',\n 'leaf_alg must be a text string when present',\n );\n }\n leafAlg = m['leaf_alg'];\n }\n\n const recomputed = merkleSha2256Root(leaves);\n if (!compareCt(recomputed, root)) {\n throw new MerkleLeavesListError(\n 'MERKLE_ROOT_MISMATCH',\n 'leaves recompute does not match declared root',\n );\n }\n\n const out: DecodedLeavesList = {\n format: LEAVES_LIST_FORMAT_V1,\n treeAlg: TREE_ALG_RFC9162,\n root,\n leaves,\n leafCount,\n ...(leafAlg !== undefined ? { leafAlg } : {}),\n };\n return out;\n}\n","// A runtime-neutral view of the bytes a resumable upload reads from. The\n// helper needs three things from its source and nothing else:\n//\n// 1. the total byte length (declared to the gateway at session create),\n// 2. an ordered byte stream over the whole input (to compute the whole-file\n// SHA-256 without buffering it), and\n// 3. random-access slices by byte range (to read one chunk at a time).\n//\n// A browser `Blob`/`File` satisfies all three natively (`.size`, `.stream()`,\n// `.slice()`), and streams from disk rather than loading into memory. On the\n// server the same contract is met by a byte array, a filesystem path, or a Node\n// readable stream — each adapted to the same `ResumableSource` shape here, so\n// the protocol driver never branches on the runtime.\n\n// `node:fs/promises` is imported lazily, never at module top level: this package\n// is browser-safe and apps bundle it for the browser, so a static `node:` import\n// would pull a Node builtin into every browser build and break it. Only the\n// filesystem-path source actually needs it, and that branch runs only in Node;\n// the Blob/File/Uint8Array sources (the browser cases) never reach this loader.\ntype FsPromisesOpen = (typeof import('node:fs/promises'))['open'];\n\nlet openHandlePromise: Promise<FsPromisesOpen> | undefined;\nasync function loadOpen(): Promise<FsPromisesOpen> {\n // Cache the dynamic import so repeated path-source reads share one resolution.\n if (openHandlePromise === undefined) {\n openHandlePromise = import('node:fs/promises').then((fs) => fs.open);\n }\n return openHandlePromise;\n}\n\n/** The runtime-neutral source contract the resumable uploader drives. */\nexport interface ResumableSource {\n /** Total number of bytes in the input. */\n readonly size: number;\n /**\n * Read the half-open byte range `[start, end)`. May resolve synchronously or\n * asynchronously; callers always `await` the result. The returned array owns\n * its bytes (callers may transfer it into a request body).\n */\n slice(start: number, end: number): Uint8Array | Promise<Uint8Array>;\n /**\n * An ordered async stream over the whole input, used once to compute the\n * whole-file digest. Implementations stream in bounded chunks so a multi-GB\n * input is never materialised in full.\n */\n stream(): AsyncIterable<Uint8Array>;\n}\n\n/**\n * Any value `toResumableSource` knows how to adapt:\n * - a `ResumableSource` (passed through),\n * - a browser `Blob`/`File` (uses native `.slice()`/`.stream()`),\n * - a `Uint8Array`/`Buffer` (in-memory bytes),\n * - a filesystem path string (read in bounded slices, never fully buffered).\n */\nexport type ResumableSourceInput = ResumableSource | Blob | Uint8Array | string;\n\n// Default stream chunk for the whole-file hash pass. Independent of the upload\n// chunk size: this only bounds the hashing read buffer, so a small value keeps\n// peak memory low without affecting wire behaviour.\nconst HASH_STREAM_CHUNK_BYTES = 1024 * 1024;\n\nfunction isResumableSource(value: unknown): value is ResumableSource {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as ResumableSource).size === 'number' &&\n typeof (value as ResumableSource).slice === 'function' &&\n typeof (value as ResumableSource).stream === 'function' &&\n // A Blob/File shares all three members but exposes `.arrayBuffer`; exclude it\n // here so the adapter contract is unambiguous regardless of check order. A\n // Blob is handled by its own branch, which adapts `.slice`/`.stream` to bytes.\n typeof (value as { arrayBuffer?: unknown }).arrayBuffer !== 'function'\n );\n}\n\n// A `Blob` is detected structurally (not via `instanceof Blob`) so the check\n// holds across realms and runtimes that expose a Blob-shaped object without the\n// same constructor identity.\nfunction isBlobLike(value: unknown): value is Blob {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Blob).size === 'number' &&\n typeof (value as Blob).slice === 'function' &&\n typeof (value as Blob).arrayBuffer === 'function'\n );\n}\n\nasync function blobSlice(blob: Blob, start: number, end: number): Promise<Uint8Array> {\n return new Uint8Array(await blob.slice(start, end).arrayBuffer());\n}\n\nasync function* blobStream(blob: Blob): AsyncIterable<Uint8Array> {\n // `Blob.stream()` yields from disk in the browser and from the in-memory\n // buffer in Node; either way it never copies the whole blob into one array.\n const reader = blob.stream().getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) yield value as Uint8Array;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction fromBlob(blob: Blob): ResumableSource {\n return {\n size: blob.size,\n slice: (start, end) => blobSlice(blob, start, end),\n stream: () => blobStream(blob),\n };\n}\n\nfunction fromBytes(bytes: Uint8Array): ResumableSource {\n return {\n size: bytes.byteLength,\n slice: (start, end) => bytes.subarray(start, end),\n stream: async function* () {\n for (let offset = 0; offset < bytes.byteLength; offset += HASH_STREAM_CHUNK_BYTES) {\n yield bytes.subarray(offset, Math.min(offset + HASH_STREAM_CHUNK_BYTES, bytes.byteLength));\n }\n },\n };\n}\n\nasync function fromPath(path: string): Promise<ResumableSource> {\n const open = await loadOpen();\n // Read each slice with a positional read so the file is never buffered whole;\n // the whole-file hash pass streams it in bounded chunks for the same reason.\n const sliceAt = async (start: number, end: number): Promise<Uint8Array> => {\n const length = end - start;\n if (length <= 0) return new Uint8Array(0);\n const handle = await open(path, 'r');\n try {\n const buffer = new Uint8Array(length);\n // A single positional read may return fewer bytes than requested (a short\n // read is allowed by the OS even mid-file), so loop until the slice is\n // filled or we hit real EOF. Emitting a short chunk for a non-final index\n // would corrupt the assembled file, since the gateway places each chunk at\n // its deterministic offset; only the final chunk may legitimately be short.\n let filled = 0;\n while (filled < length) {\n const { bytesRead } = await handle.read(buffer, filled, length - filled, start + filled);\n if (bytesRead === 0) break; // real EOF: the file is shorter than declared\n filled += bytesRead;\n }\n return filled === length ? buffer : buffer.subarray(0, filled);\n } finally {\n await handle.close();\n }\n };\n const streamFile = async function* (): AsyncIterable<Uint8Array> {\n const handle = await open(path, 'r');\n try {\n const buffer = new Uint8Array(HASH_STREAM_CHUNK_BYTES);\n let position = 0;\n for (;;) {\n const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);\n if (bytesRead === 0) break;\n position += bytesRead;\n // Copy out the filled prefix; the buffer is reused on the next read.\n yield buffer.slice(0, bytesRead);\n }\n } finally {\n await handle.close();\n }\n };\n const { size } = await statSize(path);\n return { size, slice: sliceAt, stream: streamFile };\n}\n\nasync function statSize(path: string): Promise<{ size: number }> {\n const open = await loadOpen();\n // `readFile().byteLength` would buffer the whole file; use the handle's stat\n // instead so a large file's size is read without touching its bytes.\n const handle = await open(path, 'r');\n try {\n const stats = await handle.stat();\n return { size: stats.size };\n } finally {\n await handle.close();\n }\n}\n\n/**\n * Adapt any supported input to the runtime-neutral {@link ResumableSource}\n * contract. Returns a promise because a filesystem-path source must stat the\n * file before its size is known. Throws `TypeError` for unsupported inputs.\n *\n * The path branch is the only one that touches `node:fs`; a browser caller\n * passes a `Blob`/`File` or `Uint8Array` and never reaches it.\n */\nexport async function toResumableSource(input: ResumableSourceInput): Promise<ResumableSource> {\n if (typeof input === 'string') return fromPath(input);\n if (input instanceof Uint8Array) return fromBytes(input);\n // A `Blob`/`File` is checked BEFORE the generic `ResumableSource` shape: a Blob\n // also has `.size`/`.slice`/`.stream`, but its `.slice` returns a `Blob` (not a\n // `Uint8Array`) and its `.stream` is a `ReadableStream`, so passing it through\n // as a `ResumableSource` would hand the uploader Blobs where it expects byte\n // arrays. `isBlobLike` keys on `.arrayBuffer`, which a real adapter never has.\n if (isBlobLike(input)) return fromBlob(input);\n if (isResumableSource(input)) return input;\n throw new TypeError(\n 'uploadResumable: unsupported source. Pass a Blob/File, a Uint8Array, a ' +\n 'filesystem path string, or a ResumableSource.',\n );\n}\n","// Threshold-gated resumable upload driver.\n//\n// A file at or below `threshold` is sent with the existing single-shot\n// `uploads()` call, unchanged. A larger file is uploaded as a content-addressed\n// session: the helper hashes the whole file once (streaming, so a multi-GB file\n// is never buffered), creates a session, PUTs each fixed-size chunk (several in\n// parallel, retrying a failed chunk), then completes — polling the shared\n// attempt endpoint if completion is accepted asynchronously. Both paths converge\n// on one `ar://` URI.\n//\n// The chunk size is the server's call: the create response returns the\n// authoritative `chunk_bytes` and a `max_chunk_bytes` ceiling, and the helper\n// recomputes its grid from those rather than from what it requested. So a\n// deployment behind a stricter proxy cap is honoured without an SDK release.\n\nimport { sha256, sha256Stream } from '@cardanowall/crypto-core/hash';\n\nimport { Label309HttpError } from './http-error';\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport { toResumableSource, type ResumableSource } from './resumable-source';\nimport type {\n FetchImpl,\n StorageTarget,\n UploadResumableInput,\n UploadResumableResult,\n UploadSessionChunkResponse,\n UploadSessionCompleteResponse,\n UploadSessionCreateResponse,\n UploadSessionDeduplicatedResponse,\n UploadSessionStatus,\n UploadAttemptStatus,\n UploadAttemptCommitted,\n UploadAttemptReleased,\n} from './types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\n// Single-shot uploads() of one blob, returning the resolved URI. Imported as a\n// callback so the driver does not depend on the PoeNamespace class shape.\nexport type SingleShotUpload = (args: {\n readonly target: StorageTarget;\n readonly bytes: Uint8Array;\n readonly idempotencyKey?: string;\n readonly signal?: AbortSignal;\n}) => Promise<{ readonly uri: string; readonly sha256: string; readonly bytes: number }>;\n\n// ~48 MiB. Sits comfortably under a 100 MB CDN body cap AND under stricter\n// nginx/proxy defaults below it, so a single chunk PUT clears the smallest\n// common single-request ceiling. Both the switch-to-chunked threshold and the\n// requested chunk size default here; the server's max_chunk_bytes always wins.\nexport const DEFAULT_RESUMABLE_THRESHOLD_BYTES = 50_331_648;\nexport const DEFAULT_RESUMABLE_CHUNK_BYTES = 50_331_648;\nconst DEFAULT_PARALLELISM = 4;\nconst DEFAULT_MAX_CHUNK_RETRIES = 4;\nconst DEFAULT_CONTENT_TYPE = 'application/octet-stream';\nconst DEFAULT_TARGET: StorageTarget = 'arweave';\nconst ATTEMPT_POLL_INTERVAL_MS = 1000;\nconst ATTEMPT_POLL_MAX_ATTEMPTS = 600;\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\n// Standards-only base64 (RFC 4648) over raw bytes, used for the per-chunk\n// `Digest: sha-256=<base64>` header. A hand-rolled encoder keeps the helper free\n// of any runtime-specific path (`btoa` is DOM-only, `Buffer` is Node-only).\nconst B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nfunction bytesToBase64(bytes: Uint8Array): string {\n let out = '';\n let i = 0;\n for (; i + 2 < bytes.length; i += 3) {\n const n = (bytes[i]! << 16) | (bytes[i + 1]! << 8) | bytes[i + 2]!;\n out +=\n B64_ALPHABET[(n >> 18) & 63]! +\n B64_ALPHABET[(n >> 12) & 63]! +\n B64_ALPHABET[(n >> 6) & 63]! +\n B64_ALPHABET[n & 63]!;\n }\n const rem = bytes.length - i;\n if (rem === 1) {\n const n = bytes[i]! << 16;\n out += B64_ALPHABET[(n >> 18) & 63]! + B64_ALPHABET[(n >> 12) & 63]! + '==';\n } else if (rem === 2) {\n const n = (bytes[i]! << 16) | (bytes[i + 1]! << 8);\n out +=\n B64_ALPHABET[(n >> 18) & 63]! +\n B64_ALPHABET[(n >> 12) & 63]! +\n B64_ALPHABET[(n >> 6) & 63]! +\n '=';\n }\n return out;\n}\n\nfunction jsonHeaders(config: ResolvedConfig, idempotencyKey?: string): Headers {\n const headers = new Headers({ 'content-type': 'application/json', accept: 'application/json' });\n if (config.apiKey !== undefined) headers.set('authorization', `Bearer ${config.apiKey}`);\n if (idempotencyKey !== undefined) headers.set('idempotency-key', idempotencyKey);\n return headers;\n}\n\nfunction octetHeaders(config: ResolvedConfig, length: number, digestBase64: string): Headers {\n const headers = new Headers({\n 'content-type': 'application/octet-stream',\n accept: 'application/json',\n 'content-length': String(length),\n digest: `sha-256=${digestBase64}`,\n });\n if (config.apiKey !== undefined) headers.set('authorization', `Bearer ${config.apiKey}`);\n return headers;\n}\n\nconst SESSIONS_PATH = '/api/v1/poe/uploads/sessions';\n\nfunction chunkRange(index: number, chunkBytes: number, totalBytes: number): [number, number] {\n const start = index * chunkBytes;\n return [start, Math.min(start + chunkBytes, totalBytes)];\n}\n\nfunction missingIndices(received: ReadonlyArray<number>, chunkCount: number): number[] {\n const have = new Set(received);\n const out: number[] = [];\n for (let i = 0; i < chunkCount; i++) if (!have.has(i)) out.push(i);\n return out;\n}\n\n/**\n * The authoritative set of chunk indices to send for a resumed session. The\n * server's `missing` set is the source of truth; `received` is only a progress\n * signal. A gateway that omits `missing` (older deployments) falls back to the\n * gap derived from `received` so resume still works.\n */\nfunction serverMissing(status: UploadSessionStatus): ReadonlyArray<number> {\n if (Array.isArray(status.missing)) return status.missing;\n return missingIndices(status.received, status.chunk_count);\n}\n\n/** Whole-file SHA-256 (hex) over the source, streamed so a large file is never buffered. */\nasync function hashWholeFile(source: ResumableSource): Promise<string> {\n return bytesToHex(await sha256Stream(source.stream()));\n}\n\nasync function createSession(\n config: ResolvedConfig,\n body: {\n target: StorageTarget;\n sha256: string;\n total_bytes: number;\n chunk_bytes: number;\n content_type: string;\n },\n signal: AbortSignal | undefined,\n): Promise<UploadSessionCreateResponse | UploadSessionDeduplicatedResponse> {\n const response = await config.fetch(`${config.baseUrl}${SESSIONS_PATH}`, {\n method: 'POST',\n headers: jsonHeaders(config),\n body: JSON.stringify(body),\n ...(signal ? { signal } : {}),\n });\n // A 402 funding error is surfaced through the typed-error path like any other\n // non-2xx; the dedup short-circuit arrives as a 200 and is read below.\n await throwIfNotOk(response);\n return (await readJson(response)) as\n | UploadSessionCreateResponse\n | UploadSessionDeduplicatedResponse;\n}\n\nasync function getSessionStatus(\n config: ResolvedConfig,\n sessionId: string,\n signal: AbortSignal | undefined,\n): Promise<UploadSessionStatus> {\n const response = await config.fetch(\n `${config.baseUrl}${SESSIONS_PATH}/${encodeURIComponent(sessionId)}`,\n {\n method: 'GET',\n headers: jsonHeaders(config),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadSessionStatus;\n}\n\nasync function putChunk(\n config: ResolvedConfig,\n sessionId: string,\n index: number,\n bytes: Uint8Array,\n signal: AbortSignal | undefined,\n): Promise<UploadSessionChunkResponse> {\n const digest = bytesToBase64(sha256(bytes));\n const response = await config.fetch(\n `${config.baseUrl}${SESSIONS_PATH}/${encodeURIComponent(sessionId)}/chunks/${index}`,\n {\n method: 'PUT',\n headers: octetHeaders(config, bytes.byteLength, digest),\n // A Blob body streams without copying; a matching-digest re-PUT is an\n // idempotent 200 server-side, so a retried chunk is always safe.\n body: new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadSessionChunkResponse;\n}\n\nasync function completeSession(\n config: ResolvedConfig,\n sessionId: string,\n idempotencyKey: string,\n signal: AbortSignal | undefined,\n): Promise<UploadSessionCompleteResponse> {\n const response = await config.fetch(\n `${config.baseUrl}${SESSIONS_PATH}/${encodeURIComponent(sessionId)}/complete`,\n {\n method: 'POST',\n headers: jsonHeaders(config, idempotencyKey),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadSessionCompleteResponse;\n}\n\nasync function pollAttempt(\n config: ResolvedConfig,\n attemptId: string,\n signal: AbortSignal | undefined,\n): Promise<UploadAttemptCommitted | UploadAttemptReleased> {\n for (let attempt = 0; attempt < ATTEMPT_POLL_MAX_ATTEMPTS; attempt++) {\n const response = await config.fetch(\n `${config.baseUrl}/api/v1/poe/uploads/attempts/${encodeURIComponent(attemptId)}`,\n {\n method: 'GET',\n headers: jsonHeaders(config),\n ...(signal ? { signal } : {}),\n },\n );\n await throwIfNotOk(response);\n const status = (await readJson(response)) as UploadAttemptStatus;\n // `reserved` is the only in-flight state; `committed` and `released` are\n // terminal and returned to the caller to resolve.\n if (status.state !== 'reserved') return status;\n await delay(ATTEMPT_POLL_INTERVAL_MS, signal);\n }\n throw new ResumableUploadError(\n 'ATTEMPT_POLL_TIMEOUT',\n `upload attempt ${attemptId} did not reach a terminal state in time`,\n );\n}\n\nfunction delay(ms: number, signal: AbortSignal | undefined): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signalReason(signal));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(signalReason(signal));\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nfunction signalReason(signal: AbortSignal | undefined): Error {\n const reason = signal?.reason;\n return reason instanceof Error ? reason : new ResumableUploadError('ABORTED', 'upload aborted');\n}\n\nexport class ResumableUploadError extends Error {\n readonly code:\n | 'SHA256_MISMATCH'\n | 'SESSION_FAILED'\n | 'ATTEMPT_FAILED'\n | 'ATTEMPT_POLL_TIMEOUT'\n | 'CHUNK_UPLOAD_FAILED'\n | 'ABORTED';\n\n constructor(code: ResumableUploadError['code'], message: string) {\n super(message);\n this.name = 'ResumableUploadError';\n this.code = code;\n }\n}\n\n/** Upload `missing` chunk indices with bounded parallelism, retrying each on failure. */\nasync function uploadChunks(\n config: ResolvedConfig,\n sessionId: string,\n source: ResumableSource,\n chunkBytes: number,\n totalBytes: number,\n missing: ReadonlyArray<number>,\n parallelism: number,\n maxRetries: number,\n signal: AbortSignal | undefined,\n): Promise<void> {\n let cursor = 0;\n const workers: Promise<void>[] = [];\n const lanes = Math.max(1, Math.min(parallelism, missing.length || 1));\n for (let lane = 0; lane < lanes; lane++) {\n workers.push(\n (async () => {\n for (;;) {\n if (signal?.aborted) throw signalReason(signal);\n const next = cursor++;\n if (next >= missing.length) return;\n const index = missing[next]!;\n const [start, end] = chunkRange(index, chunkBytes, totalBytes);\n const bytes = await source.slice(start, end);\n await putChunkWithRetry(config, sessionId, index, bytes, maxRetries, signal);\n }\n })(),\n );\n }\n await Promise.all(workers);\n}\n\nasync function putChunkWithRetry(\n config: ResolvedConfig,\n sessionId: string,\n index: number,\n bytes: Uint8Array,\n maxRetries: number,\n signal: AbortSignal | undefined,\n): Promise<void> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (signal?.aborted) throw signalReason(signal);\n try {\n await putChunk(config, sessionId, index, bytes, signal);\n return;\n } catch (err) {\n if (signal?.aborted) throw signalReason(signal);\n // A deterministic client-side 4xx (e.g. 400 chunk-size-mismatch, 400\n // chunk-digest-mismatch, 409 chunk-conflict) cannot be fixed by resending\n // the same bytes: fail fast and surface the real problem rather than\n // burning retries and masking it as CHUNK_UPLOAD_FAILED. Only transient\n // failures (network errors, 5xx, 429, 408) are worth a retry. A\n // matching-digest re-PUT is an idempotent 200 server-side, so a retried\n // transient chunk is always safe.\n if (isTerminalChunkError(err)) throw err;\n lastError = err;\n if (attempt < maxRetries) {\n // Exponential backoff (250ms, 500ms, 1s, ...) capped at 8s.\n await delay(Math.min(250 * 2 ** attempt, 8000), signal);\n }\n }\n }\n throw new ResumableUploadError(\n 'CHUNK_UPLOAD_FAILED',\n `chunk ${index} failed after ${maxRetries + 1} attempt(s): ${\n lastError instanceof Error ? lastError.message : String(lastError)\n }`,\n );\n}\n\n/**\n * Drive a single-file upload, choosing single-shot vs the chunked session flow\n * by size. See {@link UploadResumableInput} for the options.\n */\nexport async function uploadResumable(\n config: ResolvedConfig,\n singleShot: SingleShotUpload,\n input: UploadResumableInput,\n): Promise<UploadResumableResult> {\n const source = await toResumableSource(input.source);\n const target = input.target ?? DEFAULT_TARGET;\n const threshold = input.threshold ?? DEFAULT_RESUMABLE_THRESHOLD_BYTES;\n const totalBytes = source.size;\n\n // Small file (or no resume requested): the unchanged single-shot path. The\n // whole file is small enough to read once into memory for the multipart body.\n if (totalBytes <= threshold && input.sessionId === undefined) {\n const bytes = await source.slice(0, totalBytes);\n const result = await singleShot({\n target,\n bytes,\n ...(input.idempotencyKey !== undefined ? { idempotencyKey: input.idempotencyKey } : {}),\n ...(input.signal ? { signal: input.signal } : {}),\n });\n return {\n uri: result.uri,\n sha256: result.sha256,\n bytes: result.bytes,\n deduplicated: false,\n mode: 'single-shot',\n };\n }\n\n return runSession(config, source, target, totalBytes, input);\n}\n\nasync function runSession(\n config: ResolvedConfig,\n source: ResumableSource,\n target: StorageTarget,\n totalBytes: number,\n input: UploadResumableInput,\n): Promise<UploadResumableResult> {\n const signal = input.signal;\n\n let sessionId: string;\n let chunkBytes: number;\n let missing: ReadonlyArray<number>;\n // The declared whole-file SHA-256 (hex) the session is content-addressed by.\n // On a fresh create it is computed once over the local source; on resume it is\n // ADOPTED from the server status, never recomputed. It drives both the\n // completion idempotency key and the result `sha256`.\n let declaredSha256: string;\n // The total the chunk grid is sliced against. On a fresh create this is the\n // local source size (which the gateway echoes back, since we just declared it).\n // On resume it is the server's `total_bytes`: a source that grew between\n // attempts must not redraw the grid, or the final chunk would over-read past\n // the originally declared length and contradict the digest.\n let gridTotalBytes: number;\n\n if (input.sessionId !== undefined) {\n // Resume: a session is content-addressed, so its declared digest, total, and\n // chunk grid all live server-side. Adopt the server status as authoritative\n // and NEVER re-hash the local source — re-reading a multi-GB file on every\n // resume defeats the point, and a local file that changed since create would\n // yield a digest that disagrees with the actually-uploaded bounded bytes.\n const status = await getSessionStatus(config, input.sessionId, signal);\n if (status.state === 'completed' && status.uri !== null) {\n return {\n uri: status.uri,\n sha256: status.sha256,\n bytes: status.total_bytes,\n deduplicated: false,\n mode: 'chunked',\n };\n }\n if (status.state === 'failed' || status.state === 'expired') {\n throw new ResumableUploadError(\n 'SESSION_FAILED',\n `cannot resume session ${input.sessionId} in state '${status.state}'`,\n );\n }\n sessionId = status.session_id;\n declaredSha256 = status.sha256;\n chunkBytes = status.chunk_bytes;\n // The server's declared total is authoritative for the chunk grid, not the\n // live local source size. The original create fixed `total_bytes`, the whole-\n // file digest, and the index<->offset mapping together; bounding the final\n // chunk against the server total keeps the last slice the exact declared\n // remainder even if the underlying source has since grown.\n gridTotalBytes = status.total_bytes;\n // The server's `missing` set is authoritative for which indices to send: it\n // is the source of truth for what the gateway holds, where `received` is\n // only a progress signal. Re-deriving the gap from `received` would diverge\n // if the server's grid ever differs from ours (e.g. a chunk it dropped after\n // acking, or a window it expresses differently).\n missing = serverMissing(status);\n } else {\n // Fresh create: this is the only path that reads the whole source to compute\n // the declared digest, streamed so a multi-GB file is never buffered.\n declaredSha256 = await hashWholeFile(source);\n const requestedChunkBytes = input.chunkBytes ?? DEFAULT_RESUMABLE_CHUNK_BYTES;\n const created = await createSession(\n config,\n {\n target,\n sha256: declaredSha256,\n total_bytes: totalBytes,\n chunk_bytes: requestedChunkBytes,\n content_type: input.contentType ?? DEFAULT_CONTENT_TYPE,\n },\n signal,\n );\n // Create-time dedup: the bytes already exist; nothing is uploaded.\n if ('deduplicated' in created) {\n return {\n uri: created.uri,\n sha256: created.sha256,\n bytes: created.bytes,\n deduplicated: true,\n mode: 'chunked',\n };\n }\n sessionId = created.session_id;\n // Honour the server's authoritative chunk size (it may clamp to its ceiling).\n chunkBytes = created.chunk_bytes;\n gridTotalBytes = totalBytes;\n // A fresh create has no `missing` field and an empty `received`, so every\n // index is outstanding.\n missing = missingIndices(created.received, created.chunk_count);\n }\n\n if (missing.length > 0) {\n await uploadChunks(\n config,\n sessionId,\n source,\n chunkBytes,\n gridTotalBytes,\n missing,\n input.parallelism ?? DEFAULT_PARALLELISM,\n input.maxChunkRetries ?? DEFAULT_MAX_CHUNK_RETRIES,\n signal,\n );\n }\n\n return finishSession(config, sessionId, declaredSha256, input);\n}\n\n// Drive /complete to a terminal result. On a 409 incomplete-upload, the server's\n// status is re-fetched and the still-missing chunks are resent against the\n// server-authoritative grid (`status.chunk_bytes` / `status.total_bytes`), so the\n// completion path never trusts a stale local size.\nasync function finishSession(\n config: ResolvedConfig,\n sessionId: string,\n declaredSha256: string,\n input: UploadResumableInput,\n): Promise<UploadResumableResult> {\n const signal = input.signal;\n // The completion key is the caller's promise of sameness; default it to the\n // session's declared digest (computed on create, adopted from server status on\n // resume) so a re-invocation replays the recorded terminal result.\n const idempotencyKey = input.idempotencyKey ?? `resumable-${declaredSha256}`;\n\n // A 409 incomplete-upload means the server is missing chunks (e.g. a write was\n // dropped after the bit flipped client-side): GET the gap, resend it, retry.\n const COMPLETE_RETRIES = 2;\n for (let attempt = 0; attempt <= COMPLETE_RETRIES; attempt++) {\n try {\n const completion = await completeSession(config, sessionId, idempotencyKey, signal);\n if ('ok' in completion) {\n return {\n uri: completion.uri,\n sha256: completion.sha256,\n bytes: completion.bytes,\n // The server sends the number 0 for a dedup-on-commit (the bytes were\n // already stored, so nothing was charged); compare numerically.\n deduplicated: completion.charged_usd_micros === 0,\n mode: 'chunked',\n };\n }\n return resolveAccepted(config, completion.attempt_id, signal);\n } catch (err) {\n if (attempt < COMPLETE_RETRIES && isIncompleteUpload(err)) {\n const status = await getSessionStatus(config, sessionId, signal);\n const stillMissing = serverMissing(status);\n if (stillMissing.length === 0) continue; // racing assembly; retry complete\n await uploadChunks(\n config,\n sessionId,\n await toResumableSource(input.source),\n status.chunk_bytes,\n // Re-bound the resend grid against the server's declared total too, so a\n // source that grew during the upload cannot over-read the final chunk.\n status.total_bytes,\n stillMissing,\n input.parallelism ?? DEFAULT_PARALLELISM,\n input.maxChunkRetries ?? DEFAULT_MAX_CHUNK_RETRIES,\n signal,\n );\n continue;\n }\n throw err;\n }\n }\n // Loop exhaustion means the gateway kept reporting an incomplete upload\n // despite resending the missing chunks.\n throw new ResumableUploadError(\n 'SESSION_FAILED',\n `session ${sessionId} could not be completed after resending missing chunks`,\n );\n}\n\nasync function resolveAccepted(\n config: ResolvedConfig,\n attemptId: string,\n signal: AbortSignal | undefined,\n): Promise<UploadResumableResult> {\n const status = await pollAttempt(config, attemptId, signal);\n // `released` is the terminal failure; surface the server's reason.\n if (status.state === 'released') {\n throw new ResumableUploadError(\n 'ATTEMPT_FAILED',\n `upload attempt ${attemptId} was released: ${status.reason}`,\n );\n }\n // `committed` is the terminal success and MUST carry a uri; a committed\n // attempt without one is a server contract violation, not a silent success.\n if (status.uri.length === 0) {\n throw new ResumableUploadError(\n 'ATTEMPT_FAILED',\n `upload attempt ${attemptId} committed without a uri`,\n );\n }\n return {\n uri: status.uri,\n sha256: status.sha256,\n bytes: status.bytes,\n // A committed attempt that charged nothing deduped against bytes already\n // stored for this account on this backend.\n deduplicated: status.charged_usd_micros === 0,\n mode: 'chunked',\n };\n}\n\n/**\n * Whether a chunk-PUT error is the caller's fault (terminal) rather than a\n * transient server/transport hiccup worth retrying. A definitive client-side\n * 4xx is terminal — a conflicting digest, a size mismatch, an\n * unauthorised/forbidden caller, an expired or missing session — and resending\n * the same bytes cannot fix it. 408 (request timeout) and 429 (rate limited)\n * are transient; any non-HTTP error (a network/egress failure) is transient\n * too, since the request never reached a definitive verdict.\n */\nfunction isTerminalChunkError(err: unknown): boolean {\n if (!(err instanceof Label309HttpError)) return false;\n const status = err.httpStatus;\n return status >= 400 && status < 500 && status !== 408 && status !== 429;\n}\n\nfunction isIncompleteUpload(err: unknown): boolean {\n // The typed HTTP error carries the RFC 7807 `code`; an incomplete upload at\n // /complete is a 409 with code `incomplete-upload`.\n return (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as { code: unknown }).code === 'incomplete-upload'\n );\n}\n","// High-level publish helpers — collapse the new uploads + publish flow into\n// single calls for the three common shapes:\n//\n// 1. `publishContent({content, signer?})` — anchor a single content blob by\n// its `sha2-256` (or `blake2b-256`) digest. No Arweave, no /uploads —\n// the record is constructed entirely client-side and posted directly to\n// /publish.\n//\n// 2. `publishSealed({content, recipients, signer?})` — encrypt the content\n// to the recipient X25519 public keys (age-style sealed envelope),\n// upload the ciphertext to Arweave via /uploads, build a Label 309 record\n// with the resulting `ar://` URI, sign, and post to /publish.\n//\n// 3. `publishMerkle({leaves, signer?})` — anchor an arbitrary number of leaf\n// hashes under a single RFC 9162 §2.1.1 root, with the leaves-list CBOR\n// uploaded to Arweave via /uploads. The Merkle root + leaf_count are\n// bound into the on-chain record via `merkle[0]`.\n//\n// Signer architecture: the SDK does NOT hold identity keys (privacy contract\n// in `off-host-sign.ts`). The helpers take an optional `Signer` that owns the\n// Ed25519 private key (in-memory `@noble/ed25519`, AWS KMS, GCP HSM, …). The\n// helper builds the canonical `Sig_structure`, hands the bytes to the signer,\n// and never sees the private key. When `signer` is omitted the record\n// publishes unsigned (conformance profile `core` for hash-only;\n// `sealed` for sealed envelopes).\n\nimport {\n sha256,\n blake2b256,\n merkleSha2256Root,\n MERKLE_ALG_ID,\n} from '@cardanowall/crypto-core/hash';\nimport { encodeLeavesList } from '@cardanowall/crypto-core/merkle';\nimport { eciesSealedPoeWrap } from '@cardanowall/crypto-core/sealed-poe';\nimport {\n encodePoeRecord,\n type EncryptionEnvelope,\n type MerkleCommit,\n type PoeRecord,\n} from '@cardanowall/poe-standard';\n\nimport { assembleCoseSign1, prepareSigStructure } from './off-host-sign';\nimport { PartialUploadError } from './partial-upload-error';\nimport { parseHttpError } from './parse-http-error';\nimport {\n uploadResumable,\n DEFAULT_RESUMABLE_THRESHOLD_BYTES,\n type SingleShotUpload,\n} from './resumable-upload';\nimport type {\n FetchImpl,\n PublishContentInput,\n PublishMerkleInput,\n PublishMerkleResponse,\n PublishPrehashedInput,\n PublishResponse,\n PublishSealedInput,\n Signer,\n StorageTarget,\n SupportedHashAlg,\n UploadsResponse,\n UploadSuccessEntry,\n} from './types';\n\nconst ED25519_PUBLIC_KEY_LENGTH = 32;\nconst ED25519_SIGNATURE_LENGTH = 64;\nconst X25519_PUBLIC_KEY_LENGTH = 32;\nconst MLKEM768X25519_PUBLIC_KEY_LENGTH = 1216;\nconst LEAF_DIGEST_LENGTH = 32;\nconst STORAGE_TARGET_ARWEAVE = 'arweave' as const;\n\nexport interface ResolvedPublishConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nexport class PublishError extends Error {\n readonly code:\n | 'INVALID_SIGNER_PUBKEY'\n | 'INVALID_SIGNER_SIGNATURE'\n | 'INVALID_LEAVES'\n | 'INVALID_DIGEST'\n | 'INVALID_RECIPIENT'\n | 'UNSUPPORTED_HASH_ALG';\n\n constructor(code: PublishError['code'], message: string) {\n super(message);\n this.name = 'PublishError';\n this.code = code;\n }\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new PublishError('INVALID_LEAVES', `hex string has odd length: ${hex.length}`);\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n if (Number.isNaN(byte)) {\n throw new PublishError('INVALID_LEAVES', `invalid hex byte at offset ${i * 2}`);\n }\n out[i] = byte;\n }\n return out;\n}\n\nfunction toBytes(content: Uint8Array | string): Uint8Array {\n if (typeof content === 'string') return new TextEncoder().encode(content);\n return content;\n}\n\n// Allocate a fresh Uint8Array (with a concrete ArrayBuffer backing, not\n// ArrayBufferLike) so the result satisfies the strict `Uint8Array<ArrayBuffer>`\n// generic that Zod infers for hash-digest schemas. @noble/hashes returns the\n// generic `Uint8Array<ArrayBufferLike>` shape; an explicit clone collapses it\n// to the strict variant without `as` casts.\nfunction cloneToOwnedBuffer(src: Uint8Array): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(new ArrayBuffer(src.length));\n out.set(src);\n return out;\n}\n\nfunction hashContent(bytes: Uint8Array, alg: SupportedHashAlg): Uint8Array<ArrayBuffer> {\n if (alg === 'sha2-256') return cloneToOwnedBuffer(sha256(bytes));\n if (alg === 'blake2b-256') return cloneToOwnedBuffer(blake2b256(bytes));\n throw new PublishError(\n 'UNSUPPORTED_HASH_ALG',\n `hashAlg must be 'sha2-256' or 'blake2b-256', got '${alg as string}'`,\n );\n}\n\nfunction assertSigner(signer: Signer): void {\n if (\n !(signer.signerPubkey instanceof Uint8Array) ||\n signer.signerPubkey.length !== ED25519_PUBLIC_KEY_LENGTH\n ) {\n throw new PublishError(\n 'INVALID_SIGNER_PUBKEY',\n `signer.signerPubkey must be a Uint8Array(${ED25519_PUBLIC_KEY_LENGTH})`,\n );\n }\n if (typeof signer.sign !== 'function') {\n throw new PublishError('INVALID_SIGNER_PUBKEY', 'signer.sign must be a function');\n }\n}\n\nfunction buildJsonHeaders(apiKey: string | undefined, idempotencyKey?: string): Headers {\n const headers = new Headers({ 'content-type': 'application/json', accept: 'application/json' });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n if (idempotencyKey !== undefined) headers.set('idempotency-key', idempotencyKey);\n return headers;\n}\n\nfunction buildMultipartHeaders(apiKey: string | undefined, idempotencyKey?: string): Headers {\n const headers = new Headers({ accept: 'application/json' });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n if (idempotencyKey !== undefined) headers.set('idempotency-key', idempotencyKey);\n return headers;\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n const text = await response.text();\n if (text.length === 0) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (header === null) return undefined;\n const parsed = Number(header);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nasync function throwIfNotOk(response: Response): Promise<void> {\n if (response.ok) return;\n const body = await readJson(response);\n const requestId = response.headers.get('x-request-id') ?? undefined;\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n throw parseHttpError({ httpStatus: response.status, body, requestId, retryAfterSeconds });\n}\n\n/**\n * Sign a record path-1 (in-memory Ed25519 / KMS / HSM) and return the final\n * canonical-CBOR bytes ready for /publish. The signature is embedded into\n * the record's `sigs[]` field — the wire `signatures` parameter on /publish\n * is reserved for the path-2 wallet flow (CIP-30 cose_key sidecar).\n */\nasync function signAndEncodeRecord(record: PoeRecord, signer: Signer): Promise<Uint8Array> {\n const { sigStructureBytes } = prepareSigStructure({\n record,\n signerPubkey: signer.signerPubkey,\n });\n const signature = await signer.sign(sigStructureBytes);\n if (!(signature instanceof Uint8Array) || signature.length !== ED25519_SIGNATURE_LENGTH) {\n throw new PublishError(\n 'INVALID_SIGNER_SIGNATURE',\n `signer.sign() must return a Uint8Array(${ED25519_SIGNATURE_LENGTH}); got length ${\n signature instanceof Uint8Array ? signature.length : 'non-Uint8Array'\n }`,\n );\n }\n const { sigEntry } = assembleCoseSign1({\n record,\n signerPubkey: signer.signerPubkey,\n signature,\n });\n const signed: PoeRecord = { ...record, sigs: [sigEntry] };\n return encodePoeRecord(signed);\n}\n\nasync function encodeRecord(record: PoeRecord, signer: Signer | undefined): Promise<Uint8Array> {\n if (signer === undefined) return encodePoeRecord(record);\n return signAndEncodeRecord(record, signer);\n}\n\nasync function postPublish(\n config: ResolvedPublishConfig,\n recordBytesHex: string,\n quoteId: string,\n idempotencyKey: string | undefined,\n): Promise<PublishResponse> {\n const body = { record: recordBytesHex, quote_id: quoteId };\n const response = await config.fetch(`${config.baseUrl}/api/v1/poe/publish`, {\n method: 'POST',\n headers: buildJsonHeaders(config.apiKey, idempotencyKey),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n const parsed = (await readJson(response)) as Omit<PublishResponse, 'dedup_hit'>;\n return { ...parsed, dedup_hit: response.status === 200 };\n}\n\n// Single-shot multipart upload of one blob, resolving its `ar://` URI. Backs\n// the small-blob branch of `uploadBlob` and the resumable helper's\n// below-threshold fast path.\nconst singleShotUpload =\n (config: ResolvedPublishConfig): SingleShotUpload =>\n async ({ target, bytes, idempotencyKey, signal }) => {\n const form = new FormData();\n form.append('target', target);\n form.append(\n 'file_0',\n new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n 'file_0.bin',\n );\n const response = await config.fetch(`${config.baseUrl}/api/v1/poe/uploads`, {\n method: 'POST',\n headers: buildMultipartHeaders(config.apiKey, idempotencyKey),\n body: form,\n ...(signal ? { signal } : {}),\n });\n await throwIfNotOk(response);\n const result = (await readJson(response)) as UploadsResponse;\n const entry = result.uploads[0];\n if (entry === undefined || entry.ok === false) {\n throw new PartialUploadError(result);\n }\n const ok = entry as UploadSuccessEntry;\n return { uri: ok.uri, sha256: ok.sha256, bytes: ok.bytes };\n };\n\n// Upload one blob (sealed ciphertext or Merkle leaves-list) and return its\n// `ar://` URI. A blob at or below the resumable threshold takes the unchanged\n// single-shot multipart path; a larger blob transparently uses the resumable\n// session flow so a multi-GB ciphertext clears CDN/proxy single-request caps.\n// Both paths end at the same URI, so the publisher helpers' signatures and\n// on-chain record shape are unaffected by the blob's size.\nasync function uploadBlob(\n config: ResolvedPublishConfig,\n bytes: Uint8Array,\n idempotencyKey: string | undefined,\n): Promise<string> {\n const target: StorageTarget = STORAGE_TARGET_ARWEAVE;\n if (bytes.byteLength <= DEFAULT_RESUMABLE_THRESHOLD_BYTES) {\n const single = await singleShotUpload(config)({\n target,\n bytes,\n ...(idempotencyKey !== undefined ? { idempotencyKey } : {}),\n });\n return single.uri;\n }\n const result = await uploadResumable(config, singleShotUpload(config), {\n target,\n source: bytes,\n ...(idempotencyKey !== undefined ? { idempotencyKey } : {}),\n });\n return result.uri;\n}\n\n/**\n * Hash-only PoE — anchor a single content blob's digest, optionally with\n * one path-1 signature. No Arweave, no /uploads.\n */\nexport async function publishContent(\n config: ResolvedPublishConfig,\n input: PublishContentInput,\n): Promise<PublishResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n const hashAlg: SupportedHashAlg = input.hashAlg ?? 'sha2-256';\n const contentBytes = toBytes(input.content);\n const digest = hashContent(contentBytes, hashAlg);\n\n const record: PoeRecord = {\n v: 1,\n items: [{ hashes: { [hashAlg]: digest } }],\n };\n const recordBytes = await encodeRecord(record, input.signer);\n return postPublish(config, bytesToHex(recordBytes), input.quoteId, input.idempotencyKey);\n}\n\n// `sha2-256` and `blake2b-256` both produce 32-byte digests. Kept as a\n// per-alg map for forward-compat when wider hash registries land.\nconst DIGEST_BYTE_LENGTH: Record<SupportedHashAlg, number> = {\n 'sha2-256': 32,\n 'blake2b-256': 32,\n};\n\n/**\n * Hash-already-computed PoE — anchor a precomputed content digest (the user\n * already has it), optionally signed. The SDK does not re-hash; it\n * constructs a single-item record with the supplied digests in\n * `items[0].hashes`.\n */\nexport async function publishPrehashed(\n config: ResolvedPublishConfig,\n input: PublishPrehashedInput,\n): Promise<PublishResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n const entries = Object.entries(input.hashes) as Array<[SupportedHashAlg, string | undefined]>;\n const present = entries.filter(([, hex]) => typeof hex === 'string' && hex.length > 0) as Array<\n [SupportedHashAlg, string]\n >;\n if (present.length === 0) {\n throw new PublishError(\n 'INVALID_DIGEST',\n 'publishPrehashed requires at least one digest in `hashes`',\n );\n }\n const decoded: Record<string, Uint8Array<ArrayBuffer>> = {};\n for (const [alg, hex] of present) {\n if (!(alg in DIGEST_BYTE_LENGTH)) {\n throw new PublishError(\n 'UNSUPPORTED_HASH_ALG',\n `unsupported hash algorithm '${alg as string}' (expected 'sha2-256' or 'blake2b-256')`,\n );\n }\n const bytes = hexToBytes(hex);\n const expected = DIGEST_BYTE_LENGTH[alg];\n if (bytes.length !== expected) {\n throw new PublishError(\n 'INVALID_DIGEST',\n `hashes[${alg}] must be a ${expected}-byte digest (got ${bytes.length} bytes)`,\n );\n }\n decoded[alg] = cloneToOwnedBuffer(bytes);\n }\n\n const record: PoeRecord = {\n v: 1,\n items: [{ hashes: decoded }],\n };\n const recordBytes = await encodeRecord(record, input.signer);\n return postPublish(config, bytesToHex(recordBytes), input.quoteId, input.idempotencyKey);\n}\n\n/**\n * Sealed-PoE: encrypt content to N X25519 recipients (age-style envelope),\n * upload the ciphertext to Arweave, build a single-item record with the\n * resulting `ar://` URI and the sealed envelope in `items[0].enc`, sign\n * (optional), and post to /publish.\n *\n * The plaintext content-hash is bound into `items[0].hashes` so any verifier\n * that successfully decrypts the ciphertext can reconstruct the plaintext\n * and prove the chain of custody from the on-chain hash to the decrypted\n * bytes.\n */\nexport async function publishSealed(\n config: ResolvedPublishConfig,\n input: PublishSealedInput,\n): Promise<PublishResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n if (input.recipients.length < 1) {\n throw new PublishError(\n 'INVALID_RECIPIENT',\n 'publishSealed requires at least one recipient public key',\n );\n }\n // Default to the post-quantum-safe X-Wing hybrid KEM; x25519 is the explicit\n // classical opt-out. The recipient length guard is KEM-aware: 32 B for\n // x25519, 1216 B for the hybrid path.\n const kem = input.kem ?? 'mlkem768x25519';\n const expectedRecipientLength =\n kem === 'x25519' ? X25519_PUBLIC_KEY_LENGTH : MLKEM768X25519_PUBLIC_KEY_LENGTH;\n for (let i = 0; i < input.recipients.length; i++) {\n const pub = input.recipients[i]!;\n if (!(pub instanceof Uint8Array) || pub.length !== expectedRecipientLength) {\n throw new PublishError(\n 'INVALID_RECIPIENT',\n `recipients[${i}] must be a ${expectedRecipientLength}-byte public key for kem='${kem}'`,\n );\n }\n }\n\n const hashAlg: SupportedHashAlg = input.hashAlg ?? 'sha2-256';\n const plaintext = toBytes(input.content);\n const plaintextDigest = hashContent(plaintext, hashAlg);\n const hashes = { [hashAlg]: plaintextDigest };\n\n // Encrypt the plaintext to the recipient public keys under the chosen KEM.\n // The item's plaintext-hash claim is bound into the slots transcript, so\n // the envelope cannot later be spliced onto a different hashes map.\n const sealed = eciesSealedPoeWrap({\n plaintext,\n hashes,\n recipientPublicKeys: input.recipients.map((r) => r),\n kem,\n });\n\n // Upload the ciphertext to Arweave (resumable for large ciphertexts).\n const uri = await uploadBlob(config, sealed.ciphertext, input.idempotencyKey);\n\n // Build the sealed record: one item with the plaintext-bind hash, the\n // `ar://<tx>` URI of the ciphertext, and the discriminated envelope shape.\n // Narrow on the envelope `kem` to emit the correct per-slot fields:\n // classical slots carry `{ epk, wrap }`, hybrid slots carry the single\n // 1120-byte `{ kem_ct, wrap }`.\n const env = sealed.envelope;\n const slots =\n env.kem === 'mlkem768x25519'\n ? env.slots.map((s) => ({\n kem_ct: cloneToOwnedBuffer(s.kem_ct),\n wrap: cloneToOwnedBuffer(s.wrap),\n }))\n : env.slots.map((s) => ({\n epk: cloneToOwnedBuffer(s.epk),\n wrap: cloneToOwnedBuffer(s.wrap),\n }));\n const envelope: EncryptionEnvelope = {\n scheme: 1,\n aead: env.aead,\n kem: env.kem,\n nonce: cloneToOwnedBuffer(env.nonce),\n slots,\n slots_mac: cloneToOwnedBuffer(env.slots_mac),\n };\n\n const record: PoeRecord = {\n v: 1,\n items: [\n {\n hashes,\n uris: [uri],\n enc: envelope,\n },\n ],\n };\n const recordBytes = await encodeRecord(record, input.signer);\n return postPublish(config, bytesToHex(recordBytes), input.quoteId, input.idempotencyKey);\n}\n\n/**\n * Merkle batch publish via /uploads + /publish — N leaves under one\n * transaction. The leaves-list CBOR is uploaded to Arweave as a single\n * blob; the on-chain record carries\n * `merkle[0] = { alg: 'rfc9162-sha256', root, leaf_count, uris: [ar://<tx>] }`.\n *\n * Only `sha2-256` leaves are supported because `rfc9162-sha256` is the only\n * registered tree algorithm and its underlying hash is SHA-256 (32-byte\n * leaves).\n */\nexport async function publishMerkle(\n config: ResolvedPublishConfig,\n input: PublishMerkleInput,\n): Promise<PublishMerkleResponse> {\n if (input.signer !== undefined) assertSigner(input.signer);\n if (input.hashAlg !== undefined && input.hashAlg !== 'sha2-256') {\n throw new PublishError(\n 'UNSUPPORTED_HASH_ALG',\n `publishMerkle only supports 'sha2-256' leaves; got '${input.hashAlg as string}'`,\n );\n }\n if (input.leaves.length < 1) {\n throw new PublishError('INVALID_LEAVES', 'publishMerkle requires at least one leaf hash');\n }\n\n const leaves: Uint8Array[] = input.leaves.map((leaf, idx) => {\n const bytes = typeof leaf === 'string' ? hexToBytes(leaf) : leaf;\n if (!(bytes instanceof Uint8Array) || bytes.length !== LEAF_DIGEST_LENGTH) {\n throw new PublishError(\n 'INVALID_LEAVES',\n `leaves[${idx}] must be a ${LEAF_DIGEST_LENGTH}-byte sha2-256 digest`,\n );\n }\n return bytes;\n });\n\n const root = cloneToOwnedBuffer(merkleSha2256Root(leaves));\n const leavesListCbor = encodeLeavesList({ leaves, root });\n\n // Upload the leaves-list to Arweave (resumable for large leaves-lists).\n const uri = await uploadBlob(config, leavesListCbor, input.idempotencyKey);\n\n // Build the on-chain record with the resulting `ar://` URI.\n const merkleEntry: MerkleCommit = {\n alg: MERKLE_ALG_ID,\n root,\n leaf_count: leaves.length,\n uris: [uri],\n };\n const record: PoeRecord = { v: 1, merkle: [merkleEntry] };\n const recordBytes = await encodeRecord(record, input.signer);\n const published = await postPublish(\n config,\n bytesToHex(recordBytes),\n input.quoteId,\n input.idempotencyKey,\n );\n\n return {\n id: published.id,\n tx_hash: published.tx_hash,\n status: published.status,\n root: bytesToHex(root),\n leaf_count: leaves.length,\n ar_uri: uri,\n balance_after_usd_micros: published.balance_after_usd_micros,\n };\n}\n","// Low-level wrappers over the public mutating /api/v1/poe/* surface:\n//\n// POST /api/v1/poe/quote — lock a USD price for a publish\n// POST /api/v1/poe/uploads — multipart binary upload to a backend\n// POST /api/v1/poe/publish — single finalised record (JSON)\n// POST /api/v1/poe/publish-batch — 1..50 finalised records (JSON)\n//\n// Plus high-level helpers that compose the above into common flows:\n//\n// publishContent({content, quoteId, signer?}) — hash-only\n// publishPrehashed({hashes, quoteId, signer?}) — caller already holds digest\n// publishSealed({content, recipients, quoteId, signer?}) — encrypt + uploads + publish\n// publishMerkle({leaves, quoteId, signer?}) — uploads + publish, Merkle root\n\nimport { bytesToHex } from '../hex';\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport { PartialUploadError } from './partial-upload-error';\nimport {\n publishContent as publishContentImpl,\n publishMerkle as publishMerkleImpl,\n publishPrehashed as publishPrehashedImpl,\n publishSealed as publishSealedImpl,\n type ResolvedPublishConfig,\n} from './publish';\nimport { uploadResumable as uploadResumableImpl, type SingleShotUpload } from './resumable-upload';\nimport type {\n FetchImpl,\n PublishBatchInput,\n PublishBatchResponse,\n PublishContentInput,\n PublishInput,\n PublishMerkleInput,\n PublishMerkleResponse,\n PublishPrehashedInput,\n PublishResponse,\n PublishSealedInput,\n QuoteInput,\n QuoteResponse,\n UploadResumableInput,\n UploadResumableResult,\n UploadSuccessEntry,\n UploadsInput,\n UploadsResponse,\n} from './types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nfunction buildJsonHeaders(args: {\n apiKey: string | undefined;\n idempotencyKey?: string | undefined;\n}): Headers {\n const headers = new Headers({ 'content-type': 'application/json', accept: 'application/json' });\n if (args.apiKey !== undefined) headers.set('authorization', `Bearer ${args.apiKey}`);\n if (args.idempotencyKey !== undefined) headers.set('idempotency-key', args.idempotencyKey);\n return headers;\n}\n\nfunction buildMultipartHeaders(args: {\n apiKey: string | undefined;\n idempotencyKey?: string | undefined;\n}): Headers {\n // Do NOT set content-type — the runtime emits the multipart boundary header\n // automatically when the body is a FormData. Forcing it here would emit a\n // boundary-less content-type that the server rejects.\n const headers = new Headers({ accept: 'application/json' });\n if (args.apiKey !== undefined) headers.set('authorization', `Bearer ${args.apiKey}`);\n if (args.idempotencyKey !== undefined) headers.set('idempotency-key', args.idempotencyKey);\n return headers;\n}\n\nfunction toHex(record: Uint8Array | string): string {\n return typeof record === 'string' ? record : bytesToHex(record);\n}\n\nexport class PoeNamespace {\n private readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * Request an opaque price lock for an upcoming /publish call. The gateway\n * prices the described publish from the supplied byte counts, records the\n * lock, and returns a sealed price token: `quote_id`, the total `amount` in\n * `currency`, and an `expires_at`. The gateway's pricing internals are\n * deliberately NOT part of the response.\n *\n * `amount` is a decimal string; promote it to `BigInt` (or a decimal type)\n * at the application boundary if you need exact arithmetic.\n *\n * Pass the returned `quote_id` to `publish()` (or one of the high-level\n * `publishContent` / `publishSealed` / `publishMerkle` helpers).\n */\n async quote(input: QuoteInput): Promise<QuoteResponse> {\n const body = {\n record_bytes: input.recordBytes,\n recipient_count: input.recipientCount,\n file_bytes_total: input.fileBytesTotal,\n };\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/quote`, {\n method: 'POST',\n headers: buildJsonHeaders({ apiKey: this.config.apiKey }),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n return (await readJson(response)) as QuoteResponse;\n }\n\n /**\n * Upload 1..32 binary files to a storage backend. Returns one entry per file\n * — successful entries carry the `ar://` URI + content hash, failed entries\n * carry an error code / detail so the caller can retry just the failed\n * indices.\n *\n * Billing: free. The storage cost is part of the publish quote (POST\n * /api/v1/poe/quote → POST /api/v1/poe/publish) and is debited once at\n * publish time against the locked price snapshot.\n *\n * On HTTP-level failure (auth, rate limit, malformed request) this throws\n * a typed `Label309HttpError` subclass. Per-file failures inside a 200\n * response are NOT thrown by `uploads()` itself — the response body is\n * returned verbatim so the caller can decide how to react. The\n * higher-level helpers (`publishSealed`, `publishMerkle`) treat any failed\n * file as a `PartialUploadError`.\n */\n async uploads(input: UploadsInput): Promise<UploadsResponse> {\n const form = new FormData();\n form.append('target', input.target);\n for (let idx = 0; idx < input.data.length; idx++) {\n const bytes = input.data[idx]!;\n // Uint8Array is a valid Blob source in every runtime that ships\n // FormData (browser, undici, node 20+); cast through `unknown` keeps\n // strict-mode TS happy without dragging in lib.dom.iterable.d.ts here.\n form.append(\n `file_${idx}`,\n new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n `file_${idx}.bin`,\n );\n }\n const headers = buildMultipartHeaders({\n apiKey: this.config.apiKey,\n idempotencyKey: input.idempotencyKey,\n });\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/uploads`, {\n method: 'POST',\n headers,\n body: form,\n });\n await throwIfNotOk(response);\n return (await readJson(response)) as UploadsResponse;\n }\n\n /**\n * Upload a single file of any size, choosing the ingress path by size.\n *\n * A file at or below `threshold` (default ~48 MiB) is sent with the unchanged\n * single-shot `uploads()` multipart call. A larger file is uploaded as a\n * resumable, content-addressed session: the helper streams the whole-file\n * SHA-256 once (never buffering a multi-GB file), creates a session, PUTs each\n * chunk (several in parallel, retrying a failed chunk), then completes —\n * polling the shared attempt endpoint when completion is accepted\n * asynchronously. Both paths converge on one `ar://` URI.\n *\n * The chunk size is the server's authoritative `chunk_bytes` from the create\n * response, clamped to its `max_chunk_bytes` ceiling; the client's `chunkBytes`\n * is only a request. A create-time dedup hit returns the existing URI without\n * uploading; a `402` funding error is surfaced as a typed error.\n *\n * The `source` works in both runtimes: a `Blob`/`File` in the browser, a\n * `Uint8Array`, a filesystem path string, or a pre-adapted `ResumableSource`\n * on the server. To resume an interrupted upload, pass the prior `sessionId`;\n * the helper GETs its status and uploads only the missing chunks.\n */\n async uploadResumable(input: UploadResumableInput): Promise<UploadResumableResult> {\n return uploadResumableImpl(this.config, this.singleShotUpload, input);\n }\n\n /**\n * Upload exactly one blob via the single-shot multipart route and resolve its\n * `ar://` URI. Backs the small-file branch of `uploadResumable`; it shares the\n * `uploads()` wire shape but takes one blob and an optional abort signal, and\n * surfaces a per-file failure as a `PartialUploadError` (the resumable helper\n * promises a single resolved URI, unlike the raw `uploads()` passthrough).\n */\n private readonly singleShotUpload: SingleShotUpload = async ({\n target,\n bytes,\n idempotencyKey,\n signal,\n }) => {\n const form = new FormData();\n form.append('target', target);\n form.append(\n 'file_0',\n new Blob([bytes as unknown as ArrayBuffer], { type: 'application/octet-stream' }),\n 'file_0.bin',\n );\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/uploads`, {\n method: 'POST',\n headers: buildMultipartHeaders({ apiKey: this.config.apiKey, idempotencyKey }),\n body: form,\n ...(signal ? { signal } : {}),\n });\n await throwIfNotOk(response);\n const result = (await readJson(response)) as UploadsResponse;\n const entry = result.uploads[0];\n if (entry === undefined || entry.ok === false) {\n throw new PartialUploadError(result);\n }\n const ok = entry as UploadSuccessEntry;\n return { uri: ok.uri, sha256: ok.sha256, bytes: ok.bytes };\n };\n\n /**\n * Submit a single finalised canonical-CBOR record to Cardano. Caller is\n * responsible for constructing the record bytes (use `publishContent` /\n * `publishSealed` / `publishMerkle` for the assisted flows) and for\n * acquiring a `quote_id` via `quote()` first.\n *\n * Returns 202 (`dedup_hit: false`) on freshly enqueued records, or 200\n * (`dedup_hit: true`) when the same record bytes were previously submitted\n * by this account. Dedup hits debit nothing.\n */\n async publish(input: PublishInput): Promise<PublishResponse> {\n const body: { record: string; quote_id: string; signatures?: ReadonlyArray<unknown> } = {\n record: toHex(input.record),\n quote_id: input.quoteId,\n };\n if (input.signatures !== undefined) body.signatures = input.signatures;\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/publish`, {\n method: 'POST',\n headers: buildJsonHeaders({\n apiKey: this.config.apiKey,\n idempotencyKey: input.idempotencyKey,\n }),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n const parsed = (await readJson(response)) as Omit<PublishResponse, 'dedup_hit'>;\n return { ...parsed, dedup_hit: response.status === 200 };\n }\n\n /**\n * Submit 1..50 finalised records as independent Cardano transactions.\n * Each entry carries its own `quote_id` — request quotes ahead of time\n * with one `quote()` call per record. Returns 200 with `results[]` —\n * successful entries land alongside failed ones; per-record errors do NOT\n * roll back the batch.\n */\n async publishBatch(input: PublishBatchInput): Promise<PublishBatchResponse> {\n const body = {\n records: input.records.map((r) => ({\n record: toHex(r.record),\n quote_id: r.quoteId,\n ...(r.signatures !== undefined ? { signatures: r.signatures } : {}),\n })),\n };\n const response = await this.config.fetch(`${this.config.baseUrl}/api/v1/poe/publish-batch`, {\n method: 'POST',\n headers: buildJsonHeaders({\n apiKey: this.config.apiKey,\n idempotencyKey: input.idempotencyKey,\n }),\n body: JSON.stringify(body),\n });\n await throwIfNotOk(response);\n return (await readJson(response)) as PublishBatchResponse;\n }\n\n /**\n * High-level hash-only publish: hash the supplied content, build a\n * single-item Label 309 record, optionally sign it with the caller-supplied\n * signer, and submit. No Arweave, no storage round-trip — anchors the\n * digest only.\n */\n async publishContent(input: PublishContentInput): Promise<PublishResponse> {\n return publishContentImpl(this.config as ResolvedPublishConfig, input);\n }\n\n /**\n * Hash-already-computed publish: caller already holds the digest(s) — e.g.\n * the CLI `--hash <hex>` mode, an air-gapped offline hashing flow, or any\n * pipeline that proxies digests from another tool. No client-side hashing.\n */\n async publishPrehashed(input: PublishPrehashedInput): Promise<PublishResponse> {\n return publishPrehashedImpl(this.config as ResolvedPublishConfig, input);\n }\n\n /**\n * Sealed-PoE: encrypt the supplied content to the recipient X25519 public\n * keys (age-style sealed envelope), upload the ciphertext to Arweave via\n * /uploads, build a Label 309 record with the resulting `ar://` URI, sign\n * it (optional), and submit via /publish.\n *\n * The sender SHOULD include their own X25519 public key in `recipients`\n * to retain decrypt access — the SDK does NOT inject the sender silently.\n */\n async publishSealed(input: PublishSealedInput): Promise<PublishResponse> {\n return publishSealedImpl(this.config as ResolvedPublishConfig, input);\n }\n\n /**\n * Merkle batch publish: compute the RFC 9162 §2.1.1 root over N\n * caller-supplied 32-byte leaf hashes, upload the canonical leaves-list\n * CBOR to Arweave via /uploads, bind the root + leaf_count into\n * `merkle[0]` of an on-chain record, optionally sign, and submit.\n *\n * Returns the on-chain id + tx hash + root + leaf count + the canonical\n * `ar://<tx>` URI of the leaves-list. Anyone with that URI can later\n * fetch the leaves-list, recompute the root, and prove inclusion of any\n * leaf via `merkleSha2256VerifyInclusion`.\n */\n async publishMerkle(input: PublishMerkleInput): Promise<PublishMerkleResponse> {\n return publishMerkleImpl(this.config as ResolvedPublishConfig, input);\n }\n}\n","// `client.records.*` wraps the open-standard indexer read surface:\n//\n// GET /api/v1/records → records.list(input?)\n// GET /api/v1/records/{tx_hash} → records.get(txHash)\n// POST /api/v1/records/{tx_hash}/verify → records.verify(txHash, input)\n//\n// The PoE namespace owns the mutation methods (uploads, publish,\n// publishBatch + the high-level publishContent/publishSealed/publishMerkle\n// helpers); reads and verifications live here under Records — same tag\n// grouping the OpenAPI registry uses (`tags: ['Records']` on these\n// operationIds).\n//\n// Auth is optional: chain data is public. When an API key is configured the\n// SDK forwards it as `Authorization: Bearer …` so owner-only fields\n// (currently just `account_id`) surface for the caller's own rows, and so the\n// `sealed` list filter can resolve records addressed to the caller.\n\nimport { readJson, throwIfNotOk } from './http-helpers';\nimport type {\n FetchImpl,\n PoeVerifyInput,\n RecordResource,\n RecordsListInput,\n RecordsListResponse,\n} from './types';\nimport type { VerifyReport } from '../verifier/types';\n\ninterface ResolvedConfig {\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n readonly fetch: FetchImpl;\n}\n\nfunction buildHeaders(apiKey: string | undefined): Headers {\n const headers = new Headers({\n 'content-type': 'application/json',\n accept: 'application/json',\n });\n if (apiKey !== undefined) headers.set('authorization', `Bearer ${apiKey}`);\n return headers;\n}\n\n/**\n * Derive the chain tip from a record page as `max(block_height +\n * num_confirmations - 1)` over the rows that carry a block height. Returns\n * `null` for an empty page or one with no anchored rows.\n */\nfunction deriveTipBlockHeight(records: ReadonlyArray<RecordResource>): number | null {\n let tip: number | null = null;\n for (const r of records) {\n if (r.block_height === null) continue;\n const candidate = r.block_height + r.num_confirmations - 1;\n tip = tip === null ? candidate : Math.max(tip, candidate);\n }\n return tip;\n}\n\nexport class RecordsNamespace {\n private readonly config: ResolvedConfig;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n }\n\n /**\n * List records as a paginated `RecordsListResponse` whose `data[]` entries\n * are the same `RecordResource` projection `get()` returns.\n *\n * Pass `{ sealed: true }` to restrict the page to sealed records addressed\n * to the authenticated caller (the gateway resolves the recipient from the\n * bearer identity); omit it to list every record the caller may read. Page\n * with `{ cursor: previous.next_cursor }` until `has_more` is false.\n */\n async list(input?: RecordsListInput): Promise<RecordsListResponse> {\n const params = new URLSearchParams();\n if (input?.sealed === true) params.set('sealed', 'true');\n if (input?.limit !== undefined) params.set('limit', String(input.limit));\n if (input?.cursor !== undefined && input.cursor !== null) {\n params.set('cursor', input.cursor);\n }\n const query = params.toString();\n const url = `${this.config.baseUrl}/api/v1/records${query === '' ? '' : `?${query}`}`;\n const response = await this.config.fetch(url, {\n method: 'GET',\n headers: buildHeaders(this.config.apiKey),\n });\n await throwIfNotOk(response);\n const page = (await readJson(response)) as RecordsListResponse;\n // A gateway that reports `tip_block_height` populates confirmation data\n // directly; otherwise derive it from the page rows so sealed-record sync\n // has a tip to compute confirmation depth against.\n if (page.tip_block_height === undefined || page.tip_block_height === null) {\n return { ...page, tip_block_height: deriveTipBlockHeight(page.data) };\n }\n return page;\n }\n\n /**\n * Fetch a record by Cardano transaction hash. Returns the JSON\n * `RecordResource` projection — same shape every `records.list` page entry\n * carries inside `data[]`.\n *\n * 404 (RecordNotFoundError) on tx_hashes the indexer has not seen, OR on\n * un-anchored rows when the caller is not their owner (oracle-safe\n * indistinguishable response per the route's privacy invariant).\n */\n async get(txHash: string): Promise<RecordResource> {\n const response = await this.config.fetch(\n `${this.config.baseUrl}/api/v1/records/${encodeURIComponent(txHash)}`,\n {\n method: 'GET',\n headers: buildHeaders(this.config.apiKey),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as RecordResource;\n }\n\n /**\n * Run the canonical Label 309 verifier against the record at `txHash`.\n * Returns the same `VerifyReport` shape the standalone verifier emits —\n * `VerifyReport` IS the wire body of this endpoint, with no transformer in\n * between.\n *\n * Auth required (Bearer with `poe:read` scope, or NextAuth session\n * cookie). This is the hosted PUBLIC verifier: it accepts no decryption\n * credentials, and sealed items report as unverifiable without decryption.\n * To verify as a recipient (decrypt + plaintext-hash recheck), run the\n * `verifier` module locally with its `decryption` input — keys never leave\n * the process. Optional `fetch_content: false` skips content re-fetching;\n * affected claims report `not_checked`.\n */\n async verify(txHash: string, input?: PoeVerifyInput): Promise<VerifyReport> {\n // Whitelist-build the wire body field by field — never serialize the\n // caller's object verbatim — so unknown properties smuggled in by an\n // untyped call site (including credential material) can never reach the\n // gateway.\n const body: { fetch_content?: boolean } = {};\n if (input?.fetch_content !== undefined) body.fetch_content = input.fetch_content;\n const response = await this.config.fetch(\n `${this.config.baseUrl}/api/v1/records/${encodeURIComponent(txHash)}/verify`,\n {\n method: 'POST',\n headers: buildHeaders(this.config.apiKey),\n body: JSON.stringify(body),\n },\n );\n await throwIfNotOk(response);\n return (await readJson(response)) as VerifyReport;\n }\n}\n","import { AccountNamespace } from './account';\nimport { InvalidClientConfigError } from './invalid-client-config-error';\nimport { PoeNamespace } from './poe';\nimport { RecordsNamespace } from './records';\nimport type { Label309ClientConfig, FetchImpl } from './types';\n\nfunction resolveFetch(provided: FetchImpl | undefined): FetchImpl {\n if (provided !== undefined) return provided;\n if (typeof globalThis.fetch === 'function') {\n // Bind to preserve `this` inside Node/browser fetch implementations.\n return globalThis.fetch.bind(globalThis);\n }\n throw new Error(\n 'Label309Client: no fetch implementation available. Pass `fetch` in the config or run on a platform with globalThis.fetch.',\n );\n}\n\n/**\n * Resolves the gateway base URL the client targets.\n *\n * `baseUrl` is REQUIRED and is used verbatim — the client is gateway-agnostic\n * and binds to no particular deployment. A missing or empty `baseUrl` is a\n * configuration error: there is nowhere to send requests. Trailing slashes are\n * stripped so callers may pass `https://gw.example.com/` or\n * `https://gw.example.com` interchangeably.\n *\n * The `apiKey`, when present, is an OPAQUE bearer token forwarded verbatim as\n * `Authorization: Bearer <apiKey>`. It is never parsed, validated, or used to\n * infer the URL — any Label 309 gateway may issue keys in its own format. Omit it\n * for anonymous read-only usage.\n */\nfunction resolveBaseUrl(config: Label309ClientConfig): string {\n const baseUrl = config.baseUrl?.trim();\n if (baseUrl === undefined || baseUrl === '') {\n throw new InvalidClientConfigError(\n 'Label309Client: baseUrl is required. Pass the base URL of the Label 309 ' +\n 'gateway you are targeting (e.g. https://gateway.example.com).',\n );\n }\n return baseUrl.replace(/\\/$/, '');\n}\n\nexport class Label309Client {\n public readonly poe: PoeNamespace;\n public readonly records: RecordsNamespace;\n public readonly account: AccountNamespace;\n\n /**\n * Construct a client against a Label 309 gateway.\n *\n * `config.baseUrl` is required — there is no default deployment. The\n * `config.apiKey`, when supplied, is an opaque bearer token sent verbatim as\n * `Authorization: Bearer <apiKey>`; omit it for anonymous read-only access.\n *\n * PoE submissions debit the gateway's own balance model. Acquire a price lock\n * via `client.poe.quote(...)` first; the resulting `quote_id` is consumed by\n * the publish call.\n */\n constructor(config: Label309ClientConfig) {\n const fetchImpl = resolveFetch(config.fetch);\n const baseUrl = resolveBaseUrl(config);\n const resolved = { apiKey: config.apiKey, baseUrl, fetch: fetchImpl };\n this.poe = new PoeNamespace(resolved);\n this.records = new RecordsNamespace(resolved);\n this.account = new AccountNamespace(resolved);\n }\n}\n"]}
|