RoseChat

A simple, encrypted, multicast lan-chat.

RoseChat

RoseChat is a serverless, local area network (LAN) messaging application built with Flutter. It utilizes UDP Multicast for peer-to-peer discovery and communication, allowing users on the same network to chat without a central server or internet connection.

It is designed to be lightweight, private, and resilient, featuring distinct channels for public broadcasting and private direct messaging, all secured by AES-256 encryption.

RoseChat

Features

📡 Serverless Networking

  • UDP Multicast: Automatically discovers other users on the LAN by broadcasting presence packets to a specific IP group (default 224.0.0.1) on port 5000.
  • Zero Configuration: No servers to set up. Just launch the app, and it finds peers immediately.
  • Offline Capable: Works entirely on local Wi-Fi or Ethernet; no internet access required.

💬 Messaging

  • Public Broadcast Channel: A shared lobby visible to everyone on the same multicast group.
  • Direct Messaging (DM): Private, one-on-one chats. Messages are filtered at the application layer so only the intended recipient displays them.
  • Unread Indicators: A visual "red dot" notification appears next to users in the sidebar who have sent you new messages while you were away.

🔒 Security & Privacy

  • AES-256 Encryption: All traffic—including presence announcements and chat messages—is encrypted using a shared secret key.
  • Packet Envelope: Traffic is wrapped in an encrypted envelope. Sniffers (like Wireshark) only see randomized garbage data.
  • Network Isolation: Users can change their Multicast Group IP and Secret Key in settings. Peers must share both to communicate, effectively creating private "rooms" on the same LAN.

🎨 User Interface

  • Modern Dark UI: Built with a "Slate" color palette tailored for desktop and mobile.
  • Dynamic Sidebar: Lists discovered peers with real-time status updates and unread message tracking.
  • Customizable Profiles: Users can set their display name and randomize their avatar (generated via DiceBear seeds).

How It Works

1. Architecture

RoseChat follows a clean, component-based architecture:

  • main.dart: The application core. It manages the UI state, handles message routing (filtering public vs. private), and updates the peer list.
  • multicast_service.dart: The networking engine. It binds to the system's RawDatagramSocket, handles the joinMulticast logic, and performs the AES encryption/decryption pipeline.
  • models/: Defines the immutable data structures for Peer and ChatMessage.
  • sidebar/ & chatwindow/: Modular UI components.

2. The Protocol

RoseChat uses a custom JSON-over-UDP protocol. To ensure security, every packet is wrapped in an encrypted envelope.

The Envelope (On the Wire)

{
  "iv": "base64_initialization_vector",
  "d": "aes_encrypted_payload_string"
}

The Payload (Decrypted) Once the app receives a packet and successfully decrypts it with the matching key, the payload looks like this:

  • Message Packet:
    {
      "type": "msg",
      "group": "224.0.0.1",       // Ensures we don't process packets from other groups
      "senderId": "uuid-1234",    // Unique Instance ID
      "sender": "Alice",
      "seed": "avatar_seed",
      "content": "Hello World!",
      "recipientId": "uuid-5678"  // null for Public Broadcast, UUID for DM
    }

3. Discovery & Filtering

  1. Binding: On startup, RoseChat binds to 0.0.0.0 (any IPv4) on port 5000 and joins the multicast group (e.g., 224.0.0.1).
  2. Announcing: It broadcasts a "Presence" packet to the group.
  3. Listening: It listens for incoming UDP datagrams.
  4. Filtering Pipeline:
    • Decrypt: Attempt to decrypt d using the current Secret Key. If it fails, drop the packet.
    • Group Check: Does json['group'] match our current group? If no, drop it.
    • Peer Check: Is senderId new? If yes, add to the Sidebar.
    • Message Routing: Is recipientId null (Public)? Or does it match my ID (Private)? If neither, ignore it.

Usage Guide

Installation

  1. Clone the repository.
  2. Install dependencies:
    flutter pub get
  3. Run the application:
    flutter run
    (Note: To test locally, you can run flutter run -d windows (or macos/linux) in two separate terminals to spawn two distinct windows).

Controls

  • Send Message: Type in the box and press Enter. Use Shift + Enter for a new line.
  • Switch Channels: Click "Public Broadcast" or a user's name in the sidebar to switch views.
  • Profile Settings: Click the Gear icon next to your name (bottom left) to change your Display Name or Avatar.
  • Network Settings: Click the Ethernet/Gear icon next to the Multicast IP (sidebar) to change the Group IP or Encryption Key.
    • Reset: Inside Network Settings, click "Reset Defaults" to return to 224.0.0.1 and the default key.