Post-quantum cryptography for Rust. You describe what you're protecting; LatticeArc picks the algorithm, security level, and compliance mode. Hybrid (PQ + classical) by default. One crate.
| What you'd normally wire up yourself | What can go wrong |
|---|---|
| Pick from 4 NIST standards, 11 parameter sets | Wrong security level, wrong algorithm type |
| Combine ML-KEM + X25519 + HKDF + AES-GCM | Broken key combiner, missing domain separation |
| Zeroize secrets, constant-time comparisons | Leaks via Debug, timing side-channels |
| FIPS 140-3, CNSA 2.0 mode restrictions | Non-compliant algorithm silently selected |
use latticearc::{encrypt, decrypt, CryptoConfig, UseCase, EncryptKey, DecryptKey};
use latticearc::generate_hybrid_keypair_with_level;
use latticearc::primitives::kem::ml_kem::MlKemSecurityLevel;
// HealthcareRecords resolves to ML-KEM-1024 (NIST Level 5), so the keypair
// must be generated at the matching level — generate_hybrid_keypair() defaults
// to ML-KEM-768 and would be rejected by validate_key_matches_scheme.
let (pk, sk) = generate_hybrid_keypair_with_level(MlKemSecurityLevel::MlKem1024)?;
let encrypted = encrypt(b"patient records",
EncryptKey::Hybrid(&pk),
CryptoConfig::new().use_case(UseCase::HealthcareRecords))?;
let decrypted = decrypt(&encrypted, DecryptKey::Hybrid(&sk), CryptoConfig::new())?;
// ML-KEM-1024 + X25519 + HKDF-SHA256 + AES-256-GCM — selected automatically[dependencies]
latticearc = "0.9"Hybrid encryption — PQ + classical, both must fail for an attacker to succeed:
use latticearc::{encrypt, decrypt, CryptoConfig, EncryptKey, DecryptKey};
let (pk, sk) = latticearc::generate_hybrid_keypair()?;
let encrypted = encrypt(b"secret data", EncryptKey::Hybrid(&pk), CryptoConfig::new())?;
let decrypted = decrypt(&encrypted, DecryptKey::Hybrid(&sk), CryptoConfig::new())?;Digital signatures — ML-DSA-65 + Ed25519 hybrid:
use latticearc::{
generate_signing_keypair, sign_with_key, verify_with_anchor, CryptoConfig,
};
let config = CryptoConfig::new();
let kp = generate_signing_keypair(config.clone())?;
let signed = sign_with_key(
b"document",
kp.expose_secret_key(),
kp.public_key(),
config.clone(),
)?;
// Production verify pins the trust anchor. Bare `verify(&signed, config)`
// also exists but trusts the public key the envelope itself carries —
// appropriate only when the embedded key IS the trust root. See
// `docs/SECURITY_GUIDE.md` for the embedded-key threat model.
assert!(verify_with_anchor(&signed, kp.public_key(), kp.scheme(), CryptoConfig::new())?);latticearc-cli exposes the same library for ops and CI workflows — no Rust required:
cargo install --git https://github.com/LatticeArc/latticearc latticearc-cli
# or, from a local checkout: cargo install --path latticearc-cli# Sign a legal document (ML-DSA-87 + Ed25519 hybrid, selected by use case)
latticearc-cli keygen --use-case legal-documents --output ./keys
latticearc-cli sign --input contract.pdf \
--key keys/hybrid-ml-dsa-87-ed25519.sec.json \
--public-key keys/hybrid-ml-dsa-87-ed25519.pub.json
latticearc-cli verify --input contract.pdf \
--signature contract.pdf.sig.json \
--key keys/hybrid-ml-dsa-87-ed25519.pub.json
# Encrypt healthcare records (AES-256-GCM)
latticearc-cli keygen --algorithm aes256 --output ./keys
latticearc-cli encrypt --use-case healthcare-records \
--input patient.json --output patient.enc.json \
--key keys/aes256.key.json22 use cases · 12 algorithms · hybrid + PQ-only modes. Full reference:
latticearc-cli/README.md.
Use LatticeArc when you want:
- Hybrid PQ + classical encrypt/decrypt without wiring ML-KEM + X25519 + HKDF + AES-GCM yourself
- Use-case-driven algorithm selection (22 workloads, 3 compliance modes)
- A CLI that ops teams can use without writing Rust
- Opt-in FIPS routing with no code changes
Reach for something else when you need:
- A single low-level primitive — use
aws-lc-rs,fips204,fips205, orfn-dsadirectly - End-to-end CMVP-certified module — no CMVP backend exists for PQ signatures yet
- Cross-language bindings —
liboqscovers C, Python, Go, Java no_std/ embedded —wolfCryptleads for embedded PQ- A TLS stack — use
rustls, OpenSSL 3.5, or wolfSSL
Detailed comparison: Ecosystem Map
Plaintext, key type, and config flow through a policy engine that selects the algorithm pipeline at runtime:
flowchart LR
subgraph "You provide"
DATA["Plaintext"]
KEY["Key type"]
CFG["CryptoConfig"]
end
subgraph "LatticeArc decides"
ENGINE["Policy\nEngine"]
end
subgraph "Hybrid mode"
H_KEM["ML-KEM\nencapsulate"]
H_ECDH["X25519\nkey exchange"]
H_HKDF["HKDF\ncombine"]
H_AES["AES-256-GCM\nencrypt"]
H_KEM --> H_HKDF
H_ECDH --> H_HKDF
H_HKDF --> H_AES
end
subgraph "PQ-only mode"
P_KEM["ML-KEM\nencapsulate"]
P_HKDF["HKDF\nderive"]
P_AES["AES-256-GCM\nencrypt"]
P_KEM --> P_HKDF
P_HKDF --> P_AES
end
DATA --> ENGINE
KEY --> ENGINE
CFG --> ENGINE
ENGINE -->|"CryptoMode::Hybrid"| H_KEM
ENGINE -->|"CryptoMode::PqOnly"| P_KEM
style ENGINE fill:#8b5cf6,stroke:#6d28d9,color:#fff
style H_AES fill:#10b981,stroke:#059669,color:#fff
style P_AES fill:#3b82f6,stroke:#1d4ed8,color:#fff
Algorithm conformance ≠ module validation. --features fips switches aws-lc-rs to its CMVP-validated build for the algorithms it covers. PQ signatures always use non-validated crates. LatticeArc itself is not a CMVP-certified module.
| Category | Algorithms | Backend |
|---|---|---|
| PQ Key Encapsulation | ML-KEM-512/768/1024 (FIPS 203) | aws-lc-rs — FIPS 140-3 validated with --features fips |
| PQ Signatures | ML-DSA-44/65/87 (FIPS 204) | fips204 — NIST-conformant, not CMVP-validated |
| PQ Hash Signatures | SLH-DSA (FIPS 205) | fips205 — NIST-conformant, not CMVP-validated |
| PQ Lattice Signatures | FN-DSA-512/1024 (draft FIPS 206) | fn-dsa — NIST-conformant, not CMVP-validated |
| Classical Signatures | Ed25519 | ed25519-dalek — audited |
| Classical Key Exchange | X25519 | aws-lc-rs — FIPS 140-3 validated with --features fips |
| Symmetric Encryption | AES-256-GCM | aws-lc-rs — FIPS 140-3 validated with --features fips |
| Symmetric Encryption | ChaCha20-Poly1305 | chacha20poly1305 — non-FIPS |
| Hash | SHA-2 (256/384/512) | RustCrypto sha2 — widely reviewed, NOT CMVP-validated. --features fips does NOT swap SHA-2 to aws-lc-rs. |
| Hash | SHA-3, BLAKE2 | sha3 / blake2 crates — non-FIPS |
| KDF | HKDF-SHA256 | aws-lc-rs — FIPS 140-3 validated with --features fips |
Details: Algorithm Selection Guide · NIST Compliance
The unified API sits over a small set of composite operations, which sit over the NIST primitives, which sit over their backends:
block-beta
columns 3
block:API["Unified API"]:3
columns 3
encrypt["encrypt()"] decrypt["decrypt()"] sign["sign_with_key()"]
end
block:CONFIG["Configuration"]:3
columns 3
cc["CryptoConfig"] mode["CryptoMode"] level["SecurityLevel"]
end
block:HYBRID["Hybrid & PQ-Only Encryption"]:2
columns 2
henc["hybrid\nML-KEM + X25519\n+ HKDF + AES-GCM"]
pqenc["pq_only\nML-KEM\n+ HKDF + AES-GCM"]
end
block:SIG["Signatures"]:1
columns 1
hsig["ML-DSA + Ed25519\nSLH-DSA · FN-DSA"]
end
block:PRIM["Primitives"]:3
columns 5
kem["ML-KEM\nFIPS 203"] dsa["ML-DSA\nFIPS 204"] slh["SLH-DSA\nFIPS 205"] fn["FN-DSA\ndraft FIPS 206"] sym["AES-GCM\nX25519 · Ed25519"]
end
block:BACK["Backends"]:3
columns 3
awslc["aws-lc-rs\n(FIPS opt-in)"] fips204["fips204 · fips205"] fndsa["fn-dsa · ed25519-dalek"]
end
style API fill:#3b82f6,stroke:#1d4ed8,color:#fff
style CONFIG fill:#e2e8f0,stroke:#64748b
style HYBRID fill:#10b981,stroke:#059669,color:#fff
style SIG fill:#f59e0b,stroke:#d97706,color:#fff
style PRIM fill:#e2e8f0,stroke:#94a3b8
style BACK fill:#374151,stroke:#1f2937,color:#fff
Multi-layered — each tier catches what the tier below cannot.
| Tool | What it proves | Scope |
|---|---|---|
| SAW (via aws-lc-rs) | Machine-checked correctness of C primitives | AES-GCM, HMAC, HKDF, SHA-2, ECDSA, ECDH — see aws-lc-verification for the up-to-date proof inventory |
| Kani | Bounded model checking of Rust code | 29 proofs; 18 PR-blocking, full suite scheduled nightly |
| Tool | What it catches |
|---|---|
| Proptest | Roundtrip, non-malleability, single-bit rejection invariants (40+ properties × 256+ cases) |
| Cross-impl differential | ML-KEM (fips203 vs aws-lc-rs, 600 round-trips/run), ML-DSA (fips204 vs pqcrypto-mldsa), SLH-DSA (fips205 vs pqcrypto-sphincsplus) — 21 tests |
| Wycheproof | 555 attacker-chosen vectors through our AES-GCM, ChaCha20-Poly1305, HMAC, HKDF wrappers |
| Tool | Methodology |
|---|---|
| Criterion | Qualitative wall-clock divergence between input classes |
| DudeCT | Welch's t-test; per-bench gates — |max t| < 10 for HMAC verify (PRIMARY CT gate), |max t| < 50 for hybrid ct_eq (regression sentry — ctgrind is authoritative on this pure-Rust path). See .github/workflows/dudect.yml for rationale. |
| ctgrind (Valgrind memcheck) | Marks secret bytes as uninit; fails on any branch or index depending on them |
- Allocation budgets — per-API-call ceiling on every crypto op, regression-gated via
stats_alloc - 31 libfuzzer targets — AEAD, KEM, signatures, KDF, serialization, DoS; weekly matrix; OSS-Fuzz scaffold in
fuzz/oss-fuzz/ cargo-mutants --in-diff— 80% score floor, PR-blocking on changed crypto files- Sanitizers — ASan / TSan / LSan run weekly (Rust-side coverage); C-side uninitialized-read coverage for
aws-lclives in the upstream library's own CI, matching aws-lc-rs / ring / rustls / RustCrypto practice #![forbid(unsafe_code)]enforced at workspace level
Full proof inventory: Formal Verification
Designed under the assumption that any single algorithm may be broken — hybrid mode ensures an attacker must defeat both components. Key material is zeroized on drop, tag comparisons run in constant time, secret types have manual Debug impls that redact contents.
- Not a CMVP-certified cryptographic module. No CMVP backend exists for PQ signatures. Use
--features fipsfor the subset that routes through aws-lc-rs. - Not independently audited. Security researchers welcome to review.
- Pre-1.0. API may change between minor versions; see CHANGELOG.md. CLI environment variables documented in
latticearc-cli/README.md.
- Report security issues to Security@LatticeArc.com — see SECURITY.md
- Upstream contributions: aws-lc-rs#1029 (ML-KEM
DecapsulationKeyserialization, shipped in v1.16.0) · aws-lc-rs#1034 (ML-DSA seed-based deterministic keygen, shipped in v1.16.0)
Requires Rust 1.93+ and a C/C++ compiler. FIPS builds also need CMake and Go.
cargo build # default
brew install cmake go # macOS, FIPS prerequisites
# sudo apt install cmake golang-go build-essential # Ubuntu
cargo build --features fips # FIPS-validated backend| Error | Fix |
|---|---|
CMake not found |
Install CMake (FIPS only) |
Go not found |
Install Go 1.18+ (FIPS only) |
cc not found (Linux) |
sudo apt install build-essential |
| Long initial build | First build compiles AWS-LC from source (~2-3 min) |
| Feature | Default | Effect |
|---|---|---|
fips |
off | Routes AES-GCM, ML-KEM, X25519, HKDF through CMVP-validated aws-lc-rs. Required for ComplianceMode::Fips140_3 / Cnsa2_0. SHA-2 stays on RustCrypto sha2. Transitively enables fips-self-test. |
fips-self-test |
off | Power-up KAT self-tests for FIPS-boundary algorithms (ML-KEM, AES-GCM, ML-DSA, SLH-DSA). |
tracing-init |
off | Exposes init_tracing[_with_file] helpers. Libraries must NOT enable this — subscriber init belongs in the binary. Enabled by latticearc-cli. |
secret-mlock |
off | mlock(2) / VirtualLock for heap-backed SecretVec buffers — prevents swap and core-dump exposure. |
kat-test-vectors |
off | Test-only. Exposes AeadCipher::new_allow_weak_key to reproduce NIST AES-GCM Test Cases 1 & 2 (all-zero key). |
perf |
off | Benchmarking/metrics module (latticearc::perf) — bench scaffolding with no production consumer; enable only for perf tooling. |
LatticeArc is pre-1.0; each minor version may ship breaking changes. See CHANGELOG.md for the authoritative per-release breaking-change list with rationale.
| Document | Description |
|---|---|
| Algorithm Selection Guide | Use-case tables, security-level mapping, compliance modes |
| Unified API Guide | Zero-trust sessions, all 22 use cases, PQ-only mode |
| Key Format Specification | LatticeArc Portable Key (LPK) schema, JSON + CBOR |
| Ecosystem Map | Comparison with OpenSSL, aws-lc-rs, liboqs, RustCrypto, age, Sequoia |
| NIST Compliance | Per-algorithm FIPS conformance status |
| Formal Verification | Complete Kani proof inventory |
| Design & Architecture | Crate structure, module boundaries, design decisions |
| Design Patterns | Config, crypto safety, and testing patterns |
| CLI Reference | Full latticearc-cli command reference |
Apache 2.0 — see LICENSE. Contributions welcome; see CONTRIBUTING.md.