292 lines
10 KiB
ReStructuredText
292 lines
10 KiB
ReStructuredText
================================================================================
|
||
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 recipient’s 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).
|