krypteia — Post-Quantum and Classical Cryptography in Rust

A pure-Rust cryptographic workspace covering both post-quantum and classical cryptography, with zero external dependencies (only the Rust standard library, and core + alloc in no_std mode). Designed from the start for embedded targets — secure elements, Cortex-M, RISC-V — and hardened against physical side-channel attacks.

The name Krypteia comes from the Greek κρυπτεία (“the hidden things”), the same root that gave us cryptography — and a nod to ancient Sparta, often cited as one of the earliest practitioners of secret communication.

Goals

The workspace is built around five non-negotiable rules that apply to every crate, classical or post-quantum:

  1. Pure Rust, zero external crates — only the standard library (std / core / alloc).

  2. Side-channel hardened against SPA, DPA, DFA, template attacks, and timing attacks. Constant-time primitives are implemented in architecture-specific assembly for several embedded targets.

  3. Embedded-friendly — small RAM footprint, fits secure elements, STM32 (Cortex-M0/M4/M33), RISC-V parts (ESP32-C3, …).

  4. Validated against the official NIST ACVP test vectors at minimum, plus Wycheproof edge-case vectors and other recognized vector sets.

  5. Usable from C and JavaScript through dedicated FFI and WebAssembly crates. The Rust API is the v0.1 stable contract; the *_ffi and quantica_wasm crates ship as previews in v0.1 (workspace-internal, publish = false on crates.io) and stabilise in v0.2.

Status

v0.1 is a deliberate first cut: the four published crates (krypteia-silentops, krypteia-memory, krypteia-quantica, krypteia-arcana on crates.io — imported in code as the bare silentops / memory / quantica / arcana paths via [lib] name = "<bare>" overrides) are functional, continuously exercised, and ready to depend on for prototyping and evaluation. The pre-1.0 version number reflects that the public Rust API is not yet semver-locked, not that the code is unfinished.

Concern

v0.1 state

Functional correctness

361 library unit tests pass across the 4 published crates, plus the workspace-level NIST ACVP / Wycheproof / CAVP vector corpora.

Cross-architecture validation

7 targets exercised on every push: 3 Linux triplets (aarch64, armv7, riscv64gc) under cross + qemu-user; 4 bare-metal targets (riscv32imc ESP32-C3, riscv32imac ESP32-C6/H2, thumbv6m Cortex-M0, thumbv7em Cortex-M4F) under qemu-system.

Side-channel verification

ctgrind (Valgrind memcheck) and dudect (Welch t-test) run green on the host CI for every silentops::ct::* primitive and every published hot path in quantica / arcana.

Public availability

Codeberg: codeberg.org/cslashm/krypteia. crates.io: krypteia-silentops, krypteia-memory, krypteia-quantica, krypteia-arcana. docs.rs auto-built per crate; long-form pack at cslashm.codeberg.page/krypteia.

License

Apache-2.0 (single licence across the workspace).

Honest caveats (what v0.1 does NOT promise):

  • Pre-1.0 — breaking API changes may land in v0.2 as the Rust surface is reviewed and stabilised. Pin a specific version range for production-class consumers.

  • No third-party evaluation yetkrypteia is structured for a lab-class external evaluation but that pass has not happened. Do not deploy v0.1 in a context that requires an audited cryptographic library.

  • Per-primitive hardening tier varies — every primitive has a documented tier (T1 = active-vulnerability mitigated, T2 = standard hardening, T3 = verification tooling, T4 = deferred / beyond v0.1 scope). Some primitives carry stub implementations (Ed448) or T2-tier hardening pending (quantica T2-A/B/D, arcana T1-AT2-K). See each crate’s Roadmap chapter for the full status matrix.

  • C and JavaScript bindings are previews*_ffi and quantica_wasm ship as workspace-internal previews (publish = false). The C ABI and JS surface stabilise in v0.2.

For reviewers and external auditors: every claim above is backed by machine-checkable evidence under each crate’s doc/sca/ tree and the workspace tools/ scripts (tools/ctgrind.sh, tools/qemu-{user,system,vector}-tests.sh, tools/stack-sizes.sh). The full per-release feature list and known limitations live in CHANGELOG.

Workspace layout

Crate

Path

v0.1 status

Role

krypteia-quantica

quantica/

published

Post-quantum cryptography: ML-KEM (FIPS 203), ML-DSA (FIPS 204), SLH-DSA (FIPS 205). Feature-gated algorithms, first-order DPA masking + shuffled NTT, typed Zeroize-on-Drop key wrappers, no_std support. Import as use quantica::* ([lib] name override).

krypteia-arcana

arcana/

published

Classical cryptography: RSA, ECDSA / ECDH (NIST / SECG / BSI curves), EdDSA / EdDH (Ed25519, X25519, X448; Ed448 stub for v0.2), AES, DES / 3DES, ChaCha20-Poly1305, hashes (SHA-1/2/3, RIPEMD-160), MACs. Custom API + RustCrypto trait bridges. Import as use arcana::*.

