Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changeset/book-principal-per-half-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

Book-only: describe the principal as a credential-scoped identity whose key-package halves carry their own signing keys; nothing ships.
17 changes: 10 additions & 7 deletions book/src/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ operations for a credential funnel through the one object.
TwoMLSPQ deliberately breaks this up into three app-facing objects, each owning
exactly the state its job needs:

- **`TwoMlsPqPrincipal`** — the principal: a credential-scoped signing identity. Its job
is minting key packages and invitations and holding their private material only until it
is captured into an invitation (`generate_invitation` purges the principal's own copies).
It is not a hub for group operations.
- **`TwoMlsPqPrincipal`** — the principal: a credential-scoped identity (one MLS Basic
Credential). Its job is minting key packages and invitations and holding their private
material only until it is captured into an invitation (`generate_invitation` purges the
principal's own copies). It is not a hub for group operations. Each half of a key package
it mints carries a signing key, and that key is the one its owner signs with in the group
the half joins (see [Group Rules](./group-rules.md), rule 4). A principal may use one
signing key for every half it mints, or a fresh key per half; both conform.
- **`TwoMlsPqInvitation`** — a self-contained receiving capability: one published
combiner key package's private material, the signing identity, and the
consumed-remote replay guard. It turns welcomes into sessions with no live client
combiner key package's private material (each half's HPKE and signing keys), the
credential it was minted under, and the consumed-remote replay guard. It turns welcomes into sessions with no live client
and survives restarts through its own archive. TwoMLS manages the key package's
lifetime itself rather than via mls-rs's on-the-wire last-resort extension: a
*last-resort* invitation retains its key package to accept many welcomes, while a
Expand All @@ -34,7 +37,7 @@ CommProtocol's `Agent` (this crate is CommProtocol-agnostic):

| mls-rs | TwoMLSPQ | role |
|---|---|---|
| `Client` | **`TwoMlsPqPrincipal`** | credential-scoped signer; mints invitations & sessions |
| `Client` | **`TwoMlsPqPrincipal`** | credential-scoped identity; mints key packages, invitations & sessions |
| `KeyPackage` | **`TwoMlsPqInvitation`** | one published key package's private material |
| group | **`TwoMlsPqSession`** | one established pairwise channel |

Expand Down
9 changes: 4 additions & 5 deletions book/src/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ It does not otherwise depend on CommProtocol's identities and exposes an MLS cli
of basic credentials.

The app hands TwoMLSPQ the opaque **`ClientId`** of one of its **agents** — identity bytes.
TwoMLSPQ builds a **`TwoMlsPqPrincipal`** for that ClientId, minting a fresh MLS leaf signing key
internally. The ClientId is carried as the MLS Basic Credential — identity trust comes
from the app layer, not an
external Authentication Service — and the signing key that authenticates the leaf lives
inside this library and never crosses the boundary. Everything above the ClientId is outside
TwoMLSPQ builds a **`TwoMlsPqPrincipal`** for that ClientId, and mints the MLS leaf signing
keys internally. The ClientId is carried as the MLS Basic Credential — identity trust comes
from the app layer, not an external Authentication Service — and the signing keys that
authenticate its leaves live inside this library and never cross the boundary. Everything above the ClientId is outside
this library's boundary.

## How a session is built
Expand Down
3 changes: 2 additions & 1 deletion book/src/session-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ under it (Establishment, above).
## Invitations & replayed initial frames

A published key package is backed by a self-contained **`TwoMlsPqInvitation`** (the
signing identity plus the key package's private material) rather than a live client;
credential plus the key package's private material, including its signing keys) rather
than a live client;
one invitation services many welcomes, deduplicating repeats per remote
(`DuplicateWelcome`). `receive(welcome, their_classical_kp, bootstrap_kp_commitment,
spawn_token)` takes an opaque, caller-chosen, replay-stable token for the initial frame
Expand Down
Loading