# What Encryption Protocol Is Used for End-to-End Encryption in the BLE Mesh Transport?

> Discover the end-to-end encryption protocol in BLE mesh transport. Learn how Noise_XX and XChaCha20-Poly1305 secure your communications.

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

---

**The BLE mesh transport in bitchat implements end-to-end encryption using the Noise Protocol framework (specifically the Noise_XX handshake pattern) combined with XChaCha20-Poly1305 authenticated encryption.**

The **permissionlesstech/bitchat** repository provides a peer-to-peer messaging system that utilizes Bluetooth Low Energy (BLE) mesh networking for decentralized communication. Understanding what encryption protocol is used for end-to-end encryption in the BLE mesh transport reveals a sophisticated cryptographic architecture designed to ensure both confidentiality and authentication while maintaining forward secrecy.

## Noise Protocol Framework with XChaCha20-Poly1305

The bitchat implementation relies on the **Noise Protocol framework** rather than traditional TLS or custom cryptographic implementations. This choice provides formal security guarantees and resistance to common cryptographic pitfalls.

According to the source code in [`bitchat/BLENoisePayloadFactory.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/BLENoisePayloadFactory.swift) and the architectural documentation in [`docs/BLE-ARCHITECTURE-V3.md`](https://github.com/permissionlesstech/bitchat/blob/main/docs/BLE-ARCHITECTURE-V3.md), the system employs a layered approach:

- **Noise_XX handshake pattern** for Initial key exchange and session establishment
- **X25519 (Curve25519)** elliptic curve keys for ephemeral and static key exchange
- **XChaCha20-Poly1305** as the AEAD (Authenticated Encryption with Associated Data) construction for payload encryption

### The Noise_XX Handshake Pattern

The **Noise_XX** pattern is a specific handshake sequence within the Noise Protocol framework that provides strong identity hiding and forward secrecy. In `bitchat/BLEService+LinkLayerCentralRole.swift`, each peer generates an **X25519** key pair during session initialization.

The handshake process establishes a shared secret between communicating devices without transmitting the actual keys over the air. This ensures that even if session keys are compromised in the future, past communications remain secure—a property known as **forward secrecy**.

### Payload Encryption with XChaCha20-Poly1305

Once the Noise_XX handshake completes, the derived shared secret feeds into the **XChaCha20-Poly1305** AEAD construction. This modern cryptographic primitive provides both confidentiality (encryption) and integrity (authentication) in a single operation.

The encrypted payloads are then wrapped in outer packets signed with the peer's **Ed25519** identity key. This dual-layer approach ensures that while the Ed25519 signature provides sender authentication and non-repudiation, the Noise-derived encryption guarantees that the payload content remains confidential even if the signature keys are later compromised.

## Implementation in the Bitchat Codebase

The encryption logic is distributed across several key files in the repository, demonstrating a clean separation between the cryptographic primitives and the BLE transport layer.

### Key Exchange and Session Establishment

In `bitchat/BLEService+LinkLayerCentralRole.swift`, the BLE transport layer integrates with the `BLENoisePayloadFactory` to handle the cryptographic handshake. When establishing a connection, the service initializes the Noise_XX handshake state and manages the transition from plaintext to encrypted communication.

The test suite in [`bitchatTests/Services/NoiseEncryptionServiceTests.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchatTests/Services/NoiseEncryptionServiceTests.swift) validates the correctness of this implementation, ensuring that payloads encrypted by one peer can be successfully decrypted by the intended recipient using the shared secrets derived during the Noise handshake.

### Packet Signing and Identity Verification

While the Noise protocol handles session encryption, bitchat adds an additional layer of security using **Ed25519** signatures. Each outer packet carries a self-signature from the sender's identity key, binding the Noise payload to the correct sender.

This architecture means that the BLE transport itself cannot inspect the interior payload—it merely routes the encrypted blob. Only the intended recipient possessing the correct session keys can decrypt the content using the `BLENoisePayloadFactory` decryption methods.

