163 lines
5.9 KiB
ReStructuredText
163 lines
5.9 KiB
ReStructuredText
================================================================================
|
||
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.
|
||
|