The protocol and the wire, written down. This page is the reference; the white paper is the reasoning; the source is the proof.
A 12-word BIP-39 phrase seeds an HKDF-SHA-256 tree. Derived on the device, never stored: the Ed25519 identity key, the X25519 signed prekey and one-time prekeys, the ML-KEM-1024 signed prekey, the ML-DSA-65 identity signing key, the SQLCipher database key, the backup key and the discovery beacon key. Only public halves are published.
identity_key · signed_prekey + signature · pq_signed_prekey (ML-KEM-1024) + signature + pq_signature · one_time_prekeys[] · bundle signatures: Ed25519 and ML-DSA-65 over the canonical encoding. A relay cannot substitute a bundle: the safety number commits to all public keys.
The initiator's first envelope: its identity and ephemeral public keys, the prekey ids consumed, the ML-KEM ciphertext (pqct), and the first ratchet message. The responder derives the same root key without a round trip. A replayed pkm is detected by the ephemeral key and refused.
Header: DH ratchet public key, previous chain length, message number, and the post-quantum ratchet leg — a fresh ML-KEM-768 encapsulation key on every new sending chain and the ciphertext to the peer’s last one. Body: AES-256-GCM under the message key with the whole header, KEM leg included, as associated data.
Around every ratchet message, one more layer the relay cannot open: an ephemeral X25519 key against the recipient’s identity key and an ML-KEM-1024 encapsulation to the recipient’s post-quantum prekey, HKDF-SHA-256 into one key, AES-256-GCM over {from, message} with the recipient’s routing id as associated data. Any device of the recipient opens it (both keys come from the twelve words); nobody else can; a quantum adversary recording the relay cannot unwrap the sender later.
A frame is {to: routing id, envelope: base64} — no sender. It arrives over an anonymous connection, is stored with no sender column, and the recipient learns who wrote inside the sealed layer. Routing ids are random per account and rotate; there is no name, number or e-mail anywhere in the frame or the database. Frames are deleted on delivery. What the relay can still see is the network address a connection came from, until the private route ships.
blob = nonce(12) ‖ AES-256-GCM(plaintext) ‖ tag(16) under a fresh 256-bit key; the key travels inside the ratcheted message. The store holds only the blob, by random id, with a per-tier expiry.
RSABSSA (RFC 9474) with PSS-SHA-384: the app blinds a random message, the payment leg signs it, the app unblinds. The relay verifies tier and epoch from which key verifies — never from the payload. Token = v2.<tier>.<epoch>.<msg>.<sig>.
Per-Echo Ed25519 pseudonym derived from the identity seed and the Echo id. Attunement token = blind signature over spojiti-echo-attune-v1:<echo>:<day>, carried in x-spojiti-attune. Every write is signed: posts spojiti-echo-post-v2|echo|id|parent|sha256(body)|sha256(title)|media, media spojiti-echo-media-v1|echo|sha256, moderation spojiti-echo-mod-v1|echo|op|target|until, marks spojiti-echo-pn-avatar-v1|echo|code.
WebSocket over TLS 1.3 to the relay; the app races every published rail and keeps the first that answers. Push is a content-free nudge over APNs/FCM; content is fetched over the socket after wake.
WebRTC with DTLS-SRTP, signalled through the ratcheted channel; ICE over our own STUN and TURN (TLS on 443) with a fallback TURN on a second box; a surge valve degrades to STUN-only rather than failing.
Caddy edge → Elixir relay + control plane → PostgreSQL + object store, an isolated Echo box, two disaster-recovery boxes with monthly restore drills, GeoIP for pricing only, encrypted backups. Every operational switch is a signed action in the Ops console and lands in an audit log.