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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// Copyright (c) 2025-2026 Federico Hoerth <memparanoid@gmail.com>
// SPDX-License-Identifier: GPL-3.0-only
// See LICENSE in the repository root for full license text.
//! Core traits for systematic zeroization.
use ZeroizeOnDropSentinel;
/// Trait for verifying that a value has been zeroized.
///
/// This trait allows runtime checks to verify that zeroization actually happened.
/// Used in tests and assertions to ensure no sensitive data remains in memory.
///
/// # Example
///
/// ```rust
/// use redoubt_zero_core::{ZeroizationProbe, FastZeroizable};
///
/// let mut value: u32 = 42;
///
/// assert!(!value.is_zeroized());
///
/// value.fast_zeroize();
/// assert!(value.is_zeroized());
/// assert_eq!(value, 0);
/// ```
/// Trait for types that verify zeroization happened before drop.
///
/// Types implementing this trait contain a [`ZeroizeOnDropSentinel`] and provide
/// methods to verify that `.zeroize()` was called before the value is dropped.
///
/// This trait is typically derived using `#[derive(RedoubtZero)]` from the `RedoubtZero` crate.
/// Trait for mutable guards that auto-zeroize on drop.
///
/// Types implementing this trait wrap a mutable reference `&mut T` and
/// provide controlled access while ensuring zeroization on drop.
///
/// # Example
///
/// ```rust,ignore
/// use redoubt_zero_core::{MutGuarded, ZeroizingMutGuard};
///
/// fn process_guarded<'a, T: MutGuarded<'a, SomeType>>(guard: &mut T) {
/// let value = guard.expose_mut();
/// // ... use value
/// } // guard zeroizes on drop
/// ```
/// Metadata about zeroization strategy for a type.
///
/// This trait provides compile-time information about whether a type can be
/// bulk-zeroized with memset or requires element-by-element zeroization.
///
/// **Note:** This trait is NOT dyn-compatible (has associated constants).
/// Use [`FastZeroizable`] for trait objects.
/// Trait for types that can be zeroized at runtime.
///
/// This trait is dyn-compatible, allowing it to be used in trait objects
/// like `&mut dyn FastZeroizable`.
///
/// Use this trait when you need dynamic dispatch for zeroization operations.
/// Combined trait for types with both zeroization metadata and runtime zeroization.
///
/// This is the main trait users should implement. It combines:
/// - [`ZeroizeMetadata`]: Compile-time optimization hints
/// - [`FastZeroizable`]: Runtime zeroization method (dyn-compatible)
///
/// # Usage
///
/// Most types should use `#[derive(RedoubtZero)]` which implements this automatically.
/// Manual implementation is only needed for custom types with special zeroization requirements.
///
/// # `CAN_BE_BULK_ZEROIZED` Constant
///
/// ## `CAN_BE_BULK_ZEROIZED = true` (Fast Path)
///
/// All-zeros is a valid bit pattern. Enables:
/// - Fast vectorized memset operations (`ptr::write_bytes`)
/// - ~20x performance improvement over byte-by-byte writes
/// - Safe for: primitives (u8-u128, i8-i128, bool, char, floats)
///
/// ## `CAN_BE_BULK_ZEROIZED = false` (Slow Path)
///
/// Requires element-by-element zeroization because:
/// - Type contains pointers, references, or heap allocations
/// - All-zeros may not be a valid representation
/// - Needs recursive calls on each field
///
/// # Example
///
/// ```rust,ignore
/// use redoubt_zero_core::FastZeroize;
///
/// // Primitive: bulk zeroization
/// impl FastZeroize for u32 {
/// const CAN_BE_BULK_ZEROIZED: bool = true;
///
/// fn fast_zeroize(&mut self) {
/// redoubt_util::zeroize_primitive(self);
/// }
/// }
///
/// // Complex type: element-by-element
/// struct ApiKey {
/// secret: Vec<u8>,
/// }
///
/// impl FastZeroize for ApiKey {
/// const CAN_BE_BULK_ZEROIZED: bool = false;
///
/// fn fast_zeroize(&mut self) {
/// self.secret.fast_zeroize();
/// }
/// }
/// ```
// Blanket impl: any type implementing both sub-traits automatically gets FastZeroize
/// Trait for static zeroization of global CipherBox instances.
///
/// Used by `#[cipherbox(..., global = true)]` to expose `fast_zeroize()` on
/// the generated module. Requires trait import for consistency with
/// [`FastZeroizable`].
///
/// # Example
///
/// ```rust,ignore
/// use redoubt::codec::RedoubtCodec;
/// use redoubt::vault::cipherbox;
/// use redoubt::zero::{RedoubtZero, StaticFastZeroizable};
///
/// #[cipherbox(SensitiveDataBox, global = true)]
/// #[derive(Default, RedoubtCodec, RedoubtZero)]
/// struct SensitiveData {
/// // ...
/// }
///
/// SENSITIVE_DATA_BOX::fast_zeroize();
/// ```