1# SophaxChat — Threat Model23> Version 1.0 · 2026-03-284> Prepared for independent security audit56---78## 1. System Overview910SophaxChat is a serverless, anonymous peer-to-peer encrypted messaging application for iOS and macOS. All communication happens directly between devices over local radio transports. There are no servers, no cloud infrastructure, and no central directories.1112```13┌────────────┐ Bluetooth LE / WiFi Direct ┌────────────┐14│ Device A │◄─────────────────────────────────►│ Device B │15│ (Alice) │ │ (Bob) │16└────────────┘ optionally via └────────────┘17 ┌─────────────────────┐18 │ Relay device (C) │19 │ (honest-but-curious│20 │ mesh node) │21 └─────────────────────┘22```2324**Transports:**25- MultipeerConnectivity (Apple) — Bluetooth LE + WiFi Direct, up to 6 relay hops (TTL)26- mDNS / TCP — same WiFi network27- Tor hidden services (`.onion`) — optional, for global reachability2829**Identity model:** Each user generates a random Ed25519 + X25519 keypair on first launch. There are no usernames registered with any server; the `peerID` is `SHA256(signingPub ∥ dhPub)[:16]`.3031---3233## 2. Assets Being Protected3435| Asset | Sensitivity | Storage |36|-------|-------------|---------|37| Ed25519 signing private key | Critical | iOS Keychain (`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`) |38| X25519 DH private key | Critical | iOS Keychain |39| Double Ratchet session states | High | Keychain (JSON-encoded per peer) |40| Message plaintext | High | AES-256-GCM encrypted files in Application Support |41| Contact list (known peers) | Medium | UserDefaults (contains only public keys + usernames) |42| Attachment files (images, audio, video) | High | AES-256-GCM encrypted files in Application Support |43| Username | Low | Keychain + broadcast in Hello messages |44| Safety numbers (verification state) | Medium | Keychain |45| Group sender key chains | High | Keychain (per-group, per-member) |4647---4849## 3. Trust Boundaries5051```52┌─────────────────────────────────────────────────────┐53│ Trusted: iOS Secure Enclave / Keychain │54│ Trusted: Swift standard library / CryptoKit │55├──────────────────────────┬──────────────────────────┤56│ Semi-trusted: │ Untrusted: │57│ MultipeerConnectivity │ Mesh relay nodes │58│ (Apple framework) │ Remote peers │59│ │ Network (BLE/WiFi air) │60└──────────────────────────┴──────────────────────────┘61```6263**iOS Keychain** is the root of trust. Private keys never leave the Keychain in plaintext and are bound to `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` (not migratable, not iCloud-backed).6465---6667## 4. Attacker Models6869### 4.1 Passive Observer70**Capability:** Can observe all Bluetooth/WiFi frames in radio range.71**Cannot:** Decrypt any messages; all payloads are ChaCha20-Poly1305 encrypted.72**Learns:** Approximate location of communicating devices (radio proximity), packet timing, approximate message sizes (padded), and sender/recipient peerIDs in relay headers.73**Mitigations:** Sealed sender (peerID encrypted inside DR payload), TTL-limited relay headers, no persistent identifiers in headers.7475### 4.2 Active MITM76**Capability:** Can inject, replay, or drop packets on the transport layer.77**Cannot:** Forge authenticated messages; Ed25519 signatures cover every wire message.78**Attacks attempted:** Replay, message injection, route hijacking.79**Mitigations:** HMAC-SHA256 MAC on every message, Double Ratchet nonce prevents replay within a session, message deduplication (LRU cache of seen messageIDs), TTL enforcement.8081### 4.3 Malicious Relay Node82**Capability:** Owns a device that participates in mesh routing. Sees all relayed wire messages.83**Cannot:** Decrypt message contents (E2EE); forge messages (signing); identify sender (sealed sender).84**Learns:** Approximate timing and size of relayed messages; public peerIDs in outer relay header (if not sealed).85**Mitigations:** Relay nodes see only outer WireMessage envelope. Inner `MessageContent` is DR-encrypted. Sealed sender wraps the peerID in an ECIES envelope visible only to the recipient.8687### 4.4 Compromised Group Member88**Capability:** Attacker owns one member's device and reads their Keychain.89**Past messages:** Protected by forward secrecy — DR ratchet steps ensure past message keys are deleted after use.90**Future messages:** Compromised member's sender key chain is leaked. **Mitigation:** Other members can call "Reset Encryption Key" which generates new sender key chains and distributes them. On member leave, remaining members rotate all their sender keys automatically.91**Group membership:** Compromised member knows the group member list.9293### 4.5 Server-Level Attacker94**Capability:** N/A — SophaxChat has no servers.95**Notes:** No metadata is stored server-side. There are no DNS lookups, push notification servers, or CDNs involved in message delivery.9697### 4.6 Physical Device Access (Out of Scope for This Audit)98An attacker with physical access to an unlocked device can read all data. This is mitigated by:99- App Lock (Face ID / Touch ID) on foreground restore100- Keychain accessibility flag (`WhenUnlockedThisDeviceOnly`)101102Full disk encryption (FileVault / iOS data protection) is handled by the OS and is out of scope.103104---105106## 5. Threats & Mitigations107108| Threat | Attack | Mitigation | Status |109|--------|--------|------------|--------|110| Message eavesdropping | Passive radio sniffing | ChaCha20-Poly1305 AEAD on all messages | ✅ |111| Message forgery | Inject fake messages | Ed25519 signature on every WireMessage | ✅ |112| Replay attack | Re-send captured valid message | DR nonce uniqueness; LRU dedup cache (messageID) | ✅ |113| MITM at session init | Replace X3DH public keys | Safety Numbers (SHA512 fingerprint), user verification | ✅ |114| Identity spoofing | Claim another user's peerID | peerID is SHA256 of public keys; signing verifies control of key | ✅ |115| Sender identification via relay | Relay node identifies sender | Sealed sender: senderPeerID encrypted in ECIES envelope | ✅ |116| Future secrecy loss after compromise | Read future messages | Double Ratchet ratchet step on each message | ✅ |117| Past messages after key compromise | Read past messages | Forward secrecy: DR ratchet deletes used message keys | ✅ |118| Group member eavesdropping after leave | Ex-member reads future | Remaining members rotate sender keys on leave (SKD re-distribution) | ✅ |119| Group MITM via new member | Inject attacker as member | Group invites sent via E2EE DR channel (not broadcast) | ✅ |120| Timing analysis | Infer activity from packet timing | No specific mitigation (out of scope) | ⚠️ |121| Traffic analysis (message size) | Infer content type from size | No padding currently implemented | ⚠️ |122| Prekey exhaustion DoS | Download all OPKs | Prekey rotation, fallback to SPK-only session (with alert) | ✅ |123| Malicious expiry timestamp | Set expiresAt to year 9999 | Clamped to maxExpiryInterval = 1 year | ✅ |124| Oversized message DoS | Send multi-MB body | Message size limit enforced on receive | ✅ |125| Timestamp skew attack | Replay with future timestamp | Timestamp validation window (±10 min) | ✅ |126| Rate-limit bypass | Flood a peer with messages | Per-peer rate limiter in ChatManager | ✅ |127| Session init dedup race | Trigger two X3DH sessions simultaneously | Session initiation dedup (`pendingSessionInits` set) | ✅ |128| Key history tampering | Rewrite UserDefaults keylog | Log is append-only; key changes trigger visible alerts | ✅ |129130**⚠️ Known limitations (not mitigated):**131- Traffic analysis via packet sizes and timing132- No message padding (size reveals content type)133- Bluetooth/WiFi presence reveals physical proximity134135---136137## 6. Cryptographic Parameters Summary138139| Primitive | Usage | Key size |140|-----------|-------|----------|141| Ed25519 (CryptoKit) | Identity signing, message authentication | 32B private / 32B public |142| X25519 (CryptoKit) | DH key agreement (X3DH, DR) | 32B private / 32B public |143| ChaCha20-Poly1305 (CryptoKit) | Message encryption (DR) | 32B symmetric key |144| AES-256-GCM (CryptoKit) | Message storage at rest, backup | 32B symmetric key |145| HKDF-SHA256 (CryptoKit) | Key derivation (X3DH, DR chain) | — |146| HMAC-SHA256 | Sender key ratchet (KDF chain) | 32B |147| SHA512 | Safety number fingerprint | — |148| SHA256 | peerID derivation, key log fingerprint | — |149| PBKDF2-HMAC-SHA256 | Backup key derivation | 32B salt, 600 000 iterations |150151---152153## 7. Out of Scope154155- iOS operating system and kernel security156- Bluetooth and WiFi firmware157- MultipeerConnectivity Apple framework internals158- Physical device theft / shoulder surfing159- Side-channel attacks on CryptoKit implementations160- Social engineering / phishing161162---163164## 8. Recommended Audit Focus Areas1651661. **X3DH implementation** (`Sources/SophaxChatCore/Crypto/X3DH.swift`) — key derivation, DH concatenation order, associated data1672. **Double Ratchet** (`Sources/SophaxChatCore/Crypto/DoubleRatchet.swift`) — header encryption, out-of-order handling, skipped key cache1683. **Sealed sender** (`ChatManager.swift` — `sealMessage`/`unsealMessage`) — ECIES envelope, key derivation info1694. **Sender Keys v2** (`ChatManager.swift`, `GroupTypes.swift`) — KDF chain, replay protection, member leave re-keying1705. **Backup encryption** (`BackupManager.swift`) — PBKDF2 parameters, authenticated encryption1716. **Identity export** (`IdentityExport.swift`) — private key handling, passphrase entropy enforcement1727. **Key storage** (`KeychainManager.swift`) — accessibility flags, no data leaving device1738. **Prekey rotation & reuse** (`PreKeyManager.swift`) — OPK consumption, fallback to SPK