=============================================== CCC Rust Crypto Provider — Architecture Plan =============================================== :Status: Approved :Date: 2026-02-24 :Author: Engineering Overview -------- This document describes the architecture for the **CCC Rust Crypto Provider**, the first of three milestones in delivering hardware-grade cryptography to the LetUsMsg application. The guiding constraint is *clean separation*: each milestone is a distinct, independently testable artifact with no forbidden upward dependencies. ---- Three-Milestone Strategy ------------------------ ============= =================================== ========================== =========================== Milestone Repository What ships Depends on ============= =================================== ========================== =========================== **1 (this)** ``ccc_rust`` Pure Rust crypto library wolfSSL (vendored) **2** ``ccc_dart_plugin`` Flutter plugin + Dart API ``ccc_rust`` (git/semver) **3** ``letusmsg`` (existing app) App integration ``ccc_dart_plugin`` package ============= =================================== ========================== =========================== Milestone 1 is complete and independently verified *before* any bridge or Dart code is written. Milestone 2 owns the ``flutter_rust_bridge`` dependency and all generated Dart bindings. Milestone 3 makes no Rust changes; it consumes only the published Dart package. ---- Milestone 1 — ``ccc_rust`` Scope (this repository) **Goal**: a fully tested, provider-agnostic Rust crypto library. **Hard boundaries** — this repo must never contain: * ``flutter_rust_bridge`` or any Flutter/Dart dependency * Generated Dart files (``frb_generated.rs``, ``*.dart``) * ``flutter_rust_bridge.yaml`` * Any platform plugin scaffold (``ios/``, ``android/``, ``macos/``) Guiding Principles ~~~~~~~~~~~~~~~~~~ 1. Every provider reports its own capabilities at runtime — no compile-time hard-coding of ``available: true/false``. 2. Algorithm IDs in Rust map 1-to-1 to the integer constants in ``cipher_constants.dart`` — zero Dart changes needed when wiring up. 3. Key material is zeroed on drop (``zeroize`` crate) everywhere. 4. A conformance test suite validates NIST/RFC vectors for every algorithm before any provider is marked ``available``. 5. The library has no runtime dependency on Flutter; it is consumable by any FFI host (Flutter plugin, Python tests, CLI tools). Repository Layout (Milestone 1 — this repo) :: ccc_rust/ ├── Cargo.toml ← workspace manifest (3 members, no bridge) ├── rust-toolchain.toml ← pinned stable toolchain ├── .cargo/ │ └── config.toml ← cross-compile target aliases ├── vendors/ │ ├── README.md ← submodule pin rationale + upgrade notes │ └── wolfssl/ ← git submodule (wolfSSL/wolfssl @ v5.7.2-stable) ├── crates/ │ ├── ccc-crypto-core/ ← shared traits, enums, registry │ │ ├── Cargo.toml │ │ └── src/ │ │ ├── lib.rs │ │ ├── algorithms.rs ← algorithm enums (values == cipher_constants.dart) │ │ ├── capabilities.rs ← AlgorithmCapability, ProviderCapabilities │ │ ├── error.rs ← CryptoError enum │ │ ├── provider.rs ← CryptoProvider umbrella trait │ │ ├── registry.rs ← ProviderRegistry (OnceLock>) │ │ └── types.rs ← KemKeyPair, SelfTestReport, BenchmarkReport │ └── ccc-crypto-wolfssl/ ← wolfSSL provider implementation │ ├── Cargo.toml │ └── src/ │ ├── lib.rs │ ├── aead.rs ← AES-256-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305 │ ├── kdf.rs ← HKDF-SHA256/384/512, Argon2id, BLAKE2b-KDF │ ├── mac.rs ← HMAC-SHA256/384/512, BLAKE2b-MAC │ ├── hash.rs ← SHA-256/384/512, SHA3-256/512, BLAKE2b-512 │ ├── kem.rs ← X25519, X448 (ML-KEM deferred Phase 5) │ ├── capabilities.rs ← probe-at-startup + benchmark() │ └── provider.rs ← WolfSslProvider: CryptoProvider impl └── tests/ └── conformance/ ├── Cargo.toml └── src/ └── main.rs ← NIST/RFC vectors for all algorithms Step 1 — Cargo Workspace Scaffold ``Cargo.toml``:: [workspace] resolver = "2" members = [ "crates/ccc-crypto-core", "crates/ccc-crypto-wolfssl", "tests/conformance", ] ``rust-toolchain.toml``:: [toolchain] channel = "stable" ``.cargo/config.toml``:: [alias] build-ios = "build --target aarch64-apple-ios" build-android-arm64 = "build --target aarch64-linux-android" build-android-x64 = "build --target x86_64-linux-android" build-macos = "build --target aarch64-apple-darwin" Step 2 — ``ccc-crypto-core`` Trait Crate Algorithm Enumerations ~~~~~~~~~~~~~~~~~~~~~~ All discriminant values match the integer constants in ``cipher_constants.dart`` exactly, so the Dart cipher-sequencing logic requires zero changes. =================== ========================================================= Enum Variants → value =================== ========================================================= ``AeadAlgorithm`` AesGcm256=12, ChaCha20Poly1305=13, XChaCha20Poly1305=14, Ascon128a=15 ``KdfAlgorithm`` Sha256=1, Sha384=2, Sha512=3, Blake2b512=4 ``MacAlgorithm`` HmacSha256=30, HmacSha512=32, Blake2bMac=33 ``HashAlgorithm`` Sha256=40, Sha384=41, Sha512=42, Blake2b512=43, Sha3_256=44 ``KemAlgorithm`` X25519=50, X448=51, MlKem768=52, MlKem1024=53, ClassicMcEliece=54 =================== ========================================================= Key Structs ~~~~~~~~~~~ ``AlgorithmCapability``:: available: bool deterministic_io: bool efficiency_score: u8 // populated by WolfSslProvider::benchmark() reliability_score: u8 // populated by WolfSslProvider::self_test() ``ProviderCapabilities``:: provider_name: &'static str aead: HashMap kdf: HashMap mac: HashMap hash: HashMap kem: HashMap ``KemKeyPair``:: public_key: Zeroizing> private_key: Zeroizing> ``CryptoError``:: UnsupportedAlgorithm(String) InvalidKey(String) InvalidNonce(String) AuthenticationFailed InternalError(String) Provider Traits ~~~~~~~~~~~~~~~ .. code-block:: rust pub trait AeadProvider { fn encrypt_aead( &self, algo: AeadAlgorithm, key: &[u8], nonce: &[u8], plaintext: &[u8], aad: &[u8], ) -> Result, CryptoError>; fn decrypt_aead( &self, algo: AeadAlgorithm, key: &[u8], nonce: &[u8], ciphertext: &[u8], aad: &[u8], ) -> Result, CryptoError>; } pub trait KdfProvider { fn derive_key( &self, algo: KdfAlgorithm, ikm: &[u8], salt: &[u8], info: &[u8], length: usize, ) -> Result>, CryptoError>; } pub trait MacProvider { fn compute_mac( &self, algo: MacAlgorithm, key: &[u8], data: &[u8], ) -> Result, CryptoError>; fn verify_mac( &self, algo: MacAlgorithm, key: &[u8], data: &[u8], mac: &[u8], ) -> Result; } pub trait HashProvider { fn hash( &self, algo: HashAlgorithm, data: &[u8], ) -> Result, CryptoError>; } pub trait KemProvider { fn generate_keypair( &self, algo: KemAlgorithm, ) -> Result; fn encapsulate( &self, algo: KemAlgorithm, public_key: &[u8], ) -> Result<(Vec, Zeroizing>), CryptoError>; fn decapsulate( &self, algo: KemAlgorithm, private_key: &[u8], ciphertext: &[u8], ) -> Result>, CryptoError>; } pub trait CryptoProvider: AeadProvider + KdfProvider + MacProvider + HashProvider + Send + Sync { fn provider_name(&self) -> &'static str; fn capabilities(&self) -> ProviderCapabilities; fn self_test(&self) -> SelfTestReport; fn benchmark(&self) -> BenchmarkReport; } ``ProviderRegistry``:: OnceLock>>> fn register(name, provider) fn get(name) -> Option> fn list() -> Vec<&'static str> Step 3 — wolfSSL Submodule + ``ccc-crypto-wolfssl`` wolfSSL is vendored as a git submodule pinned to ``v5.7.2-stable``. The crate uses ``cmake`` + ``bindgen`` in ``build.rs`` to build and bind it. A ``stub_ffi`` feature bypasses the C build for fast unit-test cycles. wolfSSL Phase 4 Algorithm Coverage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =================== =========================================== Category Algorithms =================== =========================================== AEAD AES-256-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305 KDF HKDF-SHA256/384/512, Argon2id, BLAKE2b-KDF MAC HMAC-SHA256/384/512, BLAKE2b-MAC Hash SHA-256/384/512, SHA3-256/512, BLAKE2b-512 KEM X25519, X448 KEM (Phase 5) ML-KEM-768, ML-KEM-1024, Classic McEliece =================== =========================================== Capability Probe Strategy ~~~~~~~~~~~~~~~~~~~~~~~~~~ ``WolfSslProvider::capabilities()`` runs a minimal probe call (encrypt 1 byte; decrypt; compare) per algorithm at startup. Sets ``available = probe_succeeded``. If the wolfSSL build omits PQ support, ML-KEM entries report ``available: false`` gracefully. Benchmark Strategy ~~~~~~~~~~~~~~~~~~ ``WolfSslProvider::benchmark()`` encrypts a 1 MB buffer × 100 iterations per AEAD algorithm, measures wall-clock throughput, normalises to a 0–100 ``efficiency_score``. Run once at library init and cached. Step 4 — Conformance Test Suite Location: ``tests/conformance/src/main.rs`` Run with ``cargo run -p ccc-conformance-tests`` and ``cargo test --workspace``. ========================= ================================ Test Source ========================= ================================ AES-256-GCM NIST SP 800-38D vectors ChaCha20-Poly1305 RFC 8439 vectors XChaCha20-Poly1305 Extended nonce vectors HKDF-SHA256/512 RFC 5869 vectors HMAC-SHA256/512 RFC 4231 vectors SHA-256/512, SHA3, BLAKE2b FIPS / reference vectors X25519 DH RFC 7748 vectors X448 DH RFC 7748 vectors ========================= ================================ **Gate**: ``ALL VECTORS PASSED`` must print before Milestone 1 is tagged. Step 5 — Architecture Documentation ``docs/ccc_rust_milestone1.rst`` covers: * Crate dependency graph (ASCII) * "How to add a new provider" — 7-step trait checklist * ``algo: u32`` → cipher constant mapping table * Milestone 2 hand-off contract (API surface Milestone 2 must implement against) Milestone 1 Verification Gate All of the following must pass before the ``v0.1.0`` tag is cut and Milestone 2 work begins: * ``cargo test --workspace`` — all unit tests pass * ``cargo run -p ccc-conformance-tests`` — ``ALL VECTORS PASSED`` * ``cargo build --target aarch64-apple-ios`` — compiles * ``cargo build --target aarch64-linux-android`` — compiles * No ``flutter_rust_bridge``, Dart, or Flutter dependency anywhere in the workspace * ``cargo audit`` — no known CVEs in dependency tree Milestone 2 — ``ccc_dart_plugin`` (separate repository) *(Planned — not started. Work begins after Milestone 1 gate passes.)* A separate Dart/Flutter plugin package repository. It contains: * A small Rust bridge crate that references ``ccc_rust`` via git tag: .. code-block:: toml [dependencies] ccc-crypto-core = { git = "https://github.com/letusmsg/ccc_rust", tag = "v0.1.0" } ccc-crypto-wolfssl = { git = "https://github.com/letusmsg/ccc_rust", tag = "v0.1.0" } flutter_rust_bridge = "2" * ``flutter_rust_bridge_codegen generate`` output (``frb_generated.rs``, Dart bindings) * Flutter plugin scaffold: ``ios/``, ``android/``, ``macos/`` * Dart API surface: ``CccCrypto``, ``CccSelfTest``, ``CccProviderCatalog`` * Flutter integration tests (roundtrip encrypt/decrypt, self-test harness) Milestone 3 — LetUsMsg App Integration (existing repository) *(Planned — not started. Work begins after Milestone 2 gate passes.)* The existing ``letusmsg`` Flutter app adds ``ccc_dart_plugin`` as a pubspec dependency. Changes are confined to: * ``crypto_wolfssl.dart`` — replace ``UnimplementedError`` stubs with plugin calls * ``ccc_provider_spec.dart`` — populate ``CccProviderCatalog`` at runtime * ``main.dart`` — call ``CccCrypto.cccInit()`` at startup * App debug screen — expose ``CccSelfTest.runAll()`` results No Rust changes and no bridge changes are made in Milestone 3. Phase 8 — Stretch Goal Providers (Future) *(Out of scope for Phase 4. Tracked here for future scheduling.)* ================== ===================================================== Library Rust crate / approach ================== ===================================================== libsodium ``sodiumoxide`` or ``safe_libsodium`` OpenSSL ``openssl`` crate BoringSSL ``boring`` crate RustCrypto Pure-Rust trait impls; no native dep liboqs Open Quantum Safe — ML-KEM, BIKE, HQC, Falcon, Dilithium, SPHINCS+ Signal libsignal ``libsignal`` (Apache-2 subset) Botan ``botan`` crate mbedTLS ``mbedtls`` crate Nettle ``nettle-sys`` crate ================== =====================================================