lum_ccc_rust/docs/encryption_implementation_n...

292 lines
10 KiB
ReStructuredText
Raw 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.

================================================================================
Normal Mode Encryption Specification Hydra Apocalypse Ratchet
================================================================================
**Project**: World's Most Secure Messaging App
**Mode**: Normal Mode (default for all channels)
**Codename**: Hydra Apocalypse Ratchet Normal Mode
**Author**: JohnΞ (@j3g)
**Date**: February 18, 2026
**Version**: 1.1 Dart/Flutter + Hive + Modular CCCData + Encrypted Channel Blob (last phase)
**Primary Design Goal (Non-Negotiable)**
=======================================
This app is built to be **the most secure messaging application on the planet**.
Even in Normal Mode (the fast default), we refuse to make the compromises that Signal and every other mainstream app make.
The user has **full cryptographic sovereignty**: they choose every primitive, every provider (wolfSSL, BoringSSL, libsodium, OpenSSL, etc.), every parameter.
The entire scheme is defined at channel creation time and never changed by the server or developer.
Executive Summary
=================
Normal Mode is the **default encryption scheme** for every channel.
It is a **highly configurable, post-quantum hybrid Double Ratchet** that is deliberately stronger than Signal's 2026 PQ Triple Ratchet because:
- Every cryptographic primitive and provider is user-selected at channel creation.
- The complete configuration lives in **CCCData** (modular, provider-aware).
- All parameters are stored locally in Hive and shared securely during channel invite.
- Full forward secrecy + post-compromise security with user-controlled rekey frequency.
- Zero server influence over cryptography.
CCCData is the **single source of truth** for the encryption scheme.
CCCData Modular & Provider-Aware (Dart)
==========================================
.. code-block:: dart
@HiveType(typeId: 42)
class CCCData extends HiveObject {
@HiveField(0)
final int version = 1;
@HiveField(1)
final String mode = 'normal'; // 'normal' or 'ultra'
// Modular crypto providers (user can enable any combination)
@HiveField(2)
final List<String> enabledProviders; // e.g. ['wolfssl', 'boringssl', 'libsodium', 'openssl']
// Category-based configuration user picks per category, with provider fallback
@HiveField(3)
final Map<String, List<CryptoSelection>> kemConfigs; // key = category, value = ordered list (round-robin)
@HiveField(4)
final Map<String, List<CryptoSelection>> aeadConfigs;
@HiveField(5)
final Map<String, List<CryptoSelection>> kdfConfigs;
@HiveField(6)
final Map<String, List<CryptoSelection>> hashConfigs;
// Ratchet behavior (user configurable)
@HiveField(7)
final int ratchetFrequency; // messages between full KEM ratchet steps (0 = every message)
@HiveField(8)
final bool symmetricRatchetEveryMessage;
@HiveField(9)
final int rekeyInterval; // 0 = manual only
@HiveField(10)
final String rekeyMode; // 'manual', 'auto', 'button'
// Anti-distinguisher / padding
@HiveField(11)
final int minPaddingBytes;
@HiveField(12)
final int blockSize; // pad to multiple of this
// Channel identifiers
@HiveField(13)
final Uint8List groupId; // 32 bytes
@HiveField(14)
final int createdAt; // unix ms
@HiveField(15)
final Uint8List creatorDeviceId; // 32 bytes
CCCData({
required this.enabledProviders,
required this.kemConfigs,
required this.aeadConfigs,
required this.kdfConfigs,
required this.hashConfigs,
required this.ratchetFrequency,
required this.symmetricRatchetEveryMessage,
required this.rekeyInterval,
required this.rekeyMode,
required this.minPaddingBytes,
required this.blockSize,
required this.groupId,
required this.createdAt,
required this.creatorDeviceId,
});
}
@HiveType(typeId: )
class CryptoSelection extends HiveObject {
@HiveField(0)
final String provider; // 'wolfssl', 'boringssl', etc.
@HiveField(1)
final String algorithm; // 'Kyber1024', 'AES256GCM', 'KMAC256', etc.
@HiveField(2)
final int priority; // 0 = first in round-robin, higher = later
}
Defaults (hard-coded best-in-class):
- enabledProviders: ['wolfssl', 'boringssl', 'libsodium']
- kemConfigs['hybrid']: [wolfssl:X448+Kyber1024+McEliece460896, boringssl:Kyber1024, libsodium:X25519+Kyber768]
- aeadConfigs['main']: [wolfssl:ChaCha20-Poly1305, boringssl:AES256GCM, libsodium:Ascon-AEAD-128a]
All fields are **user-editable** in the channel creation screen (with defaults pre-selected and highlighted).
Channel Creation & Sharing (Current + Future Phase)
===================================================
**Current Phase**:
1. User creates channel → app builds CCCData with user choices.
2. Generate group_master_seed (512-bit).
3. Store CCCData + group_master_seed in Hive (encrypted with device master key).
4. Invite link contains encrypted (under recipients public key) copy of CCCData + group_master_seed.
**Future Phase Encrypted Channel Blob (Last Phase)**:
- When sharing a channel, serialize the entire CCCData + group_master_seed + initial ratchet states into a single encrypted blob (using a strong symmetric key derived from invite secret).
- This blob is the only thing sent to new members.
- Signature algorithm
Local Persistence Hive
========================
All data uses Hive:
- Box 'cccdata' → key = groupId.toHex(), value = CCCData
- Box 'messages' → composite key = '${groupId.toHex()}_${fromRlyUserId}_${senderCounter}'
- Model:
```dart
@HiveType(typeId: 50)
class StoredMessage extends HiveObject {
@HiveField(0) Uint8List groupId;
@HiveField(1) int fromRlyUserId;
@HiveField(2) int senderCounter;
@HiveField(3) Uint8List rawRelayMessage; // entire protobuf
@HiveField(4) Uint8List encryptedBaseKey; // encrypted with device master key
@HiveField(5) int timestamp; // extracted after decrypt
@HiveField(6) String? plaintext; // optional cache
}
```
Wire Protocol (RelayMessage) Backwards Compatible
===================================================
.. code-block:: proto
message RelayMessage {
uint32 from_rly_user_id = 1;
uint32 to_rly_chan_id = 2;
uint32 options = 3; // kept for backwards compatibility (will be removed later)
bytes data = 4; // FULL E2EE ciphertext (inner timestamp + content + padding + rekey if any)
uint64 server_seq = 5; // kept for backwards compatibility (will be removed later)
}
**data** field contains everything E2EE (timestamp for UI, message JSON, rekey payload, padding, etc.).
Normal Mode Ratchet Suggested Implementation
==============================================
```dart
class NormalRatchet {
final CCCData ccc;
final Uint8List groupMasterSeed;
// Per-sender chains
Map<int, Uint8List> sendingChainKeys = {}; // fromRlyUserId -> current chain key
Map<int, Uint8List> receivingChainKeys = {};
Uint8List advanceAndGetBaseKey(int fromRlyUserId, int senderCounter, bool isSending) {
var chain = isSending ? sendingChainKeys[fromRlyUserId]! : receivingChainKeys[fromRlyUserId]!;
// Symmetric ratchet every message (user configurable)
if (ccc.symmetricRatchetEveryMessage) {
chain = KDF(ccc.kdfConfigs, chain, utf8.encode('next'));
}
// Derive base_message_key
final baseKey = KDF(ccc.kdfConfigs, chain, senderCounter.toBytes());
// Update chain for next message
if (isSending) sendingChainKeys[fromRlyUserId] = chain;
return baseKey;
}
// Full KEM ratchet step (triggered by ratchetFrequency)
Future<void> performKEMRatchet(int fromRlyUserId) async {
final kemPub = await HybridKEM.generate(ccc.kemConfigs); // uses user-chosen providers
final sharedSecret = await HybridKEM.encap(...); // encapsulated inside encrypted payload
// Update root and chains
}
}
```
Message Sending Flow (Normal Mode)
==================================
1. Load CCCData for channel.
2. Advance ratchet → base_message_key.
3. Pad plaintext per CCCData.blockSize + minPaddingBytes (random bytes from KDF).
4. Round-robin encrypt with AEADs from ccc.aeadConfigs using base_message_key.
5. If rekey triggered → add RekeyPayload inside inner data.
6. Serialize into RelayMessage.data.
7. Send RelayMessage to relay.
Message Receiving & Local Storage Flow
======================================
1. Receive RelayMessage → immediately store raw bytes in Hive 'messages' box.
2. Load CCCData → advance receiving ratchet → derive base_message_key.
3. Decrypt data field → extract timestamp for UI.
4. If RekeyPayload → apply new root.
5. Cache plaintext if desired.
Rekey Flow
==========
- auto every rekeyInterval messages
- Fresh hybrid KEM secret encapsulated and sent inside encrypted data (never on wire header).
Security Guarantees Why This Is the Most Secure Normal Mode on Earth
=====================================================================
- User chooses every provider and algorithm (wolfSSL AES + BoringSSL Kyber + libsodium Ascon in same channel).
- All decisions cryptographically bound to channel via CCCData.
- Modular provider system allows mixing libraries for maximum implementation diversity.
- No ratchet_public on wire (future-proofed).
- Hive at-rest encryption + device master key protects everything locally.
Implementation Checklist (Dart/Flutter)
=======================================
1. Hive adapters for CCCData, CryptoSelection, StoredMessage.
2. Channel creation screen with provider picker + category lists.
3. CryptoProvider registry (wolfssl.dart, boringssl.dart, etc.) with abstract interfaces.
4. NormalRatchet class that reads CCCData at runtime.
5. HybridKEM, AEADRoundRobin, KDF engines that respect provider lists.
6. Invite flow that sends encrypted CCCData blob.
7. Unit tests for every possible CCCData combination.
8. Fuzz padding, ratchet advance, provider fallback.
Future Phase Encrypted Channel Blob
=====================================
- Serialize entire CCCData + groupMasterSeed + initial ratchet states.
- Encrypt under a strong symmetric key derived from invite secret.
- This single blob becomes the canonical way to share a channel (last phase).