docs: ADR for a post-quantum bootstrap epoch (epoch 0) #190

Merged
sirius merged 2 commits from onionwire/t_8fb1a517-decision-doc-post-quantum-bootstrap-epoc into main 2026-10-24 22:10:48 +00:00
Owner

What

Adds docs/design/pq-bootstrap-epoch.md, an ADR for the ratchet bootstrap epoch (epoch 0). Docs only: no src/, no protocol change, no behavior change.

Decision

Option C — accept the window, with named revisit triggers. The doc states the invariant first (each chat message is its own one-shot Noise session, and either peer may send first with no wire field), then evaluates:

  • A — one-time prekey batch in the invite
  • B — per-session epoch derivation with an extra wire field
  • C — accept the window and keep the current honesty bounds

A does not fix epoch 0: an ML-KEM encapsulation is randomised, so a prekey secret can only reach the peer through a wire field, which is B — and B cannot converge under both-send-first (the first rotator may not have the peer's salt, so the root stops being a pure function of the pair). A batch is also not representable: a v2 invite is 1930 chars, each ML-KEM-768 OPK adds 1584, MAX_INVITE is 4096, and the TUI QR path (qrcode 0.14.1, EcLevel::M) caps at 2331 bytes — measured, not recalled.

Verification

  • git diff --stat -> docs/design/pq-bootstrap-epoch.md | 301 +++..., 1 file changed, 301 insertions(+)
  • grep -c '' docs/design/pq-bootstrap-epoch.md -> 301
  • No source path, existing doc, workflow, or Cargo file touched.
## What Adds `docs/design/pq-bootstrap-epoch.md`, an ADR for the ratchet bootstrap epoch (epoch 0). Docs only: no `src/`, no protocol change, no behavior change. ## Decision **Option C — accept the window**, with named revisit triggers. The doc states the invariant first (each chat message is its own one-shot Noise session, and either peer may send first with no wire field), then evaluates: - **A — one-time prekey batch in the invite** - **B — per-session epoch derivation with an extra wire field** - **C — accept the window and keep the current honesty bounds** A does not fix epoch 0: an ML-KEM encapsulation is randomised, so a prekey secret can only reach the peer through a wire field, which is B — and B cannot converge under both-send-first (the first rotator may not have the peer's salt, so the root stops being a pure function of the pair). A batch is also not representable: a v2 invite is 1930 chars, each ML-KEM-768 OPK adds 1584, `MAX_INVITE` is 4096, and the TUI QR path (`qrcode` 0.14.1, `EcLevel::M`) caps at 2331 bytes — measured, not recalled. ## Verification - `git diff --stat` -> `docs/design/pq-bootstrap-epoch.md | 301 +++...`, 1 file changed, 301 insertions(+) - `grep -c '' docs/design/pq-bootstrap-epoch.md` -> 301 - No source path, existing doc, workflow, or Cargo file touched.
Records why epoch 0 is prekey-derived: one-shot Noise sessions plus
both-send-first convergence forbid a per-session secret with no wire field.
Evaluates a one-time prekey batch in the invite, a per-session epoch field in
the hybrid header, and accepting the window; picks accept with named revisit
triggers. No code or protocol change.

Measured facts used: v2 invite is 1930 chars; each ML-KEM-768 OPK adds 1584
base64url chars; MAX_INVITE is 4096; the TUI QR path (qrcode 0.14.1,
EcLevel::M) caps at 2331 bytes.
Merge branch 'main' into onionwire/t_8fb1a517-decision-doc-post-quantum-bootstrap-epoc
Some checks failed
android-ci / android (pull_request) Has been cancelled
ci / sdk (pull_request) Has been cancelled
ci / test (pull_request) Has been cancelled
d1a8aeccd0
sirius merged commit 56c0b67cdf into main 2026-10-24 22:10:48 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
sirius/onionwire!190
No description provided.