How the security works, in plain words.
For the curious and the careful. The short version first, the technical detail after.
In plain words
Each of your devices makes its own pair of keys. When you send a message, your phone locks it with a fresh one-time key, then locks that key separately for every device in the chat. Only those devices can unlock it. Your phone also signs the message, so the reader's phone can tell it really came from you and was not changed on the way.
Technical summary
- Device keys: X25519 for key agreement and Ed25519 for signatures, generated on the device. Private keys are kept in the platform's secure storage and never uploaded.
- Messages: a random 256-bit content key encrypts the payload with ChaCha20-Poly1305. The content key is wrapped per recipient device using ephemeral X25519 + HKDF-SHA256. The envelope header (conversation, sender, device, message id, recipient list) is bound as associated data and signed with Ed25519.
- Files: encrypted on the device with a one-time key that travels inside the encrypted message. The server stores only ciphertext.
- Calls: WebRTC with DTLS-SRTP media. Offers, answers and ICE candidates travel in the same signed, encrypted envelopes, so the server cannot read or forge call set-up.
- Safety numbers: a fingerprint of both people's device keys. Compare in person to confirm nobody is in the middle. The app warns when a contact's keys change.
- Sign-in: scrypt password hashes, optional TOTP two-step verification with hashed recovery codes, lock-out after 5 failures, 12-hour idle and 24-hour maximum sessions, HttpOnly SameSite=Strict cookie. No SMS anywhere.
- Web: strict Content-Security-Policy, no third-party origins, frame embedding denied, HSTS in production.
- Android: FLAG_SECURE against screen capture, cleartext traffic disabled, app backup disabled.
What the server can see
Who talks to whom and when, message and file sizes, group names and membership, and that a call is being set up. Tasks, agreements and report drafts are stored on the server without end-to-end encryption. We list this openly on the Privacy page.
How we test
Every release passes an automated gate of more than 40 checks, including: an independent implementation of the protocol written in Python that must interoperate with the app; attacks on tampered, forged and replayed envelopes; a scan of the server database for plaintext; verification that expired disappearing messages are deleted along with their keys; and a browser audit that the web app makes zero third-party requests.
Known limits
- No forward secrecy ratchet yet: a stolen device key could decrypt past messages addressed to that device. A double-ratchet design is on the roadmap.
- Metadata is visible to the server, as described above.
- A web version's security depends on the browser and on the code our server delivers. That is one reason the web version is paused: the Google Play app comes first, and we will publish its signing certificate on the Get Namaskara page.
Report a security issue
Found a vulnerability? Please tell us privately before publishing, through Contact with “Security” in the subject. We will reply, fix and credit you if you wish. Please do not test against other people's accounts.