Add post-quantum (age ML-KEM-768 / X-Wing) scaffold for WebCrypt/onlyagent#39
Add post-quantum (age ML-KEM-768 / X-Wing) scaffold for WebCrypt/onlyagent#390c-coder wants to merge 6 commits into
Conversation
|
Related post-quantum (ML-KEM-768 / X-Wing) work across the stack:
|
- xwing.js: verified split-decaps crypto (mlkem seed expansion, recipient build, encapsulate, xwingSplitDecapsulate) against @noble/post-quantum - onlykey-pqc.js: 64-byte derive wrappers (getRecipient / decapsulate) over the existing FIDO2 derive flow; device returns [ss_X|mlkem_seed], sk_X never leaves - age-pqc.js: recipient/encrypt/decrypt wired to the verified KEM (age container framing left as scoped TODOs to byte-match the age mlkem768x25519 format) - INTEGRATION.md: pinned spec (HKDF domain separation, 64-byte layout, combiner) - test/xwing-split.test.mjs: proves split decaps == standard encaps shared secret
|
Firmware counterpart (the 64-byte derive response, UNTESTED): trustcrypto/libraries#30. |
|
age container framing implemented (the last open TODO; KEM was already done). Added on
Note: the web app addresses keys by derivation label, not a slot, so it doesn't emit #90's slot-based identity string — but the recipient ( |
|
Withdrawing this PR. The web app has no age workflow, and its key derivation works differently from the CLI: the web app derives keys per-label from the reserved web-derivation key (no slots), whereas python-onlykey#90 / the CLI use on-device ECC slots (101–116). So this scaffold implements an age client the web app isn't — and its label-derived keys wouldn't be the CLI's slot identities anyway, so the earlier "interoperates with the CLI" framing doesn't hold. The KEM/container code and tests remain on branch |
Host-side post-quantum KEM scaffold for the WebCrypt/onlyagent app, mirroring the age PQC support in python-onlykey#90 + firmware libraries#29 (ML-KEM-768 = keytype 5, X-Wing = keytype 6).
New files only, no edits to existing files:
Design: the web path has no key slots -- keys are derived per-identity from the reserved web-derivation key. The 32-byte derived secret feeds X-Wing directly (its private key is a 32-byte seed) and expands to ML-KEM's (d,z). Only the keytype byte (5/6) is added to the derive request.
Compatibility with #38 (OnlyAgent reskin): disjoint file sets. #38 only touches src/app-src.html, src/index-src.html, and two asset files; this only adds device-layer JS and a new src/plugins/age/ folder. They merge cleanly in either order, and the reskin's app_pages loop auto-styles the new age plugin page.
Status: scaffold / WIP. Encapsulation and the derive-flow shape are real; the TODO(verify) items in INTEGRATION.md (identity->keyhandle encoding, decaps op, ML-KEM seed expansion, age stanza/HPKE) must be matched byte-for-byte against python-onlykey#90 (tests/test_age_wire.py) before interop.