1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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)
}