Ciphersuites

A suite selects a key encapsulation mechanism (KEM), key derivation function (KDF), and authenticated cipher (AEAD). Both peers must use the same suite. Sizes below are bytes; IDs are hexadecimal wire codepoints.

open Hpke

let suite =
  Suite.create ~kem:Kem.X25519 ~kdf:Kdf.Hkdf_sha256 ~aead:Aead.Aes_128_gcm

let exporter =
  Suite.export_only ~kem:Kem.X25519 ~kdf:Kdf.Hkdf_sha256

Registries use OCaml variants. Convert wire IDs with of_int; unknown IDs return Unsupported_algorithm. Hybrid KEMs and Draft_hpke_04 require 0.4.0 or newer.

KEM

Key encapsulation mechanisms
Constructor Registry name ID Public Enc Private Secret
Kem.P256DHKEM(P-256, HKDF-SHA256)0x001065653232
Kem.P384DHKEM(P-384, HKDF-SHA384)0x001197974848
Kem.P521DHKEM(P-521, HKDF-SHA512)0x00121331336664
Kem.X25519DHKEM(X25519, HKDF-SHA256)0x002032323232
Kem.X448DHKEM(X448, HKDF-SHA512)0x002156565664
Kem.Mlkem512ML-KEM-5120x00408007686432
Kem.Mlkem768ML-KEM-7680x00411,1841,0886432
Kem.Mlkem1024ML-KEM-10240x00421,5681,5686432
Kem.Mlkem768_p256MLKEM768-P2560x00501,2491,1533232
Kem.Mlkem1024_p384MLKEM1024-P3840x00511,6651,6653232
Kem.Mlkem768_x25519MLKEM768-X25519 (X-Wing)0x647a1,2161,1203232

Public and Private are serialized key sizes; Enc is the encapsulated key size; Secret is the shared secret size. Read them through Kem.public_key_size, private_key_size, encapsulated_key_size, and secret_size. Kem.supports_auth reports Auth support.

X448 backends

X448 uses curve448's OCaml backend by default. Add curve448.c to your executable's libraries to select its C backend. With ocamlfind, link curve448.ocaml or curve448.c explicitly.

ML-KEM

These KEMs use FIPS 203 ML-KEM from mlkem with the HPKE integration from draft-ietf-hpke-pq-05. They support Base and PSK; Auth and AuthPSK return Unsupported_mode.

The draft prefers ML-KEM-768 and ML-KEM-1024 to ML-KEM-512. mlkem is unaudited and does not guarantee constant-time execution; read the dependency limits.

Hybrid KEMs

MLKEM768-P256, MLKEM768-X25519 (X-Wing), and MLKEM1024-P384 combine ML-KEM with an elliptic-curve exchange using SHA3-256. They follow draft-ietf-hpke-pq-05 and draft-irtf-cfrg-concrete-hybrid-kems. Like ML-KEM, they support Base and PSK only.

This implementation rejects all-zero X25519 exchanges, although the concrete hybrid draft leaves them unchecked. Honest senders do not produce them. The draft and key-derivation caveats above also apply.

KDF

Key derivation functions
Constructor Name ID Hash size Longest export
Kdf.Hkdf_sha256HKDF-SHA2560x0001328,160
Kdf.Hkdf_sha384HKDF-SHA3840x00024812,240
Kdf.Hkdf_sha512HKDF-SHA5120x00036416,320

HKDF exports allow 0 through 255 times the hash size. A negative or excessive length returns Export_length_out_of_range.

SHAKE KDFs

These KDFs are available only in Hpke.Draft_hpke_04. Its registry also includes the three HKDFs above.

One-stage KDFs of Draft_hpke_04
Constructor Name ID Nh Longest export
Draft_hpke_04.Kdf.Shake128SHAKE1280x00103265,535
Draft_hpke_04.Kdf.Shake256SHAKE2560x00116465,535

The one-stage schedule derives the key, base nonce, and exporter secret in one LabeledDerive call. Each of info, the PSK, and its identifier is limited to 65,535 bytes; longer inputs return Invalid_length. Exports allow 0 through 65,535 bytes. Nh is the KDF parameter returned by hash_size.

AEAD

Authenticated encryption
Constructor Name ID Key Nonce Tag Longest plaintext
Aead.Aes_128_gcmAES-128-GCM0x0001161216236 − 32
Aead.Aes_256_gcmAES-256-GCM0x0002321216236 − 32
Aead.Chacha20_poly1305ChaCha20-Poly13050x0003321216238 − 64
Suite.export_onlyExport-only0xFFFF————

Export-only is a separate suite type. It supports context setup and export, but cannot be passed to encryption or decryption functions.

Modes

ModeIDAdditional input
Base0x00None; does not authenticate the sender.
PSK0x01A shared secret of at least 32 bytes and a non-empty identifier.
Auth0x02The sender's static key pair. DHKEM only.
AuthPSK0x03Both a sender key pair and a PSK. DHKEM only.

Draft_hpke_04 provides Base and PSK only.

Key validation

Limits

Not provided

Transport framing, key management, compressed NIST points, expanded ML-KEM private keys, and TurboSHAKE KDFs. Private keys and PSKs have no printers or equality helpers.

Protocol versions

Hpke.Rfc9180 keeps its RFC wire behavior. Hpke.Draft_hpke_04 implements draft-ietf-hpke-hpke-04 with Base, PSK, and the SHAKE KDFs. With HKDF, it produces the same encapsulations, ciphertexts, and exports as Rfc9180. Keys, AEADs, PSKs, and context types are shared.

let draft_suite =
  Draft_hpke_04.Suite.create ~kem:Kem.Mlkem768_x25519
    ~kdf:Draft_hpke_04.Kdf.Shake256 ~aead:Aead.Chacha20_poly1305

let send ~rng ~recipient ~plaintext =
  Draft_hpke_04.seal_base ~rng draft_suite ~recipient
    ~info:"example-v1" ~aad:"" ~plaintext

A later HPKE draft that changes wire behavior gets a separate module. The ML-KEM and hybrid KEM integrations also follow drafts; pin versions when testing interoperability.