1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Cédric Mesnil <cslashm@pm.me>
//! Constant-time cryptographic primitives with architecture-specific
//! assembly backends.
//!
//! This module provides the fundamental constant-time operations
//! needed by both classical and post-quantum cryptographic
//! implementations:
//!
//! | Primitive | Operation |
//! |-----------|-----------|
//! | [`ct_select_u8`] | Conditional byte selection without branching |
//! | [`ct_select_i16`] | Conditional i16 selection (NTT coefficients) |
//! | [`ct_select_i32`] | Conditional i32 selection (ML-DSA coefficients) |
//! | [`ct_select_bytes`] | Conditional slice select into a fresh destination |
//! | [`ct_eq`] | Constant-time byte-slice equality comparison |
//! | [`ct_eq_u32`] | Constant-time `u32` equality comparison |
//! | [`ct_zeroize`] | Secure memory zeroization (resists DSE) |
//! | [`ct_zeroize_i16`] | Secure zeroization of i16 slices (coefficients) |
//! | [`ct_copy`] | Conditional buffer copy |
//!
//! # Architecture dispatch
//!
//! At compile time, the crate selects the best implementation:
//!
//! | Target (core) | Method | Instructions used |
//! |---------------|--------|-------------------|
//! | `aarch64` + `asm-aarch64` | Inline asm | `csel`, `csinv` |
//! | `thumbv7*` (M3/M4/M7) + `asm-thumbv7` | Inline asm | IT blocks + conditional exec |
//! | `thumbv8m.main` (M33) + `asm-thumbv7` | Inline asm | IT blocks + conditional exec |
//! | `thumbv6m` (M0/M0+) + `asm-thumbv6m` | Inline asm | AND/OR/XOR (no IT, no csel) |
//! | `thumbv8m.base` (M23) + `asm-thumbv6m` | Inline asm | AND/OR/XOR (no IT, no csel) |
//! | `riscv32` + `asm-riscv32` | Inline asm | AND/OR/XOR (no cmov) |
//! | *(default)* | Pure Rust | Bitwise ops (relies on compiler) |
//!
//! The IT-block (Thumb-2) vs 2-operand (Thumb-1) split on ARM M-profile
//! cores is not driven by `target_feature` — rustc emits no `thumb2`
//! feature for bare-metal M-profile targets, and `target_has_atomic` is
//! set on the M23 (`thumbv8m.base`) core that has no IT blocks. Instead,
//! `silentops/build.rs` derives a `ct_thumb2` cfg from the target triple
//! (true for `thumbv7*` and `thumbv8m.main`, false for `thumbv6m` and
//! `thumbv8m.base`), and the ARM backend gates below select `thumbv7.rs`
//! vs `thumbv6m.rs` on it. See `build.rs` for the rationale.
// Architecture-specific modules
pub use *;
pub use *;
// `ct_thumb2` is emitted by `build.rs` for Thumb-2 / IT-block M-profile cores
// (ARMv7-M, ARMv8-M.main). rustc emits no `target_feature = "thumb2"` for these
// targets, so the triple is the only reliable discriminator — see build.rs. The
// two ARM gates below are disjoint by construction (`ct_thumb2` vs its
// negation), so at most one ARM backend ever compiles.
pub use *;
pub use *;
pub use *;
// Default: pure Rust fallback (used on desktop without asm-x86_64, or when
// no asm feature enabled at all).
pub use *;