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>
impl<T> Equatable<T>
Sourcepub fn new(x: <Equatable<T> as Controlled>::Inner) -> Selfwhere
Self: Controlled,
pub fn new(x: <Equatable<T> as Controlled>::Inner) -> Selfwhere
Self: Controlled,
Create a new Equatable from an inner value.
Source§impl<T: Controlled> Equatable<T>where
T::Inner: ConstantTimeEq,
impl<T: Controlled> Equatable<T>where
T::Inner: ConstantTimeEq,
pub fn constant_time_eq(&self, other: &Self) -> bool
Trait Implementations§
Source§impl<T, O> ConstantTimeEq<O> for Equatable<T>
impl<T, O> ConstantTimeEq<O> for Equatable<T>
Source§fn constant_time_eq(&self, other: &O) -> bool
fn constant_time_eq(&self, other: &O) -> bool
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,
impl<T> Controlled for Equatable<T>where
T: Controlled,
type Inner = <T as Controlled>::Inner
fn init_from_inner(x: Self::Inner) -> Self
Source§fn risky_ref(&self) -> &Self::Inner
fn risky_ref(&self) -> &Self::Inner
fn inner_mut(&mut self) -> &mut Self::Inner
Source§fn risky_unwrap(self) -> Self::Inner
fn risky_unwrap(self) -> Self::Inner
Source§fn new(inner: Self::Inner) -> Selfwhere
Self: Sized,
fn new(inner: Self::Inner) -> Selfwhere
Self: Sized,
Source§fn generate<F>(f: F) -> Self
fn generate<F>(f: F) -> Self
Source§fn generate_ok<F, E>(f: F) -> Result<Self, E>
fn generate_ok<F, E>(f: F) -> Result<Self, E>
Result with the inner value. Read moreSource§fn map<B, F>(self, f: F) -> <Self as ReplaceT<B>>::Outputwhere
Self: Sized + ReplaceT<B>,
F: FnOnce(<Self as Controlled>::Inner) -> B,
<Self as ReplaceT<B>>::Output: Controlled<Inner = B>,
B: Zeroize,
fn map<B, F>(self, f: F) -> <Self as ReplaceT<B>>::Outputwhere
Self: Sized + ReplaceT<B>,
F: FnOnce(<Self as Controlled>::Inner) -> B,
<Self as ReplaceT<B>>::Output: Controlled<Inner = B>,
B: Zeroize,
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,
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,
map but the closure returns a Result with the new inner value.
The result is a Result with the new Controlled type. Read moreSource§fn zip<Other, Out, F>(self, b: Other, f: F) -> Protected<Out>
fn zip<Other, Out, F>(self, b: Other, f: F) -> Protected<Out>
Source§fn zip_ref<'a, A, Other, Out, F>(
self,
other: &'a Other,
f: F,
) -> <Self as ReplaceT<Out>>::Output
fn zip_ref<'a, A, Other, Out, F>( self, other: &'a Other, f: F, ) -> <Self as ReplaceT<Out>>::Output
zip but the second argument is a reference. Read moreSource§fn update<F>(&mut self, f: F)
fn update<F>(&mut self, f: F)
map but using references to that the inner value is updated in place. Read moreSource§fn update_with<Other, F>(&mut self, other: Other, f: F)
fn update_with<Other, F>(&mut self, other: Other, f: F)
Source§fn update_with_ref<'a, A, F>(&mut self, other: ProtectedRef<'a, A>, f: F)
fn update_with_ref<'a, A, F>(&mut self, other: ProtectedRef<'a, A>, f: F)
update_with but the second argument is a reference. Read moreSource§fn iter<'a, I>(&'a self) -> impl Iterator<Item = Protected<I>>
fn iter<'a, I>(&'a self) -> impl Iterator<Item = Protected<I>>
Protected.
I must be Copy because Protected always takes ownership of the inner value.Source§fn replace(&mut self, new: Self) -> Selfwhere
Self: Sized,
fn replace(&mut self, new: Self) -> Selfwhere
Self: Sized,
Self. Read moreSource§fn risky_inner_mut(&mut self) -> &mut Self::Inner
fn risky_inner_mut(&mut self) -> &mut Self::Inner
Source§impl<T, A> Extend<A> for Equatable<T>where
T: Extend<A>,
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>,
fn extend<I>(&mut self, iter: I)where
I: IntoIterator<Item = A>,
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)Source§impl<T, O> PartialEq<O> for Equatable<T>
PartialEq is implemented in constant time for any Equatable to any (nested) Equatable.
impl<T, O> PartialEq<O> for Equatable<T>
PartialEq is implemented in constant time for any Equatable to any (nested) Equatable.