tpt-rust1
RustRust hardening suite: ZK compliance receipts, capability-based WASM sandbox, typestate hardware transitions, lock-free pools, and deterministic execution — no_std-first, zero external ZK/WASM deps.
Languages
tpt-rust1 — The Rust Hardening Suite
tpt-rust1 is a workspace of 16 Rust crates — 10 foundational libraries plus 6 internal
proc-macro support crates — that harden systems software for cryptographic compliance,
deterministic execution, safe boundaries, and high-performance concurrency —
without sacrificing zero-cost abstractions.
- License: MIT OR Apache-2.0
- MSRV: 1.83.0
- Status:
0.1.0release (seeCHANGELOG.md; remaining work tracked intodo.md) - Design:
spec.txt - Security:
SECURITY_REVIEW.md
Crate Index
| Crate | Tier | Purpose |
|---|---|---|
tpt-zk-audit | 1 | Zero-knowledge event sourcing with compliance receipts |
tpt-cap-wasm | 1 | Capability-based WASM micro-runtime |
tpt-wire | 2 | Declarative stateful protocol parser generator |
tpt-periph-state | 2 | Typestate-safe hardware/ISR transitions |
tpt-pool | 2 | Lock-free, wait-free object pool |
tpt-async-guard | 3 | Compile-time cancellation safety |
tpt-async-replay | 3 | Deterministic async record & replay |
tpt-trace-error | 3 | Unified error + tracing derive |
tpt-ffi-bridge | 4 | Zero-alloc multi-language FFI generator |
tpt-deterministic | 4 | Strict cross-platform deterministic math & RNG |
Internal crates. Six additional workspace members are proc-macro support crates (
tpt-zk-audit-macros,tpt-wire-macros,tpt-periph-state-macros,tpt-async-guard-macros,tpt-trace-error-macros,tpt-ffi-bridge-macros). They are implementation dependencies of the libraries above and are not listed individually because they expose no public runtime API — each foundational crate re-exports what its macro needs.
Quickstart: which crate do I need?
| Symptom / problem | Crate | Start here |
|---|---|---|
| A tamper-evident audit trail with compliance receipts | tpt-zk-audit | EventStore::new, #[derive(ComplianceRule)] |
| Running untrusted plugins/drivers without privilege escape | tpt-cap-wasm | Runtime::new, runtime.load_module |
| Parsing industrial/medical binary frames (Modbus, CAN, …) | tpt-wire | #[wire_parser(schema = "…")] |
| Hardware/ISR states must make invalid transitions unrepresentable | tpt-periph-state | #[derive(PeriphState)] |
| A lock-free pool for embedded / hot paths | tpt-pool | Pool::new, pool.acquire |
| Async code corrupted state on cancellation | tpt-async-guard | CancelGuard, #[cancel_safe] |
| A flaky async bug that only reproduces sometimes | tpt-async-replay | record, replay |
Display / Error / tracing spans without the boilerplate | tpt-trace-error | #[derive(TraceError)] |
| Exposing Rust structs to Go / TypeScript / C | tpt-ffi-bridge | #[ffi_bridge(target = "…")] |
| Bit-identical math / RNG across x86, ARM, RISC-V, wasm32 | tpt-deterministic | DetF32, DetRng |
Five-minute quickstart per crate
tpt-zk-audit — emit a verifiable compliance receipt:
use tpt_zk_audit::{ComplianceRule, EventStore, Receipt};
#[derive(ComplianceRule)]
struct NonNegativeBalance;
let mut store = EventStore::<(), ()>::new();
let receipt: Receipt = store.append(event).unwrap(); // ZK receipt over the transition
tpt-cap-wasm — sandbox an untrusted module behind capabilities:
use tpt_cap_wasm::{Runtime, Capability, AccessMode};
let mut runtime = Runtime::new();
runtime.register_host("read", Capability::new(1, AccessMode::ReadWrite), |a| Ok(a[0] + 1));
let grant = runtime.issue(Capability::new(1, AccessMode::ReadWrite));
let module = runtime.load_module(&wasm, &[grant]).unwrap();
let out = module.call("run", &[41]).unwrap(); // 42, only if the grant verifies
tpt-wire — declare a binary frame once, parse with zero alloc:
use tpt_wire::wire_parser;
#[wire_parser(schema = "tid: u16 @ 0\nunit: u8 @ 2\nfn: u8 @ 3\ndata: bytes @ 4 len = fn")]
pub struct ModbusFrame<'a> { _p: core::marker::PhantomData<&'a ()> }
let f = ModbusFrame::parse(&buf).unwrap();
tpt-periph-state — make illegal transitions a compile error:
use tpt_periph_state::PeriphState;
#[derive(PeriphState)]
#[periph(transitions(Idle -> Active, Active -> Idle))]
enum DmaChannel { Idle, Active }
tpt-pool — reuse objects without a mutex:
use tpt_pool::Pool;
let pool = Pool::new(|| Vec::<u8>::new(), 16);
let mut obj = pool.acquire().unwrap(); // RAII; returned on drop
obj.push(1);
tpt-async-guard — survive cancellation without leaking a resource:
use tpt_async_guard::{CancelGuard, cancel_safe};
#[cancel_safe]
async fn transfer() -> Result<(), ()> {
let mut g = CancelGuard::new(|| rollback());
g.commit(); // commit before any .await
tokio::task::yield_now().await;
Ok(())
}
tpt-async-replay — reproduce a racy interleaving:
use tpt_async_replay::{record, replay};
let trace = record(tasks);
let replayed = replay(&trace, tasks).unwrap(); // identical poll order
tpt-trace-error — get Display/Error/spans for free:
use tpt_trace_error::TraceError;
#[derive(TraceError)]
#[trace_error(span(level = "error", name = "db"))]
enum DbError { #[trace_error(field(code = %self.0))] ConnectionFailed(u8) }
tpt-ffi-bridge — hand a Rust struct to C / Go / TS:
use tpt_ffi_bridge::ffi_bridge;
#[ffi_bridge(target = "c")]
pub struct UserData { pub id: u32, pub name: String }
// emits `user_data_new` / `user_data_id` / `user_data_name` / `user_data_free`
// plus `UserData::FFI_C` (and `FFI_GO` / `FFI_TS`) wrapper source.
tpt-deterministic — portable, reproducible floats:
use tpt_deterministic::{DetF32, DetRng};
let a = DetF32::new(1.0);
let b = DetF32::new(2.0);
let c = a.mul_add(b, DetF32::new(0.5)); // bit-identical everywhere
Why hand-rolled (not arkworks / wasmtime / serde / …)?
Every foundational crate here was built from scratch on purpose, and the trade-off is worth stating plainly:
- No external crypto/ZK or WASM-engine dependency.
tpt-zk-audit(Schnorr over a hand-rolled EC group + Pedersen commitments) andtpt-cap-wasm(from-scratch WASM parser + i32/i64/f32/f64 interpreter) deliberately avoidarkworks/halo2andwasmi/wasmtime. That keeps theno_stdsurface tiny, the audit boundary small, and#![forbid(unsafe_code)]enforceable — a sandbox you cannot read is a sandbox you cannot trust. The cost is a non-standard curve and a subset instruction set; both are documented inSECURITY_REVIEW.md. - No pulling in
serdewhere a fewfrom_le_bytescalls suffice.tpt-wire,tpt-ffi-bridge, andtpt-async-replayserialize with hand-written,no_std-friendly code so the deterministic and embedded crates stay allocation-free by default. - Compile-time guarantees instead of runtime frameworks.
tpt-periph-state,tpt-async-guard, andtpt-trace-errorlean on proc-macros so the safety property is checked byrustc, not by a heavier runtime dependency.
The guiding principle: when the trust boundary or the determinism guarantee is the whole point of the crate, minimizing third-party surface area is a feature, not a limitation.
Philosophy
- Zero-cost by default — no runtime overhead for compile-time-enforced features.
no_stdfirst — core primitives work in bare-metal, microkernel, and WASM.- Determinism over heuristics — reproducible, provable concurrency, math, and state.
- Compliance as code — ZK receipts enforced by the type system.
Building
cargo build --workspace
cargo test --workspace
See todo.md for the full phased rollout. Each crate has its own README.md
under crates/<name>/ with a runnable example and key API.
Start a new project
Scaffold a runnable project pre-wired to a few of these crates with
cargo-generate:
cargo generate --git https://github.com/tpt-solutions/tpt-rust1 --subfolder templates/starter
See templates/starter for what it generates and how
to swap in whichever crates your project actually needs.
Cross-crate examples
| Example | Crates |
|---|---|
examples/src/secure_plugin.rs | cap-wasm + periph-state + zk-audit |
examples/src/industrial_parser.rs | wire + deterministic |
examples/src/physics_engine.rs | pool + deterministic |
Integration tests live in examples/tests/ (one per phase).
Contributing
This project is issues only. Bug reports and feature requests are welcome
via the issue tracker, but pull requests are not accepted — see
CONTRIBUTING.md.