phantom_protocol/lib.rs
1//! # Phantom Protocol SDK
2//!
3//! Post-quantum secure L4/L6 universal transport framework.
4//!
5//! Provides:
6//! - Hybrid key exchange (X25519 + Kyber768)
7//! - Hybrid signatures (Ed25519 + Dilithium3)
8//! - Multi-path transport (KCP, TCP, FakeTLS)
9//! - Connection migration and fallback
10//! - Stream multiplexing (reliable + unreliable)
11//!
12//! The core transmits only `Vec<u8>` / `Bytes`.
13//! Serialization (JSON, Protobuf, etc.) is the user's responsibility.
14
15// Security-friendly lints. Now `deny` (was `warn` until the codebase drove the
16// remaining unannotated sites to zero). Every surviving panic-shaped call in
17// production code carries an inline `// PANIC-SAFETY:` comment and a narrow
18// `#[allow(clippy::unwrap_used)]` / `#[allow(clippy::expect_used)]` at the
19// statement scope; the canonical inventory lives in `docs/security/panic-sites.md`.
20// Tests opt in to `expect_used` for readable failure diagnostics. Phase 1.3
21// (Production Readiness) — closed.
22//
23// `clippy::indexing_slicing` is deliberately omitted at this stage — it fires
24// on every constant-bounded array index and would generate too much noise.
25// It is tracked as a separate phase 1.13 item (bounds-check audit).
26#![deny(
27 clippy::unwrap_used,
28 clippy::expect_used,
29 clippy::panic,
30 clippy::unreachable,
31 clippy::todo,
32 clippy::unimplemented,
33 clippy::missing_safety_doc
34)]
35// Tests use `expect()` / `unwrap()` / `panic!()` freely so failures surface as
36// readable diagnostics rather than swallowed `Result`s. The `deny` above only
37// governs the production code path; this `cfg_attr(test, allow(...))` flips
38// the same lints back to permissive for `cargo test` builds.
39#![cfg_attr(
40 test,
41 allow(
42 clippy::unwrap_used,
43 clippy::expect_used,
44 clippy::panic,
45 clippy::unreachable,
46 clippy::todo,
47 clippy::unimplemented,
48 clippy::missing_safety_doc,
49 // Same rationale: tests call `.unwrap()` on `Result` / `Option`
50 // routinely; the disallowed-methods list in `.clippy.toml` is
51 // for production code, not the test harness.
52 clippy::disallowed_methods
53 )
54)]
55// Deny `unsafe` by default at the crate root. The three modules that genuinely
56// require `unsafe` (a single `libc::setsockopt(SO_MAX_PACING_RATE)` call in
57// `transport::udp_transport`, native-only — the dead `sendmmsg` GSO path was
58// removed; wasm-bindgen-generated JS-boundary glue in
59// `transport::legs::websocket`, wasm32-only; `unsafe impl Send/Sync for
60// WasiLeg` over WIT-bindgen `Resource<T>` socket handles in
61// `transport::legs::wasi`, WASI-only) opt back in with a module-level
62// `#![allow(unsafe_code)]` and per-block `// SAFETY:` comments. Audit lens:
63// any future PR touching `unsafe` outside those three modules will fail this
64// lint and must justify itself explicitly.
65#![deny(unsafe_code)]
66// Phase 3.6: when neither `std` nor any std-implying feature is on, drop std
67// from the crate root so a bare-metal `--no-default-features --features
68// embedded,no-std` build links only `core` + `alloc`. The std build (the
69// default) is unchanged.
70#![cfg_attr(not(feature = "std"), no_std)]
71
72// Phase 5.5 / A8 — the FIPS 140-3 primitive swap (X25519 → ECDH-P-256,
73// ring → aws-lc-rs, blake3 → HKDF-SHA256, drop ChaCha20-Poly1305,
74// CTR_DRBG RNG, POST hook) is **shipped**. `--features fips` now
75// builds and serves a FIPS-substrate Phantom Protocol. The scaffold
76// `compile_error!` from commit `d4d121b` is gone; the only
77// remaining build-time gate enforces mutual exclusion with `no-std`,
78// since `aws-lc-rs` requires libc + dlopen / OpenSSL ABI and cannot
79// run on bare-metal.
80#[cfg(all(feature = "fips", feature = "no-std"))]
81compile_error!(
82 "Cargo features `fips` and `no-std` are mutually exclusive — \
83 `aws-lc-rs` (the FIPS-validated substrate) needs libc / dlopen \
84 and does not build for bare-metal targets. Build either with \
85 `--features fips` (FIPS posture, requires std) or with \
86 `--features embedded,no-std` (no_std posture, default crypto)."
87);
88
89// B1 — the `wasi-leg` Cargo feature lives at the WASI target (the
90// `wasi` crate's WIT bindings are only available there). Enabling it
91// on `wasm32-unknown-unknown` (the browser target with WebSocketLeg /
92// WasmRuntime) is a misconfiguration; fail the build loudly with a
93// pointer at the recipe.
94#[cfg(all(feature = "wasi-leg", target_arch = "wasm32", not(target_os = "wasi")))]
95compile_error!(
96 "The `wasi-leg` Cargo feature is only supported on WASI targets \
97 (wasm32-wasi, wasm32-wasip1, wasm32-wasip2). For \
98 wasm32-unknown-unknown (browser) builds use the default feature \
99 set, which exposes the `WebSocketLeg` + `WasmRuntime` surface \
100 instead."
101);
102
103#[cfg(not(feature = "std"))]
104extern crate alloc;
105
106// `errors` and the `transport::session_transport` / `transport::legs::embedded`
107// subtree are no_std-clean and compile under both feature configurations.
108mod errors;
109
110// ── std-only top-level modules ─────────────────────────────────────────
111// The bare-metal subset (Phase 3.6) compiles only `errors` and the embedded
112// transport subset. Everything below is gated behind `std`: it either uses
113// `tokio`, `parking_lot`, `dashmap`, raw sockets, `std::time::Instant`,
114// `std::sync::*`, or a std-bound dep (e.g. `ring`, `ml-kem`, `x25519-dalek`)
115// that is itself only compiled when `std` is on.
116
117#[cfg(feature = "std")]
118pub mod config;
119#[cfg(feature = "std")]
120pub mod observability;
121#[cfg(feature = "std")]
122pub mod security;
123#[cfg(feature = "std")]
124pub mod validation;
125
126// Crypto module (hybrid KEM, hybrid sign) — std-only: pulls `ring`,
127// `x25519-dalek`, `ed25519-dalek`, `ml-kem`, `ml-dsa`.
128#[cfg(feature = "std")]
129pub mod crypto;
130
131// Transport module (Universal Transport Core). The module itself has a
132// no_std-clean subset (`session_transport`, `legs::embedded`). The rest of the
133// sub-modules opt into `std` from within `transport/mod.rs`.
134pub mod transport;
135
136// Async runtime abstraction (Phase 3.1). `TokioRuntime` is the default
137// implementation; the trait surface is in place for follow-up commits
138// that introduce WASM / embedded backends.
139#[cfg(feature = "std")]
140pub mod runtime;
141
142// Public API facade — std-only: every entry point (`PhantomSession`,
143// `PhantomListener`, `TcpSessionTransport`) depends on `tokio`.
144#[cfg(feature = "std")]
145pub mod api;
146
147// Test harness for network simulation
148#[cfg(all(test, feature = "std"))]
149pub mod test_harness;
150
151// Public exports
152#[cfg(feature = "std")]
153pub use config::PhantomConfig;
154pub use errors::CoreError;
155
156// UniFFI scaffolding. Gated on the `bindings` feature so the WASI
157// guest build (which sets `--features wasi-leg` without `bindings`)
158// skips it — UniFFI's exported-symbol metadata is incompatible with
159// `wasm-component-ld`, the wasm32-wasip2 linker. Default builds keep
160// `bindings` active, so the native FFI consumers (Swift / Kotlin /
161// Python / C bindings) see the historical surface unchanged.
162#[cfg(feature = "bindings")]
163uniffi::setup_scaffolding!();