Auth Handshake#
6. Auth handshake (reconnect)#
After pairing, subsequent connections use a 2-message static-key handshake — no code required.
Wire messages#
1. C → S: {"v": 1, "kind": "auth_hello",
"e": <e_c_pub 32 B>,
"s": <s_c_pub 32 B>}
2. S → C: {"v": 1, "kind": "auth_offer",
"e": <e_s_pub 32 B>,
"ct": AEAD(k, nonce=0, plaintext=b"ok")}
If the server does not recognise the client’s static key (s_c_pub), it
still responds with message 2 but with ct = b"" (zero bytes), then closes
— deliberately ambiguous to avoid leaking whether the key was unknown vs.
the DH was bad.
Key derivation (auth)#
transcript = SHA-256(e_s_pub || e_c_pub || s_c_pub)
k = HKDF-SHA256(salt=transcript,
ikm=DH(e_s, e_c) || DH(s_s, e_c),
info="opendesk-auth-k")
The b"ok" payload encrypted under k gives the client proof that the server
holds the private key for s_s_pub (recorded at pairing time).
Session key derivation (auth)#
dh_chain = [
DH(e_s, e_c), # server ephemeral × client ephemeral
DH(s_s, e_c), # server static × client ephemeral
DH(e_s, s_c), # server ephemeral × client static
DH(s_s, s_c), # server static × client static
]
64 bytes = HKDF-SHA256(salt=transcript, ikm=concat(dh_chain),
info="opendesk-session-keys", length=64)
No PSK is mixed in for auth (only for pairing).
Auth failure codes#
|
Meaning |
|---|---|
|
AEAD decryption failed — PSK mismatch (wrong pairing code). |
|
Client’s static key not in server’s |
|
Server’s auth proof didn’t verify — server holds a different key than expected. |
|
Malformed message, wrong version, or wrong |
With the connection live, both sides exchange typed frames. See Frames & Errors →