================================================================================ Ultra Mode – Complete Detailed Design & Persistence Specification ================================================================================ **Project**: World's Most Secure Messaging App **Mode**: Ultra Secret Mode (opt-in per channel) **Date**: February 20, 2026 **Version**: 1.0 – Written for someone who has never built a ratchet before This document explains **everything** from first principles, just like the Normal Mode document. Every term is defined the first time it appears. Every high-level statement is followed by the low-level cryptographic details. No assumptions. No gaps. 1. What Makes Ultra Mode Different from Normal Mode =================================================== Ultra Mode is for people who believe a nation-state or powerful adversary has already secretly broken one major cryptographic family (e.g., AES, Kyber, McEliece, etc.). The core idea: - Instead of trusting one or two algorithms (like Normal Mode does), - Ultra Mode puts **16–24 different algorithms in a secret sequence**. - The sequence is different for every message and never sent over the wire. - The attacker must break **all** of them in the unknown order to read a message. This is called a **cascade** (layers of encryption). We combine it with a ratchet so we still get forward secrecy and post-compromise security. 2. The Triple-Compound Ratchet (High-Level + Low-Level) ======================================================= Ultra Mode uses **three ratchet layers** working together: **Layer 1 – Inner Ratchet** Same as Normal Mode Double Ratchet (symmetric chain + occasional asymmetric reset). This is the fast daily engine. **Low-Level (same as Normal Mode but inside the cascade)**: - Starts with root secret from channel creation. - Symmetric advance: chainKey = KDF(chainKey, "next" + groupId) - Base message key = KDF(chainKey, counter + groupId) - Asymmetric reset (every N messages): fresh KEM shared secret mixed in. **Layer 2 – Secret Cascade** After the inner ratchet encrypts, we encrypt **again** with 16–24 layers of different algorithms in a secret order. **Low-Level**: - From the inner base_message_key, derive a 32-byte seq_seed: seq_seed = KMAC256(base_message_key, "seq-seed" + groupId + counter) - Generate secret sequence: Use ChaCha20 (seeded by seq_seed) as CSPRNG → Fisher-Yates shuffle of pool indices → take first 16–24. - For each layer in sequence: layerKey = HKDF(base_message_key, "layer-" + i + groupId + counter, keyLength) ciphertext = encrypt(ciphertext, layerKey, algorithm from pool) - Strongest algorithms first (McEliece/Kyber early, AES last). **Layer 3 – Sequence Mutation** The seq_seed itself changes every message (ratcheted forward), so the cascade sequence changes every message. **Low-Level**: - After each message, update seq_seed base: new_seq_seed_base = KMAC256(seq_seed, "mutate" + groupId + counter) - Next message uses this as starting point for new seq_seed. 3. What Exactly Is Stored on Your Device (Very Specific) ======================================================== For each chat and each sender: - **CCCData** – full user settings (providers, cascadeLength=20, poolSize=56, etc.) - **Raw encrypted wire blobs** – every message's exact RelayMessage bytes (this is the permanent chat history) - **Ratchet state** (one per sender per channel): - encryptedRootKey (AES-256-GCM under device master key) - currentChainKey (inner ratchet, 32 bytes) - lastProcessedCounter (highest decrypted message) - checkpoints (chain key snapshots every 500 messages) No per-message keys. No full historical chain. Only current state + raw blobs. 4. Message Flow From One User to Another ======================================== **Sending Side** 1. Type message. 2. Load CCCData (builds cascade pool from your providers). 3. Load sending ratchet state. 4. Advance inner symmetric chain (KDF "next"). 5. Derive base_message_key (KDF chain + counter). 6. Derive seq_seed (KMAC256 base + "seq-seed" + counter). 7. Generate secret cascade sequence (ChaCha20 shuffle). 8. Pad plaintext. 9. Inner AEAD round-robin (your chosen list). 10. Cascade encrypt (16–24 layers, strongest first). 11. Optional re-key inner root from cascade output. 12. Outer AEAD (fast fixed). 13. Build RelayMessage → send via gRPC. 14. Update & save ratchet state. **Receiving Side** 1. Receive RelayMessage → store raw bytes immediately. 2. Load CCCData + receiving state. 3. Advance inner ratchet to match counter. 4. Derive base_message_key. 5. Derive seq_seed + cascade sequence (same as sender). 6. Decrypt outer AEAD. 7. Cascade decrypt (reverse order). 8. Inner AEAD decrypt. 9. Remove padding → show message. 10. Update & save state. 5. How We Load Messages on Cold Start ===================================== **Recent Messages (instant)** 1. Authenticate → device master key. 2. Load CCCData + ratchet state. 3. Load newest raw blobs. 4. For messages > lastProcessedCounter: - Advance inner ratchet forward. - Derive base + seq_seed + cascade. - Full decrypt. - Update state. **Older Messages (paranoid, lazy)** 1. Scroll up → old messages show "Locked". 2. Tap "Unlock older" → re-authenticate (passphrase/biometrics). 3. App replays inner ratchet forward from last state to old counter. 4. Derives base + seq_seed + cascade for each. 5. Decrypts raw blobs. 6. Caches plaintext (encrypted under device master key). 7. Updates state and checkpoints. 6. Starting the Ratchet Chain (Channel Creation / Invite) ========================================================== 1. Creator generates 512-bit root secret. 2. Encrypts under recipient’s public key (KEM from CCCData). 3. Sends in invite. 4. Recipient decrypts root secret. 5. Both initialize: inner chain keys = KDF(root, "inner-sending/receiving" + groupId) 6. Save encrypted root + initial chain keys.