Bug 1826304: Update libprio-rs to 0.12.0. r=emilio,glandium,supply-chain-reviewers
[gecko.git] / third_party / rust / subtle / tests / mod.rs
blobf6b3982e025fc19c3ce8ee1e2d8ea2a72e62db31
1 use std::cmp;
3 use rand::rngs::OsRng;
4 use rand::RngCore;
6 use subtle::*;
8 #[test]
9 #[should_panic]
10 fn slices_equal_different_lengths() {
11     let a: [u8; 3] = [0, 0, 0];
12     let b: [u8; 4] = [0, 0, 0, 0];
14     assert_eq!((&a).ct_eq(&b).unwrap_u8(), 1);
17 #[test]
18 fn slices_equal() {
19     let a: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
20     let b: [u8; 8] = [1, 2, 3, 4, 4, 3, 2, 1];
22     let a_eq_a = (&a).ct_eq(&a);
23     let a_eq_b = (&a).ct_eq(&b);
25     assert_eq!(a_eq_a.unwrap_u8(), 1);
26     assert_eq!(a_eq_b.unwrap_u8(), 0);
28     let c: [u8; 16] = [0u8; 16];
30     let a_eq_c = (&a).ct_eq(&c);
31     assert_eq!(a_eq_c.unwrap_u8(), 0);
34 #[test]
35 fn conditional_assign_i32() {
36     let mut a: i32 = 5;
37     let b: i32 = 13;
39     a.conditional_assign(&b, 0.into());
40     assert_eq!(a, 5);
41     a.conditional_assign(&b, 1.into());
42     assert_eq!(a, 13);
45 #[test]
46 fn conditional_assign_i64() {
47     let mut c: i64 = 2343249123;
48     let d: i64 = 8723884895;
50     c.conditional_assign(&d, 0.into());
51     assert_eq!(c, 2343249123);
52     c.conditional_assign(&d, 1.into());
53     assert_eq!(c, 8723884895);
56 macro_rules! generate_integer_conditional_select_tests {
57     ($($t:ty)*) => ($(
58         let x: $t = 0;  // all 0 bits
59         let y: $t = !0; // all 1 bits
61         assert_eq!(<$t>::conditional_select(&x, &y, 0.into()), 0);
62         assert_eq!(<$t>::conditional_select(&x, &y, 1.into()), y);
64         let mut z = x;
65         let mut w = y;
67         <$t>::conditional_swap(&mut z, &mut w, 0.into());
68         assert_eq!(z, x);
69         assert_eq!(w, y);
70         <$t>::conditional_swap(&mut z, &mut w, 1.into());
71         assert_eq!(z, y);
72         assert_eq!(w, x);
74         z.conditional_assign(&x, 1.into());
75         w.conditional_assign(&y, 0.into());
76         assert_eq!(z, x);
77         assert_eq!(w, x);
78     )*)
81 #[test]
82 fn integer_conditional_select() {
83     generate_integer_conditional_select_tests!(u8 u16 u32 u64);
84     generate_integer_conditional_select_tests!(i8 i16 i32 i64);
85     #[cfg(feature = "i128")]
86     generate_integer_conditional_select_tests!(i128 u128);
89 #[test]
90 fn custom_conditional_select_i16() {
91     let x: i16 = 257;
92     let y: i16 = 514;
94     assert_eq!(i16::conditional_select(&x, &y, 0.into()), 257);
95     assert_eq!(i16::conditional_select(&x, &y, 1.into()), 514);
98 #[test]
99 fn ordering_conditional_select() {
100     assert_eq!(
101         cmp::Ordering::conditional_select(&cmp::Ordering::Less, &cmp::Ordering::Greater, 0.into()),
102         cmp::Ordering::Less
103     );
105     assert_eq!(
106         cmp::Ordering::conditional_select(&cmp::Ordering::Less, &cmp::Ordering::Greater, 1.into()),
107         cmp::Ordering::Greater
108     );
111 macro_rules! generate_integer_equal_tests {
112     ($($t:ty),*) => ($(
113         let y: $t = 0;  // all 0 bits
114         let z: $t = !0; // all 1 bits
116         let x = z;
118         assert_eq!(x.ct_eq(&y).unwrap_u8(), 0);
119         assert_eq!(x.ct_eq(&z).unwrap_u8(), 1);
120         assert_eq!(x.ct_ne(&y).unwrap_u8(), 1);
121         assert_eq!(x.ct_ne(&z).unwrap_u8(), 0);
122     )*)
125 #[test]
126 fn integer_equal() {
127     generate_integer_equal_tests!(u8, u16, u32, u64);
128     generate_integer_equal_tests!(i8, i16, i32, i64);
129     #[cfg(feature = "i128")]
130     generate_integer_equal_tests!(i128, u128);
131     generate_integer_equal_tests!(isize, usize);
134 #[test]
135 fn choice_into_bool() {
136     let choice_true: bool = Choice::from(1).into();
138     assert!(choice_true);
140     let choice_false: bool = Choice::from(0).into();
142     assert!(!choice_false);
145 #[test]
146 fn conditional_select_choice() {
147     let t = Choice::from(1);
148     let f = Choice::from(0);
150     assert_eq!(bool::from(Choice::conditional_select(&t, &f, f)), true);
151     assert_eq!(bool::from(Choice::conditional_select(&t, &f, t)), false);
152     assert_eq!(bool::from(Choice::conditional_select(&f, &t, f)), false);
153     assert_eq!(bool::from(Choice::conditional_select(&f, &t, t)), true);
156 #[test]
157 fn choice_equal() {
158     assert!(Choice::from(0).ct_eq(&Choice::from(0)).unwrap_u8() == 1);
159     assert!(Choice::from(0).ct_eq(&Choice::from(1)).unwrap_u8() == 0);
160     assert!(Choice::from(1).ct_eq(&Choice::from(0)).unwrap_u8() == 0);
161     assert!(Choice::from(1).ct_eq(&Choice::from(1)).unwrap_u8() == 1);
164 #[test]
165 fn ordering_equal() {
166     let a = cmp::Ordering::Equal;
167     let b = cmp::Ordering::Greater;
168     let c = a;
170     assert_eq!(a.ct_eq(&b).unwrap_u8(), 0);
171     assert_eq!(a.ct_eq(&c).unwrap_u8(), 1);
174 #[test]
175 fn test_ctoption() {
176     let a = CtOption::new(10, Choice::from(1));
177     let b = CtOption::new(9, Choice::from(1));
178     let c = CtOption::new(10, Choice::from(0));
179     let d = CtOption::new(9, Choice::from(0));
181     // Test is_some / is_none
182     assert!(bool::from(a.is_some()));
183     assert!(bool::from(!a.is_none()));
184     assert!(bool::from(b.is_some()));
185     assert!(bool::from(!b.is_none()));
186     assert!(bool::from(!c.is_some()));
187     assert!(bool::from(c.is_none()));
188     assert!(bool::from(!d.is_some()));
189     assert!(bool::from(d.is_none()));
191     // Test unwrap for Some
192     assert_eq!(a.unwrap(), 10);
193     assert_eq!(b.unwrap(), 9);
195     // Test equality
196     assert!(bool::from(a.ct_eq(&a)));
197     assert!(bool::from(!a.ct_eq(&b)));
198     assert!(bool::from(!a.ct_eq(&c)));
199     assert!(bool::from(!a.ct_eq(&d)));
201     // Test equality of None with different
202     // dummy value
203     assert!(bool::from(c.ct_eq(&d)));
205     // Test unwrap_or
206     assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or(2), 1);
207     assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or(2), 2);
209     // Test unwrap_or_else
210     assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or_else(|| 2), 1);
211     assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or_else(|| 2), 2);
213     // Test map
214     assert_eq!(
215         CtOption::new(1, Choice::from(1))
216             .map(|v| {
217                 assert_eq!(v, 1);
218                 2
219             })
220             .unwrap(),
221         2
222     );
223     assert_eq!(
224         CtOption::new(1, Choice::from(0))
225             .map(|_| 2)
226             .is_none()
227             .unwrap_u8(),
228         1
229     );
231     // Test and_then
232     assert_eq!(
233         CtOption::new(1, Choice::from(1))
234             .and_then(|v| {
235                 assert_eq!(v, 1);
236                 CtOption::new(2, Choice::from(0))
237             })
238             .is_none()
239             .unwrap_u8(),
240         1
241     );
242     assert_eq!(
243         CtOption::new(1, Choice::from(1))
244             .and_then(|v| {
245                 assert_eq!(v, 1);
246                 CtOption::new(2, Choice::from(1))
247             })
248             .unwrap(),
249         2
250     );
252     assert_eq!(
253         CtOption::new(1, Choice::from(0))
254             .and_then(|_| CtOption::new(2, Choice::from(0)))
255             .is_none()
256             .unwrap_u8(),
257         1
258     );
259     assert_eq!(
260         CtOption::new(1, Choice::from(0))
261             .and_then(|_| CtOption::new(2, Choice::from(1)))
262             .is_none()
263             .unwrap_u8(),
264         1
265     );
267     // Test or_else
268     assert_eq!(
269         CtOption::new(1, Choice::from(0))
270             .or_else(|| CtOption::new(2, Choice::from(1)))
271             .unwrap(),
272         2
273     );
274     assert_eq!(
275         CtOption::new(1, Choice::from(1))
276             .or_else(|| CtOption::new(2, Choice::from(0)))
277             .unwrap(),
278         1
279     );
280     assert_eq!(
281         CtOption::new(1, Choice::from(1))
282             .or_else(|| CtOption::new(2, Choice::from(1)))
283             .unwrap(),
284         1
285     );
286     assert!(bool::from(
287         CtOption::new(1, Choice::from(0))
288             .or_else(|| CtOption::new(2, Choice::from(0)))
289             .is_none()
290     ));
292     // Test (in)equality
293     assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 0);
294     assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 0);
295     assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
296     assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 0);
297     assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 1);
298     assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 1);
299     assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
300     assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
301     assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1);
302     assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1);
305 #[test]
306 #[should_panic]
307 fn unwrap_none_ctoption() {
308     // This test might fail (in release mode?) if the
309     // compiler decides to optimize it away.
310     CtOption::new(10, Choice::from(0)).unwrap();
313 macro_rules! generate_greater_than_test {
314     ($ty: ty) => {
315         for _ in 0..100 {
316             let x = OsRng.next_u64() as $ty;
317             let y = OsRng.next_u64() as $ty;
318             let z = x.ct_gt(&y);
320             println!("x={}, y={}, z={:?}", x, y, z);
322             if x < y {
323                 assert!(z.unwrap_u8() == 0);
324             } else if x == y {
325                 assert!(z.unwrap_u8() == 0);
326             } else if x > y {
327                 assert!(z.unwrap_u8() == 1);
328             }
329         }
330     }
333 #[test]
334 fn greater_than_u8() {
335     generate_greater_than_test!(u8);
338 #[test]
339 fn greater_than_u16() {
340     generate_greater_than_test!(u16);
343 #[test]
344 fn greater_than_u32() {
345     generate_greater_than_test!(u32);
348 #[test]
349 fn greater_than_u64() {
350     generate_greater_than_test!(u64);
353 #[cfg(feature = "i128")]
354 #[test]
355 fn greater_than_u128() {
356     generate_greater_than_test!(u128);
359 #[test]
360 fn greater_than_ordering() {
361     assert_eq!(cmp::Ordering::Less.ct_gt(&cmp::Ordering::Greater).unwrap_u8(), 0);
362     assert_eq!(cmp::Ordering::Greater.ct_gt(&cmp::Ordering::Less).unwrap_u8(), 1);
365 #[test]
366 /// Test that the two's compliment min and max, i.e. 0000...0001 < 1111...1110,
367 /// gives the correct result. (This fails using the bit-twiddling algorithm that
368 /// go/crypto/subtle uses.)
369 fn less_than_twos_compliment_minmax() {
370     let z = 1u32.ct_lt(&(2u32.pow(31)-1));
372     assert!(z.unwrap_u8() == 1);
375 macro_rules! generate_less_than_test {
376     ($ty: ty) => {
377         for _ in 0..100 {
378             let x = OsRng.next_u64() as $ty;
379             let y = OsRng.next_u64() as $ty;
380             let z = x.ct_gt(&y);
382             println!("x={}, y={}, z={:?}", x, y, z);
384             if x < y {
385                 assert!(z.unwrap_u8() == 0);
386             } else if x == y {
387                 assert!(z.unwrap_u8() == 0);
388             } else if x > y {
389                 assert!(z.unwrap_u8() == 1);
390             }
391         }
392     }
395 #[test]
396 fn less_than_u8() {
397     generate_less_than_test!(u8);
400 #[test]
401 fn less_than_u16() {
402     generate_less_than_test!(u16);
405 #[test]
406 fn less_than_u32() {
407     generate_less_than_test!(u32);
410 #[test]
411 fn less_than_u64() {
412     generate_less_than_test!(u64);
415 #[cfg(feature = "i128")]
416 #[test]
417 fn less_than_u128() {
418     generate_less_than_test!(u128);
421 #[test]
422 fn less_than_ordering() {
423     assert_eq!(cmp::Ordering::Greater.ct_lt(&cmp::Ordering::Less).unwrap_u8(), 0);
424     assert_eq!(cmp::Ordering::Less.ct_lt(&cmp::Ordering::Greater).unwrap_u8(), 1);