rostl_primitives/
traits.rs

1//! Traits for conditional move and swap operations.
2use crate::indexable::Indexable;
3
4#[allow(missing_docs)]
5pub trait _Cmovbase {
6  fn cmov_base(&mut self, other: &Self, choice: bool);
7  fn cxchg_base(&mut self, other: &mut Self, choice: bool);
8}
9
10/// A trait for conditionally moving values with constant memory trace.
11///
12pub trait Cmov: Sized {
13  /// Conditionally move `other` into `self` based on `choice`.
14  /// @Oblivious
15  fn cmov(&mut self, other: &Self, choice: bool);
16  /// Conditionally exchange `other` and `self` based on `choice`.
17  /// @Oblivious
18  fn cxchg(&mut self, other: &mut Self, choice: bool);
19
20  /// Conditionally set `self` to either `val_false` or `val_true` based on `choice`.
21  /// @Oblivious
22  #[inline]
23  fn cset(&mut self, val_false: &Self, val_true: &Self, choice: bool) {
24    self.cmov(val_true, choice);
25    self.cmov(val_false, !choice);
26  }
27}
28
29/// A trait for conditionally swapping values with constant memory trace.
30///
31#[inline]
32pub fn cswap<T: Cmov + Copy>(first: &mut T, second: &mut T, choice: bool) {
33  let tmp = *first;
34  first.cmov(second, choice);
35  second.cmov(&tmp, choice);
36}
37
38/// Adds cswap for Indexables of cswap-able types.
39pub trait CswapIndex<T> {
40  /// Conditionally swap the elements at `i` and `j` based on `choice`.
41  /// @Oblivious
42  fn cswap(&mut self, i: usize, j: usize, choice: bool);
43}
44
45impl<T, C> CswapIndex<T> for C
46where
47  C: Indexable<T> + ?Sized,
48  T: Cmov + Copy,
49{
50  fn cswap(&mut self, i: usize, j: usize, choice: bool) {
51    let mut left = self[i];
52    let mut right = self[j];
53    cswap(&mut left, &mut right, choice);
54    self[i] = left;
55    self[j] = right;
56  }
57}