{"version":3,"sources":["../../src/protocol/identity.ts"],"sourcesContent":["/**\n * Enclave identity and consent primitives for Personal Servers.\n *\n * Owner/Web -> Gateway -> Agent(CVM): derive wallet and quote\n * Web verifies evidence; Account authenticates and encrypts the EIP-191 master\n * signature to the enclave key; Gateway relays it blind; Agent decrypts/seals.\n *\n * @category Protocol\n */\n\nimport * as secp256k1 from \"@noble/secp256k1\";\nimport {\n  concat,\n  encodePacked,\n  fromHex,\n  getAddress,\n  isAddressEqual,\n  keccak256,\n  recoverPublicKey,\n  toBytes,\n  toHex,\n  type Address,\n  type Hex,\n} from \"viem\";\nimport { publicKeyToAddress } from \"viem/accounts\";\nimport { serializeECIES, type ECIESProvider } from \"../crypto/ecies/interface\";\nimport { deriveMasterKey, recoverServerOwner } from \"../crypto/keys/derive\";\nimport type { ServerRegistrationMessage } from \"./eip712\";\n\nexport const ENCLAVE_IDENTITY_EVIDENCE_VERSION = 1;\nexport const USER_PS_ID_DOMAIN = \"vana.ps-enclave.v1\";\nexport const ENCLAVE_WALLET_PURPOSE = \"vana.ps-enclave.wallet.v1\";\nexport const MASTER_SIGNATURE_DELIVERY_VERSION = \"vana.ps-enclave.delivery.v1\";\n/** Agent rejects deliveries when `|now - issuedAt|` exceeds this value. */\nexport const MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS = 600;\nexport const SEALED_ENVELOPE_VERSION = 1;\n\nconst VANA_MAINNET_CHAIN_ID = 1480;\nconst MOKSHA_CHAIN_ID = 14800;\nconst KMS_ISSUED_PREFIX = \"dstack-kms-issued\";\nconst PREIMAGE_SEPARATOR = \":\";\nconst UNCOMPRESSED_PUBLIC_KEY_BYTES = 65;\nconst UNCOMPRESSED_PUBLIC_KEY_PREFIX = \"04\";\nconst EMPTY_HEX = \"0x\";\n\n/** `keccak256(encodePacked([string,uint256,address], [USER_PS_ID_DOMAIN,chainId,owner]))`. */\nexport type UserPsId = Hex;\n\n/** Attested identity evidence returned by the enclave agent. */\nexport interface EnclaveIdentityEvidence {\n  v: typeof ENCLAVE_IDENTITY_EVIDENCE_VERSION;\n  userPsId: UserPsId;\n  chainId: number;\n  ownerAddress: Address;\n  /** Path suffix `users/{id}/wallet/ethereum/secp256k1/v{epoch}`. */\n  epoch: number;\n  address: Address;\n  /** 65-byte uncompressed `0x04..`; `publicKeyToAddress(publicKey) == address`. */\n  publicKey: Hex;\n  /** 20-byte dstack `app_id`. */\n  appId: Hex;\n  /** 32-byte compose hash. */\n  composeHash: Hex;\n  /** Omitted when the OS does not expose its image hash. */\n  osImageHash?: Hex;\n  /** Must equal `ENCLAVE_WALLET_PURPOSE`. */\n  purpose: string;\n  /** `[appRoot over link 0, kmsRoot over link 1]`; see `appRootPreimage` and `kmsIssuedPreimage`. */\n  signatureChain: [Hex, Hex];\n  /** Raw TDX quote with report_data `keccak256(userPsId || address)`; not parsed. */\n  quote: Hex;\n  eventLog?: string;\n  /** `keccak256` of the uncompressed KMS root public key. */\n  kmsRootFingerprint: Hex;\n}\n\n/** Identity values the caller expects the evidence to bind. */\nexport interface ExpectedIdentity {\n  ownerAddress: Address;\n  chainId: number;\n  epoch: number;\n}\n\n/** Request for an owner-scoped enclave identity. */\nexport interface IdentityRequest {\n  ownerAddress: Address;\n  chainId: number;\n}\n\n/** Lifecycle state of an enclave identity. */\nexport type IdentityState = \"prepared\" | \"registered\" | \"sealed\" | \"retired\";\n\n/** Gateway response containing enclave identity state and registration data. */\nexport interface IdentityResponse {\n  identity: EnclaveIdentityEvidence;\n  state: IdentityState;\n  created: boolean;\n  /** Exact `ServerRegistration.serverUrl` the owner signs. */\n  serverUrl: string;\n  serverId?: Hex;\n  serverStatus?:\n    | \"pending\"\n    | \"submitting\"\n    | \"confirmed\"\n    | \"finalized\"\n    | \"failed\";\n  sealed: boolean;\n}\n\n/** Versioned server-registration request for an enclave identity. */\nexport type IdentityRegistrationRequest =\n  | { version: \"v2\"; message: ServerRegistrationMessage }\n  | {\n      version: \"v3\";\n      message: ServerRegistrationMessage & { nonce: string; deadline: string };\n    };\n\n/** Accepted identity-registration response. */\nexport interface IdentityRegistrationResponse {\n  serverId: Hex;\n  state: \"registered\";\n  serverStatus: \"pending\";\n}\n\n/** Inner plaintext of the ECIES box. */\nexport interface MasterSignatureDelivery {\n  v: typeof MASTER_SIGNATURE_DELIVERY_VERSION;\n  userPsId: UserPsId;\n  epoch: number;\n  enclaveAddress: Address;\n  ownerAddress: Address;\n  /** 65-byte EIP-191 signature over `MASTER_KEY_MESSAGE`. */\n  masterSignature: Hex;\n  /** Unix seconds; see `MASTER_SIGNATURE_DELIVERY_MAX_AGE_SECONDS`. */\n  issuedAt: number;\n}\n\n/** Enclave-bound ciphertext submitted for sealing. */\nexport interface SealedSecretSubmission {\n  userPsId: UserPsId;\n  epoch: number;\n  enclaveAddress: Address;\n  /** `iv(16) || ephemPub(65) || ct || mac(32)` to `evidence.publicKey`. */\n  ciphertext: Hex;\n}\n\n/** Confirmation that the enclave sealed a submitted secret. */\nexport interface SealedSecretResponse {\n  sealed: true;\n  /** `sha256(ciphertext)`. */\n  secretHash: Hex;\n  sealedAt: string;\n}\n\n/** AES-GCM fields encoded as base64 strings. */\nexport interface AesGcmBox {\n  /** Base64 initialization vector. */\n  iv: string;\n  /** Base64 ciphertext. */\n  ciphertext: string;\n  /** Base64 authentication tag. */\n  tag: string;\n}\n\n/** Persisted enclave envelope; the Gateway treats it as opaque text. */\nexport interface SealedEnvelope extends AesGcmBox {\n  v: typeof SEALED_ENVELOPE_VERSION;\n  wrappedContentKey: AesGcmBox;\n}\n\n/** Fleet-pinned KMS root and allowed dstack application IDs. */\nexport interface EnclaveTrustAnchors {\n  kmsRootPubkey: Hex;\n  appIds: readonly Hex[];\n}\n\n/**\n * Mainnet fleet anchors, harvested from the prod9 fleet on 2026-09-15.\n *\n * `kmsRootPubkey` is byte-identical to Moksha's: both fleets run under the same\n * Phala KMS, so the key-provider root does NOT separate them. `appIds` is what\n * does — it lists the mainnet worker app only, and must never contain a Moksha\n * app id. The controller is absent by design: it derives no owner keys.\n */\nconst MAINNET_ANCHOR: Readonly<EnclaveTrustAnchors> = Object.freeze({\n  kmsRootPubkey:\n    \"0x0434c76e0c3f52ec64cbf9bbf5c910c272330166fd656c0a86bb330963e46910e1a0e6fa51bec74be2f9129342707636060d85856d102cee8290185409ecf7422f\",\n  appIds: Object.freeze([\n    \"0x01bb1b6dcaf1ea170f1480c5e53b093f384d939a\",\n  ] as Hex[]),\n});\n\n/** Fleet-provisioned trust anchors keyed by Vana chain ID. */\nexport const ENCLAVE_TRUST_ANCHORS: Readonly<\n  Record<number, Readonly<EnclaveTrustAnchors>>\n> = Object.freeze({\n  [VANA_MAINNET_CHAIN_ID]: MAINNET_ANCHOR,\n  // Moksha workers share this dstack app and KMS root; the controller does not derive owner keys.\n  [MOKSHA_CHAIN_ID]: Object.freeze({\n    kmsRootPubkey:\n      \"0x0434c76e0c3f52ec64cbf9bbf5c910c272330166fd656c0a86bb330963e46910e1a0e6fa51bec74be2f9129342707636060d85856d102cee8290185409ecf7422f\",\n    appIds: Object.freeze([\n      \"0xec9a39de98c760e1ded9f1e97016dc5f0e357cf2\" as Hex,\n    ]),\n  }),\n});\n\n/**\n * Derives the deterministic Personal Server ID used by enclave paths.\n *\n * @param chainId - Vana chain ID.\n * @param ownerAddress - Checksummed owner address.\n * @returns The path-compatible keccak256 digest.\n */\nexport function userPsId(chainId: number, ownerAddress: Address): UserPsId {\n  const packed = encodePacked(\n    [\"string\", \"uint256\", \"address\"],\n    [USER_PS_ID_DOMAIN, BigInt(chainId), getAddress(ownerAddress)],\n  );\n\n  return keccak256(packed);\n}\n\nfunction compressPublicKey(publicKey: Hex): Uint8Array {\n  return secp256k1.ProjectivePoint.fromHex(\n    fromHex(publicKey, \"bytes\"),\n  ).toRawBytes(true);\n}\n\nfunction sameKey(a: Hex, b: Hex): boolean {\n  return toHex(compressPublicKey(a)) === toHex(compressPublicKey(b));\n}\n\nfunction assertUncompressedKey(publicKey: Hex): void {\n  const hex = publicKey.slice(2);\n  if (\n    hex.length !== UNCOMPRESSED_PUBLIC_KEY_BYTES * 2 ||\n    !hex.startsWith(UNCOMPRESSED_PUBLIC_KEY_PREFIX) ||\n    !/^[0-9a-fA-F]+$/.test(hex)\n  ) {\n    throw new Error(\"Public key must be a 65-byte uncompressed secp256k1 key\");\n  }\n}\n\n/**\n * Builds keccak256(utf8(purpose || \":\" || lowercase hex(compressed pubkey))).\n *\n * Matches `dstack/guest-agent/src/rpc_service.rs:612-628`.\n */\nexport function appRootPreimage(purpose: string, publicKey: Hex): Hex {\n  const keyHex = toHex(compressPublicKey(publicKey)).slice(2);\n  return keccak256(toBytes(`${purpose}${PREIMAGE_SEPARATOR}${keyHex}`));\n}\n\n/**\n * Hashes the KMS prefix, raw app ID bytes, and compressed app-root public key.\n *\n * Matches `dstack/kms/src/crypto.rs:23-40`; there is no separator between the\n * raw 20-byte app ID and the compressed key.\n */\nexport function kmsIssuedPreimage(appId: Hex, appRootPublicKey: Hex): Hex {\n  const prefix = concat([\n    toBytes(`${KMS_ISSUED_PREFIX}${PREIMAGE_SEPARATOR}`),\n    fromHex(appId, \"bytes\"),\n  ]);\n  const compressed = compressPublicKey(appRootPublicKey);\n\n  return keccak256(concat([prefix, compressed]));\n}\n\nasync function recoverChainKey(\n  hash: Hex,\n  signature: Hex,\n  link: number,\n): Promise<Hex> {\n  try {\n    return (await recoverPublicKey({ hash, signature })).toLowerCase() as Hex;\n  } catch {\n    throw new Error(`Invalid enclave signature chain link ${link}`);\n  }\n}\n\n/**\n * Verifies the enclave wallet binding against fleet-provisioned trust anchors.\n *\n * @param evidence - Identity evidence returned by the enclave agent.\n * @param anchors - Pinned KMS root and allowed dstack app IDs.\n * @param expected - Owner, chain, and epoch requested by the caller.\n *\n * @remarks\n * The dstack chain signs only `purpose || publicKey` and `appId || appRootPub`;\n * owner, chain and epoch are bound to the key by the TDX quote report_data\n * (`keccak256(userPsId || address)`), which v1 stores but does not verify\n * (DCAP is step 4). Until then the agent's derivation check is the backstop.\n * @throws When any identity binding or trust check fails.\n */\nexport async function verifyEnclaveIdentityEvidence(\n  evidence: EnclaveIdentityEvidence,\n  anchors: EnclaveTrustAnchors,\n  expected: ExpectedIdentity,\n): Promise<void> {\n  if (evidence.v !== ENCLAVE_IDENTITY_EVIDENCE_VERSION) {\n    throw new Error(\"Unsupported enclave identity evidence version\");\n  }\n\n  if (!Number.isInteger(evidence.epoch) || evidence.epoch < 1) {\n    throw new Error(\"Invalid enclave identity epoch\");\n  }\n\n  if (evidence.chainId !== expected.chainId) {\n    throw new Error(\n      \"Enclave identity chain ID does not match expected chain ID\",\n    );\n  }\n\n  if (!isAddressEqual(evidence.ownerAddress, expected.ownerAddress)) {\n    throw new Error(\"Enclave identity owner does not match expected owner\");\n  }\n\n  if (evidence.epoch !== expected.epoch) {\n    throw new Error(\"Enclave identity epoch does not match expected epoch\");\n  }\n\n  const expectedUserPsId = userPsId(expected.chainId, expected.ownerAddress);\n  if (evidence.userPsId.toLowerCase() !== expectedUserPsId.toLowerCase()) {\n    throw new Error(\"Enclave userPsId does not match expected identity\");\n  }\n\n  if (evidence.purpose !== ENCLAVE_WALLET_PURPOSE) {\n    throw new Error(\"Unexpected enclave wallet purpose\");\n  }\n\n  if (anchors.kmsRootPubkey === EMPTY_HEX) {\n    throw new Error(\"KMS root trust anchor is not provisioned\");\n  }\n\n  assertUncompressedKey(evidence.publicKey);\n  const derivedAddress = publicKeyToAddress(evidence.publicKey);\n\n  if (getAddress(derivedAddress) !== getAddress(evidence.address)) {\n    throw new Error(\"Enclave public key does not match its address\");\n  }\n\n  const appRootPublicKey = await recoverChainKey(\n    appRootPreimage(evidence.purpose, evidence.publicKey),\n    evidence.signatureChain[0],\n    0,\n  );\n  const kmsRootPublicKey = await recoverChainKey(\n    kmsIssuedPreimage(evidence.appId, appRootPublicKey),\n    evidence.signatureChain[1],\n    1,\n  );\n\n  let matchesAnchor: boolean;\n  try {\n    matchesAnchor = sameKey(kmsRootPublicKey, anchors.kmsRootPubkey);\n  } catch {\n    throw new Error(\"KMS root trust anchor is malformed\");\n  }\n\n  if (!matchesAnchor) {\n    throw new Error(\"KMS root public key does not match the trust anchor\");\n  }\n\n  if (\n    keccak256(kmsRootPublicKey) !== evidence.kmsRootFingerprint.toLowerCase()\n  ) {\n    throw new Error(\"KMS root fingerprint does not match the evidence\");\n  }\n\n  const appId = evidence.appId.toLowerCase();\n  if (\n    !anchors.appIds.some((allowedAppId) => allowedAppId.toLowerCase() === appId)\n  ) {\n    throw new Error(\"Enclave app ID is not trusted\");\n  }\n}\n\n/**\n * Builds the authenticated master-signature plaintext delivered to an enclave.\n *\n * @param evidence - Verified enclave identity evidence.\n * @param masterSignature - EIP-191 signature over the master-key message.\n * @param now - Issuance time in Unix seconds.\n * @returns The authenticated plaintext delivery object.\n * @throws When the signature is malformed or does not belong to the owner.\n */\nexport async function buildMasterSignatureDelivery(\n  evidence: EnclaveIdentityEvidence,\n  masterSignature: Hex,\n  now = Math.floor(Date.now() / 1000),\n): Promise<MasterSignatureDelivery> {\n  // Validate signature length and hex encoding before recovery.\n  deriveMasterKey(masterSignature);\n  const signerAddress = await recoverServerOwner(masterSignature);\n\n  if (!isAddressEqual(signerAddress, evidence.ownerAddress)) {\n    throw new Error(\"Master signature signer does not match evidence owner\");\n  }\n\n  return {\n    v: MASTER_SIGNATURE_DELIVERY_VERSION,\n    userPsId: evidence.userPsId,\n    epoch: evidence.epoch,\n    enclaveAddress: evidence.address,\n    ownerAddress: evidence.ownerAddress,\n    masterSignature,\n    issuedAt: now,\n  };\n}\n\n/**\n * Encrypts a master-signature delivery in the SDK's ECIES wire format.\n *\n * @param delivery - Plaintext delivery object.\n * @param publicKey - Enclave 65-byte uncompressed public key.\n * @param ecies - Platform-specific ECIES provider.\n * @returns The 0x-prefixed serialized ciphertext.\n * @throws When the public key is malformed or belongs to another enclave.\n */\nexport async function encryptMasterSignatureDelivery(\n  delivery: MasterSignatureDelivery,\n  publicKey: Hex,\n  ecies: ECIESProvider,\n): Promise<Hex> {\n  assertUncompressedKey(publicKey);\n\n  if (!isAddressEqual(publicKeyToAddress(publicKey), delivery.enclaveAddress)) {\n    throw new Error(\n      \"Public key does not belong to the delivery's enclave address\",\n    );\n  }\n\n  const plaintext = toBytes(JSON.stringify(delivery));\n  const encrypted = await ecies.encrypt(fromHex(publicKey, \"bytes\"), plaintext);\n\n  return `0x${serializeECIES(encrypted)}`;\n}\n"],"mappings":"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","names":[]}