crates/protocol/src/crypto.rs. The design is
WireGuard/Noise-inspired and deliberately conservative — “very high quality,
boring crypto.”
Primitives
| Purpose | Primitive | Crate |
|---|---|---|
| Key agreement | X25519 ECDH (ephemeral) | x25519-dalek |
| Authentication | Pre-shared key mixed into the KDF salt | — |
| Key derivation | HKDF-SHA256 | hkdf, sha2 |
| Record encryption | ChaCha20-Poly1305 (AEAD) | chacha20poly1305 |
Handshake (per session)
Exchange public keys
Over the TCP bulk channel they exchange 32-byte public keys in the clear
(safe for ECDH).
Derive key material
HKDF-SHA256 derives keys with salt = PSK (the passphrase → authentication),
ikm = shared_secret, and info = "sc-v1-kd" || sorted(pubkey_a, pubkey_b)
(binds the transcript).Why this is secure
Confidentiality + integrity
Confidentiality + integrity
ChaCha20-Poly1305 is an AEAD; any tampering fails the Poly1305 tag and the
packet is rejected.
Authentication / anti-MITM
Authentication / anti-MITM
Without the correct PSK, the two peers derive different keys and every
open() fails. An attacker who intercepts and replaces the ephemeral keys
still can’t derive the session keys without the PSK. This is why mDNS
discovery is safe — discovery only finds a candidate address; the PSK still
proves identity.Forward secrecy
Forward secrecy
Keys are ephemeral per session, so compromising one session’s keys doesn’t
expose past or future sessions.
Nonce safety
Nonce safety
A unique key per direction + a monotonic counter (UDP: the packet
seq; TCP:
an implicit ordered counter) guarantees no (key, nonce) pair is ever
reused — the cardinal AEAD rule.Threat model
- In scope (defended)
- Out of scope
- Passive eavesdropper on the LAN/Wi-Fi.
- Active attacker who forges/replays/tampers packets (rejected by AEAD + counter).
- Imposter advertising the same mDNS service (rejected without the PSK).
Operational guidance
Tests
crypto.rs unit tests assert: round-trip both directions; wrong PSK fails;
tampered ciphertext fails; wrong counter fails; tag-only overhead; and that the
input and bulk channels use independent keys (a ciphertext from one cannot be
opened by the other).