Why not use push notifications instead of polling?

Push notifications are a privacy compromise we don't want to make. The two planet-scale push pipes — Apple Push Notification Service (APNs) for iOS and Firebase Cloud Messaging (FCM) for Android — only work if our server hands every outgoing message to Apple or Google first, addressed to a per-device token that we'd have to keep in our database alongside the user identity. That single design decision would force us to learn, store, and reveal a long list of things we deliberately don't know today: which of our users are on iPhones and which are on Android, the device-level identifier those vendors use to track them across every app they've ever installed, and the precise timing and frequency of every conversation each user is part of. Even with the message body fully encrypted, the metadata trail — this user, this token, at this minute, woken by a message from someone — is exactly the surveillance signal that's most useful to anyone with subpoena power or a court order to compel Apple and Google.

The EFF has spent years documenting how this design has already been used against journalists, activists, and ordinary users by federal and foreign governments alike, because push metadata sits in two of the largest centralized aggregation points on the internet and law enforcement has learned exactly how to ask for it. Long-polling has none of these properties: the client opens an authenticated connection directly to our server when it wants new messages, the connection is end-to-end encrypted and short-lived, no third party ever sees that the conversation happened, and no per-device token tying a real-world identity to a vendor account ever leaves the user's phone. We pay a small battery cost for that guarantee, and we think it's worth it — the entire reason this server exists is to keep the metadata you don't want shared from being shared.

What does the server actually know about me?

