Security upgrade · 2026
Raven's end-to-end encryption — extended to Bluetooth mesh.
Every conversation runs on X3DH key agreement and the Double Ratchet,
wrapped inside the ATSAM protocol stack. That brings forward secrecy (a key leak
today reveals nothing about yesterday's messages) and post-compromise security
(a single new handshake heals every channel going forward) to every Raven chat. Crucially,
the same protocol runs over a 5-hop Bluetooth mesh — the cryptographic guarantees do not
depend on the internet being up.
- X3DHAsynchronous initial key exchange — start a chat while the recipient is offline.
- Double RatchetPer-message symmetric + DH ratcheting; keys evolve forward and erase the past.
- Safety NumbersSHA-512-derived 60-digit fingerprint, comparable in person, on a call, or by QR.
- Signed PreKeysRecipient publishes a signed batch so first contact handshakes survive cold start.
- OPAQUE PAKE · soonZero-knowledge password authentication (RFC 9497) — server never sees the password.
🛰️ Session establishment — X3DH + Double Ratchet
Raven's session establishment follows the published X3DH spec. The initial root key is
derived from up to four Diffie–Hellman outputs combining identity, signed-prekey, ephemeral
and one-time-prekey contributions:
DH1 = DH(IK_A, SPK_B) // authenticates A's identity to B
DH2 = DH(EK_A, IK_B) // authenticates B's identity to A
DH3 = DH(EK_A, SPK_B) // forward-secrecy contribution
DH4 = DH(EK_A, OPK_B) // one-time post-compromise security
SK = HKDF-SHA256(DH1 ‖ DH2 ‖ DH3 [‖ DH4])
The session immediately moves to the Double Ratchet, which combines a symmetric ratchet
(chain-key advanced per message) with a DH ratchet (root key re-derived each round trip).
The result:
- Forward secrecy: stealing today's session keys cannot decrypt yesterday's
ciphertext — the chain key that produced it is unrecoverable.
- Post-compromise security: a single new round of DH ratcheting heals the
channel — the attacker is locked out of all subsequent messages.
- Out-of-order resilience: a small skipped-key cache lets a delayed mesh
delivery decrypt correctly even if newer messages arrived first.
- Per-device sessions: multi-device users have one independent ratchet per
peer device; compromise of one device cannot quietly read another's traffic.
X3DH
Double Ratchet
X25519 ECDH
HKDF-SHA256
Ed25519 SPK signature
🧬 Safety Numbers — verify the human, not the network
End-to-end encryption is only meaningful if you're talking to the right person. Raven's
Safety Numbers use a deterministic fingerprint construction: take both
identity public keys, sort them, hash them through SHA-512 5,200 times, and render the
first 30 bytes as a 60-digit grouped number. Compare it once — read aloud, scan as a QR,
or check in person — and a man-in-the-middle becomes cryptographically detectable,
even if the carrier, the ISP, and our own server cooperate against you.
SHA-512 ×5200
Sorted IK pair
QR or voice compare
🔐 End-to-end encryption — primitives
Every direct message, group message, post, and comment is encrypted on the sender's device. The server,
relay nodes, and any device in between only ever see opaque ciphertext.
X25519 ECDH
AES-256-GCM
ChaCha20-Poly1305
Ed25519
HMAC-SHA-256
HKDF-SHA256
Argon2id (login)
SQLCipher (AES-256)
- Identity keys (Ed25519) are generated on first launch and stored in the iOS Keychain. On devices
with Secure Enclave the private key never leaves the chip.
- Session keys are derived from the X3DH handshake (see above) and rotated per-message by the
Double Ratchet, so each message has its own independent symmetric secret.
- Payloads are sealed with AES-256-GCM using a per-message nonce. The GCM tag doubles as integrity
protection; we additionally HMAC the routing envelope so relays can drop tampered packets early.
- Login: passwords are stretched with Argon2id before any verifier is sent; OPAQUE PAKE
(RFC 9497) is rolling out so the server never sees the password at all.
- Local storage: the on-device SQLite database is encrypted at rest with SQLCipher (AES-256). The
database key itself is stored in the Keychain, behind device-unlock protection.
- Vault content adds a second key layer locked behind Face ID / Touch ID — even with the unlocked
phone in hand, vaulted media stays sealed.
📡 Bluetooth-LE mesh protocol
Raven turns every device into both a BLE peripheral and a BLE central simultaneously. Encrypted message
frames hop from device to device, store-and-forward, until they reach the recipient — no router, no
cell tower, no internet required.
CoreBluetooth
BLE 5.0
Spray-and-Wait
TTL · 5 hops
SHA-256 dedup
Anti-replay
- Service UUID: a single fixed UUID identifies Raven peers in any environment, so
iOS and Mac builds discover each other automatically. Mac Catalyst uses the same GATT service so
cross-platform mesh works out of the box.
- Discovery: background scanning + advertising both run, even with the screen off
on iOS (with the Bluetooth-Always entitlement) and with the window closed on Mac (via a
LaunchAgent companion).
- Spray-and-Wait routing: messages are sprayed to up to L nearby nodes, then those
nodes wait for a direct delivery opportunity. Balances reach against airtime so the mesh doesn't
saturate.
- TTL: default hop limit of 5. Each relay decrements the counter; envelopes that
expire are dropped silently.
- Deduplication: a SHA-256 of the envelope body keys a per-device LRU. Each device
refuses to re-relay the same envelope, so loops can't form even with cyclic topologies.
- Anti-replay: timestamp + nonce verification rejects envelopes that fall outside a
sliding window or reuse a known nonce.
- Zero-knowledge relay: a relay node only ever sees the envelope wrapper. Payloads,
sender content, and reactions remain ciphertext throughout the path.
🌐 Hybrid delivery — three modes, one envelope
The on-device router picks the cheapest delivery path that's actually working. The decision logic is
local — no cloud lookups, no pre-flight checks.
- Online: a persistent WebSocket to the FastAPI relay delivers in real-time and
notifies recipients via APNs if they're offline.
- Direct mesh: if internet is unreachable but the recipient's BLE peer is in range,
the envelope is delivered peer-to-peer with no intermediate hop.
- Bridge (multi-hop): if neither path works, nearby devices act as store-and-forward
relays. Each carrier device passes the envelope on whenever it sees a node that's online or
closer to the recipient — Raven catches up on first network or proximity event.
- Failover: mode transitions are silent. A WebSocket drop instantly switches the
next outgoing message to mesh; a peer regaining LTE flushes its bridge queue to the server.
- End-to-end receipts: delivered/seen acks are themselves envelopes — the same
routing applies, so receipts work just as well over a 5-hop bridge as they do online.
📦 MeshEnvelope — the universal message format
Every payload travels in the same envelope, regardless of transport. The wrapper carries just enough
routing metadata for the network to do its job — and not a byte more.
MeshEnvelope {
id: SHA-256 hash // dedup + content addressing
sender_id: Hash(device_pubkey) // anonymised identity
recipient_id: Hash(target_pubkey) // routing target
payload: AES-256-GCM(blob) // opaque ciphertext
signature: Ed25519(envelope) // origin authentication
hmac: HMAC-SHA-256 // integrity (cheap drop)
ttl: uint8 // hops remaining (default 5)
timestamp: ISO-8601 UTC // anti-replay window
nonce: uint64 random // per-message uniqueness
route_type: online | direct | bridge
}
- The HMAC is verified before any expensive crypto so junk envelopes get dropped at line rate.
- The Ed25519 signature is verified once the envelope is admitted, before relay or local storage.
- Only the recipient can decrypt the payload — relays never have the symmetric key.
⚡ Server architecture
The server is a thin relay — a stateless FastAPI service that accepts encrypted envelopes, fans them
out via WebSocket and APNs, and parks them in PostgreSQL for offline pickup. Cost-wise it scales to
zero when nobody's chatting.
Python 3.11
FastAPI
WebSocket
PostgreSQL 15
Cloud Run
APNs HTTP/2
- Zero-knowledge: the database stores ciphertext blobs and routing hashes only.
Decryption keys never leave the device.
- Realtime: a single WebSocket per device handles inbound delivery, presence
heartbeats, and live audio room control. Falls back to APNs push when the socket is closed.
- Scale-to-zero: Cloud Run with min-instances 0 means idle traffic costs nothing.
Cold-start adds ~1.5s on the first request, then the service stays warm during the burst.
- Stateless: any instance can serve any request. Persistent state lives in
PostgreSQL (encrypted-at-rest) and Cloud Storage for media blobs.
- LiveKit Cloud SFU handles audio room media; the server only mints short-lived
JWTs and never proxies audio.
🍎 One Swift codebase, two native binaries
Raven runs natively on iOS 17+ and macOS 14+ — same Swift sources, same business logic, same crypto.
We use Mac Catalyst with platform-specific shells so the Mac build feels native to macOS 26 (Liquid
Glass UI, capsule sidebar, ⌘-shortcuts) without forking the codebase.
Swift 5.10
SwiftUI
Catalyst
CoreBluetooth
Multipeer Connectivity
Foundation Models
- iOS: distributed via the App Store. Background BLE keeps mesh participation alive
when the phone is locked.
- Mac: distributed as a signed DMG outside the Mac App Store so we can disable the
sandbox — required for full BLE peripheral mode. A LaunchAgent companion keeps the mesh bridge
running while the GUI is closed.
- Cross-platform mesh: a Mac next to an iPhone immediately becomes a relay node
for the iPhone's traffic, and vice-versa. Same GATT service UUID, same envelope format.
🧠 On-device intelligence
Smart features run locally — no prompts ever leave the device.
Foundation Models
Apple Translation
SFSpeechRecognizer
- Smart replies: three short suggestions above the input bar, generated by Apple's
on-device Foundation Model from the recent transcript. Never sent to a server.
- Inline translation: long-press a message → translate via Apple's Translation
framework. On macOS Catalyst the equivalent UI is gated behind the same on-device models.
- Voice transcription: voice notes are transcribed locally with SFSpeechRecognizer
so search and accessibility work without uploading the audio.
📊 What Raven sets out to do
Raven is built around a specific problem: keeping trusted users connected when the internet is unavailable, while keeping the same end-to-end protections that apply when it is. The list below is what Raven aims to ship, on its own terms, without framing it against any other product.
- End-to-end encryption on every conversation, online or over Bluetooth mesh.
- Works fully offline through nearby-device mesh routing (multi-hop store-and-forward).
- Works online through the same ATSAM-protected envelope format, server-routed when the internet is available.
- Hybrid auto-failover between the two paths without user intervention.
- Live audio rooms for small groups, online or in audible range over mesh.
- Decentralised social feed that survives without a central server.
- No phone number required — identity is a device-bound keypair, not a cellular subscription.
- Native iOS & macOS apps with reproducible builds.
🎯 Threat model — what Raven defends against
- Network-level adversary: ISPs, Wi-Fi snoops, and state-level passive observers
see only TLS-wrapped ciphertext. Even the relay server cannot decrypt it.
- Compromised relay node: a malicious mesh peer can drop or delay envelopes but
cannot read, modify, or impersonate the sender (Ed25519 signature + HMAC).
- Lost / stolen device: the encrypted database needs the device unlock to open;
Vault content needs an additional Face ID prompt.
- Server compromise: the server holds ciphertext blobs only. There are no
plaintext messages, no encryption keys, no IP/contact metadata.
Out of scope: a sophisticated attacker with persistent access to the unlocked device, or one capable
of compromising Apple's Secure Enclave. We document the boundary honestly rather than overpromise.
📋 What's not yet shipped — and when it is
Trust in a messenger is earned by what you ship and what you admit. Below is the honest list of
items a security researcher would (correctly) call out today, paired with the version that closes
each gap. If we miss a date, we will say so publicly.
Next release · v1.6
- Sealed Sender: hide the sender's user ID from the relay layer.
Today the recipient verifies the sender end-to-end via Ed25519, but the relay sees the user ID;
Sealed Sender encrypts that too, so the server learns "a message exists for X" but not "from Y".
- OPAQUE PAKE (RFC 9497): zero-knowledge password authentication — the server
never receives the password, even hashed. Replaces the current Argon2id-stretched verifier flow.
- Reproducible builds: anyone can rebuild the App Store binary from public sources
and verify it byte-for-byte. The build that runs on your phone matches the build we publish.
- Encrypted key backup & recovery: opaque-encrypted backup of identity +
ratchet state to iCloud, sealed with a user-chosen recovery passphrase the server can't see.
Lose your phone, keep your messages — only if you opted in.
Committed · 2026 H2
- MLS for groups (RFC 9420): migrate group chats from per-group symmetric AES
keys to Messaging Layer Security — IETF-standard continuous group key agreement that scales to
thousands of members with the same forward-secrecy guarantees as 1:1.
- Independent third-party audit: Cure53 / Trail of Bits / NCC Group-tier
engagement against the cryptographic core, the mesh envelope, and the BLE protocol layer. Full
report published in the open. "Designed to be reviewed" is not "audited" — we know.
- Open-source crypto core: the X3DH / Double Ratchet implementation, MeshEnvelope
parser, and BLE transport released under an audit-friendly license. Application code follows in
stages.
- Mesh cover traffic + padding: constant-rate decoy envelopes at the radio layer
so radio-traffic analysis cannot extract the social-graph pattern from BLE airtime. Today we
mitigate with anonymised hashes, dedup, and randomised re-broadcast jitter — but cover traffic
is the real fix.
- Censorship-resistant transport: domain fronting + pluggable transports
(obfs4 / Snowflake-style) for the online path. Already today the BLE-mesh path is unaffected by
network filtering — we want online to match.
- BLE side-channel hardening (KNOB / BLURtooth / BLESA): app-layer crypto already
neutralises pairing-level downgrade attacks (we don't trust BLE pairing for confidentiality —
every envelope is independently signed and encrypted). Protocol-level mitigations (encrypted
pairing, MITM-resistant GATT verification) are explicit audit scope.
Why the bluntness? Because security marketing copy that overpromises makes every other
claim suspect. We'd rather tell you exactly what's done, exactly what's coming, and let you make
an informed choice — than wave hands and lose the trust of the readers who matter most.
👨💻 Architected & built by Ahmadreza
Raven is independently designed and built — every line of crypto, mesh routing, server code, and UI
ships from one author. The cryptographic core (X3DH, Double Ratchet, MeshEnvelope, BLE transport)
will be open-sourced alongside the third-party audit in 2026 H2; until then, security researchers
can request review access today.
Reach
out →
Want to audit it?
Security researchers and review partners can request access to the cryptography and mesh protocol
sources. We'd rather you check than take our word for it.