"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.generateEphemeralKeyPair=generateEphemeralKeyPair,exports.importX25519PublicKey=importX25519PublicKey,exports.deriveSharedKeyECDH=deriveSharedKeyECDH,exports.senderKeyAgreement=senderKeyAgreement,exports.receiverKeyAgreement=receiverKeyAgreement,exports.combineSharedSecrets=combineSharedSecrets,exports.senderHybridKeyAgreement=senderHybridKeyAgreement,exports.receiverHybridKeyAgreement=receiverHybridKeyAgreement;const shared_1=require("../_deps/shared/index.js"),mlkem_1=require("mlkem"),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}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(0,shared_1.ok)({privateKey:e.privateKey,publicKey:e.publicKey,rawPublicKey:r})}catch{return(0,shared_1.err)("KEYGEN_FAILED")}}async function importX25519PublicKey(e){if(e.length!==X25519_RAW_KEY_BYTES)return(0,shared_1.err)("INVALID_KEY_LENGTH:EXPECTED_32");try{const r=await crypto.subtle.importKey("raw",toArrayBuffer(e),{name:"X25519"},!0,[]);return(0,shared_1.ok)(r)}catch{return(0,shared_1.err)("IMPORT_FAILED")}}async function deriveSharedKeyECDH(e,r){try{const t=await crypto.subtle.deriveBits({name:"X25519",public:r},e,AES_KEY_BITS),a=await crypto.subtle.importKey("raw",t,{name:"AES-GCM",length:AES_KEY_BITS},!1,["encrypt","decrypt"]);return(0,shared_1.ok)(a)}catch{return(0,shared_1.err)("DERIVE_FAILED")}}async function senderKeyAgreement(e){const r=await generateEphemeralKeyPair();if(!r.ok)return r;const t=await deriveSharedKeyECDH(r.value.privateKey,e);return t.ok?(0,shared_1.ok)({sharedKey:t.value,ephemeralPublicKey:r.value.rawPublicKey}):t}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";async function combineSharedSecrets(e,r,t,a,n,i){try{const c=e.length+r.length+t.length+a.length+n.length+i.length,y=new Uint8Array(c);let s=0;y.set(e,s),s+=e.length,y.set(r,s),s+=r.length,y.set(t,s),s+=t.length,y.set(a,s),s+=a.length,y.set(n,s),s+=n.length,y.set(i,s);const o=(new TextEncoder).encode("XWingKEM"),u=await crypto.subtle.importKey("raw",toArrayBuffer(y),"HKDF",!1,["deriveBits"]),l=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:o,info:(new TextEncoder).encode(HYBRID_HKDF_INFO)},u,AES_KEY_BITS),K=await crypto.subtle.importKey("raw",l,{name:"AES-GCM",length:AES_KEY_BITS},!1,["encrypt","decrypt"]);return(0,shared_1.ok)(K)}catch{return(0,shared_1.err)("HKDF_FAILED")}}async function senderHybridKeyAgreement(e,r){const t=await generateEphemeralKeyPair();if(!t.ok)return t;let a,n,i,c;try{a=new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:e},t.value.privateKey,AES_KEY_BITS))}catch{return(0,shared_1.err)("DERIVE_FAILED")}try{const e=await(0,mlkem_1.createMlKem768)(),[t,a]=e.encap(r);n=t,i=a}catch{return(0,shared_1.err)("KEM_ENCAPSULATE_FAILED")}try{const r=await crypto.subtle.exportKey("raw",e);c=new Uint8Array(r)}catch{return(0,shared_1.err)("EXPORT_KEY_FAILED")}const y=await combineSharedSecrets(i,n,a,t.value.rawPublicKey,c,r);return y.ok?(0,shared_1.ok)({sharedKey:y.value,ephemeralPublicKey:t.value.rawPublicKey,kemCiphertext:n}):y}async function receiverHybridKeyAgreement(e,r,t,a,n,i){const c=await importX25519PublicKey(t);if(!c.ok)return c;let y,s;try{y=new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:c.value},e,AES_KEY_BITS))}catch{return(0,shared_1.err)("DERIVE_FAILED")}try{s=(await(0,mlkem_1.createMlKem768)()).decap(a,n)}catch{return(0,shared_1.err)("KEM_DECAPSULATE_FAILED")}return combineSharedSecrets(s,a,y,t,r,i)}