1use crate::{
2 macros::{impl_choose_int, impl_sealed_trait_for_uint},
3 types::NumericalZeroSizedType,
4};
5use core::{
6 cmp::PartialOrd,
7 fmt::{Debug, Display},
8 hash::Hash,
9 ops::{Add, AddAssign},
10};
11use typenum::{IsLessOrEqual, Sum, True, Unsigned, U0, U1};
12
13pub trait ExposeSecret<'max, T, MEC: Unsigned, EC: Unsigned>: Sized {
26 type Exposed<'brand>
28 where
29 'max: 'brand;
30
31 type Next: ExposeSecret<'max, T, MEC, Sum<EC, U1>>
34 where
35 EC: Add<U1> + Unsigned + IsLessOrEqual<MEC, Output = True>,
36 Sum<EC, U1>: Unsigned + IsLessOrEqual<MEC, Output = True> + Add<U1>;
37
38 fn expose_secret<ReturnType, ClosureType>(self, scope: ClosureType) -> (Self::Next, ReturnType)
47 where
48 for<'brand> ClosureType: FnOnce(Self::Exposed<'brand>) -> ReturnType,
49 EC: Add<U1> + IsLessOrEqual<MEC, Output = True>,
50 Sum<EC, U1>: Unsigned + Add<U1> + IsLessOrEqual<MEC, Output = True>;
51}
52
53#[cfg(feature = "cloneable-secret")]
54pub use self::cloneable_secret::CloneableSecret;
55
56#[cfg(feature = "debug-secret")]
57pub use self::debug_secret::DebugSecret;
58
59#[cfg(feature = "cloneable-secret")]
60mod cloneable_secret {
61 use core::clone::Clone;
64
65 #[cfg(feature = "zeroize")]
66 use zeroize::Zeroize;
67
68 #[cfg(feature = "zeroize")]
73 pub trait CloneableSecret: Clone + Zeroize {}
74
75 #[cfg(not(feature = "zeroize"))]
80 pub trait CloneableSecret: Clone {}
81
82 impl<
83 #[cfg(feature = "zeroize")] T: Clone + Zeroize,
84 #[cfg(not(feature = "zeroize"))] T: Clone,
85 const N: usize,
86 > CloneableSecret for [T; N]
87 {
88 }
89
90 #[cfg(feature = "alloc")]
91 use alloc::{string::String, vec::Vec};
92
93 #[cfg(feature = "alloc")]
94 impl CloneableSecret for String {}
95
96 #[cfg(feature = "alloc")]
97 impl<
98 #[cfg(feature = "zeroize")] T: Clone + Zeroize,
99 #[cfg(not(feature = "zeroize"))] T: Clone,
100 > CloneableSecret for Vec<T>
101 {
102 }
103
104 crate::macros::impl_cloneable_secret_for_numbers!(
105 i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
106 );
107}
108
109#[cfg(feature = "debug-secret")]
110mod debug_secret {
111 use core::fmt::Debug;
112
113 #[cfg(feature = "zeroize")]
114 use zeroize::Zeroize;
115
116 #[cfg(feature = "zeroize")]
121 pub trait DebugSecret: Debug + Zeroize {
122 fn debug_secret(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
124 f.write_str("[REDACTED]")
125 }
126 }
127
128 #[cfg(not(feature = "zeroize"))]
133 pub trait DebugSecret: Debug {
134 fn debug_secret(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
136 f.write_str("[REDACTED]")
137 }
138 }
139
140 impl<
141 #[cfg(feature = "zeroize")] T: Debug + Zeroize,
142 #[cfg(not(feature = "zeroize"))] T: Debug,
143 const N: usize,
144 > DebugSecret for [T; N]
145 {
146 }
147
148 #[cfg(feature = "alloc")]
149 use alloc::{string::String, vec::Vec};
150
151 #[cfg(feature = "alloc")]
152 impl DebugSecret for String {}
153
154 #[cfg(feature = "alloc")]
155 impl<
156 #[cfg(feature = "zeroize")] T: Debug + Zeroize,
157 #[cfg(not(feature = "zeroize"))] T: Debug,
158 > DebugSecret for Vec<T>
159 {
160 }
161
162 crate::macros::impl_debug_secret_for_numbers!(
163 i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
164 );
165}
166
167impl_sealed_trait_for_uint!(u8, u16, u32, u64, u128);
168
169pub trait ChooseMinimallyRepresentableUInt: __private::SealedTrait {
171 type Output: AddAssign
174 + Add<Self::Output, Output = Self::Output>
175 + PartialOrd
176 + Debug
177 + Display
178 + Copy
179 + Eq
180 + Ord
181 + PartialOrd
182 + Clone
183 + Hash
184 + Default;
185 type AtomicOutput;
187 const ZERO: Self::Output;
189 const ONE: Self::Output;
191
192 fn cast_unsigned_to_self_type<T: Unsigned>(_: __private::SealedToken) -> Self::Output;
195}
196
197pub trait AsAtomic: __private::SealedTrait {
200 type Output;
201}
202
203pub(crate) mod __private {
204
205 pub struct SealedToken {}
206 pub trait SealedTrait {}
207}
208
209#[cfg(target_pointer_width = "32")]
210impl_choose_int! {
211 B00 => u8;
212 B01 => u8;
213 B02 => u8;
214 B03 => u8;
215 B04 => u8;
216 B05 => u8;
217 B06 => u8;
218 B07 => u8;
219
220 B10 => u16;
221 B11 => u16;
222 B12 => u16;
223 B13 => u16;
224 B14 => u16;
225 B15 => u16;
226 B16 => u16;
227 B17 => u16;
228
229 B20 => u32;
230 B21 => u32;
231 B22 => u32;
232 B23 => u32;
233 B24 => u32;
234 B25 => u32;
235 B26 => u32;
236 B27 => u32;
237
238 B30 => u32;
239 B31 => u32;
240 B32 => u32;
241 B33 => u32;
242 B34 => u32;
243 B35 => u32;
244 B36 => u32;
245 B37 => u32;
246}
247
248#[cfg(target_pointer_width = "64")]
249impl_choose_int! {
250 B00 => u8;
251 B01 => u8;
252 B02 => u8;
253 B03 => u8;
254 B04 => u8;
255 B05 => u8;
256 B06 => u8;
257 B07 => u8;
258
259 B10 => u16;
260 B11 => u16;
261 B12 => u16;
262 B13 => u16;
263 B14 => u16;
264 B15 => u16;
265 B16 => u16;
266 B17 => u16;
267
268 B20 => u32;
269 B21 => u32;
270 B22 => u32;
271 B23 => u32;
272 B24 => u32;
273 B25 => u32;
274 B26 => u32;
275 B27 => u32;
276
277 B30 => u32;
278 B31 => u32;
279 B32 => u32;
280 B33 => u32;
281 B34 => u32;
282 B35 => u32;
283 B36 => u32;
284 B37 => u32;
285
286 B40 => u64;
287 B41 => u64;
288 B42 => u64;
289 B43 => u64;
290 B44 => u64;
291 B45 => u64;
292 B46 => u64;
293 B47 => u64;
294
295 B50 => u64;
296 B51 => u64;
297 B52 => u64;
298 B53 => u64;
299 B54 => u64;
300 B55 => u64;
301 B56 => u64;
302 B57 => u64;
303
304 B60 => u64;
305 B61 => u64;
306 B62 => u64;
307 B63 => u64;
308 B64 => u64;
309 B65 => u64;
310 B66 => u64;
311 B67 => u64;
312
313 B70 => u64;
314 B71 => u64;
315 B72 => u64;
316 B73 => u64;
317 B74 => u64;
318 B75 => u64;
319 B76 => u64;
320 B77 => u64;
321}
322
323impl __private::SealedTrait for U0 {}
324
325impl ChooseMinimallyRepresentableUInt for U0 {
326 type Output = NumericalZeroSizedType;
327 type AtomicOutput = NumericalZeroSizedType;
328
329 const ZERO: Self::Output = NumericalZeroSizedType {};
330 const ONE: Self::Output = NumericalZeroSizedType {};
331
332 fn cast_unsigned_to_self_type<T: Unsigned>(_: __private::SealedToken) -> Self::Output {
333 NumericalZeroSizedType {}
334 }
335}
336
337#[cfg(target_has_atomic = "8")]
338impl AsAtomic for u8 {
339 type Output = core::sync::atomic::AtomicU8;
340}
341
342#[cfg(target_has_atomic = "16")]
343impl AsAtomic for u16 {
344 type Output = core::sync::atomic::AtomicU16;
345}
346
347#[cfg(target_has_atomic = "32")]
348impl AsAtomic for u32 {
349 type Output = core::sync::atomic::AtomicU32;
350}
351
352#[cfg(target_has_atomic = "64")]
353impl AsAtomic for u64 {
354 type Output = core::sync::atomic::AtomicU64;
355}