## Practical Usage Example

The following Swift code demonstrates how the bitchat SDK handles encrypted file transfers over the BLE mesh transport:

```swift
// Create a Noise payload for a private file (used by the BLE mesh)
let fileData = try Data(contentsOf: fileURL)
let encryptedPayload = try BLENoisePayloadFactory.privateFile(fileData)

// Send the encrypted payload through the BLE service
bleService.send(payload: encryptedPayload, to: destinationPeer)

// On the receiving side the payload is decrypted automatically
let receivedPayload = try bleService.receive()
let plainFile = try BLENoisePayloadFactory.decrypt(receivedPayload)

```

The `BLENoisePayloadFactory.privateFile(_:)` method constructs a payload using the Noise_XX handshake parameters and encrypts the content with XChaCha20-Poly1305. The `bleService.send(payload:to:)` method then passes this encrypted blob to the BLE transport layer without exposing the plaintext content to the mesh intermediaries.

Upon receipt, `BLENoisePayloadFactory.decrypt(_:)` reverses the Noise handshake process to derive the same shared secret and decrypt the payload, returning the original file data only to the authorized recipient.

## Summary

- **bitchat** uses the **Noise Protocol framework** with the **Noise_XX** handshake pattern for BLE mesh encryption.
- **X25519 (Curve25519)** provides the underlying elliptic curve cryptography for key exchange.
- **XChaCha20-Poly1305** handles authenticated encryption of message payloads.
- The implementation spans [`bitchat/BLENoicePayloadFactory.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/BLENoicePayloadFactory.swift), `bitchat/BLEService+LinkLayerCentralRole.swift`, and related test files.
- **Ed25519** signatures provide outer packet authentication while Noise provides end-to-end confidentiality.
- This architecture ensures forward secrecy and prevents the BLE transport layer from accessing message contents.

## Frequently Asked Questions

### What specific Noise handshake pattern does bitchat use for BLE mesh?

The implementation uses the **Noise_XX** handshake pattern, as documented in [`docs/BLE-ARCHITECTURE-V3.md`](https://github.com/permissionlesstech/bitchat/blob/main/docs/BLE-ARCHITECTURE-V3.md) and implemented in the `BLENoisePayloadFactory`. This pattern provides mutual authentication and strong forward secrecy while allowing both parties to transmit static public keys in encrypted form, protecting against passive surveillance of the BLE mesh network.

### How does bitchat achieve forward secrecy in BLE communications?

Forward secrecy is achieved through the **X25519** ephemeral key exchange during the Noise_XX handshake. Each session generates new ephemeral keys that are not stored after the session ends. Even if an attacker compromises the long-term Ed25519 identity keys at a later date, they cannot decrypt past communications because the session keys were ephemeral and the shared secrets were never transmitted over the network.

### What is the difference between the Ed25519 signing and the Noise encryption?

The **Ed25519** signature provides cryptographic proof of sender identity and ensures message integrity at the packet level, functioning as an outer wrapper. The **Noise Protocol** encryption provides the inner end-to-end confidentiality, ensuring that only the intended recipient can read the payload contents. This separation allows the BLE mesh to verify packet authenticity without accessing the encrypted message content, creating a zero-trust transport layer.

### Where is the encryption logic implemented in the bitchat source code?

The core encryption logic resides in [`bitchat/BLENoisePayloadFactory.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/BLENoisePayloadFactory.swift), while the BLE transport integration appears in `bitchat/BLEService+LinkLayerCentralRole.swift`. The architectural rationale is documented in [`docs/BLE-ARCHITECTURE-V3.md`](https://github.com/permissionlesstech/bitchat/blob/main/docs/BLE-ARCHITECTURE-V3.md), and comprehensive test coverage exists in [`bitchatTests/Services/NoiseEncryptionServiceTests.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchatTests/Services/NoiseEncryptionServiceTests.swift).