feat: add protocol test vectors generated from the reference implementation

Known-answer tests for every part of the protocol that produces bytes: key
derivation, sealed envelopes with their intermediate values, accept tokens,
session and registration frames, rotation certificates, frontmatter parsing,
and the inputs a conformant implementation must refuse.

vectors.py derives every value by calling smolmail.py, so the vectors cannot
drift from the code, and verifies each one from the opposite side before
emitting it. --check regenerates and diffs against the committed files.

Verified independently: a checker written against SPEC.md and libsodium alone,
without importing the reference, reproduces all 81 values.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
randogoth 2026-10-14 16:05:23 +03:00
parent 43e4be2b8a
commit 9d5908104e
4 changed files with 2216 additions and 1 deletions

View file

@ -84,6 +84,19 @@ A security review of the protocol and these reference implementations found no i
[SPEC.md](SPEC.md) defines the wire format, the operations and the trust model.
## Test vectors
[VECTORS.md](VECTORS.md) is a set of known-answer tests for every part of the protocol that produces bytes: key derivation, sealed envelopes with their intermediate values, accept tokens, the session and registration frames, rotation certificates, frontmatter parsing, and the inputs a conformant implementation must refuse. [vectors.json](vectors.json) carries the same values for a test harness to load.
[vectors.py](vectors.py) generates both from `smolmail.py`, so they cannot drift from the code, and verifies every vector from the opposite side before emitting it. `uv run vectors.py --check` regenerates and compares against the committed files:
```
uv run vectors.py # write vectors.json and VECTORS.md
uv run vectors.py --check # verify the committed files still reproduce
```
Start from the `unpadded` envelope. If its `seal_key` matches and the envelope does not, the fault is in the payload layout; if `x25519_shared` already differs, it is in the §2 key map.
## Inspiration
The smolmail project takes inspiration from [Gemini Protocol](https://geminiprotocol.net), [Misfin](gemini://misfin.org/), and [LXMF](https://github.com/markqvist/lxmf).
@ -92,4 +105,4 @@ The smolmail project takes inspiration from [Gemini Protocol](https://geminiprot
The protocol definition, [SPEC.md](SPEC.md), is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license ([CC BY-SA-4.0](LICENSES/CC-BY-SA-4.0.txt)).
The reference code, `smolmail.py`, `smolmaild.py`, `smolmail_rns.py` and `smolmaild_rns.py`, is licensed under the Apache License 2.0 ([Apache-2.0](LICENSES/Apache-2.0.txt)).
The reference code, `smolmail.py`, `smolmaild.py`, `smolmail_rns.py`, `smolmaild_rns.py` and `vectors.py`, is licensed under the Apache License 2.0 ([Apache-2.0](LICENSES/Apache-2.0.txt)). The vectors it generates, [VECTORS.md](VECTORS.md) and [vectors.json](vectors.json), are licensed with the specification.