pub struct Choice(/* private fields */);Expand description
Constant-time analogue of bool providing a “best effort” optimization barrier.
This type attempts to hint to the compiler and its codegen backends that optimizations should not be applied which depend on specific values of this type.
This is used as a “belt-and-suspenders” defense in addition to mechanisms like
constant-time predication intrinsics provided by the cmov crate, and is never expected to be
the only line of defense.
Implementations§
Source§impl Choice
impl Choice
Sourcepub const fn from_i64_eq(x: i64, y: i64) -> Self
pub const fn from_i64_eq(x: i64, y: i64) -> Self
Returns Choice::TRUE if x == y, and Choice::FALSE otherwise.
Sourcepub const fn from_u8_eq(x: u8, y: u8) -> Self
pub const fn from_u8_eq(x: u8, y: u8) -> Self
Returns Choice::TRUE if x == y, and Choice::FALSE otherwise.
Sourcepub const fn from_u8_le(x: u8, y: u8) -> Self
pub const fn from_u8_le(x: u8, y: u8) -> Self
Returns Choice::TRUE if x <= y and Choice::FALSE otherwise.
Sourcepub const fn from_u8_lsb(value: u8) -> Self
pub const fn from_u8_lsb(value: u8) -> Self
Initialize from the least significant bit of a u8.
Sourcepub const fn from_u8_lt(x: u8, y: u8) -> Self
pub const fn from_u8_lt(x: u8, y: u8) -> Self
Returns Choice::TRUE if x < y, and Choice::FALSE otherwise.
Sourcepub const fn from_u8_nz(value: u8) -> Self
pub const fn from_u8_nz(value: u8) -> Self
Returns Choice::TRUE if value != 0, and Choice::FALSE otherwise.
Sourcepub const fn from_u16_eq(x: u16, y: u16) -> Self
pub const fn from_u16_eq(x: u16, y: u16) -> Self
Returns Choice::TRUE if x == y, and Choice::FALSE otherwise.
Sourcepub const fn from_u16_le(x: u16, y: u16) -> Self
pub const fn from_u16_le(x: u16, y: u16) -> Self
Returns Choice::TRUE if x <= y and Choice::FALSE otherwise.
Sourcepub const fn from_u16_lsb(value: u16) -> Self
pub const fn from_u16_lsb(value: u16) -> Self
Initialize from the least significant bit of a u16.
Sourcepub const fn from_u16_lt(x: u16, y: u16) -> Self
pub const fn from_u16_lt(x: u16, y: u16) -> Self
Returns Choice::TRUE if x < y, and Choice::FALSE otherwise.
Sourcepub const fn from_u16_nz(value: u16) -> Self
pub const fn from_u16_nz(value: u16) -> Self
Returns Choice::TRUE if value != 0, and Choice::FALSE otherwise.
Sourcepub const fn from_u32_eq(x: u32, y: u32) -> Self
pub const fn from_u32_eq(x: u32, y: u32) -> Self
Returns Choice::TRUE if x == y, and Choice::FALSE otherwise.
Sourcepub const fn from_u32_le(x: u32, y: u32) -> Self
pub const fn from_u32_le(x: u32, y: u32) -> Self
Returns Choice::TRUE if x <= y and Choice::FALSE otherwise.
Sourcepub const fn from_u32_lsb(value: u32) -> Self
pub const fn from_u32_lsb(value: u32) -> Self
Initialize from the least significant bit of a u32.
Sourcepub const fn from_u32_lt(x: u32, y: u32) -> Self
pub const fn from_u32_lt(x: u32, y: u32) -> Self
Returns Choice::TRUE if x < y, and Choice::FALSE otherwise.
Sourcepub const fn from_u32_nz(value: u32) -> Self
pub const fn from_u32_nz(value: u32) -> Self
Returns Choice::TRUE if value != 0, and Choice::FALSE otherwise.
Sourcepub const fn from_u64_eq(x: u64, y: u64) -> Self
pub const fn from_u64_eq(x: u64, y: u64) -> Self
Returns Choice::TRUE if x == y, and Choice::FALSE otherwise.
Sourcepub const fn from_u64_le(x: u64, y: u64) -> Self
pub const fn from_u64_le(x: u64, y: u64) -> Self
Returns Choice::TRUE if x <= y and Choice::FALSE otherwise.
Sourcepub const fn from_u64_lsb(value: u64) -> Self
pub const fn from_u64_lsb(value: u64) -> Self
Initialize from the least significant bit of a u64.
Sourcepub const fn from_u64_lt(x: u64, y: u64) -> Self
pub const fn from_u64_lt(x: u64, y: u64) -> Self
Returns Choice::TRUE if x < y, and Choice::FALSE otherwise.
Sourcepub const fn from_u64_nz(value: u64) -> Self
pub const fn from_u64_nz(value: u64) -> Self
Returns Choice::TRUE if value != 0, and Choice::FALSE otherwise.
Sourcepub const fn from_u128_eq(x: u128, y: u128) -> Self
pub const fn from_u128_eq(x: u128, y: u128) -> Self
Returns Choice::TRUE if x == y, and Choice::FALSE otherwise.
Sourcepub const fn from_u128_le(x: u128, y: u128) -> Self
pub const fn from_u128_le(x: u128, y: u128) -> Self
Returns Choice::TRUE if x <= y and Choice::FALSE otherwise.
Sourcepub const fn from_u128_lsb(value: u128) -> Self
pub const fn from_u128_lsb(value: u128) -> Self
Initialize from the least significant bit of a u128.
Sourcepub const fn from_u128_lt(x: u128, y: u128) -> Self
pub const fn from_u128_lt(x: u128, y: u128) -> Self
Returns Choice::TRUE if x < y, and Choice::FALSE otherwise.
Sourcepub const fn from_u128_nz(value: u128) -> Self
pub const fn from_u128_nz(value: u128) -> Self
Returns Choice::TRUE if value != 0, and Choice::FALSE otherwise.
Sourcepub const fn select_i64(self, a: i64, b: i64) -> i64
pub const fn select_i64(self, a: i64, b: i64) -> i64
const fn helper: return b if self is Choice::TRUE, otherwise return a.
Only use this instead of the [CtSelect] trait in the event you’re in a const fn context
and can’t use the trait. The former will provide better constant-time assurances.
Sourcepub const fn select_u8(self, a: u8, b: u8) -> u8
pub const fn select_u8(self, a: u8, b: u8) -> u8
const fn helper: return b if self is Choice::TRUE, otherwise return a.
Only use this instead of the [CtSelect] trait in the event you’re in a const fn context
and can’t use the trait. The former will provide better constant-time assurances.
Sourcepub const fn select_u16(self, a: u16, b: u16) -> u16
pub const fn select_u16(self, a: u16, b: u16) -> u16
const fn helper: return b if self is Choice::TRUE, otherwise return a.
Only use this instead of the [CtSelect] trait in the event you’re in a const fn context
and can’t use the trait. The former will provide better constant-time assurances.
Sourcepub const fn select_u32(self, a: u32, b: u32) -> u32
pub const fn select_u32(self, a: u32, b: u32) -> u32
const fn helper: return b if self is Choice::TRUE, otherwise return a.
Only use this instead of the [CtSelect] trait in the event you’re in a const fn context
and can’t use the trait. The former will provide better constant-time assurances.
Sourcepub const fn select_u64(self, a: u64, b: u64) -> u64
pub const fn select_u64(self, a: u64, b: u64) -> u64
const fn helper: return b if self is Choice::TRUE, otherwise return a.
Only use this instead of the [CtSelect] trait in the event you’re in a const fn context
and can’t use the trait. The former will provide better constant-time assurances.
Sourcepub const fn select_u128(self, a: u128, b: u128) -> u128
pub const fn select_u128(self, a: u128, b: u128) -> u128
const fn helper: return b if self is Choice::TRUE, otherwise return a.
Only use this instead of the [CtSelect] trait in the event you’re in a const fn context
and can’t use the trait. The former will provide better constant-time assurances.
Sourcepub fn to_bool(self) -> bool
pub fn to_bool(self) -> bool
Convert Choice into a bool.
Using this function will introduce timing variability, since computing this at all currently requires a branch.
This is intended to be used as either the one and only branch at the end of a constant-time operation to e.g. differentiate between success and failure, or in contexts where constant-time doesn’t matter, e.g. variable-time code that operates on “maybe secret” types which aren’t secrets in a particular context.
If you are trying to use this in the context of a constant-time operation, be warned that the small amount of timing variability it introduces can potentially be exploited. Whenever possible, prefer fully constant-time approaches instead.
Sourcepub fn to_u8(self) -> u8
pub fn to_u8(self) -> u8
Convert Choice to a u8, attempting to apply a “best effort” optimization barrier.
Sourcepub const fn to_bool_vartime(self) -> bool
pub const fn to_bool_vartime(self) -> bool
HACK: workaround to allow const fn boolean support on Rust 1.85.
This does not apply black_box to the output.
See the security warnings for Choice::to_bool.
Sourcepub const fn to_u8_vartime(self) -> u8
pub const fn to_u8_vartime(self) -> u8
HACK: workaround to allow const fn boolean support on Rust 1.85.
This does not apply black_box to the output.
Sourcepub const fn to_u8_mask(self) -> u8
pub const fn to_u8_mask(self) -> u8
Sourcepub const fn to_u16_mask(self) -> u16
pub const fn to_u16_mask(self) -> u16
Sourcepub const fn to_u32_mask(self) -> u32
pub const fn to_u32_mask(self) -> u32
Sourcepub const fn to_u64_mask(self) -> u64
pub const fn to_u64_mask(self) -> u64
Sourcepub const fn to_u128_mask(self) -> u128
pub const fn to_u128_mask(self) -> u128
Trait Implementations§
Source§impl BitAndAssign for Choice
impl BitAndAssign for Choice
Source§fn bitand_assign(&mut self, rhs: Choice)
fn bitand_assign(&mut self, rhs: Choice)
&= operation. Read moreSource§impl BitOrAssign for Choice
impl BitOrAssign for Choice
Source§fn bitor_assign(&mut self, rhs: Choice)
fn bitor_assign(&mut self, rhs: Choice)
|= operation. Read moreSource§impl BitXorAssign for Choice
impl BitXorAssign for Choice
Source§fn bitxor_assign(&mut self, rhs: Choice)
fn bitxor_assign(&mut self, rhs: Choice)
^= operation. Read moreSource§impl CtAssignSlice for Choice
impl CtAssignSlice for Choice
Source§fn ct_assign_slice(dst: &mut [Self], src: &[Self], choice: Choice)
fn ct_assign_slice(dst: &mut [Self], src: &[Self], choice: Choice)
Source§impl CtEqSlice for Choice
impl CtEqSlice for Choice
Source§fn ct_eq_slice(a: &[Self], b: &[Self]) -> Choice
fn ct_eq_slice(a: &[Self], b: &[Self]) -> Choice
a is equal to b in constant-time.Source§fn ct_ne_slice(a: &[Self], b: &[Self]) -> Choice
fn ct_ne_slice(a: &[Self], b: &[Self]) -> Choice
a is NOT equal to b in constant-time.Source§impl From<Choice> for bool
Convert Choice into a bool.
impl From<Choice> for bool
Convert Choice into a bool.
Using this function will introduce timing variability, since computing this at all currently requires a branch.
See the security warnings for Choice::to_bool.
Source§impl From<u8> for Choice
DEPRECATED: this exists to aid migrating code from subtle. Use Choice::from_u8_lsb instead.
impl From<u8> for Choice
DEPRECATED: this exists to aid migrating code from subtle. Use Choice::from_u8_lsb instead.
Rust doesn’t actually let us deprecate an impl block, however this comment is here to discourage future use and warn that this will be removed in a future release.