ForumClient is a BSP client that synchronises forum posts among groups of devices. Any subscriber to a forum can invite new subscribers, and any subscriber can post to the forum. Posts may be anonymous or signed.
Implementation note: We propose to use Ed25519 for signatures.
Each forum has its own group. The group descriptor is a BDF list with two elements: title (string) and salt (raw). The salt is HASH_LEN random bytes, to prevent collisions between forums with the same title.
For exchanging invitations, the client uses a separate group for each pair of contacts. The group descriptor is a BDF list containing the unique IDs of the contacts' identities, sorted in ascending order as byte strings.
0: INVITATION - The content is a BDF list with three elements: title (string), salt (raw), and note (string or null). The identifier of the forum group to which the invitation refers can be calculated from title and salt, as described above. note is an optional note from the inviter to the invitee.
1: RESPONSE - The content is a BDF list with three elements: invitation_id (raw), decision (boolean), and note (string or null). invitation_id is the identifier of an invitation created by the opposite peer. decision indicates whether the invitee wishes to subscribe. note is an optional note from the invitee to the inviter.
2: DEPARTURE - The content is a BDF list with one element: invitation_id (raw), which is the identifier of an invitation created by either peer.
3: POST - The content is a BDF list with three elements: author (list or null), content (list), and signature (raw or null).
author is a list with two elements: name (string) and public_key (raw).
content is a list with three elements: parent_id (raw or null), content_type (string), body (raw), and attachments (dictionary or null). parent_id is the identifier of a post to which this is a response. Each key in attachments is the name of an attachment, and the value is a list with two elements: content_type (string) and message_id (raw).
signature is a signature over a list with five elements: group_id (raw), timestamp (int), author (list), and content (list). group_id and timestamp are taken from the message header. author and content are described above.
If author and signature are null, the post is anonymous.
4: ATTACHMENT - The content is raw data.
An invitation or response must belong to an invitation group.
A post or attachment must belong to a forum group.
An invitation is valid if it is well-formed.
A response is valid if it is well-formed and it references a valid invitation created by the opposite peer.
A departure is valid if it is well-formed and it references a valid invitation created by either peer.
A post is valid if it is well-formed, its parent (if any) is a valid post, and it is either anonymous or carries a valid signature.
An attachment is always valid.
Note that a post can be validated before its attachments have been received, and an attachment can be validated before it has been completely received.