CtOption

Struct CtOption 

Source
pub struct CtOption<T> { /* private fields */ }
Expand description

Equivalent of Option but predicated on a Choice with combinators that allow for constant-time operations which always perform the same sequence of instructions regardless of the value of is_some.

Unlike Option, CtOption always contains a value, and will use the contained value when e.g. evaluating the callbacks of combinator methods, which unlike core it does unconditionally in order to ensure constant-time operation. This approach stands in contrast to the lazy evaluation similar methods on Option provide.

Implementations§

Source§

impl<T> CtOption<T>

Source

pub const fn new(value: T, is_some: Choice) -> CtOption<T>

Construct a new CtOption, with a Choice parameter is_some as a stand-in for Some or None enum variants of a typical Option type.

Source

pub const fn as_mut(&mut self) -> CtOption<&mut T>

Convert from a &mut CtOption<T> to CtOption<&mut T>.

Source

pub const fn as_ref(&self) -> CtOption<&T>

Convert from a &CtOption<T> to CtOption<&T>.

Source

pub fn as_deref(&self) -> CtOption<&T::Target>
where T: Deref,

Convert from CtOption<T> (or &CtOption<T>) to CtOption<&T::Target>, for types which impl the Deref trait.

Source

pub fn as_deref_mut(&mut self) -> CtOption<&mut T::Target>
where T: DerefMut,

Convert from CtOption<T> (or &mut CtOption<T>) to CtOption<&mut T::Target>, for types which impl the DerefMut trait.

Source

pub fn expect(self, msg: &str) -> T

Return the contained value, consuming the self value.

§Panics

In the event self.is_some() is Choice::FALSE, panics with a custom panic message provided as the msg argument.

Source

pub fn into_option(self) -> Option<T>

Convert the CtOption wrapper into an Option, depending on whether CtOption::is_some is a truthy or falsy Choice.

This function exists to avoid ending up with ugly, verbose and/or bad handled conversions from the CtOption wraps to an Option or Result.

It’s equivalent to the corresponding From impl, however this version is friendlier for type inference.

This implementation doesn't intend to be constant-time nor try to protect the leakage of the `T` value since the [`Option`] will do it anyway.
Source

pub const fn is_some(&self) -> Choice

Returns Choice::TRUE if the option is the equivalent of a Some.

Source

pub const fn is_none(&self) -> Choice

Returns Choice::TRUE if the option is the equivalent of a None.

Source

pub fn and<U>(self, optb: CtOption<U>) -> CtOption<U>

Returns optb if self.is_some() is Choice::TRUE, otherwise returns a CtOption where self.is_some() is Choice::FALSE.

Source

pub fn and_then<U, F>(self, f: F) -> CtOption<U>
where F: FnOnce(T) -> CtOption<U>,

Calls the provided callback with the wrapped inner value, returning the resulting CtOption value in the event that self.is_some() is Choice::TRUE, or if not returns a CtOption with self.is_none().

Unlike Option, the provided callback f is unconditionally evaluated to ensure constant-time operation. This requires evaluating the function with “dummy” value of T (e.g. if the CtOption was constructed with a supplied placeholder value and Choice::FALSE, the placeholder value will be provided).

Source

pub fn filter<P>(self, predicate: P) -> Self
where P: FnOnce(&T) -> Choice,

Calls the provided callback with the wrapped inner value, which computes a Choice, and updates self.is_some().

It updates it to be Choice::FALSE in the event the returned choice is also false. If it was Choice::FALSE to begin with, it will unconditionally remain that way.

Source

pub fn map<U, F>(self, f: F) -> CtOption<U>
where F: FnOnce(T) -> U,

Maps a CtOption<T> to a CtOption<U> by unconditionally applying a function to the contained value, but returning a new option value which inherits self.is_some().

Source

pub fn map_or<U, F>(self, default: U, f: F) -> U
where U: CtSelect, F: FnOnce(T) -> U,

Maps a CtOption<T> to a U value, eagerly evaluating the provided function, and returning the supplied default in the event self.is_some() is Choice::FALSE.

Source

pub fn map_or_default<U, F>(self, f: F) -> U
where U: CtSelect + Default, F: FnOnce(T) -> U,

Maps a CtOption<T> to a U value, eagerly evaluating the provided function, precomputing U::default() using the Default trait, and returning it in the event self.is_some() is Choice::FALSE.

Source

pub fn ok_or<E>(self, err: E) -> Result<T, E>

Transforms a CtOption<T> into a Result<T, E>, mapping to Ok(T) if self.is_some() is Choice::TRUE, or mapping to the provided err in the event self.is_some() is Choice::FALSE.

This implementation doesn't intend to be constant-time nor try to protect the leakage of the `T` value since the [`Option`] will do it anyway.
Source

pub fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
where F: FnOnce() -> E,

Transforms a CtOption<T> into a Result<T, E> by unconditionally calling the provided callback value and using its result in the event self.is_some() is Choice::FALSE.

Source

pub fn or(self, optb: CtOption<T>) -> CtOption<T>
where T: CtSelect,

