docs: Layer 2 — CDN-verified FoF comments (per-V_x keypair)

Replace single per-post priv_post with per-V_x (pub_x, priv_x). Post
header publishes pub_post_set; comments declare pub_x_index; CDN
propagation nodes verify group_sig + identity_sig against named pubkey
before forwarding. Kills bandwidth-amplification DoS from admitted-but-
malicious FoF members.

Dual-derivation wrap slot (read → CEK, sign → priv_x) with shared
structure Layer 3 inherits. Comments encrypted under CEK_comments so
Mode 2 comments are genuinely FoF-read-gated, not just FoF-sign-filtered.

Author-signed revocation diff appended to post; CDN honors per-chain
revocation. Tradeoff: pub_x_index is a per-post voucher-chain pseudonym,
re-randomized across posts. Accepted.

Layer 3 banner added noting wrap-slot structure is now superseded by
Layer 2's canonical form; full reconciliation deferred.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Scott Reimers 2026-04-24 08:25:40 -04:00
parent b8b38a6f03
commit 553fbd3a20
4 changed files with 225 additions and 59 deletions

View file

@ -32,7 +32,38 @@ See `CONTRIBUTING.md` for the protocol. See `AGENTS.md` for the Claude-specific
- Opus confirmation passes still open on other layers (WrapSlot byte layout, AEAD choice for body, padding schemes).
- Layer 26 untouched in this pass.
**Stopping point**: merged to master; branch deleted.
**Stopping point**: Scott asked to hold merges until Layers 26 iterations complete. Branch stays open locally and on Forgejo; continuing to stack commits on it.
### Update 2026-04-24 — Layer 2 rewrite (CDN-level verification)
**Scope**: Scott shared Opus's Layer 2 design answer. Folded in.
**Design commitments added**:
- **Per-`V_x` signing keypair `(pub_x, priv_x)`** — replaces single per-post `pub_post/priv_post`. CDN can now verify comment signatures against a published `pub_post_set` before forwarding, killing the bandwidth-amplification DoS an admitted FoF member could otherwise mount.
- **Dual-derivation wrap slot**: `read_slot → CEK`, `sign_slot → priv_x`. One unwrap yields both capabilities. Slot structure is shared with Layer 3 (canonical form lives here).
- **Comment body encrypted under `CEK_comments = HKDF(CEK, "comments")`** — Mode 2 comments are genuinely FoF-read-gated now, not just FoF-sign-filtered at render (strengthening vs skeleton).
- **Propagation-node four-check accept rule**: valid `pub_x_index`, not in `revocation_list`, `group_sig` verifies, `identity_sig` verifies. Any fail → drop without forwarding.
- **Author-signed revocation diff** appended to post header; CDN honors on next sync. Per-chain revocation at propagation layer.
- **`pub_x_index` is a per-post pseudonym** — leaks "these N comments came through the same chain" within a single post; re-randomizes across posts. Accepted tradeoff for CDN-level DoS resistance.
- **v1 ships Ed25519 inline** (~77KB header at 500 vouchees). **PQ future** requires Merkle-commit over `pub_post_set` with per-comment inclusion proofs; deferred but spec shape doesn't preclude.
**Files touched**:
- `docs/fof-spec/layer-2-mode2-fof-comments.md` — rewritten end-to-end.
- `docs/fof-spec/layer-3-mode1-fof-closed.md` — prominent "partially superseded" banner added; body retained pending reconciliation when Scott + Opus review Layer 3.
- `docs/fof-spec/README.md` — glossary updated (`pub_x`/`priv_x`, `pub_post_set`, `revocation_list`); integration bullet updated for new `InlineComment` fields + CDN accept rule.
**Open questions I raised back to Scott** (awaiting his answer before finalizing):
1. `(pub_x, priv_x)` lifecycle: generated at `V_x` genesis (Layer 1) and stable across posts, vs regenerated per-post by author. Lead leaning per-post. Needs confirmation.
2. `pub_post_set` padding vs `wrap_slots` padding — real/dummy alignment when dummies shouldn't be indexable by `pub_x_index`.
3. Non-FoF rendering of comment count (reveal engagement? suppress?).
4. Who holds `priv_me` (author) — generated alongside `V_me` at Layer 1, vs per-post regeneration. Same as #1 but for author's own entry.
**Pending**:
- Scott reviews / answers open questions.
- Layer 3 reconciliation when Scott + Opus get to Mode 1.
- Layers 46 iterations.
**Stopping point**: commit `b8b38a6` (Layer 1) + new commit for Layer 2 both on branch; not merged. Awaiting Scott.
---