# krypteia-silentops — side-channel countermeasure toolkit [![Crates.io](https://img.shields.io/crates/v/krypteia-silentops.svg)](https://crates.io/crates/krypteia-silentops) [![Docs.rs](https://docs.rs/krypteia-silentops/badge.svg)](https://docs.rs/krypteia-silentops) [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) Side-channel countermeasure primitives shared by the [krypteia](https://codeberg.org/cslashm/krypteia) cryptographic workspace (post-quantum `quantica` and classical `arcana`). `silentops` packages three families of primitives that any cryptographic crate concerned with timing, cache, or fault side-channels needs to write once and trust everywhere: - **`ct`** — constant-time core ops (`ct_eq`, `ct_select`, `ct_zeroize`, conditional buffer copy) with architecture-specific inline-assembly backends so the compiler cannot rewrite the bit-twiddle into a secret-dependent CMOV (the [Kocher cache-timing pattern](https://www.usenix.org/conference/usenixsecurity21/presentation/coppens)). Five backends ship today: `x86_64`, `aarch64`, `thumbv7` (M3/M4/M33), `thumbv6m` (M0/M0+), `riscv32` (RV32I + ESP32-class chips), plus a portable pure-Rust fallback. `no_std`. - **`ct_grind`** — Valgrind memcheck client-request helpers (`poison` / `unpoison`) used to verify constant-time code under `valgrind --error-exitcode=1` on `x86_64-linux` / `aarch64-linux`. Compiles to zero-cost no-ops on every other target so call sites stay unconditional. `no_std`. - **`verify`** — dudect-style timing leakage detector built on Welch's t-test. Drives randomised secret/public input pairs through a candidate function and surfaces statistically significant timing distinguishers. `std`-only (test tooling). ## Cargo features | Feature | Default | Effect | |----------------------|:-------:|-------------------------------------------------------------------------------------| | `std` | no | Pulls in `std` to enable the `verify` module (host-side timing tests). | | `ct-grind` | no | Emit Valgrind memcheck client-request instrumentation in `ct_grind::{poison, unpoison}`. Inert on non-Linux x86_64/aarch64. | | `asm-x86_64` | no | Route `ct` primitives through the inline-asm x86_64 backend. | | `asm-aarch64` | no | Same, AArch64 (`csel`, `csinv`). | | `asm-thumbv7` | no | Same, ARMv7-M Thumb2 (IT blocks). Cortex-M3 / M4 / M33. | | `asm-thumbv6m` | no | Same, ARMv6-M Thumb (AND/OR/XOR, no IT). Cortex-M0 / M0+. | | `asm-riscv32` | no | Same, RV32I (AND/OR/XOR, no cmov). ESP32-C3 / C6 / H2. | Each asm feature is gated on `target_arch` + `target_feature` inside the crate, so enabling several simultaneously is harmless — only the matching backend's module is compiled. ## Verification status The constant-time claims are exercised on every PR through three independent paths on the workspace CI: - **Host x86_64**: ctgrind (Valgrind memcheck) on every `ct::*` primitive — `tools/ctgrind.sh` returns non-zero on any secret-dependent branch. - **Cross-arch host**: same ctgrind run under `cross` on aarch64 (qemu-user), exercising the `asm-aarch64` backend. - **On-target bare-metal**: `tests-embedded` workspace member smoke-tests the active asm backend under `qemu-system` on `riscv32imc`, `riscv32imac`, `thumbv6m` and `thumbv7em` — each run boots silentops + ct_eq end-to-end on the real ISA. See [`doc/sca/`](https://codeberg.org/cslashm/krypteia/src/branch/main/quantica/doc/sca/) in the workspace repository for the full threat model and per-algorithm SCA evidence. ## License Apache-2.0