# How BitChat Implements Decentralized Peer-to-Peer Messaging: Bluetooth Mesh and Nostr Protocol

> Discover how BitChat implements decentralized peer-to-peer messaging using Bluetooth mesh for local offline chat and Nostr for global reach. Experience secure end-to-end encrypted communication.

- Repository: [permissionlesstech/bitchat](https://github.com/permissionlesstech/bitchat)
- Tags: deep-dive
- Published: 2026-08-22

---

**BitChat achieves decentralized peer-to-peer messaging by combining a Bluetooth mesh network for offline local communication with a Nostr relay network for global internet reach, using Noise encryption for links and a proprietary private-envelope format for end-to-end security.**

The `permissionlesstech/bitchat` repository implements a hybrid decentralized messaging system that operates entirely without centralized servers. By fusing two complementary transport layers—Bluetooth Low Energy (BLE) for offline peer-to-peer mesh networking and the Nostr protocol for online relay-based messaging—BitChat ensures message delivery whether devices are physically adjacent or continents apart. This architecture guarantees privacy through local cryptographic operations, with all encryption and signing performed on-device before transmission.

## Dual-Transport Architecture

BitChat’s core innovation lies in its seamless integration of two distinct communication layers:

- **Bluetooth Mesh (Offline)** – Enables direct, local-area communication without cellular or Wi-Fi connectivity
- **Nostr Relay Network (Online)** – Provides global reach through public Nostr relays when mesh connectivity is unavailable

The system automatically selects the optimal transport based on peer availability, falling back from BLE to Nostr transparently. Both layers share a common packet model and cryptographic foundation, ensuring consistent security regardless of transmission method.

## Bluetooth Mesh Transport Implementation

### Discovery and Link Management

The Bluetooth mesh functionality resides primarily in [`BLEService.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEService.swift), which manages device discovery and connection state. The `BLERadioController` scans for peers advertising the BitChat service UUID (`F47B5E2D‑…‑B5C`), supporting both central and peripheral roles simultaneously.

Each established link undergoes a **Noise-IK handshake** via `NoiseEncryptionService` to derive a unique shared secret for per-link encryption. The [`BLELinkAuthState.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLELinkAuthState.swift) file tracks the authentication state of each connection, ensuring forward secrecy for live traffic.

### Packet Structure and Framing

Messages transmitted over BLE use a compact binary protocol defined in [`BinaryProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BinaryProtocol.swift). The `BinaryProtocol.encode` function constructs packets with the following structure:

- Binary header (version, type, TTL, timestamp, flags, payload length)
- Sender and recipient IDs
- Optional route hops for multi-hop forwarding
- Optional compression preamble
- Payload data
- Optional signature

```swift
// Construct a BitChat packet for BLE transmission
let packet = BitchatPacket(
    type: MessageType.message.rawValue,
    senderID: myPeerID.data,
    recipientID: nil,  // nil indicates public broadcast
    timestamp: UInt64(Date().timeIntervalSince1970 * 1000),
    payload: Data(envelope.jsonString().utf8),
    signature: nil,
    ttl: TransportConfig.messageTTLDefault
)
let binary = BinaryProtocol.encode(packet)!  // Automatically padded for BLE MTU

```

### Fragmentation and Routing

Large payloads exceeding BLE MTU limits are automatically fragmented by `BLEOutboundFragmentTransferScheduler` and reassembled by `BLEFragmentHandler` using `BLEFragmentAssemblyBuffer`. The mesh supports multi-hop routing when the `hasRoute` flag is set—peers forward packets hop-by-hop until the TTL expires or the destination is reached.

Deduplication is handled by `MessageDeduplicator` and `BLESelfBroadcastTracker`, which prevent routing loops and duplicate processing across the mesh.

## Nostr Protocol and Private Envelopes

When internet connectivity is available or when BLE peers are unreachable, BitChat utilizes the Nostr relay network through [`NostrProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NostrProtocol.swift). Unlike standard Nostr DMs, BitChat implements a **proprietary private-envelope format** using three nested layers of encryption.

### The Three-Layer Envelope Structure

1. **Rumor** – An unsigned `NostrEvent` of kind 14 (DM) containing the plaintext message
2. **Seal** – The rumor encrypted with the recipient’s public key, then signed with the sender’s long-term Schnorr key via `createSeal`
3. **Gift-Wrap** – The sealed event encrypted with a freshly generated ephemeral Schnorr key and signed via `createGiftWrap`, producing a kind 1059 event

The resulting envelope uses the format `v2:` + Base64URL(nonce || ciphertext || tag) with HKDF-derived symmetric keys. This **BitChat-specific implementation** employs **XChaCha20-Poly1305** encryption and is not compatible with NIP-44.

### Encryption Implementation

All cryptographic operations occur locally; relays only receive opaque ciphertext. The `NostrProtocol` class handles both encryption and decryption:

```swift
// Build a BitChat private envelope manually
let envelope = try NostrProtocol.createPrivateMessage(
    content: "Secret hello",
    recipientPubkey: recipientPubkeyHex,
    senderIdentity: myNostrIdentity
)

```

Incoming Nostr events are decrypted via `decryptPrivateMessage`, extracting the inner rumor’s content for delivery to the UI.

## Automatic Transport Fallback

BitChat implements intelligent transport selection in `BLEService.sendMessage`. The system first attempts delivery via `sendPrivateMessage` over the Bluetooth mesh. If no mesh link is available, the message automatically wraps in a BitChat private envelope and publishes through `NostrRelayManager`.

This fallback mechanism ensures message delivery operates as a unified `ChatTransportEventCoordinator`, abstracting the underlying transport complexity from the user interface.

## Security Architecture

### Link-Level Security

**Noise Encryption** on BLE links guarantees confidentiality and forward secrecy for local traffic. Each peer-to-peer connection maintains independent session keys derived from the Noise-IK handshake.

### End-to-End Security

**BitChat Private Envelopes** provide end-to-end encryption over Nostr, with sender identity authenticated by the seal’s Schnorr signature. The use of ephemeral keys for gift-wrapping ensures that even Nostr relays cannot correlate sender and recipient metadata.

### Optional Compression

The `BinaryProtocol` implements optional zlib compression when payload size reduction is beneficial, storing the original length for safe decompression. This optimization applies only to BLE transport to maximize throughput over limited bandwidth.

## Summary

- **BitChat** combines **Bluetooth Mesh** (offline) and **Nostr relays** (online) for universal decentralized peer-to-peer messaging
- **BLE transport** uses [`BLEService.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEService.swift) with Noise-IK handshake, packet fragmentation, and multi-hop routing via [`BinaryProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BinaryProtocol.swift)
- **Nostr transport** implements a proprietary three-layer envelope (gift-wrap → seal → rumor) using **XChaCha20-Poly1305** encryption in [`NostrProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NostrProtocol.swift)
- **Automatic fallback** occurs when `BLEService.sendMessage` detects unavailable mesh peers, seamlessly switching to `NostrRelayManager`
- **End-to-end security** is enforced locally with per-link Noise encryption and ephemeral-key envelopes, ensuring relays and intermediaries process only opaque ciphertext

## Frequently Asked Questions

### How does BitChat work without internet connectivity?

BitChat utilizes a **Bluetooth mesh network** implemented in [`BLEService.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEService.swift) that operates independently of internet infrastructure. Devices discover each other via BLE advertising (service UUID `F47B5E2D‑…‑B5C`) and form multi-hop ad-hoc networks. Messages fragment automatically to handle BLE MTU limitations and route through intermediate peers using TTL-based forwarding, enabling communication in offline environments such as disaster zones or remote areas.

### What encryption algorithms does BitChat use?

BitChat employs **XChaCha20-Poly1305** for Nostr envelope encryption and **Noise-IK** for Bluetooth link encryption. The Nostr implementation uses HKDF for key derivation and Schnorr signatures for authentication. For BLE transport, the `NoiseEncryptionService` establishes per-session symmetric keys that provide forward secrecy, ensuring captured traffic cannot be decrypted even if long-term private keys are compromised later.

### How is BitChat's Nostr implementation different from standard Nostr DMs?

BitChat uses a **proprietary private-envelope format** that is incompatible with NIP-44. While standard Nostr DMs typically use simple encryption, BitChat implements a three-layer structure: an unsigned rumor (kind 14), a sealed envelope encrypted to the recipient, and a gift-wrapped event (kind 1059) encrypted with an ephemeral key. This architecture prevents relays from identifying conversation participants or accessing message content, whereas standard Nostr events may expose metadata.

### Can messages hop through multiple devices to reach distant recipients?

Yes, the **Bluetooth mesh** supports multi-hop routing when the `hasRoute` flag is set in the packet header. [`BLEService.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEService.swift) forwards packets hop-by-hop until they reach the destination or the TTL (time-to-live) counter expires. The `MessageDeduplicator` prevents infinite loops, while `BLEFragmentHandler` ensures large messages reassemble correctly across multiple hops. This topology allows messages to traverse distances beyond direct Bluetooth range by relaying through intermediate BitChat devices.