Remove Noise protocol references from wiki docs and tests
Delete 8 Noise-specific documentation pages (noise-xx.md,
transport-keys.md, adr-001/003/006, framing-codec.md) and update
~30 remaining wiki pages to reflect QUIC+TLS as the sole transport.
Remove obsolete Noise-based integration tests (auth_service.rs,
mls_group.rs). Code-side Noise removal was done in f334ed3.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,8 +20,8 @@ how the crates relate to one another.
|
||||
▼ ▼
|
||||
┌────────────────────────┐ ┌────────────────────────┐
|
||||
│ quicnprotochat-core │ │ quicnprotochat-server │
|
||||
│ (crypto, Noise, │ │ (QUIC listener, │
|
||||
│ MLS, hybrid KEM) │ │ NodeService RPC, │
|
||||
│ (crypto, MLS, │ │ (QUIC listener, │
|
||||
│ hybrid KEM) │ │ NodeService RPC, │
|
||||
│ │ │ storage) │
|
||||
└──────────┬─────────────┘ └─────────┬──────────────┘
|
||||
│ │
|
||||
@@ -42,27 +42,23 @@ serialisation. The server and client crates both depend on core and proto.
|
||||
|
||||
## quicnprotochat-core
|
||||
|
||||
**Role:** Pure cryptographic logic and transport primitives. No network I/O
|
||||
(except for the Noise handshake helpers that take an existing `TcpStream`). No
|
||||
async runtime dependency beyond what Noise transport needs.
|
||||
**Role:** Pure cryptographic logic. No network I/O. No async runtime
|
||||
dependency.
|
||||
|
||||
### Modules
|
||||
|
||||
| Module | Public API | Description |
|
||||
|---------------|-----------------------------------------------------------------------------|-------------|
|
||||
| `keypair` | `NoiseKeypair` | Static X25519 keypair for Noise_XX. `StaticSecret` is `ZeroizeOnDrop`. `private_bytes()` returns `Zeroizing<[u8; 32]>`. |
|
||||
| `identity` | `IdentityKeypair` | Ed25519 signing keypair for MLS credentials. Seed stored as `Zeroizing<[u8; 32]>`. Implements `openmls_traits::Signer`. |
|
||||
| `noise` | `handshake_initiator`, `handshake_responder`, `NoiseTransport` | Noise_XX_25519_ChaChaPoly_BLAKE2s handshake over TCP. `NoiseTransport` provides `send_frame`/`recv_frame`, envelope helpers, and `into_capnp_io()` bridge. |
|
||||
| `codec` | `LengthPrefixedCodec`, `NOISE_MAX_MSG` | Tokio `Encoder<Bytes>` + `Decoder`. 4-byte LE length prefix. Max frame 65,535 bytes. |
|
||||
| `group` | `GroupMember` | MLS group state machine wrapping `openmls::MlsGroup`. Lifecycle: `new` -> `generate_key_package` -> `create_group` / `join_group` -> `send_message` / `receive_message`. |
|
||||
| `keypackage` | `generate_key_package` | Standalone KeyPackage generation (returns TLS-encoded bytes + SHA-256 fingerprint). |
|
||||
| `keystore` | `DiskKeyStore`, `StoreCrypto` | `OpenMlsKeyStore` implementation backed by an in-memory `HashMap` with optional bincode flush to disk. `StoreCrypto` couples `RustCrypto` + `DiskKeyStore` into an `OpenMlsCryptoProvider`. |
|
||||
| `hybrid_kem` | `HybridKeypair`, `HybridPublicKey`, `hybrid_encrypt`, `hybrid_decrypt` | X25519 + ML-KEM-768 hybrid KEM. HKDF-SHA256 key derivation, ChaCha20-Poly1305 AEAD. Versioned envelope wire format. |
|
||||
| `error` | `CoreError`, `CodecError`, `MAX_PLAINTEXT_LEN` | Unified error types. `CoreError` covers Noise, Codec, Cap'n Proto, MLS, and hybrid KEM failures. |
|
||||
| `error` | `CoreError`, `MAX_PLAINTEXT_LEN` | Unified error types. `CoreError` covers Cap'n Proto, MLS, and hybrid KEM failures. |
|
||||
|
||||
### What this crate does NOT do
|
||||
|
||||
- No network I/O beyond the Noise helpers (which take a pre-connected `TcpStream`).
|
||||
- No network I/O.
|
||||
- No QUIC or TLS -- that is the server and client crates' concern.
|
||||
- No async runtime setup (it uses Tokio types internally but does not spawn or
|
||||
manage a runtime).
|
||||
@@ -70,10 +66,10 @@ async runtime dependency beyond what Noise transport needs.
|
||||
|
||||
### Key dependencies
|
||||
|
||||
`snow`, `x25519-dalek`, `ed25519-dalek`, `openmls`, `openmls_rust_crypto`,
|
||||
`openmls_traits`, `tls_codec`, `ml-kem`, `chacha20poly1305`, `hkdf`, `sha2`,
|
||||
`zeroize`, `capnp`, `quicnprotochat-proto`, `tokio`, `tokio-util`, `futures`,
|
||||
`bytes`, `serde`, `bincode`, `serde_json`, `thiserror`.
|
||||
`ed25519-dalek`, `openmls`, `openmls_rust_crypto`,
|
||||
`openmls_traits`, `tls_codec`, `ml-kem`, `x25519-dalek`, `chacha20poly1305`,
|
||||
`hkdf`, `sha2`, `zeroize`, `capnp`, `quicnprotochat-proto`, `tokio`,
|
||||
`serde`, `bincode`, `serde_json`, `thiserror`.
|
||||
|
||||
---
|
||||
|
||||
@@ -87,7 +83,7 @@ for the wire format.
|
||||
|
||||
| Item | Description |
|
||||
|---------------------------|-------------|
|
||||
| `schemas/envelope.capnp` | `Envelope` struct and `MsgType` enum -- top-level wire message for Noise-channel traffic. |
|
||||
| `schemas/envelope.capnp` | `Envelope` struct and `MsgType` enum -- top-level wire message. |
|
||||
| `schemas/auth.capnp` | `AuthenticationService` interface -- `uploadKeyPackage`, `fetchKeyPackage`. |
|
||||
| `schemas/delivery.capnp` | `DeliveryService` interface -- `enqueue`, `fetch`. |
|
||||
| `schemas/node.capnp` | `NodeService` interface (unified AS+DS) -- all RPC methods plus `Auth` struct. |
|
||||
@@ -148,7 +144,6 @@ is handled by `spawn_local`.
|
||||
- No direct crypto operations (it delegates to `quicnprotochat-core` types
|
||||
for fingerprinting and storage only).
|
||||
- No MLS processing -- all payloads are opaque byte strings.
|
||||
- No Noise transport (QUIC/TLS only).
|
||||
|
||||
### Key dependencies
|
||||
|
||||
@@ -192,7 +187,6 @@ group state to disk.
|
||||
### What this crate does NOT do
|
||||
|
||||
- No server-side logic.
|
||||
- No Noise transport (QUIC/TLS only for server communication).
|
||||
- No direct crypto beyond calling `GroupMember` and verifying SHA-256
|
||||
fingerprints.
|
||||
|
||||
|
||||
@@ -26,24 +26,15 @@ connection lifecycle, and the long-polling `fetchWait` mechanism.
|
||||
|
||||
---
|
||||
|
||||
## Dual-Key Model
|
||||
## Identity Key Model
|
||||
|
||||
quicnprotochat uses two independent asymmetric key pairs per client, each
|
||||
serving a distinct role:
|
||||
Each quicnprotochat client holds a single Ed25519 signing keypair that serves
|
||||
as its long-term identity:
|
||||
|
||||
```text
|
||||
quicnprotochat Key Model
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ X25519 static keypair (Noise transport) │
|
||||
│ ───────────────────────────────────── │
|
||||
│ - Generated once per node identity │
|
||||
│ - Used in the Noise_XX handshake (M1 stack) │
|
||||
│ - Provides mutual authentication + │
|
||||
│ channel confidentiality at the TCP layer │
|
||||
│ - Classical only (no PQ protection) │
|
||||
│ - Managed by NoiseKeypair, zeroize-on-drop │
|
||||
│ │
|
||||
│ Ed25519 signing keypair (MLS identity) │
|
||||
│ ────────────────────────────────────── │
|
||||
│ - Generated once per user/device │
|
||||
@@ -55,17 +46,16 @@ serving a distinct role:
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| Property | X25519 (Noise) | Ed25519 (MLS) |
|
||||
|-------------------|-------------------------------------|--------------------------------------------|
|
||||
| Curve | Curve25519 (Montgomery) | Ed25519 (Twisted Edwards) |
|
||||
| Purpose | Transport authentication + secrecy | Identity binding, signing, MLS credentials |
|
||||
| Crate | `x25519-dalek` | `ed25519-dalek` |
|
||||
| Zeroize on drop | Yes (`StaticSecret`) | Yes (`Zeroizing<[u8; 32]>`) |
|
||||
| PQ protection | None (classical X25519) | MLS key schedule uses DHKEM(X25519); hybrid PQ KEM available at envelope level |
|
||||
| Property | Ed25519 (MLS) |
|
||||
|-------------------|--------------------------------------------|
|
||||
| Curve | Ed25519 (Twisted Edwards) |
|
||||
| Purpose | Identity binding, signing, MLS credentials |
|
||||
| Crate | `ed25519-dalek` |
|
||||
| Zeroize on drop | Yes (`Zeroizing<[u8; 32]>`) |
|
||||
| PQ protection | MLS key schedule uses DHKEM(X25519); hybrid PQ KEM available at envelope level |
|
||||
|
||||
For details on the cryptographic properties of each key type, see
|
||||
[Ed25519 Identity Keys](../cryptography/identity-keys.md) and
|
||||
[X25519 Transport Keys](../cryptography/transport-keys.md).
|
||||
For details on the cryptographic properties, see
|
||||
[Ed25519 Identity Keys](../cryptography/identity-keys.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -80,14 +70,9 @@ For details on the cryptographic properties of each key type, see
|
||||
│ │ │ │
|
||||
│ GroupMember │ │ GroupMember │
|
||||
│ (MLS state) │ │ (MLS state) │
|
||||
│ │ │ │
|
||||
│ NoiseKeypair* │ │ NoiseKeypair* │
|
||||
│ (X25519, M1) │ │ (X25519, M1) │
|
||||
└────────┬─────────┘ └────────┬─────────┘
|
||||
│ │
|
||||
│ QUIC + TLS 1.3 (quinn/rustls) │
|
||||
│ ─── or ─── │
|
||||
│ Noise_XX over TCP (snow, M1 stack) │
|
||||
│ │
|
||||
▼ ▼
|
||||
┌────────────────────────────────────────────────────────────────────────────┐
|
||||
@@ -118,8 +103,7 @@ For details on the cryptographic properties of each key type, see
|
||||
2. KeyPackages are single-use (RFC 9420 requirement). The AS atomically removes
|
||||
a KeyPackage on fetch to enforce this invariant.
|
||||
|
||||
3. The QUIC + TLS 1.3 stack is the primary transport (M3+). The Noise_XX over
|
||||
TCP stack from M1 remains available for environments where QUIC is blocked.
|
||||
3. QUIC + TLS 1.3 is the sole transport layer.
|
||||
|
||||
---
|
||||
|
||||
@@ -127,9 +111,8 @@ For details on the cryptographic properties of each key type, see
|
||||
|
||||
The system stacks three protocol layers:
|
||||
|
||||
1. **Transport** -- QUIC + TLS 1.3 (primary) or Noise_XX over TCP (M1
|
||||
fallback). Provides confidentiality, integrity, and server authentication.
|
||||
See [Protocol Stack](protocol-stack.md).
|
||||
1. **Transport** -- QUIC + TLS 1.3. Provides confidentiality, integrity, and
|
||||
server authentication. See [Protocol Stack](protocol-stack.md).
|
||||
|
||||
2. **Framing / RPC** -- Cap'n Proto serialisation and RPC. Provides zero-copy
|
||||
typed messages, schema versioning, and async method dispatch.
|
||||
@@ -152,7 +135,7 @@ The implementation is split across four workspace crates:
|
||||
|
||||
| Crate | Role |
|
||||
|----------------------------|-------------------------------------------------------------------|
|
||||
| `quicnprotochat-core` | Crypto primitives, Noise transport, MLS state machine, hybrid KEM |
|
||||
| `quicnprotochat-core` | Crypto primitives, MLS state machine, hybrid KEM |
|
||||
| `quicnprotochat-proto` | Cap'n Proto schemas, codegen, and serialisation helpers |
|
||||
| `quicnprotochat-server` | QUIC listener, NodeService RPC, storage |
|
||||
| `quicnprotochat-client` | QUIC client, CLI subcommands, state persistence |
|
||||
@@ -164,7 +147,7 @@ and dependency diagram.
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Protocol Stack](protocol-stack.md) -- layered comparison of the two transport stacks
|
||||
- [Protocol Stack](protocol-stack.md) -- layered protocol stack description
|
||||
- [Service Architecture](service-architecture.md) -- NodeService RPC methods, connection lifecycle, long-polling
|
||||
- [End-to-End Data Flow](data-flow.md) -- registration, group creation, and message exchange sequence diagrams
|
||||
- [Wire Format Overview](../wire-format/overview.md) -- Cap'n Proto schema reference
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
|
||||
quicnprotochat layers three protocol stages to move a plaintext message from
|
||||
sender to recipient with end-to-end encryption, typed RPC framing, and
|
||||
authenticated transport. This page describes each layer, explains why both the
|
||||
QUIC and Noise transport stacks exist, and provides a side-by-side comparison.
|
||||
authenticated transport. This page describes each layer and provides a
|
||||
comparison table.
|
||||
|
||||
---
|
||||
|
||||
## Primary Stack (M3+): QUIC + TLS 1.3
|
||||
## Transport: QUIC + TLS 1.3
|
||||
|
||||
Starting from milestone M3, the primary transport is QUIC over UDP with TLS 1.3
|
||||
negotiated by `quinn` and `rustls`. Cap'n Proto RPC rides on a bidirectional
|
||||
QUIC stream.
|
||||
The transport layer is QUIC over UDP with TLS 1.3 negotiated by `quinn` and
|
||||
`rustls`. Cap'n Proto RPC rides on a bidirectional QUIC stream.
|
||||
|
||||
```text
|
||||
┌─────────────────────────────────────────────┐
|
||||
@@ -56,90 +55,6 @@ QUIC stream.
|
||||
`BasicCredential`.
|
||||
- Ciphersuite: `MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519`.
|
||||
|
||||
---
|
||||
|
||||
## M1 Stack: Noise_XX over TCP
|
||||
|
||||
The original milestone-1 transport uses a Noise Protocol Framework handshake
|
||||
directly over TCP. This stack is retained for environments where QUIC (UDP) is
|
||||
blocked by middleboxes.
|
||||
|
||||
```text
|
||||
TCP connection
|
||||
└── Noise_XX handshake (snow)
|
||||
└── Authenticated encrypted channel (ChaCha20-Poly1305)
|
||||
└── [u32 frame_len LE][Cap'n Proto encoded message]
|
||||
└── Cap'n Proto RPC (capnp-rpc)
|
||||
```
|
||||
|
||||
### Layer details
|
||||
|
||||
**TCP**
|
||||
|
||||
- Reliable, ordered byte stream.
|
||||
- No built-in encryption or authentication.
|
||||
|
||||
**Noise_XX** (`snow`)
|
||||
|
||||
- Pattern: `Noise_XX_25519_ChaChaPoly_BLAKE2s`.
|
||||
- Three-message handshake that mutually authenticates both peers' static
|
||||
X25519 keys:
|
||||
|
||||
```text
|
||||
XX handshake (3 messages):
|
||||
-> e (initiator sends ephemeral public key)
|
||||
<- e, ee, s, es (responder: DH + static key)
|
||||
-> s, se (initiator: static key + final DH)
|
||||
```
|
||||
|
||||
- After the handshake, every frame is encrypted with ChaCha20-Poly1305 (AEAD)
|
||||
using session keys derived from the Noise key schedule.
|
||||
- Maximum Noise message size: 65,535 bytes.
|
||||
|
||||
**Length-Prefixed Codec** (`LengthPrefixedCodec` in `quicnprotochat-core`)
|
||||
|
||||
- Each frame is prefixed by a 4-byte little-endian `u32` length field.
|
||||
- Little-endian was chosen for consistency with Cap'n Proto's segment table
|
||||
encoding.
|
||||
- Wire format:
|
||||
|
||||
```text
|
||||
┌──────────────────────────┬──────────────────────────────────────┐
|
||||
│ length (4 bytes, LE u32)│ payload (length bytes) │
|
||||
└──────────────────────────┴──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- Maximum payload size is `NOISE_MAX_MSG` (65,535 bytes), enforced on both
|
||||
encode and decode.
|
||||
- See [Length-Prefixed Framing Codec](../wire-format/framing-codec.md) for the
|
||||
full specification.
|
||||
|
||||
**Cap'n Proto RPC**
|
||||
|
||||
- Same schema and RPC interface as the QUIC stack.
|
||||
- The `NoiseTransport::into_capnp_io()` method bridges the message-oriented
|
||||
Noise channel to the byte-stream interface that `capnp-rpc`'s
|
||||
`twoparty::VatNetwork` expects, using a `tokio::io::duplex` pipe and a
|
||||
background shuttle task.
|
||||
|
||||
---
|
||||
|
||||
## Why Both Stacks Exist
|
||||
|
||||
| Concern | QUIC + TLS 1.3 | Noise_XX over TCP |
|
||||
|------------------------|----------------------------------------|----------------------------------------|
|
||||
| **Milestone** | M3+ (primary) | M1 (original, retained) |
|
||||
| **UDP availability** | Requires UDP; may be blocked on some networks | TCP-only; works everywhere |
|
||||
| **Connection setup** | 1-RTT (or 0-RTT on resumption) | 1-RTT TCP + 1.5-RTT Noise handshake |
|
||||
| **Multiplexing** | Native QUIC stream multiplexing | Single TCP connection, single stream |
|
||||
| **Authentication** | Server cert (self-signed / CA-issued) | Mutual static-key authentication |
|
||||
| **PQ gap** | TLS 1.3 key exchange is classical ECDHE | Noise key exchange is classical X25519 |
|
||||
| **Crate** | `quinn`, `rustls` | `snow` |
|
||||
|
||||
Both stacks carry the same Cap'n Proto RPC and MLS layers on top, so
|
||||
application logic is transport-agnostic. The Noise_XX stack may also serve as a
|
||||
peer-to-peer transport in future mesh topologies where a QUIC server
|
||||
certificate model does not apply.
|
||||
|
||||
---
|
||||
|
||||
@@ -148,7 +63,6 @@ certificate model does not apply.
|
||||
| Layer | Provides | Crate(s) |
|
||||
|-------------|------------------------------------------------------------------|-----------------------------------------|
|
||||
| **Transport: QUIC + TLS 1.3** | Confidentiality, server authentication, forward secrecy, multiplexed streams, congestion control | `quinn`, `rustls` |
|
||||
| **Transport: Noise_XX** | Confidentiality, mutual authentication, forward secrecy (per-session) | `snow` |
|
||||
| **Framing: Cap'n Proto** | Zero-copy typed serialisation, schema versioning, async RPC with promise pipelining | `capnp`, `capnp-rpc` |
|
||||
| **Encryption: MLS** | Group key agreement, forward secrecy, post-compromise security, identity binding | `openmls`, `openmls_rust_crypto` |
|
||||
| **Encryption: Hybrid KEM** (optional) | Post-quantum confidentiality for individual payloads (X25519 + ML-KEM-768) | `ml-kem`, `x25519-dalek`, `chacha20poly1305`, `hkdf` |
|
||||
@@ -175,12 +89,12 @@ TLS-encoded MlsMessageOut (opaque ciphertext blob)
|
||||
Cap'n Proto: enqueue(recipientKey, payload)
|
||||
│ ── serialised into NodeService RPC call ──
|
||||
▼
|
||||
QUIC stream (TLS 1.3 encrypted) ─── or ─── Noise frame (ChaCha20-Poly1305)
|
||||
│ │
|
||||
▼ ▼
|
||||
QUIC stream (TLS 1.3 encrypted)
|
||||
│
|
||||
▼
|
||||
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ network ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
|
||||
│ │
|
||||
▼ ▼
|
||||
│
|
||||
▼
|
||||
Server: NodeService.enqueue() stores payload in FIFO queue
|
||||
│
|
||||
▼
|
||||
@@ -200,8 +114,7 @@ The server **never** holds the MLS group key. It sees only the encrypted
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Architecture Overview](overview.md) -- high-level system diagram and dual-key model
|
||||
- [Noise_XX Handshake](../protocol-layers/noise-xx.md) -- deep dive into the three-message handshake
|
||||
- [Architecture Overview](overview.md) -- high-level system diagram and identity key model
|
||||
- [QUIC + TLS 1.3](../protocol-layers/quic-tls.md) -- QUIC configuration, ALPN, and certificate handling
|
||||
- [Cap'n Proto Serialisation and RPC](../protocol-layers/capn-proto.md) -- schema design and VatNetwork wiring
|
||||
- [MLS (RFC 9420)](../protocol-layers/mls.md) -- ciphersuite selection, key schedule, and ratchet tree
|
||||
|
||||
Reference in New Issue
Block a user