use crate::{
macros::{impl_choose_int, impl_sealed_trait_for_uint},
types::NumericalZeroSizedType,
};
use core::{
cmp::PartialOrd,
fmt::{Debug, Display},
hash::Hash,
ops::{Add, AddAssign},
};
use typenum::{IsLessOrEqual, Sum, True, Unsigned, U0, U1};
pub trait ExposeSecret<'max, T, MEC: Unsigned, EC: Unsigned>: Sized {
type Exposed<'brand>
where
'max: 'brand;
type Next: ExposeSecret<'max, T, MEC, Sum<EC, U1>>
where
EC: Add<U1> + Unsigned + IsLessOrEqual<MEC, Output = True>,
Sum<EC, U1>: Unsigned + IsLessOrEqual<MEC, Output = True> + Add<U1>;
fn expose_secret<ReturnType, ClosureType>(self, scope: ClosureType) -> (Self::Next, ReturnType)
where
for<'brand> ClosureType: FnOnce(Self::Exposed<'brand>) -> ReturnType,
EC: Add<U1> + IsLessOrEqual<MEC, Output = True>,
Sum<EC, U1>: Unsigned + Add<U1> + IsLessOrEqual<MEC, Output = True>;
}
#[cfg(feature = "cloneable-secret")]
pub use self::cloneable_secret::CloneableSecret;
#[cfg(feature = "debug-secret")]
pub use self::debug_secret::DebugSecret;
#[cfg(feature = "cloneable-secret")]
mod cloneable_secret {
use core::clone::Clone;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
#[cfg(feature = "zeroize")]
pub trait CloneableSecret: Clone + Zeroize {}
#[cfg(not(feature = "zeroize"))]
pub trait CloneableSecret: Clone {}
impl<
#[cfg(feature = "zeroize")] T: Clone + Zeroize,
#[cfg(not(feature = "zeroize"))] T: Clone,
const N: usize,
> CloneableSecret for [T; N]
{
}
#[cfg(feature = "alloc")]
use alloc::{string::String, vec::Vec};
#[cfg(feature = "alloc")]
impl CloneableSecret for String {}
#[cfg(feature = "alloc")]
impl<
#[cfg(feature = "zeroize")] T: Clone + Zeroize,
#[cfg(not(feature = "zeroize"))] T: Clone,
> CloneableSecret for Vec<T>
{
}
crate::macros::impl_cloneable_secret_for_numbers!(
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
);
}
#[cfg(feature = "debug-secret")]
mod debug_secret {
use core::fmt::Debug;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
#[cfg(feature = "zeroize")]
pub trait DebugSecret: Debug + Zeroize {
fn debug_secret(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
f.write_str("[REDACTED]")
}
}
#[cfg(not(feature = "zeroize"))]
pub trait DebugSecret: Debug {
fn debug_secret(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
f.write_str("[REDACTED]")
}
}
impl<
#[cfg(feature = "zeroize")] T: Debug + Zeroize,
#[cfg(not(feature = "zeroize"))] T: Debug,
const N: usize,
> DebugSecret for [T; N]
{
}
#[cfg(feature = "alloc")]
use alloc::{string::String, vec::Vec};
#[cfg(feature = "alloc")]
impl DebugSecret for String {}
#[cfg(feature = "alloc")]
impl<
#[cfg(feature = "zeroize")] T: Debug + Zeroize,
#[cfg(not(feature = "zeroize"))] T: Debug,
> DebugSecret for Vec<T>
{
}
crate::macros::impl_debug_secret_for_numbers!(
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
);
}
impl_sealed_trait_for_uint!(u8, u16, u32, u64, u128);
pub trait ChooseMinimallyRepresentableUInt: __private::SealedTrait {
type Output: AddAssign
+ Add<Self::Output, Output = Self::Output>
+ PartialOrd
+ Debug
+ Display
+ Copy
+ Eq
+ Ord
+ PartialOrd
+ Clone
+ Hash
+ Default;
type AtomicOutput;
const ZERO: Self::Output;
const ONE: Self::Output;
fn cast_unsigned_to_self_type<T: Unsigned>(_: __private::SealedToken) -> Self::Output;
}
pub trait AsAtomic: __private::SealedTrait {
type Output;
}
pub(crate) mod __private {
pub struct SealedToken {}
pub trait SealedTrait {}
}
#[cfg(target_pointer_width = "32")]
impl_choose_int! {
B00 => u8;
B01 => u8;
B02 => u8;
B03 => u8;
B04 => u8;
B05 => u8;
B06 => u8;
B07 => u8;
B10 => u16;
B11 => u16;
B12 => u16;
B13 => u16;
B14 => u16;
B15 => u16;
B16 => u16;
B17 => u16;
B20 => u32;
B21 => u32;
B22 => u32;
B23 => u32;
B24 => u32;
B25 => u32;
B26 => u32;
B27 => u32;
B30 => u32;
B31 => u32;
B32 => u32;
B33 => u32;
B34 => u32;
B35 => u32;
B36 => u32;
B37 => u32;
}
#[cfg(target_pointer_width = "64")]
impl_choose_int! {
B00 => u8;
B01 => u8;
B02 => u8;
B03 => u8;
B04 => u8;
B05 => u8;
B06 => u8;
B07 => u8;
B10 => u16;
B11 => u16;
B12 => u16;
B13 => u16;
B14 => u16;
B15 => u16;
B16 => u16;
B17 => u16;
B20 => u32;
B21 => u32;
B22 => u32;
B23 => u32;
B24 => u32;
B25 => u32;
B26 => u32;
B27 => u32;
B30 => u32;
B31 => u32;
B32 => u32;
B33 => u32;
B34 => u32;
B35 => u32;
B36 => u32;
B37 => u32;
B40 => u64;
B41 => u64;
B42 => u64;
B43 => u64;
B44 => u64;
B45 => u64;
B46 => u64;
B47 => u64;
B50 => u64;
B51 => u64;
B52 => u64;
B53 => u64;
B54 => u64;
B55 => u64;
B56 => u64;
B57 => u64;
B60 => u64;
B61 => u64;
B62 => u64;
B63 => u64;
B64 => u64;
B65 => u64;
B66 => u64;
B67 => u64;
B70 => u64;
B71 => u64;
B72 => u64;
B73 => u64;
B74 => u64;
B75 => u64;
B76 => u64;
B77 => u64;
}
impl __private::SealedTrait for U0 {}
impl ChooseMinimallyRepresentableUInt for U0 {
type Output = NumericalZeroSizedType;
type AtomicOutput = NumericalZeroSizedType;
const ZERO: Self::Output = NumericalZeroSizedType {};
const ONE: Self::Output = NumericalZeroSizedType {};
fn cast_unsigned_to_self_type<T: Unsigned>(_: __private::SealedToken) -> Self::Output {
NumericalZeroSizedType {}
}
}
#[cfg(target_has_atomic = "8")]
impl AsAtomic for u8 {
type Output = core::sync::atomic::AtomicU8;
}
#[cfg(target_has_atomic = "16")]
impl AsAtomic for u16 {
type Output = core::sync::atomic::AtomicU16;
}
#[cfg(target_has_atomic = "32")]
impl AsAtomic for u32 {
type Output = core::sync::atomic::AtomicU32;
}
#[cfg(target_has_atomic = "64")]
impl AsAtomic for u64 {
type Output = core::sync::atomic::AtomicU64;
}