Skip to content

Commit 7f459a5

Browse files
authored
ctutils: add size integers implementations (#1416)
- Add `CtGt` and `CtLt` for usize - Add `CtAssign` and `CtSelect` for `NonZero{U,I}size` - Add `CtNeg` for `NonZero{U,I}size` and `{u,i}size` - Add some tests Co-authored-by: Nics <NicsTr@users.noreply.github.com>
1 parent f5dbf7c commit 7f459a5

File tree

6 files changed

+149
-46
lines changed

6 files changed

+149
-46
lines changed

ctutils/src/traits/ct_assign.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use cmov::Cmov;
33
use core::{
44
cmp,
55
num::{
6-
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroU8, NonZeroU16,
7-
NonZeroU32, NonZeroU64, NonZeroU128,
6+
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize, NonZeroU8,
7+
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
88
},
99
};
1010

@@ -19,8 +19,8 @@ use core::num::NonZero;
1919
/// This crate provides built-in implementations for the following types:
2020
/// - [`i8`], [`i16`], [`i32`], [`i64`], [`i128`], [`isize`]
2121
/// - [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], [`usize`]
22-
/// - [`NonZeroI8`], [`NonZeroI16`], [`NonZeroI32`], [`NonZeroI64`], [`NonZeroI128`]
23-
/// - [`NonZeroU8`], [`NonZeroU16`], [`NonZeroU32`], [`NonZeroU64`], [`NonZeroU128`]
22+
/// - [`NonZeroI8`], [`NonZeroI16`], [`NonZeroI32`], [`NonZeroI64`], [`NonZeroI128`], [`NonZeroI128`]
23+
/// - [`NonZeroU8`], [`NonZeroU16`], [`NonZeroU32`], [`NonZeroU64`], [`NonZeroU128`],, [`NonZeroUsize`]
2424
/// - [`cmp::Ordering`]
2525
/// - [`Choice`]
2626
/// - `[T]` and `[T; N]` where `T` impls [`CtAssignSlice`], which the previously mentioned
@@ -106,11 +106,13 @@ impl_ct_assign_slice_with_cmov!(
106106
NonZeroI32,
107107
NonZeroI64,
108108
NonZeroI128,
109+
NonZeroIsize,
109110
NonZeroU8,
110111
NonZeroU16,
111112
NonZeroU32,
112113
NonZeroU64,
113114
NonZeroU128,
115+
NonZeroUsize,
114116
cmp::Ordering
115117
);
116118

ctutils/src/traits/ct_eq.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,24 +259,43 @@ mod tests {
259259
};
260260
}
261261

262-
macro_rules! ct_eq_test {
262+
macro_rules! ct_eq_test_unsigned {
263263
($ty:ty, $name:ident) => {
264264
#[test]
265265
fn $name() {
266-
let a: $ty = 42;
267-
let b: $ty = 42;
268-
let c: $ty = 1;
266+
let a = <$ty>::MAX;
267+
let b = <$ty>::MAX;
268+
let c = <$ty>::MIN;
269269
truth_table!(a, b, c);
270270
}
271271
};
272272
}
273273

274-
ct_eq_test!(u8, u8_ct_eq);
275-
ct_eq_test!(u16, u16_ct_eq);
276-
ct_eq_test!(u32, u32_ct_eq);
277-
ct_eq_test!(u64, u64_ct_eq);
278-
ct_eq_test!(u128, u128_ct_eq);
279-
ct_eq_test!(usize, usize_ct_eq);
274+
macro_rules! ct_eq_test_signed {
275+
($ty:ty, $name:ident) => {
276+
#[test]
277+
fn $name() {
278+
let a = <$ty>::MAX;
279+
let b = <$ty>::MAX;
280+
let c = <$ty>::MIN;
281+
truth_table!(a, b, c);
282+
}
283+
};
284+
}
285+
286+
ct_eq_test_unsigned!(u8, u8_ct_eq);
287+
ct_eq_test_unsigned!(u16, u16_ct_eq);
288+
ct_eq_test_unsigned!(u32, u32_ct_eq);
289+
ct_eq_test_unsigned!(u64, u64_ct_eq);
290+
ct_eq_test_unsigned!(u128, u128_ct_eq);
291+
ct_eq_test_unsigned!(usize, usize_ct_eq);
292+
293+
ct_eq_test_signed!(i8, i8_ct_eq);
294+
ct_eq_test_signed!(i16, i16_ct_eq);
295+
ct_eq_test_signed!(i32, i32_ct_eq);
296+
ct_eq_test_signed!(i64, i64_ct_eq);
297+
ct_eq_test_signed!(i128, i128_ct_eq);
298+
ct_eq_test_signed!(isize, isize_ct_eq);
280299

281300
#[test]
282301
fn array_ct_eq() {

ctutils/src/traits/ct_gt.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::Choice;
22
use core::{
33
cmp,
4-
num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128},
4+
num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize},
55
};
66

