libsoliton/README.md
Kamal Tufekcic 4840868b24
Some checks failed
CI / lint (push) Successful in 1m34s
CI / test-python (push) Successful in 1m46s
CI / test-zig (push) Successful in 1m37s
CI / test-wasm (push) Successful in 1m52s
CI / test (push) Successful in 14m16s
CI / miri (push) Successful in 14m9s
CI / build (push) Successful in 1m7s
CI / fuzz-regression (push) Successful in 9m20s
CI / publish-python (push) Successful in 1m47s
CI / publish (push) Successful in 1m53s
CI / publish-wasm (push) Failing after 1m53s
initial commit
Signed-off-by: Kamal Tufekcic <kamal@lo.sh>
2026-04-03 21:58:14 +03:00

9.2 KiB

libsoliton

Pure-Rust post-quantum cryptographic library. Provides composite identity keys (X-Wing + ML-DSA-65), hybrid signatures, KEM-based authentication, asynchronous key exchange, double-ratchet message encryption, and encrypted storage — all without a C toolchain.

Use cases: any application requiring two-party encrypted communication or authenticated key agreement — messaging, voice/video calls, peer-to-peer sessions, file transfer, encrypted storage, zero-knowledge authentication, password-protected key vaults. The library provides the complete primitive stack; the application layer decides the transport and session management.

Documentation

Document Description
Abstract.md Security analysis specification — adversary model, theorems, and verification targets for formal modeling
Specification.md Full cryptographic specification (v1)
CHEATSHEET.md API quick reference with types, sizes, and signatures

Crate Layout

Package Path Purpose
libsoliton (crates.io) soliton/ Core library — all cryptographic logic
libsoliton_capi (crates.io) soliton_capi/ C ABI FFI layer (cbindgen-generated header)
soliton-py (PyPI) soliton_py/ Python binding (PyO3/maturin, wraps core Rust API)
soliton-wasm (npm) soliton_wasm/ WASM binding (wasm-bindgen, wraps core Rust API)
soliton-cli (cargo) soliton_cli/ Native CLI (cargo install soliton-cli)
soliton_zig soliton_zig/ Zig wrapper (consumes CAPI via @cImport)

Testing

By location (non-overlapping — these add up to the total):

Location Count Description
Core unit tests 488 soliton/src/**/ #[cfg(test)] — unit tests + proptests
Core integration tests 61 soliton/tests/ — KEX → ratchet, storage round-trips, argon2, zeroization verification, Appendix F vectors
CAPI tests 287 soliton_capi/tests/ — null pointers, invalid lengths, round-trips, error codes
Python tests 49 soliton_py/tests/ — full KEX → ratchet round-trip, serialize, reset, call keys, storage, streaming (_at), auth, identity, primitives
Zig tests 35 soliton_zig/src/soliton.zig — full KEX → ratchet round-trip, serialize, reset, call keys, storage, streaming (_at), auth, AEAD, X-Wing, argon2id
WASM tests 36 soliton_wasm/tests/ — full KEX → ratchet lifecycle, serialize/deserialize, call keys, storage, streaming (_at), auth, identity, primitives, argon2id (Node + Chromium)
Fuzz targets 36 */fuzz/fuzz_targets/ — 29 core + 7 CAPI (cargo-fuzz / libFuzzer)

Cross-cutting (subsets of the above):

Property Count Subset of Description
MIRI-eligible 455 core + CAPI PQ-free subset safe for instruction-level interpretation (--profile miri)
KAT vectors 27 core unit + integration 17 in src/**/ #[cfg(test)] — SHA3-256, HMAC-SHA3-256, HKDF-SHA3-256, Ed25519, X25519, X-Wing, AEAD, KDF, KEX, streaming, call; 10 in tests/compute_vectors.rs — Specification.md Appendix F vectors F.25-F.37 (HKDF, AEAD, HybridSign, streaming, Argon2, HMAC long-key, first-message AAD, SPK sig, session-init sig, LO-Auth)
# Full test suite
cargo test -p libsoliton -p libsoliton_capi

# MIRI (requires nightly)
MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri nextest run \
  -p libsoliton -p libsoliton_capi --profile miri -j$(nproc)

# Fuzzing — corpus regression (replays all seeds, no mutations, fast)
./ci_regression.sh

# Fuzzing — overnight campaign (all active targets in parallel)
./fuzz_overnight.sh 24 2    # 24 hours, 2 workers per target
./fuzz_stats.sh             # Post-run summary

Fuzzing

36 fuzz targets (29 core + 7 CAPI) with two corpora (core: soliton/fuzz/corpus/, CAPI: soliton_capi/fuzz/corpus/) totaling 165,540 entries (883 MB). All corpora are checked in via Git LFS; ci_regression.sh replays every seed with zero mutations as a CI regression gate.

Excluded targets — 5 of 36 are excluded from overnight campaigns after saturation analysis. All reachable edges were discovered; additional CPU time yields no new coverage. These targets retain their corpora and run in ci_regression.sh.

Target Corpus Edges Reason
fuzz_identity_from_bytes 84 107 3 length checks only
fuzz_auth_verify ~15 88 Single ct_eq call
fuzz_xwing_roundtrip 7 763 No adversarial input (keygen→encap→decap)
fuzz_verification_phrase 29 88 SHA3→wordlist index, trivial surface
fuzz_auth_respond 4 1573 Single KEM decap→HMAC, no branching on input

