docs/ANNOUNCEMENT_GOSSIP.md
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.
type = 0x01 (ANNOUNCE). Header is unchanged.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.Each TLV uses a compact layout:
type: 1 bytelength: 1 byte (0..255)value: length bytesExisting TLVs (unchanged):
0x01 NICKNAME: UTF‑8 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. Assigned bits
match iOS: 0 prekeys, 1 Wi-Fi bulk, 2 gateway, 3 private groups, 4 board,
5 vouch, 6 mesh diagnostics, 7 bridge, 8 authenticated Noise private media,
9 private-media receipts, and 10 reserved non-destructive Noise replacement.
Bit 8's exact value is 00 01. An empty value is valid and means no
advertised capabilities. For this announcement TLV, unknown bits and bytes
beyond the low 64 bits must be tolerated for forward compatibility. This
tolerance does not apply to the Noise-authenticated peer-state payload
0x21, whose capability field must be canonical and 1...8 bytes; see
PRIVATE_MEDIA_V1.md.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 IDs are represented as 8 raw bytes (16 hex chars) in “network order” (left‑to‑right):
0x00 at the end to reach 8 bytes.This matches the on‑wire 8‑byte senderID/recipientID encoding used in the BitChat packet header.
0x01..0x03 as usual.0x04 with up to 10 unique, directly connected peer IDs.
0x05 with private-media bit 8 set
in every broadcast and peer-directed announcement.0x03.0. This allows TTL to change during relays without invalidating the signature.0x01..0x03 as usual; ignore any unknown TLVs.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.0x21 peer state to prove both bits 8 and 9. An
announcement alone never authorizes that behavior.0x04 TLV is present:
N = length / 8 peer IDs (ignore trailing non‑aligned bytes).0x04.timestamp in the BitChat packet header), replace A’s previously recorded neighbor list with the new one. If older or equal, ignore the neighbor update.{A, B} in your topology visualization; i.e., if A reports direct peers [B, C], add edges A–B and A–C.N ≥ 0 implied by length / 8 up to the received length.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).ANNOUNCE payload TLVs (concatenated):
01 [len=N] [UTF‑8 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 8‑byte binary form of the peer ID as specified above.
That’s the entire change; the outer packet header, message type, and relay/TTL behavior are unchanged.