Returns self if self.is_some() is Choice::TRUE, otherwise returns optb.

Source

pub fn unwrap(self) -> T

Return the contained value, consuming the self value.

Use of this function is discouraged due to panic potential. Instead, prefer non-panicking alternatives such as unwrap_or or unwrap_or_default which operate in constant-time.

As the final step of a sequence of constant-time operations, or in the event you are dealing with a CtOption in a non-secret context where constant-time does not matter, you can also convert to Option using into_option or the From impl on Option. Note this introduces a branch and with it a small amount of timing variability. If possible try to avoid this branch when writing constant-time code (e.g. use implicit rejection instead of Option/Result to handle errors)

§Panics

In the event self.is_some() is Choice::FALSE.

Source

pub fn unwrap_or(self, default: T) -> T
where T: CtSelect,

Return the contained value in the event self.is_some() is Choice::TRUE, or if not, uses a provided default.

Source

pub fn unwrap_or_default(self) -> T
where T: CtSelect + Default,

Unconditionally computes T::default() using the Default trait, then returns either the contained value if self.is_some() is Choice::TRUE, or if it’s Choice::FALSE returns the previously computed default.

Source

pub fn xor(self, optb: CtOption<T>) -> CtOption<T>
where T: CtSelect,

Returns an “is some” CtOption with the contained value from either self or optb in the event exactly one of them has self.is_some() set to Choice::TRUE, or else returns a CtOption with self.is_some() set to Choice::FALSE.

Source

pub fn zip<U>(self, other: CtOption<U>) -> CtOption<(T, U)>

Zips self with another CtOption.

If self.is_some() && other.is_some(), this method returns a new CtOption for a 2-tuple of their contents where is_some() is Choice::TRUE.

Otherwise, a CtOption where is_some() is Choice::FALSE is returned.

Source

pub fn zip_with<U, F, R>(self, other: CtOption<U>, f: F) -> CtOption<R>
where F: FnOnce(T, U) -> R,

Zips self and another CtOption with function f.

If self.is_some() && other.is_some(), this method returns a new CtOption for the result of f applied to their inner values where is_some() is Choice::TRUE.

Otherwise, a CtOption where is_some() is Choice::FALSE is returned.

Source§

impl<T> CtOption<&T>

Source

pub const fn copied(self) -> CtOption<T>
where T: Copy,

Maps a CtOption<&T> to CtOption<T> by copying the contents of the option.

Source

pub fn cloned(self) -> CtOption<T>
where T: Clone,

Maps a CtOption<&T> to CtOption<T> by cloning the contents of the option.

Source§

impl<T> CtOption<&mut T>

Source

pub const fn copied(self) -> CtOption<T>
where T: Copy,

Maps a CtOption<&mut T> to CtOption<T> by copying the contents of the option.

Source

pub fn cloned(self) -> CtOption<T>
where T: Clone,

Maps a CtOption<&mut T> to CtOption<T> by cloning the contents of the option.

Trait Implementations§

Source§

impl<T: Clone> Clone for CtOption<T>

Source§

fn clone(&self) -> CtOption<T>

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: CtEq> CtEq for CtOption<T>

Source§

fn ct_eq(&self, other: &CtOption<T>) -> Choice

Equality
Source§

fn ct_ne(&self, other: &Rhs) -> Choice

Inequality
Source§

impl<T: CtSelect> CtSelect for CtOption<T>

Source§

fn ct_select(&self, other: &Self, choice: Choice) -> Self

Select between self and other based on choice, returning a copy of the value. Read more
Source§

fn ct_assign(&mut self, other: &Self, choice: Choice)

Conditionally assign other to self if choice is Choice::TRUE.
Source§

fn ct_swap(&mut self, other: &mut Self, choice: Choice)

Conditionally swap self and other if choice is Choice::TRUE.
Source§

impl<T: Debug> Debug for CtOption<T>

Source§

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

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

impl<T> From<CtOption<T>> for CtOption<T>

Available on crate feature subtle only.

NOTE: in order to be able to unwrap the subtle::CtOption we rely on a Default bound in order to have a placeholder value, and ConditionallySelectable to be able to use unwrap_or.

Source§

fn from(src: CtOption<T>) -> CtOption<T>

Converts to this type from the input type.
Source§

impl<T> From<CtOption<T>> for CtOption<T>

Available on crate feature subtle only.
Source§

fn from(src: CtOption<T>) -> CtOption<T>

Converts to this type from the input type.
Source§

impl<T> From<CtOption<T>> for Option<T>

Convert the CtOption wrapper into an Option, depending on whether CtOption::is_some is a truthy or falsy Choice.

This implementation doesn’t intend to be constant-time nor try to protect the leakage of the T value since the Option will do it anyway.

Source§

fn from(src: CtOption<T>) -> Option<T>

Converts to this type from the input type.
Source§

impl<T: Copy> Copy for CtOption<T>

Auto Trait Implementations§

§

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

§

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

§

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

§

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

§

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

§

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

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn into(self) -> U

Calls U::from(self).

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

§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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

§

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

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

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

Performs the conversion.