krypteia-silentops

silentops/

published

Side-channel toolkit: constant-time primitives (ct_eq, ct_select_*, ct_zeroize, …) with arch-specific asm backends, plus a dudect-style timing leakage verifier exposed as a reusable library. Import as use silentops::*.

krypteia-memory

memory/

published

Shared TLSF allocator for bare-metal targets (no-std heap management). Import as use memory::*.

quantica_ffi

quantica_ffi/

v0.2 preview

C FFI for the post-quantum side. Builds libquantica_ffi.{a,so} and ships a quantica.h header. Workspace-internal in v0.1 (publish = false); C ABI stabilises in v0.2.

arcana_ffi

arcana_ffi/

v0.2 preview

C FFI for the classical side. Builds libarcana_ffi.{a,so} and ships an arcana.h header. Same v0.1/v0.2 staging as quantica_ffi.

quantica_wasm

quantica_wasm/

v0.2 preview

WebAssembly bindings for quantica. Runs ML-KEM, ML-DSA, SLH-DSA in the browser (90 KB .wasm). Built with wasm-pack. Workspace-internal in v0.1, JS API stabilises in v0.2.

quantica_bench

quantica_bench/

v0.2 preview

Cross-algorithm micro-benchmarks + ctgrind harness for the post-quantum side. Workspace-internal.

arcana_bench

arcana_bench/

v0.2 placeholder

Cross-algorithm micro-benchmarks for the classical side — empty skeleton in v0.1, populated in v0.2 mirroring quantica_bench.

arcana_wasm

arcana_wasm/

v0.2 placeholder

WebAssembly bindings for arcana — empty skeleton in v0.1, populated in v0.2 mirroring quantica_wasm.

Each crate has its own README with the per-crate features, examples, test corpora and side-channel notes. The published v0.1 crates carry the long-form chapters; the v0.2-preview / v0.2-placeholder crates carry a short README focused on what they currently do and what they will become.

Published (v0.1):

  • quantica/README.md — post-quantum: features, Quick Start, typed key wrappers, side-channel countermeasures, ACVP + Wycheproof validation, performance, parameter sets, no_std cross-compile.

  • arcana/README.md — classical: the same level of detail for the classical algorithms.

  • silentops/README.md — side-channel toolkit (constant-time primitives, dudect, ctgrind), feature matrix, asm backends per ISA, verification status.

  • memory/README.md — TLSF allocator, os-alloc / self-alloc / global-alloc features, bare-metal C usage snippet.

Bindings (v0.2 preview, workspace-internal):

  • quantica_ffi/README.md — C ABI for the post-quantum side.

  • arcana_ffi/README.md — C ABI for the classical side.

  • quantica_wasm/README.md — WebAssembly bindings for the post-quantum side.

  • quantica_bench/README.md — PQC micro-benches + ctgrind harness.

Placeholders (v0.2 deferred):

  • arcana_bench/README.md — empty skeleton.

  • arcana_wasm/README.md — empty skeleton.

Project structure

krypteia/                       Cargo workspace
├── Cargo.toml                  Workspace manifest + 3 build profiles
├── README.md                   (this file)
├── CHANGELOG.md                Release history (Keep a Changelog 1.1.0 format)
├── CONTRIBUTING.md             Contribution policy (AI-assist authorship trailer required)
├── SECURITY.md                 Maintenance process + vulnerability disclosure policy
├── LICENSE                     Apache-2.0
├── NOTICE                      Third-party attribution notice
├── gendoc.sh                   Sphinx + cargo-doc documentation builder
│
├── quantica/                   Post-quantum crate           → quantica/README.md
├── arcana/                     Classical crypto crate        → arcana/README.md
├── silentops/                  CT primitives + dudect + ctgrind   → silentops/README.md
├── memory/                     Shared TLSF allocator (bare-metal) → memory/README.md
├── quantica_ffi/               C FFI for the post-quantum side (v0.2 preview)
├── arcana_ffi/                 C FFI for the classical side   (v0.2 preview)
├── quantica_wasm/              WebAssembly bindings for quantica  (v0.2 preview)
├── quantica_bench/             PQC micro-benchmarks + ctgrind harness
├── arcana_bench/               Classical micro-benchmarks (v0.2 placeholder)
├── arcana_wasm/                WebAssembly bindings for arcana (v0.2 placeholder)
├── tests-embedded/             Bare-metal qemu-system harness (T3-A)
├── tools/                      Helper scripts + vector-runner host generator
├── htmldoc/                    Generated HTML documentation (gendoc.sh)
│
└── doc/                        Workspace-level documentation sources (Sphinx)
    ├── conf.py                 Unified Sphinx configuration
    ├── TOC.md                  README chapter-list contract (per-crate parity)
    ├── index_all.rst           TOC root for `gendoc.sh all`
    ├── index_quantica.rst      TOC root for `gendoc.sh quantica`
    ├── index_arcana.rst        TOC root for `gendoc.sh arcana`
    ├── infra/                  Workspace-level infra notes (ctgrind, …)
    └── requirements.txt        Sphinx + sphinxcontrib-bibtex + MyST

