Skip to main content

Equatable

Struct Equatable 

Source
pub struct Equatable<T>(/* private fields */);
Expand description

A controlled wrapper type that allows for constant time equality checks of a Controlled type. The immediate inner type must also be Controlled (typically Protected).

§Examples

Initializing an Equatable:

use vitaminc::protected::{Equatable, Controlled, Protected};
let x: Equatable<Protected<u8>> = 42.into();
let y: Equatable<Protected<u8>> = Equatable::<Protected<u8>>::new(42);

§Constant time comparisons

Equatable requires that types are equatable in constant time.

use vitaminc::protected::{Equatable, Protected};
let x: Equatable<Protected<u8>> = 112.into();
let y: Equatable<Protected<u8>> = 112.into();

assert!(x.constant_time_eq(&y));

The Equatable type also implements PartialEq and Eq for easy comparison using the constant time implementation.

use vitaminc::protected::{Equatable, Protected};
let x: Equatable<Protected<u8>> = 112.into();
let y: Equatable<Protected<u8>> = 112.into();
assert_eq!(x, y);

§Nesting Equatable types

Constant time comparison also works for nested Equatable types. This way, the ordering or depth of the nesting doesn’t matter, the comparison will always be constant time.

See also crate::Exportable.

use vitaminc::protected::{Exportable, Equatable, Protected};
let x: Equatable<Protected<[u8; 16]>> = [0u8; 16].into();
let y: Exportable<Equatable<Protected<[u8; 16]>>> = Exportable::new([0u8; 16]);

assert_eq!(x, y);

§Opaque Debug

Because Equatable wraps Controlled, inner types will never be printed. It’s therefore safe to use it in debug output and in custom types.

use vitaminc::protected::{Equatable, Controlled, Protected};

type Inner = Equatable<Protected<u8>>;

#[derive(Debug, PartialEq)]
struct SafeType(Inner);
let x = SafeType(Inner::new(100));
assert!(format!("{:?}", x).contains("Protected<u8>"));

§Usage in a struct

use vitaminc::protected::{Equatable, Protected};

#[derive(Debug, PartialEq)]
struct AuthenticatedString {
  tag: Equatable<Protected<[u8; 32]>>,
  value: String
}

impl AuthenticatedString {
    fn new(tag: [u8; 32], value: String) -> Self {
        Self { tag: tag.into(), value }
    }
}

let a = AuthenticatedString::new([0u8; 32], "Hello, world!".to_string());
let b = AuthenticatedString::new([0u8; 32], "Hello, world!".to_string());
assert_eq!(a, b);

Implementations§

Source§

impl<T> Equatable<T>

Source

pub fn new(x: <Equatable<T> as Controlled>::Inner) -> Self
where Self: Controlled,

Create a new Equatable from an inner value.

Source§

impl<T: Controlled> Equatable<T>

Source

pub fn constant_time_eq(&self, other: &Self) -> bool

Trait Implementations§

Source§

impl<T, O> ConstantTimeEq<O> for Equatable<T>

Source§

fn constant_time_eq(&self, other: &O) -> bool

This method tests for self and other values to be equal, using constant time operations. Implementations will mostly use ConstantTimeEq::ct_eq to achieve this but because not everything is implemented in subtle-ng, we create our own “wrapping” trait.
Source§

impl<T> Controlled for Equatable<T>
where T: Controlled,

Source§

type Inner = <T as Controlled>::Inner

Source§

fn init_from_inner(x: Self::Inner) -> Self

Source§

fn risky_ref(&self) -> &Self::Inner

Provides a reference to the inner value. This is a risky operation because it bypasses the protections that the Controlled type provides. Use with caution!
Source§

fn inner_mut(&mut self) -> &mut Self::Inner

Source§

fn risky_unwrap(self) -> Self::Inner

Unwraps the inner value of the Controlled type. This is a risky operation because it consumes the Controlled type and returns the inner value negating the protections that the Controlled type provides. Read more
Source§

fn new(inner: Self::Inner) -> Self
where Self: Sized,

Initialize a new instance of the Controlled type from the inner value.
Source§

fn generate<F>(f: F) -> Self
where Self: Sized, F: FnOnce() -> Self::Inner,

Generate a new instance of the Controlled type from a function that returns the inner value. Read more
Source§

fn generate_ok<F, E>(f: F) -> Result<Self, E>
where Self: Sized, F: FnOnce() -> Result<Self::Inner, E>,

Generate a new Controlled type from a function that returns a Result with the inner value. Read more
Source§

fn map<B, F>(self, f: F) -> <Self as ReplaceT<B>>::Output
where Self: Sized + ReplaceT<B>, F: FnOnce(<Self as Controlled>::Inner) -> B, <Self as ReplaceT<B>>::Output: Controlled<Inner = B>, B: Zeroize,

