lum_ccc_rust/docs/encryption_implementation_d...

202 lines
9.9 KiB
ReStructuredText
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.. _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 1624 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 — ~12 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 members 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 3080 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=4864, length=1624)
3. Inner AEAD encrypt plaintext → inner_ct (triple AEAD with base_message_key).
4. Cascade encrypt inner_ct using the 1624 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 1624 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 + 3264 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.