Files
bitchat-android/docs/ANNOUNCEMENT_GOSSIP.md
T

100 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Announcement Gossip TLV (Direct Neighbors)
This document specifies an optional TLV extension to the BitChat `ANNOUNCE` message that allows peers to gossip which other peers they are currently connected to directly over Bluetooth. Implementations can use this to build a mesh topology view (nodes = peers, edges = direct connections).
Status: optional and backward-compatible.
## Layering Overview
- Outer packet: BitChat binary packet with `type = 0x01` (ANNOUNCE). Header is unchanged.
- Payload: A sequence of TLVs. Unknown TLVs MUST be ignored for forward compatibility.
- Signature: The packet is signed using the Ed25519 public key carried in TLV
`0x03`. The gossip and capability TLVs are part of the payload and therefore
covered by the signature. Current clients require a valid signature before
applying identity or capability state.
## TLV Format
Each TLV uses a compact layout:
- `type`: 1 byte
- `length`: 1 byte (0..255)
- `value`: `length` bytes
Existing TLVs (unchanged):
- `0x01` NICKNAME: UTF8 string (≤ 255 bytes)
- `0x02` NOISE_PUBLIC_KEY: Noise static public key bytes (typically 32 bytes for X25519)
- `0x03` SIGNING_PUBLIC_KEY: Ed25519 public key bytes (typically 32 bytes)
Other optional extension:
- `0x05` CAPABILITIES: Minimal little-endian feature bitfield. Bit 8 advertises
authenticated Noise private media (`PRIVATE_MEDIA_V1`); its exact value is
`00 01`. An empty value is valid and means no advertised capabilities.
New TLV (optional):
- `0x04` DIRECT_NEIGHBORS: Concatenation of up to 10 peer IDs, each encoded as exactly 8 bytes. There is no inner count; the number of neighbors is `length / 8`. If `length` is not a multiple of 8, trailing partial bytes MUST be ignored.
### Peer ID Binary Encoding (8 bytes)
Peer IDs are represented as 8 raw bytes (16 hex chars) in “network order” (lefttoright):
- Take the peer ID hex string, lowercase/truncate to at most 16 hex chars.
- Convert each 2 hex chars to 1 byte from left to right.
- If fewer than 16 hex chars are available, pad the remaining bytes with `0x00` at the end to reach 8 bytes.
This matches the onwire 8byte `senderID`/`recipientID` encoding used in the BitChat packet header.
## Sender Behavior
- Build the base announcement payload by emitting TLVs `0x01`..`0x03` as usual.
- Optionally append TLV `0x04` with up to 10 unique, directly connected peer IDs.
- Remove duplicates before encoding.
- Order is arbitrary and not semantically significant.
- Current capable senders also include TLV `0x05` with private-media bit 8 set
in every broadcast and peer-directed announcement.
- Sign the ANNOUNCE packet so all extension TLVs are covered:
- Signature algorithm: Ed25519 using the key in TLV `0x03`.
- Signature input: the binary packet encoding with the signature field omitted and the TTL normalized to `0`. This allows TTL to change during relays without invalidating the signature.
- The payload may be compressed per the base protocol; the gossip TLV is encoded prior to optional compression.
## Receiver Behavior
- Decompress payload if the packets compression flag is set, then parse TLVs in order.
- Parse TLVs `0x01`..`0x03` as usual; ignore any unknown TLVs.
- Parse TLV `0x05`, when present, as a little-endian bitfield. Absence and an
explicitly empty value remain valid legacy capability states. A
security-sensitive bit is trusted only after the signed announcement key is
bound to the matching remote static key from a live Noise handshake; see
`PRIVATE_MEDIA_V1.md`.
- If a `0x04` TLV is present:
- Interpret the value as `N = length / 8` peer IDs (ignore trailing nonaligned bytes).
- Each 8byte chunk is decoded back to a 16hexchar peer ID string (lowercase).
- Deduplicate neighbors.
- Topology maintenance guidance (optional, but recommended for consistent behavior):
- Maintain, for each announcing peer A, the last announcement timestamp and the neighbor list from TLV `0x04`.
- When a newer announcement from A arrives (use the 8byte unsigned `timestamp` in the BitChat packet header), replace As previously recorded neighbor list with the new one. If older or equal, ignore the neighbor update.
- Treat the neighbor list as a set of undirected edges `{A, B}` in your topology visualization; i.e., if A reports direct peers `[B, C]`, add edges AB and AC.
## Limits and Compatibility
- Max neighbors per TLV: 10. Senders MAY send fewer; receivers MUST accept any number `N ≥ 0` implied by `length / 8` up to the received `length`.
- Omission: If the TLV `0x04` is omitted, the announce remains valid. Peers can still chat and interoperate normally; the topology graph will just not include edges reported by that peer (other peers that include A in their neighbor lists can still introduce edges to A).
- Unknown TLVs MUST be ignored. This makes the extension safe for older implementations.
## Minimal Example (conceptual)
ANNOUNCE payload TLVs (concatenated):
- `01 [len=N] [UTF8 nickname]`
- `02 [len=32] [32 bytes X25519 pubkey]`
- `03 [len=32] [32 bytes Ed25519 pubkey]`
- `04 [len=8*M] [peerID1(8) || peerID2(8) || ... || peerIDM(8)]` (optional)
- `05 02 00 01` (optional private-media-v1 capability)
Where each `peerIDk(8)` is the 8byte binary form of the peer ID as specified above.
Thats the entire change; the outer packet header, message type, and relay/TTL behavior are unchanged.