# Which Noise Pattern Is Used for Live Session Establishment in BitChat?

> Discover how BitChat establishes live sessions using the Noise XX pattern for secure real-time communication. Learn about its cryptographic components.

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

---

**BitChat establishes live (real-time) sessions using the `Noise_XX_25519_ChaChaPoly_SHA256` pattern, combining an XX handshake with Curve25519 key exchange, ChaCha20-Poly1305 authenticated encryption, and SHA-256 hashing.**

BitChat is an open-source, permissionless messaging application that implements end-to-end encryption for real-time communication. When establishing live sessions between peers, the application relies on a specific Noise protocol framework that ensures forward secrecy and authenticated encryption. Understanding which Noise pattern is used for live session establishment in BitChat requires examining the protocol definitions in the source code and the cryptographic handshake implementation.

## Noise_XX_25519_ChaChaPoly_SHA256 Pattern Breakdown

The `Noise_XX_25519_ChaChaPoly_SHA256` pattern provides the cryptographic foundation for BitChat's live messaging. This protocol definition consists of four distinct components that work together to secure peer-to-peer connections:

- **XX Handshake Pattern**: Enables mutual authentication where both parties transmit ephemeral and static public keys, providing forward secrecy and resistance to key-compromise impersonation.
- **Curve25519**: The elliptic curve Diffie-Hellman function used for key agreement, offering 128-bit security with compact 32-byte public keys.
- **ChaCha20-Poly1305**: The authenticated encryption with associated data (AEAD) cipher providing confidentiality and integrity for all messages exchanged after the handshake.
- **SHA-256**: The cryptographic hash function used throughout the Noise protocol for key derivation and mixing operations.

## Implementation in BitChat Source Code

The BitChat repository implements this specific Noise pattern across several core files in the `bitchat/Noise/` directory, with explicit verification in the test suite.

### Protocol Definition in NoiseProtocol.swift

In [`bitchat/Noise/NoiseProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseProtocol.swift), the application defines the protocol name builder that constructs the canonical Noise identifier. The source code implements enumerations for pattern, DH, cipher, and hash parameters, assembling them into the full protocol string `Noise_\(pattern)_\(dh)_\(cipher)_\(hash)`.

### Session Management in NoiseSessionManager.swift

The [`NoiseSessionManager.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseSessionManager.swift) file handles the creation and lookup of secure sessions. When initiating a live session, the manager instantiates a `SecureNoiseSession` object configured with the `.xx` pattern, `.curve25519` DH function, `.chachaPoly` cipher, and `.sha256` hash algorithm.

### Handshake Execution in SecureNoiseSession.swift

The [`SecureNoiseSession.swift`](https://github.com/permissionlesstech/bitchat/blob/main/SecureNoiseSession.swift) class implements the actual XX handshake logic for live sessions. This file manages the state machine transitions required for the two-message handshake pattern, handling the transmission of ephemeral and static public keys between peers to establish the shared secret.

### Test Verification in NoiseProtocolTests.swift

The test suite explicitly documents the pattern used. In [`bitchatTests/Noise/NoiseProtocolTests.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchatTests/Noise/NoiseProtocolTests.swift) at line 18, a comment states: “`Noise_XX_25519_ChaChaPoly_SHA256` — the exact protocol this app speaks”. Additionally, [`bitchatTests/Noise/NoiseTestVectors.json`](https://github.com/permissionlesstech/bitchat/blob/main/bitchatTests/Noise/NoiseTestVectors.json) at line 3 contains the `protocol_name` field set to `Noise_XX_25519_ChaChaPoly_SHA256`, providing machine-verifiable confirmation of the implementation.

## Establishing a Live Session: Swift Code Example

Below is the practical implementation pattern used in BitChat to create an encrypted live session using the Noise XX handshake:

```swift
import Bitchat

// 1️⃣ Create a Noise session manager (singleton in the app)
let sessionManager = NoiseSessionManager.shared

// 2️⃣ Obtain the peer's Noise static public key (32 bytes) – e.g. from a peer's profile
let peerPublicKey: Data = … // the 32-byte Curve25519 key

// 3️⃣ Start a live (XX) session with the peer
let liveSession = try sessionManager.createSecureSession(
    withPeerPublicKey: peerPublicKey,
    pattern: .xx,                     // selects Noise_XX_25519_ChaChaPoly_SHA256
    dh: .curve25519,
    cipher: .chachaPoly,
    hash: .sha256
)

// 4️⃣ Encrypt a message for the live session
let plaintext = "Hello, live chat!".data(using: .utf8)!
let encrypted = try liveSession.encrypt(plaintext)

// 5️⃣ Decrypt a received payload
let receivedPlaintext = try liveSession.decrypt(encrypted)

```

The `createSecureSession` method initiates the XX handshake pattern, performing the cryptographic key exchange before returning a session object capable of encrypting and decrypting messages using ChaCha20-Poly1305 with keys derived via SHA-256.

## Summary

- BitChat uses the **`Noise_XX_25519_ChaChaPoly_SHA256`** pattern exclusively for live session establishment.
- The XX handshake provides mutual authentication and forward secrecy for real-time peer-to-peer connections.
- Implementation spans [`NoiseProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseProtocol.swift), [`NoiseSessionManager.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseSessionManager.swift), and [`SecureNoiseSession.swift`](https://github.com/permissionlesstech/bitchat/blob/main/SecureNoiseSession.swift) in the source tree.
- Test vectors in [`NoiseProtocolTests.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseProtocolTests.swift) and [`NoiseTestVectors.json`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseTestVectors.json) explicitly confirm the protocol name.
- The combination of Curve25519, ChaCha20-Poly1305, and SHA-256 provides modern, high-performance cryptography suitable for mobile messaging.

## Frequently Asked Questions

### What components make up the Noise_XX_25519_ChaChaPoly_SHA256 pattern?

The pattern consists of the XX handshake (mutual key transmission), Curve25519 for elliptic curve Diffie-Hellman key exchange, ChaCha20-Poly1305 for authenticated encryption, and SHA-256 for cryptographic hashing. Together, these primitives provide forward secrecy, authentication, and data integrity for BitChat's live sessions.

### How does BitChat verify the Noise protocol implementation?

Verification occurs through unit tests in [`bitchatTests/Noise/NoiseProtocolTests.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchatTests/Noise/NoiseProtocolTests.swift) and conformance testing against [`NoiseTestVectors.json`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseTestVectors.json). These files contain the explicit protocol name and test vectors that validate the correctness of the cryptographic operations against known-good outputs.

### Why does BitChat use the XX handshake pattern for live sessions?

The XX pattern supports mutual authentication without prior knowledge of the other party's static key, making it ideal for decentralized, permissionless chat scenarios. Both peers transmit ephemeral and static keys, allowing each side to verify the other's identity while establishing forward-secret session keys.

### Where is the Noise protocol name constructed in the codebase?

The canonical protocol string is constructed in [`bitchat/Noise/NoiseProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseProtocol.swift), which implements a builder pattern assembling the components into the format `Noise_\(pattern)_\(dh)_\(cipher)_\(hash)`. This ensures consistency between the runtime implementation and the test vector specifications.