libsoliton/README.md
Kamal Tufekcic 6992c4b2a0
Add paper, more minor doc updates
Signed-off-by: Kamal Tufekcic <kamal@lo.sh>
2026-04-23 15:52:36 +03:00

9.6 KiB
Raw Blame History

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
paper.tex Protocol paper — design, security analysis, formal verification, implementation
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
tamarin/README.md Symbolic formal verification — 8 Tamarin models, 55 lemmas (Theorems 113)
cryptoverif/README.md Computational formal verification — 5 CryptoVerif models with concrete security bounds

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