Classic McEliece 6960-119 + X25519 + HKDF-SHAKE256 KEM. => Classic McEliece => X25519 => RFC 5869, HKDF => SHAKE XOF function kem-with-encap { {field . {map}} {field a {str} >0} {# sntrup761-x25519-hkdf-blake2b} {# mceliece6960119-x25519-hkdf-shake256} {field cek {bin} >0} {# wrapped CEK} {field encap {bin} >0} {field to {with fpr} optional} {# recipient's public key} {field from {with fpr} optional} {# sender's public key} } "/kem/*/a" equals to "mceliece6960119-x25519-hkdf-shake256". Recipient public key with [cm/pub/mceliece6960119-x25519] algorithm must be used. It should have "kem" key usage set. "/kem/*/encap" field is a concatenation of 194 bytes of Classic McEliece 6960-119 ciphertext, with XChaCha20-Poly1305-encrypted 32 bytes ephemeral X25519 public key: mceliece-ciphertext || XChaCha20-Poly1305( key=decapKey, nonce=decapNonce, data=e-x25519-sender-public-key, ad=mceliece-ciphertext) Recipient performs Classic McEliece decapsulation, decrypts ephemeral X25519 public key, computes shared secrets, combines them and derives KEK. ==================================================== WARNING ==================================================== Sender authentication uses only *NON*-PQ crypto! ==================================================== H = SHAKE256 mceliece-ciphertext, mceliece-shared-key = KEM-Encap(mceliece-recipient-public-key) mceliece-shared-key = KEM-Decap(mceliece-recipient-private-key, mceliece-ciphertext) decapKey, decapNonce = HKDF-Expand(H, prk=mceliece-shared-key, info="cm/encrypted/mceliece6960119-x25519-hkdf-shake256/decap" || /id) es-x25519-shared-key = X25519(e-x25519-sender-private-key, s-x25519-recipient-public-key) PRK = HKDF-Extract(H, salt="", ikm= mceliece-shared-key || es-x25519-shared-key || H(mceliece-sender-ciphertext || e-x25519-sender-public-key) || H(mceliece-recipient-public-key || s-x25519-recipient-public-key)) if {specified sender} ss-x25519-shared-key = X25519(s-x25519-sender-private-key, s-x25519-recipient-public-key) PRK = HKDF-Extract(H, salt=PRK, ikm= ss-x25519-shared-key || s-x25519-sender-public-key) KEK = HKDF-Expand(H, prk=PRK, info="cm/encrypted/mceliece6960119-x25519-hkdf-shake256" || /id) "/kem/*/cek" is wrapped with [cm/keywrap/xchapoly] mechanism. KEM combiner nearly fully resembles: => Chempat If sender/recipient's public key structure contains "/load/v/prehash" field, then it could be used as already calculated values of SHAKE256 calls of PRK.