Cyfer Platform Technical White Paper
Version 1.0 | March 22, 2026
Executive Summary
Cyfer is a quantum-safe secure messaging and collaboration platform that implements classical and post-quantum cryptographic protocols to deliver end-to-end encrypted real-time communication between humans, devices, and AI agents.
The platform leverages multiple IETF standards including MLS [Messaging Layer Security - RFC 9420], MIMI [More Instant Messaging Interoperability], HPKE [Hybrid Public Key Encryption - RFC 9180], and SFrame [Secure Frame - RFC 9605] to provide a comprehensive and interoperable messaging solution.
This white paper provides a high-level technical overview of the Cyfer platform architecture, covering its cryptographic foundations, distributed systems design, client implementations, and deployment models. The reader is encouraged to read the references for detailed information for each standard.
Table of Contents
- Introduction
- Architecture Overview
- Messaging Layer Security
- Cryptographic Foundations
- MLS Service Abstrations
- MIMI Transport Protocol
- MIMI Message Format
- Authentication and Credentials
- Real-Time Communication
- Data Architecture
- AI Agent Integration
- Deployment Models
- Security Considerations
- References
- Appendix A: Cryptography Bill of Materials
Introduction
Modern messaging platforms face several critical challenges:
- Security: End-to-end encryption must protect messages from all intermediaries
- Scalability: Group messaging with thousands of participants must remain efficient
- Interoperability: Users on different platforms should communicate seamlessly
- Privacy: Minimal metadata exposure while maintaining functionality
- Recovery: Systems must recover security properties after key compromise
- AI Integration: Support for LLM-based agents to interact with messaging services Cyfer addresses these challenges by unifying multiple international standards into a coherent, extensible platform. This standards-based approach is future-proof and ensures crypto-agility and an open ecosystem where third-parties can build interoperable components.
At the core of Cyfer is Messaging Layer Security [MLS]. MLS introduces a novel tree-based continuous group key agreement protocol, reducing computational complexity from exponential load to linear or logarithmic performance, unlocking secure real-time communication for large groups at global scale.
MLS as a security protocol is flexible to support any kind of data communicated across clients, not just human-readable messages. This makes it appropriate for many use cases, including drone swarms and AI agents.
Architecture Overview
High-Level System Architecture
The Cyfer platform consists of three primary tiers: client applications, service layer, and data persistence.
graph TB
subgraph "Client Tier"
HumanAgent[Human Clients<br/>Native Apps]
AIAgent[AI Agents<br/>Model Context Protocol]
end
subgraph "Gateway Tier"
Discovery[Discovery Service<br/>Endpoint Resolution]
Auth[Authentication Service<br/>OAuth 2.0 + DPoP]
end
subgraph "Service Tier"
GraphSvc[Graph Service<br/>Social Relationships]
NotifySvc[Notification Service<br/>Push/SSE/WebSocket]
MCPSvc[MCP Server<br/>AI Integration]
end
subgraph "MIMI Hub"
DeliverySvc[Delivery Service<br/>MLS Message Routing]
end
subgraph "Real-Time Tier"
SFUSvc[SFU Service<br/>Real-Time Media]
end
subgraph "Data Tier"
IdentityDB[(Identity DB<br/>Accounts & Credentials)]
KeysDB[(Keys DB<br/>Encryption & Signing)]
GraphDB[(Graph DB<br/>Relationships)]
BlobStorage[Object Storage<br/>Key Packages & State]
TableStorage[Table Storage<br/>Message Queues]
end
HumanAgent --> Discovery
HumanAgent --> SFUSvc
HumanAgent --> DeliverySvc
HumanAgent --> GraphSvc
HumanAgent --> NotifySvc
AIAgent --> MCPSvc
AIAgent --> NotifySvc
Discovery --> Auth
Discovery --> GraphSvc
Auth --> IdentityDB
Auth --> KeysDB
DeliverySvc --> BlobStorage
DeliverySvc --> TableStorage
GraphSvc --> GraphDB
NotifySvc --> TableStorage
Component Responsibilities
| Component | Responsibility | Technology |
|---|---|---|
| Discovery Service | User account discovery, endpoint resolution | Serverless / Container |
| Authentication Service | OAuth 2.0, DPoP, credential management | Serverless / Container |
| Delivery Service | MLS message routing, MIMI Hub/Follower, UTCP | Container |
| Graph Service | Account relationships, profiles, tenants, UTCP | Serverless / Container |
| Notification Service | Push notifications, SSE, WebSocket, UTCP | Serverless |
| SFU Service | SFrame-encrypted media forwarding | Container |
| MCP Server | AI agent integration via MCP | Container |
Messaging Layer Security
The Messaging Layer Security protocol [MLS] is and end-to-end encrypted messaging system based on tree structures that enables asynchronous group keying with forward secrecy and post-compromise security. This tree structure allows the members of the group to derive and update shared keys with costs that scale as the log of the group size.
The Ratchet Tree
Each client maintains a ratchet tree representing the group’s cryptographic state. The ratchet tree is central to MLS’s ability to securely rekey and maintain group confidentiality.
- The tree tracks public keys, parent-derived secrets, and the structure required to compute group secrets and validate the tree composition.
- Each client occupies a leaf in a balanced binary tree.
- Internal nodes hold cryptographic secrets that contribute to the group’s shared key material.
- Updates propagate efficiently through the tree, enabling logarithmic scaling for rekey operations.
- This structure provides forward secrecy, post-compromise security, and efficient group operations.
- The state evolves with membership changes or security updates.
graph TB
Root[Root<br/>Group Secret]
L1L[Left<br/>Parent]
L1R[Right<br/>Parent]
L2A[Client A]
L2B[Client B]
L2C[Client C]
L2D[Client D]
Root --> L1L
Root --> L1R
L1L --> L2A
L1L --> L2B
L1R --> L2C
L1R --> L2D
Key Properties:
- O(log n) Complexity: Key updates require O(log n) operations per client
- Path Secrets: Each node derives secrets from its parent
- Blank Nodes: Removed members leave blank nodes for efficiency
Message Types
MLS defines two categories of messages:
-
Handshake messages: orchestrate group operations.
-
Application messages: private communication (message content). There are two methods of framing these messages for transmission:
-
PublicMessage: signed but not encrypted.
-
PrivateMessage: signed and encrypted. Applications must use PrivateMessage to encrypt application messages and should use PrivateMessage to encode handshake messages, but they may transmit handshake messages encoded as PublicMessage objects in cases where it is necessary for the Delivery Service to examine the messages.
By default, Cyfer sends handshake messages as PublicMessages to support MIMI transport and management operations. Cyfer has other non-MIMI modes of operation that allow handshake messages to be sent as PrivateMessages with the group members handling commit negotiation logic.
Group State Evolution
Proposal and Commit messages are handshake messages that manage group changes:
- Proposals suggest actions (add, update, remove, re-initialize, etc.)
- Commits finalize and incorporate those proposals into the group state. Only commits modify the group’s cryptographic tree, ensuring consistency and deterministic evolution. Each commit should be finalized by only one member of the group.
Cryptographic State Evolution
A group in MLS progresses through a linear sequence of key‑schedule epochs.
In each epoch, the group members share a unique epoch secret that only the authenticated members for that epoch can access. Because the group’s membership can change between epochs, MLS ensures that only the members of the current epoch can derive this secret. Removed members lose access, and new members gain access.
From the epoch secret, members derive all additional cryptographic material needed for the epoch, including message encryption keys, sender authentication keys, and other shared secrets.
A Commit message starts a new epoch. A Commit:
- Applies Proposals (add, update, remove, etc.) so every member updates their local copy of the ratchet tree in the same way.
- Generates fresh entropy, which becomes the new epoch secret and is distributed through the updated tree.
- Ensures that this new secret material is available only to members of the new epoch, excluding anyone who has been removed. Because messages in an epoch are encrypted with keys derived from that epoch’s unique secret, compromising past keys does not reveal future messages—this is forward secrecy.
MLS also provides post‑compromise security. If an attacker temporarily compromises a member’s device, the next epoch (triggered by an Update or Commit) injects new entropy into the ratchet tree. This forces all members to derive new keys that the attacker cannot compute, cutting off access even if the attacker previously held internal secrets.
In short:
- Forward secrecy: Learning old epoch secrets does not help decrypt messages in later epochs.
- Post‑compromise security: A compromised member can heal by participating in a new epoch, which produces fresh secrets the attacker can’t recover. In the following example, Alice adds Carol to the group. Instead of sending the add proposal and commit as separate messages, Alice embeds the proposal inside the commit message.
sequenceDiagram
participant A as Alice
participant B as Bob
participant C as Carol
participant DS as Delivery Service
Note over A,B: Epoch N
A->>A: Create Add (Carol) Proposal
A->>A: Create Commit
A->>DS: Send Commit + Welcome
DS->>B: Deliver Commit
DS->>C: Deliver Welcome
B->>B: Process Commit
C->>C: Process Welcome
Note over A,C: Epoch N+1 New keys, forward secrecy
Cryptographic Foundations
Core Cryptographic Primitives
Cyfer implements a comprehensive cryptographic stack based on modern standards:
MLS uses HPKE for public key encryption [RFC9180] providing authenticated encryption with associated data using a combination of asymmetric and symmetric cryptography.
MLS Cipher Suites
Each MLS session uses a single cipher suite that specifies the following primitives to be used in group key computations:
- HPKE parameters:
- A Key Encapsulation Mechanism (KEM)
- A Key Derivation Function (KDF)
- An Authenticated Encryption with Associated Data (AEAD) encryption algorithm
- A hash algorithm
- A Message Authentication Code (MAC) algorithm
- A signature algorithm MLS Cipher Suites with classical encryption:
| KEM | KDF | AEAD | Hash | Signature |
|---|---|---|---|---|
| DHKEM(X25519, HKDF-SHA256) | HKDF-SHA256 | AES-128-GCM | SHA256 | ed25519 |
| DHKEM(P-256, HKDF-SHA256) | HKDF-SHA256 | AES-128-GCM | SHA256 | ecdsa_secp256r1_sha256 |
| DHKEM(X25519, HKDF-SHA256) | HKDF-SHA256 | ChaCha20-Poly1305 | SHA256 | ed25519 |
| DHKEM(X448, HKDF-SHA512) | HKDF-SHA512 | AES-256-GCM | SHA512 | ed448 |
| DHKEM(P-521, HKDF-SHA512) | HKDF-SHA512 | AES-256-GCM | SHA512 | ecdsa_secp521r1_sha512 |
| DHKEM(X448, HKDF-SHA512) | HKDF-SHA512 | ChaCha20-Poly1305 | SHA512 | ed448 |
| DHKEM(P-384, HKDF-SHA384) | HKDF-SHA384 | AES-256-GCM | SHA384 | ecdsa_secp384r1_sha384 |
Post-Quantum Cipher Suites
MLS supports multiple ciphersuites that incorporate post‑quantum (PQ) security by combining:
-
ML‑KEM (a NIST‑selected module‑lattice–based KEM) for key establishment
-
Symmetric algorithms appropriate for the intended security level
-
Either traditional signature algorithms or ML‑DSA, a module‑lattice–based PQ digital signature algorithm There is currently a split in preferences within the community:
-
Some deployments want 128‑bit security using the same AEAD and hash algorithms as classical suites.
-
Others prefer to follow recent guidance favoring AES‑256‑GCM and HMAC‑SHA‑384, aligning with modern conservative recommendations.
To support crypto agility, Cyfer offers several ciphersuites that accommodate:
- Deployments requiring only NIST‑approved algorithms
- Deployments wanting higher security levels
- Deployments that prefer hybrid traditional + PQ KEMs rather than pure ML‑KEM
This flexibility allows operators to match policy, regulatory, or performance needs without limiting interoperability.
Role of Traditional vs PQ Signatures
- Ciphersuites with traditional signatures still mitigate harvest‑now, decrypt‑later risks, because confidentiality comes from the PQ‑secure ML‑KEM. They avoid the computational overhead of PQ signatures.
- Ciphersuites with post‑quantum signatures go further by eliminating dependence on classical signature schemes, using only PQ KEMs and PQ signatures for all cryptographic operations.
MLS cipher suites with PQ confidentiality and classical authenticity:
| KEM | KDF | AEAD | Hash | Signature |
|---|---|---|---|---|
| ML-KEM-768 + X25519 | SHAKE256 | AES-128-GCM | SHA256 | ed25519 |
| ML-KEM-768 + X25519 | SHAKE256 | AES-256-GCM | SHA384 | ed25519 |
| ML-KEM-768 + P-256 | SHAKE256 | AES-128-GCM | SHA256 | ecdsa_secp256r1_sha256 |
| ML-KEM-768 + P-256 | SHAKE256 | AES-256-GCM | SHA384 | ecdsa_secp256r1_sha256 |
| ML-KEM-1024 + P-384 | SHAKE256 | AES-256-GCM | SHA384 | ecdsa_secp384r1_sha384 |
| ML-KEM-768 | SHAKE256 | AES-256-GCM | SHA384 | ecdsa_secp256r1_sha256 |
| ML-KEM-1024 | SHAKE256 | AES-256-GCM | SHA384 | ecdsa_secp384r1_sha384 |
MLS cipher suites with PQ confidentiality and PQ authenticity:
| KEM | KDF | AEAD | Hash | Signature |
|---|---|---|---|---|
| ML-KEM-768 | SHAKE256 | AES-256-GCM | SHA384 | mldsa65 |
| ML-KEM-1024 | SHAKE256 | AES-256-GCM | SHA384 | mldsa87 |
For a complete inventory of all cryptographic algorithms, implementations, and platform availability, see Appendix A: Cryptography Bill of Materials.
Amortized PQ MLS Combiner
Post‑quantum (PQ) algorithms such as ML‑KEM and ML‑DSA provide strong security against quantum-capable adversaries, but they come with substantial costs: large public keys, larger ciphertexts, and significantly greater CPU overhead than classical algorithms. Running MLS entirely with PQ ciphersuites would be secure but inefficient for many deployments.
The Amortized PQ MLS Combiner addresses this by running two synchronized MLS groups in parallel:
- A classical MLS group (fast, low overhead)
- A post‑quantum MLS group (secure against quantum adversaries)
Clients join both groups, but each group plays a different role:
- The PQ group updates less frequently and exports fresh PQ‑secure secret material.
- The classical group updates more frequently and performs all regular messaging operations.
At each PQ epoch, the PQ group produces a PQ‑secure secret, which is then fed into the classical MLS key schedule. This means the classical group’s cryptographic state is continuously anchored to PQ-protected material, even though the classical group is using cheap, efficient algorithms.
Key principles:
- Two trees, one logical session: You maintain a classical ratchet tree and a PQ ratchet tree, representing two MLS groups that advance together.
- Amortized PQ cost: PQ operations are performed infrequently (e.g., large epochs), dramatically reducing computational and bandwidth overhead.
- Configurable rotation policies:
- Classical epochs can rotate rapidly to maintain strong post-compromise security against classical attackers.
- PQ epochs can rotate more slowly, defining the system’s post‑quantum secrecy window, depending on organizational risk tolerance.
- Security benefits:
- Achieves PQ confidentiality and authenticity without paying the cost of full‑PQ MLS for every update.
- Maintains tight PCS and FS against traditional attackers via rapid classical key rotation.
- Protects long‑term confidentiality from quantum “harvest‑now, decrypt‑later” attacks with significantly lower overhead.
The combiner yields security properties equivalent to running a full PQ MLS session, but with compute and bandwidth costs similar to classical MLS for routine operations. It’s a flexible mechanism that allows deployments to tune PQ vs. classical rotation frequencies to match threat models, performance constraints, and regulatory requirements.
MLS Service Abstractions
MLS is designed to operate within the context of a messaging service, which may be a single service provider, a federated system, or some kind of peer-to-peer system. The service needs to provide two services that facilitate client communication using MLS:
Authentication Service (AS)
Responsible for attesting to bindings between application-meaningful identifiers and the public key material used for authentication in the MLS protocol. The AS must also be able to generate credentials that encode these bindings and validate credentials provided by MLS clients.
Delivery Service (DS)
Receives and distributes messages between group members. In the case of group messaging, the DS may also be responsible for acting as a “broadcaster” where the sender sends a single message which is then forwarded to each recipient in the group by the DS. The DS is also responsible for storing and delivering initial public key material required by MLS clients in order to proceed with the group secret key establishment that is part of the MLS protocol.
While these abstractions are a good baseline, a robust group messaging protocol requires more sophistication to handle advanced use cases.
This is where the MIMI (More Instant Messaging Interoperability) protocol fits in.
MIMI Transport Protocol
The More Instant Messaging Interoperability [MIMI] transport protocol enables interoperability between different providers of end-to-end encrypted instant messaging.
Each MIMI protocol room is hosted at a single provider (the “hub” provider"), but allows users from different providers to become participants in the room. The hub provider is responsible for ordering and distributing messages, enforcing policy, and authorizing messages. It also keeps a copy of the room state, which includes the room policy and participant list, which it can provide to new joiners. Each provider also stores initial keying material for its own users (who may be offline).
Hub/Follower Model
graph TB
subgraph "Provider A (Hub)"
Hub[Hub Server]
RoomState[(Room State)]
ClientA1[Client A1<br/>Alice]
ClientA2[Client A2<br/>Alice Device 2]
end
subgraph "Provider B (Follower)"
FollowerB[Follower Server]
ClientB1[Client B1<br/>Bob]
end
subgraph "Provider C (Follower)"
FollowerC[Follower Server]
ClientC1[Client C1<br/>Carol]
end
ClientA1 --> Hub
ClientA2 --> Hub
Hub --> RoomState
ClientB1 --> FollowerB
FollowerB <-->|"Register/Events"| Hub
ClientC1 --> FollowerC
FollowerC <-->|"Register/Events"| Hub
Room Model
- All conversations (DMs and group chats) are modeled as rooms.
- Each room has a single hub provider (the host).
- Users from multiple providers can participate in the same room.
Hub Responsibilities
- Ordering & distribution of messages to participants
- Policy enforcement and message authorization
- Maintains authoritative room state (policy + participant list)
- Serves room state to new joiners
- (Each provider, separately) stores initial keying material for its own users, including when they are offline.
Inter‑Provider Operations
- Share room policy
- Add / remove participants
- Exchange secure messages
- Primitives to:
- Fetch initial keying material for users
- Fetch current MLS group state for the room
Security / E2EE with MLS
- Every room maps to an MLS group.
- All room messages are E2EE using MLS application keys.
- MIMI integrates MLS so that:
- A client can join the MLS group only if its user is an authorized room participant.
- All clients converge on the same room state (policy and participant list) as part of the MLS group state.
Event Flow
sequenceDiagram
participant C as Client
participant F as Follower
participant H as Hub
participant F2 as Other Follower
participant C2 as Other Client
C->>F: Send MLS Message
F->>H: Forward to Hub
H->>H: Validate & Sequence
H->>H: Update Room State
par Distribute to All Followers
H->>F: Deliver Event (seq=42)
H->>F2: Deliver Event (seq=42)
end
F->>C: Deliver to Local Client
F2->>C2: Deliver to Local Client
Note over C,C2: All clients receive<br/>same event sequence
MIMI Message Format
The MIMI message format [ietf-mimi-content] defines how clients achieve the various features of a messaging application, for example:
- Text messaging
- File attachements
- Replies
- Reactions
- Initiation of real-time sessions
Messages transit MIMI servers by means of a message forwarding protocol, which carries an opaque, encrypted message payload together with enough metadata to facilitate delivery to the clients participating in a room.
Authentication and Credentials
JSON Web Tokens (JWTs) are compact, signed tokens that carry authentication and authorization claims. After a server validates a user, it issues a JWT containing identity and expiration data. Because the token is self‑verifying—its signature can be checked without contacting the issuer—JWTs enable stateless, scalable authentication across APIs, SPAs, and microservices.
However, JWTs are bearer tokens, meaning anyone who obtains one can use it. There is no cryptographic binding to the original client, so leaked tokens can be replayed by attackers to access protected APIs. This makes bearer tokens vulnerable to theft and misuse, especially in environments like browsers, mobile devices, and distributed systems.
Demonstrating Proof‑of‑Possession (DPoP) solves this by binding tokens to a client‑held key pair. The client sends a signed DPoP proof with token requests and API calls, allowing servers to confirm the caller actually holds the private key associated with the access token. Tokens contain a confirmation claim linking them to that key, and each request requires a fresh proof. This prevents replay attacks and makes tokens unusable if stolen, providing sender‑constrained security even when traditional transport‑layer mechanisms aren’t available.
sequenceDiagram
autonumber
actor C as Client
participant AS as Authorization Server
participant RS as Resource Server (API)
Note over C: 1) Generate a key pair for DPoP<br/>Used to sign per-request DPoP proof JWTs
C->>C: Generate JWK (public) + hold private key
Note over C,AS: 2) Obtain a sender-constrained access token
C->>AS: POST /token<br/>Headers: DPoP: <proof JWT signed with private key><br/>Body: grant_type=...&client_id=...&code=...
note right of C: DPoP proof claims:<br/>jti (unique), iat (issued time)<br/>htm (HTTP method), htu (token endpoint URL)<br/>jwk (public key)
AS->>AS: Validate DPoP proof (signature, htm, htu, iat, jti)
AS->>C: 200 OK<br/>access_token(bound to key via cnf.jkt)<br/>token_type=DPoP (optionally refresh_token)
Note over C,RS: 3) Call protected resource with proof-of-possession
C->>RS: GET /resource<br/>Authorization: DPoP <access_token><br/>DPoP: <new proof JWT signed with same private key>
note right of C: Request-time DPoP proof includes:<br/>jti, iat, htm=GET, htu=/resource<br/>ath=hash(access_token) (recommended)
RS->>RS: Validate DPoP proof (sig, htm, htu, iat, jti [+ nonce if required])
RS->>RS: Validate access token is bound to key (cnf.jkt == thumbprint(jwk))
RS->>C: 200 OK (resource)
alt Optional anti-replay hardening
RS-->>C: 401 Unauthorized<br/>DPoP-Nonce: <server nonce>
C->>RS: Retry with new DPoP proof including nonce claim
RS->>C: 200 OK
end
rect rgba(200, 200, 255, 0.15)
Note over C,RS: 4) Refresh flow
C->>AS: POST /token (refresh_token grant)<br/>Headers: DPoP: <proof JWT>
AS->>AS: Check that refresh token binding (cnf.jkt) matches proof key
AS->>C: New DPoP-bound access token (and refresh token)
end
Authentication Flow
In addition to the classical RSA and ECC algorithms, we support ML-DSA for all tokens, enabling quantum-safe authentication sessions.
sequenceDiagram
participant Client
participant Auth as Auth Service
participant IdentityDB as Identity DB
participant KeysDB as Keys DB
Client->>Auth: POST /token<br/>(email, password, dpop_proof)
Auth->>IdentityDB: Lookup by normalized email
IdentityDB-->>Auth: Account record
Auth->>Auth: Verify password hash
Auth->>Auth: Verify DPoP proof
Auth->>KeysDB: Fetch current signing key
KeysDB-->>Auth: SigningKey
Auth->>Auth: Generate JWT (RS256)
Auth->>Auth: Generate refresh token
Auth-->>Client: {access_token, refresh_token, expires_in}
Note over Client,Auth: Subsequent API Calls
Client->>Auth: API Request<br/>Authorization: DPoP {token}<br/>DPoP: {proof}
Auth->>Auth: Validate JWT signature
Auth->>Auth: Validate DPoP binding
Auth-->>Client: API Response
MLS Credential Binding
In order to facilitate the asynchronous addition of clients to a group, clients pre-publish Key Package objects that provide some public information about the user. The Key Package contains a credential that can be verified by the Authentication Service.
To prevent correlation between accounts and credentials, a pseudonomous identifier is created from the internal account ID when generating the credentials. Unique credentials are generated for each Key Package.
Since these credentials are potentially long-lived, they may be signed using post‑quantum (PQ) signature algorithms to provide quantum‑resilient authentication guarantees and to maintain long‑term cryptographic robustness against adversaries with access to quantum‑capable computing resources.
graph LR
subgraph "Authentication Domain"
Account[Account<br/>email, password]
end
subgraph "Cryptographic Domain"
Credential[MLS Credential<br/>signing key]
KeyPackage[Key Package<br/>init key]
end
subgraph "Identifiers"
AccountId[AccountId<br/>GUID]
PseudoId[PseudoAccountId<br/>derived]
Thumbprint[Thumbprint<br/>SHA-256]
end
Account --> AccountId
AccountId --> PseudoId
Credential --> Thumbprint
PseudoId -.->|linked| Thumbprint
Real-Time Communication
SFrame Architecture
SFrame [RFC 9605) is a media‑agnostic encryption framework designed for real‑time communications such as WebRTC. It provides end‑to‑end encryption of media frames independent of transport or signaling protocols.
When integrated with MLS, SFrame obtains its key material directly from the MLS group key schedule. This allows an MLS session to act as the secure group key management layer for real‑time audio/video, giving group calls the same forward secrecy and post‑compromise security guarantees as MLS text messaging.
Each MLS epoch produces a set of application secrets, from which applications can derive specialized key material. In the SFrame integration mode:
- The MLS group derives a media encryption secret as an application‑specific secret.
- From this secret, each sender derives:
- A sender-specific SFrame encryption key
- A sender-specific SFrame nonce base
- Optional context (e.g., frame counter initialization)
These values are fed directly into the SFrame key schedule.
All recipients in the MLS group can derive the same sender‑specific keys, ensuring interoperable decryption.
Frame Encryption Model
SFrame encrypts entire encoded media frames (video frames, audio packets, etc.) using:
- AEAD encryption (e.g., AES-CTR or AES‑GCM)
- A monotonically increasing per-frame counter mixed into the nonce
- A compact per‑frame header that identifies the sender key index and counter Because keys come from MLS, the sender key index is tied to the member’s MLS leaf, allowing receivers to bind media streams to authenticated MLS identities.
Sender Keys and Per-Sender Encryption
SFrame uses per‑sender keys, meaning:
- Every MLS client that transmits media uses a unique SFrame sender key.
- Receivers derive the corresponding sender key to decrypt frames from that sender.
- Changing MLS epochs forces automatic regeneration of all SFrame keys, providing:
- Forward secrecy: past frames cannot be decrypted after key updates
- Post‑compromise security: compromised clients heal when entering a new MLS epoch
Synchronization and Key Updates
MLS-driven SFrame keys update whenever the MLS epoch changes—typically triggered by:
- Membership changes (add/remove)
- Sender key updates (commit-based)
- Security updates (new entropy injected)
Upon entering a new MLS epoch:
- The sender derives a new SFrame key/nonce base.
- The SFrame sender key identifier is rotated.
- Receivers use the new identifier to sync automatically with the updated keys.
No separate SRTP-style rekeying protocol is needed because MLS handles all key agreement.
SFrame cipher suites
SFrame cipher suites utilize an AEAD encryption algorithm with a truncated authentication tag and a hash function defined by the cipher suite in use.
| AEAD | Hash | Auth Tag Length (bits) |
|---|---|---|
| AES-128-CTR | SHA256 | 80 |
| AES-128-CTR | SHA256 | 64 |
| AES-128-CTR | SHA256 | 32 |
| AES-128-GCM | SHA256 | 128 |
| AES-256-GCM | SHA512 | 128 |
| AES-256-CTR | SHA512 | 80 |
| AES-256-CTR | SHA512 | 64 |
| AES-256-CTR | SHA512 | 32 |
For a complete inventory of all cryptographic algorithms, implementations, and platform availability, see Appendix A: Cryptography Bill of Materials.
Key Derivation from MLS
SFrame keys are derived from MLS group secrets:
graph LR
MLS[MLS Group<br/>Epoch Secret] --> HKDF[Media Encryption Secret<br/>HKDF Expand]
HKDF --> SFrameKey[SFrame Key]
HKDF --> SFrameSalt[SFrame Salt]
SFrameSalt --> SFrameNonce[CTR Nonce]
SFrameKey --> Encrypt[Frame<br/>Encryption]
SFrameNonce--> Encrypt
Selective Forwarding Units
Cyfer provides an SFrame‑compatible Selective Forwarding Unit (SFU), which is a media router that forwards encrypted media frames between participants without ever decrypting them.
Cyfer prefers SFrame using Media over QUIC Transport [MOQT) for the highest performance. With Media over QUIC, the SFU becomes a QUIC‑native, object‑aware router that leverages QUIC’s reliability mix, priorities, and congestion control—while preserving end‑to‑end SFrame security and integrating smoothly with MLS‑based identity and key management. This architecture scales multi‑party A/V without ever exposing plaintext, aligning perfectly with Cyfer’s standards‑driven, crypto‑agile design.
The SFU in MOQT mode:
- Terminates QUIC connections with each participant (one client ↔ one QUIC connection).
- Forwards encrypted SFrame payloads as QUIC uni/bidi streams or datagrams, per application policy.
- Performs selective forwarding and congestion‑aware adaptation using MoQ/QUIC metadata (object headers, priorities, stream flow control) and control feedback—not media content.
Key property: No server‑side access to A/V plaintext. Endpoints hold SFrame keys; the SFU operates on encrypted objects with observable metadata only (e.g., track/layer IDs, key IDs, counters, priorities).
Packet & Frame Processing Pipeline
Ingress (per publisher connection):
-
QUIC session management: Accept a client QUIC connection; negotiate application protocol (e.g., MoQ subprotocol).
-
Object framing: Parse MoQ object headers (track, group/object sequence, dependency, priority), and SFrame header (key ID + counter) without decrypting payload.
-
Buffer & catalog: Store a sliding window of encrypted objects by (track → layer → object sequence). Maintain minimal indices for RTX/re‑delivery and late joiners. Egress (per subscriber connection):
-
Subscription mapping: For each receiver, map selected tracks/layers to QUIC streams (reliable, ordered) or datagrams (unreliable, unordered) per media profile (e.g., audio on streams, video enhancement layers on datagrams).
-
Scheduling & pacing: Use QUIC per‑stream flow control, priorities, and application‑level object deadlines to schedule sends. Do not modify SFrame payloads.
-
Adaptive delivery: Drop or skip lower‑value objects (e.g., delta frames, enhancement layers) under congestion; never tamper with object bytes.
Never performed by the SFU: SFrame decryption, transcoding, or content‑aware manipulation.
Identity, Tracks, and Binding
- Identity binding: Each publisher’s QUIC connection and track namespace binds to an authenticated application identity (e.g., MLS credential/leaf). The SFU trusts the control plane for admission and authorization.
- SFrame key tracking: Maintain per‑publisher tuples (epoch, key_id, frame_counter range) derived from SFrame headers. When keys rotate, update state for ordering and metrics—no key material is stored.
- Track model: Organize media as tracks (audio/video), each optionally with layers (simulcast/SVC). The SFU routes by
(publisher, track, layer)labels exposed in MoQ headers.
Selective Forwarding with QUIC Streams & Datagrams
- Reliability mix:
- Audio / base video layer: QUIC streams (reliable, in‑order) to preserve continuity.
- Enhancement layers / high‑temporal video: Datagrams (unreliable, low‑latency).
- Layer selection: Use dependency metadata (e.g., keyframe markers, decode dependencies) to pick the best layer for each receiver given bandwidth and device constraints.
- Re‑request & repair: For stream‑carried objects, rely on QUIC reliability; for datagram‑carried layers, allow opportunistic re‑publication (if cached) or skip to maintain latency.
Congestion Control & Adaptation (QUIC‑native)
- Congestion signals: Leverage QUIC’s built‑in ACKs, loss signals, RTT, cwnd per connection, plus any application feedback frames.
- Priority scheduling: Assign higher priority to audio and base layers. Use QUIC stream priorities to ensure timely delivery under load.
- Latency budgets: Enforce per‑object deadlines; drop expired enhancement objects rather than queueing them behind older content.
- Fairness: Apply per‑receiver pacing and per‑publisher policing to prevent head‑of‑line blocking across streams.
Rekeying, Epoch Changes, and Synchronization
- Key/epoch rotation: When endpoints rotate MLS epochs, senders rotate SFrame key IDs. The SFU:
- Detects key_id transitions and treats them as new key phases.
- Allows a short grace overlap to bridge reordering and partial delivery across the change.
- Joiners & catch‑up: For new subscribers, request or prioritize the next keyframe object (base layer) to enable rapid decoder lock. The SFU can advertise keyframe hints via control messages.
- Out‑of‑sync streams: If counters regress or jump, prefer keyframe gating (forward only after next keyframe) to avoid futile delivery.
Security & Privacy Posture
- End‑to‑end A/V confidentiality: SFrame protects payloads; the SFU sees only encrypted bytes and minimal headers (track/layer, SFrame key ID, counter).
- Integrity preservation: Any byte‑level modification to SFrame ciphertext will fail AEAD checks at receivers—hence the SFU must forward payloads verbatim.
- Access control: Enforced by the control plane (e.g., MLS room membership, policy). The SFU enforces publish/subscribe permissions and transport‑level isolation, not content authentication.
Data Architecture
Database Topology
Cyfer uses three SQL databases with distinct responsibilities:
graph TB
subgraph "Identity Domain"
IdentityDB[(Cyfer.Auth.CyferIdentityDatabase)]
Account[Account Table]
MlsCred[MlsCredential Table]
end
subgraph "Keys Domain"
KeysDB[(Cyfer.Auth.CyferKeysDatabase)]
EncKey[EncryptionKey Table]
SignKey[SigningKey Table]
end
subgraph "Graph Domain"
GraphDB[(Cyfer.Graph.CyferGraphDatabase)]
Tenant[Tenant Table]
GAccount[Account Table]
Profile[AccountProfile Table]
Client[Client Table]
end
IdentityDB --> Account
IdentityDB --> MlsCred
KeysDB --> EncKey
KeysDB --> SignKey
GraphDB --> Tenant
GraphDB --> GAccount
GraphDB --> Profile
GraphDB --> Client
Account -.->|"AccountId"| GAccount
MlsCred -.->|"PseudoAccountId"| Profile
The keys database contains keys for authentication (signing and encrypting the JWT tokens). The private keys for a client are generated on that client and are never transmitted to any service.
Database Separation Rationale
| Concern | Solution |
|---|---|
| Security | Credential data isolated from social graph |
| Scalability | Independent scaling per domain |
| Compliance | Per-database controls |
| Performance | Domain-specific indexing strategies |
Cloud Storage Layout
Blob Storage:
keypackages/{clientId}/{keyPackageId}- Key packagesgroupstate/{groupId}/state- MLS group state (binary)messages/{groupId}/{messageId}- Message distribution
AI Agent Integration
Cyfer supports AI agent integration through two complementary protocols that enable LLM-based agents to discover, understand, and interact with platform services.
Overview
graph TB
subgraph "AI Agents"
Claude[Claude]
GPT[GPT]
Custom[Custom Agents]
end
subgraph "Discovery Layer"
UTCP[UTCP Endpoints<br/>Embedded in Services]
end
subgraph "Dedicated Server"
MCP[MCP Server<br/>Bidirectional Protocol]
end
subgraph "Platform Services"
DS[Delivery Service]
GS[Graph Service]
NS[Notification Service]
end
Claude --> UTCP
GPT --> UTCP
Custom --> MCP
UTCP --> DS
UTCP --> GS
UTCP --> NS
MCP --> DS
UTCP
Universal Tool Calling Protocol [UTCP] is an embedded discovery protocol that allows AI agents to understand and call service APIs. Rather than being a separate server, UTCP endpoints are integrated into existing services:
graph LR
subgraph "AI Agent"
Agent[LLM Agent<br/>Claude/GPT]
end
subgraph "Services with UTCP"
DS[Delivery Service<br/>/utcp]
GS[Graph Service<br/>/utcp]
NS[Notification Service<br/>/utcp]
end
Agent -->|"GET /utcp"| DS
Agent -->|"GET /utcp"| GS
Agent -->|"GET /utcp"| NS
DS -->|"UTCP Manual"| Agent
GS -->|"UTCP Manual"| Agent
NS -->|"UTCP Manual"| Agent
UTCP Endpoints
| Endpoint | Description |
|---|---|
| GET /utcp | Returns complete UTCP manual with all tools |
| GET /utcp/tools | Returns simplified list of available tools |
| GET /utcp/tools/{name} | Returns details for a specific tool |
Supported Call Template Types
| Type | Description |
|---|---|
| http | HTTP/HTTPS REST API calls |
| cli | Command-line interface execution |
| mcp | Model Context Protocol |
| grpc | gRPC protocol |
UTCP-Enabled Services
| Service | Tools | Description |
|---|---|---|
| Delivery Service | send_message, get_messages, create_group | MLS messaging operations |
| Graph Service | get_profile, search_users, get_contacts | Social graph queries |
| Notification Service | subscribe, get_notifications | Real-time updates |
MCP
Model Context Protocol [MCP] provides a dedicated server for AI agent integration with bidirectional communication, supporting more complex interaction patterns than UTCP’s request-response model.
MCP Architecture
graph TB
subgraph "MCP Server (:8082)"
Tools[MCP Tools]
Resources[MCP Resources]
Transport[Transport Layer]
end
subgraph "Transports"
Stdio[stdio]
SSE[HTTP/SSE]
end
subgraph "Backend"
DS[Delivery Service]
Auth[Auth Service]
end
Tools --> DS
Resources --> DS
Transport --> Stdio
Transport --> SSE
Tools --> Auth
MCP Capabilities
| Category | Items | Description |
|---|---|---|
| Tools | create_room, add_participant, send_message, get_room_state | Actions the agent can perform |
| Resources | room://, policy://, events:// | Data the agent can read |
| Transports | stdio, HTTP/SSE | Communication channels |
MCP vs UTCP Comparison
| Aspect | UTCP | MCP |
|---|---|---|
| Architecture | Embedded in services | Dedicated server |
| Communication | Request-response | Bidirectional |
| Discovery | Self-describing via /utcp | Protocol negotiation |
| Real-time | Via separate notification | Built-in streaming |
| Use Case | Simple tool calling | Complex agent workflows |
Deployment Models
Container Deployment
graph TB
subgraph "Container Runtime"
Docker[Docker/Podman/K8s]
end
subgraph "Services"
DS[Delivery Service<br/>:8080]
AS[Auth Service<br/>:8081]
MCP[MCP Server<br/>:8082]
SFU[SFU Service<br/>:8083]
end
subgraph "Infrastructure"
SQL[SQL Server<br/>:1433]
Azurite[Azurite<br/>:10000-10002]
end
Docker --> DS
Docker --> AS
Docker --> MCP
Docker --> SFU
Docker --> SQL
Docker --> Azurite
DS --> SQL
DS --> Azurite
AS --> SQL
SFU --> DS
MCP --> DS
Cloud Deployment (Azure Example)
graph TB
subgraph "Compute"
Functions[Serverless Functions]
ContainerApps[Managed Containers]
end
subgraph "Data"
AzureSQL[Managed SQL<br/>3 Databases]
BlobStorage[Object Storage<br/>Key Packages, State]
TableStorage[Table Storage<br/>Queues, Index]
end
subgraph "Networking"
FrontDoor[Global Load Balancer<br/>CDN]
APIM[API Gateway]
end
subgraph "Security"
KeyVault[Secrets Manager]
AAD[Identity Provider]
end
FrontDoor --> APIM
APIM --> Functions
APIM --> ContainerApps
Functions --> AzureSQL
Functions --> BlobStorage
Functions --> TableStorage
ContainerApps --> AzureSQL
ContainerApps --> BlobStorage
Functions --> KeyVault
ContainerApps --> KeyVault
Functions --> AAD
Security Considerations
Threat Model
| Threat | Mitigation |
|---|---|
| Server Compromise | Zero-knowledge architecture; server cannot decrypt messages |
| Key Theft | Forward secrecy; past messages remain secure |
| Man-in-the-Middle | TLS 1.3 + DPoP token binding |
| Replay Attacks | Nonce-based DPoP proofs, epoch tracking |
| Insider Threat | Database separation, minimal privilege |
| Quantum Attacks | Hybrid ML-KEM cipher suites |
Data Classification
All PII is classified using SQL sensitivity labels:
| Classification | Label ID | Examples |
|---|---|---|
| Sensitive - Personal | Internal | Email, Phone |
| Confidential | System-defined | Credentials, Keys |
| Public | N/A | Display names, Profile pictures |
References
Standards
- [RFC 9420] Messaging Layer Security (MLS) Protocol
- [RFC 9750] Messaging Layer Security (MLS) Architecture
- [draft-ietf-mls-combiner] Amortized PQ MLS Combiner
- [draft-ietf-mls-pq-ciphersuites] ML-KEM and Hybrid Cipher Suites for MLS
- [draft-ietf-mimi-arch] An Architecture for More Instant Messaging Interoperability (MIMI)
- [draft-ietf-mimi-protocol] More Instant Messaging Interoperability (MIMI) using HTTPS and MLS
- [draft-ietf-mimi-content] More Instant Messaging Interoperability (MIMI) message content
- [RFC 9605] Secure Frame (SFrame): Lightweight Authenticated Encryption for Real-Time Media
- [draft-ietf-moq-transport] Media over QUIC Transport
- [RFC 9180] Hybrid Public Key Encryption (HPKE)
- [RFC 9449] OAuth 2.0 Demonstrating Proof of Possession (DPoP)
AI Agent Protocols
- UTCP - Universal Tool Calling Protocol (utcp.io)
- MCP - Model Context Protocol
Technology Stack
| Component | Technology | Version |
|---|---|---|
| Runtime | .NET | .NET 10 |
| Client - Native | .NET MAUI | .NET 10 |
| Server - Serverless | Cloud Functions (FaaS) | Latest |
| Server - Containers | ASP.NET Core | .NET 10 |
| Database | Managed SQL | Latest |
| Storage | Object/Table Storage | Latest |
| Testing | TUnit | Latest |
| CI/CD | GitHub Actions | Latest |
Appendix A: Cryptography Bill of Materials
The following tables document all cryptographic algorithms, their implementations, and platform availability. BouncyCastle is the primary implementation to ensure consistent cross-platform behavior.
Key Exchange & Encapsulation (KEM)
| Algorithm | Standard | Implementation | Version | Platform | PQ Status | Usage |
|---|---|---|---|---|---|---|
| X25519 | RFC 7748 | BouncyCastle | 2.6.2 | Server, MAUI, IoT | Classical | HPKE, MLS Key Packages |
| X448 | RFC 7748 | BouncyCastle | 2.6.2 | Server, MAUI, IoT | Classical | HPKE (high security) |
| P-256 | FIPS 186-5 | BouncyCastle | 2.6.2 | All | Classical | HPKE fallback |
| P-384 | FIPS 186-5 | BouncyCastle | 2.6.2 | Server, MAUI, IoT | Classical | HPKE (192-bit) |
| ML-KEM-768 | FIPS 203 | BouncyCastle | 2.6.2 | Server, MAUI | Post-Quantum | Hybrid MLS |
Digital Signatures
| Algorithm | Standard | Implementation | Version | Platform | PQ Status | Usage |
|---|---|---|---|---|---|---|
| Ed25519 | RFC 8032 | BouncyCastle | 2.6.2 | Server, MAUI, IoT | Classical | MLS Credentials, Key Packages |
| ECDSA P-256 | FIPS 186-5 | BouncyCastle | 2.6.2 | Server, MAUI, IoT | Classical | JWT, MLS Credentials, Key Packages |
| ECDSA P-384 | FIPS 186-5 | BouncyCastle | 2.6.2 | Server, MAUI, IoT | Classical | JWT, MLS Credentials, Key Packages |
| RSA-2048 | FIPS 186-5 | .NET | 10.0.x | Server, MAUI | Classical | Legacy JWT signing |
| ML-DSA | FIPS 204 | BouncyCastle | 2.6.2 | Server, MAUI | Post-Quantum | JWT, MLS Credentials, Key Packages |
Authenticated Encryption (AEAD)
| Algorithm | Standard | Implementation | Version | Platform | Security | Usage |
|---|---|---|---|---|---|---|
| AES-128-GCM | NIST SP 800-38D | BouncyCastle | 2.6.2 | Server, MAUI, IoT | 128-bit | HPKE, MLS messages |
| AES-256-GCM | NIST SP 800-38D | BouncyCastle | 2.6.2 | All | 256-bit | HPKE, SFrame |
| ChaCha20-Poly1305 | RFC 8439 | BouncyCastle | 2.6.2 | Server, MAUI, IoT | 256-bit | HPKE alternative |
| AES-128-CTR | NIST SP 800-38A | BouncyCastle | 2.6.2 | All | 128-bit | SFrame media |
| AES-256-CTR | NIST SP 800-38A | BouncyCastle | 2.6.2 | All | 256-bit | SFrame media |
Key Derivation Functions (KDF)
| Algorithm | Standard | Implementation | Version | Platform | Usage |
|---|---|---|---|---|---|
| HKDF-SHA256 | RFC 5869 | .NET | 10.0.x | All | HPKE, MLS secrets |
| HKDF-SHA384 | RFC 5869 | .NET | 10.0.x | All | HPKE |
| HKDF-SHA512 | RFC 5869 | .NET | 10.0.x | All | MLS, SFrame keys |
| SHAKE-256 | FIPS 202 | BouncyCastle | 2.6.2 | All | HPKE |
Hash Functions & MACs
| Algorithm | Standard | Implementation | Version | Platform | Usage |
|---|---|---|---|---|---|
| SHA-256 | FIPS 180-4 | .NET | 10.0.x | All | HKDF |
| SHA-384 | FIPS 180-4 | .NET | 10.0.x | All | HKDF |
| SHA-512 | FIPS 180-4 | .NET | 10.0.x | All | HKDF, SFrame, Thumbprints |
| HMAC-SHA256 | RFC 2104 | .NET | 10.0.x | All | SFrame auth tag |
| HMAC-SHA512 | RFC 2104 | .NET | 10.0.x | All | SFrame auth tag |
High-Level Protocols
| Protocol | Standard | Implementation | Version | Platform | Usage |
|---|---|---|---|---|---|
| HPKE | RFC 9180 | Cyfer | 1.0.0 | All | Key encapsulation, encryption |
Note: HPKE is a custom implementation that composes primitives from other libraries:
- KEM (X25519, P-256, etc.): BouncyCastle
- KDF (HKDF): .NET
- AEAD (AES-GCM, ChaCha20-Poly1305): BouncyCastle
This approach ensures RFC 9180 compliance while leveraging audited cryptographic implementations. The implementation is validated against the RFC 9180 test vectors.
Platform Legend
| Platform | Description | Primary Crypto Provider | Fallback |
|---|---|---|---|
| Server | ASP.NET Core services, Azure Functions | BouncyCastle (asymmetric), .NET (hash/KDF) | — |
| MAUI | Windows, macOS, iOS, Android native apps | BouncyCastle (asymmetric), .NET (hash/KDF) | — |
| Browser | Web Assembly (in progress) | BouncyCastle (asymmetric), .NET (hash/KDF) | SubtleCrypto, Web Crypto API |
| IoT | Meadow F7, Raspberry Pi | BouncyCastle (asymmetric), .NET (hash/KDF) | — |
Migration Planning
| Algorithm | Status | Deprecation | Replacement |
|---|---|---|---|
| RSA-2048 | Legacy | 2030-01-01 | Ed25519, ECDSA P-256 |
| P-256 (KEM) | Active | — | X25519 preferred |
| Classical-only | Active | 2030-01-01 | Hybrid PQ required |
| ML-KEM-768 | Active | — | — |
Document Version: 1.0
Last Updated: March 22, 2026
Author: Ron Peters