From 29212ed924c72082faf31faba7fe6d81801eb695 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 23 Feb 2024 07:12:57 +0100 Subject: [PATCH] #37; removed the SIZE type parameter - MEC itself is sufficient - good; all tests passed --- src/macros.rs | 6 ++ src/runtime.rs | 2 +- src/runtime/error.rs | 18 ++--- src/runtime/secret.rs | 70 ++++++++----------- src/runtime/traits.rs | 6 +- src/traits.rs | 23 ++++-- ..._impl_minimally_representable_uints.stderr | 4 +- 7 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index ca9554f..c6547ab 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -45,6 +45,12 @@ macro_rules! impl_choose_int { impl<$($prev_args,)* $arg> $crate::traits::ChooseMinimallyRepresentableUInt for $crate::prelude::typenum::uint::UInt<$prev_num, $arg> { type Output = $out; + const MIN: Self::Output = Self::Output::MIN; + const ONE: Self::Output = 1; + + fn cast_unsigned_to_self_type(_: $crate::traits::__private::SealedToken) -> Self::Output { + ::USIZE as Self::Output + } } impl_choose_int!{ diff --git a/src/runtime.rs b/src/runtime.rs index 803f355..9dc617e 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -1,4 +1,4 @@ -pub mod common; +// pub mod common; pub mod error; pub mod secret; pub mod secret_sync; diff --git a/src/runtime/error.rs b/src/runtime/error.rs index 2c9b55c..22d12c5 100644 --- a/src/runtime/error.rs +++ b/src/runtime/error.rs @@ -1,26 +1,26 @@ -use crate::runtime::traits::MinimallyRepresentableUInt; +use crate::traits::ChooseMinimallyRepresentableUInt; #[derive(Debug)] #[non_exhaustive] -pub enum ExposeSecretError { - ExposeMoreThanMaximallyAllow(ExposeMoreThanMaximallyAllowError), +pub enum ExposeSecretError { + ExposeMoreThanMaximallyAllow(ExposeMoreThanMaximallyAllowError), } #[derive(Debug)] -pub struct ExposeMoreThanMaximallyAllowError { - pub mec: SIZE::Type, - pub ec: SIZE::Type, +pub struct ExposeMoreThanMaximallyAllowError { + pub mec: ::Output, + pub ec: ::Output, } -impl core::fmt::Display - for ExposeMoreThanMaximallyAllowError +impl core::fmt::Display + for ExposeMoreThanMaximallyAllowError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "`Secret` is exposed more than what it is maximally allowed to; it is exposed for {} times and it is only allowed to be exposed for {} times", self.ec, self.mec) } } -impl core::fmt::Display for ExposeSecretError { +impl core::fmt::Display for ExposeSecretError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::ExposeMoreThanMaximallyAllow(err) => err.fmt(f), diff --git a/src/runtime/secret.rs b/src/runtime/secret.rs index 1ddd280..5f9be2e 100644 --- a/src/runtime/secret.rs +++ b/src/runtime/secret.rs @@ -1,27 +1,22 @@ use core::{ - cell::UnsafeCell, + cell::Cell, marker::PhantomData, ops::{Deref, Drop}, }; use crate::{ - runtime::{common::DefaultMinimallyRepresentableUInt, error, traits}, - traits::__private, + runtime::{error, traits}, + traits::{ChooseMinimallyRepresentableUInt, __private}, }; -use typenum::{IsLessOrEqual, True, Unsigned}; +use typenum::Unsigned; #[cfg(feature = "zeroize")] use zeroize::Zeroize; pub struct RTSecret< #[cfg(feature = "zeroize")] T: Zeroize, #[cfg(not(feature = "zeroize"))] T, - MEC: Unsigned, - SIZE: traits::MinimallyRepresentableUInt = DefaultMinimallyRepresentableUInt, ->( - T, - UnsafeCell<::Type>, - PhantomData, -); + MEC: ChooseMinimallyRepresentableUInt + Unsigned, +>(T, Cell<::Output>); pub struct RTExposedSecret<'brand, T>(T, PhantomData &'brand ()>); @@ -35,29 +30,22 @@ impl<'brand, T> Deref for RTExposedSecret<'brand, &'brand T> { impl< #[cfg(feature = "zeroize")] T: Zeroize, #[cfg(not(feature = "zeroize"))] T, - MEC: Unsigned, - SIZE: traits::MinimallyRepresentableUInt, - > RTSecret + MEC: ChooseMinimallyRepresentableUInt + Unsigned, + > RTSecret { - pub const fn new(t: T) -> Self - where - MEC: IsLessOrEqual, - { - Self(t, UnsafeCell::new(SIZE::MIN), PhantomData) + pub const fn new(t: T) -> Self { + Self(t, Cell::new(::MIN)) } - pub fn new_with(f: impl FnOnce() -> T) -> Self - where - MEC: IsLessOrEqual, - { - Self(f(), UnsafeCell::new(SIZE::MIN), PhantomData) + pub fn new_with(f: impl FnOnce() -> T) -> Self { + Self( + f(), + Cell::new(::MIN), + ) } - pub fn exposure_count(&self) -> &SIZE::Type { - // SAFETY: The function only returns a shared reference (&usize) to the exposure count. - // It does not allow mutable access to the exposure count directly. - // This means that while external code can observe the exposure count, it cannot modify it directly. - unsafe { &*self.1.get() } + pub fn exposure_count(&self) -> ::Output { + self.1.get() } } @@ -65,9 +53,8 @@ impl< 'secret, #[cfg(feature = "zeroize")] T: Zeroize, #[cfg(not(feature = "zeroize"))] T, - MEC: Unsigned, - SIZE: traits::MinimallyRepresentableUInt, - > traits::RTExposeSecret<'secret, &'secret T, SIZE> for RTSecret + MEC: ChooseMinimallyRepresentableUInt + Unsigned, + > traits::RTExposeSecret<'secret, &'secret T, MEC> for RTSecret { type Exposed<'brand> = RTExposedSecret<'brand, &'brand T> where @@ -88,20 +75,20 @@ impl< fn try_expose_secret( &self, scope: ClosureType, - ) -> Result> + ) -> Result> where for<'brand> ClosureType: FnOnce(RTExposedSecret<'brand, &'brand T>) -> ReturnType, { // SAFETY: All tuple fields of `RTSecret` are private, there are no setter to them. // `RTSecret` is also not `Sync` so it is not possible to have multithreading race condition. - let ec_mut = unsafe { &mut *self.1.get() }; - let mec = SIZE::cast_unsigned_to_self_type::(__private::SealedToken {}); + let ec_mut = unsafe { &mut *self.1.as_ptr() }; + let mec = MEC::cast_unsigned_to_self_type::(__private::SealedToken {}); if *ec_mut >= mec { return Err(error::ExposeSecretError::ExposeMoreThanMaximallyAllow( error::ExposeMoreThanMaximallyAllowError { mec, ec: *ec_mut }, )); }; - *ec_mut += SIZE::ONE; + *ec_mut += MEC::ONE; Ok(scope(RTExposedSecret(&self.0, PhantomData))) } } @@ -109,9 +96,8 @@ impl< impl< #[cfg(feature = "zeroize")] T: Zeroize, #[cfg(not(feature = "zeroize"))] T, - MEC: Unsigned, - SIZE: traits::MinimallyRepresentableUInt, - > Drop for RTSecret + MEC: ChooseMinimallyRepresentableUInt + Unsigned, + > Drop for RTSecret { fn drop(&mut self) { #[cfg(feature = "zeroize")] @@ -129,8 +115,8 @@ mod tests { expected = "`RTSecret` has already been exposed for 255 times, the maximum number it is allowed to be exposed for is 255 times." )] fn test_usize_max_expose_secret() { - use typenum::{U255, U8}; - let mut secret_one = RTSecret::::new(69); + use typenum::U255; + let mut secret_one = RTSecret::::new(69); *secret_one.1.get_mut() = u8::MAX - 6; for _ in 0..=5 { @@ -139,7 +125,7 @@ mod tests { }); } - assert_eq!(secret_one.exposure_count(), &u8::MAX); + assert_eq!(secret_one.exposure_count(), u8::MAX); let _ = secret_one.expose_secret(|exposed_secret| { assert_eq!(*exposed_secret, 69); diff --git a/src/runtime/traits.rs b/src/runtime/traits.rs index 31eacf1..3f80cbc 100644 --- a/src/runtime/traits.rs +++ b/src/runtime/traits.rs @@ -6,10 +6,10 @@ use core::{ pub use crate::runtime::error; -use crate::traits::__private; +use crate::traits::{ChooseMinimallyRepresentableUInt, __private}; use typenum::Unsigned; -pub trait RTExposeSecret<'secret, T, SIZE: MinimallyRepresentableUInt> { +pub trait RTExposeSecret<'secret, T, MEC: ChooseMinimallyRepresentableUInt> { type Exposed<'brand> where 'secret: 'brand; @@ -21,7 +21,7 @@ pub trait RTExposeSecret<'secret, T, SIZE: MinimallyRepresentableUInt> { fn try_expose_secret( &self, scope: ClosureType, - ) -> Result> + ) -> Result> where for<'brand> ClosureType: FnOnce(Self::Exposed<'brand>) -> ReturnType; } diff --git a/src/traits.rs b/src/traits.rs index 328720e..c33059e 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -2,6 +2,7 @@ use crate::macros::impl_choose_int; use core::{ cmp::PartialOrd, fmt::{Debug, Display}, + hash::Hash, ops::{Add, AddAssign}, }; use typenum::{IsLessOrEqual, Sum, True, Unsigned, U1}; @@ -159,16 +160,30 @@ mod debug_secret { ); } +pub trait ChooseMinimallyRepresentableUInt: __private::SealedTrait { + type Output: AddAssign + + PartialOrd + + Debug + + Display + + Copy + + Eq + + Ord + + PartialOrd + + Clone + + Hash + + Default; + const MIN: Self::Output; + const ONE: Self::Output; + + fn cast_unsigned_to_self_type(_: __private::SealedToken) -> Self::Output; +} + pub(crate) mod __private { pub struct SealedToken {} pub trait SealedTrait {} } -pub trait ChooseMinimallyRepresentableUInt: __private::SealedTrait { - type Output: AddAssign + PartialOrd + Debug + Display + Copy; -} - impl_choose_int! { B00 => u8; B01 => u8; diff --git a/trybuild_tests/runtime/cannot_impl_minimally_representable_uints.stderr b/trybuild_tests/runtime/cannot_impl_minimally_representable_uints.stderr index d32a0c5..0e5e588 100644 --- a/trybuild_tests/runtime/cannot_impl_minimally_representable_uints.stderr +++ b/trybuild_tests/runtime/cannot_impl_minimally_representable_uints.stderr @@ -7,8 +7,8 @@ error[E0603]: module `__private` is private note: the module `__private` is defined here --> src/runtime/traits.rs | - | use crate::traits::__private; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | use crate::traits::{ChooseMinimallyRepresentableUInt, __private}; + | ^^^^^^^^^ error[E0277]: the trait bound `A: typenum::sealed::Sealed` is not satisfied --> trybuild_tests/runtime/cannot_impl_minimally_representable_uints.rs:11:23