fido2 derive: X-Wing (mlkem768x25519) split-custody support [UNTESTED]#30
Open
0c-coder wants to merge 1 commit into
Open
Conversation
Web app PQC over the existing derive flow with no large payloads: device keeps sk_X (X25519) and returns [pk_X|mlkem_seed] or [ss_X|mlkem_seed] (64 bytes); browser expands mlkem_seed and does the ML-KEM half locally. mlkem_seed = SHA256(sk_X || domain-tag), one-way/domain-separated. Not hardware-tested.
Author
|
Web-app counterpart (spec + browser impl + passing crypto proof): onlykey/onlykey.github.io#39. Together they deliver split-custody X-Wing: device does X25519, browser does ML-KEM, no large FIDO2 payloads. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
FIDO2 derive: X-Wing (mlkem768x25519) split-custody support — UNTESTED
Adds an X-Wing branch to the FIDO2 keyhandle derive flow (
bridge_to_onlykey,fido2/ok_extension.cpp) so the OnlyKey web app can do post-quantum age(
mlkem768x25519) with no large payloads over FIDO2.Model (split custody)
The device keeps the X25519 half; the browser does the ML-KEM half:
sk_X(X25519) is derived per label from the web-derivation key and neverleaves — the device only returns
ss_X = X25519(sk_X, ct_X).mlkem_seed; the browser expands it anddecapsulates the 1088-byte ML-KEM ciphertext locally (never sent to the
device). Decryption still requires the OnlyKey (no
ss_Xwithout it).Every round-trip is ≤ 64 bytes. Full spec + browser side + a passing crypto
proof:
onlykey.github.ioPR #39 (src/plugins/age/INTEGRATION.md,test/xwing-split.test.mjs).Wire
KEYTYPE_XWING (6)after the existingopt2++.DERIVE_PUBLIC_KEY→[ pk_X(32) | mlkem_seed(32) ]DERIVE_SHAREDSEC(_REQ_PRESS)→[ ss_X(32) | mlkem_seed(32) ](button press)transit_keywhenENCRYPT_RESP.Derivation (domain-separated — the security-critical bit)
sk_X= existingokcrypto_derive_key(KEYTYPE_CURVE25519, additional_data, RESERVED_KEY_WEB_DERIVATION).mlkem_seed = SHA256( sk_X || "onlykey/xwing/mlkem768-seed/v1" )— one-way, sohanding
mlkem_seedto the browser can never disclosesk_X, and it isconstant per label (stable recipient).
Review notes / open items
os=='W'dedupe used by theclassical
DERIVE_SHAREDSECpath) is not replicated here — confirm whetherPQC decrypt needs it.
send_transport_responselength is32 + sizeof(UNLOCKED) + 1 + 64; verifythe transit-encryption path handles the 64-byte body.
opt2collisions with existing classical types (5/6 are new).