|
| 1 | +# Encryption Architecture Decision - Phase 1 Review Follow-up |
| 2 | + |
| 3 | +**Date**: 2026-01-29 |
| 4 | +**Status**: DECISION REQUIRED |
| 5 | +**Context**: Codex review raised valid concern about removing application-layer encryption |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Background |
| 10 | + |
| 11 | +Phase 1 baseline measurements identified redundant encryption: |
| 12 | +- **Application layer**: ChaCha20Poly1305 (classical, 28B overhead per message) |
| 13 | +- **Transport layer**: saorsa-transport ML-KEM-768 (post-quantum, 16B overhead per packet) |
| 14 | + |
| 15 | +**Proposal**: Remove application-layer encryption, rely exclusively on saorsa-transport's PQC |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## Codex Review Concern (HIGH Severity) |
| 20 | + |
| 21 | +> "The baseline doc asserts 'no downsides' to removing application-layer encryption and treats |
| 22 | +> transport QUIC as full E2E. That is unsafe if messages are stored, relayed, or routed via |
| 23 | +> headless nodes/DHT—transport crypto only protects in-transit hops, not at-rest data or |
| 24 | +> offline verification." |
| 25 | +
|
| 26 | +**Valid Point**: Transport encryption (saorsa-transport) only protects data **in transit**, not: |
| 27 | +- Messages stored in DHT |
| 28 | +- Messages relayed through headless nodes |
| 29 | +- Offline message queues |
| 30 | +- Multi-hop routing scenarios |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## Encryption Decision Tree |
| 35 | + |
| 36 | +### Scenario 1: Direct Peer-to-Peer Messages |
| 37 | +**Characteristics**: |
| 38 | +- Direct QUIC connection between two active devices |
| 39 | +- No intermediate storage |
| 40 | +- No relaying through third parties |
| 41 | +- Real-time synchronous communication |
| 42 | + |
| 43 | +**Encryption Approach**: |
| 44 | +- ✅ **saorsa-transport ML-KEM-768 ONLY** |
| 45 | +- Provides: Post-quantum E2E encryption, integrity, replay protection |
| 46 | +- Overhead: 16 bytes per packet (AES-GCM tag) |
| 47 | +- Security: End-to-end between connected peers |
| 48 | + |
| 49 | +**Verdict**: Application-layer encryption **NOT NEEDED** |
| 50 | + |
| 51 | +--- |
| 52 | + |
| 53 | +### Scenario 2: Messages Stored in DHT |
| 54 | +**Characteristics**: |
| 55 | +- Messages persisted in distributed hash table |
| 56 | +- Stored on headless nodes (untrusted storage) |
| 57 | +- Retrieved later by recipient |
| 58 | +- No direct P2P connection during storage |
| 59 | + |
| 60 | +**Encryption Approach**: |
| 61 | +- ❌ **saorsa-transport protection ENDS at storage boundary** |
| 62 | +- ✅ **REQUIRES message-level encryption**: |
| 63 | + - Encrypt with recipient's public key (ML-KEM-768 encapsulation) |
| 64 | + - Sign with sender's private key (ML-DSA-65 signature) |
| 65 | + - Store encrypted+signed message in DHT |
| 66 | + |
| 67 | +**Overhead**: |
| 68 | +- ML-KEM-768 ciphertext: 1,088 bytes (per message, not per packet) |
| 69 | +- ML-DSA-65 signature: ~3,300 bytes |
| 70 | +- **Total**: ~4,400 bytes per stored message |
| 71 | + |
| 72 | +**Verdict**: Application-layer encryption **REQUIRED** |
| 73 | + |
| 74 | +--- |
| 75 | + |
| 76 | +### Scenario 3: Multi-Hop Routing via Headless Nodes |
| 77 | +**Characteristics**: |
| 78 | +- Message routed through intermediate headless nodes |
| 79 | +- Each hop is a separate QUIC connection |
| 80 | +- Transport encryption ends/restarts at each hop |
| 81 | +- Intermediate nodes should NOT see message content |
| 82 | + |
| 83 | +**Encryption Approach**: |
| 84 | +- ❌ **saorsa-transport protects hop-by-hop, NOT end-to-end in multi-hop** |
| 85 | +- ✅ **REQUIRES onion routing OR message-level encryption**: |
| 86 | + - Option A: Onion routing (layer encryption per hop) |
| 87 | + - Option B: Single message-level encryption (simpler) |
| 88 | + |
| 89 | +**Recommendation**: Message-level ML-KEM-768 encryption + ML-DSA-65 signature |
| 90 | + |
| 91 | +**Verdict**: Application-layer encryption **REQUIRED** |
| 92 | + |
| 93 | +--- |
| 94 | + |
| 95 | +### Scenario 4: Offline Message Delivery |
| 96 | +**Characteristics**: |
| 97 | +- Recipient is offline when message is sent |
| 98 | +- Message stored until recipient comes online |
| 99 | +- May be stored on sender's device, relay nodes, or DHT |
| 100 | + |
| 101 | +**Encryption Approach**: |
| 102 | +- ❌ **No active QUIC connection during offline storage** |
| 103 | +- ✅ **REQUIRES message-level encryption + signing** |
| 104 | + |
| 105 | +**Verdict**: Application-layer encryption **REQUIRED** |
| 106 | + |
| 107 | +--- |
| 108 | + |
| 109 | +## Current Saorsa Architecture Analysis |
| 110 | + |
| 111 | +### Question 1: Does Saorsa use DHT storage? |
| 112 | +**Answer**: YES |
| 113 | +- `src/dht/` module exists with Kademlia implementation |
| 114 | +- DHT used for peer discovery and data storage |
| 115 | +- Headless devices act as storage nodes |
| 116 | + |
| 117 | +**Implication**: **Message-level encryption IS NEEDED** for DHT-stored data |
| 118 | + |
| 119 | +--- |
| 120 | + |
| 121 | +### Question 2: Does Saorsa support offline message delivery? |
| 122 | +**Answer**: LIKELY YES (needs confirmation) |
| 123 | +- Presence system (`src/messaging/presence.rs`) suggests online/offline states |
| 124 | +- Multi-device support suggests asynchronous messaging |
| 125 | +- Headless devices could act as message queues |
| 126 | + |
| 127 | +**Implication**: **Message-level encryption IS NEEDED** for offline messages |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +### Question 3: Does Saorsa use multi-hop routing? |
| 132 | +**Answer**: UNCLEAR (needs confirmation) |
| 133 | +- Adaptive routing (`src/adaptive/`) suggests intelligent path selection |
| 134 | +- Trust-based routing might imply indirect paths |
| 135 | +- Network topology may require relaying |
| 136 | + |
| 137 | +**Implication**: If multi-hop routing exists, **message-level encryption IS NEEDED** |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +## Revised Architecture Proposal |
| 142 | + |
| 143 | +### Phase 4: Remove REDUNDANT Encryption (Not ALL encryption) |
| 144 | + |
| 145 | +**Keep**: |
| 146 | +- ✅ **Message-level ML-DSA-65 signatures** (for integrity + non-repudiation) |
| 147 | +- ✅ **Message-level ML-KEM-768 encryption** (for DHT storage + offline delivery) |
| 148 | +- ✅ **Transport-level saorsa-transport ML-KEM-768** (for in-transit protection) |
| 149 | + |
| 150 | +**Remove**: |
| 151 | +- ❌ **ChaCha20Poly1305** (classical, weaker than ML-KEM-768) |
| 152 | +- ❌ **Redundant EncryptedMessage wrapper** (simplify to single encryption layer) |
| 153 | + |
| 154 | +### Updated Message Flow |
| 155 | + |
| 156 | +#### For Direct P2P Messages (Synchronous) |
| 157 | +``` |
| 158 | +RichMessage |
| 159 | + → Bincode |
| 160 | + → ML-DSA-65 signature (for integrity) |
| 161 | + → saorsa-transport ML-KEM-768 (transport) |
| 162 | + → Wire |
| 163 | +``` |
| 164 | + |
| 165 | +**Rationale**: Signature provides integrity, transport provides confidentiality |
| 166 | + |
| 167 | +#### For DHT Storage / Offline Messages |
| 168 | +``` |
| 169 | +RichMessage |
| 170 | + → Bincode |
| 171 | + → ML-KEM-768 encrypt (with recipient public key) |
| 172 | + → ML-DSA-65 sign (with sender private key) |
| 173 | + → saorsa-transport ML-KEM-768 (transport to DHT node) |
| 174 | + → Wire → DHT Storage |
| 175 | +``` |
| 176 | + |
| 177 | +**Rationale**: Message-level encryption protects at-rest data, signature ensures authenticity |
| 178 | + |
| 179 | +--- |
| 180 | + |
| 181 | +## Performance Impact Re-Analysis |
| 182 | + |
| 183 | +### Current Architecture (ChaCha20 + saorsa-transport) |
| 184 | +``` |
| 185 | +Overhead per message: 28B (ChaCha20) + 16B (saorsa-transport) = 44B |
| 186 | +Encryption operations: 2 (ChaCha20 + ML-KEM-768) |
| 187 | +Key exchange: Separate + QUIC handshake |
| 188 | +``` |
| 189 | + |
| 190 | +### Revised Architecture (ML-KEM-768 message + saorsa-transport transport) |
| 191 | + |
| 192 | +**Direct P2P (Synchronous)**: |
| 193 | +``` |
| 194 | +Overhead per message: 3,300B (ML-DSA-65 sig) + 16B (saorsa-transport) = 3,316B |
| 195 | +Encryption operations: 1 (ML-KEM-768 via saorsa-transport) |
| 196 | +Signing operations: 1 (ML-DSA-65 for integrity) |
| 197 | +``` |
| 198 | + |
| 199 | +**DHT Storage / Offline**: |
| 200 | +``` |
| 201 | +Overhead per message: 1,088B (ML-KEM-768 ciphertext) + 3,300B (ML-DSA-65 sig) + 16B (saorsa-transport) = 4,404B |
| 202 | +Encryption operations: 2 (ML-KEM-768 message + saorsa-transport transport) |
| 203 | +Signing operations: 1 (ML-DSA-65) |
| 204 | +``` |
| 205 | + |
| 206 | +### Trade-off Analysis |
| 207 | + |
| 208 | +**Direct P2P**: |
| 209 | +- **Downside**: 3,316B overhead (vs 44B ChaCha20+antquic) |
| 210 | +- **Upside**: Provides non-repudiation via signature |
| 211 | +- **Mitigation**: Could make signature optional for ephemeral chat messages |
| 212 | + |
| 213 | +**DHT Storage**: |
| 214 | +- **Upside**: Proper end-to-end encryption (solves Codex concern) |
| 215 | +- **Overhead**: 4,404B (but necessary for security) |
| 216 | +- **Note**: This is correct architecture, not optional |
| 217 | + |
| 218 | +--- |
| 219 | + |
| 220 | +## Recommendation: Hybrid Approach |
| 221 | + |
| 222 | +### Message Classification |
| 223 | + |
| 224 | +**Type A: Ephemeral Direct Messages** (e.g., real-time chat) |
| 225 | +- Transport encryption only (saorsa-transport ML-KEM-768) |
| 226 | +- Optional: ML-DSA-65 signature for integrity |
| 227 | +- Overhead: 16B (or 3,316B with signature) |
| 228 | + |
| 229 | +**Type B: Stored/Relayed Messages** (e.g., offline messages, DHT data) |
| 230 | +- Message-level ML-KEM-768 encryption |
| 231 | +- Mandatory ML-DSA-65 signature |
| 232 | +- Transport encryption (saorsa-transport) |
| 233 | +- Overhead: 4,404B |
| 234 | + |
| 235 | +### Implementation Strategy |
| 236 | + |
| 237 | +1. **Add message type field** to RichMessage: |
| 238 | + ```rust |
| 239 | + enum MessageType { |
| 240 | + Ephemeral, // Direct P2P, no storage |
| 241 | + Persistent, // May be stored/relayed |
| 242 | + } |
| 243 | + ``` |
| 244 | + |
| 245 | +2. **Conditional encryption**: |
| 246 | + - Ephemeral: saorsa-transport transport only |
| 247 | + - Persistent: ML-KEM-768 + ML-DSA-65 + saorsa-transport |
| 248 | + |
| 249 | +3. **Default to Persistent** for safety: |
| 250 | + - All messages encrypted by default |
| 251 | + - Opt-in to ephemeral mode for performance |
| 252 | + |
| 253 | +--- |
| 254 | + |
| 255 | +## Phase 2 Action Items |
| 256 | + |
| 257 | +### Before Implementation (Architecture Analysis): |
| 258 | +1. ✅ **Confirm Saorsa's message flow patterns**: |
| 259 | + - Are all messages direct P2P, or are some stored/relayed? |
| 260 | + - Does DHT store user messages, or only metadata? |
| 261 | + - Is multi-hop routing used? |
| 262 | + |
| 263 | +2. ✅ **Document threat model**: |
| 264 | + - What are we protecting against? |
| 265 | + - Who are the adversaries (network eavesdroppers, malicious nodes, etc.)? |
| 266 | + - What data needs at-rest vs in-transit protection? |
| 267 | + |
| 268 | +3. ✅ **Design encryption API**: |
| 269 | + - Message classification (ephemeral vs persistent) |
| 270 | + - Encryption selection based on message type |
| 271 | + - Key management for message-level encryption |
| 272 | + |
| 273 | +### Phase 4 Revised Scope: |
| 274 | +- Remove **ChaCha20Poly1305** (classical encryption) |
| 275 | +- Keep **ML-DSA-65 signatures** (integrity + non-repudiation) |
| 276 | +- Add **conditional ML-KEM-768 message encryption** (for stored/relayed messages) |
| 277 | +- Simplify to single encryption layer per message (no double wrapping) |
| 278 | + |
| 279 | +--- |
| 280 | + |
| 281 | +## Conclusion |
| 282 | + |
| 283 | +**Codex's concern is VALID and IMPORTANT**: |
| 284 | +- Removing ALL application-layer encryption is unsafe for stored/relayed messages |
| 285 | +- Transport-only encryption (saorsa-transport) is insufficient for DHT storage |
| 286 | + |
| 287 | +**Revised Proposal**: |
| 288 | +- Remove **classical** encryption (ChaCha20) |
| 289 | +- Keep/add **post-quantum** message-level encryption (ML-KEM-768) for non-ephemeral messages |
| 290 | +- Keep **post-quantum** signatures (ML-DSA-65) for integrity |
| 291 | +- Use **saorsa-transport ML-KEM-768** for transport |
| 292 | + |
| 293 | +**Net Result**: |
| 294 | +- Stronger security (all PQC, no classical crypto) |
| 295 | +- Simplified architecture (no redundant double encryption) |
| 296 | +- Proper protection for all message types |
| 297 | +- Performance tradeoff: Larger overhead for stored messages, but necessary for security |
| 298 | + |
| 299 | +--- |
| 300 | + |
| 301 | +**Status**: Awaiting architectural analysis in Phase 2 |
| 302 | +**Next Steps**: |
| 303 | +1. Confirm Saorsa's message storage/routing patterns |
| 304 | +2. Update Phase 4 plan based on findings |
| 305 | +3. Design message classification API |
0 commit comments