58 lines
3.5 KiB
Markdown
58 lines
3.5 KiB
Markdown
# Smol Mail
|
|
|
|
A minimalist, decentralized, end-to-end encrypted mail protocol.
|
|
|
|
Email should be simple again. Inspired by [Spartan](spartan://spartan.mozz.us/), [Misfin](gemini://misfin.org/), and [LXMF](https://github.com/markqvist/lxmf). Smol Mail reduces electronic correspondence to its essentials: an address, a key and a message. One keypair per user, five operations, one binary message format. No sprawling infrastructure, no proprietary accounts, no advertising, no tracking. Anyone can run a server, anyone can write a client, and only the intended recipient can read a message.
|
|
|
|
A server learns which mailbox a message is for, how big it is and when it arrived. Nothing else — not the sender, not the subject, not the content.
|
|
|
|
- **Minimal** — five operations, four primitives, no extensibility mechanisms.
|
|
- **Private** — messages are sealed and signed; senders are absent from the wire format.
|
|
- **Decentralized** — independent servers, no federation, no directories.
|
|
- **Portable** — identity is a keypair, not an account.
|
|
|
|
## Identity
|
|
|
|
Identity is one Ed25519 keypair. The 32-byte public key *is* the identity; the 32-byte seed is the only secret to back up. Encryption keys are derived from the same keypair, so there is exactly one thing to hold, move between servers, print on paper or scan from a screen.
|
|
|
|
Signatures prove authorship. A throwaway key per message means a stolen identity key cannot decrypt anything already sent.
|
|
|
|
## Addressing
|
|
|
|
```
|
|
alice@example.org short form, resolved via the server
|
|
smol://alice@example.org/mfrggzdfmztwq2lknnwg23tpo… self-certifying, carries its own key
|
|
```
|
|
|
|
The short form is typeable. The long form carries the key itself, so an address shared by QR code, contact file or link needs no trust in any server at all. Either way, changing servers never changes an identity.
|
|
|
|
Keys learned from a server are pinned on first use. Later changes need a rotation certificate signed by the previous key, or explicit confirmation.
|
|
|
|
## Cryptography
|
|
|
|
Ed25519 · X25519 · ChaCha20-Poly1305 · SHA-256. Four established primitives, no novel cryptography, nothing else anywhere in the protocol. Transport is TCP with a Noise handshake — no certificates, no CA, no expiry.
|
|
|
|
## What is not protected
|
|
|
|
Traffic analysis, delivery timing, mailbox size, and whether a user has an account on a given server. Run a server as a Tor onion service for metadata resistance; the transport needs no changes for it.
|
|
|
|
There is no forward secrecy on the recipient side: a seized recipient key decrypts ciphertext recorded while it was valid. Messages are signed, so they carry non-repudiation rather than deniability.
|
|
|
|
Version 1 excludes attachments, group messaging, federation, anonymous routing, multi-device synchronisation and key revocation.
|
|
|
|
## Reference server
|
|
|
|
[smolmaild.py](smolmaild.py) is a complete server in one file. It declares its own dependencies inline, so there is nothing to install:
|
|
|
|
```
|
|
uv run smolmaild.py keygen
|
|
uv run smolmaild.py serve
|
|
```
|
|
|
|
`keygen` writes the server's static key to `server.key` and prints its public key in base32. Publish that public key through a trusted channel — clients pin it, and a mismatch aborts the handshake.
|
|
|
|
`serve` listens on `127.0.0.1:1961` by default and stores mail in `mail.db`. Use `--host 0.0.0.0` to accept remote connections, and `--invite-token` to close registration. `--help` lists the size, quota, retention and rate limits.
|
|
|
|
## Specification
|
|
|
|
[SPEC.md](SPEC.md) — wire format, operations, trust model and conformance.
|