Threat model
owned is designed for adversaries who can see the network but not the user’s phone. Specifically: a passive ISP, a hostile Wi-Fi operator, a compromised or coerced relay operator (us), a malicious peer attempting to MITM a contact-pairing flow, and a future quantum computer decrypting recorded ciphertext. We do not defend against an attacker with code execution on the user’s phone, or against the user being physically compelled to unlock the device.
The user contributes one critical secret: the 24-word recovery phrase produced at onboarding. Losing it means losing access; sharing it means surrendering all past and future messages. There is no escrow and no operator-mediated recovery. We can’t reset your account because we don’t have anything to reset it from.
The floor
Properties below are non-negotiable. Every milestone on the roadmap preserves them — features that would weaken one get rescoped, not the floor.
End-to-end encrypted. Only the two phones can decrypt content. The server, ISP, and relay operator never see plaintext.
Forward secrecy. Compromise of a long-term key does not unlock past messages. The steady-state ratchet derives ephemeral message keys that are discarded after use.
Post-compromise security. A future compromise heals. Once the ratchet steps past the compromise window, new messages are protected again.
Post-quantum hybrid. Handshake and ratchet combine classical Diffie-Hellman (X25519) with ML-KEM (lattice-based KEM). Recorded ciphertext stays unreadable even if an attacker later builds a cryptographically-relevant quantum computer.
Sealed sender. Every envelope on the wire carries only the recipient’s opaque per-install token. The relay does not learn who sent it.
Metadata minimisation. The server holds no directory linking handles to identities. Pairing happens out of band — in person, by QR or proximity — not via any contact-discovery service.
Cryptographic primitives
Handshake. A PQ-hybrid variant of the Signal X3DH protocol (“PQXDH”): an X25519 Diffie-Hellman exchange combined with an ML-KEM-1024 key encapsulation. The two halves are concatenated and HKDF-ed into the initial root key.
Ratchet. Double-ratchet steady state with per-message post-quantum mixing (“SPQR”). Every outgoing envelope carries a fresh ML-KEM-768 encapsulation; the receiver decapsulates and the resulting 32-byte shared secret is HKDF-mixed into that message’s AEAD key. On every direction change the same PQ shared secret is ALSO mixed into the new root key alongside the X25519 Diffie-Hellman output, so HNDL resistance carries across direction changes, not just within a single chain.
Envelope. Sealed-sender outer layer with hybrid PQ HPKE. The relay sees the recipient token, an envelope-size bucket, and ciphertext; it does not see sender identity or content. Padded to one of a small fixed set of size buckets (4 KiB, 16 KiB, 64 KiB, 256 KiB, 1 MiB) so a network observer learns nothing from envelope length.
At-rest. The local SQLCipher database is encrypted with a per-install key derived from the mnemonic. The mnemonic seed is wrapped under the iOS Secure Enclave and unwrapped only after Face ID / Touch ID succeeds. Cold start always re-prompts; a five-second background grace allows silent re-entry.
What the relay sees
The relay receives, per envelope:
- The recipient’s 32-byte opaque per-install token.
- A padded ciphertext blob (one of the size buckets above).
- An envelope-kind discriminator (SEAL, PROFILE_SHARE, IMAGE, VOICE, DELIVERY_RECEIPT, PQXDH_HANDSHAKE).
- A freshness nonce + Ed25519 signature for replay protection.
It does not receive:
- Plaintext content of any kind.
- The sender’s recipient token, identity, or device.
- The recipient’s real-world name, phone number, email, or device fingerprint.
- The user’s IP address (Tor hidden service on the wire).
Auxiliary state that does persist: a day-resolution
last_seen date per recipient token (V5
activity-status feature), an optional APNs device token
if the user opts into push notifications, and aggregated
daily request counters published on the
public stats page. Retention
windows are itemised in the
privacy notice.
Trust boundary
Two phones are inside your trust boundary. The relay is outside it. A coerced or rogue operator can be assumed to log everything they receive; the design constraint is that what they receive doesn’t let them decrypt or correlate.
The single point at which the user must trust the operator is at iOS app delivery — Apple cryptographically signs the IPA, so a malicious replacement would have to compromise Apple’s signing infrastructure. The same trust premise as every other iOS app. Once installed, the app verifies every relay response cryptographically.
Known gaps
owned is in active development. The points below are honest limitations of the current scope, not security shortcuts.
One device per identity. No multi-device sync by design — the security model assumes one identity = one active phone. Migration is a sequential handoff between two devices the user holds at the same time, not a cloud sync.
No audits yet. Independent cryptographic review is on the post-V1 wishlist; owned is currently a single-operator hobby project, and the protocol primitives (Signal X3DH, ML-KEM-1024, HPKE-PQ, double ratchet) are themselves well-studied, but no auditor has examined this specific implementation. Treat accordingly until that lands.
iOS only, currently. Android is planned but happens after iOS is fully shipped and the security model has held up in real-world use. The Rust protocol core can be reused via JNI; the iOS-specific boundaries (Secure Enclave, APNs, SQLCipher) re-map to Android equivalents.
Want more depth?
This page is the public summary. The canonical requirements document — including the full adversary model and per-milestone security constraints — lives in the source tree. Drop a note to owned@spitzbub.app if you have specific protocol questions; corrections and signal-boosting from security-aware readers are welcome.