Privacy is not a policy. It is mathematics.
End-to-end encrypted messaging on a relay you run yourself. Messages are encrypted on your phone before they leave it, with post-quantum protection, and the relay passes on ciphertext it holds no keys for.
- X3DH + Double Ratchet Key agreement, hybrid with post-quantum ML-KEM-768
- XChaCha20-Poly1305 AEAD encryption
- TLS 1.3 only Transport — no TLS 1.2, no plaintext fallback
- Signed key bundles Keys signed by each account, proven over the TLS session
- No logs The relay logs nothing that identifies who talks to whom
The relay carries ciphertext.
Messages are encrypted with the Double Ratchet on your phone. The relay you run routes them between devices without the keys to read them. It is not blind to who talks to whom, and the security model says exactly what it can see.
ciphertext = XChaCha20Poly1305(key=k_ratchet, msg=plaintext) Strictly on-device.
Secret keys are generated on your phone and never sent anywhere. Each account signs its public keys, so the relay cannot swap in keys of its own. Messages and requests are protected end to end with post-quantum encryption (X25519 with ML-KEM-768), and the connection to the relay uses a post-quantum key exchange too, so recording traffic today won’t let a future quantum computer read it later.
Thin logs, stated limits.
While running, the relay sees which accounts are connected, when and from which IP address, and which two have a conversation open. It does not write this to its logs. After two people’s first conversation, they reconnect with a code that changes every day. While a conversation is open, the relay’s memory still links its two members (as it did before). Once both have been gone about 10 minutes, nothing it keeps names the pair; waiting blind asks name no one; and no token or circuit id links one connection period to the next. Someone watching the relay live can still see two accounts connect to each other. Messages for someone offline are held in memory for up to 72 hours, filed under the recipient, with the sender inside the encryption. Optional steady traffic makes the timing of your messages reveal less while the app is open.
TLS 1.3 only.
All traffic is WebSocket inside TLS 1.3, terminated by the relay itself. Joining is one scan of the relay’s invite, which pins its identity. Every message is padded to a size bucket, and each relay shows its own decoy website to anything that isn’t the app.
Not a service. Software you run.
There is no rChat cloud, no sign-up and no subscription. You deploy the relay on a server you control and give people its invite, one QR code. Whoever runs a relay is its operator, and decides where it runs and who may use it.
- The relay Runs on your server, under the law where you run ityours
- The keys Generated on each phone, never sent to the relayon-device
- Accounts None. An identity is a key pair on your phonenone
- The software Developed by PDG Global Limited, Hong Kongopen source
How it compares.
rChat trades a hosted service for one you control. It is younger and smaller, and it does not have everything the large messengers have.
| Feature | rChat | Signal | Telegram |
|---|---|---|---|
| Who runs the server | You | Signal | Telegram |
| End-to-end encrypted by default | Yes | Yes | No (secret chats only) |
| Run your own server with the official app | Yes | No | No |
| Contact key verification | Safety numbers and QR | Safety numbers | Secret chats only |
Don’t trust us. Run your own node.
You should not have to trust whoever runs a server. rChat is open source: audit the code, build the relay and run it on a host you control.
The relay terminates TLS itself and obtains and renews its own certificate over TLS-ALPN-01 on port 443. No port 80, and no TLS-terminating proxy in front.
cargo build --release --bin rchat-server
# point an A/AAAA record for relay.example.com at this host
sudo install -m 0755 target/release/rchat-server /usr/local/bin/
sudo useradd --system --home /var/lib/rchat --shell /usr/sbin/nologin rchat
# /etc/rchat/server.toml
[server]
bind_addr = "0.0.0.0:443"
websocket_path = "/a-long-random-path"
relay_identity_path = "/var/lib/rchat/relay_identity.key"
[server.acme]
enabled = true
domains = ["relay.example.com"]
contacts = ["mailto:[email protected]"]
cache_dir = "/var/lib/rchat/acme"
# once, as the service user: create the relay identity (prints its pin)
sudo install -d -m 0700 -o rchat -g rchat /var/lib/rchat
sudo -u rchat rchat-server --config /etc/rchat/server.toml --init-relay-identity
sudo systemctl enable --now rchat-server
# invite people: a link and a QR code with the address and the relay identity
sudo -u rchat rchat-server --config /etc/rchat/server.toml --print-invite End-to-end encrypted messaging on a relay you run
Abstract
How rChat’s protocol version 3 works: a post-quantum hybrid handshake, key bundles signed and bound to the TLS session, conversations that open only when both people ask, blinded pairing, steady traffic, relay invites and size padding. It also sets out plainly what a self-hosted relay knows about you, and what it never has.
Who makes rChat.
The developer
rChat is developed by PDG Global Limited, a company based in Hong Kong, outside the jurisdiction of the Five Eyes intelligence alliance.
Jurisdiction
Because rChat is self-hosted, the law that governs a relay is the law where its operator runs it, not where the developer is based. Message content is protected by end-to-end encryption, which does not depend on any jurisdiction.
No hosted service
PDG Global Limited does not run relays for users and holds no accounts or messages. For what a relay can see, read the security model.
Run rChat.
Set up a relay on your own server, then invite people to it with one QR code.