Hybrid Public Key Encryption (RFC 9180) with ML-KEM
OCaml 94%
4%
Dune 2%

README.md

hpke #

Hybrid Public Key Encryption: the base mode of RFC 9180 with the ML-KEM KEMs of draft-ietf-hpke-pq.

A sender encapsulates a shared secret to the recipient's ML-KEM public key, both ends run the RFC 9180 key schedule over that secret and an application info string, and the resulting context seals and opens messages with AES-GCM under a nonce derived per message, or exports secrets.

The primitives are dependencies: ML-KEM from nox-crypto-pq, HKDF from nox-kdf and AES-GCM from nox-crypto. This library is the RFC 9180 key schedule and encryption context built over them.

Registry Supported
KEM ML-KEM-768 (0x0041), ML-KEM-1024 (0x0042)
KDF HKDF-SHA256 (0x0001), HKDF-SHA384 (0x0002)
AEAD AES-128-GCM (0x0001), AES-256-GCM (0x0002)

Only the base mode is provided: the PSK, Auth and AuthPSK modes of RFC 9180 sections 5.1.2 to 5.1.4 are not.

Usage #

# Crypto_rng_unix.use_default ();;
- : unit = ()
# let sk, pk = Crypto_pq.Mlkem768.generate ();;
val sk : Crypto_pq.Mlkem768.priv = <abstr>
val pk : Crypto_pq.Mlkem768.pub = <abstr>
# let enc, ct =
    Hpke.seal_base ~kdf:Sha256 ~aead:Aes_256_gcm ~info:"app" ~aad:""
      (Hpke.Ml_kem_768_public pk) "hello"
  in
  (String.length enc, String.length ct);;
- : int * int = (1088, 21)
# let enc, ct =
    Hpke.seal_base ~kdf:Sha256 ~aead:Aes_256_gcm ~info:"app" ~aad:""
      (Hpke.Ml_kem_768_public pk) "hello"
  in
  Hpke.open_base ~kdf:Sha256 ~aead:Aes_256_gcm ~info:"app" ~aad:"" ~enc
    (Hpke.Ml_kem_768_private sk) ct;;
- : (string, Hpke.error) result = Ok "hello"

Tests #

The test suite replays the draft-ietf-hpke-pq base-mode vectors for ML-KEM-768 with HKDF-SHA256 and AES-128-GCM, and ML-KEM-1024 with HKDF-SHA384 and AES-256-GCM: the encapsulation, every sealed message and every exported secret. The vectors are those the draft publishes, as carried in the Go standard library's crypto/hpke test data.

  • Go's crypto/hpke implements RFC 9180 with the same ML-KEM KEMs and the hybrid ones of the draft; it is the source of the test vectors here.
  • hpke-rs (Rust) and hpke (Python, pyhpke) implement the RFC 9180 DHKEM suites.

License #

ISC