Changelog

All notable changes to this project are documented in this file.

The format is based on Keep a Changelog 1.1.0, and the workspace follows Semantic Versioning 2.0.0. The pre-1.0 line ships breaking changes in minor version bumps (0.1.x0.2.0); patch versions remain backwards-compatible.

Unreleased

Items planned for v0.2 — see each crate’s Roadmap chapter for the full tier matrix.

  • Stabilise the C ABI (quantica_ffi, arcana_ffi) and the WebAssembly bindings (quantica_wasm); flip these crates from publish = false to crates.io-published.

  • Fill in the arcana_bench and arcana_wasm placeholders.

  • arcana::ecc::eddsa::Ed448 full implementation (RFC 8032 §5.2).

  • Continued T1 / T2 hardening work per the Roadmap chapters of quantica/README.md and arcana/README.md.

  • Veille-trigger formalisation — record the veille window in CHANGELOG.md at every release bump (<window dates>; items reviewed: …; items folded into release: ) so the discipline becomes auditable.

0.1.0 - 2026-06-11

First public release of the krypteia cryptographic workspace. Four crates ship on crates.io under the krypteia-* namespace: krypteia-silentops, krypteia-memory, krypteia-quantica, and krypteia-arcana. Apache-2.0 across the workspace.

The krypteia-* namespace prefix was adopted because the bare names memory and arcana were already taken on crates.io by third parties at first publish attempt. Every published crate sets [lib] name = "<short>" so consumers use silentops::*, use memory::*, use quantica::*, use arcana::* exactly as they would have with the bare names; the only place the namespaced name appears is the Cargo.toml [dependencies] line and on crates.io / docs.rs URLs.

Added — quantica (post-quantum cryptography)

  • ML-KEM (FIPS 203, Key Encapsulation Mechanism) — pure-Rust implementation, all parameter sets (MlKem512, MlKem768, MlKem1024), typed Zeroize-on-Drop key wrappers.

  • ML-DSA (FIPS 204, Digital Signature Algorithm) — pure-Rust implementation, all parameter sets (MlDsa44, MlDsa65, MlDsa87), with per-iteration mask refresh in the rejection loop (T1-A), Hermelink 2025/276 audit annex on ml_dsa::masked (T1-B).

  • SLH-DSA (FIPS 205, Stateless Hash-Based Signatures) — pure-Rust implementation, SHAKE variants (Sha2-128f/s, Shake-128f/s, Shake-192f/s, Shake-256f/s), with FORS recompute-and-compare redundancy (T1-C, anti-grafting Castelnovi 2018), full-tree streaming FORS sign (T1-D, anti-template Kannwischer 2018), digest → FORS-indices integrity check (T1-E, anti-fault), and a constant-time fors_pk_from_sig_ct (T1-F).

  • First-order DPA masking + shuffled NTT on both ML-KEM and ML-DSA secret paths (sca-protected Cargo feature, on by default).

  • Iterative BDS FORS treehash (256 KiB → 448 B per call) and streaming signature output (one allocation, *_into variants throughout) to fit the M0 baseline RAM budget.

  • Seven RAM-reduction features for ML-DSA bringing the M0 Sign stack from 179 KB → ~17 KB peak.

  • no_std build target support; cross-compile recipes in quantica/README.md for thumbv6m-none-eabi, thumbv7em-none-eabihf, thumbv8m.main-none-eabihf, riscv32imc-unknown-none-elf.

Added — arcana (classical cryptography)

  • RSA — PKCS#1 v1.5, PSS (with Sha256 / Sha384 / Sha512 / SHA-3 family digests), OAEP.

  • ECDSA / ECDH — NIST P-256 / P-384 / P-521, SECG secp256k1, Brainpool families (P-256 / P-384 / P-512). CT hardening on scalar_mul_point (Montgomery ladder, branchless point_add_ct, black_box shielding on field_* masks).

  • EdDSA — Ed25519 (RFC 8032 §5.1).

  • ECDH — X25519 and X448.

  • AES — 128 / 192 / 256 with ECB, CBC, CTR, GCM, CCM (RFC 3610), XTS (IEEE 1619) modes.

  • ChaCha20 and ChaCha20-Poly1305 (RFC 8439), XChaCha20-Poly1305 (24-byte nonce extension).

  • DES / 3DES (legacy use only — flagged in the per-crate Known limitations).

  • Hashes: SHA-1, SHA-2 family (224 / 256 / 384 / 512 / 512-truncated), SHA-3 family (224 / 256 / 384 / 512 + SHAKE128/256, cSHAKE128/256), BLAKE2b / BLAKE2s, RIPEMD-160.

  • MACs: HMAC, CMAC.

  • Optional RustCrypto trait bridges (digest, cipher, signature) behind the rust-crypto-traits Cargo feature.

  • no_std build target support.

Added — silentops (side-channel countermeasure toolkit)

  • Constant-time primitives — ct::ct_eq, ct::ct_select_*, ct::ct_zeroize, ct::ct_copy with five architecture- specific inline-assembly backends gated on target_arch + target_feature + Cargo feature:

    • asm-x86_64 — x86_64 inline asm;

    • asm-aarch64 — AArch64 with csel / csinv;

    • asm-thumbv7 — ARMv7-M Thumb2 IT blocks (Cortex-M3 / M4 / M33);

    • asm-thumbv6m — ARMv6-M no-IT branchless (Cortex-M0 / M0+);

    • asm-riscv32 — RV32I branchless (ESP32-C3 / C6 / H2).

  • ct_grind — Valgrind memcheck client-request helpers (poison / unpoison) with zero-cost no-op fallback on non-Linux x86_64 / aarch64 targets.

  • verify — dudect-style timing-leakage detector (Welch t-test, std-only) refactored as a reusable library.

