پرش به محتویات

Private Groups

Private groups enable encrypted group messaging with CRDT-synchronized membership.

Overview

Property Value
Encryption AES-256-GCM with shared group key
Membership 2P-Set CRDT (add/remove)
Invites ECIES-encrypted per-member
Max members Soft limit ~100 (practical)

Group Creation

sequenceDiagram
    participant Creator as Group Creator
    participant DB as Local Database
    participant DTN as DTN Layer

    Creator->>DB: Create group record
    Note over DB: groupId, name, key
    Creator->>DB: Add self as admin
    Creator->>DTN: Optionally announce (public only)

Group Record

Each group record contains: - groupId - Unique identifier (e.g., "group:team-chat") - shortId - 10-character hash for routing - displayName - Human-readable name - groupKey - AES-256 symmetric key (32 bytes) - adminPubKey - Creator's public key - createdAt - Creation timestamp - isPublic - Whether public discovery is enabled

Group Key

Each group has a 32-byte AES-256 key for message encryption, generated using SecureRandom.

Key Generation

When creating a group: 1. Generate 32 random bytes for the group key 2. Create group ID from the name 3. Compute short ID as base32 of first 6 bytes of SHA256(groupId)

Invitations

Inviting a member requires encrypting the group key to their public key using ECIES with XChaCha20-Poly1305.

Invite Flow

sequenceDiagram
    participant Admin as Admin
    participant Crypto as Crypto Layer
    participant DTN as DTN Layer
    participant Invitee as Invitee

    Admin->>Crypto: Encrypt invite for recipient
    Note over Crypto: ECIES: X25519 + XChaCha20
    Crypto-->>Admin: GroupInviteMsg
    Admin->>DTN: Send bundle (dst=invitee UID)
    DTN->>Invitee: Bundle arrives
    Invitee->>Crypto: Decrypt invite
    Crypto-->>Invitee: Group key + metadata
    Note over Invitee: Join group

GroupInviteMsg

Field Size Description
encryptedPayload Variable ECIES-encrypted invite
ephemeralPubKey 32 bytes X25519 ephemeral key
nonce 24 bytes XChaCha20 nonce

Encrypted Payload Contents

The invite payload contains: - Group ID and display name - The shared encryption key (32 bytes) - Admin public key - Invitation timestamp

Membership CRDT

Membership uses a 2P-Set CRDT (Two-Phase Set) for conflict-free synchronization.

2P-Set Structure

  • adds - Set of member entries that have been added
  • removes - Set of member entries that have been removed (tombstones)

Each member entry contains: - uid - Member's user ID - addedAt - Timestamp of addition - addedBy - Admin who added this member

Merge Operation

To merge two CRDT states: 1. Union all entries from both adds sets 2. Union all entries from both removes sets 3. Active members = adds - removes (remove trumps add)

Properties

Property Guarantee
Commutativity Order of merges doesn't matter
Associativity Grouping of merges doesn't matter
Idempotency Merging same state twice is safe
Convergence All replicas converge to same state

Membership Updates

After initial invite, membership changes use GroupUpdateMsg.

GroupUpdateMsg

Field Size Description
encryptedPayload Variable AES-GCM encrypted update
nonce 12 bytes AES-GCM nonce

The encrypted payload contains: - Action (ADD_MEMBER or REMOVE_MEMBER) - Target user UID - Admin signature - Timestamp

Update Flow

sequenceDiagram
    participant Admin as Admin
    participant Group as Group Members
    participant DTN as DTN Layer

    Admin->>Admin: Create update (add/remove)
    Admin->>Admin: Sign with admin key
    Admin->>Admin: Encrypt with group key
    Admin->>DTN: Send to group topic
    DTN->>Group: All members receive
    Group->>Group: Verify admin sig
    Group->>Group: Apply CRDT update

Message Encryption

Group messages use the shared symmetric key with AES-256-GCM: 1. Generate random 12-byte nonce 2. Encrypt plaintext with group key and nonce 3. Send ciphertext + nonce in bundle

Routing

Group messages are routed via interest-based filtering.

Interest Filter

Members subscribe to the group topic (SHA256 of groupId). When a bundle arrives with a matching topic, it is delivered.

Bundle Addressing

Group bundles use dstTopic instead of dstUser or dstNode, allowing them to reach all subscribers.

Public vs Private Groups

Aspect Private Public
Discovery Invite only GroupAnnounceMsg broadcast
Join Requires invite Self-join via announcement
Key distribution ECIES per-member In announcement (less secure)
Visibility Hidden Listed in discovery

Security Considerations

Forward Secrecy

  • Not supported for groups (shared key)
  • Compromise of key exposes all past messages

Member Removal

  • Remove from CRDT
  • Key is not rotated (design decision)
  • Removed member can still decrypt old messages

Admin Authority

  • Only admin can add/remove members
  • Admin signatures verified before applying changes

Next: Channels | Encryption