Most encrypted messengers protect message contents, but their account systems still know that an account exists. They may also retain information needed for contact discovery, delivery, recovery, and abuse prevention.
I wanted to explore a different tradeoff: what does an iPhone messenger look like when the service does not maintain a central account database or message server?
That experiment became PrivaMesh, an open-source messenger for iPhone.
Start with the threat model
The design has three primary goals:
- Protect message content from the transport layer.
- Minimize the metadata available to a central service operator.
- Keep identity, contacts, conversation state, and chat history at the endpoints.
It is equally important to state what those goals do not mean. PrivaMesh does not claim perfect anonymity. A compromised phone can expose local data. A sufficiently capable network observer may correlate traffic. Protocol and implementation bugs remain possible. Metadata-resistant design reduces signals; it does not make them disappear.
Removing the account server
PrivaMesh does not ask for a phone number or email address. Identity is created on the device, and there is no central PrivaMesh account record that maps a conventional identifier to that identity.
This changes the trust boundary. A central service is no longer responsible for mapping a phone number or email address to a user. It also cannot provide the same contact-discovery and account-recovery conveniences as a conventional messenger.
“Serverless” does not mean packets never touch network infrastructure. A public, decentralized transport still carries data between participants. The distinction is that PrivaMesh does not operate a central account or message service, and the transport receives ciphertext rather than plaintext.
The simplified data path is:
iPhone A → key agreement and authenticated encryption → public transport carrying ciphertext → iPhone B
Identity and conversation state stay at the two endpoints.
Local identity and storage
Identity and messaging keys are generated on the iPhone and stored in the iOS Keychain. Contacts and chat history remain on the device.
Keeping this state local reduces the user data available to a service operator. It also moves more responsibility to the endpoint. Device security matters, and reinstalling the app or losing a phone has different consequences from losing access to a messenger that can restore an account from a central service.
The Keychain is part of the security boundary, not a magic shield. If the endpoint is compromised while it can access its keys and plaintext, transport encryption cannot fix that.
Establishing and evolving keys
The protocol uses X3DH to establish the initial shared secret between two participants. After a session is established, Double Ratchet evolves the conversation keys so that the same static message key is not reused throughout a chat.
Payloads are protected with AES-256-GCM. This provides authenticated encryption: a recipient can detect modification as well as decrypt the message with the correct key.
These primitives are established building blocks. The interesting engineering work is integrating them into a system where there is no central PrivaMesh account database coordinating user identity.
Several implementation details matter here:
- Ratchet state must be persisted safely and updated consistently.
- Receiving messages out of order must not silently corrupt the session.
- Key material should have the smallest practical lifetime and scope.
- Failures should be explicit instead of falling back to an insecure mode.
Publishing the source is useful, but it is not equivalent to a professional cryptographic audit. The implementation still deserves hostile review.
Reducing metadata leakage
End-to-end encryption does not automatically hide metadata. Message size, timing, frequency, and repeated identifiers can reveal patterns even when the content is unreadable.
PrivaMesh experiments with three mitigations:
- Fixed-size padding reduces information exposed by ciphertext length.
- One-time addresses reduce the usefulness of repeated transport identifiers.
- Optional cover traffic adds traffic that is not a user message, making simple timing analysis less reliable.
Each mitigation has a cost. Padding uses more bandwidth. One-time addressing makes routing and state management more complex. Cover traffic consumes battery and network resources, which is especially relevant on a phone.
These measures are meant to reduce specific signals. They should not be interpreted as proof that an observer cannot correlate participants.
Transport is not identity
A useful architectural distinction is between the messaging protocol and the transport.
The transport moves encrypted payloads. It should not be treated as the source of user identity or trusted with plaintext. Identity, ratchet state, contacts, and message keys remain at the endpoints.
This separation makes the transport less trusted, but it does not make it irrelevant. Delivery latency and availability still depend on it. A transport failure can prevent communication even if it cannot read the message.
It also means contact exchange is less convenient than searching a centralized directory. That is a deliberate tradeoff: reducing centralized knowledge removes some of the convenience that centralized knowledge enables.
The tradeoffs in one view
| Design choice | Privacy benefit | Practical cost |
|---|---|---|
| No phone or email signup | No central mapping from a conventional identifier to an account | Contact exchange is less convenient |
| Local keys and history | Less user state available to an operator | Device loss and recovery are harder |
| Public transport carries ciphertext | Transport does not need message plaintext | Delivery still depends on transport availability |
| Padding and cover traffic | Less obvious size and timing signals | More bandwidth, battery use, and complexity |
| One-time addresses | Fewer stable transport identifiers | More routing and state-management work |
This is not a claim that every product should make these choices. It is an attempt to make the costs visible instead of hiding them behind the word “private.”
What I would like reviewed
The app is available now, and the implementation is public:
The areas where feedback would be most useful are:
- The threat model and assumptions around transport observers
- Protocol integration and ratchet-state handling
- Key recovery and device-loss behavior
- Whether onboarding communicates the tradeoffs clearly
- Real-world delivery, latency, battery use, and usability
I am especially interested in criticism from people who have worked on secure messaging, iOS key storage, or metadata-resistant systems. What would you want audited or changed before trusting this design?
Disclosure: I used AI assistance to help organize and edit this article. I reviewed the technical claims against the PrivaMesh implementation and project documentation before publishing.
Top comments (0)