Added — memory (TLSF allocator)

  • Two allocator backends gated by Cargo feature:

    • os-alloc (default) — forwards to the platform malloc / free;

    • self-alloc — TLSF allocator over a caller-provided RAM block, single-init, no std.

  • global-alloc feature for the FFI consumers (arcana_ffi, future quantica_ffi) to register as #[global_allocator].

Added — Cross-architecture validation infrastructure (T3-A)

Workspace-internal, exercised on every push:

  • tools/qemu-user-tests.sh — workspace lib tests on three Linux triplets via cross + qemu-user: aarch64-unknown- linux-gnu, armv7-unknown-linux-gnueabihf, riscv64gc-unknown-linux-gnu. Pinned to cross 0.2.5 + ghcr.io/cross-rs/*:0.2.5 Docker images.

  • tools/qemu-system-tests.shtests-embedded smoke test on four bare-metal targets: riscv32imc-unknown-none-elf (ESP32-C3), riscv32imac-unknown-none-elf (ESP32-C6 / H2), thumbv6m-none-eabi (Cortex-M0, qemu microbit), thumbv7em-none-eabihf (Cortex-M4F, qemu mps2-an386).

  • tools/qemu-vector-tests.sh + tools/vector-runner/ — host↔guest semihosting vector-streaming protocol that runs validation corpora through the bare-metal vector_runner bin without compiling vectors into the binary. Generator and consumer share the wire format via tests_embedded::protocol.

  • Codeberg Forgejo Actions workflow (.forgejo/workflows/qemu-cross-tests.yml) running all three layers in parallel on every push to main and every pull request.

Added — Documentation pack and CI

  • Sphinx documentation pack (gendoc.sh all) — per-crate README rendered with the per-crate doc/sca/ side-channel annex inlined as a nested TOC under each crate’s chapter VIII subsection 5; cross-crate sidebar entries for silentops and memory; separate Governance sidebar group for CONTRIBUTING and SECURITY.

  • Continuous publish to cslashm.codeberg.page/krypteia via .forgejo/workflows/doc.yml on every push to main.

  • Workspace governance documents linked from the root README:

    • CONTRIBUTING.md — contribution policy, including the AI-assist Co-Authored-By: trailer requirement;

    • SECURITY.md — security maintenance process and full responsible-disclosure policy (90-day coordinated disclosure window default, MITRE CNA process for CVE assignment, safe-harbour clause for good-faith research).

Conventions and workspace shape adopted in v0.1

  • Rust edition 2024 (MSRV 1.85) across the workspace.

  • [workspace.package] factorisation of release metadata (license, repository, homepage, authors, version, edition, rust-version) — inherited via <field>.workspace = true.

  • [workspace.dependencies] factorisation of inter-crate path-deps with version = "0.1.0" on each so cargo publish accepts them.

  • publish = false on quantica_ffi, arcana_ffi, quantica_wasm, quantica_bench, arcana_bench, arcana_wasm, tests-embedded, tools/vector-runner — these are workspace-internal previews / placeholders; the C ABI and JS surface stabilise in v0.2.

  • Strict branch policy enforced by tools/hooks/pre-commit: main, master, pqc-dev are read-only, dev work happens on dev/* / doc/* / infra/* / release/* branches.

Known limitations carried into v0.1

These are documented honestly so a v0.1 consumer or external reviewer can size them up before depending on the workspace:

  • arcana::ecc::eddsa::Ed448 — stub. Full implementation deferred to v0.2 against RFC 8032 §5.2.

  • Five #[ignore]-d KAT tests under quantica/tests/ (three ML-KEM RSP + two SLH-DSA SHAKE-256f) — root cause investigation deferred to v0.2 evaluation prep.

  • thumbv8m.main-none-eabihf bare-metal target — wired in tests-embedded/memory/mps2-an505.x, tools/qemu-system-tests.sh, and .cargo/config.toml, but currently disabled in the active matrix due to an upstream rustc 1.96 + cortex-m-rt 0.7.5 linker issue that emits an empty ELF. silentops’s asm-thumbv7 backend coverage is preserved via the thumbv7em path (M4F and M33 share the asm backend).

  • 45 unsafe-op-in-unsafe-fn warnings on arcana_ffi and ~69 not_unsafe_ptr_arg_deref clippy errors on quantica_ffi — edition 2024 ripple on the FFI surface. These are workspace-internal in v0.1 (publish = false) and addressed when the C ABI is reworked for v0.2.

  • Codeberg shared-runner CI is not green for v0.1.0 — two distinct image-compat issues block the workflows on the free shared-runner pool: (a) the cross-based qemu-user matrix in .forgejo/workflows/qemu-cross-tests.yml requires Docker-in-Docker, which the pool does not expose; (b) the doc.yml Sphinx build calls rsync, which is not present in the runner image’s apt set. The bare-metal qemu-system and qemu-vector matrices use no Docker and need no additional packages, but were not exercised on the pool for v0.1.0 because the YAMLs are bundled in a single workflow with the broken qemu-user matrix. Local validation (./tools/qemu-{user,system,vector}-tests.sh, ./tools/ctgrind.sh, ./gendoc.sh all) covers the same scope the workflows would have. The v0.1.0 long-form Sphinx doc pack was deployed to Codeberg Pages manually from a local ./gendoc.sh all run, not via the doc.yml workflow. Workflow migration to non-Docker tooling (qemu-user-static + binfmt-misc for the cross-arch matrix, apt-get rsync for the doc build) lands in v0.2.

Initial public release commit

The b31fdbd “Initial public release of krypteia” commit (2026-03-13) seeded the public history as an orphan commit, deliberately disconnected from earlier internal exploration branches that referenced third-party non-public material under NDA. All work in this CHANGELOG is reachable from that orphan root.