# Per-crate documentation (side-channel analyses, KAT corpora,
# research papers, FIPS specs) lives under each crate's own
# `doc/` subtree — see `quantica/doc/`, `arcana/doc/`,
# `silentops/doc/`. `gendoc.sh` stages them into `doc/_gen/` at
# build time.

Building

# Build all crates (release, sca-protected on by default in quantica)
cargo build --release

# Run the entire test suite (~4000 vectors + unit tests + doctests)
cargo test --release --workspace

# Cross-compile quantica for a bare-metal target (no_std + sca-protected)
cargo build -p quantica \
    --no-default-features \
    --features ml-kem,ml-dsa,slh-dsa,sca-protected \
    --target thumbv7em-none-eabihf

# Build the WebAssembly package for browsers
cd quantica_wasm && wasm-pack build --target web --release

# Generate the HTML documentation site
./gendoc.sh all        # full workspace doc (default)
./gendoc.sh quantica   # quantica-only doc (standalone distribution)
./gendoc.sh arcana     # arcana-only doc (standalone distribution)

Each invocation writes a self-contained, browsable HTML tree under htmldoc/, built with Sphinx (RTD theme) and including a copy of the Rust API reference produced by cargo doc under htmldoc/api/.

The latest main build is published automatically by the workspace CI (.forgejo/workflows/doc.yml) to https://cslashm.codeberg.page/krypteia. The crate-level Rust API documentation also auto-builds on docs.rs for each crate after a cargo publish.

For per-crate build / test / feature combinations, see the README inside the relevant crate.

Cargo profiles

Three compilation profiles are declared in the workspace Cargo.toml:

Profile

opt-level

CT guarantee

Use case

release

2

Yes (Rust source-level)

Desktop / server production

release-embedded

z + abort

Yes (asm CT backends)

Embedded, minimum size

release-bench

3

No (LLVM may break CT patterns)

Benchmarks only

Warning: opt-level=3 can defeat constant-time guarantees: LLVM may convert bitwise mask patterns into conditional memory accesses. Always use opt-level=2 or lower for security-critical builds, or rely on the assembly CT backends from silentops (asm-aarch64, asm-thumbv7, asm-thumbv6m, asm-riscv32) which bypass the compiler entirely.

Test coverage and references

The per-crate vector breakdown (NIST ACVP, Wycheproof, KAT, CAVP, custom-negative) and the per-crate primary-source bibliography (FIPS / RFC / IACR ePrint / TCHES) live in each crate’s own Test validation and References chapters. Start here:

  • quantica/README.md#test-validation and #references — ACVP + Wycheproof + custom-negative vectors for ML-KEM / ML-DSA / SLH-DSA, plus the FIPS 203/204/205 + dudect

    • masking-paper citation set.

  • arcana/README.md#test-validation and #references — CAVP + Wycheproof + custom vectors for the classical primitives, plus the RFC + NIST SP + Minerva / LadderLeak citation set.

The shared workspace-level dependencies (Apache-2.0 licence, the SCA verification toolchain under silentops, the side-channel methodology reference Reparaz–Balasch–Verbauwhede 2017 “dude, is my code constant time?”) are documented in the respective crate READMEs.

Contributing and security

Two workspace-level governance documents apply to every crate. Each link below resolves to a readable rendered version: the HTML page bundled in the Codeberg Pages doc pack (regenerated by gendoc.sh on every push to main) when read inside the doc pack, or the source markdown rendered by Codeberg / GitHub when read on the repository view.

  • CONTRIBUTING — contribution policy. Open a PR against main; AI-assisted commits must carry a Co-Authored-By: trailer that names the model and the context-window variant (e.g. Claude Opus 4.7 (1M context) <noreply@anthropic.com>). The git history is the audit trail of which tool produced which line — a generic Claude / Claude Code trailer erases that and is not acceptable. Full details (commit message style, branch policy, hooks) are in the document.

  • SECURITY — security maintenance process and vulnerability disclosure policy. Private reports go to cedric.mesnil@pm.me; the default coordinated-disclosure embargo is 90 calendar days. The document also describes the three pillars of the maintenance process (veille / doc / code), the tier-based hardening plan structure, and the per-crate threat-model contract. Read it before reporting an issue, opening a PR that touches a CT path, or proposing a new countermeasure.

License

Apache-2.0 — see LICENSE and NOTICE.