import{ok,err}from"./_deps/shared/index.js";import{createMlKem768}from"mlkem";const X25519_RAW_KEY_BYTES=32,AES_KEY_BITS=256;function toArrayBuffer(e){const r=new ArrayBuffer(e.byteLength);return new Uint8Array(r).set(e),r}export async function generateEphemeralKeyPair(){try{const e=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"]),r=new Uint8Array(await crypto.subtle.exportKey("raw",e.publicKey));return ok({privateKey:e.privateKey,publicKey:e.publicKey,rawPublicKey:r})}catch{return err("KEYGEN_FAILED")}}export async function importX25519PublicKey(e){if(32!==e.length)return err("INVALID_KEY_LENGTH:EXPECTED_32");try{const r=await crypto.subtle.importKey("raw",toArrayBuffer(e),{name:"X25519"},!0,[]);return ok(r)}catch{return err("IMPORT_FAILED")}}export async function deriveSharedKeyECDH(e,r){try{const t=await crypto.subtle.deriveBits({name:"X25519",public:r},e,256),a=await crypto.subtle.importKey("raw",t,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]);return ok(a)}catch{return err("DERIVE_FAILED")}}export async function senderKeyAgreement(e){const r=await generateEphemeralKeyPair();if(!r.ok)return r;const t=await deriveSharedKeyECDH(r.value.privateKey,e);return t.ok?ok({sharedKey:t.value,ephemeralPublicKey:r.value.rawPublicKey}):t}export async function receiverKeyAgreement(e,r){const t=await importX25519PublicKey(r);return t.ok?deriveSharedKeyECDH(e,t.value):t}const HYBRID_HKDF_INFO="xail-hybrid-kem-v2";export async function combineSharedSecrets(e,r,t,a,n,c){try{const i=e.length+r.length+t.length+a.length+n.length+c.length,o=new Uint8Array(i);let y=0;o.set(e,y),y+=e.length,o.set(r,y),y+=r.length,o.set(t,y),y+=t.length,o.set(a,y),y+=a.length,o.set(n,y),y+=n.length,o.set(c,y);const u=(new TextEncoder).encode("XWingKEM"),l=await crypto.subtle.importKey("raw",toArrayBuffer(o),"HKDF",!1,["deriveBits"]),s=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:u,info:(new TextEncoder).encode(HYBRID_HKDF_INFO)},l,256),p=await crypto.subtle.importKey("raw",s,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]);return ok(p)}catch{return err("HKDF_FAILED")}}export async function senderHybridKeyAgreement(e,r){const t=await generateEphemeralKeyPair();if(!t.ok)return t;let a,n,c,i;try{a=new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:e},t.value.privateKey,256))}catch{return err("DERIVE_FAILED")}try{const e=await createMlKem768(),[t,a]=e.encap(r);n=t,c=a}catch{return err("KEM_ENCAPSULATE_FAILED")}try{const r=await crypto.subtle.exportKey("raw",e);i=new Uint8Array(r)}catch{return err("EXPORT_KEY_FAILED")}const o=await combineSharedSecrets(c,n,a,t.value.rawPublicKey,i,r);return o.ok?ok({sharedKey:o.value,ephemeralPublicKey:t.value.rawPublicKey,kemCiphertext:n}):o}export async function receiverHybridKeyAgreement(e,r,t,a,n,c){const i=await importX25519PublicKey(t);if(!i.ok)return i;let o,y;try{o=new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:i.value},e,256))}catch{return err("DERIVE_FAILED")}try{y=(await createMlKem768()).decap(a,n)}catch{return err("KEM_DECAPSULATE_FAILED")}return combineSharedSecrets(y,a,o,t,r,c)}