use crate::prelude::*;
#[inline]
#[cfg_attr(feature = "use_attributes", not_hacspec)]
pub fn cswap_bit<T: Integer + Copy>(x: T, y: T, c: T) -> (T, T) {
cswap(x, y, T::default().wrap_sub(c))
}
#[inline]
#[cfg_attr(feature = "use_attributes", not_hacspec)]
pub fn cswap<T: Integer + Copy>(x: T, y: T, c: T) -> (T, T) {
let mask = c & (x ^ y);
(x ^ mask, y ^ mask)
}
#[inline]
#[cfg_attr(feature = "use_attributes", not_hacspec)]
pub fn cset_bit<T: Integer + Copy>(x: T, b: T, i: usize, c: T) -> T {
let set = x.set_bit(b, i);
let (out, _) = cswap(x, set, c);
out
}
#[inline]
#[cfg_attr(feature = "use_attributes", not_hacspec)]
pub fn cadd<T: Integer + Copy>(x: T, y: T, c: T) -> T {
let sum = x.wrap_add(y);
let (x, _) = cswap(x, sum, c);
x
}
#[inline]
#[cfg_attr(feature = "use_attributes", not_hacspec)]
pub fn csub<T: Integer + Copy>(x: T, y: T, c: T) -> T {
let diff = x.wrap_sub(y);
let (x, _) = cswap(x, diff, c);
x
}
#[inline]
#[cfg_attr(feature = "use_attributes", not_hacspec)]
pub fn cmul<T: Integer + Copy>(x: T, y: T, c: T) -> T {
let prod = x.wrap_mul(y);
let (x, _) = cswap(x, prod, c);
x
}
#[inline]
#[cfg_attr(feature = "use_attributes", not_hacspec)]
pub fn ct_div<T: Integer + Copy>(a: T, d: T) -> (T, T) {
let mut q = T::default();
let mut r = T::default();
for i in (0..T::NUM_BITS).rev() {
r = r << 1;
r = r.set(0, a, i);
let geq = r.greater_than_or_equal_bm(d);
r = csub(r, d, geq);
q = cset_bit(q, T::ONE(), i, geq);
}
(q, r)
}