c8398d6cb7
feat: DM epoch fix, federation relay, and mDNS mesh discovery
...
- schema: createChannel returns wasNew :Bool to elect the MLS initiator
unambiguously; prevents duplicate group creation on concurrent /dm calls
- core: group helpers for epoch tracking and key-package lifecycle
- server: federation subsystem — mTLS QUIC server-to-server relay with
Cap'n Proto RPC; enqueue/batchEnqueue relay unknown recipients to their
home domain via FederationClient
- server: mDNS _quicproquo._udp.local. service announcement on startup
- server: storage + sql_store — identity_exists, peek/ack, federation
home-server lookup helpers
- client: /mesh peers REPL command (mDNS discovery, feature = "mesh")
- client: MeshDiscovery — background mDNS browse with ServiceDaemon
- client: was_new=false path in cmd_dm waits for peer Welcome instead of
creating a duplicate initiator group
- p2p: fix ALPN from quicnprotochat/p2p/1 → quicproquo/p2p/1
- workspace: re-include quicproquo-p2p in members
2026-03-03 14:41:56 +01:00
853ca4fec0
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 >
2026-03-01 20:11:51 +01:00
4c1e4683e3
chore: exclude p2p crate from workspace, slim tokio features
...
Move quicnprotochat-p2p to workspace.exclude so ~90 iroh-only
dependencies are not compiled in the default build. Narrow tokio
features from "full" to the subset actually used. The p2p crate
now pins its own dependency versions since it is outside the workspace.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-23 23:10:23 +01:00
b5b361e2ff
chore: move Python/Ruby/bindings crates to quicnprotochat-lang-clients repo
...
The three crates (quicnprotochat-bindings, quicnprotochat-python,
quicnprotochat-ruby) are developed in a separate feature repository
at git.xorwell.de:c/quicnprotochat-lang-clients.
2026-02-22 18:58:45 +01:00
0bdc222724
fix: address 16 architecture design flaws across all crates
...
Phase 1 — Foundation:
- Constant-time token comparison via subtle::ConstantTimeEq (Fix 11)
- Structured error codes E001–E020 in new error_codes.rs (Fix 15)
- Remove dead envelope.capnp code and related types (Fix 16)
Phase 2 — Auth Hardening:
- Registration collision check via has_user_record() (Fix 5)
- Auth required on uploadHybridKey/fetchHybridKey RPCs (Fix 1)
- Identity-token binding at registration and login (Fix 2)
- Session token expiry with 24h TTL and background reaper (Fix 3)
- Bounded pending logins with 5-minute timeout (Fix 4)
Phase 3 — Resource Limits:
- Rate limiting: 100 enqueues/60s per token (Fix 6)
- Queue depth cap at 1000 + 7-day message TTL/GC (Fix 7)
- Partial queue drain via limit param on fetch/fetchWait (Fix 8)
Phase 4 — Crypto Fixes:
- OPAQUE KSF switched from Identity to Argon2id (Fix 10)
- Random AEAD nonce in hybrid KEM instead of HKDF-derived (Fix 12)
- Zeroize secret fields in HybridKeypairBytes (Fix 13)
- Encrypted client state files via QPCE format (Fix 9)
Phase 5 — Protocol:
- Commit fan-out to all existing members on invite (Fix 14)
- Add member_identities() to GroupMember
Breaking: existing OPAQUE registrations invalidated (Argon2 KSF).
Schema: added auth to hybrid key ops, identityKey to OPAQUE finish
RPCs, limit to fetch/fetchWait.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 10:51:09 +01:00
8d5c1b3b9b
WIP: add OPAQUE password-authenticated key exchange
...
Add opaque-ke (v4, ristretto255) for password-based registration and
login. Extend NodeService schema with opaqueRegisterStart/Finish and
opaqueLoginStart/Finish RPCs. Add Store trait methods for OPAQUE server
setup and user records. Initial e2e integration test scaffolding.
Note: FileBackedStore does not yet implement the new Store trait
methods — server compilation is temporarily broken.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 08:25:34 +01:00
f334ed3d43
feat: add post-quantum hybrid KEM + SQLCipher persistence
...
Feature 1 — Post-Quantum Hybrid KEM (X25519 + ML-KEM-768):
- Create hybrid_kem.rs with keygen, encrypt, decrypt + 11 unit tests
- Wire format: version(1) | x25519_eph_pk(32) | mlkem_ct(1088) | nonce(12) | ct
- Add uploadHybridKey/fetchHybridKey RPCs to node.capnp schema
- Server: hybrid key storage in FileBackedStore + RPC handlers
- Client: hybrid keypair in StoredState, auto-wrap/unwrap in send/recv/invite/join
- demo-group runs full hybrid PQ envelope round-trip
Feature 2 — SQLCipher Persistence:
- Extract Store trait from FileBackedStore API
- Create SqlStore (rusqlite + bundled-sqlcipher) with encrypted-at-rest SQLite
- Schema: key_packages, deliveries, hybrid_keys tables with indexes
- Server CLI: --store-backend=sql, --db-path, --db-key flags
- 5 unit tests for SqlStore (FIFO, round-trip, upsert, channel isolation)
Also includes: client lib.rs refactor, auth config, TOML config file support,
mdBook documentation, and various cleanups by user.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 08:07:48 +01:00
3bf3ab23e2
Rename project to quicnprotochat
2026-02-21 23:37:40 +01:00
9a0b02a012
feat: M2 + M3 — AuthService, MLS group lifecycle, Delivery Service
...
M2:
- schemas/auth.capnp: AuthenticationService (upload/fetch KeyPackage)
- noiseml-core: IdentityKeypair (Ed25519), generate_key_package, NoiseTransport
with send_envelope/recv_envelope, Noise_XX handshake (initiator + responder)
- noiseml-proto: auth_capnp module, ParsedEnvelope helpers
- noiseml-server: AuthServiceImpl backed by DashMap queue (single-use KPs)
- noiseml-client: register + fetch-key subcommands, ping over Noise_XX
- tests: auth_service integration test (upload → fetch round-trip)
M3:
- schemas/delivery.capnp: DeliveryService (enqueue/fetch opaque payloads)
- noiseml-core/group.rs: GroupMember — MLS group lifecycle
create_group, add_member (→ Commit+Welcome), join_group, send_message,
receive_message; uses openmls 0.5 public API (extract() not into_welcome,
KeyPackageIn::validate() not From<KeyPackageIn>)
- noiseml-server: DeliveryServiceImpl on port 7001 alongside AS on 7000
- noiseml-proto: delivery_capnp module
TODO (see M3_STATUS.md):
- noiseml-client: group subcommands (create-group, invite, join, send, recv)
- noiseml-client/tests/mls_group.rs: full MLS round-trip integration test
2026-02-19 23:39:49 +01:00
9fa3873bd7
feat: M1 — Noise transport, Cap'n Proto framing, Ping/Pong
...
Establishes the foundational transport layer for noiseml:
- Noise_XX_25519_ChaChaPoly_BLAKE2s handshake (initiator + responder)
via `snow`; mutual authentication of static X25519 keys guaranteed
before any application data flows.
- Length-prefixed frame codec (4-byte LE u32, max 65 535 B per Noise
spec) implemented as a Tokio Encoder/Decoder pair.
- Cap'n Proto Envelope schema with MsgType enum (Ping, Pong, and
future MLS message types defined but not yet dispatched).
- Server: TCP listener, one Tokio task per connection, Ping→Pong
handler, fresh X25519 keypair logged at startup.
- Client: `ping` subcommand — handshake, send Ping, receive Pong,
print RTT, exit 0.
- Integration tests: bidirectional Ping/Pong with mutual-auth
verification; server keypair reuse across sequential connections.
- Docker multi-stage build (rust:bookworm → debian:bookworm-slim,
non-root) and docker-compose with TCP healthcheck.
No MLS group state, no AS/DS, no persistence — out of scope for M1.
2026-02-19 21:58:51 +01:00