olvid — a Go implementation of the Olvid protocol
eio.dev/x/olvid is an independent, clean-room Go implementation of the
Olvid end-to-end-encrypted messenger protocol — the cryptography, the wire
formats, and the server/identity/group/trust state machines — together with oigw, an IRC
gateway that lets any ordinary IRC client chat with real Olvid users on the live Olvid servers.
It is written from the public Olvid technical specification and
cross-checked, byte-for-byte where it matters, against Olvid's official open-source
Android / iOS
engines, their server backend, and the real *.olvid.io
servers. It has no dependency on Olvid's own code and is not affiliated with or endorsed by Olvid
SAS.
⚠️ Experimental · unofficial · AI-assisted — work in progress
This is an ongoing development effort, not a finished product. It is NOT an official Olvid
implementation and is not affiliated with, endorsed by, or supported by Olvid SAS. Much of the
protocol reverse-engineering, code, and tests here are produced through AI-assisted development, and
the result has not been independently security-audited. APIs, wire handling, and behavior can change
or break at any time. Do not rely on it for anything security- or privacy-critical, and do not treat it
as a trustworthy Olvid client. Use it to learn, experiment, and hack — at your own risk.
Status: the crypto, protocols, and 1:1 + group messaging are implemented and interoperate with the
real apps; multi-device provisioning (device transfer) is byte-audited against the reference. See
CHANGELOG.md for the detailed history and STATE.md for a snapshot.
What it does
- End-to-end encryption the Olvid way: oblivious channels (per-message forward-secret ratchets),
KEM + AuthEnc message wrapping, the GkmV2 message-key binding, the Full Ratchet (post-compromise
security), and pre-keys — all matching the reference wire format.
- Identities & trust: self-generated cryptographic identities, invitation links / QR codes, the
out-of-band SAS trust establishment, mediated introductions, and mutual-scan-style device transfer.
- Groups v2: the admin-chain / blob / members model — create, invite, kick, leave/disband, admin
permissions, group details, and ephemeral (auto-deleting) messages.
- Messaging niceties: attachments (chunked S3 upload/download), reactions, edits, remote deletes,
screenshot notices, and delivery/read return receipts.
- Multi-device: provision the gateway as a co-device of an existing profile via the transfer
protocol, and tear a profile down again.
- An IRC gateway (
oigw): your Olvid contacts appear as nicks, groups as channels, messages as
PRIVMSGs — usable from irssi, WeeChat, HexChat, etc.
Architecture
Strict, one-directional layering. engine is pure (crypto + protocols, no I/O); server and store
sit on top of it for network and persistence; client ties them into a usable session; the two
commands are thin front-ends.
cmd/oigw ─┐ (IRC gateway) (CLI / demo) ┌─ cmd/olc
▼ ▼
┌────────────────────────────────────────────────┐
│ client │
│ high-level Session: identity + store + server, │
│ message lifecycle, channels, groups, trust, │
│ receipts, device transfer │
└──────┬──────────────────┬──────────────────┬────┘
▼ ▼ │
┌────────────┐ ┌────────────┐ │
│ server │ │ store │ │
│ REST/WS + │ │ encrypted │ │
│ transfer │ │ SQLite │ │
│ relay │ │ (Argon2id) │ │
└──────┬─────┘ └──────┬─────┘ │
│ │ ▼
│ │ ┌────────────┐
└───────────────────┴──────────▶│ engine │
│ crypto + │
│ protocols │
│ (pure) │
└────────────┘
client → {server, store, engine}; server, store → engine; engine → (nothing internal)
| Layer |
Package |
Responsibility |
| engine |
engine (+ engine/ec, engine/encoding, engine/prng, engine/types) |
Pure crypto and the Olvid protocol state machines: curves & KEM, AuthEnc, HMAC-DRBG, the Olvid TLV encoding, oblivious channels, channel creation, trust/SAS, groups v2, full ratchet, device transfer, snapshots. No network or disk. |
| server |
server |
Client for the Olvid server REST API (spec §42–50), the notification WebSocket, and the transfer.olvid.io relay. |
| store |
store |
At-rest-encrypted SQLite persistence: an Argon2id-derived keyring wrapping per-value encryption for the identity, channels, contacts, groups, and metadata. Files are 0600 from birth. |
| client |
client |
The high-level Session: authentication/token management, the receive→decrypt→dispatch loop, sending over oblivious/asymmetric channels, groups, trust onboarding, return receipts, and device-transfer orchestration. |
| cmd/oigw |
cmd/oigw |
The IRC gateway — see cmd/oigw/README.md. |
| cmd/olc |
cmd/olc |
A lower-level CLI / demo harness that drives the library directly — see cmd/olc/README.md. |
The dependency arrows never point back up: engine imports nothing internal, server and store
import only engine, client imports all three, and the commands import client.
Getting started
Requires Go 1.26+. The only external dependencies are github.com/mattn/go-sqlite3 (cgo SQLite),
golang.org/x/crypto (Argon2), golang.org/x/term (passphrase prompt), and rsc.io/qr (invitation QR).
# install the gateway only
go install eio.dev/x/olvid/cmd/oigw
# build both commands
go build ./cmd/oigw
go build ./cmd/olc
# run the tests
go test ./...
Quick start with the gateway (full details in cmd/oigw/README.md):
export OIGW_PASSPHRASE='a strong passphrase' # or omit to be prompted (no echo)
./oigw -init -name alice # create an identity in the encrypted store, print your invite link
./oigw # start the gateway on 127.0.0.1:6667
# then point your IRC client at localhost:6667 (no PASS needed) and:
# /msg *olvid help
# /msg *olvid add <invitation-link>
# /msg *olvid qr # show your invite link as a scannable QR
Security notes
- The encrypted store holds the identity's real long-term private keys. Protect it: it is
encrypted at rest (Argon2id + per-value AuthEnc) and created
0600, but a leaked store + passphrase
compromises the identity. Use -paranoid for a stronger KDF on sensitive deployments.
- The passphrase is supplied to the process (
OIGW_PASSPHRASE or a no-echo terminal prompt), never
sent over IRC.
- The IRC listener is loopback-only by default; binding to a non-loopback address without a TLS
terminator is refused unless you pass
-allow-insecure-listen.
- Identity
.olv files (used by olc) and the SQLite store both contain private keys — treat them
accordingly.
Interop & verification
Where the code must match the real apps, it is checked against the vendored reference engines and the
production servers, and pinned with tests: official crypto test vectors (AES-CTR, HMAC, the PRNG),
message/SAS/commitment/device-transfer wire-format audits, and end-to-end runs. The reference is treated
as authoritative over the spec text when they disagree; several interop fixes came from grepping the real
code (attachment descriptor layout, file_name keys, one-to-one identifiers, group ping transport, …).
Documentation
License
BSD 3-Clause — see LICENSE. "Olvid" is a trademark of Olvid SAS; this project is an
independent reimplementation and is not affiliated with or endorsed by them.