5.8 KiB
5.8 KiB
AGENTS.md
This file documents how AI agents should interact with this Rust codebase for the CCC (Copious Cipher Chain) cryptography system.
Project Overview
A multi-crate Rust workspace providing cryptographic primitives (AEAD, KDF, MAC, Hash, KEM) via pluggable providers (currently wolfSSL/wolfCrypt). The project targets mobile platforms (iOS, Android, macOS) and interoperates with a Dart/Flutter frontend via FFI.
Workspace members:
crates/ccc-crypto-core— Core types, traits, algorithm enums, registrycrates/ccc-crypto-wolfssl— wolfSSL provider implementationtests/conformance— Conformance test binary with NIST/RFC vectors
Build and Test Commands
Basic commands
# Run all tests across workspace
cargo test --workspace
# Run tests for a specific package
cargo test -p ccc-crypto-core
cargo test -p ccc-crypto-wolfssl
# Run conformance tests (binary)
cargo run -p ccc-conformance-tests
# Build for specific target (aliases defined in .cargo/config.toml)
cargo build-ios
cargo build-android-arm64
cargo build-macos-arm64
cargo build-all-apple
Running a single test
# Run all tests matching a string pattern
cargo test --workspace <TESTNAME>
# Example: run only KEM-related tests
cargo test --workspace kem
# Run specific test function
cargo test --workspace test_function_name
# Compile without running
cargo test --workspace --no-run
Linting and formatting
# Format code (uses rustfmt from rust-toolchain.toml)
cargo fmt
# Check for clippy warnings
cargo clippy --workspace -- -D warnings
# Combined check
cargo fmt --check && cargo clippy --workspace -- -D warnings
Code Style Guidelines
Imports and module organization
- Standard library first —
use std::...before workspace crates - Workspace/crate imports second —
use ccc_crypto_core::...oruse crate::... - External dependencies last — third-party crates from
[dependencies] - Group related items — use parentheses to group multi-line imports:
use ccc_crypto_core::{ algorithms::{AeadAlgorithm, HashAlgorithm}, error::CryptoError, types::{KemKeyPair, KemEncapResult}, };
File structure and documentation
- Module headers — Every
.rsfile starts with a//!doc comment explaining its purpose - Section separators — Use ASCII art dividers (
// ─────────────) to separate logical sections - Public APIs — Document all public items with
///comments; use# Parameters,# Returns,# Errorswhere applicable - Algorithm constants — When defining enum discriminants, comment the matching Dart constant value:
/// AES-256-GCM. Dart constant `12`. AesGcm256 = 12,
Naming conventions
- Types: PascalCase (
CryptoError,ProviderCapabilities,WolfSslProvider) - Functions/methods: snake_case (
encrypt_aead,derive_key,from_u32) - Modules: snake_case (
algorithms,capabilities,error) - Constants/enum variants: PascalCase with full names (
AesGcm256,MlKem768) - Private items: Prefix with underscore if needed for clarity (
_unused_var)
Type system and generics
- Prefer
Result<T, CryptoError>overpanic!for recoverable errors - Use
#[repr(u32)]on enums that cross FFI boundaries (match Dartintvalues) - Mark sensitive data with
zeroize::Zeroize/ZeroizeOnDrop:#[derive(Zeroize, ZeroizeOnDrop)] pub struct KemKeyPair { ... } - Use
OnceLock<T>for lazy-initialized singleton-like state
Error handling
- Use
thiserror— Define error enums with#[derive(Error)]:#[derive(Debug, Error)] pub enum CryptoError { #[error("unsupported algorithm: {0}")] UnsupportedAlgorithm(String), #[error("authentication failed")] AuthenticationFailed, // Do not leak details to users } - Authentication failures — Surface only
AuthenticationFailedto end users; never leak raw error details - Internal errors — Use
InternalError(String)for unexpected library errors with diagnostics
Formatting rules
- Max line length: 100 characters (rustfmt default)
- Brace style: Allman/stroustrup hybrid — opening brace on same line for items, next line for blocks
- Single-line matches — Keep simple match arms on one line when concise
- Multi-line chains — Use
.at start of continuation lines:let result = provider .encrypt_aead(algo, key, nonce, plaintext, aad)? .to_hex();
Testing conventions
- Test vectors as static slices — Define test data in
staticarrays with clear naming (AEAD_VECS,KDF_VECTORS) - Cross-provider conformance — Tests should verify identical output across different providers
- NIST/RFC references — Comment the source of each vector (e.g., "RFC 8439 §2.8.2")
Platform-specific code
- Use conditional compilation for platform differences:
#[cfg(target_os = "...")] - Linker flags and build scripts should be in
.cargo/config.tomlorbuild.rs - Document target-specific behavior in module headers
Important Notes
- Dart compatibility: All algorithm discriminant values (
#[repr(u32)]) must match constants incipher_constants.dart. Changing them requires coordinated changes across Rust and Dart codebases. - Wire format consistency: Output byte layouts (e.g.,
ciphertext || tagfor AEAD) must match the Dart implementation exactly for conformance tests to pass. - Security-sensitive data: Always use
zeroizetypes for keys, nonces, and shared secrets; never log raw cryptographic material.
Existing Rules
No .cursor/rules/, .cursorrules, or .github/copilot-instructions.md files exist in this repository. Follow the conventions documented above.