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.
- UDP Multicast: Automatically discovers other users on the LAN by broadcasting presence packets to a specific IP group (default
224.0.0.1) on port5000. - 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.
- 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.
- 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.
- 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).
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'sRawDatagramSocket, handles thejoinMulticastlogic, and performs the AES encryption/decryption pipeline.models/: Defines the immutable data structures forPeerandChatMessage.sidebar/&chatwindow/: Modular UI components.
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 }
- Binding: On startup, RoseChat binds to
0.0.0.0(any IPv4) on port5000and joins the multicast group (e.g.,224.0.0.1). - Announcing: It broadcasts a "Presence" packet to the group.
- Listening: It listens for incoming UDP datagrams.
- Filtering Pipeline:
- Decrypt: Attempt to decrypt
dusing 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
senderIdnew? If yes, add to the Sidebar. - Message Routing: Is
recipientIdnull (Public)? Or does it match my ID (Private)? If neither, ignore it.
- Decrypt: Attempt to decrypt
- Clone the repository.
- Install dependencies:
flutter pub get
- Run the application:
(Note: To test locally, you can run
flutter run
flutter run -d windows(or macos/linux) in two separate terminals to spawn two distinct windows).
- Send Message: Type in the box and press
Enter. UseShift + Enterfor 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.1and the default key.
- Reset: Inside Network Settings, click "Reset Defaults" to return to