77
/// Constant time greater than.
@@ -26,7 +26,7 @@ macro_rules! impl_unsigned_ct_gt {
2626
};
2727
}
2828

29-
impl_unsigned_ct_gt!(u8, u16, u32, u64, u128);
29+
impl_unsigned_ct_gt!(u8, u16, u32, u64, u128, usize);
3030

3131
/// Impl `CtGt` for `NonZero<T>` by calling `NonZero::get`.
3232
macro_rules! impl_ct_gt_for_nonzero_integer {
@@ -42,7 +42,14 @@ macro_rules! impl_ct_gt_for_nonzero_integer {
4242
};
4343
}
4444

45-
impl_ct_gt_for_nonzero_integer!(NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128);
45+
impl_ct_gt_for_nonzero_integer!(
46+
NonZeroU8,
47+
NonZeroU16,
48+
NonZeroU32,
49+
NonZeroU64,
50+
NonZeroU128,
51+
NonZeroUsize
52+
);
4653

4754
impl CtGt for cmp::Ordering {
4855
#[inline]
@@ -59,15 +66,29 @@ mod tests {
5966
use super::CtGt;
6067
use core::cmp::Ordering;
6168

62-
#[test]
63-
fn ct_gt() {
64-
let a = 42u64;
65-
let b = 43u64;
66-
assert!(!a.ct_gt(&a).to_bool());
67-
assert!(!a.ct_gt(&b).to_bool());
68-
assert!(b.ct_gt(&a).to_bool());
69+
/// Test `CtGt`
70+
macro_rules! ct_gt_tests {
71+
( $($int:ident),+ ) => {
72+
$(
73+
mod $int {
74+
use super::CtGt;
75+
76+
#[test]
77+
fn ct_gt() {
78+
let a = <$int>::MIN;
79+
let b = <$int>::MAX;
80+
assert!(!a.ct_gt(&a).to_bool());
81+
assert!(!a.ct_gt(&b).to_bool());
82+
assert!(b.ct_gt(&a).to_bool());
83+
}
84+
85+
}
86+
)+
87+
};
6988
}
7089

90+
ct_gt_tests!(u8, u16, u32, u64, u128, usize);
91+
7192
#[test]
7293
fn ordering() {
7394
assert!(!Ordering::Equal.ct_gt(&Ordering::Equal).to_bool());

ctutils/src/traits/ct_lt.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::Choice;
22
use core::{
33
cmp,
4-
num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128},
4+
num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize},
55
};
66

77
/// Constant time less than.
@@ -26,7 +26,7 @@ macro_rules! impl_unsigned_ct_lt {
2626
};
2727
}
2828

29-
impl_unsigned_ct_lt!(u8, u16, u32, u64, u128);
29+
impl_unsigned_ct_lt!(u8, u16, u32, u64, u128, usize);
3030

3131
/// Impl `CtLt` for `NonZero<T>` by calling `NonZero::get`.
3232
macro_rules! impl_ct_lt_for_nonzero_integer {
@@ -42,7 +42,14 @@ macro_rules! impl_ct_lt_for_nonzero_integer {
4242
};
4343
}
4444

45-
impl_ct_lt_for_nonzero_integer!(NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128);
45+
impl_ct_lt_for_nonzero_integer!(
46+
NonZeroU8,
47+
NonZeroU16,
48+
NonZeroU32,
49+
NonZeroU64,
50+
NonZeroU128,
51+
NonZeroUsize
52+
);
4653

4754
impl CtLt for cmp::Ordering {
4855
#[inline]
@@ -68,6 +75,29 @@ mod tests {
6875
assert!(!b.ct_lt(&a).to_bool());
6976
}
7077

78+
/// Test `CtLt`
79+
macro_rules! ct_lt_tests {
80+
( $($int:ident),+ ) => {
81+
$(
82+
mod $int {
83+
use super::CtLt;
84+
85+
#[test]
86+
fn ct_gt() {
87+
let a = <$int>::MIN;
88+
let b = <$int>::MAX;
89+
assert!(!a.ct_lt(&a).to_bool());
90+
assert!(a.ct_lt(&b).to_bool());
91+
assert!(!b.ct_lt(&a).to_bool());
92+
}
93+
94+
}
95+
)+
96+
};
97+
}
98+
99+
ct_lt_tests!(u8, u16, u32, u64, u128, usize);
100+
71101
#[test]
72102
fn ordering() {
73103
assert!(!Ordering::Equal.ct_lt(&Ordering::Equal).to_bool());

ctutils/src/traits/ct_neg.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{Choice, CtAssign, CtSelect};
22
use core::num::{
3-
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroU8, NonZeroU16, NonZeroU32,
4-
NonZeroU64, NonZeroU128,
3+
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize, NonZeroU8,
4+
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
55
};
66

77
/// Constant-time conditional negation: negates a value when `choice` is [`Choice::TRUE`].
@@ -62,13 +62,15 @@ impl_signed_ct_neg!(
6262
i32,
6363
i64,
6464
i128,
65+
isize,
6566
NonZeroI8,
6667
NonZeroI16,
6768
NonZeroI32,
6869
NonZeroI64,
69-
NonZeroI128
70+
NonZeroI128,
71+
NonZeroIsize
7072
);
71-
impl_unsigned_ct_neg!(u8, u16, u32, u64, u128);
73+
impl_unsigned_ct_neg!(u8, u16, u32, u64, u128, usize);
7274

7375
/// Unfortunately `NonZeroU*` doesn't support `wrapping_neg` for some reason (but `NonZeroI*` does),
7476
/// even though the wrapping negation of any non-zero integer should also be non-zero.
@@ -89,7 +91,14 @@ macro_rules! impl_ct_neg_for_unsigned_nonzero {
8991
};
9092
}
9193

92-
impl_ct_neg_for_unsigned_nonzero!(NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128);
94+
impl_ct_neg_for_unsigned_nonzero!(
95+
NonZeroU8,
96+
NonZeroU16,
97+
NonZeroU32,
98+
NonZeroU64,
99+
NonZeroU128,
100+
NonZeroUsize
101+
);
93102

94103
#[cfg(test)]
95104
mod tests {
@@ -130,14 +139,14 @@ mod tests {
130139
use crate::{Choice, CtNeg};
131140

132141
#[test]
133-
fn u32_ct_neg() {
142+
fn ct_neg() {
134143
let n: $uint = 42;
135144
assert_eq!(n, n.ct_neg(Choice::FALSE));
136145
assert_eq!(<$uint>::MAX - n + 1, n.ct_neg(Choice::TRUE));
137146
}
138147

139148
#[test]
140-
fn u32_ct_neg_assign() {
149+
fn ct_neg_assign() {
141150
let n: $uint = 42;
142151
let mut x = n;
143152
x.ct_neg_assign(Choice::FALSE);
@@ -151,6 +160,6 @@ mod tests {
151160
};
152161
}
153162

154-
signed_ct_neg_tests!(i8, i16, i32, i64, i128);
155-
unsigned_ct_neg_tests!(u8, u16, u32, u64, u128);
163+
signed_ct_neg_tests!(i8, i16, i32, i64, i128, isize);
164+
unsigned_ct_neg_tests!(u8, u16, u32, u64, u128, usize);
156165
}

ctutils/src/traits/ct_select.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use crate::{Choice, CtAssign, CtAssignSlice};
22
use core::{
33
cmp,
44
num::{
5-
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroU8, NonZeroU16,
6-
NonZeroU32, NonZeroU64, NonZeroU128,
5+
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize, NonZeroU8,
6+
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
77
},
88
};
99

@@ -15,8 +15,8 @@ use crate::CtOption;
1515
/// This crate provides built-in implementations for the following types:
1616
/// - [`i8`], [`i16`], [`i32`], [`i64`], [`i128`], [`isize`]
1717
/// - [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], [`usize`]
18-
/// - [`NonZeroI8`], [`NonZeroI16`], [`NonZeroI32`], [`NonZeroI64`], [`NonZeroI128`]
19-
/// - [`NonZeroU8`], [`NonZeroU16`], [`NonZeroU32`], [`NonZeroU64`], [`NonZeroU128`]
18+
/// - [`NonZeroI8`], [`NonZeroI16`], [`NonZeroI32`], [`NonZeroI64`], [`NonZeroI128`], [`NonZeroI128`]
19+
/// - [`NonZeroU8`], [`NonZeroU16`], [`NonZeroU32`], [`NonZeroU64`], [`NonZeroU128`],, [`NonZeroUsize`]
2020
/// - [`cmp::Ordering`]
2121
/// - [`Choice`]
2222
/// - `[T; N]` where `T` impls [`CtSelectArray`], which the previously mentioned types all do,
@@ -109,11 +109,13 @@ impl_ct_select_with_ct_assign!(
109109
NonZeroI32,
110110
NonZeroI64,
111111
NonZeroI128,
112+
NonZeroIsize,
112113
NonZeroU8,
113114
NonZeroU16,
114115
NonZeroU32,
115116
NonZeroU64,
116117
NonZeroU128,
118+
NonZeroUsize,
117119
cmp::Ordering
118120
);
119121

@@ -159,7 +161,7 @@ mod alloc {
159161
mod tests {
160162
use super::{Choice, CtSelect, cmp};
161163

162-
macro_rules! ct_select_test {
164+
macro_rules! ct_select_test_unsigned {
163165
($ty:ty, $name:ident) => {
164166
#[test]
165167
fn $name() {
@@ -171,11 +173,31 @@ mod tests {
171173
};
172174
}
173175

174-
ct_select_test!(u8, u8_ct_select);
175-
ct_select_test!(u16, u16_ct_select);
176-
ct_select_test!(u32, u32_ct_select);
177-
ct_select_test!(u64, u64_ct_select);
178-
ct_select_test!(u128, u128_ct_select);
176+
macro_rules! ct_select_test_signed {
177+
($ty:ty, $name:ident) => {
178+
#[test]
179+
fn $name() {
180+
let a: $ty = 1;
181+
let b: $ty = -2;
182+
assert_eq!(a.ct_select(&b, Choice::FALSE), a);
183+
assert_eq!(a.ct_select(&b, Choice::TRUE), b);
184+
}
185+
};
186+
}
187+
188+
ct_select_test_unsigned!(u8, u8_ct_select);
189+
ct_select_test_unsigned!(u16, u16_ct_select);
190+
ct_select_test_unsigned!(u32, u32_ct_select);
191+
ct_select_test_unsigned!(u64, u64_ct_select);
192+
ct_select_test_unsigned!(u128, u128_ct_select);
193+
ct_select_test_unsigned!(usize, usize_ct_select);
194+
195+
ct_select_test_signed!(i8, i8_ct_select);
196+
ct_select_test_signed!(i16, i16_ct_select);
197+
ct_select_test_signed!(i32, i32_ct_select);
198+
ct_select_test_signed!(i64, i64_ct_select);
199+
ct_select_test_signed!(i128, i128_ct_select);
200+
ct_select_test_signed!(isize, isize_ct_select);
179201

180202
#[test]
181203
fn ordering_ct_select() {

0 commit comments

Comments
 (0)