feat(chat): seed-derived identity + secretstream crypto core

Phase 1 crypto foundation (gated by DRAGONX_ENABLE_CHAT; the pure primitives
are always compiled + unit-tested, the feature gate lives at the future
service layer).

- chat_identity: derive the DragonX-native X25519 (crypto_kx) identity from a
  stable per-wallet secret via a domain-separated keyed BLAKE2b KDF
  (crypto_generichash, context "DragonX-HushChat-Identity-v1") into a clean
  32-byte crypto_kx seed. Deterministic; skips SDXL's UTF-8-hex-seed quirk
  (that's the Phase-4 import path). Per §5.6.
- chat_crypto: encryptOutgoing (server_tx) / decryptIncoming (client_rx) via
  crypto_secretstream_xchacha20poly1305, byte-exact per Appendix A.3/A.4 so
  DragonX interoperates with SilentDragonXLite. Single chunk, TAG_FINAL;
  decrypt enforces both the Poly1305 tag and TAG_FINAL (stricter than SDXL).
  Every session key / seed / stream state / plaintext scratch is sodium_memzero'd
  on all paths; no secret is ever logged.
- Tests: encrypt->decrypt round-trip (incl. empty + UTF-8), identity
  determinism, feature-gate + empty-secret handling, and malformed/tampered/
  wrong-key inputs all fail safely.

Adversarially security-reviewed (3 lenses: secret hygiene, crypto correctness,
SDXL wire-interop) — confirmed byte-compatible with the SDXL reference in both
directions. Fixes from review: check the secretstream_push return before
reporting Ok; allow the empty-plaintext ciphertext (== ABYTES) so encrypt/decrypt
round-trip symmetrically; document the caller-owns-and-wipes secret contract.

Interop caveat: round-trip proves self-consistency; a real captured SDXL
message is still needed to prove wire-compat end to end.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-05 19:54:47 -05:00
parent cec330ee47
commit 2502487e44
6 changed files with 437 additions and 0 deletions

View File

@@ -411,6 +411,8 @@ set(APP_SOURCES
src/services/wallet_security_workflow.cpp
src/services/wallet_security_workflow_executor.cpp
src/chat/chat_protocol.cpp
src/chat/chat_crypto.cpp
src/chat/chat_identity.cpp
src/wallet/lite_owned_string.cpp
src/wallet/lite_rollout_policy.cpp
src/wallet/lite_client_bridge.cpp
@@ -557,6 +559,8 @@ set(APP_HEADERS
src/wallet/lite_wallet_server_selection_adapter.h
src/wallet/lite_wallet_lifecycle_service.h
src/chat/chat_protocol.h
src/chat/chat_crypto.h
src/chat/chat_identity.h
src/config/version.h
src/data/wallet_state.h
src/data/transaction_history_cache.h
@@ -1005,6 +1009,8 @@ if(BUILD_TESTING)
src/services/wallet_security_workflow.cpp
src/services/wallet_security_workflow_executor.cpp
src/chat/chat_protocol.cpp
src/chat/chat_crypto.cpp
src/chat/chat_identity.cpp
src/wallet/lite_owned_string.cpp
src/wallet/lite_rollout_policy.cpp
src/wallet/lite_client_bridge.cpp