Skip to content

Commit 04b1690

Browse files
authored
ctutils: subtle interop (#1262)
Adds bidirectional `From` conversions for the following: - `ctutils::Choice` <=> `subtle::Choice` - `ctutils::CtOption` <=> `subtle::CtOption` Support is gated under an optional `subtle` feature. This will simplify using `ctutils` in codebases that are already using `subtle` such as `crypto-bigint` (the main place it seems interesting to actually attempt to use it).
1 parent 5f0b306 commit 04b1690

File tree

5 files changed

+53
-0
lines changed

5 files changed

+53
-0
lines changed

.github/workflows/ctutils.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ jobs:
6464
with:
6565
toolchain: ${{ matrix.rust }}
6666
- run: cargo test
67+
- run: cargo test --all-features
68+
- run: cargo test --all-features --release
6769

6870
# Test using `cargo careful`
6971
test-careful:

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ctutils/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ rust-version = "1.85"
1818

1919
[dependencies]
2020
cmov = "0.4"
21+
22+
# optional dependencies
23+
subtle = { version = "2", optional = true, default-features = false }

ctutils/src/choice.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,22 @@ impl From<Choice> for bool {
159159
}
160160
}
161161

162+
#[cfg(feature = "subtle")]
163+
impl From<subtle::Choice> for Choice {
164+
#[inline]
165+
fn from(choice: subtle::Choice) -> Choice {
166+
Choice(choice.unwrap_u8())
167+
}
168+
}
169+
170+
#[cfg(feature = "subtle")]
171+
impl From<Choice> for subtle::Choice {
172+
#[inline]
173+
fn from(choice: Choice) -> subtle::Choice {
174+
subtle::Choice::from(choice.0)
175+
}
176+
}
177+
162178
impl Not for Choice {
163179
type Output = Choice;
164180

ctutils/src/ct_option.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,31 @@ impl<T> From<CtOption<T>> for Option<T> {
385385
}
386386
}
387387

388+
/// NOTE: in order to be able to unwrap the `subtle::CtOption` we rely on a `Default` bound in
389+
/// order to have a placeholder value, and `ConditionallySelectable` to be able to use `unwrap_or`.
390+
#[cfg(feature = "subtle")]
391+
impl<T> From<subtle::CtOption<T>> for CtOption<T>
392+
where
393+
T: subtle::ConditionallySelectable + Default,
394+
{
395+
#[inline]
396+
fn from(src: subtle::CtOption<T>) -> CtOption<T> {
397+
let is_some = src.is_some();
398+
CtOption {
399+
value: src.unwrap_or(Default::default()),
400+
is_some: is_some.into(),
401+
}
402+
}
403+
}
404+
405+
#[cfg(feature = "subtle")]
406+
impl<T> From<CtOption<T>> for subtle::CtOption<T> {
407+
#[inline]
408+
fn from(src: CtOption<T>) -> subtle::CtOption<T> {
409+
subtle::CtOption::new(src.value, src.is_some.into())
410+
}
411+
}
412+
388413
#[cfg(test)]
389414
mod tests {
390415
use crate::{Choice, CtEq, CtOption, CtSelect};

0 commit comments

Comments
 (0)