Encryption Layer
Happy implements end-to-end encryption using TweetNaCl (NaCl/libsodium JavaScript port). All messages and sensitive data are encrypted on the client before transmission to the server.Cryptographic Primitives
TweetNaCl Library
Happy uses the tweetnacl library, a JavaScript port of Daniel J. Bernstein’s NaCl cryptography library. Key Features:- curve25519-xsalsa20-poly1305: Public-key authenticated encryption
- xsalsa20-poly1305: Secret-key authenticated encryption
- ed25519: Digital signatures for authentication
- sha512: Hash function (via Node.js crypto)
packages/happy-cli/src/api/encryption.ts
Base64 Encoding
- Standard base64: Message content, encryption keys
- Base64URL: QR codes, URL parameters (no escaping needed)
Encryption Schemes
Happy supports two encryption variants:- Data Key (New)
- Legacy
Algorithm: AES-256-GCM + Box encryptionFeatures:Implementation:
- Separate data encryption key per session
- Key wrapped with user’s public key
- Server can verify ownership without decrypting
- Forward secrecy support (future)
packages/happy-cli/src/api/encryption.ts:120Key Management
Secret Key Generation
~/.happy/access.key (or $HAPPY_HOME_DIR/access.key)
Permissions: 0600 (read/write for owner only)
Public Key Derivation
Session Data Key
For new sessions using data key encryption:Encryption Implementation
Secret-Key Encryption (Legacy)
Encrypt with secretbox
Encrypt with secretbox
- Authenticated encryption: Poly1305 MAC prevents tampering
- Nonce: Random, never reused (24-byte nonce space is huge)
- Key: 32-byte secret key (256-bit security)
Decrypt with secretbox
Decrypt with secretbox
null on decryption failure (wrong key or tampered data).Data-Key Encryption (New)
Encrypt with AES-256-GCM
Encrypt with AES-256-GCM
- Hardware acceleration on modern CPUs (AES-NI)
- Industry standard (NIST approved)
- Built-in authentication (no separate MAC needed)
Decrypt with AES-256-GCM
Decrypt with AES-256-GCM
Public-Key Encryption (Box)
Used for wrapping data keys:Authentication Flow
Challenge-Response Protocol
Authentication Sequence
Security:- Secret key never transmitted
- Challenge is random (prevents replay attacks)
- Signature proves possession of secret key
packages/happy-cli/src/api/auth.ts:19
Message Encryption Flow
Sending a Message
Receiving a Message
Security Properties
Threat Model
Compromised Server
Compromised Server
Attack: Server operator tries to read messagesDefense: End-to-end encryption
- Server only has encrypted blobs
- Decryption keys never leave clients
- Even database breach reveals no plaintext
Man-in-the-Middle
Man-in-the-Middle
Attack: Attacker intercepts network trafficDefense: TLS + authenticated encryption
- All HTTP/WebSocket traffic over TLS
- NaCl authenticated encryption prevents tampering
- Ed25519 signatures prevent impersonation
Key Compromise
Key Compromise
Attack: Attacker steals user’s secret keyCurrent: Full compromise of all sessions
- Can decrypt all past and future messages
- Can impersonate user
- Data key encryption limits to individual sessions
- Key rotation would limit exposure
- Perfect forward secrecy (ephemeral keys per message)
Replay Attacks
Replay Attacks
Attack: Attacker resends old messagesDefense: Sequence numbers + nonces
- Each message has unique sequence number
- Encryption nonces are random (never reused)
- Authentication challenge is random
Cryptographic Strength
Secret-Key Encryption
Algorithm: XSalsa20-Poly1305Key Size: 256 bitsNonce Size: 192 bits (24 bytes)Authentication: Poly1305 MAC (128-bit security)Status: Industry standard, NaCl recommendation
Data-Key Encryption
Algorithm: AES-256-GCMKey Size: 256 bitsNonce Size: 96 bits (12 bytes)Authentication: GCM (128-bit security)Status: NIST approved, hardware accelerated
Public-Key Encryption
Algorithm: Curve25519 (Box)Key Size: 256 bitsSecurity Level: ~128-bit (elliptic curve)Status: Modern standard, resistance to side-channels
Digital Signatures
Algorithm: Ed25519Key Size: 256 bitsSignature Size: 512 bits (64 bytes)Status: Fast, secure, deterministic
Best Practices
Future Improvements
Perfect Forward Secrecy
Perfect Forward Secrecy
Current: Session key reused for entire sessionProposal: Use ephemeral keys per message
- Generate fresh keypair for each message
- Encrypt message with ephemeral key
- Wrap ephemeral key with recipient’s public key
- Delete ephemeral private key immediately
Key Rotation
Key Rotation
Current: Secret key never changesProposal: Support key rotation
- Generate new secret key
- Re-encrypt all sessions with new key
- Upload encrypted transition proof
- Clients verify transition
Multi-Device Sync
Multi-Device Sync
Current: Same secret key on all devicesProposal: Device-specific keys
- Each device has unique keypair
- Session keys encrypted for all device keys
- Revoke individual devices
Post-Quantum Cryptography
Post-Quantum Cryptography
Current: Elliptic curve crypto (vulnerable to quantum computers)Proposal: Hybrid encryption
- Use both classical and post-quantum algorithms
- Encrypt with both (Belt-and-suspenders)
- Require breaking both to compromise
Testing Encryption
Unit Tests
- Round-trip encryption/decryption
- Base64 encoding variants
- Key derivation
- Authentication challenge
Integration Tests
- Cross-platform compatibility (Node.js ↔ React Native)
- Legacy format support
- Version byte handling
Debugging Encryption Issues
Reference Implementation
The encryption layer is implemented in a single file: Location:packages/happy-cli/src/api/encryption.ts
Exports:
encodeBase64()/decodeBase64()- Base64 encoding (line 9, 34)getRandomBytes()- Secure random generation (line 51)libsodiumPublicKeyFromSecretKey()- Public key derivation (line 55)libsodiumEncryptForPublicKey()- Box encryption (line 62)encryptLegacy()/decryptLegacy()- Legacy encryption (line 87, 102)encryptWithDataKey()/decryptWithDataKey()- Data key encryption (line 120, 148)authChallenge()- Authentication signature (line 199)
Next Steps
Data Flow
See how encrypted messages flow through the system
Session Lifecycle
Learn when keys are generated and used
Authentication Guide
Learn about secure authentication
Architecture
Understand overall system design