Very little, by design. The server stores two SQLite tables: a Principals row per user containing a random hex user id, your auth token (and a hashed copy of it for at-rest defence), and the type of principal (user or group); and a Messages queue holding pending notifications whose payload bodies are opaque encrypted blobs. There is no phone number, no email address, no display name (your display name lives only inside the encrypted payload, where the server can't read it), no contact list, no device push token, no IP geolocation, and no link between your user id and any real-world identifier you didn't deliberately share inside an encrypted message.

Your user id is generated on our side as a random 64-bit hex string when you register — we don't ask you for it and you don't pick it, which means it can't accidentally match a username you use elsewhere. The only network metadata the server briefly handles is the IP address of the open polling connection (used to route the response back and then immediately forgotten), and a per-user action-rate counter that lives in memory and is discarded when the process restarts. The full set of fields the server can observe is published in the API reference; if a field isn't in the schema there, the server doesn't see it.

What happens if your server is seized or subpoenaed?

A seizure of the server — or a court order compelling us to hand over its contents — would yield two SQLite files and a short-lived log. The user.db file contains random user ids and authentication tokens (themselves rotated to hashed form at rest). The msg.db file contains any messages that happen to be sitting in the delivery queue at that exact moment, addressed to recipient user ids, with the message bodies being base64 ciphertext that we cannot decrypt because we don't hold the keys. Old messages are deleted on a janitor schedule, so the queue is small even at the worst time.

What that seizure would not reveal: the plaintext content of any message, the display names of any users, the social graph of who-talks-to-whom across conversations (group fan-out is keyed on group ids, not member-pair lists), phone numbers, email addresses, real names, IP histories, or push tokens that could be cross-referenced with Apple or Google records. We can't be compelled to produce what we don't have. Compare this with the trove a comparable subpoena against a phone-number-based chat service would surface — this difference is the whole reason for the design.

Why don't you ask for a phone number or email when I sign up?

Because every chat app that does ask for one becomes a phone book that can be subpoenaed, leaked, or cross-referenced with other breaches. A phone number ties your account to a billing identity, a SIM-card registration, and an OS-level push token; an email address ties it to whatever surveillance footprint that email already has across the rest of the internet. Once we've collected either, we can't ever truthfully claim not to know who you are. So we don't collect either. Your account is a random hex id allocated by our server, nothing else.

The price is a different friend-add flow. Instead of typing in a phone number, you exchange a QR code (or an invite link) with the person you want to talk to, which carries the public half of a Diffie-Hellman handshake. That code never touches our address book because there isn't one. The trade-off is real: onboarding takes one extra step versus a phone-number lookup, and there's no "find me by my email" path if you forget your friend's user id. We think the ability to look someone up by their phone number is the original sin of modern messaging — this is the smaller cost.

Is the code open source? Has the cryptography been audited?

Yes to open source. The reference Java client (which the desktop, Android and iOS ports all derive from) lives at github.com/Secchats-tech/ChatJavaUI, including the wire-format model classes, the Diffie-Hellman + AES-256-GCM encryption layer, and the polling state machine. The server's wire contract is published as the JSON API reference — everything another implementation needs to interoperate is documented, and other groups have built independent backends from it (see our blog post on one-shot server generation from the spec for an example).

On the audit question, we owe a more honest answer than most products give. The cryptographic primitives we use are off-the-shelf and individually well-studied (AES-256-GCM, ECDH, PBKDF2-HMAC-SHA256), but the protocol composition itself has not been independently reviewed by a third-party security firm. We'd welcome such a review and we'd publish the findings. In the meantime: the source is small, the wire format is documented, and the protocol is approachable enough to be reviewed by an interested reader in a long afternoon. If you find something wrong with it, please open an issue on the GitHub repo above.

How is Secure Chats different from Signal, WhatsApp, Telegram, or iMessage?

The headline difference is the identifier. WhatsApp and Signal use your phone number, iMessage uses your Apple ID, and Telegram uses both plus a username. We use a random hex string allocated server-side, with no link to anything else about you. That single change propagates through everything: there's no address book lookup, no contact-discovery hash exchange, no "find me on this app via my phone number" path, and no SIM-swap attack surface against your account.

Other apps each have real strengths we don't try to dispute. Signal's protocol is independently audited and widely cryptanalysed; WhatsApp has billions of users and the network effect that comes with that; iMessage is invisibly integrated into the Apple device experience; Telegram has feature breadth (cloud sync, public channels) that we don't aim for. What we offer specifically is the smallest practical metadata footprint of any of them: no phone number stored, no contact graph reconstructed, no push tokens registered with Apple or Google, no cloud message backup, and a server-side database that surrenders close to nothing under legal process (see the seizure question above). If that's the trade you're looking for, we built this for you. If you need the things one of the others does better, use that one — we won't be insulted.

What happens if I lose my phone or get a new one?

Two paths: with a backup you made in advance, or without.

With a backup. SecChats includes an on-device backup feature — Settings → Back up essential data. It writes a single .scb file containing your user id, your friends list, and your group memberships, encrypted under a password you choose (minimum 12 characters, AES-256-GCM with PBKDF2-HMAC-SHA256 at 600 000 iterations). Save the file wherever you like — Files, AirDrop to another device, email to yourself, a USB stick. Nothing goes to any cloud unless you personally put it there. On the new phone, install SecChats, open the file, enter the password, and choose Restore from backup. Your account, friends, and group keys land intact. The format is byte-for-byte compatible across iOS and Android — back up on one, restore on the other. Messages are not in the backup; they stay only on whichever device they were originally delivered to.

Without a backup. You start over: new install, new randomly-allocated user id, new keys, fresh slate. Your old conversations stay on whichever devices they were already on (and become unreadable on the lost phone unless someone has its passcode). To continue talking with the people you knew before, each of them needs to add you again via a fresh QR-code exchange, which establishes new Diffie-Hellman channels with your new identity.

We deliberately don't offer an automatic cloud backup. The reason every other chat app has "restore from iCloud" or "restore from Google Drive" is that they hold a credential that can decrypt your history off a cloud blob — which means there's a credential to compel from Apple or Google, and a backup whose contents inherit the cloud provider's threat model. We don't want to be a party to that. The .scb file is entirely under your control: your password, your storage location, no third party involved. If you forget the password, no one — including us — can recover the file.

How do group chats work cryptographically?

A group has a single symmetric AES-256 key, generated by whoever creates the group. To invite someone in, the creator (or a member with invite rights) encrypts that group key using the existing one-to-one Diffie-Hellman channel they already share with the invitee — the same channel that's used for direct messages between them — and posts the encrypted bundle to the server. The invitee's client unwraps it using its half of the DH secret, stores the group key locally, and is now able to decrypt every group message addressed to that group id. Group messages themselves are AES-256-GCM ciphertexts against that shared key, posted under the group id; the server fans them out to everyone who's polling that group.

Two honest caveats. First, the server can observe that user X polls group Y — it has to, in order to route the wake-up — so the membership graph isn't cryptographically hidden from the server even though the content is. Second, removing a member doesn't automatically rotate the group key: a removed member who kept a copy of the key could still decrypt new messages they later obtained ciphertext for. Industry-standard fixes for both (sender keys with explicit rotation, MLS-style epochs) are areas we'd like to evolve toward, and the source is open if you want to help.

Why does the app feel slower at startup, or use more battery than WhatsApp?

Both effects are the direct consequence of not using push notifications (see the first question above). When you open the app cold, the client has to open a fresh long-poll connection to our server before it can show you new messages, because nothing was woken up in the background to receive them on your behalf. On a cold start that handshake adds maybe a second of latency before your inbox refreshes — small in absolute terms, but noticeable compared to an app where the OS already shoved the latest message into a banner before you tapped the icon.

The battery cost is similarly modest but real: maintaining one open TCP connection per active conversation isn't free, and reconnecting every few minutes burns slightly more radio time than passively waiting for an APNs/FCM wake-up. Modern OS power-management actually handles long-poll connections reasonably well, and our connection idle-timeout is tuned to balance battery against latency, so the difference shouldn't be dramatic on any phone made in the last few years. It is, however, the price of the privacy properties from the first question on this page. If you don't want to pay that price, there are other excellent chat apps you can use — this one is built for the people who do.