1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
[]
= "phantom-protocol"
= "0.1.1"
= "2021"
= "1.75"
= "Post-quantum-secure L4/L6 universal transport framework — hybrid X25519+ML-KEM-768 / Ed25519+ML-DSA-65, multi-path, UniFFI bindings"
= "Apache-2.0"
= "https://github.com/snaart/phantom_protocol"
= "https://docs.rs/phantom-protocol"
= "README.md"
= ["post-quantum", "transport", "cryptography", "networking", "ml-kem"]
= ["network-programming", "cryptography", "no-std"]
[]
= ["compression-zstd", "std", "bindings"]
# UniFFI bindings surface. Pulled in by `default` so the historical
# native-FFI consumers (Swift / Kotlin / Python / C bindings under
# `tests/bindings/`) compile unchanged. Split out from `std` because
# UniFFI's exported-symbol metadata is incompatible with
# `wasm-component-ld` (the wasm32-wasip2 linker); the WASI guest in
# `core/tests/fixtures/wasi-guest/` therefore opts out of `default`
# and explicitly enables `["std", "wasi-leg"]` only.
= ["std", "dep:uniffi"]
# `uniffi-cli` (SUPPLY-01): the codegen-only surface. Adds uniffi's `cli`
# feature (which drags in `clap` / `cargo_metadata` / `tempfile`) and is the
# `required-features` for the `uniffi-bindgen` binary. Kept OUT of `bindings`
# so a normal lib / server / mobile build links the FFI scaffolding WITHOUT the
# build-time CLI dependency tree. The `tests/bindings/generate_*.sh` scripts
# enable it when they regenerate the language bindings.
= ["bindings", "uniffi/cli"]
# `std` (Phase 3.6): the standard "everything on" build. Pulls every std-bound
# optional dep into the graph and unlocks all top-level modules (`api`, `runtime`,
# `transport/legs/{tcp,kcp,faketls,websocket}`, `networks`, `config`, `validation`,
# `crypto/*`, `security/*`, std-bound parts of `transport/*`). Default-on so the
# historical surface keeps compiling unchanged.
#
# Bare-metal targets pass `--no-default-features --features embedded,no-std` to
# drop this entirely.
= [
"dep:tokio",
"dep:tokio-util",
"dep:futures",
"dep:async-trait",
"dep:parking_lot",
"dep:dashmap",
"dep:arc-swap",
"dep:env_logger",
"dep:tracing",
"dep:time",
"dep:argon2",
"dep:crossbeam-queue",
"dep:crossbeam-utils",
"dep:lz4_flex",
"dep:base64",
"dep:once_cell",
"dep:anyhow",
"dep:thiserror",
"dep:rand",
"dep:ring",
"dep:x25519-dalek",
"dep:ed25519-dalek",
"dep:ml-kem",
"dep:ml-dsa",
"dep:log",
"dep:hmac",
"dep:borsh",
"dep:hex",
"dep:bitflags",
"dep:zeroize",
"dep:subtle",
"dep:blake3",
"dep:hkdf",
"dep:sha2",
"dep:getrandom",
# Native (non-wasm32) optional deps; activating these on a wasm32 target
# is a no-op because the deps themselves are gated by the
# `[target.'cfg(not(target_arch = "wasm32"))']` table.
"dep:kcp-tokio",
"dep:socket2",
"bytes/std",
"serde/std",
]
# zstd compression. Disabled when building for WASM / embedded targets where
# the C bindings in `zstd-sys` are unavailable. lz4_flex (pure-Rust) remains
# the always-on fallback. Implies `std`.
= ["dep:zstd", "std"]
# `EmbeddedLeg` transport over `embedded-io-async` byte streams (Phase 3.4).
# Pure-Rust + no_std-friendly; safe to enable on the host for `cargo test`.
= ["dep:embedded-io-async", "dep:async-lock"]
# `no-std` foundation (Phase 3.6). The audit-gate marker. When ON, the
# in-subset modules (`errors`, `transport::session_transport`, `transport::legs::
# embedded`) compile with `#![no_std] + extern crate alloc`. Whole-crate
# bare-metal compilation additionally requires `--no-default-features` to drop
# the `std` feature and all the std-bound optional deps it gates.
= []
# FIPS 140-3 posture. Pulls in `aws-lc-rs` (FIPS-validated AWS-LC
# bindings) as the substrate for the FIPS-approved primitive set:
#
# - classical KEM half: X25519 → ECDH-P-256
# - AEAD: `ring` AES-GCM → `aws-lc-rs`
# - ChaCha20-Poly1305 dropped (not FIPS-approved)
# - KDF: blake3 → HKDF-SHA256 everywhere blake3 is used as a KDF
# - RNG: `aws-lc-rs::rand` (SP 800-90A CTR_DRBG) instead of getrandom
# - `crypto::self_tests::run_post()` wired into the bind/connect bootstrap
#
# Implies `std`; mutually exclusive with `no-std` (enforced by a
# `compile_error!` in `core/src/lib.rs`). Native-only — `aws-lc-rs`
# does not support wasm32 targets. See `docs/compliance/fips-readiness.md`.
= ["std", "dep:aws-lc-rs"]
# WasiLeg transport + WasiRuntime for `wasm32-wasi*` targets (Section B
# of the pre-1.0 deferred-followups plan). Pulls in the `wasi` crate
# (>= 0.14, Preview 2 stable) only on `cfg(target_os = "wasi")`, so
# enabling this feature on non-WASI hosts is a no-op at the dep level.
# Mutually exclusive with `wasm32-unknown-unknown` (browser) — the
# `wasi` crate's WIT bindings do not target the browser; a
# `compile_error!` in `core/src/lib.rs` rejects the combination
# explicitly.
= ["std", "dep:wasi"]
# OpenTelemetry pipeline (Phase 8). Off by default; the `core` library exposes
# OTel `Counter` / `Histogram` / `UpDownCounter` instruments to the embedder
# when this is on. The library never installs a `MeterProvider` /
# `TracerProvider` — that's the embedder's job (see `server/src/telemetry.rs`).
# Implies `std`; mutually compatible with `compression-zstd`. Pulls
# `opentelemetry` + `opentelemetry_sdk` + `tracing-opentelemetry` so
# `tracing` spans bridge into OTel traces.
= [
"std",
"dep:opentelemetry",
"dep:opentelemetry_sdk",
"dep:tracing-opentelemetry",
]
[]
# --- Async & Runtime (std-only) ---
# `tokio` is split per target (Phase 3.5 conditional compilation matrix):
# - Cross-target features: sync primitives, time, io-util, macros, single-thread
# runtime. These work on both native and wasm32.
# - Native-only features (`net`, `rt-multi-thread`, `signal`, `process`, `fs`,
# `io-std`) are added in the `[target.'cfg(not(target_arch = "wasm32"))']`
# block at the bottom of this file.
= { = "1.36", = false, = true, = [
"sync", "macros", "rt", "time", "io-util",
] }
= { = "0.7", = true, = ["codec"] }
= { = "0.3", = true }
= { = "0.1", = true }
# --- Serialization & Utils ---
# `bytes` and `serde` have first-class no_std modes (`default-features = false`
# + the `alloc` feature). Kept as required deps so the no-std subset can use
# them; the `std` feature wires the `std` cargo feature back in for richer
# `std::io::Read`-style integration.
= { = "1", = false, = ["serde"] }
= { = "1", = false, = ["derive", "alloc"] }
# Wire-stability pin. `borsh` encodes the handshake messages (the packet header
# + `PhantomPacket` use a hand-rolled big-endian codec, `PacketHeader::to_wire`,
# so they have no serialization dependency). The exact serialized bytes are
# frozen by `core/tests/wire_vectors.rs` (and the transcript hash by
# `transport::handshake::tests::transcript_hash_wire_vector`). A patch/minor bump
# to `borsh` can silently shift the handshake bytes and break interop with no
# `WIRE_VERSION` change, so it is pinned to an exact version — bump it only as a
# deliberate wire change, paired with a vector regeneration.
= { = "=1.6.1", = false, = true, = ["derive"] }
= { = "0.4", = false, = true, = ["alloc"] }
= { = "0.22", = false, = true, = ["alloc"] }
= { = "1", = true }
= { = "2", = true }
= { = "0.4", = true }
= { = "0.11", = true }
= { = "0.8", = true }
= { = "1.18", = true }
= { = "2.5", = false, = true } # Constant-time equality for secrets (cookies, tokens)
= { = "0.1", = true } # Structured spans / events for observability (Phase 4.5)
# --- Crypto (std-only) ---
= { = "2", = true, = ["static_secrets", "zeroize"] }
= { = "2", = true, = ["zeroize", "rand_core"] }
= { = "0.17", = true } # HW-accelerated AES-GCM (ARM64 AES intrinsics / x86 AES-NI) + ChaCha20-Poly1305
# Phase 5.1: switched from `pqcrypto-kyber` / `pqcrypto-dilithium` (which
# wrap NIST PQC round-3 C reference impls and require libc) to the
# RustCrypto pure-Rust FIPS-203 / FIPS-204 implementations. These compile
# on every target (server, mobile, embedded, wasm32) without C bindings.
# Wire-incompatible with the prior build — bytes laid out per FIPS, not
# per NIST round-3.
# `deterministic` exposes `generate_deterministic` / `encapsulate_deterministic`
# (additive API; no change to the production random path). Used by the NIST KAT
# test (`core/tests/nist_kat.rs`) to byte-match published FIPS-203 vectors.
= { = "0.2", = true, = ["deterministic"] }
= { = "0.1.1", = true } # stable release; a release candidate must not ship in a 1.0
# `signature` traits are re-exported via `ml_dsa::{Signer, Verifier}` from
# the version ml-dsa pins (3.x); we do not need a direct dependency here.
= { = "0.13", = true }
= { = "0.11", = true }
= { = "1.5", = true }
= { = "0.2", = true }
= { = "2.13", = true }
= { = "0.12", = true } # Fast mutex for buffer pool
= { = "1", = true } # Lock-free atomic swap for the CryptoState rekey path (Phase 1.5)
= { = "0.13.1", = true } # Fastest pure-Rust LZ4 (safe, no C bindings); >=0.13.1 floor avoids yanked 0.11.5 (RUSTSEC-2026-0041)
# zstd pinned to a release version. Optional (gated by `compression-zstd`
# feature) so WASM / embedded builds can opt out of the C bindings in
# zstd-sys, falling back to lz4_flex.
= { = "0.13", = true }
# --- Networking ---
# TCP/UDP-using crates are non-wasm-only (Phase 3.5). Moved to the
# `[target.'cfg(not(target_arch = "wasm32"))']` block at the bottom.
= { = "0.3", = true }
# --- FFI ---
= { = "0.31", = true, = ["tokio"] }
= { = "1.8.2", = true, = ["derive"] }
= { = "0.5.3", = true }
= { = "0.3.12", = true }
= { = "0.8", = true } # CachePadded for observability hot-path atomics
# --- OpenTelemetry (optional, behind the `telemetry-otel` feature, Phase 8) ---
# Library-side: only the API + SDK crates. The OTLP exporter and any tonic
# transport live in `server/` (or any embedder), keeping the core library
# transport-runtime-agnostic and matching the existing "core defines, server
# wires" boundary used for HTTP metrics today.
= { = "0.32", = true, = false, = ["metrics", "trace"] }
= { = "0.32", = true, = false, = ["metrics", "trace", "rt-tokio"] }
= { = "0.33", = true, = false, = ["tracing-log"] }
= { = "0.13", = true }
= { = "6.1.0", = true }
# --- Embedded transport (optional, behind the `embedded` feature) ---
# Pure-Rust, no_std + alloc. `embedded-io-async` 0.6 is the byte-stream trait
# the `EmbeddedLeg` is generic over — 0.6 keeps MSRV 1.75, 0.7 bumped it to
# 1.81. `async-lock` is the async mutex guarding the split read/write handles;
# chosen over `embassy-sync` because the latter drags in `heapless` (MSRV 1.87)
# and would need a link-time `critical-section` impl. `async-lock` >= 3.4
# bumped its MSRV to 1.85, so it is capped at `< 3.4` to hold the crate MSRV of
# 1.75 — relax this cap once the crate MSRV moves.
= { = "0.6", = true }
= { = ">=3, <3.5", = true, = false }
[]
= { = "0.31", = ["build"] }
# ─── Native (non-wasm32) dependencies (Phase 3.5) ────────────────────────
# TCP/UDP transport legs and raw sockets live here. wasm32 builds
# skip these entirely and use the `WebSocketLeg` instead (see below).
[]
= { = "1.36", = true, = [
"net", "rt-multi-thread", "signal", "process", "fs", "io-std",
] }
= { = "0.6", = true }
# socket2 gives portable access to SO_REUSEPORT (Phase 2.9 — Linux
# multi-accept). Already in the transitive tree via tokio so this is
# free from a build-size standpoint.
= { = "0.6", = true }
# `aws-lc-rs` is the FIPS-validated substrate behind the `fips` Cargo
# feature (AES-256-GCM, ECDH-P-256, HKDF-SHA256, CTR_DRBG). Pinned to
# 1.x, declared only in this native-only target block because the
# AWS-LC C library + bindgen pipeline does not target wasm32. macOS
# hosts may need `brew install pkg-config openssl@3` for the first
# build (see CONTRIBUTING.md).
#
# Feature selection: `default-features = false` + `features = ["fips"]`.
# In aws-lc-rs 1.17, the `fips` feature is mutually exclusive with the
# default `aws-lc-sys` backend — it activates `dep:aws-lc-fips-sys`
# (AWS-LC-FIPS 3.0.x) as the sole backend. Listing both `aws-lc-sys`
# and `fips` would attempt to enable both backends and bloat the link.
= { = "1.17", = true, = false, = ["fips"] }
# ─── Linux-only dependencies ──────────────────────────────────────────────
# `libc` backs the Linux UDP fast paths in `transport/udp_transport` — the
# `SO_MAX_PACING_RATE` pacing offload (`setsockopt`) and the `sendmmsg` batch
# send — all gated on `cfg(target_os = "linux")`. Declared in a Linux-only
# target block so the direct dependency edge matches the only place the code
# names `libc::`; macOS / Windows / wasm / WASI builds never pull it here.
[]
= "0.2"
# ─── Browser-WASM-only dependencies (Phase 3.3) ───────────────────────────
# Pulled in only for `wasm32-unknown-unknown` builds (the browser target).
# Non-WASM hosts and WASI targets (wasm32-wasi*) never see these crates in
# their dependency graph.
[]
= "0.2"
= "0.4"
= "0.3"
= { = "0.3", = [
"BinaryType",
"Blob",
"CloseEvent",
"console",
"ErrorEvent",
"Event",
"MessageEvent",
"WebSocket",
] }
# Phase 3.8 partial: enable getrandom's "js" feature for wasm32-unknown-
# unknown so it falls back to `crypto.getRandomValues` rather than
# emitting a compile_error!. Non-wasm targets and WASI targets ignore
# this — it's a no-op there.
= { = "0.2", = ["js"] }
# Force-enable the `wasm_js` feature on getrandom 0.4 for wasm32-unknown-
# unknown. getrandom 0.4 is pulled in transitively by `ml-dsa →
# crypto-common 0.2` and `uniffi → tempfile`. The wasm path requires the
# `wasm_js` Cargo feature (not a --cfg rustflag) to compile in the
# js-sys/wasm-bindgen backend. WASI builds get the default getrandom path
# (which uses WASI's `random_get`).
= { = "getrandom", = "0.4", = ["wasm_js"] }
# ─── WASI-only dependencies (Section B — wasi-leg) ────────────────────────
# WASI Preview 2 bindings for the WasiLeg transport + WasiRuntime. Lives
# under `cfg(target_os = "wasi")` so it is pulled in only when the
# `wasi-leg` Cargo feature is active AND the build target is a WASI
# triple (wasm32-wasi, wasm32-wasip1, wasm32-wasip2). Non-WASI builds
# (including wasm32-unknown-unknown) never see this crate in their graph.
[]
= { = "0.14", = true }
[]
= "1.5"
= { = "2", = ["rand_core"] }
= "0.8"
= { = "0.31", = ["bindgen-tests"] }
= { = "0.5", = ["html_reports", "async_tokio"] }
= "0.4"
= "1" # property-based testing harness
= "1" # parse the committed NIST ACVP KAT vectors (core/tests/nist_kat.rs)
# UniFFI codegen entry point. Gated on `uniffi-cli` (SUPPLY-01) so a default
# `cargo build` skips it entirely — the binary needs uniffi's `cli` feature for
# `uniffi_bindgen_main`, and that feature (clap / cargo_metadata / tempfile)
# must not leak into the runtime library / server / mobile artifacts.
[[]]
= "uniffi-bindgen"
= "src/bin/uniffi-bindgen.rs"
= ["uniffi-cli"]
[[]]
= "transport_bench"
= false
[[]]
= "buffer_pool_bench"
= false
[[]]
= "syn_flood_bench"
= false
[[]]
= "protocol_comparison"
= false
[[]]
= "observability_bench"
= false
# `embedded_demo` depends on `embedded-io-async`, which is only pulled in by the
# `embedded` feature — gate it so the default `cargo test` / `cargo build
# --examples` skip it instead of failing to resolve the crate.
[[]]
= "embedded_demo"
= ["embedded"]
# NOTE: `[profile.release]` lives in the workspace root `Cargo.toml`. Declaring
# release profiles in non-root members is silently ignored by cargo (see warning
# from `cargo check`). Keep this comment as a reminder for future maintainers.
[]
= "phantom_protocol"
= ["lib", "cdylib"]