ΠΠΎΠ»Π½Π°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ΠΏΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ, ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΠΈ ΠΈ Π·Π°ΡΠΈΡΠ΅ ΠΎΡ ΡΠ³ΡΠΎΠ·.
| Algorithm | Purpose | Implementation | Key Size |
|---|---|---|---|
| X25519 | Key Exchange | libsodium | 256-bit |
| Noise_NN | Protocol Framework | Custom | - |
| ChaCha20Poly1305 | AEAD Encryption | libsodium | 256-bit (key), 96-bit (nonce) |
| BLAKE2b | Hashing | libsodium | 256-bit output |
| HMAC-SHA256 | Verification | libsodium | 256-bit |
| Aspect | Signal Protocol | Noise Protocol |
|---|---|---|
| Complexity | High (X3DH + Double Ratchet) | Medium (simpler handshake) |
| Forward Secrecy | Perfect (with ratcheting) | Perfect (with Double Ratchet) |
| Implementation | Complex, many dependencies | Modular, minimal deps |
| Auditability | Large codebase | Smaller, simpler |
| Performance | Good | Excellent |
| Industry Use | WhatsApp, Signal | WireGuard, Briar |
Decision: Noise NN with Double Ratchet gives us 99% of Signal's security with 50% of complexity.
Identity Key (IK_a)
ββ Long-term key (never changes)
ββ Curve25519 private/public
ββ Used to verify Alice's identity
Ephemeral Key (EK_a)
ββ One-time key (changes per session)
ββ Generated fresh for initial contact
ββ Used only for first message
Prekeys (PK_a)
ββ 100 keys uploaded to server
ββ Used by Bob to initiate (no prior contact)
ββ Signed by Identity Key for verification
Alice β Server:
1. Sends IK_a (identity key)
2. Generates 100 Prekeys
3. Uploads (Prekeys + IK_signature)
Bob β Server (wants to message Alice):
1. Requests one of Alice's Prekeys
2. Server returns: { prekey, signature, IK_a }
3. Bob verifies signature with IK_a
Bob β Alice (Initial Message):
DH1 = ECDH(IK_b, EK_a) # Bob identity β β Alice ephemeral
DH2 = ECDH(EK_b, IK_a) # Bob ephemeral β β Alice identity
DH3 = ECDH(EK_b, EK_a) # Bob ephemeral β β Alice ephemeral
DH4 = ECDH(IK_b, PK_a) # Bob identity β β Alice prekey
Shared_Secret = KDF(DH1 || DH2 || DH3 || DH4)
ββ First root_key = KDF(Shared_Secret, "root")
ββ First send_chain_key = KDF(Shared_Secret, "chain")
ββ Encryption_key = HKDF(chain_key)
First message encrypted with Encryption_key
ββ Only Alice can decrypt (knows her prekey)
Alice receives, decrypts:
ββ Recovers Shared_Secret (same DH4 with her PK_a)
ββ Derives first receive_chain_key
ββ Decrypts message + continues conversation
Alice sends message to Bob:
1. Current Chain Key: chain_key = HKDF(root_key, 32 bytes)
2. Message Key: msg_key = HKDF(chain_key, 32 bytes)
3. Nonce: nonce = message_counter (strictly increasing)
4. AEAD Encryption:
ciphertext = ChaCha20Poly1305::encrypt(
key: msg_key,
nonce: nonce,
plaintext: message,
ad: sender_id || recipient_id || msg_num
)
5. Ratchet Forward:
new_chain_key = HKDF(chain_key, 32 bytes)
root_key_new = HKDF(root_key, 32 bytes) # Every 100 messages
6. Generate New Ephemeral:
new_ephemeral_key = X25519::generate()
new_root_key = ECDH(new_ephemeral, bob_ephemeral)
7. Wrap in Protocol Message:
{
"type": "message",
"sender_id": alice_id,
"dh_public": alice_ephemeral.public,
"chain_num": current_chain_number,
"msg_num": message_counter,
"ciphertext": base64(ciphertext),
"auth_tag": base64(poly1305_tag)
}
8. Server Relay (if Bob offline):
- Server stores encrypted blob
- Stores: (to_phone_hash, from_phone_hash, blob, ttl=7d)
- Does NOT decrypt, does NOT log content
Bob receives message:
1. Extract DH Public (alice_ephemeral)
2. Perform DH Ratchet:
shared_secret = ECDH(bob_ephemeral_private, alice_ephemeral)
3. Update Root Key:
new_root_key = HKDF(root_key, shared_secret)
4. Advance Chain Key:
for i in range(msg_num - current_msg_num):
chain_key = HKDF(chain_key)
5. Derive Message Key:
msg_key = HKDF(chain_key)
6. Verify & Decrypt:
plaintext = ChaCha20Poly1305::decrypt(
key: msg_key,
nonce: msg_num,
ciphertext: ciphertext,
ad: sender_id || recipient_id || msg_num,
auth_tag: auth_tag
)
ββ If auth_tag fails β ABORT (tampering detected)
ββ If success β Plaintext β
7. Update Ephemeral:
bob_ephemeral = alice_ephemeral (for next message from Alice)
8. Ratchet Bob's Send Chain (for reply):
bob_new_ephemeral = X25519::generate()
bob_root_key = ECDH(bob_new_ephemeral, alice_ephemeral)
β Perfect Forward Secrecy: Old messages can't be decrypted
even if long-term keys compromised
Threat: Attacker intercepts network traffic
Mitigation:
ββ TLS 1.3: All clientβserver communication encrypted
ββ Noise E2E: End-to-end encryption (even server can't read)
ββ Perfect Forward Secrecy: Old messages safe even if keys stolen
ββ Authentication: AEAD prevents tampering
Result: β Confidentiality guaranteed
Threat: Attacker intercepts and modifies messages
Mitigation:
ββ Poly1305 Authentication Tag: Detects tampering
ββ Key Fingerprints: Users verify each other's identity
ββ Proof of Work: SMS verification prevents fake accounts
ββ Signature Verification: Prekeys signed with Identity Key
Result: β Integrity guaranteed
Scenario 1: Long-term Identity Key stolen
Threat: Attacker can impersonate user in future
Mitigation:
ββ Device compromise detection: key change alert
ββ Multiple devices: other devices unaffected
ββ Manual key rotation available
Result: β Partial (need key rotation mechanism)
Scenario 2: Session Key stolen (ephemeral)
Threat: Attacker can read current session
Mitigation:
ββ Double Ratchet: Key changes every message
ββ Forward Secrecy: Can't read past messages
ββ Receive Ratchet: Can't read future messages
Result: β Only current message readable (limited damage)
Threat: Attacker gains access to server
Attacker can see:
ββ Phone number β Public Key mapping
ββ Group metadata (names, member list - encrypted)
ββ Encrypted message blobs (can't decrypt)
ββ Presence status (online/offline)
ββ Timestamps (not meaningful without content)
Attacker CANNOT see:
ββ Message content (Noise E2E encrypted)
ββ File contents (encrypted before upload)
ββ Voice/video (WebRTC encrypted)
ββ Contact list (stored only on device)
ββ Long-term keys (never sent to server)
Result: β Content safe, metadata leaks only
Mitigation:
ββ Regular backups
ββ Monitoring/alerting
ββ Encrypted database backups
ββ Regular security audits
ββ Open-source code (anyone can audit)
What they can see:
ββ You connected to messenger.example.com
ββ Traffic volume (how much data)
ββ Frequency of messages (timing correlation)
ββ IP addresses of communication parties
ββ DNS queries
What they CANNOT see:
ββ Message content (E2E encrypted)
ββ Who you're talking to (if using Tor/VPN)
ββ File contents
ββ Metadata (if properly stripped)
Mitigation (User's responsibility):
ββ Use VPN/Tor for IP anonymity
ββ Avoid patterns (don't message at predictable times)
ββ Disable traffic analysis
iOS:
ββ Identity Keys: Stored in Secure Enclave
β ββ Encrypted, hardware-backed, can't export
ββ Session Keys: Stored in Keychain
β ββ Protected with device passcode
ββ Database: Encrypted with SQLCipher (AES-256)
Android:
ββ Identity Keys: Stored in AndroidKeyStore
β ββ Hardware-backed if available, SW fallback
ββ Session Keys: Stored in EncryptedSharedPreferences
β ββ AES-256 by default
ββ Database: Encrypted with SQLCipher (AES-256)
Local Attacker (physical device access):
ββ If device unlocked: Can access all data
β ββ Mitigation: Use strong passcode + biometric
ββ If device locked: Secure Enclave/Keystore protects keys
ββ Without passcode: Forensic extraction possible
ββ Mitigation: Factory reset or key rotation
Remote Attacker (compromised app):
ββ Can access decrypted data in memory
ββ Can intercept new messages
ββ Mitigation: Code review + reproducible builds
Malicious OS:
ββ Can theoretically intercept anything
ββ Mitigation: Keep OS updated + careful app permissions
1. Generation
ββ On-device only
ββ Using OS's secure random
ββ Keys never leave device at creation
2. Upload (Public Keys Only)
ββ Identity Public Key β Server (on registration)
ββ Prekeys β Server (100 at a time)
ββ Signed with Identity Private Key
ββ Verification by recipients
3. Storage
ββ Private Keys: Never leave device
ββ Session Keys: Encrypted local storage
ββ Backups: Optional encrypted cloud backup (user choice)
4. Usage
ββ Ephemeral keys: Generated per-session, deleted after use
ββ Chain keys: Ratcheted forward every message
ββ Message keys: Used once, discarded
5. Rotation
ββ Automatic: Ephemeral keys (every message)
ββ Periodic: Session keys (every 100 messages)
ββ Manual: Identity keys (user-initiated)
ββ Revocation: Lost device (mark old keys untrusted)
6. Deletion
ββ Explicit: User deletes contact
ββ Automatic: Archived after 30 days inactivity
ββ Secure Erase: Use TRIM command (SSDs)
User A wants to verify User B:
1. Both users see 256-bit fingerprints:
FP_B = BLAKE2b(identity_public_key_b, 32 bytes)
Display as: 4FD7-8E2A-91C3-45B6-...
2. Verify through trusted channel:
ββ In-person meeting
ββ Phone call
ββ Video call
ββ Other messaging app
3. If match: Mark as "Trusted"
ββ Future messages have β badge
ββ Warning if key changes
ββ Require re-verification for new device
4. If mismatch: Possible MITM!
ββ DO NOT continue conversation
ββ Contact user through other channel
ββ Investigate compromise
Alice sends first message:
1. Generate ephemeral key: ek_a
2. Compute commitment: H(ek_a) = BLAKE2b(ek_a)
3. Send in plaintext (commitment)
4. Send in ciphertext (ephemeral key)
ββ Only after verifying receipt
5. Bob verifies:
ββ Decrypts ciphertext β ek_a'
ββ Computes H(ek_a')
ββ Compares with commitment
Result: Commitment binding ensures key can't be changed
β Confidentiality: E2E encryption ensures only intended recipient reads message β Integrity: AEAD authentication prevents tampering β Authentication: Key fingerprints + signatures verify identity β Perfect Forward Secrecy: Old messages safe if session keys compromised β Break-in Recovery: Future messages safe after key rotation β Replay Protection: Monotonically increasing message counter β Reordering Detection: Nonce mismatch fails decryption
π« Quantum Resistance: Uses only classical crypto (Curve25519) ββ Upgrade path: Post-quantum key encapsulation available
π« Deniability: Perfect message deniability not guaranteed ββ Design decision: Sacrifice deniability for authentication
π« Anonymity: Communication patterns visible to network observer ββ Mitigation: Use Tor/VPN for IP anonymity (user's choice)
| Threat | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Eavesdropping | High | Critical | E2E + TLS encryption |
| MITM | Medium | Critical | Key verification + signatures |
| Server Compromise | Low | High | No message content stored |
| Device Theft | Medium | High | Device encryption + biometric |
| Account Takeover | Medium | High | SMS verification + 2FA |
| Denial of Service | High | Medium | Rate limiting + backups |
| Social Engineering | High | Medium | Education + key verification |
| Quantum Attack | Very Low | Critical | Future upgrade available |
- Use libsodium for all crypto (no custom crypto!)
- Constant-time comparison for secrets
- Secure random from OS (not Math.random())
- Hash all passwords (Argon2id)
- Rate limiting on auth endpoints
- HTTPS/TLS only (no HTTP)
- Certificate pinning on mobile apps
- Regular security audits
- Dependency scanning for vulnerabilities
- Keep dependencies up-to-date
- Secure error messages (no internal details)
- Logging without sensitive data
- Backup encryption separate from app
- Account recovery mechanism
- Device registration tracking
- Signal Protocol Specification
- Noise Protocol Framework
- libsodium Documentation
- OWASP Mobile Security
- NIST Cryptographic Standards
Last Updated: 2024 Review Status: Ready for implementation Audit Status: Awaiting independent review