Complete documentation of the CommiLink Protocol (CMLK)
Hybrid, multi-transport, E2EE (end-to-end encryption) protocol with support for relay, store-and-forward/DTN, rooms, and tombstones.
- Overview\
- CMLK Differentiators\
- Architecture and Flows\
- Messages and Specification\
- Reference Implementation
- E2EE Handshakes and Key Derivation\
- Rooms / Groups\
- ACKs and Tombstones\
- Persistence and Store-and-Forward\
- Security, Limitations, and Next Steps\
- License / Contributions
The CommiLink Protocol (CMLK) is a decentralized communication protocol that:
- Supports peer-to-peer (1:1) and group (rooms) communication.\
- Is adaptive and prepared for multiple transports: WebSocket, QUIC, BLE, LoRa, SMS.\
- Ensures end-to-end encryption using Curve25519 and symmetric key derivation.\
- Allows relay / store-and-forward for offline or intermittent devices.\
- Includes capability tokens, tombstones, and optional persistence for message control and revocation.
This repository provides an MVP:
- Simple WebSocket relay (
server.js)\ - Node.js CLI client (
client.js)
The relay does not access encrypted message contents, only routes and temporarily stores them.
Feature Description
Multi-transport Works over WebSocket, BLE, LoRa, QUIC, SMS. E2EE End-to-end encrypted messages (Curve25519 + symmetric key). Decentralized identity DID based on Ed25519. Rooms Group rooms with optional decryption key. Store-and-forward Relay stores messages for offline devices. Tombstones Revocation of old or compromised messages. ACKs Delivery confirmation, store update.
flowchart LR
A[Client A] -->|HELLO| R[Relay]
R --> B[Client B]
B -->|ACCEPT| R
R --> A
A -->|ENC encrypted message| R
R --> B
flowchart LR
A[Client A] -->|HELLO| R[Relay]
B[Client B] -->|HELLO| R
C[Client C] -->|HELLO| R
A -->|ENC room| R
B -->|ENC received| D[Local decryption with groupKey]
C -->|ENC received| D
- Client: generates DID, box key (Curve25519), connects and sends HELLO.\
- Relay: routes messages, temporarily stores them, sends backlog to new room subscribers.\
- Rooms: logical channels with optional group key.
- CBOR (
cbor-xin Node.js) --- compact and efficient.
Type Description
HELLO Starts contact, sends DID and public key for symmetric key derivation.
ACCEPT Accepts connection, sends peer's public key.
ENC Encrypted message (1:1 or room).
SUBSCRIBE Requests room backlog.
ACK Confirms message receipt (mid).
{
"type": "HELLO",
"from": "did:cmlk:ed25519:BASE64PUB",
"pub": "BASE64BOXPK",
"name": "Alice"
}{
"type": "ACCEPT",
"from": "did:cmlk:ed25519:BASE64PUB",
"to": "did:cmlk:ed25519:BASE64PUB",
"pub": "BASE64BOXPK",
"name": "Bob"
}{
"type": "ENC",
"from": "did:cmlk:ed25519:BASE64PUB",
"to": "did:cmlk:ed25519:BASE64PUB",
"nonce": "BASE64",
"data": "BASE64_CIPHERTEXT",
"mid": "timestamp-random",
"ts": 1690000000000
}{
"type": "ENC",
"from": "did:cmlk:ed25519:BASE64PUB",
"room": "room-abc",
"nonce": "BASE64",
"data": "BASE64_CIPHERTEXT",
"mid": "timestamp-random",
"ts": 1690000000000
}{
"type": "TOMBSTONE",
"from": "did:cmlk:ed25519:BASE64PUB",
"target_mid": "timestamp-random",
"ts": 1690000000000
}npm install ws cbor-x libsodium-wrappers readline- Manages client connections.\
- Store-and-forward by DID and by rooms.\
- Optional persistence in JSON file (
opp_store.json).\ - Forwards HELLO, ACCEPT, ENC, SUBSCRIBE, ACK, TOMBSTONE.
Run:
node server.jsRelay at ws://localhost:8080.
- Interactive CLI:
/join <room> [groupKey],/publish <room> <msg>,/send <peer> <msg>,/tombstone <mid>.\ - Derives symmetric key via
crypto_scalarmultwith peer's public key.\ - Encrypts messages with
crypto_secretbox_easy.\ - Receives and processes ACKs and TOMBSTONES.
Run:
node client.js Alice
node client.js Bob- Start relay:
node server.js- Open two terminals and run clients:
node client.js Alice
node client.js Bob- In client CLI:
/join room1 QWxhZGRpbjpPcGVuU2VzYW1l # optional Base64 groupKey
/publish room1 "Hello room!"
/send did:cmlk:ed25519:BASE64PUB "Message 1:1"
/tombstone 1690000000000-rnd
/peers
/listrooms
- Each peer generates:
sign keypair(Ed25519) for signing/verification.\box keypair(Curve25519) for symmetric key derivation.\
- HELLO sent with
pub.\ - Peer responds ACCEPT with its
pub.\ - Each peer computes:
shared = crypto_scalarmult(privateKey, peerPub)
symKey = crypto_generichash(32, shared)
symKeyis used for ENC message encryption/decryption.
Relay does not access encrypted content.
/join <room> [groupKeyBase64]joins a room.\/publish <room> <msg>publishes encrypted message with local groupKey.\- Relay stores room backlog and delivers to new subscribers.\
- Messages cannot be read without the correct groupKey.
- ACK: confirms receipt of
mid. Removes from relay and rooms queue.\ - TOMBSTONE: revokes message. Removes from pending and rooms. Propagates to all.
- Relay keeps
storein memory (byClientDid,rooms).\ - Can save/load from
opp_store.json.\ - Ensures delivery even if client was offline at send time.
- Relay must not access encrypted messages.\
- MVP limitations: WebSocket only, simple rooms.\
- Future: multi-transport, compression, capabilities, key revocation, IoT support.\
- Avoid exposing groupKeys outside the client.\
- Monitor backlog size in large rooms.
- MIT License.\
- Contributions via pull request or issues welcome.