1#![no_std]
48use core::mem::transmute as trans;
49
50const MAX_U8: u8 = ::core::u8::MAX;
51const MAX_U16: u16 = ::core::u16::MAX;
52const MAX_U32: u32 = ::core::u32::MAX;
53const MAX_U64: u64 = ::core::u64::MAX;
54const MAX_USIZE: usize = ::core::usize::MAX;
55
56
57
58#[test]
107fn test_bool_representation() {
108 let t: bool = true;
109 let f: bool = false;
110 let t_val: u8 = unsafe{ ::core::mem::transmute(t) };
111 let f_val: u8 = unsafe{ ::core::mem::transmute(f) };
112 assert_eq!( t_val, 0x01u8);
113 assert_eq!( f_val, 0x00u8);
114}
115
116macro_rules! ct_eq_gen {
123 ($name: ident, $code: ty, $max: expr, $($shr: expr),*
124 ;; $test_name: ident, $test_v0: expr, $test_v1: expr) => {
125 #[no_mangle]
129 #[inline(never)]
130 pub extern "C" fn $name( x: $code, y: $code) -> bool {
131 let mut z: $code = $max ^ (x^y);
132 $(
133 z &= z.wrapping_shr($shr);
134 )*
135 let val = z as u8;
147 unsafe{trans(val)}
148 }
149 #[test]
150 fn $test_name() {
151 let x: $code = $test_v0;
152 let y: $code = $test_v1;
153 assert_eq!( $name($max,$max), true);
154 assert_eq!( $name(x,x), true);
155 assert_eq!( $name(y,y), true);
156 assert_eq!( $name(0,0), true);
157 assert_eq!( $name(1,1), true);
158 assert_eq!( $name($max,0), false);
159 assert_eq!( $name($max,1), false);
160 assert_eq!( $name($max,x), false);
161 assert_eq!( $name($max,y), false);
162 assert_eq!( $name(y,1), false);
163 assert_eq!( $name(x,1), false);
164 assert_eq!( $name(y,0), false);
165 assert_eq!( $name(x,0), false);
166 assert_eq!( $name(x,y), false);
167 $(
168 assert_eq!( $name($shr,$shr), true);
169 assert_eq!( $name($shr,0), false);
170 assert_eq!( $name($shr,$max), false);
171 )*
172 }
173 }
174}
175ct_eq_gen!(ct_u8_eq,u8,MAX_U8,4,2,1;;
176 test_ct_u8_eq, 155, 15);
177ct_eq_gen!(ct_u16_eq,u16,MAX_U16,8,4,2,1;;
178 test_ct_u16_eq, 32000, 5);
179ct_eq_gen!(ct_u32_eq,u32,MAX_U32,16,8,4,2,1;;
180 test_ct_u32_eq, 2000000, 15);
181ct_eq_gen!(ct_u64_eq,u64,MAX_U64,32,16,8,4,2,1;;
182 test_ct_u64_eq, 25893654215879, 2);
183#[cfg(target_pointer_width = "32")]
184ct_eq_gen!(ct_usize_eq,usize,MAX_USIZE,16,8,4,2,1;;
185 test_ct_u32_eq, 2082600, 15);
186#[cfg(target_pointer_width = "64")]
187ct_eq_gen!(ct_usize_eq,usize,MAX_USIZE,32,16,8,4,2,1;;
188 test_ct_usize_eq, 859632175648921456, 5);
189
190macro_rules! ct_eq_slice_gen {
191 ($name:ident,$eq:ident,$code: ty;;$test_name:ident,$max: expr) => {
192 #[no_mangle]
199 pub extern "C" fn $name( x: &[$code], y: &[$code]) -> bool {
200 let x_len = x.len();
201 let y_len = y.len();
202 if x_len != y_len {
203 return false;
204 }
205 let mut flag: $code = 0;
206 for i in 0..x_len {
207 flag |= x[i] ^ y[i];
208 }
209 $eq(flag,0)
210 }
211 #[test]
212 fn $test_name() {
213 let x: [$code;10] = [0,0,0,0,0,0,0,0,0,0];
214 let y: [$code;10] = [$max,$max,$max,$max,$max,$max,$max,$max,$max,$max];
215 let z: [$code;10] = [1,1,1,1,1,1,1,1,1,1];
216 assert_eq!( $name( &x, &x), true);
217 assert_eq!( $name( &y, &y), true);
218 assert_eq!( $name( &z, &z), true);
219 assert_eq!( $name( &x, &y), false);
220 assert_eq!( $name( &x, &y), false);
221 assert_eq!( $name( &y, &z), false);
222 }
223 }
224}
225ct_eq_slice_gen!(ct_u8_slice_eq,ct_u8_eq,u8;;
226 test_ct_u8_slice_eq, MAX_U8);
227ct_eq_slice_gen!(ct_u16_slice_eq,ct_u16_eq,u16;;
228 test_ct_u16_slice_eq, MAX_U16);
229ct_eq_slice_gen!(ct_u32_slice_eq,ct_u32_eq,u32;;
230 test_ct_u32_slice_eq, MAX_U32);
231ct_eq_slice_gen!(ct_u64_slice_eq,ct_u64_eq,u64;;
232 test_ct_u64_slice_eq, MAX_U64);
233ct_eq_slice_gen!(ct_usize_slice_eq,ct_usize_eq,usize;;
234 test_ct_usize_slice_eq, MAX_USIZE);
235
236
237macro_rules! ct_select_gen {
238 ($name:ident,$max:expr,$code:ty;;$test_name:ident,$v0:expr,$v1:expr) => {
239 #[no_mangle]
255 #[inline(never)]
256 pub extern "C" fn $name(flag: bool, x: $code, y: $code) -> $code {
257 let val: u8 = unsafe{trans(flag)};
258 let flag = val as $code;
259 (($max ^ flag.wrapping_sub(1))&x)|(flag.wrapping_sub(1)&y)
260 }
261 #[test]
262 fn $test_name() {
263 assert_eq!( $name(true,$v0,$v1), $v0);
264 assert_eq!( $name(false,$v0,$v1), $v1);
265 assert_eq!( $name(true,$v1,$v0), $v1);
266 assert_eq!( $name(false,$v1,$v0), $v0);
267 assert_eq!( $name(true,$v0,$max), $v0);
268 assert_eq!( $name(false,$v0,$max), $max);
269 assert_eq!( $name(true,$max,$v0), $max);
270 assert_eq!( $name(false,$max,$v0), $v0);
271 assert_eq!( $name(true,$max,$v1), $max);
272 assert_eq!( $name(false,$max,$v1), $v1);
273 assert_eq!( $name(true,$v1,$max), $v1);
274 assert_eq!( $name(false,$v1,$max), $max);
275 }
276 }
277}
278
279ct_select_gen!(ct_select_u8,MAX_U8,u8;;
280 test_ct_select_u8,155,4);
281ct_select_gen!(ct_select_u16,MAX_U16,u16;;
282 test_ct_select_u16,30597,4);
283ct_select_gen!(ct_select_u32,MAX_U32,u32;;
284 test_ct_select_u32,0x0DD74AA2,4);
285ct_select_gen!(ct_select_u64,MAX_U64,u64;;
286 test_ct_select_u64,155,4);
287ct_select_gen!(ct_select_usize,MAX_USIZE,usize;;
288 test_ct_select_usize,155,4);
289
290macro_rules! ct_constant_copy_gen {
291 ($name:ident,$max:expr,$code:ty,$copy_symbol: ident
292 ;;$test_name:ident,$sl_eq:ident,$other_test:ident) => {
293 #[no_mangle]
303 pub extern "C" fn $name(flag: bool, x: &mut [$code], y: &[$code]) {
304 let x_len = x.len();
305 let y_len = y.len();
306 if x_len != y_len {
307 panic!("Consistent Time: Attempted to copy between non-equal lens");
308 }
309 for i in 0..x_len {
310 let y_temp = y[i].clone();
311 let x_temp = x[i].clone();
312 x[i] = $copy_symbol(flag,y_temp,x_temp);
313 }
314 }
315 #[test]
316 fn $test_name() {
317 let base: [$code;10] = [0,0,0,0,0,0,0,0,0,0];
318 let mut x: [$code;10] = [0,0,0,0,0,0,0,0,0,0];
319 let y: [$code;10] = [$max,$max,$max,$max,$max,$max,$max,$max,$max,$max];
320 $name(false,&mut x, &y);
321 assert_eq!( $sl_eq(&x,&base), true);
322 $name(true,&mut x, &y);
323 assert_eq!( $sl_eq(&x,&base), false);
324 assert_eq!( $sl_eq(&x,&y), true);
325 }
326 #[test]
327 #[should_panic]
328 fn $other_test() {
329 let base: [$code;10] = [0,0,0,0,0,0,0,0,0,0];
330 let mut x: [$code;9] = [0,0,0,0,0,0,0,0,0];
331 $name(false,&mut x,&base);
335 }
336 }
337}
338ct_constant_copy_gen!(ct_copy_u8,MAX_U8,u8,ct_select_u8;;
339 test_ct_copy_u8,ct_u8_slice_eq,test_ct_copy_u8_panic);
340ct_constant_copy_gen!(ct_copy_u16,MAX_U16,u16,ct_select_u16;;
341 test_ct_copy_u16,ct_u16_slice_eq,test_ct_copy_u16_panic);
342ct_constant_copy_gen!(ct_copy_u32,MAX_U32,u32,ct_select_u32;;
343 test_ct_copy_u32,ct_u32_slice_eq,test_ct_copy_u32_panic);
344ct_constant_copy_gen!(ct_copy_u64,MAX_U64,u64,ct_select_u64;;
345 test_ct_copy_u64,ct_u64_slice_eq,test_ct_copy_u64_panic);
346ct_constant_copy_gen!(ct_copy_usize,MAX_USIZE,usize,ct_select_usize;;
347 test_ct_copy_usize,ct_usize_slice_eq,test_ct_copy_usize_panic);