202 lines
9.9 KiB
ReStructuredText
202 lines
9.9 KiB
ReStructuredText
.. _worlds-most-secure-messaging-app-full-system-design:
|
||
|
||
====================================================================
|
||
World's Most Secure Messaging App – Full System Design Specification
|
||
====================================================================
|
||
|
||
**Codename**: Hydra Apocalypse Ratchet (Ultra Secret mode)
|
||
**Author**: JohnΞ (@j3g)
|
||
**Date**: February 18, 2026
|
||
**Version**: 1.0 – Complete implementation-ready specification
|
||
**Target**: Ephemeral-relay messaging app (messages exist only in RAM on relays)
|
||
|
||
Executive Summary
|
||
=================
|
||
|
||
This is the **complete, implementation-ready** end-to-end encryption system we finalized across our entire discussion.
|
||
|
||
- **Normal mode** (default for family/just-chat): fast hybrid PQ Double Ratchet.
|
||
- **Ultra Secret mode** (opt-in per group/chat): triple-compound ratchet with 16–24 diverse vetted ciphers, per-group secret, per-message sequence mutation, and massive combinatorial + multi-math hedge.
|
||
|
||
The relay is **completely stateless and ephemeral** — it only forwards blobs in RAM and drops them. Nothing persistent, no keys, no state.
|
||
|
||
All design goals from our conversation are met: survive secret breaks in any single primitive, per-group/per-message secret sequences, dependent one-way keys, strongest-first ordering, padding against distinguishers, vetted libs only, FS + PCS preserved, quantum diversity.
|
||
|
||
Why This Design
|
||
===============
|
||
|
||
- Nation-state can secretly weaken one major algorithm (AES, Kyber, McEliece, etc.).
|
||
- We force them to break **many independent lineages simultaneously** while guessing a secret per-group sequence that mutates per message.
|
||
- Ephemeral relays eliminate server-side storage attacks.
|
||
- Local storage keeps raw wire messages so history can be re-decrypted on demand.
|
||
|
||
Core Architecture
|
||
=================
|
||
|
||
- **Ephemeral Relays**: Pure RAM forwarders. Receive blob from sender, forward identical blob to each recipient, then discard.
|
||
- **Device Local Storage**: SQLite (or equivalent) encrypted at rest with device master key (separate from E2EE). Stores **raw wire messages** (ciphertext + metadata) directly.
|
||
- **Ratchet State**: Per-group, per-sender (sending + receiving chains) stored encrypted at rest.
|
||
- **Two Modes**:
|
||
- Normal: Hybrid PQ Double Ratchet (fast).
|
||
- Ultra Secret: Hydra Apocalypse Ratchet (inner PQ Double Ratchet + massive secret cascade + sequence mutation).
|
||
|
||
Wire Format (What IS and IS NOT Sent to the Relay)
|
||
===================================================
|
||
|
||
**IS sent over the wire to the relay (and forwarded identically to recipients)**:
|
||
|
||
- ``group_id`` (256-bit)
|
||
- ``sender_id`` (256-bit device/user identifier)
|
||
- ``sender_counter`` (64-bit monotonically increasing integer per sender per group)
|
||
- ``ratchet_public`` (optional KEM public key / DH public key when performing a DH/KEM ratchet step — ~1–2 KB)
|
||
- ``payload`` (the final E2EE ciphertext blob — see below)
|
||
- ``timestamp`` (for ordering/display, not security)
|
||
|
||
**IS NOT sent** (never on wire, never to relay):
|
||
- Any keys, seeds, sequence seeds, cascade permutations, inner keys, base_message_key, etc.
|
||
- Plaintext
|
||
- Any long-term secrets
|
||
|
||
The relay sees only routing metadata + opaque encrypted payload. It forwards the exact same blob to each member’s device (via push or long-poll). TLS/Noise is used for the device↔relay transport link, but that is **separate** from E2EE.
|
||
|
||
Normal Mode Ratchet (Detailed)
|
||
==============================
|
||
|
||
- Initial group setup: Hybrid KEM (X448 + Kyber-1024 + Classic McEliece 460896 round-robin) to establish per-sender root keys.
|
||
- Per sender per group: independent Double Ratchet (symmetric HKDF chain + hybrid KEM ratchet every 30–80 messages).
|
||
- Per message: derive base_message_key from current sending chain.
|
||
- AEAD: round-robin AES-256-GCM / ChaCha20-Poly1305 / Ascon-AEAD-128a using base_message_key.
|
||
- On receive: advance receiving chain using sender_counter and optional ratchet_public.
|
||
- FS/PCS: standard Double Ratchet deletion of old chain keys.
|
||
|
||
Ultra Secret Mode Ratchet (The Full Monster – Detailed)
|
||
=======================================================
|
||
|
||
**Per-group setup** (at group creation, threshold-shared):
|
||
- ``group_master_seed`` (512-bit)
|
||
|
||
**Per-sender initialization** (each member generates for itself and shares public parts):
|
||
- ``sending_root_key`` = HKDF(group_master_seed, "sender-root-" || sender_id)
|
||
- ``receiving_root_key`` (per other sender) = derived during first message exchange
|
||
|
||
**For every outgoing message (sender_counter)**:
|
||
|
||
1. Advance the **inner Double Ratchet** to produce ``base_message_key`` (256-bit).
|
||
2. Derive cascade material deterministically from base_message_key:
|
||
- ``seq_seed`` = KMAC256(base_message_key, b"seq-seed-" || group_id || sender_counter)
|
||
- ``cascade_permutation`` = deterministic_permutation_from_seed(seq_seed, pool_size=48–64, length=16–24)
|
||
3. Inner AEAD encrypt plaintext → inner_ct (triple AEAD with base_message_key).
|
||
4. Cascade encrypt inner_ct using the 16–24 layers (strongest first):
|
||
- Per-layer key = HKDF-Expand(base_message_key, b"layer-" || layer_index || group_id || sender_counter)
|
||
- Apply sequentially (encrypt outer-to-inner or as defined).
|
||
5. (Optional) Re-key the inner ratchet root with final cascade output for extra mixing.
|
||
6. Produce final payload = outer AEAD (Ascon or AES-GCM) on the cascade ciphertext for wire integrity.
|
||
|
||
**Sequence mutation** (Layer C): The seq_seed itself is derived fresh per sender_counter → every message has a completely different secret permutation.
|
||
|
||
**On receive** (using sender_id + sender_counter):
|
||
- Advance receiving Double Ratchet to derive the exact same ``base_message_key``.
|
||
- Re-derive seq_seed and cascade_permutation (deterministic).
|
||
- Decrypt cascade in reverse, then inner AEAD.
|
||
|
||
Local Storage – Exact Details
|
||
=============================
|
||
|
||
**What is stored directly from the wire** (raw, unchanged):
|
||
|
||
- Full received blob:
|
||
- group_id, sender_id, sender_counter, ratchet_public (if present), timestamp
|
||
- payload (the exact E2EE ciphertext received)
|
||
|
||
Stored in local DB table ``messages`` (encrypted at rest with device master key):
|
||
|
||
.. code-block:: sql
|
||
|
||
CREATE TABLE messages (
|
||
id INTEGER PRIMARY KEY,
|
||
group_id BLOB,
|
||
sender_id BLOB,
|
||
sender_counter INTEGER,
|
||
timestamp INTEGER,
|
||
payload BLOB, -- raw wire ciphertext
|
||
base_message_key BLOB, -- encrypted with device master key (see below)
|
||
plaintext BLOB NULL -- optional: decrypted on first view
|
||
);
|
||
|
||
**How we figure out the keys to decrypt from local storage**:
|
||
|
||
1. Load row by group_id + sender_id + sender_counter.
|
||
2. Decrypt the stored ``base_message_key`` using the device master key.
|
||
3. Using that base_message_key + group_id + sender_counter:
|
||
- Re-derive seq_seed = KMAC256(base_message_key, b"seq-seed-..." )
|
||
- Re-derive exact cascade permutation and all 16–24 per-layer keys.
|
||
- Decrypt cascade in reverse order.
|
||
- Decrypt inner triple AEAD.
|
||
4. (Optional) Cache plaintext in the same row for future views.
|
||
|
||
**Forward Secrecy Note**:
|
||
- The E2EE ratchet deletes old chain keys after successful receive/send (standard FS).
|
||
- Local storage keeps the base_message_key (encrypted under device key) so history remains decryptable.
|
||
- If the **device** is later compromised, history is readable — this is the explicit trade-off for on-demand decryption of stored wire messages. The cascade still provides the multi-alg hedge even if base_message_key leaks.
|
||
|
||
Message Sending Flow (Ultra Secret)
|
||
===================================
|
||
|
||
1. User types message.
|
||
2. Pad plaintext (multiple of 64 bytes + 32–64 random HKDF bytes from base_message_key).
|
||
3. Run ultra_encrypt as above.
|
||
4. Build wire blob with metadata + payload.
|
||
5. Send to relay (over TLS/Noise) with recipient list or group_id.
|
||
|
||
Message Receiving Flow (Ultra Secret)
|
||
=====================================
|
||
|
||
1. Receive blob from relay.
|
||
2. Store raw blob + encrypted base_message_key to local DB immediately.
|
||
3. Derive base_message_key via receiving ratchet (using sender_counter).
|
||
4. Decrypt using the process above.
|
||
5. Display plaintext.
|
||
6. Advance all ratchets (inner + sequence is automatic via counter).
|
||
|
||
Pseudocode – Ultra Secret Core Functions
|
||
========================================
|
||
|
||
.. code-block:: python
|
||
|
||
def derive_base_message_key(state, sender_counter):
|
||
# Standard Double Ratchet advance (symmetric + optional KEM)
|
||
return advance_double_ratchet(state.receiving_chain[sender_id], sender_counter)
|
||
|
||
def get_cascade_for_message(base_message_key, group_id, sender_counter):
|
||
seq_seed = kmac256(base_message_key, b"seq-seed-" + group_id + sender_counter.to_bytes(8))
|
||
permutation = deterministic_permutation(seq_seed, pool=64, length=20) # 16-24
|
||
return permutation
|
||
|
||
def ultra_decrypt(wire_payload, base_message_key, group_id, sender_counter):
|
||
seq = get_cascade_for_message(base_message_key, group_id, sender_counter)
|
||
ct = wire_payload # after outer AEAD verify if present
|
||
# decrypt cascade reverse
|
||
for layer in reversed(seq):
|
||
ct = decrypt_layer(ct, derive_layer_key(base_message_key, layer, sender_counter))
|
||
plaintext = inner_triple_aead_decrypt(ct, base_message_key)
|
||
return plaintext
|
||
|
||
def store_received_message(blob):
|
||
base_key = derive_base_message_key(...) # from ratchet
|
||
encrypted_base_key = aes_gcm_encrypt(base_key, device_master_key)
|
||
db.insert(group_id=blob.group_id, sender_id=blob.sender_id,
|
||
sender_counter=blob.sender_counter,
|
||
payload=blob.payload,
|
||
base_message_key=encrypted_base_key)
|
||
|
||
Implementation Priorities (Start Here)
|
||
======================================
|
||
|
||
1. Normal mode first (Double Ratchet + PQ KEM).
|
||
2. Per-sender ratchet tables.
|
||
3. Local DB schema exactly as above.
|
||
4. Ultra mode cascade dispatcher (test with 4 layers first).
|
||
5. Deterministic permutation function (ChaCha20 seeded by seq_seed).
|
||
6. Device master key management (separate from E2EE).
|
||
7. Threshold group creation for group_master_seed.
|