mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-27 12:45:20 +00:00
docs: record that padding changes are cross-platform coordinated
O7 began as a question about whether Android tolerates trailing bytes. The firmer answer, found while attempting the padding fix unilaterally: toBinaryDataForSigning encodes with padding enabled, so the padding bytes are inside the signed material for every signed packet. Changing the algorithm changes the signed byte stream and breaks verification against any peer that has not made the identical change. So both outstanding padding fixes — coverage beyond Noise frames, and the gap where a frame needing over 255 bytes of padding ships unpadded — are wire changes requiring both platforms, not local cleanups. O7 now says so, and names the two things to settle. Also updates the related-work section: dropping the neighbour list and randomizing origin TTL did turn out to be unilateral and have landed separately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -323,14 +323,13 @@ Still to be written jointly: a full `announceV2` packet as a hex blob, and the
|
||||
- **O4 — Unsigned v2 announces.** Binding tags to the announced peer ID removes impersonation-as-any-ID, but a recorded announce can still be rebroadcast verbatim within the epoch window, so a peer can be made to look present when absent. Is "presence is a hint; nothing consequential until a handshake whose static key matches the favourite that produced the match" acceptable? The alternatives are an ephemeral per-epoch signing key with a proof-of-continuity, or a freshness nonce echoed by the recipient — both more machinery and more bytes.
|
||||
- **O5 — Rotation while a session is live.** Defer rotation until sessions are idle, or rotate and migrate? Deferring is simpler and safer, but a long-lived session pins the ID for its lifetime, which weakens G1 for exactly the people who talk most.
|
||||
- **O6 — Nickname timing.** Moving the nickname into the session means a stranger's name appears only after a handshake. Is that acceptable UX on both platforms, or does the peer list need a "someone nearby" placeholder state?
|
||||
- **O7 — Android decoder tolerance.** iOS `BinaryProtocol.decodeCore` accepts trailing bytes (`guard offset <= buf.count`) and `decode` also retries after unpadding. Both matter for extending padding to more packet types. Does the Android decoder tolerate trailing bytes the same way? If not, padding coverage has to be gated on the capability bit too.
|
||||
- **O7 — Padding is a coordinated change, not a local one.** This started as a question about decoder tolerance and turned into something firmer. `BitchatPacket.toBinaryDataForSigning()` encodes with padding enabled, so **the padding bytes are inside the signed material for every signed packet**. Changing the padding algorithm therefore changes the signed byte stream, and signatures stop verifying against any peer that has not made the identical change. Both outstanding padding fixes are affected: extending coverage beyond `noiseEncrypted`/`noiseHandshake`, and closing the gap where a frame needing more than 255 bytes of padding is emitted unpadded (payloads of 241–256, 497–768 and 1009–1792 bytes ship at exact length today). Two things to settle: whether Android's decoder also tolerates trailing bytes the way iOS's does (`guard offset <= buf.count`, plus an unpad retry), and whether padding changes ride this protocol revision or get their own capability-gated one.
|
||||
|
||||
## 9. Relationship to other work
|
||||
|
||||
Rotation is the largest item in the radio-layer metadata cluster but not the only one, and the others are cheaper:
|
||||
|
||||
- **Drop the neighbour list** — backward compatible today, no agreement needed, removes the adjacency-graph leak.
|
||||
- **Randomize origin TTL** — packets currently leave at the default TTL, so `ttl == default` marks the originating hop to any direct listener.
|
||||
- **Extend padding beyond Noise frames, and fix the length-marker gap** — only `noiseEncrypted` and `noiseHandshake` are padded, and `pad` silently declines when the required padding exceeds the single-byte marker, so frames well below their bucket ship unpadded. Subject to O7.
|
||||
- **Drop the neighbour list** and **randomize origin TTL** — both landed separately, since neither needs agreement: see the radio-metadata PR.
|
||||
- **Extend padding beyond Noise frames, and fix the length-marker gap** — only `noiseEncrypted` and `noiseHandshake` are padded, and `pad` silently declines when the required padding exceeds the single-byte marker, so frames well below their bucket ship unpadded. **Not unilateral**: padding is inside the signed bytes, so this needs both platforms. See O7.
|
||||
|
||||
None of these substitute for rotation, and rotation does not substitute for them: a device with a rotating ID that still publishes its neighbour list, or that still marks its own originated packets by TTL, remains linkable.
|
||||
|
||||
Reference in New Issue
Block a user