# What Encryption Methods Does Bit Chat Use? A Deep Dive into Noise Protocol Security

> Explore Bit Chat's encryption methods: Noise Protocol, Curve25519, ChaCha20-Poly1305, and SHA-256. Secure your peer-to-peer messages with advanced cryptography.

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

---

**Bit Chat uses the Noise Protocol Framework with the XX handshake pattern, combining Curve25519 key exchange, ChaCha20-Poly1305 authenticated encryption, and SHA-256 hashing for secure peer-to-peer messaging.**

All cryptographic operations in the **bitchat** repository are built on a self-contained implementation of the [Noise Protocol Framework](https://noiseprotocol.org/), a modern standard for lightweight, secure transport protocols. The code explicitly avoids legacy TLS complexity while providing mutual authentication, forward secrecy, and replay protection out of the box.

## Core Encryption Methods in Bit Chat

### Noise Protocol: The Foundation

The [[`bitchat/Noise/NoiseProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseProtocol.swift)](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseProtocol.swift) file defines the complete cryptographic suite. Lines 26-29 declare the exact algorithms used across all connections:

- **Handshake pattern**: `XX` — mutual authentication where both peers exchange and verify static public keys
- **Diffie-Hellman**: `Curve25519` (X25519) for elliptic-curve key agreement
- **Symmetric cipher**: `ChaCha20-Poly1305` AEAD for encrypted payloads
- **Hash function**: `SHA-256` for key derivation and handshake transcript hashing

This selection mirrors the `Noise_XX_25519_ChaChaPoly_SHA256` protocol name from the Noise specification.

### Key Exchange with Curve25519

The **Curve25519** implementation provides 128-bit security with constant-time operations. Static keys are loaded through a `KeychainManager` abstraction, ensuring private keys never leave secure enclaves unnecessarily.

### Authenticated Encryption

**ChaCha20-Poly1305** handles all bulk data encryption after handshake completion. This AEAD construction provides:
- Confidentiality via ChaCha20 stream cipher
- Integrity via Poly1305 message authentication code
- 96-bit nonces with automatic tracking

## Security Features in the Implementation

### Mutual Authentication

The `XX` pattern requires both initiator and responder to present valid static keys. Each peer verifies the other's identity through explicit static-key signatures embedded in the handshake transcript.

### Forward Secrecy

Every session derives unique ephemeral keys through multiple X25519 operations. Even if long-term static keys are compromised later, past session keys cannot be reconstructed.

### Replay Attack Protection

Lines 33-36 of [`NoiseProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseProtocol.swift) implement a **1024-message sliding-window nonce tracker** in `NoiseCipherState`. This rejects:
- Duplicated messages with reused nonces
- Messages with nonces outside the valid window
- Out-of-order messages beyond recovery range

### Timing Attack Mitigation

The implementation uses constant-time comparisons for public-key validation, eliminating side-channel leaks during handshake verification.

## Extended Algorithm: XChaCha20-Poly1305 for Nostr

For interoperability with [Nostr](https://nostr.com) protocol messages, Bit Chat includes [[`XChaCha20Poly1305Compat.swift`](https://github.com/permissionlesstech/bitchat/blob/main/XChaCha20Poly1305Compat.swift)](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Nostr/XChaCha20Poly1305Compat.swift). This variant uses:

- **192-bit nonces** instead of 96-bit, enabling safer random nonce generation
- Same ChaCha20-Poly1305 core construction
- Dedicated compatibility layer keeping Nostr traffic isolated from Noise sessions

## Code Examples: Working with Bit Chat Encryption

### Establishing a Noise Handshake (XX Pattern)

```swift
import BitFoundation
import BitLogger
import CryptoKit
import bitchat

// Initialize with your long-term static key from secure storage
let staticKey = Curve25519.KeyAgreement.PrivateKey()

// Create handshake state as initiator
let handshake = try NoiseHandshakeState(
    role: .initiator,
    pattern: .XX,
    keychain: myKeychain,
    localStaticKey: staticKey,
    remoteStaticKey: nil,      // discovered during handshake
    prologue: Data()           // optional domain separation
)

// Send first message containing ephemeral public key
let msg1 = try handshake.writeMessage()
// Transmit msg1, receive msg2, then complete authentication
let payload = try handshake.readMessage(msg2)

```

### Encrypting and Decrypting Application Data

```swift
// Extract cipher states after handshake completion
let (sendCipher, receiveCipher, _) = try handshake.getTransportCiphers(
    useExtractedNonce: false
)

// Encrypt outbound message
let plaintext = "Secure message".data(using: .utf8)!
let ciphertext = try sendCipher.encrypt(plaintext: plaintext)

// Decrypt inbound message on peer
let recovered = try receiveCipher.decrypt(ciphertext: ciphertext)
print(String(data: recovered, encoding: .utf8)!)   // "Secure message"

```

### Using Nostr-Compatible XChaCha20-Poly1305

```swift
import bitchat.Nostr

let secretKey = SymmetricKey(size: .bits256)
let nonce = try XChaCha20Poly1305Compat.Nonce()
let message = Data("Nostr event payload".utf8)

// Seal with 192-bit nonce
let sealed = try XChaCha20Poly1305Compat.seal(
    message, 
    using: secretKey, 
    nonce: nonce
)

// Verify and open
let opened = try XChaCha20Poly1305Compat.open(
    sealed, 
    using: secretKey, 
    nonce: nonce
)

```

## Key Source Files for Encryption

| File | Purpose |
|------|---------|
| [[`bitchat/Noise/NoiseProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseProtocol.swift)](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseProtocol.swift) | Algorithm definitions, constants, and `NoiseCipherState` with replay protection |
| [[`bitchat/Noise/NoiseHandshakeState.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseHandshakeState.swift)](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseHandshakeState.swift) | Handshake orchestration, key mixing, and transport cipher export |
| [[`bitchat/Noise/NoiseCipherState.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseCipherState.swift)](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Noise/NoiseProtocol.swift#L28-L31) | Symmetric encryption operations and nonce management |
| [[`bitchat/Nostr/XChaCha20Poly1305Compat.swift`](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Nostr/XChaCha20Poly1305Compat.swift)](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Nostr/XChaCha20Poly1305Compat.swift) | Extended-nonce AEAD for Nostr protocol compatibility |

## Summary

- Bit Chat implements **Noise_XX_25519_ChaChaPoly_SHA256** for all peer-to-peer encryption
- **Curve25519** provides the elliptic-curve foundation for key agreement
- **ChaCha20-Poly1305** AEAD secures all application data with integrated authentication
- **SHA-256** hashes drive the symmetric key derivation function
- A **1024-message sliding window** prevents replay attacks without external state
- **XChaCha20-Poly1305** extends compatibility to Nostr's 192-bit nonce requirements
- Constant-time operations protect against timing side-channels throughout

## Frequently Asked Questions

### Does Bit Chat use TLS or SSL for encryption?

No. Bit Chat deliberately avoids TLS in favor of the Noise Protocol Framework. Noise provides equivalent security guarantees with substantially less code complexity, making it ideal for resource-constrained peer-to-peer messaging over Bluetooth Low Energy and similar transports.

### What happens if a message nonce is reused?

The `NoiseCipherState` sliding-window tracker in [`NoiseProtocol.swift`](https://github.com/permissionlesstech/bitchat/blob/main/NoiseProtocol.swift) rejects any nonce it has seen before or that falls outside the valid 1024-message window. This prevents decryption and terminates the suspicious session, protecting against replay and forgery attacks.

### Can Bit Chat encrypt messages for offline delivery?

The core Noise implementation requires interactive key agreement. However, the `XChaCha20Poly1305Compat` module supports static-key encryption suitable for Nostr's relay-based store-and-forward model, using randomly generated 192-bit nonces safe for single-use encryption without handshake.