From 20a352e53a2e93cb38c6587e7821d8d90da79956 Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Thu, 4 Jun 2026 16:26:43 +0300 Subject: [PATCH 1/4] docs(messaging): copy remaining specs verbatim from logos-messaging/specs Pristine copies of the last messaging specs not covered by #315/#331, imported as-is from logos-messaging/specs so the adaptation diff is isolated in the following commit: - chat-framework (logos-messaging/specs#81) - privatev1 (logos-messaging/specs#93) - introduction-encoding (logos-messaging/specs#101) - contentframe (logos-messaging/specs#82) Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/messaging/raw/chat-framework.md | 137 +++++++ docs/messaging/raw/contentframe.md | 179 +++++++++ docs/messaging/raw/introduction-encoding.md | 153 +++++++ docs/messaging/raw/privatev1.md | 417 ++++++++++++++++++++ 4 files changed, 886 insertions(+) create mode 100644 docs/messaging/raw/chat-framework.md create mode 100644 docs/messaging/raw/contentframe.md create mode 100644 docs/messaging/raw/introduction-encoding.md create mode 100644 docs/messaging/raw/privatev1.md diff --git a/docs/messaging/raw/chat-framework.md b/docs/messaging/raw/chat-framework.md new file mode 100644 index 000000000..b0a020c72 --- /dev/null +++ b/docs/messaging/raw/chat-framework.md @@ -0,0 +1,137 @@ +--- +title: CHAT-FRAMEWORK +name: A modular framework for defining chat protocols +category: Information +status: raw +tags: chat +editor: Jazz Alyxzander +contributors: +--- +# Abstract + +This specification defines a modular communication protocol framework for describing chat protocols. It introduces abstraction boundaries, and a component model for describing chat protocol functionality. + + +# Background / Rationale / Motivation + +Chat protocols specifications can be long and dense documents. To fully describe a chat protocol there are many layers and operations which are required to be documented. This includes payloads, message transport, encryption as well as user level features such as account registration, typing indicators, content formatting. + +With the vast amount of information required to maintain compatibility between applications - protocol documentation is either comprehensive which leads to large monolithic specifications or lacking the required details for interop between implementors. A suitable solution would provide both the specificity while also remaining lean and focused. + +# Theory / Semantics + +This specification defines an abstract framework for building a chat protocol. Its purpose is to name the distinct components/phases, and define modular boundaries between them to promote reuse. The end result is that a chat protocol implementation can be described by listing its approach to 5 things. + +The lifecycle of a protocol instance is divided into three phases: + +- **Discovery:** How does a Sender learn of other clients. +- **Initialization:** How does a Recipient learn a client wants to communicate with them. +- **Operation:** How do participants exchange content. + +and transport details are divided into 2 components: + +- **Delivery Service:** How are payloads routed and delivered to a client. +- **Framing Strategy:** How are payloads encoded. + +Defining these 5 parameters allows for chat protocol implementations to be fully defined, which allows clients from different applications to exchange messages. +While also dividing documents by their focus area. + +## Abstract Transport + +### Delivery service + +A Delivery Service (DS) is the service or method that distributes payloads to clients. A DS accepts payloads with a delivery_address and delivers them to all subscribers of that delivery_address. Protocols use delivery_addresses to establish delivery contracts between senders and recipients. The mapping of delivery_addresses to DS-level concepts is implementation-specific. + +#### Requirements + +- A DS MUST provide a method for clients to subscribe to messages from a delivery_address +- Payloads sent to a delivery_address are delivered by a DS to all subscribers of that delivery_address +- A DS SHOULD handle segmentation if the underling transport limits message sizes +- A DS MAY NOT guarantee message delivery +- A DS MAY NOT guarantee message ordering +- A DS MAY reject payloads + + +### Framing Strategy + +In this protocol framework, payloads from multiple protocols are potentially multiplexed over the same channel. This requires that clients are able to associate a given payload to a given instance of a protocol. + +A framing strategy should define a common payload type as well as a method to determine which state machine a receiving client must use to decode it. + + +## Protocol Phases + +In order to exchange content clients must be able to learn of each others existence, gather the pre-requisite information/parameters and, remain synchronized over time. + +The lifecycle of a protocol instance is divided into three phases, which are described by a corresponding protocol. + +- **Discovery Phase:** Discovery Protocol +- **Initialization Phase:** Initialization Protocol +- **Operation Phase:** Conversation Protocol + +```mermaid +sequenceDiagram + participant D as ??? + participant S as Saro + participant R as Raya + + + Note over D,S: Discovery + D -->> S: + + Note over R,S: Initialization + S ->> R: Invite + + Note over R,S: Operation + + loop + par + R->> S: Send Message + and + S->> R: Send Message + end + end +``` + + + +### Discovery Protocol + +A discovery protocol defines how clients gather the prerequisite information to contact another client. + +The input requirements of the discovery protocol are not defined here, and largely determined by the desired user experience. + +The output requirements of the discovery protocol are very implementation specific, and will depend on the initialization protocol requirements and DS chosen by the implementation. The data provided by the discovery protocol and required by the initialization protocol is called the `IntroductionBundle`. + +- The discovery protocol MUST provide all data required for the initialization protocol. + +Note: There is no requirement that the Discovery protocol be neither a complicated nor interactive process. Hypothetically If all required values to construct a IntroductionBundle could be statically defined, that would be sufficient for this definition. + +### Initialization Protocol + +A initialization protocol specifies how two clients can initiate communication. The input to this process is the `IntroductionBundle` and the output is an established instance of a `Conversation` between the participants. + +The core of an initialization protocol is a defined location and procedure for receiving initial messages. + +Many chat protocols choose to define the initialization protocol within the conversation protocol. This tight coupling produces two negative artifacts. +- New conversation protocols must define and deploy there own initialization channels. Increasing overhead and adding complexity. +- Protocol upgrades then create partitions in the communication network, as older clients have no means of communicating with new clients. + +Separating channel initialization from conversation flow allows multiple conversations to reuse the same initialization channel. This reduces effort for new conversation protocols, and is especially valuable when upgrading existing ones. Being independent the initialization pathway can persist across conversation versions. Even if an older client cannot parse new message types, it can still recognize their presence, adding observability. + +### Conversation Protocol + +A conversation protocol defines how messages flow between participants, and subsequently determines the properties of that channel. + +- A Conversation protocol MUST define the payloads it uses and how to handle them. +- A Conversation protocol SHOULD outline the cryptographic properties provided +- A Conversation protocol SHOULD describe bidirectional communication. +- A Conversation protocol ... + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +## References + +A list of references. diff --git a/docs/messaging/raw/contentframe.md b/docs/messaging/raw/contentframe.md new file mode 100644 index 000000000..c66230df2 --- /dev/null +++ b/docs/messaging/raw/contentframe.md @@ -0,0 +1,179 @@ +--- +title: CONTENTFRAME +name: +category: Standards Track +tags: +editor: Jazzz +contributors: +--- + +## Abstract + +This specification defines ContentFrame, a self-describing message format for decentralized chat networks. +ContentFrame wraps content payloads with metadata identifying their type and governing specification repository. +Using a `(domain, tag)` tuple, applications can uniquely identify message types and locate authoritative documentation for parsing unfamiliar content. +This approach enables permissionless innovation while maintaining the context needed for interoperability, allowing applications to gracefully handle messages from sources they don't explicitly know about. + +## Motivation + +In an interoperable chat network, participants cannot be assumed to use the same software to send and receive messages. +Users may employ different versions of the same application or different applications entirely. +This heterogeneity creates a fundamental challenge: how can applications support extensible message types without prior knowledge of every possible format? + +Two naive approaches each have significant drawbacks: + +**Developer-defined types** would allow flexibility but create fragmentation. +When developers define their own message types, the context for parsing these messages remains tightly coupled to the software that created them. +Other applications receiving these messages lack the necessary context to interpret them correctly. +This leads to multiple definitions of basic types such as `Text` and `Image` that are not compatible across applications. + +**Fixed type systems** would ensure universal understanding but restrict innovation. +A predetermined set of message types eliminates ambiguity but adds friction for developers who want to extend functionality. +In a permissionless, decentralized protocol, requiring centralized approval for new message types contradicts core design principles. + +The core challenge is managing fragmentation in a decentralized protocol while preserving developer freedom to innovate. + +**Solution:** A self-describing message format that encodes both the payload and the metadata needed to parse it. +This approach directs application developers on how a message should be parsed while providing a clear path to learn about unfamiliar content types they encounter. +By decoupling the encoded data from the specific software that created it, applications can gracefully handle messages from diverse sources without sacrificing extensibility. + + +## Theory / Semantics + +### ContentFrame + +A ContentFrame provides a self-describing format for payload types by encoding both the type identifier and its administrative origin. +The core principle is that each payload should declare which entity is responsible for its definition and provide a unique type discriminator within that entity's namespace. + +A ContentFrame consists of two key components: + +- **Domain**: Points to a specification repository that defines and governs a collection of types +- **Tag**: A unique identifier within that domain that specifies which type the payload conforms to + +Together, the tuple `(domain, tag)` serves two purposes: + +1. **Identification**: Uniquely identifies the payload type without ambiguity +2. **Discovery**: Provides a path for developers to learn how to parse and support unfamiliar types + +**Benefits:** + +This approach provides several advantages for decentralized interoperability: + +- **No naming collisions**: Developers can independently create types without coordinating with others, as each domain manages its own namespace +- **Type reuse**: Well-defined, established types can be shared across applications, reducing fragmentation +- **Graceful extensibility**: Applications encountering unknown types can direct developers to the authoritative specification +- **Decentralized governance**: No central authority is required to approve new types; domains manage their own specifications + +By separating the "who defines this" (domain) from the "what is this" (tag), ContentFrame enables permissionless innovation while maintaining the context needed for interoperability. + + +### Concept Mapping + +The following diagram illustrates the relationship between ContentFrame components and their specifications: +```mermaid +flowchart TD + d[Domain ID] -->|references| D + D[Domain] -->|Defines| T[Tag] + T -->|References| Specification +``` + +### Domain + +A domain identifies the authority responsible for defining and governing a set of content types. +By including the domain, receiving applications can locate the authoritative specification for a type, regardless of which application originally sent it. + +**Requirements:** + +- A domain MUST be a valid URL as defined in [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) +- A domain MUST host or reference definitions for all content types within its namespace +- A domain SHOULD be a specification repository or index that developers can reference + +**Specification Format:** + +Domains are responsible for describing their types in whatever format is most appropriate. +The only requirement is that the information needed to parse and understand each type is accessible from the domain URL. + + +**Domain ID Mapping:** + +To minimize payload size, domains are mapped to integer identifiers. +Each domain is assigned a unique `domain_id` which is used in the wire format instead of the full URL. + +- A `domain_id` MUST be a positive integer value +- A `domain_id` MUST correspond to exactly one unique domain +- The canonical mapping of `domain_id` to domains can be found in [Appendix A: Domains](#appendix-a-domains) + +### Tag + +A tag is a numeric identifier that uniquely specifies a content type within a domain's namespace. +After resolving the domain and tag, application developers have all the information needed to locate the definition and parse the payload. + +**Requirements:** + +- A tag MUST be a positive integer value +- A tag MUST uniquely identify a single type within its domain +- Two payloads with the same `(domain, tag)` tuple MUST conform to the same type specification +- A tag's meaning MUST NOT change after it has been assigned within a domain + +**Domain Responsibility:** + +Each domain is responsible for: +- Assigning and managing tag values within its namespace +- Documenting how each tag maps to a type specification +- Ensuring tag assignments remain stable and unambiguous + +Tags are scoped to their domain, meaning the same tag value can represent different types in different domains without conflict. + + + +## Wire Format Specification / Syntax +```protobuf +message ContentFrame { + uint32 domain_id = 1; + uint32 tag = 2; + bytes payload = 3; +} +``` + +**Field Descriptions:** + +- **domain_id**: Identifies the domain that governs this content type +- **tag**: Identifies the specific content type within the domain's namespace +- **payload**: The encoded content data + +All fields are required. + + +## Implementation Suggestions + +### Tags to Specifications + +Where possible, tag values should directly correspond to specification identifiers. +Using specification IDs as tags removes the need to maintain a separate mapping between tags and specifications. + +### Fragmentation + +This protocol allows multiple competing definitions of similar content types. +Having multiple definitions of `Text` or `Image` increases fragmentation between applications. +Where possible, reusing existing types will reduce burden on developers and increase interoperability. + +Domains should focus on providing types unique to their service or use case. + + +# Appendix A: Domains + +![TODO] Find appropriate home for this registry. + +Domain IDs are assigned sequentially on a first-come, first-served basis. +New domains are added via pull request. + +**Registry Rules:** + +- A domain MUST only appear once in the table +- A domain MAY be updated by the original submitter if the repository has been moved + +**Registry:** + +| domain_id | specification repository | +|-----------|--------------------------------------| +| 1 | https://github.com/waku-org/specs | \ No newline at end of file diff --git a/docs/messaging/raw/introduction-encoding.md b/docs/messaging/raw/introduction-encoding.md new file mode 100644 index 000000000..241165572 --- /dev/null +++ b/docs/messaging/raw/introduction-encoding.md @@ -0,0 +1,153 @@ +--- +title: Introduction Bundle Encoding +name: introduction-bundle-encoding +category: Standards Track +tags: core, encoding +editor: +contributors: + - Patryk + - Jazzz +--- + +## Abstract + +This specification defines the encoding format for Introduction Bundles — the +out-of-band information shared so that a remote party can initiate contact with +the bundle publisher. + +## Background / Rationale / Motivation + +Users need a way to share contact information across arbitrary channels +(messaging apps, emails, QR codes, URLs, CLI terminals) without relying on a +centralized directory. The Introduction Bundle provides the cryptographic +material required to establish an encrypted conversation. + +The encoding must be: +- Copy-paste safe across arbitrary text transports. +- Space-efficient for manual sharing. +- Version-aware to support protocol evolution. + +## Theory / Semantics + +An Introduction Bundle is bound to a specific protocol version; its encoded +form identifies the version unambiguously. + +### Why ASCII, Not Unicode + +The encoded string consists entirely of printable ASCII. This is a natural +consequence of the design rather than a defensive choice against Unicode: + +1. **No human-readable content.** The format contains a fixed prefix, a numeric + version, and a binary-to-text encoded payload. These components do not + require characters outside ASCII. Common binary-to-text encodings such as + hex, base32, and base64 produce ASCII output. +2. **Encoding stability.** Printable ASCII characters are represented + identically in widely deployed text encodings such as UTF-8 and Latin-1, + avoiding ambiguity in character interpretation across transports. +3. **Restricted visible alphabet.** Limiting the character set reduces the risk + of visually confusable or non-rendering characters during manual comparison, + transcription, or copy-paste across different platforms, terminals, and + fonts. + +### Delimiter Choice + +The `_` character is present in the alphabets of common binary-to-text +encodings (hex, base32, base64url) and may therefore appear inside the payload. +Parsers MUST split the encoded string on the **first three** `_` characters; +everything after the third `_` is the payload verbatim. + +The underscore was chosen because it is a printable ASCII character that is +safe in URLs, filenames, and plain text without requiring escaping. Delimiters +outside this category (e.g., `.` or `:`) may require percent-encoding in +certain URL contexts, undermining the transport-safety goal. + +## Wire Format Specification / Syntax + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC 2119]. + +### Text Format + +The Introduction Bundle is encoded as a single ASCII string: + +``` +logos___ +``` + +| Field | Description | +|-------------|-------------------------------------------------------------------| +| `logos` | Fixed prefix. Identifies the string as a Logos protocol artifact. | +| `namespace` | Domain identifier. Distinguishes bundle types. | +| `version` | Protocol version number. Decimal integer, no leading zeros. | +| `payload` | Binary-to-text encoded payload (version-specific). | + +Fields are separated by `_` (underscore). + +### V1 + +#### Parameters + +| Parameter | Value | +|-------------|--------------------------------| +| `namespace` | `chatintro` | +| `version` | `1` | +| `encoding` | base64url, no padding | +| `payload` | Protobuf-encoded `IntroBundle` | + +#### Payload Encoding + +V1 uses **base64url without padding** ([RFC 4648 §5], padding +characters `=` omitted). This encoding was chosen for: + +- URL safety without percent-encoding. +- ~33% size overhead (compared to ~100% for hex). +- Wide library support across languages. + +Future versions MAY choose a different binary-to-text encoding. + +#### Binary Payload + +The payload is a Protocol Buffers (proto3) encoding of: + +```proto +syntax = "proto3"; + +message IntroBundle { + bytes installation_pubkey = 1; // 32 bytes, X25519 + bytes ephemeral_pubkey = 2; // 32 bytes, X25519 + bytes signature = 3; // 64 bytes, XEdDSA +} +``` + +The encoding MUST use standard proto3 serialization. Canonical (deterministic) +serialization is NOT REQUIRED; decoders MUST accept any valid proto3 encoding +of the message. + +#### Encoding Procedure + +1. Construct the `IntroBundle` protobuf message. +2. Serialize using proto3 encoding (~134 bytes). +3. Encode as base64url without padding (~179 characters). +4. Prepend the preamble with version prefix. + +The resulting string is ~197 printable ASCII characters. + +## Security/Privacy Considerations + +The signature prevents tampering but does not provide confidentiality. Bundles +should be transmitted over channels appropriate for the user's threat model. + +## Copyright + +Copyright and related rights waived via [CC0]. + +## References + +- [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) — Key words for use in RFCs +- [RFC 4648 §5](https://www.rfc-editor.org/rfc/rfc4648#section-5) — Base 64 Encoding with URL and Filename Safe Alphabet +- [CC0](https://creativecommons.org/publicdomain/zero/1.0/) — Creative Commons Zero Public Domain Dedication + +[RFC 2119]: https://www.ietf.org/rfc/rfc2119.txt +[RFC 4648 §5]: https://www.rfc-editor.org/rfc/rfc4648#section-5 +[CC0]: https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/docs/messaging/raw/privatev1.md b/docs/messaging/raw/privatev1.md new file mode 100644 index 000000000..87e9a071c --- /dev/null +++ b/docs/messaging/raw/privatev1.md @@ -0,0 +1,417 @@ +--- +title: PRIVATE1 +name: Private conversation +category: Standards Track +tags: +editor: Jazz Alyxzander (@Jazzz) +contributors: +--- + +# Abstract + +This specification defines PRIVATE1, a conversation protocol for establishing secure, full-duplex encrypted communication channels between two participants. PRIVATE1 provides end-to-end encryption with forward secrecy and post-compromise security using the Double Ratchet algorithm, combined with reliable message delivery via Scalable Data Sync (SDS) and efficient segmentation for transport-constrained environments. + +The protocol is transport-agnostic and designed to support both direct messaging and as a foundation for group communication systems. PRIVATE1 ensures payload confidentiality, content integrity, sender privacy, and message reliability while remaining resilient to network disruptions and message reordering. + +# Background + +Pairwise encrypted messaging channels represent a foundational building block of modern secure communication systems. While end-to-end encrypted group chats capture user attention, the underlying infrastructure that makes these systems possible relies (at least somewhat) on secure one-to-one communication primitives. Just as higher-level network protocols are built upon reliable transport primitives like TCP, sophisticated communication systems depend on robust pairwise channels to function correctly and securely. + +These channels serve purposes beyond simple content delivery. They transmit not only user-visible messages but also critical metadata, coordination signals, and state synchronization information between clients. This signaling capability makes pairwise channels essential infrastructure for distributed systems: key material distribution, membership updates, administrative actions, and protocol coordination all flow through these channels. While more sophisticated group communication strategies can achieve better efficiency at scale—particularly for broadcast-style communication patterns — they struggle to match the privacy and security properties that pairwise channels provide inherently. The fundamental asymmetry of two-party communication enables stronger guarantees: minimal metadata exposure, simpler key management, clearer authentication boundaries, and more straightforward security analysis. + +However, being encrypted is merely the starting point, not the complete solution. Production-quality one-to-one channels must function reliably in the messy reality of modern networks. Real-world deployment demands resilience to unreliable networks where messages may be lost, delayed, duplicated, or arrive out of order. Channels must efficiently handle arbitrarily large payloads—from short text messages to multi-megabyte file transfers—while respecting the maximum transmission unit constraints imposed by various transport layers. Perhaps most critically, the protocol must remain fully operational even when one or more participants are offline or intermittently connected. + + +# Private V1 + +PRIVATE1 is a conversation type specification that establishes a full-duplex secure communication channel between two participants. It combines the Double Ratchet algorithm for encryption with Scalable Data Sync (SDS) for reliable delivery and an efficient segmentation strategy to handle transport constraints. + +PRIVATE1 provides the following properties: + +- **Payload Confidentiality**: Only the two participants can read the contents of any message sent. Observers, transport providers, and other third parties cannot decrypt message contents. +- **Content Integrity**: Recipients can detect if message contents were modified by a third party. Any tampering with encrypted payloads will cause decryption to fail, preventing corrupted messages from being accepted as authentic. +- **Sender Privacy**: Only the recipient can determine who the sender was. Observers cannot identify the sender from encrypted payloads, though both participants can authenticate each other's messages. +- **Forward Secrecy**: A compromise in the future does not allow previous messages to be decrypted by a third party. Message keys are deleted immediately after use and cannot be reconstructed from current state, even if long-term keys are later compromised. +- **Post-Compromise Security**: Conversations eventually recover from a key compromise. After an attacker loses access to a device, the security properties are eventually restored. +- **Dropped Message Observability**: Messages lost in transit are eventually observable to both sender and recipient. + +## Definitions + +This document makes use of the shared terminology defined in the [CHAT-DEFINITIONS](informational/chatdefs.md) specification. + +The terms include: +- Application +- Content +- Participant +- Payload +- Recipient +- Sender + + + +## Architecture + +This conversation type assumes there is some service or application which wishes to generate and receive end-to-end encrypted content. +It also assumes that some other component is responsible for delivering the generated payloads. At its core this protocol takes the content provided and creates a series of payloads to be sent to the recipient. + +```mermaid +flowchart LR + Content:::plain--> PrivateV1 --> Payload:::plain + classDef plain fill:none,stroke:transparent; +``` +### Content + +Applications provide content as encoded bytes, which is then packaged into payloads for transmission. + +**Size Limit** + +Content MUST be smaller than `255 * max_seg_size` +due to segmentation protocol limitations. + +**Structure** + +The protocol treats the contents as an arbitrary sequence of bytes and is agnostic to its contents. + +### Payload Delivery +How payloads are sent and received by clients is deliberately not specified by this protocol. +Transport choice is an client/application decision that should be made based on deployment requirements. + +The choice of transport mechanism has no impact on PRIVATE1's security properties. +Confidentiality, integrity, and forward secrecy are provided regardless of how payloads are delivered. +However, transport choice may affect other properties and characteristics. + +**Recipient Privacy:** +The routing/addressing layer may leak sensitive metadata including the recipient's identity. The payloads generated by this protocol do not reveal the participants of a conversation, however the overall privacy properties are determined by the delivery mechanism used to transport payloads. + +**Reliability Performance** +While PRIVATE1 handles message losses, more reliable transports reduce retransmission overhead. + +## Initialization + +The channel is initialized by both sender and recipient agreeing on the following values for each conversation: +- `sk` - initial secret key [32 bytes] +- `ssk` - sender DH seed key +- `rsk` - recipient DH seed key +- `conversation_id` - globally unique identifier + +To maintain the security properties: +- `sk` MUST be known only by the participants. +- `sk` MUST be derived in a way that ensures mutual authentication of the participants +- `sk` SHOULD have forward secrecy by incorporating ephemeral key material +- `rsk` and `ssk` SHOULD incorporate ephemeral key material + +PRIVATE1 requires a unique identifier, however the exact derivation is left to implementations to determine. +- `conversation_id` MUST be unique across all instances of chat conversations +- `conversation_id` SHOULD be consistent across applications to maintain interoperability + +Additionally implementations MUST determine the following constants: +- `max_seg_size` - maximum segmentation size to be used. +- `max_skip` - number of keys which can be skipped per session. + +## Value Derivations + +These values are derived during protocol operation and are deterministically computed from protocol data. + +### Frame Identifier + +For reliability tracking, every payload MUST have a unique deterministic identifier. + +The frame identifier is computed as: +``` +frame_id = rhex(blake2b(encoded_frame_bytes)) +``` + +Where: +- `rhex` is lowercase hexadecimal encoding without the `0x` prefix +- `blake2b` is BLAKE2b hash function with 128-bit output +- `encoded_frame_bytes` is the protobuf-encoded `PrivateV1Frame` +- `frame_id` is a 32 character string + +**Protobuf Encoding Considerations** + +Protobuf does not guarantee byte-identical outputs for multiple serializations of the same logical message. +Because of this, the `frame_id` represents the hash of specific encoded bytes rather than an abstract frame structure. +Implementations MUST compute `frame_id` from the actual bytes being transmitted to ensure sender and receiver derive identical identifiers. + + +## Protocol Operation + +PRIVATE1 processes messages through a three-stage pipeline where each stage's output becomes the next stage's input. +The specific ordering of these stages is critical for maintaining security properties while enabling efficient operation. + +```mermaid +flowchart TD + C("Content"):::plain + S(Segmentation) + R(Reliability) + E(Encryption) + D(Delivery):::plain + C --> S --> R --> E --> D + + classDef plain fill:none,stroke:transparent; +``` +**Pipeline Stages:** +- **Segmentation**: Divides content into transport-appropriate fragments +- **Reliability (SDS)**: Adds tracking metadata for delivery detection and ordering +- **Encryption (Double Ratchet)**: Provides confidentiality, authentication, and forward secrecy + + + +### Segmentation + +While PRIVATE1 itself has no inherent message size limitation, practical transport mechanisms typically impose maximum payload sizes. + +**Why Segment Before Encryption** + +Segmenting after encryption would force the transport layer to handle fragmentation of ciphertext blobs, creating several problems. +- Transport-layer segmentation would require buffering all segments before any can be authenticated, increasing the DOS attack surface. +- Unauthenticated segment reassembly opens the door to malicious segment injection and substitution attacks. +- Unencrypted segmentation metadata reveals size and other metadata about the content in transit. + +**Why Segment Before Reliability** + +Placing segmentation after reliability tracking would mean retransmission of a dropped segment would require re-broadcasting the entire frame. +By segmenting first, the reliability layer can track individual segments and request retransmission of only the missing fragments. + +**Implementation** + +The segmentation strategy used is defined by [!TODO: Flatten link once completed](https://github.com/waku-org/specs/pull/91) + +Implementation specifics: +- Error correction is not used, as reliable delivery is already provided by lower layers. +- `segmentSize` = `max_seg_size` +- All payloads regardless of size are wrapped in a segmentation message. + +### Message Reliability + +Scalable Data Sync (SDS) is used to detect missing messages, provide delivery confirmation, and handle retransmission of payloads. +SDS is implemented according to the [specification](https://github.com/vacp2p/rfc-index/blob/main/vac/raw/sds.md). + +**SDS Field Mappings** + +The following mappings connect PRIVATE1 concepts to SDS fields: + +- `sender_id`: !TODO: This requires PRIVATE1 to be identity aware +- `message_id`: uses the `frame_id` definition. +- `channel_id`: uses the `conversation_id` parameter. + +**Sender Validation** +SDS uses a `sender_id` payload field to determine whether a message was sent by the remote party. This value is sender reported and not validated which can have unknown implications if trusted in other contexts. For security hygiene Clients SHOULD drop SDS messages if `sender_id` != the sender derived from the encryption layer. !TODO: PRIVATE1 is not sender aware currently + +**Bloom Filter Configuration** + +PRIVATE1 uses bloom filter parameters of `n=2000` (expected elements) and `p=0.001` (false positive probability). +This configuration produces bloom filters of approximately 3.5 KiB per message. + +!TODO: Can the bloom filter be dropped in 1:1 communication? + +### Encryption + +Payloads are encrypted using the [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/) algorithm with the following cryptographic primitive choices: + +**Double Ratchet Configuration** + +- `DH`: X25519 for Diffie-Hellman operations +- `KDF_RK`: HKDF with Blake2b, `info = "PrivateV1RootKey"` +- `KDF_CK`: Blake2b as KDF truncated to 32 bytes, 'key'= previous_ck 'salt'= `@[]`, using `personal`=`mk` for message keys and `personal`=`ck` for chain keys +- `KDF_MK`: HKDF with SHA256, `info = "PrivateV1MessageKey"` +- `ENCRYPT`: `AEAD_CHACHA20_POLY1305` + +**AEAD Implementation** + +`ChaCha20-Poly1305` is used with randomly generated 96-bit (12-byte) nonces. +The nonce MUST be generated using a cryptographically secure random number generator for each message. +The complete ciphertext format for transport is: +``` +encrypted_payload = nonce || ciphertext || tag +``` + +Where `nonce` is 12 bytes, `ciphertext` is variable length, and `tag` is 16 bytes. + +## Frame Handling + +This protocol uses explicit frame type tagging to remove ambiguity when parsing and handling frames. +This creates a clear distinction between protocol-generated frames and application content. + +**Type Discrimination** + +All frames carry an explicit type field that identifies their purpose. +The `content` frame type is reserved exclusively for application-level data. +All other frame types are protocol-owned and intended for client processing, not application consumption. + +This establishes a critical invariant: any frame that is not `content` is meant for the protocol layer. +When a client encounters an unknown frame type, it can definitively conclude this represents a version compatibility issue. + +**Processing Rules** + +- All application-level content MUST use the `content` frame type +- Clients SHALL only pass `content` frames to applications +- Clients MAY drop unrecognized frame types + +**Future Extensibility** + +This explicit tagging mechanism allows the protocol to evolve without breaking existing implementations. +Future versions may define additional frame types for protocol-level functionality while legacy clients continue processing `content` frames normally. + +# Wire Format Specification / Syntax + +## Payload Parse Tree + +A deterministic parse tree is used to avoid ambiguity when receiving payloads. + +```mermaid +flowchart TD + + D[DoubleRatchet] + S[SDS Message] + Segment1[ Segment] + Segment2[ Segment] + Segment3[ Segment] + P[PrivateV1Frame] + + start@{ shape: start } + start --> D + D -->|Payload| S + S -->|Payload| Segment1 + + Segment1 --> P + Segment2:::plain --> P + Segment3:::plain --> P + + P --> T{frame_type} + T --content--> Bytes + + + classDef plain fill:none,stroke:transparent; +``` + + +## Payloads +!TODO: Don't duplicate payload definitions from other specs. Though its helpful for now. + +### Encrypted Payload +```protobuf +message DoubleRatchet { + bytes dh = 1; // 32 byte publickey + uint32 msgNum = 2; + uint32 prevChainLen = 3; + bytes ciphertext = 4; // arbitrary length bytes +} +``` +**dh**: the x component of the dh_pair.publickey encoded as raw bytes. +**ciphertext**: A protobuf encoded SDS Message + +### SDS Message + +This payload is used without modification from the SDS Spec. + +```protobuf +message HistoryEntry { + string message_id = 1; // Unique identifier of the SDS message, as defined in `Message` + optional bytes retrieval_hint = 2; // Optional information to help remote parties retrieve this SDS message; For example, A Waku deterministic message hash or routing payload hash +} + +message Message { + string sender_id = 1; // Participant ID of the message sender + string message_id = 2; // Unique identifier of the message + string channel_id = 3; // Identifier of the channel to which the message belongs + optional int32 lamport_timestamp = 10; // Logical timestamp for causal ordering in channel + repeated HistoryEntry causal_history = 11; // List of preceding message IDs that this message causally depends on. Generally 2 or 3 message IDs are included. + optional bytes bloom_filter = 12; // Bloom filter representing received message IDs in channel + optional bytes content = 20; // Actual content of the message +} +``` + +**content:** This field is a protobuf encoded `Segment` + +### Segmentation + +This payload is used without modification from the Segmentation [specification](https://github.com/waku-org/specs/blob/fa2993b427f12796356a232c54be75814fac5d98/standards/application/segmentation.md) + +```protobuf + +message SegmentMessageProto { + bytes entire_message_hash = 1; // 32 Bytes + uint32 index = 2; + uint32 segments_count = 3; + bytes payload = 4; + uint32 parity_segment_index = 5; + uint32 parity_segments_count = 6; +} + +``` + +**payload**: This field is an protobuf encoded `PrivateV1Frame` + +!TODO: This should be encoded as a FrameType so it can be optional. + +### PrivateV1Frame + +```protobuf +message PrivateV1Frame { + uint64 timestamp = 1; // Sender reported timestamp + oneof frame_type { + bytes content = 10; + Placeholder placeholder = 11; + // .... + } +} +``` + +**content:** is encoded as bytes in order to allow implementations to define the type at runtime. + + +## Implementation Suggestions + +### Content Types + +Implementers need to be mindful of maintaining interoperability between clients, when deciding how content is encoded prior to transmission. +In a decentralized context, clients cannot be assumed to be using the same version let alone application. It is recommended that implementers use a self-describing content payload such as [CONTENTFRAME](https://github.com/waku-org/specs/blob/jazzz/content_frame/standards/application/contentframe.md) specification. This provides the ability for clients to determine support for incoming frames, regardless of the software used to receive them. + +### Initialization + +Mutual authentication is provided by the `sk`, so there is no requirement of using authenticated keys for `ssk` and `rsk`. +Implementations SHOULD use the most ephemeral key available in order incorporate as much key material as possible. +This means that senders SHOULD generate a new ephemeral key for `ssk` for every conversation assuming channels are asynchronously initialized. + +### Excessive Skipped Message + +Handling of skipped message keys is not strictly defined in double ratchet. +Implementations need to choose a strategy which works best for their environment, and delivery mechanism. +Halting operation of the channel is the safest, as it bounds resource utilization in the event of a DOS attack but is not always possible. + +If eventual delivery of messages is not guaranteed, implementers should regularly delete keys that are older than a given time window. +Unreliable delivery mechanisms will result in increased key storage over time, as more messages are lost with no hope of delivery. + +## Security/Privacy Considerations + +### Sender Deniability and Authentication + +Encrypted messages do not have a cryptographically provable sender to third parties due to the deniability property of the Double Ratchet algorithm. +However, participants in a conversation can authenticate each other through the shared cryptographic state. +When receiving a message, the recipient knows it must have come from the other participant because only they possess the necessary key material to produce valid ciphertexts. + +Because sender identity is implicitly authenticated through shared secrets rather than explicit signatures, it is critical that the initial shared secret `sk` be derived from an authenticated key exchange process. +Without proper authentication during initialization, an adversary could perform a man-in-the-middle attack and establish separate sessions with each participant, allowing them to read and modify all messages. + + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + + +## References +- **[DOUBLERATCHET]** "The Double Ratchet Algorithm", Signal, 2016. + https://signal.org/docs/specifications/doubleratchet/ + +- **[SDS]** "Scalable Data Sync Specification", vac, 2024. + https://github.com/vacp2p/rfc-index/blob/main/vac/raw/sds.md + +- **[SEGMENTATION]** "Message Segmentation Specification", Waku, 2024. + https://github.com/waku-org/specs/blob/main/standards/application/segmentation.md + +- **[CONTENTFRAME]** "ContentFrame Specification", Waku, 2024. + https://github.com/waku-org/specs/blob/main/standards/application/contentframe.md + +- **[CHAT-DEFINITIONS]** "Chat Definitions Specification", Waku, 2024. + https://github.com/waku-org/specs/blob/main/informational/chatdefs.md From 2884ef397c2823ace2cb158a0212d88221eab90b Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Thu, 4 Jun 2026 16:26:55 +0300 Subject: [PATCH 2/4] docs(messaging): adapt remaining specs to logos-lips conventions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Converts the YAML front matter of the freshly imported specs to the canonical `| Field | Value |` metadata table (status: raw), matching #315/#331. Slugs and timelines are left to the build-time generators. Also rewrites cross-references that pointed at the old source repos to their new logos-lips locations, using repo-relative links (matching how existing specs cross-link, e.g. reliable-channel-api -> ./segmentation.md and rln-relay -> ../../../anoncomms/...): - waku-org/specs segmentation/contentframe/chatdefs → ./.md - vacp2p/rfc-index sds → ../../anoncomms/raw/sds.md - privatev1 segmentation TODO link flattened to the segmentation spec - contentframe domain-registry entry #1 repointed to logos-co/logos-lips Notes: - contentframe had an empty `name:` in source; set to "Chat Content Frames" (per logos-messaging/specs#82 title). - introduction-encoding had no `editor:`; populated from its `contributors:` list. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/messaging/raw/chat-framework.md | 20 +++++++------ docs/messaging/raw/contentframe.md | 19 ++++++------ docs/messaging/raw/introduction-encoding.md | 20 ++++++------- docs/messaging/raw/privatev1.md | 33 +++++++++++---------- 4 files changed, 48 insertions(+), 44 deletions(-) diff --git a/docs/messaging/raw/chat-framework.md b/docs/messaging/raw/chat-framework.md index b0a020c72..f4fb7edf2 100644 --- a/docs/messaging/raw/chat-framework.md +++ b/docs/messaging/raw/chat-framework.md @@ -1,12 +1,14 @@ ---- -title: CHAT-FRAMEWORK -name: A modular framework for defining chat protocols -category: Information -status: raw -tags: chat -editor: Jazz Alyxzander -contributors: ---- +# CHAT-FRAMEWORK + +| Field | Value | +| --- | --- | +| Name | A modular framework for defining chat protocols | +| Status | raw | +| Type | RFC | +| Category | Informational | +| Tags | chat | +| Editor | Jazz Alyxzander | + # Abstract This specification defines a modular communication protocol framework for describing chat protocols. It introduces abstraction boundaries, and a component model for describing chat protocol functionality. diff --git a/docs/messaging/raw/contentframe.md b/docs/messaging/raw/contentframe.md index c66230df2..7b4bf9115 100644 --- a/docs/messaging/raw/contentframe.md +++ b/docs/messaging/raw/contentframe.md @@ -1,11 +1,12 @@ ---- -title: CONTENTFRAME -name: -category: Standards Track -tags: -editor: Jazzz -contributors: ---- +# CONTENTFRAME + +| Field | Value | +| --- | --- | +| Name | Chat Content Frames | +| Status | raw | +| Type | RFC | +| Category | Standards Track | +| Editor | Jazzz | ## Abstract @@ -176,4 +177,4 @@ New domains are added via pull request. | domain_id | specification repository | |-----------|--------------------------------------| -| 1 | https://github.com/waku-org/specs | \ No newline at end of file +| 1 | https://github.com/logos-co/logos-lips | diff --git a/docs/messaging/raw/introduction-encoding.md b/docs/messaging/raw/introduction-encoding.md index 241165572..903d4c97b 100644 --- a/docs/messaging/raw/introduction-encoding.md +++ b/docs/messaging/raw/introduction-encoding.md @@ -1,13 +1,13 @@ ---- -title: Introduction Bundle Encoding -name: introduction-bundle-encoding -category: Standards Track -tags: core, encoding -editor: -contributors: - - Patryk - - Jazzz ---- +# Introduction Bundle Encoding + +| Field | Value | +| --- | --- | +| Name | introduction-bundle-encoding | +| Status | raw | +| Type | RFC | +| Category | Standards Track | +| Tags | core, encoding | +| Editor | Patryk , Jazzz | ## Abstract diff --git a/docs/messaging/raw/privatev1.md b/docs/messaging/raw/privatev1.md index 87e9a071c..ad5cb844c 100644 --- a/docs/messaging/raw/privatev1.md +++ b/docs/messaging/raw/privatev1.md @@ -1,11 +1,12 @@ ---- -title: PRIVATE1 -name: Private conversation -category: Standards Track -tags: -editor: Jazz Alyxzander (@Jazzz) -contributors: ---- +# PRIVATE1 + +| Field | Value | +| --- | --- | +| Name | Private conversation | +| Status | raw | +| Type | RFC | +| Category | Standards Track | +| Editor | Jazz Alyxzander (@Jazzz) | # Abstract @@ -175,7 +176,7 @@ By segmenting first, the reliability layer can track individual segments and req **Implementation** -The segmentation strategy used is defined by [!TODO: Flatten link once completed](https://github.com/waku-org/specs/pull/91) +The segmentation strategy used is defined by the [Segmentation specification](./segmentation.md) Implementation specifics: - Error correction is not used, as reliable delivery is already provided by lower layers. @@ -185,7 +186,7 @@ Implementation specifics: ### Message Reliability Scalable Data Sync (SDS) is used to detect missing messages, provide delivery confirmation, and handle retransmission of payloads. -SDS is implemented according to the [specification](https://github.com/vacp2p/rfc-index/blob/main/vac/raw/sds.md). +SDS is implemented according to the [specification](../../anoncomms/raw/sds.md). **SDS Field Mappings** @@ -326,7 +327,7 @@ message Message { ### Segmentation -This payload is used without modification from the Segmentation [specification](https://github.com/waku-org/specs/blob/fa2993b427f12796356a232c54be75814fac5d98/standards/application/segmentation.md) +This payload is used without modification from the Segmentation [specification](./segmentation.md) ```protobuf @@ -366,7 +367,7 @@ message PrivateV1Frame { ### Content Types Implementers need to be mindful of maintaining interoperability between clients, when deciding how content is encoded prior to transmission. -In a decentralized context, clients cannot be assumed to be using the same version let alone application. It is recommended that implementers use a self-describing content payload such as [CONTENTFRAME](https://github.com/waku-org/specs/blob/jazzz/content_frame/standards/application/contentframe.md) specification. This provides the ability for clients to determine support for incoming frames, regardless of the software used to receive them. +In a decentralized context, clients cannot be assumed to be using the same version let alone application. It is recommended that implementers use a self-describing content payload such as [CONTENTFRAME](./contentframe.md) specification. This provides the ability for clients to determine support for incoming frames, regardless of the software used to receive them. ### Initialization @@ -405,13 +406,13 @@ Copyright and related rights waived via [CC0](https://creativecommons.org/public https://signal.org/docs/specifications/doubleratchet/ - **[SDS]** "Scalable Data Sync Specification", vac, 2024. - https://github.com/vacp2p/rfc-index/blob/main/vac/raw/sds.md + ../../anoncomms/raw/sds.md - **[SEGMENTATION]** "Message Segmentation Specification", Waku, 2024. - https://github.com/waku-org/specs/blob/main/standards/application/segmentation.md + ./segmentation.md - **[CONTENTFRAME]** "ContentFrame Specification", Waku, 2024. - https://github.com/waku-org/specs/blob/main/standards/application/contentframe.md + ./contentframe.md - **[CHAT-DEFINITIONS]** "Chat Definitions Specification", Waku, 2024. - https://github.com/waku-org/specs/blob/main/informational/chatdefs.md + ./chatdefs.md From c3b8096f749e32d93e3e1ced326d0c8f16eecb88 Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Thu, 4 Jun 2026 18:00:39 +0300 Subject: [PATCH 3/4] fix: address pr comments --- docs/messaging/raw/chat-framework.md | 5 ----- docs/messaging/raw/privatev1.md | 21 ++++++--------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/docs/messaging/raw/chat-framework.md b/docs/messaging/raw/chat-framework.md index f4fb7edf2..4e2ee74cc 100644 --- a/docs/messaging/raw/chat-framework.md +++ b/docs/messaging/raw/chat-framework.md @@ -128,12 +128,7 @@ A conversation protocol defines how messages flow between participants, and subs - A Conversation protocol MUST define the payloads it uses and how to handle them. - A Conversation protocol SHOULD outline the cryptographic properties provided - A Conversation protocol SHOULD describe bidirectional communication. -- A Conversation protocol ... ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). - -## References - -A list of references. diff --git a/docs/messaging/raw/privatev1.md b/docs/messaging/raw/privatev1.md index ad5cb844c..64ae0f2de 100644 --- a/docs/messaging/raw/privatev1.md +++ b/docs/messaging/raw/privatev1.md @@ -38,7 +38,7 @@ PRIVATE1 provides the following properties: ## Definitions -This document makes use of the shared terminology defined in the [CHAT-DEFINITIONS](informational/chatdefs.md) specification. +This document makes use of the shared terminology defined in the [CHAT-DEFINITIONS](./chatdefs.md) specification. The terms include: - Application @@ -402,17 +402,8 @@ Copyright and related rights waived via [CC0](https://creativecommons.org/public ## References -- **[DOUBLERATCHET]** "The Double Ratchet Algorithm", Signal, 2016. - https://signal.org/docs/specifications/doubleratchet/ - -- **[SDS]** "Scalable Data Sync Specification", vac, 2024. - ../../anoncomms/raw/sds.md - -- **[SEGMENTATION]** "Message Segmentation Specification", Waku, 2024. - ./segmentation.md - -- **[CONTENTFRAME]** "ContentFrame Specification", Waku, 2024. - ./contentframe.md - -- **[CHAT-DEFINITIONS]** "Chat Definitions Specification", Waku, 2024. - ./chatdefs.md +- [DOUBLERATCHET](https://signal.org/docs/specifications/doubleratchet/) "The Double Ratchet Algorithm", Signal, 2016. +- [SDS](../../anoncomms/raw/sds.md) "Scalable Data Sync Specification", vac, 2024. +- [SEGMENTATION](./segmentation.md) "Message Segmentation Specification", Waku, 2024. +- [CONTENTFRAME](./contentframe.md) "ContentFrame Specification", Waku, 2024. +- [CHAT-DEFINITIONS](./chatdefs.md) "Chat Definitions Specification", Waku, 2024. From 347b4a5ef4f39a789c68da686440f301ede2e292 Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Thu, 4 Jun 2026 21:30:17 +0100 Subject: [PATCH 4/4] fix: chat-framework category Co-authored-by: Jazz Turner-Baggs <473256+jazzz@users.noreply.github.com> --- docs/messaging/raw/chat-framework.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/messaging/raw/chat-framework.md b/docs/messaging/raw/chat-framework.md index 4e2ee74cc..47cf5879c 100644 --- a/docs/messaging/raw/chat-framework.md +++ b/docs/messaging/raw/chat-framework.md @@ -5,7 +5,7 @@ | Name | A modular framework for defining chat protocols | | Status | raw | | Type | RFC | -| Category | Informational | +| Category | Standards Track | | Tags | chat | | Editor | Jazz Alyxzander |