{"version":3,"sources":["../../src/crypto/jcs.ts","../../src/crypto/hash.ts","../../src/crypto/merkle.ts","../../src/types/bundle.ts","../../src/verify/unzip.ts","../../src/verify/index.ts"],"names":["createHash","h"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * JCS (RFC 8785) canonicalization.\n *\n * Deterministic JSON serialization. Without this, two servers might\n * produce different byte strings for the same object, breaking hash\n * equality and verification. JCS sorts object keys lexically and\n * uses stable number / string formatting.\n *\n * This implementation matches Python's\n *\n *   json.dumps(o, sort_keys=True, separators=(\",\", \":\"), ensure_ascii=False)\n *\n * for all JSON-safe values used in EnvelopeV1, STH, and bundle JSON\n * files. Cross-language parity is a hard invariant — any change here\n * requires a coordinated update to the Python SDK's equivalent\n * function and a re-run of the parity fixtures (see\n * `test/envelope-parity.spec.ts` and `test/sth-parity.spec.ts`).\n *\n * Functionally equivalent to `shared-deps/chain/lib/crypto.ts::jcs`.\n * Reimplemented here rather than imported because:\n *   - the SDK has zero runtime dependencies (shared-deps pulls in\n *     `@aws-sdk/client-kms` for backend signing);\n *   - duplicating ~25 lines is cheaper than a peer-dep treadmill;\n *   - the parity tests cross-validate byte-for-byte against\n *     shared-deps' fixture, so drift is caught at CI time.\n */\n\nexport function jcs(value: unknown): string {\n  if (value === null) return \"null\";\n  if (typeof value === \"number\") {\n    if (!Number.isFinite(value)) {\n      throw new Error(\"JCS: non-finite number\");\n    }\n    return value.toString();\n  }\n  if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n  if (typeof value === \"string\") return JSON.stringify(value);\n  if (Array.isArray(value)) {\n    return \"[\" + value.map(jcs).join(\",\") + \"]\";\n  }\n  if (typeof value === \"object\") {\n    const obj = value as Record<string, unknown>;\n    const keys = Object.keys(obj).sort();\n    return (\n      \"{\" +\n      keys.map((k) => JSON.stringify(k) + \":\" + jcs(obj[k])).join(\",\") +\n      \"}\"\n    );\n  }\n  throw new Error(\"JCS: unsupported type \" + typeof value);\n}\n","/**\n * Hash primitives — SHA-256 over Buffers and strings, plus the\n * canonical envelope-hash and STH-hash entry points.\n *\n * Uses `node:crypto` only. Browser / non-Node runtimes are not\n * supported in v1; if a Phase 2 use case needs them we can swap in\n * `globalThis.crypto.subtle` behind a thin abstraction.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { jcs } from \"./jcs.js\";\n\nexport function sha256(buf: Buffer | Uint8Array | string): Buffer {\n  const input =\n    typeof buf === \"string\"\n      ? buf\n      : Buffer.isBuffer(buf)\n        ? buf\n        : Buffer.from(buf);\n  return createHash(\"sha256\").update(input).digest();\n}\n\nexport function sha256Hex(buf: Buffer | Uint8Array | string): string {\n  return sha256(buf).toString(\"hex\");\n}\n\n/**\n * Canonical envelope hash.\n *\n * Per ARCHITECTURE.md §5, the envelope does not contain a signature.\n * Defensively strip any `sig` field before hashing — protects\n * against dynamic callers (e.g. negative-case tests, or a deserialized\n * pre-spec envelope) that might include one.\n *\n * The result is the value the issuer signs, the value emitted as\n * `envelope_hash` everywhere, and the value verifiers compare to the\n * `envelope.hash` file inside a bundle.\n */\nexport function envelopeHash(envelope: Record<string, unknown>): string {\n  const withoutSig: Record<string, unknown> = { ...envelope };\n  delete withoutSig.sig;\n  return sha256Hex(jcs(withoutSig));\n}\n\n/**\n * Canonical STH hash.\n *\n * Per ARCHITECTURE.md §6.3, the chain-master signature is stored in\n * the `master_sig` field on the wire form. Strip both `master_sig`\n * and the legacy `sig` (defensively, for any pre-M03 STHs that\n * might still be in flight) before hashing.\n *\n * After stripping, JCS sorts the remaining keys lexically — the\n * preimage byte order is `alg, checkpoint, key_id, root, segment,\n * timestamp, tree_size, v`.\n */\nexport function sthHash(sth: Record<string, unknown>): string {\n  const withoutSigs: Record<string, unknown> = { ...sth };\n  delete withoutSigs.master_sig;\n  delete withoutSigs.sig;\n  return sha256Hex(jcs(withoutSigs));\n}\n","/**\n * RFC 6962 Certificate-Transparency-style Merkle tree primitives.\n *\n * - Domain-separated leaf and node prefixes (0x00, 0x01) to prevent\n *   second-preimage / length-extension attacks.\n * - SHA-256 only in v1 (matches shared-deps default; SHA-512 lives\n *   on the backend tree but is irrelevant to v1 verification).\n * - Verification only: this SDK never builds trees, only walks\n *   audit paths. Tree construction lives in the backend\n *   (`anchor-service` Lambda) and is unnecessary here.\n *\n * Mirrors `shared-deps/chain/lib/merkle.ts::leafHash`,\n * `nodeHash`, `verifyInclusion`. Reimplemented for the same\n * dependency-zero reasons as `./jcs.ts`.\n */\n\nimport { createHash } from \"node:crypto\";\n\nconst LEAF_PREFIX = Buffer.from([0x00]);\nconst NODE_PREFIX = Buffer.from([0x01]);\n\nfunction h(...parts: Buffer[]): Buffer {\n  const d = createHash(\"sha256\");\n  for (const p of parts) d.update(p);\n  return d.digest();\n}\n\n/**\n * Hash a leaf payload (canonical envelope bytes).\n *\n * The result is the bundle's `merkle.json::leaf_hash` — NOT the\n * envelope hash. The two differ by the `0x00` prefix; a verifier\n * that compares them directly is wrong.\n */\nexport function leafHash(payload: Buffer | Uint8Array): Buffer {\n  const buf = Buffer.isBuffer(payload) ? payload : Buffer.from(payload);\n  return h(LEAF_PREFIX, buf);\n}\n\n/** Hash an internal node from two children. */\nexport function nodeHash(left: Buffer, right: Buffer): Buffer {\n  return h(NODE_PREFIX, left, right);\n}\n\n/**\n * Verify an inclusion proof.\n *\n * Recomputes the root from `(leaf, m, n, path)` and compares against\n * `expectedRoot`. Consumes the path bottom-up (closest-to-leaf first),\n * matching the RFC 6962 §2.1.1 audit-path format and the order that\n * the backend's `inclusionProof` produces.\n *\n * Handles non-power-of-two sizes correctly: at levels where a subtree\n * is \"promoted\" without a sibling (`fn === sn`), the walk keeps\n * climbing until it encounters the next real sibling.\n */\nexport function verifyInclusion(\n  leaf: Buffer,\n  m: number,\n  n: number,\n  path: Buffer[],\n  expectedRoot: Buffer,\n): boolean {\n  if (m >= n || n === 0) return false;\n\n  let fn = m;\n  let sn = n - 1;\n  let r = leaf;\n\n  for (const sibling of path) {\n    if (sn === 0) return false; // over-long path\n    if ((fn & 1) === 1 || fn === sn) {\n      r = nodeHash(sibling, r);\n      while ((fn & 1) === 0 && fn !== 0) {\n        fn >>= 1;\n        sn >>= 1;\n      }\n    } else {\n      r = nodeHash(r, sibling);\n    }\n    fn >>= 1;\n    sn >>= 1;\n  }\n\n  return sn === 0 && r.equals(expectedRoot);\n}\n\n/**\n * Verify a consistency proof: old root (size m) → new root (size n).\n * RFC 6962 §2.1.4.\n *\n * Used by witness implementations and the consistency-check feature\n * in the Governance Console (M10). Verification only — no proof\n * construction in v1.\n */\nexport function verifyConsistency(\n  oldRoot: Buffer,\n  newRoot: Buffer,\n  m: number,\n  n: number,\n  proof: Buffer[],\n): boolean {\n  if (m < 0 || m > n) return false;\n  if (m === n) return proof.length === 0 && oldRoot.equals(newRoot);\n  if (m === 0) return proof.length === 0;\n\n  let fn = m - 1;\n  let sn = n - 1;\n  while ((fn & 1) === 1) {\n    fn >>= 1;\n    sn >>= 1;\n  }\n\n  let i = 0;\n  let oldHash: Buffer;\n  let newHash: Buffer;\n\n  if (fn === 0) {\n    oldHash = oldRoot;\n    newHash = oldRoot;\n  } else {\n    if (proof.length === 0) return false;\n    oldHash = proof[i] as Buffer;\n    newHash = proof[i] as Buffer;\n    i++;\n  }\n\n  while (sn !== 0) {\n    if (i >= proof.length) return false;\n    if ((fn & 1) === 1 || fn === sn) {\n      const sib = proof[i] as Buffer;\n      oldHash = nodeHash(sib, oldHash);\n      newHash = nodeHash(sib, newHash);\n      while ((fn & 1) === 0 && fn !== 0) {\n        fn >>= 1;\n        sn >>= 1;\n      }\n    } else {\n      const sib = proof[i] as Buffer;\n      newHash = nodeHash(newHash, sib);\n    }\n    i++;\n    fn >>= 1;\n    sn >>= 1;\n  }\n\n  return (\n    i === proof.length && oldHash.equals(oldRoot) && newHash.equals(newRoot)\n  );\n}\n\nexport const hex = (b: Buffer): string => b.toString(\"hex\");\nexport const unhex = (s: string): Buffer => Buffer.from(s, \"hex\");\n","/**\n * `.dpiv-bundle` JSON shapes.\n *\n * Mirrors `shared-deps/chain/bundle/bundle-types.ts`. Any drift\n * between this file and ARCHITECTURE.md §8 is a bug — the\n * architecture doc wins.\n *\n * The files documented here are the JSON payloads inside a bundle:\n *   - `merkle.json`   — `MerkleProofJson`\n *   - `sth.json`      — `STH` (re-exported from `./sth`)\n *   - `onchain.json`  — `OnchainProofJson`   (optional)\n *   - `labels.json`   — `LabelsJson`\n *   - `MANIFEST.txt`  — `ManifestEntry[]` (see `../crypto/manifest`)\n */\n\n/**\n * `merkle.json` — the inclusion proof for one leaf in one segment.\n *\n * Verifiers walk `audit_path` bottom-up using RFC 6962 domain\n * separation (`0x00 || leaf` for leaf hashes, `0x01 || left || right`\n * for nodes). The walk MUST close to the `root` field of the\n * bundle's `sth.json` for the segment — verifiers cross-check the\n * two files, not just `merkle.json` in isolation.\n *\n * `leaf_hash` is the RFC 6962 leaf hash:\n * `SHA-256(0x00 || envelope_canonical_bytes)`. It is NOT\n * `envelope_hash` (which omits the `0x00` prefix). A naive verifier\n * that checks `leaf_hash === envelope_hash` is wrong — they differ\n * by the prefix-and-rehash step.\n *\n * Hex fields are lowercase, no `0x` prefix. `audit_path` is ordered\n * leaf-to-root and its length equals `ceil(log2(tree_size))` for the\n * segment's tree at the STH used.\n */\nexport interface MerkleProofJson {\n  v: 1;\n  segment: number;\n  leaf_index: number;\n  leaf_hash: string;\n  audit_path: string[];\n}\n\n/**\n * `onchain.json` — optional. Present only when the segment has a\n * confirmed `anchor_checkpoint` row whose `tree_size` covers\n * `merkle.json.leaf_index` and whose `root` matches the bundle's\n * `sth.json.root`.\n *\n * The bundle service refuses to assemble a bundle if an attestation\n * has been logged as `onchain` or `dual` mode but no confirmed\n * receipt exists — i.e. this file is present iff the on-chain claim\n * is substantiated server-side at build time. Per\n * ARCHITECTURE.md §8 D.7, `verify.sh` step 6 is informational only;\n * absence of this file does NOT weaken the proof's off-chain checks.\n *\n * `chain` uses canonical short names matching the on-chain anchor\n * service. `contract` is the registry address as a 0x-prefixed\n * checksummed hex string. `tx` is the tx hash. `block` is the block\n * number containing the tx. `tree_size` and `root` MUST match the\n * corresponding fields of `sth.json`.\n */\nexport interface OnchainProofJson {\n  v: 1;\n  chain: \"base-mainnet\" | \"base-sepolia\";\n  contract: `0x${string}`;\n  tx: `0x${string}`;\n  block: number;\n  segment: number;\n  tree_size: number;\n  root: string;\n}\n\n/**\n * One label entry in `labels.json`.\n *\n * The discriminator is the presence of the `salt` field — `salt`\n * appears ONLY when the bundle was built with the matching label\n * name in the reveal-set query parameter. A verifier seeing a `salt`\n * field MUST compute\n *\n *   SHA-256(name + \":\" + String(value) + \":\" + salt)\n *\n * and check it equals `commit`. Mismatch = the bundle was tampered\n * with or the salt is for a different label.\n *\n * Unrevealed labels have NO `salt` and NO `value` field. Bundle\n * builders MUST default to unrevealed; salts only ship when\n * explicitly requested. SDK consumers MUST NOT render salt values\n * outside an explicit \"reveal\" UI; logging `salt` at any level is a\n * privacy bug.\n */\nexport interface RevealedLabel {\n  name: string;\n  value: boolean | string | number;\n  salt: string;\n  commit: string;\n  public_value?: boolean | string | number;\n}\n\nexport interface UnrevealedLabel {\n  name: string;\n  commit: string;\n  public_value?: boolean | string | number;\n}\n\nexport type BundleLabel = RevealedLabel | UnrevealedLabel;\n\n/**\n * `labels.json`. Always present, even when the envelope has zero\n * labels (in that case `labels` is the empty list). The empty-list\n * sentinel is non-negotiable so verifiers can unconditionally\n * attempt to read this file without first checking its existence.\n */\nexport interface LabelsJson {\n  v: 1;\n  labels: BundleLabel[];\n}\n\n/**\n * Type guard — narrow a `BundleLabel` to the revealed variant.\n * Use to gate any UI that needs to display the salt-recompute step\n * (and only that UI — never log the salt).\n */\nexport function isRevealedLabel(l: BundleLabel): l is RevealedLabel {\n  return (l as RevealedLabel).salt !== undefined;\n}\n\n/**\n * One row in `MANIFEST.txt`. `path` is the bundle-relative path\n * (POSIX forward-slashes); `sha256` is the lowercase hex digest of\n * the file's contents. The on-disk format is sha256sum-compatible.\n */\nexport interface ManifestEntry {\n  path: string;\n  sha256: string;\n}\n\n/**\n * Canonical bundle filenames. Renaming any of these is a breaking\n * change to every historical bundle's `verify.sh` script. Treat as\n * append-only.\n */\nexport const BUNDLE_FILES = {\n  MANIFEST: \"MANIFEST.txt\",\n  ENVELOPE: \"envelope.json\",\n  ENVELOPE_HASH: \"envelope.hash\",\n  ISSUER_PEM: \"issuer.pem\",\n  LABELS: \"labels.json\",\n  MASTER_PEM: \"master.pem\",\n  MERKLE: \"merkle.json\",\n  ONCHAIN: \"onchain.json\",\n  SIGNATURE: \"signature.bin\",\n  STH: \"sth.json\",\n  VERIFY_SCRIPT: \"verify.sh\",\n  MERKLE_WALK_HELPER: \"merkle-walk\",\n  TS_DIGICERT: \"timestamps/digicert.tsr\",\n  TS_DIGICERT_CA: \"timestamps/digicert-ca.pem\",\n  TS_SECTIGO: \"timestamps/sectigo.tsr\",\n  TS_SECTIGO_CA: \"timestamps/sectigo-ca.pem\",\n} as const;\n\nexport const BUNDLE_SUFFIX = \".dpiv-bundle\";\n","/**\n * Minimal stored-method ZIP reader.\n *\n * `.dpiv-bundle` files are produced by the M05 bundle Lambda using\n * the stored (uncompressed) method per ARCHITECTURE.md §8 D.4 — the\n * payloads are already entropy-dense (sigs, hex digests, signed\n * timestamps) and storing uncompressed lets verifiers operate\n * without a deflate implementation. That choice keeps this SDK at\n * zero runtime deps.\n *\n * This reader supports STORED (method=0) only. If the registry ever\n * starts emitting DEFLATE bundles, this function throws a clear\n * \"unsupported compression method\" error rather than silently\n * misverifying. The intent is documented in the bundle builder, the\n * verify.sh script, and ARCHITECTURE.md — coordinated change only.\n *\n * No symlink, no zip-slip, no UTF-8 surprises. Path entries are\n * checked against backslashes and `..` segments before being added\n * to the output map.\n */\n\nconst ZIP_LFH_SIG = 0x04034b50;\nconst ZIP_CDFH_SIG = 0x02014b50;\nconst ZIP_EOCD_SIG = 0x06054b50;\n\nconst METHOD_STORED = 0;\n\nexport interface UnzipResult {\n  /** Bundle-relative path → file bytes. POSIX forward slashes only. */\n  files: Record<string, Uint8Array>;\n}\n\n/**\n * Parse a stored-method ZIP buffer into a flat path → bytes map.\n *\n * Reads the End Of Central Directory record at the tail, walks the\n * central directory forward, and extracts each entry from its local\n * file header position. Refuses entries with backslashes, leading\n * slashes, or `..` segments.\n */\nexport function unzipBundle(input: ArrayBuffer | Uint8Array): UnzipResult {\n  const buf = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\n  const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);\n\n  // Locate EOCD (search backward up to ~64 KB to skip a minimal\n  // ZIP64 / no-comment archive — the bundle's comment is empty).\n  const maxBack = Math.min(buf.byteLength, 65557);\n  let eocdOffset = -1;\n  for (let i = buf.byteLength - 22; i >= buf.byteLength - maxBack; i--) {\n    if (i < 0) break;\n    if (dv.getUint32(i, true) === ZIP_EOCD_SIG) {\n      eocdOffset = i;\n      break;\n    }\n  }\n  if (eocdOffset === -1) {\n    throw new Error(\"unzip: not a ZIP archive (no EOCD signature)\");\n  }\n\n  const totalEntries = dv.getUint16(eocdOffset + 10, true);\n  const cdSize = dv.getUint32(eocdOffset + 12, true);\n  const cdOffset = dv.getUint32(eocdOffset + 16, true);\n  if (cdSize === 0xffffffff || cdOffset === 0xffffffff) {\n    throw new Error(\"unzip: ZIP64 archives are not supported\");\n  }\n\n  const files: Record<string, Uint8Array> = {};\n  let cur = cdOffset;\n  const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n\n  for (let i = 0; i < totalEntries; i++) {\n    if (dv.getUint32(cur, true) !== ZIP_CDFH_SIG) {\n      throw new Error(\"unzip: bad central directory file header\");\n    }\n    const method = dv.getUint16(cur + 10, true);\n    const compressedSize = dv.getUint32(cur + 20, true);\n    const uncompressedSize = dv.getUint32(cur + 24, true);\n    const nameLen = dv.getUint16(cur + 28, true);\n    const extraLen = dv.getUint16(cur + 30, true);\n    const commentLen = dv.getUint16(cur + 32, true);\n    const lfhOffset = dv.getUint32(cur + 42, true);\n\n    if (compressedSize === 0xffffffff || uncompressedSize === 0xffffffff) {\n      throw new Error(\"unzip: ZIP64 entries are not supported\");\n    }\n    if (lfhOffset === 0xffffffff) {\n      throw new Error(\"unzip: ZIP64 entries are not supported\");\n    }\n\n    const nameBytes = buf.subarray(cur + 46, cur + 46 + nameLen);\n    let name: string;\n    try {\n      name = decoder.decode(nameBytes);\n    } catch {\n      throw new Error(\"unzip: filename is not valid UTF-8\");\n    }\n\n    if (name.length === 0) {\n      throw new Error(\"unzip: empty filename in central directory\");\n    }\n    if (name.includes(\"\\\\\")) {\n      throw new Error(`unzip: backslash in filename: ${JSON.stringify(name)}`);\n    }\n    if (name.startsWith(\"/\")) {\n      throw new Error(`unzip: absolute path filename: ${JSON.stringify(name)}`);\n    }\n    for (const segment of name.split(\"/\")) {\n      if (segment === \"..\") {\n        throw new Error(\n          `unzip: parent-directory traversal in filename: ${JSON.stringify(name)}`,\n        );\n      }\n    }\n\n    cur += 46 + nameLen + extraLen + commentLen;\n\n    // Skip directory entries (trailing /).\n    if (name.endsWith(\"/\")) continue;\n\n    if (method !== METHOD_STORED) {\n      throw new Error(\n        `unzip: unsupported compression method ${method} for ${JSON.stringify(name)} ` +\n          `(only STORED is supported; .dpiv-bundle uses STORED per ARCHITECTURE.md §8 D.4)`,\n      );\n    }\n\n    if (dv.getUint32(lfhOffset, true) !== ZIP_LFH_SIG) {\n      throw new Error(\"unzip: bad local file header\");\n    }\n    const lfhNameLen = dv.getUint16(lfhOffset + 26, true);\n    const lfhExtraLen = dv.getUint16(lfhOffset + 28, true);\n    const dataStart = lfhOffset + 30 + lfhNameLen + lfhExtraLen;\n    const dataEnd = dataStart + compressedSize;\n    if (dataEnd > buf.byteLength) {\n      throw new Error(`unzip: entry \"${name}\" extends past end of archive`);\n    }\n\n    files[name] = buf.subarray(dataStart, dataEnd);\n  }\n\n  return { files };\n}\n","/**\n * Partial in-process bundle verifier — 5 of 6 checks per\n * ARCHITECTURE.md §8 D.5.\n *\n *                  ⚠ DELIBERATE PARTIAL VERIFIER ⚠\n *\n * This SDK performs FIVE of the six checks defined in\n * ARCHITECTURE.md §8 D.5. Step 3 — RFC 3161 timestamp token\n * verification against the DigiCert and Sectigo TSA CA chains — is\n * **deliberately skipped**. Pulling a full ASN.1 + RFC 3161 verifier\n * into a zero-dependency SDK would add ~200 KB of transitive deps;\n * any caller that needs the canonical TSA check should run the\n * bundle's own `verify.sh` script (which uses `openssl ts -verify`\n * and is the canonical TSA verifier by design).\n *\n * Step 3 status is reported as the literal string `\"skipped\"`\n * rather than a boolean — callers MUST handle that case explicitly.\n * We do not silently treat unverified TSA tokens as valid.\n *\n * # Checks performed\n *\n *   1. envelope_hash:          SHA-256(JCS(envelope.json)) ==\n *                              envelope.hash content\n *   2. issuer_signature:       ECDSA P-256 / SHA-256 verify of\n *                              signature.bin against the canonical\n *                              envelope bytes using issuer.pem\n *   3. tsa_tokens:             SKIPPED — see above\n *   4. merkle_inclusion:       audit_path walk closes to\n *                              sth.json.root via RFC 6962 leaf/node\n *                              prefixes\n *   5. master_sth_signature:   ECDSA P-256 / SHA-256 verify of\n *                              base64-decoded master_sig against the\n *                              JCS-canonical STH preimage using\n *                              master.pem\n *   6. onchain_anchor:         presence + structural validity of\n *                              onchain.json (or \"absent\" when the\n *                              file isn't in the bundle).\n *                              INFORMATIONAL ONLY — we do NOT call\n *                              an RPC. Live tx existence is a\n *                              verify.sh / SDK-RPC concern.\n *\n * # Cross-check requirements (defense in depth)\n *\n *   - merkle.json.segment must equal sth.json.segment\n *   - merkle.json.leaf_index must be < sth.json.tree_size\n *   - audit_path verification uses sth.json.root as the expected\n *     root\n *   - When onchain.json is present, its (segment, tree_size, root)\n *     must equal sth.json's\n *\n * # Privacy\n *\n * verifyBundle MUST NOT log salt values. Any salt in\n * `labels.json::RevealedLabel` is recomputed against `commit` and\n * cross-checked, then discarded. Callers building UIs that surface\n * the salt do so explicitly via `parseLabels` — never via the\n * verifier.\n */\n\nimport { createPublicKey, createVerify } from \"node:crypto\";\n\nimport { jcs } from \"../crypto/jcs.js\";\nimport { sha256Hex } from \"../crypto/hash.js\";\nimport { leafHash, verifyInclusion, unhex } from \"../crypto/merkle.js\";\nimport { BUNDLE_FILES } from \"../types/bundle.js\";\nimport type { MerkleProofJson, OnchainProofJson } from \"../types/bundle.js\";\nimport type { STH } from \"../types/sth.js\";\nimport { unzipBundle } from \"./unzip.js\";\n\nexport { unzipBundle } from \"./unzip.js\";\n\n/**\n * Per-check result.\n *\n * - Boolean for the four cryptographic checks plus the structural\n *   on-chain check.\n * - Literal `\"skipped\"` for the deliberately-unimplemented TSA step.\n * - Literal `\"absent\"` for the optional `onchain.json` when missing.\n */\nexport interface VerifyChecks {\n  envelope_hash: boolean;\n  issuer_signature: boolean;\n  tsa_tokens: \"skipped\";\n  merkle_inclusion: boolean;\n  master_sth_signature: boolean;\n  onchain_anchor: boolean | \"absent\";\n}\n\nexport interface VerifyResult {\n  /**\n   * `true` iff every PERFORMED check passed. The deliberately-\n   * skipped TSA step is not counted toward `ok`. Callers requiring\n   * full six-of-six verification must run `verify.sh` separately.\n   */\n  ok: boolean;\n  checks: VerifyChecks;\n  /**\n   * The list of explicitly skipped checks. Always contains\n   * `\"tsa_tokens\"` so consumers can present a \"5 of 6 verified\"\n   * disclaimer without re-deriving it.\n   */\n  skipped: ReadonlyArray<keyof VerifyChecks>;\n  /**\n   * Short human-readable explanation when `ok === false`. Names the\n   * first failing check (in declaration order). Absent on success.\n   */\n  reason?: string;\n  /**\n   * On-chain reference, when `onchain.json` was present in the\n   * bundle and structurally valid. Informational only — no RPC was\n   * called. Surfaces so consumers can render the explorer link\n   * without re-parsing the bundle.\n   */\n  onchainReference?: {\n    chain: OnchainProofJson[\"chain\"];\n    contract: string;\n    tx: string;\n    block: number;\n    segment: number;\n    treeSize: number;\n    root: string;\n  };\n}\n\n/** Map of bundle-relative path → file bytes. */\nexport type BundleFiles = Record<string, Uint8Array>;\n\n/**\n * Verify a `.dpiv-bundle` (sans TSA).\n *\n * Accepts either:\n *   - the raw `.dpiv-bundle` zip as `ArrayBuffer | Uint8Array`\n *     (most common — what `client.downloadBundle()` returns),\n *   - or a pre-unzipped `BundleFiles` map (useful for tests and for\n *     callers that already have the bundle in memory).\n *\n * Promise-returning for symmetry with the Python SDK, but the\n * implementation is fully synchronous; awaiting it adds a single\n * microtask.\n */\nexport async function verifyBundle(\n  bundle: ArrayBuffer | Uint8Array | BundleFiles,\n): Promise<VerifyResult> {\n  const files: BundleFiles =\n    bundle instanceof ArrayBuffer\n      ? unzipBundle(bundle).files\n      : bundle instanceof Uint8Array\n        ? unzipBundle(bundle).files\n        : bundle;\n\n  const checks: VerifyChecks = {\n    envelope_hash: false,\n    issuer_signature: false,\n    tsa_tokens: \"skipped\",\n    merkle_inclusion: false,\n    master_sth_signature: false,\n    onchain_anchor: \"absent\",\n  };\n  const skipped: ReadonlyArray<keyof VerifyChecks> = [\"tsa_tokens\"];\n\n  const envelopeBytes = required(files, BUNDLE_FILES.ENVELOPE);\n  const envelopeHashBytes = required(files, BUNDLE_FILES.ENVELOPE_HASH);\n  const signatureBytes = required(files, BUNDLE_FILES.SIGNATURE);\n  const issuerPemBytes = required(files, BUNDLE_FILES.ISSUER_PEM);\n  const merkleBytes = required(files, BUNDLE_FILES.MERKLE);\n  const sthBytes = required(files, BUNDLE_FILES.STH);\n  const masterPemBytes = required(files, BUNDLE_FILES.MASTER_PEM);\n\n  // Check 1 — envelope_hash.\n  const envelope = parseJson<Record<string, unknown>>(\n    envelopeBytes,\n    BUNDLE_FILES.ENVELOPE,\n  );\n  const computedHashHex = sha256Hex(jcs(envelope));\n  const claimedHashHex = bytesToString(envelopeHashBytes).trim().toLowerCase();\n  if (computedHashHex !== claimedHashHex) {\n    return fail(checks, skipped, \"envelope_hash\", \"envelope hash mismatch\");\n  }\n  checks.envelope_hash = true;\n\n  // Check 2 — issuer_signature.\n  // KMS signs the 32-byte digest in DIGEST mode. node:crypto's\n  // createVerify takes the message bytes and does the SHA-256\n  // itself, so we feed the JCS-canonical envelope bytes.\n  let issuerKey: ReturnType<typeof createPublicKey>;\n  try {\n    issuerKey = createPublicKey({\n      key: Buffer.from(issuerPemBytes),\n      format: \"pem\",\n      type: \"spki\",\n    });\n  } catch (err) {\n    return fail(\n      checks,\n      skipped,\n      \"issuer_signature\",\n      `issuer.pem could not be parsed: ${describe(err)}`,\n    );\n  }\n  const v1 = createVerify(\"SHA256\");\n  v1.update(jcs(envelope));\n  v1.end();\n  const issuerOk = v1.verify(issuerKey, Buffer.from(signatureBytes));\n  if (!issuerOk) {\n    return fail(\n      checks,\n      skipped,\n      \"issuer_signature\",\n      \"issuer signature invalid\",\n    );\n  }\n  checks.issuer_signature = true;\n\n  // Check 3 — TSA: deliberately skipped.\n\n  // Check 4 — merkle_inclusion.\n  const merkle = parseJson<MerkleProofJson>(merkleBytes, BUNDLE_FILES.MERKLE);\n  const sth = parseJson<STH & Record<string, unknown>>(\n    sthBytes,\n    BUNDLE_FILES.STH,\n  );\n  if (merkle.segment !== sth.segment) {\n    return fail(\n      checks,\n      skipped,\n      \"merkle_inclusion\",\n      `segment mismatch: merkle=${merkle.segment} sth=${sth.segment}`,\n    );\n  }\n  if (merkle.leaf_index >= sth.tree_size) {\n    return fail(\n      checks,\n      skipped,\n      \"merkle_inclusion\",\n      `leaf_index ${merkle.leaf_index} >= tree_size ${sth.tree_size}`,\n    );\n  }\n  const computedLeafHash = leafHash(Buffer.from(jcs(envelope)));\n  if (computedLeafHash.toString(\"hex\") !== merkle.leaf_hash.toLowerCase()) {\n    return fail(\n      checks,\n      skipped,\n      \"merkle_inclusion\",\n      \"merkle.leaf_hash does not match SHA-256(0x00 || envelope_canonical_bytes)\",\n    );\n  }\n  const auditPath = merkle.audit_path.map((h) => unhex(h));\n  const expectedRoot = unhex(sth.root);\n  const inclusionOk = verifyInclusion(\n    computedLeafHash,\n    merkle.leaf_index,\n    sth.tree_size,\n    auditPath,\n    expectedRoot,\n  );\n  if (!inclusionOk) {\n    return fail(\n      checks,\n      skipped,\n      \"merkle_inclusion\",\n      \"audit_path does not close to sth.root\",\n    );\n  }\n  checks.merkle_inclusion = true;\n\n  // Check 5 — master_sth_signature.\n  const sthForHash: Record<string, unknown> = { ...sth };\n  delete sthForHash.master_sig;\n  delete (sthForHash as Record<string, unknown>).sig;\n  const sthPreimageBytes = Buffer.from(jcs(sthForHash));\n  const masterSigB64 = (sth as { master_sig?: string }).master_sig;\n  if (!masterSigB64) {\n    return fail(\n      checks,\n      skipped,\n      \"master_sth_signature\",\n      \"sth.json missing master_sig\",\n    );\n  }\n  let masterKey: ReturnType<typeof createPublicKey>;\n  try {\n    masterKey = createPublicKey({\n      key: Buffer.from(masterPemBytes),\n      format: \"pem\",\n      type: \"spki\",\n    });\n  } catch (err) {\n    return fail(\n      checks,\n      skipped,\n      \"master_sth_signature\",\n      `master.pem could not be parsed: ${describe(err)}`,\n    );\n  }\n  const v5 = createVerify(\"SHA256\");\n  v5.update(sthPreimageBytes);\n  v5.end();\n  const masterOk = v5.verify(masterKey, Buffer.from(masterSigB64, \"base64\"));\n  if (!masterOk) {\n    return fail(\n      checks,\n      skipped,\n      \"master_sth_signature\",\n      \"chain-master signature on sth.json invalid\",\n    );\n  }\n  checks.master_sth_signature = true;\n\n  // Check 6 — onchain_anchor (informational).\n  const onchainBytes = files[BUNDLE_FILES.ONCHAIN];\n  let onchainReference: VerifyResult[\"onchainReference\"];\n  if (onchainBytes) {\n    const onchain = parseJson<OnchainProofJson>(\n      onchainBytes,\n      BUNDLE_FILES.ONCHAIN,\n    );\n    if (\n      onchain.segment !== sth.segment ||\n      onchain.tree_size !== sth.tree_size ||\n      onchain.root.toLowerCase() !== sth.root.toLowerCase()\n    ) {\n      return fail(\n        checks,\n        skipped,\n        \"onchain_anchor\",\n        \"onchain.json (segment, tree_size, root) does not match sth.json\",\n      );\n    }\n    checks.onchain_anchor = true;\n    onchainReference = {\n      chain: onchain.chain,\n      contract: onchain.contract,\n      tx: onchain.tx,\n      block: onchain.block,\n      segment: onchain.segment,\n      treeSize: onchain.tree_size,\n      root: onchain.root,\n    };\n  } else {\n    checks.onchain_anchor = \"absent\";\n  }\n\n  const result: VerifyResult = { ok: true, checks, skipped };\n  if (onchainReference) result.onchainReference = onchainReference;\n  return result;\n}\n\n/* -------------------------------------------------------------- *\n *  helpers\n * -------------------------------------------------------------- */\n\nfunction required(files: BundleFiles, path: string): Uint8Array {\n  const v = files[path];\n  if (!v) {\n    throw new Error(`bundle missing required file: ${path}`);\n  }\n  return v;\n}\n\nfunction bytesToString(b: Uint8Array): string {\n  return Buffer.from(b).toString(\"utf-8\");\n}\n\nfunction parseJson<T>(b: Uint8Array, label: string): T {\n  try {\n    return JSON.parse(bytesToString(b)) as T;\n  } catch (err) {\n    throw new Error(`${label}: invalid JSON: ${describe(err)}`);\n  }\n}\n\nfunction describe(err: unknown): string {\n  return err instanceof Error ? err.message : String(err);\n}\n\nfunction fail(\n  checks: VerifyChecks,\n  skipped: ReadonlyArray<keyof VerifyChecks>,\n  failedAt: keyof VerifyChecks,\n  reason: string,\n): VerifyResult {\n  return {\n    ok: false,\n    checks,\n    skipped,\n    reason: `${failedAt}: ${reason}`,\n  };\n}\n"]}