docs: Layer 3 round 1 + unified hybrid padding rule
Hybrid padding rule (slots + body, same shape): - <=256 real units: pad to next power of 2 (8, 16, ..., 256) - >256 real units: pad to real + rand(0..=256) / nearest 256KB Replaces Layer 2 round 2's rand(32..=128). Small authors/posts get strong bucket-grouping; large authors/posts get probabilistic noise without 2x bandwidth waste of pure power-of-2 at scale. Layer 3 resolutions: - Custom mode deferred; v1 ships Public / Friends-only / FoF only - Slot dedup at V_x byte level (one slot per unique key) - Body-length padding adopted Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a79cab049f
commit
3ee20736aa
3 changed files with 51 additions and 13 deletions
|
|
@ -35,7 +35,7 @@ Cost: `pub_x_index` is a per-post pseudonym for the voucher-chain — leaks "the
|
|||
- **Comments are encrypted.** `CEK_comments = HKDF(CEK, "comments")`. Non-FoF observers see only ciphertext + signatures on comments. Read-gating is a side effect of the same slot unwrap.
|
||||
- **CDN propagation verifies before forwarding.** Four-check accept rule: valid `pub_x_index`, not in `revocation_list`, `group_sig` validates, `identity_sig` validates. Any failure → drop, do not propagate.
|
||||
- **Revocation is retroactive.** Revocation diff is author-signed, appends a revoked `pub_x` entry. Every file-holder that receives the diff **deletes all comments on this post signed by that `pub_x`** from local storage, then forwards the diff. Comments in flight before the diff arrived get deleted when it catches up. Stronger than "stop forwarding" — prior garbage also goes away.
|
||||
- **Random-count dummy padding, not fixed buckets.** Append `rand(32..=128)` dummy slots (each real-shape, indistinguishable). Observers know a random amount was added; they cannot infer the floor count across multiple posts from the same author. Dummy `pub_x` entries are included in `pub_post_set` 1:1 so `pub_post_set.len() == wrap_slots.len()`; dummy pubkeys are 32B random bytes (no one holds the matching `priv_x`, so `group_sig` verify against a dummy always fails — benign).
|
||||
- **Hybrid slot-count padding.** Up to 256 real slots: pad to next power of 2 (smallest authors get strong bucket-grouping; e.g., 5 real → 8 published, 100 real → 128 published, 200 real → 256 published). Above 256 real slots: pad to `real_count + rand(0..=256)` (large authors get probabilistic noise; power-of-2 jumps would waste up to 50%). Dummy `pub_x` entries are included in `pub_post_set` 1:1 so `pub_post_set.len() == wrap_slots.len()`; dummy pubkeys are 32B random bytes (no one holds the matching `priv_x`, so `group_sig` verify against a dummy always fails — benign).
|
||||
- **Post-hoc read-access grant via author comment.** Author can widen the read-set of an already-published post by publishing an author-signed special comment that appends a new `WrapSlot` (and its `pub_post_set` entry) for a newly-vouched persona. No rotation, no republish; retroactive inclusion. See "Access-grant author comment" below.
|
||||
- **`vouch_mac` retained.** Inside ciphertext. Enables author render-time and intra-circle attribution complementary to CDN-level `pub_x_index` attribution.
|
||||
- **Author has their own `pub_me/priv_me`.** Treated as one of the entries in `pub_post_set`. Author signs their own comments through the same path.
|
||||
|
|
@ -246,7 +246,7 @@ struct AccessGrantComment {
|
|||
| `prefilter_tag` | 2 |
|
||||
| **Subtotal per slot** | **~154** |
|
||||
|
||||
At 500 real vouchees + `rand(32..=128)` dummies: header payload is 532–628 slots × ~154B = ~82KB to ~97KB. Acceptable for a header carried once per post.
|
||||
At 500 real vouchees (above the 256 inflection point): pad to `500 + rand(0..=256)` = 500–756 slots × ~154B = ~77KB to ~117KB. At 200 real vouchees: pad to 256 = ~39KB. At 9 real vouchees: pad to 16 = ~2.5KB. Acceptable for a header carried once per post.
|
||||
|
||||
Per-comment CDN overhead (vs shared-keypair baseline): +64B (`group_sig`) + 4B (`pub_x_index`) + 64B (`identity_sig` — already in baseline) ≈ 68B additional. Negligible.
|
||||
|
||||
|
|
@ -266,7 +266,11 @@ Decision: **defer Merkle variant to PQ migration**. v1 ships inline.
|
|||
|
||||
The reason this is acceptable: the alternative is no propagation-level verification, which means any one admitted FoF member can DoS the mesh. Per-post pseudonym is the minimum viable disclosure for CDN-level filtering.
|
||||
|
||||
**Vouch-set size:** random `rand(32..=128)` dummy padding means an observer sees `real_count + rand(32..=128)` and cannot infer the true count. Across multiple posts from the same author, the observer also cannot establish a lower bound — each post's padding is independent, so the minimum observed size across many posts only converges to `real_count + 32`, not to `real_count`.
|
||||
**Vouch-set size:** hybrid padding behaves differently in two regimes.
|
||||
- **Small authors (≤256 real slots)** publish a power-of-2 count. Observer learns the bucket (e.g., `published == 128` → `real_count ∈ (64, 128]`). Bucket boundaries are 8, 16, 32, 64, 128, 256. Within-bucket count is fully hidden.
|
||||
- **Large authors (>256 real slots)** publish `real_count + rand(0..=256)`. Each post leaks an upper bound on real_count. Across many posts, an observer's best floor estimate is `min(published_i) - 256`, which doesn't converge tighter without independent side information.
|
||||
|
||||
Small-author bucket boundaries are a known cost; large authors trade off a coarser noise floor against bandwidth. Both regimes hide the true count within meaningful brackets.
|
||||
|
||||
**Non-FoF reader UX:** non-FoF readers see the public body + "Comments are private" affordance. Comment count is not shown (no engagement leak). Optional: a "Request access via DM" button that sends the author a note; author can respond by publishing an access-grant author comment (above) that retroactively admits the requester.
|
||||
|
||||
|
|
@ -302,6 +306,6 @@ The reason this is acceptable: the alternative is no propagation-level verificat
|
|||
- Revocation diff format + CDN honor path (retroactive delete + forward).
|
||||
- Access-grant author comment mechanism for post-hoc read widening.
|
||||
- Per-post ephemeral-keypair generation.
|
||||
- Random-count dummy padding `rand(32..=128)` on both `wrap_slots` and `pub_post_set`, shuffled together.
|
||||
- Hybrid dummy padding on both `wrap_slots` and `pub_post_set` (power-of-2 up to 256, then `count + rand(0..=256)`), shuffled together.
|
||||
- Back-compat: old clients can still render existing non-FoF posts; old comments on new FoF posts are rejected at CDN (missing required fields).
|
||||
- Integration test: 3-node FoF chain (A→B→C). A posts Mode 2 FoF. B comments (accepted, propagates). C comments (accepted via B's chain). D (unrelated) signs junk with fake `pub_x_index` pointing at a real entry (rejected at first-hop CDN: `group_sig` fails). D signs junk with `pub_x_index` pointing at a dummy (rejected: `group_sig` fails against a dummy random pubkey). A revokes B's `pub_x`: B's already-propagated comments are deleted on each file-holder as the diff sweeps through; B's subsequent comments rejected at first hop. A vouches for E after the post is live and publishes access-grant author comment; E can now read + comment retroactively.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue