diff --git a/ctutils/src/choice.rs b/ctutils/src/choice.rs
index ec895a76..a7a7ebf6 100644
--- a/ctutils/src/choice.rs
+++ b/ctutils/src/choice.rs
@@ -66,6 +66,12 @@ impl Choice {
/// HACK: workaround to allow `const fn` boolean support on Rust 1.85.
///
/// This does not apply `black_box` to the output.
+ ///
+ ///
+ /// Security Warning
+ ///
+ /// See the security warnings for [`Choice::to_bool`].
+ ///
// TODO(tarcieri): deprecate/remove this in favor of `to_bool` when MSRV is Rust 1.86
pub const fn to_bool_vartime(self) -> bool {
self.0 != 0
@@ -355,6 +361,16 @@ impl From for u8 {
}
}
+/// Convert `Choice` into a `bool`.
+///
+///
+/// Security Warning
+///
+/// Using this function will introduce timing variability, since computing this at all currently
+/// requires a branch.
+///
+/// See the security warnings for [`Choice::to_bool`].
+///
impl From for bool {
fn from(choice: Choice) -> bool {
choice.to_bool()
diff --git a/ctutils/src/ct_option.rs b/ctutils/src/ct_option.rs
index 9b306e9a..a935c389 100644
--- a/ctutils/src/ct_option.rs
+++ b/ctutils/src/ct_option.rs
@@ -116,7 +116,10 @@ impl CtOption {
self.value
}
- /// Return a copy of the contained value without consuming `self`.
+ /// Return the contained value, consuming the `self` value, with `const fn` support.
+ ///
+ /// Relies on a `Copy` bound which implies `!Drop` which is needed to be able to move out of
+ /// `self` in a `const fn` without `feature(const_precise_live_drops)`.
///
/// # Panics
/// In the event `self.is_some()` is [`Choice::FALSE`], panics with a custom panic message
@@ -157,6 +160,8 @@ impl CtOption {
/// type inference.
///
///
+ /// Warning: variable-time!
+ ///
/// 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.
///
@@ -176,6 +181,8 @@ impl CtOption {
/// `const fn` and destructors.
///
///
+ /// Warning: variable-time!
+ ///
/// 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.
///
@@ -310,8 +317,10 @@ impl CtOption {
/// [`Choice::FALSE`].
///
///
+ /// Warning: variable-time!
+ ///
/// 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.
+ /// `T` value since the [`Result`] will do it anyway.
///
#[inline]
pub fn ok_or(self, err: E) -> Result {
@@ -320,6 +329,13 @@ impl CtOption {
/// Transforms a `CtOption` into a `Result` by unconditionally calling the provided
/// callback value and using its result in the event `self.is_some()` is [`Choice::FALSE`].
+ ///
+ ///
+ /// Warning: variable-time!
+ ///
+ /// This implementation doesn't intend to be constant-time nor try to protect the leakage of the
+ /// `T` value since the [`Result`] will do it anyway.
+ ///
#[inline]
pub fn ok_or_else(self, err: F) -> Result
where
@@ -524,10 +540,10 @@ impl Default for CtOption {
/// [`CtOption::is_some`] is a truthy or falsy [`Choice`].
///
///
+/// Warning: variable-time!
///
/// 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.
-///
///
impl From> for Option {
fn from(src: CtOption) -> Option {