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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//! Personality typestate: a zero-size marker that selects which implementation
//! of an operation is picked at monomorphization.
//!
//! Two personalities ship here:
//!
//! - [`Nct`] (default): standard "non-constant-time" implementation.
//! - [`Ct`]: constant-time implementation. Slower bodies whose timing is
//! independent of operand values, defensible against an adversarial
//! optimizer. Used by signing paths and any code handling secret values.
//!
//! This is a pure-`core` marker (it depends only on [`PhantomData`]); it is
//! deliberately **not** gated behind the `ct` feature, which governs only the
//! `subtle`-backed constant-time *implementations*. It is intended to apply to
//! this crate's numeric operations, but nothing about the marker itself is
//! numeric — if a non-numeric consumer ever needs it, lifting it into its own
//! crate (re-exported here) is mechanical.
//!
//! ## Const-eval dispatch via `match P::TAG`
//!
//! Composite `const fn` methods that need to dispatch on personality can
//! `match` on the [`PersonalityTag`] associated constant:
//!
//! ```ignore
//! const fn dispatched<P: Personality>(x: u32) -> u32 {
//! match P::TAG {
//! PersonalityTag::Nct => fast_body(x),
//! PersonalityTag::Ct => ct_body(x),
//! }
//! }
//! ```
//!
//! Trait *method* calls (e.g. `P::widening_mul(x, y)`) require unstable
//! `const_trait_impl` in const contexts and are not used by this pattern. Tag
//! dispatch works on stable today and composes through multi-level generic
//! `const fn` chains without loss of const-eval.
use PhantomData;
/// Marker trait for personalities. Sealed — implementations live in this
/// crate. Downstream code uses the [`Nct`] and [`Ct`] types directly or
/// writes `match P::TAG` dispatch using [`PersonalityTag`].
/// Compile-time tag identifying the active personality. Returned by
/// [`Personality::TAG`] and used as the discriminant for `match P::TAG`
/// dispatch in `const fn` bodies.
/// Non-constant-time marker. The default personality.
;
/// Constant-time marker.
///
/// Selects constant-time implementations of operation primitives — bodies
/// whose execution time and memory access pattern do not depend on operand
/// values. Appropriate for code that handles secret values, where
/// operand-dependent timing or memory access would leak them.
///
/// Constant-time-only APIs (e.g. `subtle::ConditionallySelectable`,
/// `ConstantTimeEq`) should be exposed only for the `Ct` variant — wrong-
/// variant calls then become compile errors, not silent non-constant-time
/// execution.
;
/// `PhantomData` helper for storing a personality marker as a zero-size field.
/// Use as `_p: PersonalityMarker<P>` in struct definitions.
pub type PersonalityMarker<P> = ;