Architecture overview

All protocol and crypto logic lives in one Rust library on the device. The servers are deliberately simple: they hold sealed envelopes in mailboxes and hand them back to whoever can prove they may fetch them.

The core Built

pigeon-core is a single Rust crate that every client links: the desktop app, the command-line tool and, later, the phone apps. It does MLS group encryption (OpenMLS), identity, sealing, media encryption and the device store. Clients are thin shells that move bytes between the core, the network and the screen. Keeping the crypto in one place means one implementation to review and one set of test vectors.

Mailbox nodes Built

pigeon-node is a server that stores and forwards opaque bytes. It never parses ciphertext, holds no account database and has no view of MLS framing. Envelopes are stored in an embedded database (redb) with every write committed durably before it's acknowledged, so a node survives a restart or a kill -9 without losing anything it accepted. Clients talk to nodes over HTTP/1.1 on TLS 1.3, with each node's key pinned.

Mailboxes and access Built

A mailbox belongs to a group and an MLS epoch, not to a person. Its id is a hash of a 32-byte capability derived from the MLS exporter secret, so it changes with every epoch and isn't derived from anyone's identity key. To fetch, a client presents the capability; the node checks the hash. To delete an envelope after reading it, the client also presents a per-envelope acknowledgement key that the sender sealed inside the envelope; the node holds only its hash. Invitations to a group arrive in a one-time introduction mailbox named in the recipient's KeyPackage.

Known limits, stated in the design: anyone can currently deposit into a mailbox (deposit tokens are Planned), and members of the same epoch can fetch each other's sealed envelopes, which they can't open beyond what MLS already gives them.

Sealed envelopes Built

Every MLS message is sealed again before it leaves the device, with HPKE (RFC 9180) using X-Wing, a hybrid post-quantum KEM, with HKDF-SHA256 and ChaCha20-Poly1305. The node sees no group id, epoch, content type or sender: only a mailbox id, a size and a time. Full sender anonymity at deposit, using anonymous deposit tokens, is Planned.

The swarm Built

Each mailbox lives on five nodes chosen by rendezvous hashing: every node gets the score SHA-256("pigeon/placement/v2" || node_id || mailbox_id), and the five highest win. A node's id is the hash of its TLS public key, so a node can't claim another's place. A send succeeds when three of the five acknowledge it. Nodes never sync with each other; the client reads from all five, repairs any gaps it sees, and acknowledges everywhere. Delivery keeps working with two of five nodes down.

Today the node list is static. A public node registry, and defences against one operator running many nodes, are Planned.

Where to go next

Sources: ADR-0001 (mailbox addressing and access), ADR-0002 (swarm placement and replication), ADR-0004 (node persistence); crates/pigeon-core/src/seal.rs, crates/pigeon-core/src/placement.rs.