Marketing Claim Audit — Phantom Chat by Veilus Digital
Verification document
Phantom Chat — Marketing Claim Audit
Date<br>2026-06-19 (re-verified against the current build)
Prepared by<br>Curtis Tunaley, Veilus Digital
Audience<br>Journalists, podcast hosts, security researchers evaluating Phantom Chat.
This document maps every technical claim made on veilusdigital.co and inside the iOS app to the specific Swift source file that implements it. Each row reflects what the code actually does — not what marketing copy aspires to. Where a claim is partial or unimplemented, that is noted explicitly. The goal is to make this product easy to fact-check before you write or record about it.
On line numbers: the line references below were accurate when re-verified on the date above. Line numbers drift as code evolves — the file name + symbol/function name is the durable reference. If a line has moved, search for the named symbol in that file. Happy to share the exact commit on request.
If anything here is unclear, contact support@veilusdigital.co and I'll walk through the relevant code or schedule a screen-share.
1. Cryptography
1.1 Post-Quantum Key Exchange (PQXDH / Hybrid Curve25519 + ML-KEM-768)
Claim<br>Every new conversation uses NIST FIPS 203 ML-KEM-768 (Kyber) hybridised with classical Curve25519 — if either survives the next 20 years, messages stay safe.
Status<br>✅ Verified, executes on every new conversation. Not dead code.
Code path<br>Phantom Chat/X3DHProtocol.swift:64-80 (Kyber-768 keypair generation, integrated into bundle)<br>Phantom Chat/X3DHProtocol.swift:161-191 (PQXDH hybrid is engaged for both initiator and responder)<br>Phantom Chat/X3DHProtocol.swift:182 — PQXDHHybrid.combine() merges classical X3DH with Kyber shared secret via HKDF<br>Phantom Chat/KeyStore.swift:329-352 — ensureKyberKey() generates and persists Kyber-768 keypairs (2400 bytes)
Note<br>Implementation is custom Swift, not libsignal. The algorithms (X3DH, Double Ratchet, ML-KEM-768) are standard and publicly documented; the Swift code re-implements them rather than linking the Rust libsignal library.
1.2 Double Ratchet (Signal Protocol)
Claim<br>Every message uses a fresh derived key, rotated automatically per message with a Diffie-Hellman ratchet step on conversation-direction change.
Status<br>✅ Verified — full implementation of all 5 algorithm components.
Code path<br>Phantom Chat/DoubleRatchet.swift:20-33 (root key + send/receive chain keys + DH ratchet keys)<br>Phantom Chat/DoubleRatchet.swift:45-46 (skipped-message-keys dictionary for out-of-order delivery)<br>Phantom Chat/DoubleRatchet.swift:66-88 (encryptMessage() derives the next message key, advances send chain)<br>Phantom Chat/DoubleRatchet.swift:112-114 (performDHRatchet() step)<br>Phantom Chat/DoubleRatchet.swift:117-128 (skipped-keys path)
1.3 AES-256-GCM
Claim<br>Messages and media are encrypted with AES-256-GCM.
Status<br>✅ Verified — used everywhere.
Code path<br>Phantom Chat/DoubleRatchet.swift:71 — AES.GCM.seal() for message encryption<br>Phantom Chat/SecureMediaManager.swift:41 — AES.GCM.seal(data, using: key) for media<br>Phantom Chat/ChatAPI.swift:978, 1338 — AES.GCM.SealedBox for decrypt<br>Phantom Chat/VerificationStore.swift:388 — AES-GCM for stored fingerprint encryption
1.4 Hardware-Bound Identity (Secure Enclave)
Claim<br>Long-term identity key generated inside the iPhone's Secure Enclave; private key never leaves hardware.
Status<br>✅ Verified — SE preferred on first launch.
Code path<br>Phantom Chat/KeyStore.swift:40, 60, 78, 109 — SecureEnclave.P256.KeyAgreement.PrivateKey creation and persistence<br>Phantom Chat/KeyStore.swift:192 — biometric access control on SE key<br>Phantom Chat/KeyStore.swift:554-580 — createAndPersistSecureEnclaveKey() and loadSecureEnclaveKey() via SE blob
Caveat<br>Falls back to software key only if the device does not have a Secure Enclave (older simulators, jailbroken devices missing SEP). Software fallback preserved for backward compatibility.
1.5 App Attest (Device Attestation)
Claim<br>Server verifies that the connecting device is a real iPhone running unmodified Phantom Chat code.
Status<br>✅ Verified — wired end-to-end (client + server).
Code path<br>Phantom Chat/AuthService.swift:329, 410-475 — AppAttestService instantiates DCAppAttestService.shared<br>Phantom Chat/AuthService.swift:469 — service.generateKey() called and cached<br>Phantom Chat/AuthService.swift:452, 475-485 — attestKey(keyID, clientDataHash:) + POST to verifyAppAttestKey Cloud Function<br>Phantom Chat/functions_index_consolidated.ts:1390-1410 — server-side attestation verification
2. Privacy & Anonymity
2.1 Anonymous Sign-up
Claim<br>No phone number, email, real name, or personal information collected at sign-up. Username only.
Status<br>✅ Verified.
Code path<br>Phantom Chat/AuthView.swift:6 — @State private var username: String = "" (the only signup field)<br>Phantom Chat/AuthView.swift:239-241 — signup collects only username, trims whitespace, calls viewModel.signIn(username: name)
2.2 What the Server Stores
Claim<br>The server...