Latchat

Technical

How Latchat works

What the app actually does with your messages, what you can verify yourself, and what its current limitations are.

This page is a description, not a proof. Latchat's source code is not public, and nobody outside this project has audited it.

However, what a document like this can do is be specific enough to be held accountable. That's why every section below ends with an earnest look at what it does not establish.

1. Encryption

The claim: Messages are end-to-end encrypted, and our server holds no keys to decrypt them.

How it works

Before leaving your phone, every message is encrypted using XChaCha20-Poly1305 with a unique key generated just for that payload. Message IDs and routing fields are authenticated alongside it, so if a relay alters them, the cryptographic seal breaks and the message is instantly rejected.

These unique keys are derived from a group key that each member generates locally; no server ever holds it. Each sender maintains their own key chain, generating a new key for every message based on a sequence number. We derive the nonce from this sequence number instead of picking it at random. This ensures that if a nonce is reused, the sequence number is also reused, an anomaly that receiving phones will immediately spot and reject.

We use Ed25519 for identity, X25519 for key agreement, and BLAKE2b for key derivation and group MACs. Link-based invitations are encrypted under numbers stretched with Argon2id (using 256 MiB of memory and three passes), which is why processing them takes a phone several seconds. Everything is built on libsodium, strictly pinned to a single version with a build checksum. We use absolutely no hand-rolled cryptography.

We deliberately avoided using a double ratchet for groups. Because mesh messages can arrive out of order or hours late, a ratchet would end up hoarding keys for messages stuck on a phone three valleys away. Instead, one key per epoch unlocks any message from that timeframe, whenever it finally turns up. We are upfront about the tradeoff: there is no forward secrecy within a single epoch. To actually revoke someone's access, you have to remove them, which automatically re-keys the group.

In addition to being encrypted, every message is signed with the sender's private key. While the group encryption proves a message originated from within the group, the signature verifies exactly who sent it. Without it, any member could impersonate another, since everyone shares the same derived group key.

What you can check yourself

Point a network monitor at a phone running Latchat. You'll see it communicates with exactly two hosts: Google's push service and relay.latch.chat. Any data sent to the relay is fully encrypted.

Read the privacy policy. It clearly outlines what metadata the relay actually sees, because it isn't nothing. It logs the patterns of who talks to whom, when, and how often.

What this does not establish

  • While the relay only receives ciphertext, this doesn't prove the app isn't secretly storing a copy of your keys elsewhere. Only the source code can answer that, and our source is not public.
  • We haven't undergone a third-party audit. No one outside the project has reviewed the code.
  • A digital signature only proves who sent a message, not whether the contents are true. Group members can still lie, and cryptography can't fix human behavior.
  • Because there is no forward secrecy within an epoch, an attacker who extracts an epoch key from a compromised phone could decrypt any stored messages from that specific timeframe.

2. The paths: Internet first, Bluetooth as a fallback

The claim: The internet is our primary routing path, Bluetooth is the fallback, and neither guarantees delivery.

How it works

When connected to the internet, messages are routed through a small relay assigned to your group. This relay holds encrypted envelopes for a maximum of 24 hours. It wakes sleeping phones using an empty push notification, a ping that carries zero data other than "wake up, you have a message."

Without internet, phones in the group connect directly via Bluetooth, passing along any messages they are carrying. A message stops hopping through the mesh once it reaches everyone or expires after 24 hours.

We use both paths simultaneously, not sequentially. Because neither path guarantees delivery, the app will never display a 'delivered' status unless it can prove it.

What you can check yourself

This is easy to verify yourself. All you need is five minutes and two phones in the same Latchat group.

One. Put both phones in airplane mode, then turn only Bluetooth back on. Ensure there is no Wi-Fi or cellular signal. Send a message. It will arrive.

Two. Now, turn off Bluetooth and enable Wi-Fi on both devices. Send another message. It will also arrive.

Regarding Bluetooth range, we measured this outdoors on August 13, 2026, using two phones. We saw reliable message delivery at roughly 30 meters, while devices remained detectable up to 51–55 meters. We only advertise the 30-meter range on our homepage because merely detecting a device doesn't guarantee a successful data transfer.

What this does not establish

  • Our distance metrics come from a single outdoor test using one specific pair of phones with their screens on. We haven't established baseline measurements for indoor environments.
  • Neither routing path guarantees instant delivery. In testing, standard-priority push notifications to a sleeping Android phone took a median of 4,392 seconds to arrive. That’s over an hour of delay, and it is a hard measurement, not an estimate.
  • If users are completely disconnected (no internet and out of Bluetooth range), messages are held in a waiting state. They aren't lost, but they haven't been delivered. After 24 hours, the network drops them.

3. What is not inside the app

The claim: No analytics, no crash reporters, no ad SDKs, and no trackers. We make exactly one exception: Firebase Cloud Messaging (FCM). We use this strictly to wake sleeping devices, because Android simply doesn't offer a viable alternative.

What you can check yourself

An APK is just a ZIP archive. You can extract it and read the class names inside its .dex files. If an analytics SDK is present, you'll see its name in there.

We ran this exact scan on August 25, 2026, across all twenty DEX files in our debug build. We confirmed the complete absence of: crashlytics, FirebaseAnalytics, com.google.android.gms.measurement, firebase/perf, remoteconfig, and inappmessaging.

The only artifact containing the word "analytics" is firebase-measurement-connector. This is a stub containing four interfaces and one empty class, essentially an unplugged socket that Firebase Analytics would use if it were installed, and nothing on our end fills it.

If you run this scan yourself, verify that your analysis tools actually executed. Our first attempt falsely reported a clean result because a missing dependency caused the pipeline to fail silently. A test that fails to run looks exactly like a test that passes.

What this does not establish

  • You can only inspect a build you possess. Since Latchat isn't publicly released yet, there are currently no APKs available for you to download and verify.

What is missing

We're listing these outright so you don't have to uncover them yourself.

  • The source code is not public.
  • We have not undergone a third-party security audit.
  • The threat model is not published. It exists (drafted on September 7, 2026), but like our source code, it isn't available for public inspection. It outlines vulnerabilities that code changes alone cannot fix: the source isn't public, it hasn't been stress-tested by outside attackers, and the relay can still observe metadata.
  • The relay still sees metadata. It cannot read message content, but it can observe patterns in your contact network and activity. Full details are available in our privacy policy.