Add end-to-end encryption for chat messages (X25519 / NaCl box)

Each device generates its own X25519 key pair on login (tweetnacl); the
private key never leaves localStorage or reaches our server. Messages are
encrypted client-side with the recipient's public key before being sent,
so the backend and anyone intercepting traffic only ever see ciphertext.

- src/lib/e2ee.ts: key generation/registration + encrypt/decrypt (NaCl box)
- Chat thread + matches list: encrypt on send, decrypt on receive/preview,
  with a graceful fallback when a message can't be decrypted on this device
  (e.g. after switching browsers) and full backward compat for legacy
  plaintext messages sent before this change
- Privacy settings page explains the guarantee and its one deliberate
  trade-off: there is no key backup/escrow, so clearing browser data or
  switching devices makes old messages permanently unreadable

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 18:58:21 +03:30
parent d55d61ba81
commit 0118ecc63a
8 changed files with 231 additions and 15 deletions
+3 -1
View File
@@ -16,7 +16,9 @@
"lucide-react": "^1.45.0",
"next": "16.3.5",
"react": "19.2.8",
"react-dom": "19.2.8"
"react-dom": "19.2.8",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.1"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",