Overview
Crosslink uses a layered cryptographic design:Identity keys
Each device (host or client) has a long-term Ed25519 key pair:- Private key: Stored in OS keychain (host) or WebCrypto non-extractable key (client)
- Public key: Shared during pairing, used for authentication
- Fingerprint: SHA-256 of the public key, first 16 hex chars displayed in QR code
Key generation
CLX1 handshake
The CLX1 handshake authenticates both parties and establishes a shared secret:Handshake security properties
Session encryption
Once the handshake completes, all communication uses XChaCha20-Poly1305:Why XChaCha20-Poly1305?
The 192-bit nonce makes random nonce generation safe without worrying about collisions, which is critical for the concurrent frame streams in Crosslink.
Key derivation
Session keys are derived using HKDF-SHA256:Secret storage encryption
Host (Node.js)
When the OS keychain is unavailable, the SDK falls back to AES-256-GCM file encryption:Client (Browser)
When usingCrosslinkClient.create(), the SDK encrypts at rest with AES-256-GCM under a WebCrypto key:
Algorithm choices and alternatives
Security limitations
- No post-quantum resistance: Ed25519 and X25519 are vulnerable to quantum computers
- No key escrow: Lost identity keys cannot be recovered (by design)
- No anonymity: Device fingerprints are visible during pairing
- No traffic analysis resistance: Frame sizes and timing are visible to network observers