Back to Blog
zero-knowledgeprivacyencryptionE2Eend-to-endsubpoenametadataserver architecture

Zero-Knowledge Messaging: What the NoChat Server Sees (and What It Doesn't)

A concrete breakdown of what data NoChat's server stores, what it cannot read, and what 'zero-knowledge' actually means in practice — including what happens under a legal subpoena.

Taylor MohneyJune 1, 20265 min read

"Zero-knowledge" is a term that gets thrown around a lot in privacy marketing. Here's exactly what it means for NoChat, with concrete specifics rather than vague reassurances.

What the server stores

When you send a message on NoChat, the server receives and stores:

DataWhat's storedCan we read it?
Message contentAES-256-GCM ciphertextNo — we don't have the keys
File attachmentsEncrypted blob reference (key in S3)No — encrypted client-side
Message metadataSender UUID, conversation UUID, timestampYes, but no names
Your identityA UUID and your public keyWe see the public key, not the private key
Your email (if provided)Hashed or stored encryptedYes, if you chose email signup
Your phone numberNot stored unless you optionally added oneDepends on signup method
Your IP addressNot stored — discarded at ingressN/A
Your contact graphWho you've messaged, whenUUIDs only, no names

For anonymous / guest users: the server stores a UUID and a public key only. There's no email, no name, no phone number.

The encryption in detail

Every message goes through this path:

  1. On your device: Your client generates a session key for this conversation through ECDH key exchange with the recipient's public key (+ ML-KEM-1024 hybrid for DMs)
  2. Encryption: The plaintext message is encrypted with AES-256-GCM using that session key. The result is an opaque ciphertext blob.
  3. In transit: Only the ciphertext reaches our servers. Plaintext never leaves your device.
  4. At rest: We store the ciphertext in PostgreSQL. The session key that could decrypt it exists only on the sender and recipient's devices.

The server acts as an encrypted relay and storage system. It can confirm that a message exists between two conversation participants and when it was sent. It cannot tell you what the message says.

What happens under a legal subpoena

This is the most important test of any "zero-knowledge" claim.

If we receive a valid legal order for user data, we can produce:

  • Account UUIDs
  • Timestamps of messages (when they were sent, not what they say)
  • Conversation membership (which UUIDs participated in which conversations)
  • Public keys (mathematically useless without the corresponding private keys)
  • Email addresses (if the user provided one at signup)

We cannot produce:

  • Message content — we genuinely don't have it
  • Call recordings — calls are peer-to-peer, not routed through us
  • File contents — files are encrypted client-side before upload
  • Private keys — they never leave the user's device

This isn't a legal limitation or a policy we could change under pressure. It's an architectural fact: the keys don't exist on our servers. There's nothing to hand over even if we wanted to.

What "zero-knowledge" doesn't mean

Zero-knowledge doesn't mean we know nothing. We know:

  • That your account exists (UUID)
  • Approximately when you're active (connection timestamps)
  • Which conversations you participate in (conversation membership)
  • That you sent messages, and how many (without reading them)

This is significantly less than most messaging apps (which see your contacts, groups, message content, and often phone numbers), but it's not nothing.

We don't claim to be completely metadata-free. Sealed sender — which would hide the sender's identity from the server — is in our codebase but not yet integrated. It's on the roadmap.

Why "zero-knowledge" requires trust-but-verify

You shouldn't take our word for it. The code is open source (MIT). The encryption stack is in packages/web/src/crypto/ and packages/server/internal/crypto/. You can verify that:

  • Keys are generated client-side (not server-side)
  • The server never receives plaintext
  • Our server code stores only ciphertext

We haven't had a formal third-party cryptographic audit. "Open source" and "audited" are different things, and we only claim the former. We'd welcome an independent audit.

What makes this different from Signal, WhatsApp, or iMessage

All four (NoChat, Signal, WhatsApp, iMessage) provide end-to-end encryption for message content. The differences are in what metadata each service collects and what signup requires:

Phone number requiredMetadata collectedPQ encryption
SignalYesMinimalYes (PQXDH)
WhatsAppYesExtensive (Meta)Yes
iMessageYes (or Apple ID)Moderate (Apple)Yes (PQ3)
NoChatNoMinimal (UUIDs, timestamps)Yes (DMs, ML-KEM-1024)

The no-phone-number angle matters beyond convenience: your phone number is linked to your real-world identity in ways your email isn't, and phone number requirements create a friction barrier to anonymous use that NoChat specifically removes.


The code is at github.com/kindlyrobotics/nochat. Security reports go to security@nochat.io.


Share this article:

Related Articles

Ready for Private Conversations?

NoChat uses post-quantum encryption so your messages are unreadable by anyone — including us. No phone number required.

Start Messaging Privately