Messaging Mechanics

Group Shared Pad Architecture

Arithmetic lanes, slot assignment, full-mesh delivery, and background resync sweeps.

Overview

Wiltkey groups do not use key distribution centers. Instead, they expand a single, shared group keystream file (the Shared Pad) derived from a group seed. This pad is arithmetically partitioned into dedicated member lanes. Because the geometry of these lanes is fixed, clients can decrypt incoming group messages directly without routing through a central server or relying on a single group owner for message relaying.

Shared Pad Geometry

Info Lane (1MB) Slot 1: Member 1 Lane Slot 2: Member 2 Lane Slot 3: Member 3 Lane Offset 0 1MB 1MB + laneSize 1MB + 2*laneSize Lane Start Offset = 1MB + (slotIndex - 1) * laneSize

How it Works

  1. Fixed Partitioning: The group pad begins with a 1MB Info Lane (offset 0 to 1,048,576 bytes). This lane is reserved for metadata updates (profiles, membership, custom emojis). Offsets above 1MB are divided into member lanes of size laneSize. A member assigned to slotIndex writes exclusively to their lane starting at:
    laneStart = AppState.infoLaneSize + (slotIndex - 1) * laneSize
  2. BLE Slot Provisioning: The group owner registers new members in person over BLE. The owner fetches empty lanes from the group database, assigns the member the next available slotIndex, encrypts the group seed, and transmits it. The owner then broadcasts a group_info_update metadata frame over the WebSocket.
  3. Full-Mesh Envelope Delivery: The blind relay does not support multicast rooms. When sending a group message, the sender client writes to their lane, packages the envelope with the group ID, sender ID, slot index, and current offset, and sends the frame individually to each member of the group (full-mesh delivery).
  4. Gap Resync Sweeps: If a client goes offline, the server queue may drop messages from new members. To heal, on opening the chat or reconnecting, the client triggers `autoSyncGroup`. It requests a full resync range sweep (offset 0 to totalGroupSize) from all members via `chat_resync_request`. Peers query their local databases and send back a `chat_resync_response` containing the missing envelopes.

Key Files & Symbols

File Path Symbol Name Description
lib/core/state_groups.dart laneStartFor() Calculates the absolute keystream start offset for a slot index: 1MB + (slot - 1) * laneSize.
lib/core/state_groups.dart sendGroupMessage() Writes payload to active lane, increments pointer, and sends to all member hashes over WebSockets.
lib/core/state_groups.dart autoSyncGroup() Triggers automatic background resync sweeps from members.
lib/core/state_inbound.dart _handleGroupPayload() Decodes incoming group frames, performs gap checks, and updates lane write offsets.

Gotchas & Edge Cases

⚠️ MEMBER-TO-MEMBER METADATA DISCOVERY
Because members discover each other's profiles from lane headers or owner broadcasts, a member might receive a message from a peer before processing their profile. The client automatically constructs a placeholder profile "Member " and triggers a background metadata request to keep the UI from stalling.