Security & Encryption
Privacy in WallyMates isn't a single settings toggle — it's several independent layers of protection, each aimed at a different threat: server-side interception, a stolen phone, a man-in-the-middle attack during a call, syncing with the web version.
1:1 end-to-end encryption — Static X3DH
Private chats are encrypted with an in-house Static X3DH implementation (a triple Diffie-Hellman exchange over an identity key, a signed pre-key, and an ephemeral key — a simplified "SESAME-lite" multi-device session scheme inspired by Signal's approach) with AES-256-GCM. The encryption key is derived independently for every device pair — no Double Ratchet chain, no one-time pre-keys — a simpler model than the classic Signal protocol, but the server still never sees the content and never receives any of the keys.
- The private key stays on the device — The long-term identity key is generated locally and stored in protected hardware storage (Android Keystore) — it can't be extracted programmatically, even with root access.
- The server never sees the content — Only an encrypted data blob passes through the server — only the specific device it was encrypted for can decrypt a given message.
- A separate key per device pair — The key is derived independently for each "your device ↔ their device" pair — compromising one device doesn't expose conversations on all your other devices at once.
- Sync across your own devices — A sent message is additionally encrypted separately for each of your other devices (Android, Windows, web) — so it shows up in your history everywhere you're signed in, without ever sending the keys themselves through the server unencrypted.
- Secret chats — A separate chat mode with a self-destruct timer — once time runs out, the message is permanently deleted from both devices.
Group end-to-end encryption — Sender Key
Group chats can't be efficiently encrypted the same way as 1:1 — that would mean separately encrypting every message for every member. Instead, WallyMates uses a Sender Key scheme (v5): each member generates their own AES-256 key for a specific group and distributes it to the other members, individually encrypted through the same end-to-end encrypted channel used for regular private messages — the server sees only encrypted blobs, never the key itself. Group messages are then encrypted with fast AES-256-GCM using that shared key — no per-message key negotiation. The protocol is wire-compatible between Android and Windows — the exact same key-distribution and encryption scheme on both platforms.
More on groups and channels themselves — see the Groups & Channels page.
Call verification — MITM protection
Voice and video in a call are protected separately (see the Calls page), but one question remains: how do you know you're actually calling that person, and not someone who intercepted the connection? During a call, the app shows a "call fingerprint" — a sequence of 96 emoji computed from both parties' long-term identity keys. Compare it out loud, and if it matches, a swap is ruled out: an attacker would need the other party's private key, which not even the server has. It's the same idea as Signal's or WhatsApp's "safety number", and the algorithm is identical on Android and Windows.
More on calls themselves — see the Calls page.
Syncing with the web version
The web messenger (web.worldmates.club) is a special case: to show chat history in a browser, messages are additionally re-encrypted with a Web Sync key (AES-128) and stored encrypted in the database. This is a deliberate trade-off — without it, the web version simply couldn't show chat history at all.
Local storage
- Encrypted local database — The on-device database (message cache, drafts, attachments) is protected by SQLCipher — AES-256 encryption "at rest", separate from the E2EE of the conversation itself.
- EncryptedSharedPreferences — The user session and API access tokens are stored in Android's protected system storage, not in ordinary app settings.
- App integrity check — On launch, the app verifies its own digital signature (a SHA-256 of the signing certificate) — a modified or tampered APK build simply refuses to run.
What data reaches the WallyMates servers?
"Encrypted message storage" is not the same thing as "the server stores nothing." Here's an honest breakdown of what the server actually sees and what it doesn't, without claiming more than the current implementation actually guarantees.
What the server receives and stores
- Account and profile data — Username, display name, avatar, and the email or phone number used at registration.
- Routing metadata — Who's messaging whom and when (sender, recipient, group or channel, timestamp) — needed to deliver the message at all, and true of any messenger, not just WallyMates.
- Encrypted message blobs — The text of private and group chats is stored as ciphertext the server cannot decrypt (see the sections above for detail).
- A short plaintext reply snippet — When you reply to a message in an end-to-end encrypted chat, the sending app additionally sends the first ~100 characters of the original as a plaintext preview — the server can't decrypt the original itself to generate that preview, so the client provides it.
- Channel content — Channel posts are broadcast to a wide audience and aren't end-to-end encrypted (the same exception already mentioned in the web-sync section above).
- Technical data for notifications and sessions — Device tokens for push notifications, and the active-session list for the Account Protection section above.
What end-to-end encryption protects
The text of private chats (Static X3DH) and group chats (Sender Key) can't be decrypted by the server — none of the cipher versions currently used for new messages (cipher_version 6 for private chats, 4 for group chats) involve a server-held decryption key. 1:1 voice and video calls run directly between devices (WebRTC) — the app's servers never receive the call's media stream at all, only the signaling data needed to set up the connection.
For everyday messaging features — see the Messaging page.
Where the private key is stored
- Android — Android Keystore — hardware-backed protected storage that the key can't be extracted from programmatically, even with root access.
- Windows — The key is encrypted via Electron's safeStorage API (backed by OS-level protection — DPAPI on Windows) before being stored locally; the same mechanism, since version 2, also protects the on-disk offline message cache — before that, the Windows cache was stored unencrypted, which has since been fixed.
Both clients — on the Download page.
Account protection
- Two-factor authentication — An extra code when signing in from a new device — even if the password is compromised, getting into the account without the second factor isn't possible.
- Biometric unlock — Unlock the app with a fingerprint or face, without typing a password every time.
- Session management — A list of every device currently signed in, with the ability to instantly end any session remotely.
- Encrypted key backup — An optional encrypted backup of your encryption keys — lets you recover access to your conversations if you lose a device, without ever sending the keys themselves to the server unencrypted.
- Account deletion — The account is deactivated immediately and permanently deleted after 45 days — signing back in during that window restores it.