From 327fca9cb11268e0753a24af2e467d13598fbe93 Mon Sep 17 00:00:00 2001 From: jack <212554440+jackjackbits@users.noreply.github.com> Date: Sat, 2 Aug 2025 11:36:20 +0200 Subject: [PATCH] Remove cover traffic functionality (#389) - Remove cover traffic variables and timer - Remove cover traffic methods (startCoverTraffic, scheduleCoverTraffic, sendDummyMessage, generateDummyContent) - Remove cover traffic initialization in startSession() - Remove cover traffic check in handleReceivedPacket - Remove timer invalidation in reset() - Update README.md and AI_CONTEXT.md to remove cover traffic mentions Co-authored-by: jack --- AI_CONTEXT.md | 1 - README.md | 1 - bitchat/Services/BluetoothMeshService.swift | 100 -------------------- 3 files changed, 102 deletions(-) diff --git a/AI_CONTEXT.md b/AI_CONTEXT.md index fcb41a47..57ae9635 100644 --- a/AI_CONTEXT.md +++ b/AI_CONTEXT.md @@ -148,7 +148,6 @@ BitChat is a decentralized, peer-to-peer messaging application that works over B ### 4. Privacy Features - **Message Padding**: Obscures message length -- **Cover Traffic**: Optional dummy messages - **Timing Obfuscation**: Randomized delays - **Emergency Wipe**: Triple-tap to clear all data diff --git a/README.md b/README.md index 6a17d50a..4b2c3199 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ This project is released into the public domain. See the [LICENSE](LICENSE) file - **Decentralized Mesh Network**: Automatic peer discovery and multi-hop message relay over Bluetooth LE - **Privacy First**: No accounts, no phone numbers, no persistent identifiers -- **Cover Traffic**: Timing obfuscation and dummy messages for enhanced privacy - **Private Message End-to-End Encryption**: [Noise Protocol](http://noiseprotocol.org) - **Store & Forward**: Messages cached for offline peers and delivered when they reconnect - **IRC-Style Commands**: Familiar `/slap`, `/msg`, `/who` style interface diff --git a/bitchat/Services/BluetoothMeshService.swift b/bitchat/Services/BluetoothMeshService.swift index f3d22c76..0ad94957 100644 --- a/bitchat/Services/BluetoothMeshService.swift +++ b/bitchat/Services/BluetoothMeshService.swift @@ -638,13 +638,6 @@ class BluetoothMeshService: NSObject { // Noise session state tracking for lazy handshakes private var noiseSessionStates: [String: LazyHandshakeState] = [:] - // MARK: - Cover Traffic - - // Cover traffic for privacy - private var coverTrafficTimer: Timer? - private let coverTrafficPrefix = "☂DUMMY☂" // Prefix to identify dummy messages after decryption - private var lastCoverTrafficTime = Date() - // MARK: - Connection State // Connection state tracking @@ -1719,7 +1712,6 @@ class BluetoothMeshService: NSObject { // Invalidate other timers scanDutyCycleTimer?.invalidate() batteryMonitorTimer?.invalidate() - coverTrafficTimer?.invalidate() bloomFilterResetTimer?.invalidate() aggregationTimer?.invalidate() cleanupTimer?.invalidate() @@ -1963,14 +1955,6 @@ class BluetoothMeshService: NSObject { // Setup battery optimizer setupBatteryOptimizer() - - // Start cover traffic for privacy (disabled by default for now) - // TODO: Make this configurable in settings - let coverTrafficEnabled = true - if coverTrafficEnabled { - SecureLogger.log("Cover traffic enabled", category: SecureLogger.security, level: .info) - startCoverTraffic() - } } // MARK: - Consolidated Timer Management @@ -3668,11 +3652,6 @@ class BluetoothMeshService: NSObject { // Parse the message if let message = BitchatMessage.fromBinaryPayload(decryptedPayload) { - // Check if this is a dummy message for cover traffic - if message.content.hasPrefix(self.coverTrafficPrefix) { - return // Silently discard dummy messages - } - // Check if this is a favorite/unfavorite notification if message.content.hasPrefix("SYSTEM:FAVORITED") || message.content.hasPrefix("SYSTEM:UNFAVORITED") { let parts = message.content.split(separator: ":") @@ -6209,85 +6188,6 @@ extension BluetoothMeshService: CBPeripheralManagerDelegate { category: SecureLogger.session, level: .debug) } - // MARK: - Cover Traffic - - private func startCoverTraffic() { - // Start cover traffic with random interval - scheduleCoverTraffic() - } - - private func scheduleCoverTraffic() { - // Random interval between 30-120 seconds - let interval = TimeInterval.random(in: 30...120) - - coverTrafficTimer?.invalidate() - coverTrafficTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: false) { [weak self] _ in - self?.sendDummyMessage() - self?.scheduleCoverTraffic() // Schedule next dummy message - } - } - - private func sendDummyMessage() { - // Only send dummy messages if we have connected peers with established sessions - let peersWithSessions = getAllConnectedPeerIDs().filter { peerID in - return noiseService.hasEstablishedSession(with: peerID) - } - - guard !peersWithSessions.isEmpty else { - SecureLogger.log("Cover traffic: No peers with established sessions, skipping dummy message", - category: SecureLogger.security, level: .debug) - return - } - - // Skip if battery is low - if currentBatteryLevel < 0.2 { - SecureLogger.log("Cover traffic: Battery low, skipping dummy message", - category: SecureLogger.security, level: .debug) - return - } - - // Pick a random peer with an established session to send to - guard let randomPeer = peersWithSessions.randomElement() else { return } - - // Generate random dummy content - let dummyContent = generateDummyContent() - - SecureLogger.log("Cover traffic: Sending dummy message to \(randomPeer)", - category: SecureLogger.security, level: .info) - - // Send as a private message so it's encrypted - let recipientNickname = collectionsQueue.sync { - return self.peerSessions[randomPeer]?.nickname ?? "unknown" - } - - sendPrivateMessage(dummyContent, to: randomPeer, recipientNickname: recipientNickname) - } - - private func generateDummyContent() -> String { - // Generate realistic-looking dummy messages - let templates = [ - "hey", - "ok", - "got it", - "sure", - "sounds good", - "thanks", - "np", - "see you there", - "on my way", - "running late", - "be there soon", - "👍", - "✓", - "meeting at the usual spot", - "confirmed", - "roger that" - ] - - // Prefix with dummy marker (will be encrypted) - return coverTrafficPrefix + (templates.randomElement() ?? "ok") - } - private func updatePeerLastSeen(_ peerID: String) { peerLastSeenTimestamps.set(peerID, value: Date())