logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·01.11.26
← Back to news

How should group chats work in decentralized systems?

Original article
marindedic.com|10 points|5 comments|by Realman78|Jul 9, 2026

Architecting Group Chats for Decentralized Systems

Date: July 9, 2026 | Tags: #foss, #p2p, #networking

Introduction

I recently launched the first iteration of Kiyeovo, a desktop messaging application built on a decentralized P2P architecture. While building it, I spent an immense amount of time obsessing over the implementation of group chats.

Every architectural model I prototyped seemed to have a critical flaw. This is precisely where the "serverless" requirement becomes a significant hurdle. I eventually realized that a "perfect" solution doesn't exist; instead, I had to make specific tradeoffs to maintain a fully decentralized environment.


The "Server Advantage"

In traditional systems, a central server acts as the Trusted Authority. It provides definitive answers to critical questions: Who is currently in this group?

Even applications that utilize end-to-end encryption (E2EE) still rely on servers for coordination:

  • Signal: The server manages the group roster and handles message forwarding.
  • Matrix: The homeserver maintains the group state and determines the order of events.

These servers distribute the current state to new arrivals and block removed users from receiving further updates. While the content is encrypted, the coordination (membership, sequencing, and synchronization for offline users) is centralized.

In a P2P system, we lack:

  1. A definitive "source of truth" for the roster.
  2. A sequencer to order messages.
  3. A persistent 24/7 mailbox for offline peers.

Evaluating Alternative Approaches

I explored several existing methodologies before deciding on my own path.

Comparison of Considered Models

ApproachMechanismWhy it was Rejected
Coordinating ServerE2EE content, but central roster (Signal/Matrix)Violates the non-negotiable goal of total decentralization.
MLS / TreeKEMTree-based key management (RFC 9420)Requires a "Delivery Service"; overkill for groups ≤10\le 10≤10.
LeaderlessPeer-to-peer convergence via merge logicRace conditions; no global clock for event ordering.
Fixed MembershipStatic member sets (Briar-style)Too restrictive; lacks the ability to invite or kick.

Deep Dive into the Rejections

"The moment two people change membership simultaneously, peers can end up with diverging views of the group."

  • On Leaderless Systems: Without a trusted clock, answering a question like "Was User X kicked before or after they sent this message?" is nearly impossible. I considered a proof-of-work layer to solve this, but it felt too computationally expensive.
  • On MLS: While highly scalable for thousands of users, the complexity of implementing it over a DHT (Distributed Hash Table) with offline peers is immense.
  • On Fixed Groups: While I've noticed that my own groups rarely change membership, the lack of dynamic control was a dealbreaker.

The Kiyeovo Implementation

My goal was simple: No servers, trivial convergence.

1. Membership: The Single Creator Model

Every group is anchored by one Creator, identified by an Ed25519 public key.

  • Authority: Only the creator can modify the roster.
  • Process: If a member wishes to leave, they send a signed request, which the creator then applies to the state.
  • Benefit: This eliminates "split-brain" scenarios where two admins kick different people during a network partition.

The Tradeoff:

  • Simple convergence.
  • If the creator loses their identity or stays offline, the group remains functional for existing members, but no one can be added or removed.

2. Key Management: Epoch-Based Rotation

I implemented a system of Epochs (essentially group versions).

Each epoch utilizes a single random symmetric key: Group Key=Kepoch∈{0,1}256\text{Group Key} = K_{epoch} \in \{0, 1\}^{256}Group Key=Kepoch​∈{0,1}256

The creator distributes this 32-byte key by "sealing" it (using public-key encryption) for each individual member. These sealed keys are delivered via private inboxes.

// Conceptual Control Message
{
  "epoch": 5,
  "creator_sig": "0xabc123...",
  "sealed_keys": {
    "user_a": "encrypted_key_1",
    "user_b": "encrypted_key_2"
  }
}

Note: This means there is no continuous forward secrecy within a single stable epoch.

3. Rotation and Topic-Based Messaging

Whenever a member joins, leaves, or is kicked, a new epoch is triggered.

  • Forward Secrecy: New members only receive the key for the current epoch, preventing them from reading historical messages.
  • The Topic System: Real-time messages are sent to a specific "topic."
  • Security: The topic name is derived from the group key: Topic=Hash(Kepoch)\text{Topic} = \text{Hash}(K_{epoch})Topic=Hash(Kepoch​)

Because the topic name changes whenever the key rotates, a removed member cannot even identify the new topic to subscribe to, let alone decrypt the messages.

4. State Distribution

To ensure everyone stays in sync, group metadata (membership lists and per-sender sequence boundaries) is stored in the DHT as an append-only log.

Logic Flow Diagram

P2P Architecture Concept