Pre-alpha · unaudited · open source
Private communication without a single owner.
KARST is an experimental messenger. Messages are end-to-end encrypted with hybrid post-quantum key agreement, and the relays that carry them are run by independent operators — no company sits in the middle, and none has to.
X25519 + ML-KEM-768 key agreement Double Ratchet per message Noise_NK to a pinned relay AGPL-3.0
What this is, and what it is not
Privacy claims are easy to write and hard to keep. These are the ones this build actually makes, and the ones it does not.
Content stays between the ends
A relay carries ciphertext it cannot open. Keys are generated on your device and never leave it.
No phone number, no account
An identity is a keypair you hold. Nothing links it to a number, an email or a billing record.
Operators are interchangeable
Relays are chosen, not assigned. Anyone can run one, and moving between them does not change who you are.
This is not anonymity
A relay still sees an address connecting to it and the timing of that connection. Metadata is reduced here, not removed.
Not independently audited
The cryptographic composition has had no external review. Some primitives are feature-gated and off by default.
Not ready to depend on
Pre-alpha. Formats still change, and a failure of security, privacy or delivery should be assumed possible.
What it looks like
A desktop client, dark by default. The parts that matter are the ones that say what is happening: which relay carried this, what the fingerprint is, whether a file arrived intact.
How a message travels
Four steps, and at each one the honest answer to “what can the relay see?”
- 01
Agree on keys, twice over
First contact runs
X25519andML-KEM-768together, so recording today's traffic for a future quantum computer buys nothing. - 02
Address a box no one can link to you
The drop-box address is derived from the session and blinded per relay, and it rotates. Two operators comparing notes cannot match it up.
- 03
Hand over a fixed-size block
Every envelope is padded to the same length, so the relay learns nothing from how big a message was.
- 04
The relay stores, and knows little
It sees a connecting address, an opaque box and a constant-size blob. It does not log them — but it is a machine someone else runs, and that is a claim, not a proof.
Run a relay
A relay is a small Rust binary. It stores sealed messages for a while and hands them over when the owner asks. It holds no user list, no directory of who talks to whom, and nothing it could later be asked to produce.
- Binary
- one static Rust build
- State it keeps
- sealed mail, briefly
- Request-path logging
- none, enforced by a test
- Admission
- proof-of-work or invite
cargo build --release -p relay
# run, and print the id clients pin
./target/release/relay
relay-id 9f3a…c7d1
listening 0.0.0.0:9444
Check it yourself
Nothing here asks to be believed. Each claim has something you can read or run.
The maturity map
A line-by-line account of what works, what is stubbed, and what is blocked — kept honest as the code moves.
docs/STATUS.md →The claims matrix
The ceiling for anything written about this project, including this page.
docs/SECURITY_CLAIMS.md →Safety numbers
Compare a 60-digit fingerprint out of band and you have checked the channel without trusting any relay.
How it is computed →The test suite
Properties are pinned by tests that fail when the property is lost — including one asserting the relay writes nothing down.
Browse the tests →