{"version":3,"file":"HPKEService.mjs","names":["HPKEService"],"sources":["../../src/services/HPKEService.ts"],"sourcesContent":["/**\n * HPKE Service for Vaults\n *\n * Implements RFC 9180 HPKE for sealing ML-KEM public keys during key exchange.\n *\n * Uses:\n * - KEM: DHKEM(P-256, HKDF-SHA256)\n * - KDF: HKDF-SHA256\n * - AEAD: AES-256-GCM\n */\n\nimport { injectable } from '@credo-ts/core'\nimport { CipherSuite, Aes256Gcm, HkdfSha256, DhkemP256HkdfSha256 } from '@hpke/core'\nimport { sha256 } from '@noble/hashes/sha256'\n\n/**\n * HPKE encryption result\n */\nexport interface HPKEEncryptResult {\n  /** Encrypted payload */\n  ciphertext: Uint8Array\n  /** Ephemeral public key */\n  ephemeralPublicKey: Uint8Array\n}\n\n/**\n * HPKE decryption result\n */\nexport interface HPKEDecryptResult {\n  /** Decrypted payload */\n  plaintext: Uint8Array\n}\n\n@injectable()\nexport class HPKEService {\n  /**\n   * Get CipherSuite for HPKE operations\n   */\n  private getCipherSuite(): CipherSuite {\n    return new CipherSuite({\n      kem: new DhkemP256HkdfSha256(),\n      kdf: new HkdfSha256(),\n      aead: new Aes256Gcm(),\n    })\n  }\n\n  /**\n   * Encrypt payload with HPKE\n   *\n   * @param recipientPublicKey - Recipient's P-256 public key (raw bytes)\n   * @param plaintext - Payload to encrypt\n   * @param aad - Additional authenticated data (optional)\n   * @returns Encryption result with ciphertext and ephemeral key\n   */\n  public async encrypt(\n    recipientPublicKey: Uint8Array,\n    plaintext: Uint8Array,\n    aad?: Uint8Array\n  ): Promise<HPKEEncryptResult> {\n    const suite = this.getCipherSuite()\n\n    // Import recipient public key\n    const pkR = await suite.kem.importKey('raw', recipientPublicKey, true)\n\n    // Encrypt using HPKE Base mode\n    const sender = await suite.createSenderContext({\n      recipientPublicKey: pkR,\n    })\n\n    const ciphertext = new Uint8Array(await sender.seal(plaintext, aad))\n\n    return {\n      ciphertext,\n      ephemeralPublicKey: new Uint8Array(sender.enc),\n    }\n  }\n\n  /**\n   * Decrypt payload with HPKE\n   *\n   * @param recipientPrivateKey - Recipient's P-256 private key (raw bytes)\n   * @param ciphertext - Encrypted payload\n   * @param ephemeralPublicKey - Ephemeral public key from encryption\n   * @param aad - Additional authenticated data (must match encryption)\n   * @returns Decryption result with plaintext\n   */\n  public async decrypt(\n    recipientPrivateKey: Uint8Array,\n    ciphertext: Uint8Array,\n    ephemeralPublicKey: Uint8Array,\n    aad?: Uint8Array\n  ): Promise<HPKEDecryptResult> {\n    const suite = this.getCipherSuite()\n\n    // Import recipient private key\n    const skR = await suite.kem.importKey('raw', recipientPrivateKey, false)\n\n    // Decrypt using HPKE Base mode\n    const recipient = await suite.createRecipientContext({\n      recipientKey: skR,\n      enc: ephemeralPublicKey,\n    })\n\n    const plaintext = new Uint8Array(await recipient.open(ciphertext, aad))\n\n    return { plaintext }\n  }\n\n  /**\n   * Generate key pair for HPKE (P-256)\n   *\n   * @returns Object with public and private keys\n   */\n  public async generateKeyPair(): Promise<{\n    publicKey: Uint8Array\n    privateKey: Uint8Array\n  }> {\n    const suite = this.getCipherSuite()\n    const keyPair = await suite.kem.generateKeyPair()\n\n    const publicKeyRaw = await suite.kem.serializePublicKey(keyPair.publicKey)\n    const privateKeyRaw = await suite.kem.serializePrivateKey(keyPair.privateKey)\n\n    return {\n      publicKey: new Uint8Array(publicKeyRaw),\n      privateKey: new Uint8Array(privateKeyRaw),\n    }\n  }\n\n  /**\n   * Compute digest for AAD binding\n   *\n   * @param data - Data to hash\n   * @returns SHA-256 hash\n   */\n  public computeDigest(data: Uint8Array): Uint8Array {\n    return sha256(data)\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkCO,wBAAMA,cAAY;;;;CAIvB,AAAQ,iBAA8B;AACpC,SAAO,IAAI,YAAY;GACrB,KAAK,IAAI,qBAAqB;GAC9B,KAAK,IAAI,YAAY;GACrB,MAAM,IAAI,WAAW;GACtB,CAAC;;;;;;;;;;CAWJ,MAAa,QACX,oBACA,WACA,KAC4B;EAC5B,MAAM,QAAQ,KAAK,gBAAgB;EAGnC,MAAM,MAAM,MAAM,MAAM,IAAI,UAAU,OAAO,oBAAoB,KAAK;EAGtE,MAAM,SAAS,MAAM,MAAM,oBAAoB,EAC7C,oBAAoB,KACrB,CAAC;AAIF,SAAO;GACL,YAHiB,IAAI,WAAW,MAAM,OAAO,KAAK,WAAW,IAAI,CAAC;GAIlE,oBAAoB,IAAI,WAAW,OAAO,IAAI;GAC/C;;;;;;;;;;;CAYH,MAAa,QACX,qBACA,YACA,oBACA,KAC4B;EAC5B,MAAM,QAAQ,KAAK,gBAAgB;EAGnC,MAAM,MAAM,MAAM,MAAM,IAAI,UAAU,OAAO,qBAAqB,MAAM;EAGxE,MAAM,YAAY,MAAM,MAAM,uBAAuB;GACnD,cAAc;GACd,KAAK;GACN,CAAC;AAIF,SAAO,EAAE,WAFS,IAAI,WAAW,MAAM,UAAU,KAAK,YAAY,IAAI,CAAC,EAEnD;;;;;;;CAQtB,MAAa,kBAGV;EACD,MAAM,QAAQ,KAAK,gBAAgB;EACnC,MAAM,UAAU,MAAM,MAAM,IAAI,iBAAiB;EAEjD,MAAM,eAAe,MAAM,MAAM,IAAI,mBAAmB,QAAQ,UAAU;EAC1E,MAAM,gBAAgB,MAAM,MAAM,IAAI,oBAAoB,QAAQ,WAAW;AAE7E,SAAO;GACL,WAAW,IAAI,WAAW,aAAa;GACvC,YAAY,IAAI,WAAW,cAAc;GAC1C;;;;;;;;CASH,AAAO,cAAc,MAA8B;AACjD,SAAO,OAAO,KAAK;;;0BAvGtB,YAAY"}