chore: rename project quicnprotochat -> quicproquo (binaries: qpq)

Rename the entire workspace:
- Crate packages: quicnprotochat-{core,proto,server,client,gui,p2p,mobile} -> quicproquo-*
- Binary names: quicnprotochat -> qpq, quicnprotochat-server -> qpq-server,
  quicnprotochat-gui -> qpq-gui
- Default files: *-state.bin -> qpq-state.bin, *-server.toml -> qpq-server.toml,
  *.db -> qpq.db
- Environment variable prefix: QUICNPROTOCHAT_* -> QPQ_*
- App identifier: chat.quicnproto.gui -> chat.quicproquo.gui
- Proto package: quicnprotochat.bench -> quicproquo.bench
- All documentation, Docker, CI, and script references updated

HKDF domain-separation strings and P2P ALPN remain unchanged for
backward compatibility with existing encrypted state and wire protocol.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 20:11:51 +01:00
parent 553de3a2b7
commit 853ca4fec0
152 changed files with 4070 additions and 788 deletions

View File

@@ -1,8 +1,8 @@
# MLS (RFC 9420)
The Messaging Layer Security protocol (RFC 9420) is the core cryptographic layer in quicnprotochat. It provides authenticated group key agreement with forward secrecy and post-compromise security -- properties that distinguish quicnprotochat from a simple transport-encrypted relay. This is the most detailed page in the Protocol Deep Dives section because MLS is the most complex layer in the stack.
The Messaging Layer Security protocol (RFC 9420) is the core cryptographic layer in quicproquo. It provides authenticated group key agreement with forward secrecy and post-compromise security -- properties that distinguish quicproquo from a simple transport-encrypted relay. This is the most detailed page in the Protocol Deep Dives section because MLS is the most complex layer in the stack.
The implementation lives in `quicnprotochat-core/src/group.rs` and `quicnprotochat-core/src/keystore.rs`, using the `openmls 0.5` crate.
The implementation lives in `quicproquo-core/src/group.rs` and `quicproquo-core/src/keystore.rs`, using the `openmls 0.5` crate.
## Background: what problem MLS solves
@@ -21,7 +21,7 @@ MLS takes a fundamentally different approach: it uses a **ratchet tree** (a bina
## Ciphersuite
quicnprotochat uses:
quicproquo uses:
```text
MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519
@@ -38,7 +38,7 @@ This ciphersuite provides 128-bit classical security. Post-quantum protection is
## The `GroupMember` state machine
The central type is `GroupMember`, defined in `quicnprotochat-core/src/group.rs`. It wraps an openmls `MlsGroup`, a persistent crypto backend (`StoreCrypto`), and the user's long-term Ed25519 identity keypair.
The central type is `GroupMember`, defined in `quicproquo-core/src/group.rs`. It wraps an openmls `MlsGroup`, a persistent crypto backend (`StoreCrypto`), and the user's long-term Ed25519 identity keypair.
### Lifecycle diagram
@@ -135,7 +135,7 @@ pub fn create_group(&mut self, group_id: &[u8]) -> Result<(), CoreError>
Creates a new MLS group at epoch 0 with the caller as the sole member.
**Parameters:**
- `group_id`: Any non-empty byte string. By convention, quicnprotochat uses the SHA-256 digest of a human-readable group name.
- `group_id`: Any non-empty byte string. By convention, quicproquo uses the SHA-256 digest of a human-readable group name.
**What happens internally:**
@@ -259,7 +259,7 @@ Processes an incoming TLS-encoded MLS message.
## The `StoreCrypto` backend
The `StoreCrypto` struct (in `quicnprotochat-core/src/keystore.rs`) implements `OpenMlsCryptoProvider`, which openmls requires for all cryptographic operations:
The `StoreCrypto` struct (in `quicproquo-core/src/keystore.rs`) implements `OpenMlsCryptoProvider`, which openmls requires for all cryptographic operations:
```rust
pub struct StoreCrypto {
@@ -318,11 +318,11 @@ KeyPackageIn::tls_deserialize(&mut bytes.as_ref())?
### Feature-gated methods
Several convenient methods (`into_welcome()`, `into_protocol_message()`) are feature-gated behind openmls feature flags that quicnprotochat does not enable. The workaround is to use `msg_in.extract()` and pattern-match on the `MlsMessageInBody` enum variants.
Several convenient methods (`into_welcome()`, `into_protocol_message()`) are feature-gated behind openmls feature flags that quicproquo does not enable. The workaround is to use `msg_in.extract()` and pattern-match on the `MlsMessageInBody` enum variants.
### MlsGroup is not Send
`MlsGroup` holds internal state that may not be `Send` depending on the crypto backend. In quicnprotochat, `StoreCrypto` uses `RwLock` (which is `Send + Sync`), so `GroupMember` is `Send`. However, all MLS operations must use the same backend instance, so `GroupMember` should not be cloned across tasks.
`MlsGroup` holds internal state that may not be `Send` depending on the crypto backend. In quicproquo, `StoreCrypto` uses `RwLock` (which is `Send + Sync`), so `GroupMember` is `Send`. However, all MLS operations must use the same backend instance, so `GroupMember` should not be cloned across tasks.
## Ratchet tree embedding
@@ -335,7 +335,7 @@ The trade-off:
- **Pro**: No need for a separate tree distribution service or additional round-trips.
- **Con**: Welcome messages grow with the group size (O(n log n) for a balanced tree of n members).
For quicnprotochat's target group sizes (2-100 members), this trade-off is acceptable.
For quicproquo's target group sizes (2-100 members), this trade-off is acceptable.
## Wire format
@@ -386,7 +386,7 @@ The following sequence shows a complete Alice-and-Bob scenario, matching the `tw
## Credential model
quicnprotochat uses MLS `Basic` credentials. The credential body is the raw Ed25519 public key bytes (32 bytes), and the `signature_key` is the same public key:
quicproquo uses MLS `Basic` credentials. The credential body is the raw Ed25519 public key bytes (32 bytes), and the `signature_key` is the same public key:
```rust
let credential = Credential::new(