Map the inner value of this Controlled type. Conceptually similar to Option::map`. Read more
Source§

fn map_ok<B, F, E>(self, f: F) -> Result<<Self as ReplaceT<B>>::Output, E>
where Self: Sized + ReplaceT<B>, F: FnOnce(<Self as Controlled>::Inner) -> Result<B, E>, <Self as ReplaceT<B>>::Output: Controlled<Inner = B>, B: Zeroize,

Similar to map but the closure returns a Result with the new inner value. The result is a Result with the new Controlled type. Read more
Source§

fn zip<Other, Out, F>(self, b: Other, f: F) -> Protected<Out>
where Self: Sized, Other: Controlled, Out: Zeroize, F: FnOnce(Self::Inner, Other::Inner) -> Out,

Zip two Controlled values of the same type together with a function that combines them. Read more
Source§

fn zip_ref<'a, A, Other, Out, F>( self, other: &'a Other, f: F, ) -> <Self as ReplaceT<Out>>::Output
where A: ?Sized + 'a, Self: Sized + ReplaceT<Out>, <Self as ReplaceT<Out>>::Output: Controlled<Inner = Out>, Other: AsProtectedRef<'a, A>, Out: Zeroize, F: FnOnce(Self::Inner, &A) -> Out,

Like zip but the second argument is a reference. Read more
Source§

fn update<F>(&mut self, f: F)
where F: FnMut(&mut Self::Inner),

Similar to map but using references to that the inner value is updated in place. Read more
Source§

fn update_with<Other, F>(&mut self, other: Other, f: F)
where F: FnMut(&mut Self::Inner, Other::Inner), Other: Controlled,

Update the inner value with another Controlled value. The inner value of the second argument is passed to the closure. Read more
Source§

fn update_with_ref<'a, A, F>(&mut self, other: ProtectedRef<'a, A>, f: F)
where A: ?Sized + 'a, F: FnMut(&mut Self::Inner, &A),

Like update_with but the second argument is a reference. Read more
Source§

fn iter<'a, I>(&'a self) -> impl Iterator<Item = Protected<I>>
where <Self as Controlled>::Inner: AsRef<[I]>, I: Copy + 'a,

Iterate over the inner value and wrap each element in a Protected. I must be Copy because Protected always takes ownership of the inner value.
Source§

fn replace(&mut self, new: Self) -> Self
where Self: Sized,

Replace the inner value with a new one. The new value must be Self. Read more
Source§

fn risky_inner_mut(&mut self) -> &mut Self::Inner

Provides a mutable reference to the inner value. This is a risky operation because it bypasses the protections that the Controlled type provides. Use with caution!
Source§

impl<T: Debug> Debug for Equatable<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T, A> Extend<A> for Equatable<T>
where T: Extend<A>,

Source§

fn extend<I>(&mut self, iter: I)
where I: IntoIterator<Item = A>,

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<T> From<T> for Equatable<Protected<T>>
where T: Into<Protected<T>> + Zeroize,

Source§

fn from(x: T) -> Self

Converts to this type from the input type.
Source§

impl<T> From<T> for Equatable<T>
where T: ControlledPrivate,

Source§

fn from(x: T) -> Self

Converts to this type from the input type.
Source§

impl<T, O> PartialEq<O> for Equatable<T>

PartialEq is implemented in constant time for any Equatable to any (nested) Equatable.

Source§

fn eq(&self, other: &O) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T, K> ReplaceT<K> for Equatable<Exportable<Protected<T>>>

Source§

impl<T, K> ReplaceT<K> for Equatable<Protected<T>>

Source§

impl<T> Serialize for Equatable<T>

Serialize is implemented for any Equatable type that has a SafeSerialize inner type.

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<T> Zeroed for Equatable<T>
where T: Zeroed,

Source§

fn zeroed() -> Self

Source§

impl<T> Zeroize for Equatable<T>
where T: Zeroize,

Source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the zeroization operation is not “optimized away” by the compiler.

Auto Trait Implementations§

§

impl<T> Freeze for Equatable<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Equatable<T>
where T: RefUnwindSafe,

§

impl<T> Send for Equatable<T>
where T: Send,

§

impl<T> Sync for Equatable<T>
where T: Sync,

§

impl<T> Unpin for Equatable<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Equatable<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for Equatable<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T> AsProtectedRef<'a, <T as Controlled>::Inner> for T
where T: Controlled,

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<'de, T> SafeDeserialize<'de> for T
where <T as Controlled>::Inner: SafeDeserialize<'de>, T: Controlled,

Source§

fn safe_deserialize<S>( deserializer: S, ) -> Result<T, <S as Deserializer<'de>>::Error>
where S: Deserializer<'de>,

Source§

impl<T> SafeSerialize for T

Source§

fn safe_serialize<S>( &self, serializer: S, ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where S: Serializer,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.