Skip to content

feat: add Hybrid KEMs - #67

Merged
twiss merged 12 commits into
WICG:mainfrom
panva:hybrids
Sep 3, 2026
Merged

twiss merged 12 commits into
WICG:mainfrom
panva:hybrids

Conversation

@panva

@panva panva commented May 15, 2026 •

Copy link
Copy Markdown
Collaborator

I had this lying around since March, gave it a rebase and updated references. I'm opening this as a draft PR to accomodate a discussion (and to get a preview link).

Proposes to add 3 Hybrid KEMs (per https://www.ietf.org/archive/id/draft-irtf-cfrg-concrete-hybrid-kems-03.html) as Web Cryptography algorithms. These three KEMs are exactly what HPKE-PQ uses.

  • MLKEM768-P256
  • MLKEM768-X25519 (aka X-Wing)
  • MLKEM1024-P384

Yanked SPKI / PKCS#8 discovery

SPKI import/export is specified using the Composite ML-KEM OIDs from draft-ietf-lamps-pq-composite-kem:

  • MLKEM768-X25519 -> id-MLKEM768-X25519-SHA3-256 (1.3.6.1.5.5.7.6.58)
  • MLKEM768-P256 -> id-MLKEM768-ECDH-P256-SHA3-256 (1.3.6.1.5.5.7.6.59)
  • MLKEM1024-P384 -> id-MLKEM1024-ECDH-P384-SHA3-256 (1.3.6.1.5.5.7.6.63)

PKCS#8 is kept as an issue in the proposal for now. LAMPS encodes OneAsymmetricKey.privateKey as mlkemSeed || tradSK, while this draft's raw-seed and JWK private-key forms use the 32-byte seed from the CFRG Hybrid KEM DeriveKeyPair flow. Seed-backed keys should be able to export PKCS#8 if the implementation can derive and serialize the component private keys. PKCS#8-imported keys can be usable for decapsulation and PKCS#8 re-export, but cannot be exported as raw-seed or JWK unless the original 32-byte seed is also available. The proposal calls out whether pkcs8 import should require extractable to be false, or whether seed-based export formats should fail for non-seed-backed keys.

Additionaly, raw-private export/import in the LAMPS mlkemSeed || tradSK definition might be an option to support in addition to raw-seed.

raw-seed must remain as-is to support HPKE-PQ.


I'm not married to either pkcs8, spki, or raw-private. But i at least did the due diligence for the proposal. Happy to adjust based on feedback.

WPTs: web-platform-tests/wpt#59947


Preview | Diff

@hubertchao

Copy link
Copy Markdown

JWK import question: There is a note that says:

 The "alg" values registered in the IANA JSON Web Signature and Encryption Algorithms registry for the hybrid KEM instances defined by this specification are  MLKEM768-P256 , MLKEM768-X25519 , and  MLKEM1024-P384 . Implementations should also accept other values from this registry that identify an algorithm utilizing the same hybrid KEM instance. 

(a) where are the hybrid KEM algorithm registrations defined? https://www.ietf.org/archive/id/draft-irtf-cfrg-concrete-hybrid-kems-03.html#name-iana-considerations doesn't seem to match, and I don't see it in https://datatracker.ietf.org/doc/draft-ietf-lamps-pq-composite-kem/ either (or in https://www.iana.org/assignments/jose/jose.xhtml)

(b) is this saying that there may be more than one name for the same Hybrid KEM?

@panva

panva commented May 29, 2026 •

Copy link
Copy Markdown
Collaborator Author

@hubertchao happy to explain

the "alg" values come from the proposal's own IANA registration section where we'll register the exact names that correspond for use with JWK only, i.e. in JOSE there isn't actually going to be a JWE "alg" for MLKEM768-X25519.

What https://datatracker.ietf.org/doc/draft-skokan-jose-hpke-pq-pqt/ (pending confirmation of adoption, only positive signals on the JOSE WG mailing list) will register are JWE "alg" values that will end up using these hybrid KEMs, due to reasons? the convention set out by https://datatracker.ietf.org/doc/draft-ietf-jose-hpke-encrypt/ the HPKE specific alg names are non-descriptive e.g. HPKE-7 😭

So, the modern algorithms draft (or webcrypto-actual after merge) will register JWK use alg values like "MLKEM768-X25519" so that we can use those during jwk import/export. While when those hybrid KEMs will end up being used in JWE HPKE-PQ those will be e.g. HPKE-9 and those will end up in the https://www.iana.org/assignments/jose/jose.xhtml registry as well.

The "alg" values registered in the IANA JSON Web Signature and Encryption Algorithms registry for the hybrid KEM instances defined by this specification are MLKEM768-P256 , MLKEM768-X25519 , and MLKEM1024-P384 . Implementations should also accept other values from this registry that identify an algorithm utilizing the same hybrid KEM instance.

This was my way of attempting to let implementers know that e.g. { kty: 'AKP', alg: 'HPKE-9', pub: '...' } is also an "alg" that represents MLKEM768-X25519, albeit without having an actual adopted IETF JOSE draft to refer to just yet.

To be honest because the https://datatracker.ietf.org/doc/draft-skokan-jose-hpke-pq-pqt/ defines the JWK serialization for its keys as just direct callouts to HPKE's SerializePublicKey and SerializePrivateKey which correspond with raw-public and raw-seed I don't necessarily believe we need JWK for these hybrids. But then I recall a conversation with @twiss about the usefulness of JWK/pkcs8/spki in wrapKey/unwrapKey because the wrapped key in a jwk/pkcs8/spki format cannot be unwrapped to another algorithm (due to either "alg" binding or an X509 OID). I have yet to see actual use of wrapKey/unwrapKey ever but will leave this to @twiss to chime in on.


For now based on the feedback from @davidben that also happens to align with my view i'm removing spki from the PR. I've gathered the spki/pkcs8 discovery i did in a collapsible section in the PR description.

@panva
panva marked this pull request as ready for review May 30, 2026 08:16
@panva
panva requested a review from twiss June 6, 2026 11:47
beckysiegel pushed a commit to chromium/chromium that referenced this pull request Jun 11, 2026
Implements importKey and exportKey using the JWK format, based on spec
PR in WICG/webcrypto-modern-algos#67.

Add unit tests for now, which can be deleted once the PR is merged in
and WPTs are added web-platform-tests/wpt#59947

Change-Id: I856ae991432c99612cf7b5d9198dba81fccf1e7b
Bug: 510170714
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7887900
Reviewed-by: David Benjamin <davidben@chromium.org>
Commit-Queue: Hubert Chao <hchao@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1645466}
@panva

panva commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator Author

This is part of the Chrome 151 to 154 Origin Trials.

@panva

panva commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

3b840c6 i pushed just now wires Hybrid KEMs to a KEM-fixed supports() (#77)

@twiss twiss left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks! 🙏

@twiss
twiss merged commit 2ff1a92 into WICG:main Sep 3, 2026
2 checks passed
github-actions Bot added a commit that referenced this pull request Sep 3, 2026
SHA: 2ff1a92
Reason: push, by twiss

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@panva
panva deleted the hybrids branch September 3, 2026 15:54
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