Add HPKE test vectors - #273
Conversation
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.
|
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. |
|
@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? |
| implementations used to cross-validate these vectors, only AWS-LC implements | ||
| ML-KEM in HPKE. |
There was a problem hiding this comment.
Did you mean to say only 512 in:
"only AWS-LC implements ML-KEM in HPKE." Because BoringSSL implements ML-KEM in HPKE, right?
| 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. |
|
|
||
| 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- |
There was a problem hiding this comment.
This renders all on one line like "what a deterministic- encapsulation hook consumes, not RFC 9180's" so we don't need the -:
| 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." |
There was a problem hiding this comment.
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
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. |
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.
x25519_test.json, which marks them acceptable.