Skip to content

Add HPKE test vectors - #273

Open
sgmenda wants to merge 1 commit into
C2SP:mainfrom
sgmenda:hpke-mlkem-vectors
Open

Add HPKE test vectors#273
sgmenda wants to merge 1 commit into
C2SP:mainfrom
sgmenda:hpke-mlkem-vectors

Conversation

@sgmenda

@sgmenda sgmenda commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Wycheproof test vectors for HPKE (RFC 9180) base mode, covering DHKEM(X25519, HKDF-SHA256) and ML-KEM-512/768/1024 (draft-ietf-hpke-pq). See doc/hpke.md for detailed documentation.

  • we mark X25519 all-zero-DH keys as invalid per RFC 9180 §5.1.1, which is stricter than RFC 7748 and than x25519_test.json, which marks them acceptable.
  • we generated these vectors using aws-lc and checked them against pyca/cryptography, Go crypto/hpke, and BoringSSL everywhere they overlap.
  • one particular gap is HPKE with ML-KEM-512 which only aws-lc implements.

Wycheproof test vectors for HPKE (RFC 9180) base mode, covering DHKEM(X25519,
HKDF-SHA256) and ML-KEM-512/768/1024 (draft-ietf-hpke-pq). See doc/hpke.md for
detailed documentation.

**For reviewers:**
- we mark X25519 all-zero-DH keys as *invalid* per RFC 9180 §5.1.1, which is
  stricter than RFC 7748 and than `x25519_test.json`, which marks them
  **acceptable**.
- we generated these vectors using aws-lc and checked them against
  pyca/cryptography, Go crypto/hpke, and BoringSSL everywhere they overlap.
- one particular gap is HPKE with ML-KEM-512 which only aws-lc implements.
@cpu

cpu commented Aug 21, 2026

Copy link
Copy Markdown
Member

Thank you! Adding HPKE coverage is something I've talked about with Filippo but neither of us had gotten to it yet. I won't be able to review this until the ~end of next week but I'm very supportive.

As a side note I think the upstream hpkewg is interested in finding a home for their vectors (hpkewg/hpke#72). Did you want to reach out and see if they're interested in joining forces and using c2sp/wycheproof for that home? They also recently added some new corner cases (hpkewg/hpke#70), and if you haven't already considered those they might be helpful additions.

@sgmenda

sgmenda commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

@cpu thanks for the pointers, I will reach out.

My initial instinct was those vectors should go in CCTV. But from the perspective of a crypto library, it's easier to track one external test vector library than two (Wycheproof and CCTV). @FiloSottile I'm curious for your thoughts?

Comment thread doc/hpke.md
Comment on lines +50 to +51
implementations used to cross-validate these vectors, only AWS-LC implements
ML-KEM in HPKE.

@jakemas jakemas Aug 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to say only 512 in:
"only AWS-LC implements ML-KEM in HPKE." Because BoringSSL implements ML-KEM in HPKE, right?

Suggested change
implementations used to cross-validate these vectors, only AWS-LC implements
ML-KEM in HPKE.
implementations used to cross-validate these vectors, only AWS-LC implements
ML-KEM-512 in HPKE.

Comment thread doc/hpke.md

Valid decryption cases also carry `ikmE`, the 32-byte seed that fixes the
sender's ephemeral key: for ML-KEM the encapsulation randomness, for
DHKEM(X25519) the ephemeral private key `skEm` (what a deterministic-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This renders all on one line like "what a deterministic- encapsulation hook consumes, not RFC 9180's" so we don't need the -:

Suggested change
DHKEM(X25519) the ephemeral private key `skEm` (what a deterministic-
DHKEM(X25519) the ephemeral private key `skEm` (what a deterministic

"skRm": {
"type": "string",
"format": "HexBytes",
"description": "Optional. The recipient private key (64-byte d || z seed) corresponding to pkRm, when one exists. Present lets a consumer additionally decapsulate enc and open ct to recover pt."

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this schema apply to both ML-KEM and x25519? i.e. hpke_x25519_encap_test.json has a 32-byte skRm. In decap you cover both cases

@cpu

cpu commented Aug 31, 2026

Copy link
Copy Markdown
Member

My initial instinct was those vectors should go in CCTV. But from the perspective of a crypto library, it's easier to track one external test vector library than two (Wycheproof and CCTV)

Yeah I think the boundary of which belongs where is a little fuzzy. Beyond the benefit of one-source-of-truth Wycheproof 's JSON schemas make life easier for downstreams 🤷‍♂️ I'd be happy with either.

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.

3 participants