Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/permissionlesstech/bitchat/llms.txt

Use this file to discover all available pages before exploring further.

Bitchat collects nothing. There are no analytics SDKs, no telemetry endpoints, no advertising identifiers, no project-operated messaging servers, and no account database with records of who you are. The project operates no backend infrastructure of any kind — the Bluetooth mesh is peer-to-peer and the internet path uses public third-party Nostr relays. The full source code is open; everything described here can be audited directly. That said, a design with no central servers does not automatically mean invisible. This page is honest about what is private, what is observable, and what the current design does not protect.

What’s Private

Private Message Content

All private messages, delivery acknowledgements, and read receipts are end-to-end encrypted with Noise XX (Curve25519 / ChaCha20-Poly1305 / SHA-256) over BLE. Relay nodes forward opaque ciphertext.

Courier Envelope Content

Courier envelopes are sealed with Noise X to the recipient’s static key. Couriers hold only opaque ciphertext and a rotating recipient tag — they cannot read content or identify the sender.

Nostr Sender Identity

In Bitchat’s double-sealed Nostr envelope format, the sender’s stable identity is inside authenticated ciphertext. Relays see only the recipient’s public key tag, event size, and timing.
The persistent private-message outbox is sealed at rest with ChaCha20-Poly1305 under a key stored in the iOS Keychain. Queued messages survive an app kill without ever touching disk as plaintext.

What’s Observable

This section documents known metadata that is visible to passive listeners or infrastructure operators. It is not an exhaustive risk assessment but a honest description of what the current protocol reveals.

On the Bluetooth Mesh

Every packet header carries an 8-byte sender peer ID. This ID does not rotate. It is the first 8 bytes of the SHA-256 fingerprint of the device’s Noise static key — a key that persists across sessions, reboots, and reinstalls that preserve the Keychain. A passive sniffer who records BLE advertisements can reliably identify and track a specific Bitchat device across time and physical location using only the peer ID.The peer ID changes only when the device’s identity is replaced by a panic wipe.
Bitchat broadcasts signed announce packets roughly every 4–30 seconds (with jitter). Each announce contains:
  • The device’s nickname (user-chosen, cleartext)
  • The Noise static public key (Curve25519, 32 bytes, cleartext)
  • The Ed25519 signing public key (cleartext)
  • Capability flags
These fields are transmitted in cleartext — anyone in radio range can read them. The announce is signed by the Ed25519 key, but the fields themselves are not encrypted. Because the Noise static key is stable, a receiver can link a device across sessions and across locations regardless of MAC address randomization at the BLE layer.
Each announce includes a bounded list of up to 10 short peer IDs of the device’s current direct BLE neighbors. This means a single passive sniffer who records announces can reconstruct the local mesh adjacency graph — who is physically near whom — without needing to be one of the participants.
Packets originate with TTL 7. Each relay decrements the TTL by 1. A receiver who observes a packet with TTL 7 knows it came directly from the originating device with no intermediate hops; TTL 6 means one hop away, and so on. Hop distance identifies the originator’s physical proximity to any given observer.
Nicknames, public channel messages, board posts, and announce metadata are broadcast to all devices in radio range and propagated through the mesh. This is an intentional design property, not a bug. Do not treat public channel participation as private.
MAC address randomization at the BLE layer — which iOS manages automatically — does not prevent device linkability in Bitchat. The application layer publishes stable identifiers (peer ID, static public keys) that sit above the MAC layer. A passive observer can recognise a specific Bitchat installation across sessions and locations based on these application-layer identifiers alone, even while the underlying MAC address is cycling.

On the Nostr Internet Path

Every Nostr envelope carries a p tag with the recipient’s public Nostr key. This tag is visible to every relay that stores or forwards the event. Relays also see event timing (randomized ±15 minutes from the real send time), event size, and your IP address unless Tor routing is enabled.
Location channels are scoped to geohash cells. Subscribing to or publishing in a geohash channel reveals to relays that you are in or interested in that approximate geographic area. Finer geohash precision means a smaller disclosed area.
Public events and encrypted envelopes may remain on Nostr relays according to each relay operator’s retention policy. The project does not operate relays and cannot remove data from third-party infrastructure.

What Bitchat Stores Locally

All persistent storage is included in the panic wipe. Data lives on your device only.
StoreContentsRetention
KeychainNoise static key, Ed25519 key, Nostr keys, group keys, outbox seal key, geohash seeds, install markerUntil rotated, removed by feature, or panic wipe
Encrypted outboxQueued outgoing private messages (ChaCha20-Poly1305 at rest)Until acknowledged, 8 resend attempts exhausted, or 24h
Courier envelopesOpaque sealed envelopes carried for other usersUntil handed off, evicted by quota, or 24h
Public gossip archiveSigned public mesh messages cached for syncUp to 6 hours
Public board postsBoard posts and deletion tombstonesUntil author-set expiry, max 7 days
Group stateNames, rosters, creator identity, key epochUntil leave/remove, panic wipe, or app removal
MediaAccepted images and voice notes (Application Support)7 days, or sooner by 100 MB quota eviction
Location stateGeohash bookmarks, teleport flags, display namesUntil removed, panic wipe, or app removal
Favorites and preferencesContacts, petnames, settings, read-receipt identifiersUntil removed, panic wipe, or app removal

Future Work on Privacy

The protocol design acknowledges several known gaps and lists them explicitly as future work:

Rotating On-Air Identity

Epoch-rotating peer IDs, with static-key disclosure moved inside the encrypted handshake. Mutual favorites would recognise each other through a tag derived from their shared secret, so presence stops being linkable across sessions and locations.

Padding for Non-Noise Packets

Extending payload-length padding to public messages, announces, and other currently-unpadded packet types. Also closing the edge case where a frame needing more than 255 bytes of padding is emitted unpadded.

Optional Neighbor List

Making the direct-neighbor ID list in announces optional, or restricting it to authenticated links, to reduce the local adjacency graph that a single passive sniffer can reconstruct.

Courier Forward Secrecy

A prekey-based scheme for courier envelopes that would provide forward secrecy for sealed offline mail, analogous to what the Noise XX handshake provides for live sessions.
To destroy all local identity state immediately — keys, messages, favorites, media, and all stored data — use the Panic Wipe. Triple-tap the logo.

Build docs developers (and LLMs) love