Latest campaign — 31 targets (24 core + 7 CAPI), 1 libFuzzer worker per target, Hetzner CCX53 (32 vCPUs, AMD EPYC, 128 GB RAM), 24 hours.

Metric Value
Total targets 36 (29 core + 7 CAPI)
Active in campaign 31
Total executions 574.6 billion
Corpus 165,540 entries (883 MB)
Crashes / Timeouts / OOM 0 / 0 / 0

The state-machine fuzzer (fuzz_ratchet_state_machine) performs full cryptographic sessions with up to 200 protocol actions per execution (KEM, AEAD, HKDF, HMAC per message) — 12,714 coverage features, the highest of any target.

./ci_regression.sh          # Replay all seeds — fast, runs in CI
./fuzz_overnight.sh 24 1    # 31 active targets, 24 hours, 1 worker each
./fuzz_stats.sh             # Per-target breakdown (edges, features, throughput, RSS)

Benchmarks

Measured with cargo +nightly bench across three platforms. ML-DSA-65, SHA3-256, and Keccak do not have SIMD implementations in the current RustCrypto crates — expect these numbers to improve as upstream adds platform-specific optimizations. All operations are pure ARX or field arithmetic; no hardware acceleration is required.

Platform support: Tested on x86-64, aarch64, riscv64gc, and wasm32. 32-bit native platforms are untested and unsupported — the library uses u64 extensively and the PQ primitives have non-trivial stack requirements.

Platform CPU Arch Clock
Desktop AMD Ryzen 7 7840HS x86-64 (Zen 4) ~5.1 GHz boost
RPi 5 Cortex-A76 aarch64 2.4 GHz
VisionFive 2 SiFive U74 riscv64gc 1.5 GHz

Per-message hot paths (what users feel on every send/receive):

Operation Desktop RPi 5 VisionFive 2 Notes
Ratchet encrypt (same epoch) 4.3 µs 7.2 µs 47.6 µs HMAC-SHA3-256 + XChaCha20-Poly1305
Ratchet decrypt (same epoch) 6.2 µs 10.1 µs 67.5 µs Includes from_bytes deserialization
KDF root (isolated) 5.7 µs 9.2 µs 59.5 µs HKDF-SHA3-256, 64-byte output
Ratchet serialize 1.6 µs 6.1 µs 38.1 µs to_bytes
Ratchet deserialize 0.7 µs 2.7 µs 17.8 µs from_bytes_with_min_epoch

Direction-change paths (one KEM round-trip per direction switch):

Operation Desktop RPi 5 VisionFive 2 Notes
Ratchet encrypt (direction change) 182 µs 651 µs 2.46 ms X-Wing keygen + encapsulate + KDF
Ratchet decrypt (direction change) 127 µs 473 µs 1.76 ms X-Wing decapsulate + KDF

Session establishment (one-time per conversation):

Operation Desktop RPi 5 VisionFive 2 Notes
Identity keygen 417 µs 1.05 ms 4.90 ms X-Wing + Ed25519 + ML-DSA-65
Hybrid sign 988 µs 2.85 ms 10.6 ms Ed25519 + ML-DSA-65 (no SIMD)
Hybrid verify 254 µs 794 µs 3.31 ms Ed25519 + ML-DSA-65 (no SIMD)
X-Wing encapsulate 104 µs 417 µs 1.44 ms X25519 + ML-KEM-768
X-Wing decapsulate 112 µs 451 µs 1.61 ms X25519 + ML-KEM-768
Initiate session (Alice) 1.41 ms 3.95 ms 17.1 ms Ephemeral keygen + 3 encaps + HKDF + sign
Receive session (Bob) 585 µs 1.88 ms 7.70 ms Verify + 3 decaps + HKDF

Streaming AEAD (file/media encryption):

Operation Desktop RPi 5 VisionFive 2 Notes
Encrypt 1 MiB 537 µs (1.95 GB/s) 3.96 ms (265 MB/s) 31.0 ms (33.8 MB/s) XChaCha20-Poly1305, single chunk
Decrypt 1 MiB 749 µs (1.40 GB/s) 4.74 ms (221 MB/s) 34.9 ms (30.0 MB/s) Includes init overhead
Encrypt 4 MiB sequential 2.58 ms (1.55 GB/s) 15.8 ms (253 MB/s) 124 ms (32.3 MB/s) 4 chunks, sequential API
Encrypt 4 MiB parallel 867 µs (4.61 GB/s) 5.35 ms (748 MB/s) 33.0 ms (121 MB/s) 4 chunks via encrypt_chunk_at, rayon (4 cores)
Encrypt 8 MiB parallel 1.29 ms (6.21 GB/s) 10.7 ms (748 MB/s) 67.8 ms (118 MB/s) 8 chunks, 2 rounds on 4 cores

Password KDF (key vault protection):

Operation Desktop RPi 5 VisionFive 2 Notes
Argon2id OWASP minimum 10.9 ms 42.0 ms 256 ms 19 MiB, 2 passes, 1 lane
Argon2id recommended 65.0 ms 227 ms 1.35 s 64 MiB, 3 passes, 4 lanes

License

AGPL-3.0-only