Skip to content

Add ML-KEM support to HPKE (draft-ietf-hpke-pq-04)#3277

Draft
jakemas wants to merge 2 commits into
aws:mainfrom
jakemas:pq-hpke-mlkem
Draft

Add ML-KEM support to HPKE (draft-ietf-hpke-pq-04)#3277
jakemas wants to merge 2 commits into
aws:mainfrom
jakemas:pq-hpke-mlkem

Conversation

@jakemas

@jakemas jakemas commented May 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Implement ML-KEM-512/768/1024 as HPKE KEMs per draft-ietf-hpke-pq-04
  • Refactor evp_hpke_key_st to heap-allocated key storage for ML-KEM key sizes
  • Add HKDF-SHA384 KDF and update MAX constants
  • Priority ciphersuite: HPKE(ML-KEM-1024, HKDF-SHA384, AES-256-GCM)

Details

ML-KEM shared secret is used directly in the HPKE key schedule (no ExtractAndExpand). Auth mode is not supported for ML-KEM KEMs. Secret keys are validated via ml_kem_*_check_sk() on init.

FIPS 203 page 16
Screenshot 2026-05-29 at 1 46 17 PM

Performance

1000 iterations, 64-byte plaintext. Keygen is measured independently. Encap/Decap = setup_sender/setup_recipient (includes key schedule).

Ciphersuite Keygen Encap Decap Full roundtrip
X25519 + SHA256 + AES-128-GCM 58.9 us 50.8 us 39.1 us 89.7 us
X25519 + SHA256 + AES-256-GCM 10.4 us 49.9 us 40.1 us 89.3 us
ML-KEM-512 + SHA256 + AES-128-GCM 12.5 us 23.3 us 26.3 us 49.7 us
ML-KEM-768 + SHA256 + AES-256-GCM 20.5 us 31.5 us 37.4 us 67.2 us
ML-KEM-1024 + SHA384 + AES-256-GCM 29.6 us 48.7 us 48.8 us 92.1 us

Benchmarks run on Intel Xeon Platinum 8175M (4c/8t @ 2.50GHz, 30 GiB RAM, AVX-512/AES-NI) running Linux 6.17.0-1013-aws.

ML-KEM-1024 full roundtrip is within 3% of X25519 DHKEM. ML-KEM-512/768 are faster due to skipping the ExtractAndExpand step.

Test plan

  • All 11 existing X25519 HPKE tests pass (zero regressions)
  • 35 new ML-KEM parameterized tests covering:
    • Round-trip (keygen -> setup_sender -> seal -> setup_recipient -> open)
    • Multi-message seal/open sequence (10 messages)
    • Key serialization round-trip (generate -> export -> re-import -> verify)
    • Key copy and move operations
    • Auth mode correctly returns error
    • Wrong ciphertext size rejected
    • Export secret matches between sender and recipient
  • Downstream callers build cleanly (encrypted_client_hello.cc, generate_ech.cc)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

Implement ML-KEM-512, ML-KEM-768, and ML-KEM-1024 as HPKE KEMs,
enabling post-quantum-safe HPKE encryption. The priority ciphersuite
is HPKE(ML-KEM-1024, HKDF-SHA384, AES-256-GCM).

Changes:
- Refactor evp_hpke_key_st to use heap-allocated key storage to
  accommodate ML-KEM key sizes (up to 3168 bytes)
- Update EVP_HPKE_MAX constants for ML-KEM-1024 dimensions
- Add HKDF-SHA384 KDF (EVP_hpke_hkdf_sha384)
- Implement ML-KEM KEM functions (init, generate, encap, decap)
  for all three parameter sets
- ML-KEM shared secret is used directly per draft-ietf-hpke-pq-04
  (no ExtractAndExpand step)
- Auth mode returns error for ML-KEM KEMs (not supported)
- Validate secret keys via ml_kem_*_check_sk on init
@jakemas jakemas requested a review from a team as a code owner May 29, 2026 19:04
@jakemas jakemas marked this pull request as draft May 29, 2026 19:04
github-actions[bot]

This comment was marked as spam.

@codecov-commenter

codecov-commenter commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.44444% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.42%. Comparing base (7830af6) to head (4964746).
⚠️ Report is 49 commits behind head on main.

Files with missing lines Patch % Lines
crypto/hpke/hpke.c 73.41% 63 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3277      +/-   ##
==========================================
+ Coverage   78.16%   78.42%   +0.26%     
==========================================
  Files         689      689              
  Lines      123334   124082     +748     
  Branches    17148    17241      +93     
==========================================
+ Hits        96401    97313     +912     
+ Misses      26022    25849     -173     
- Partials      911      920       +9     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Cover the input validation branches in the ML-KEM KEM functions:
- Wrong private key length (too short)
- Corrupted private key (correct length, fails check_sk)
- Wrong seed length via setup_sender_with_seed_for_testing
- Wrong public key length for encap
- Enc buffer too small
- Public/private key export buffer too small
- Copy of a zeroed (uninitialized) key
github-actions[bot]

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants