From 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:41:41 +0200 Subject: Merging upstream version 1.70.0+dfsg2. Signed-off-by: Daniel Baumann --- vendor/subtle/tests/mod.rs | 389 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 vendor/subtle/tests/mod.rs (limited to 'vendor/subtle/tests') diff --git a/vendor/subtle/tests/mod.rs b/vendor/subtle/tests/mod.rs new file mode 100644 index 000000000..eaa98a460 --- /dev/null +++ b/vendor/subtle/tests/mod.rs @@ -0,0 +1,389 @@ +extern crate rand; +extern crate subtle; + +use rand::rngs::OsRng; +use rand::RngCore; + +use subtle::*; + +#[test] +#[should_panic] +fn slices_equal_different_lengths() { + let a: [u8; 3] = [0, 0, 0]; + let b: [u8; 4] = [0, 0, 0, 0]; + + assert_eq!((&a).ct_eq(&b).unwrap_u8(), 1); +} + +#[test] +fn slices_equal() { + let a: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; + let b: [u8; 8] = [1, 2, 3, 4, 4, 3, 2, 1]; + + let a_eq_a = (&a).ct_eq(&a); + let a_eq_b = (&a).ct_eq(&b); + + assert_eq!(a_eq_a.unwrap_u8(), 1); + assert_eq!(a_eq_b.unwrap_u8(), 0); + + let c: [u8; 16] = [0u8; 16]; + + let a_eq_c = (&a).ct_eq(&c); + assert_eq!(a_eq_c.unwrap_u8(), 0); +} + +#[test] +fn conditional_assign_i32() { + let mut a: i32 = 5; + let b: i32 = 13; + + a.conditional_assign(&b, 0.into()); + assert_eq!(a, 5); + a.conditional_assign(&b, 1.into()); + assert_eq!(a, 13); +} + +#[test] +fn conditional_assign_i64() { + let mut c: i64 = 2343249123; + let d: i64 = 8723884895; + + c.conditional_assign(&d, 0.into()); + assert_eq!(c, 2343249123); + c.conditional_assign(&d, 1.into()); + assert_eq!(c, 8723884895); +} + +macro_rules! generate_integer_conditional_select_tests { + ($($t:ty)*) => ($( + let x: $t = 0; // all 0 bits + let y: $t = !0; // all 1 bits + + assert_eq!(<$t>::conditional_select(&x, &y, 0.into()), 0); + assert_eq!(<$t>::conditional_select(&x, &y, 1.into()), y); + + let mut z = x; + let mut w = y; + + <$t>::conditional_swap(&mut z, &mut w, 0.into()); + assert_eq!(z, x); + assert_eq!(w, y); + <$t>::conditional_swap(&mut z, &mut w, 1.into()); + assert_eq!(z, y); + assert_eq!(w, x); + + z.conditional_assign(&x, 1.into()); + w.conditional_assign(&y, 0.into()); + assert_eq!(z, x); + assert_eq!(w, x); + )*) +} + +#[test] +fn integer_conditional_select() { + generate_integer_conditional_select_tests!(u8 u16 u32 u64); + generate_integer_conditional_select_tests!(i8 i16 i32 i64); + #[cfg(feature = "i128")] + generate_integer_conditional_select_tests!(i128 u128); +} + +#[test] +fn custom_conditional_select_i16() { + let x: i16 = 257; + let y: i16 = 514; + + assert_eq!(i16::conditional_select(&x, &y, 0.into()), 257); + assert_eq!(i16::conditional_select(&x, &y, 1.into()), 514); +} + +macro_rules! generate_integer_equal_tests { + ($($t:ty),*) => ($( + let y: $t = 0; // all 0 bits + let z: $t = !0; // all 1 bits + + let x = z; + + assert_eq!(x.ct_eq(&y).unwrap_u8(), 0); + assert_eq!(x.ct_eq(&z).unwrap_u8(), 1); + )*) +} + +#[test] +fn integer_equal() { + generate_integer_equal_tests!(u8, u16, u32, u64); + generate_integer_equal_tests!(i8, i16, i32, i64); + #[cfg(feature = "i128")] + generate_integer_equal_tests!(i128, u128); + generate_integer_equal_tests!(isize, usize); +} + +#[test] +fn choice_into_bool() { + let choice_true: bool = Choice::from(1).into(); + + assert!(choice_true); + + let choice_false: bool = Choice::from(0).into(); + + assert!(!choice_false); +} + +#[test] +fn conditional_select_choice() { + let t = Choice::from(1); + let f = Choice::from(0); + + assert_eq!(bool::from(Choice::conditional_select(&t, &f, f)), true); + assert_eq!(bool::from(Choice::conditional_select(&t, &f, t)), false); + assert_eq!(bool::from(Choice::conditional_select(&f, &t, f)), false); + assert_eq!(bool::from(Choice::conditional_select(&f, &t, t)), true); +} + +#[test] +fn choice_equal() { + assert!(Choice::from(0).ct_eq(&Choice::from(0)).unwrap_u8() == 1); + assert!(Choice::from(0).ct_eq(&Choice::from(1)).unwrap_u8() == 0); + assert!(Choice::from(1).ct_eq(&Choice::from(0)).unwrap_u8() == 0); + assert!(Choice::from(1).ct_eq(&Choice::from(1)).unwrap_u8() == 1); +} + +#[test] +fn test_ctoption() { + let a = CtOption::new(10, Choice::from(1)); + let b = CtOption::new(9, Choice::from(1)); + let c = CtOption::new(10, Choice::from(0)); + let d = CtOption::new(9, Choice::from(0)); + + // Test is_some / is_none + assert!(bool::from(a.is_some())); + assert!(bool::from(!a.is_none())); + assert!(bool::from(b.is_some())); + assert!(bool::from(!b.is_none())); + assert!(bool::from(!c.is_some())); + assert!(bool::from(c.is_none())); + assert!(bool::from(!d.is_some())); + assert!(bool::from(d.is_none())); + + // Test unwrap for Some + assert_eq!(a.unwrap(), 10); + assert_eq!(b.unwrap(), 9); + + // Test equality + assert!(bool::from(a.ct_eq(&a))); + assert!(bool::from(!a.ct_eq(&b))); + assert!(bool::from(!a.ct_eq(&c))); + assert!(bool::from(!a.ct_eq(&d))); + + // Test equality of None with different + // dummy value + assert!(bool::from(c.ct_eq(&d))); + + // Test unwrap_or + assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or(2), 1); + assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or(2), 2); + + // Test unwrap_or_else + assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or_else(|| 2), 1); + assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or_else(|| 2), 2); + + // Test map + assert_eq!( + CtOption::new(1, Choice::from(1)) + .map(|v| { + assert_eq!(v, 1); + 2 + }) + .unwrap(), + 2 + ); + assert_eq!( + CtOption::new(1, Choice::from(0)) + .map(|_| 2) + .is_none() + .unwrap_u8(), + 1 + ); + + // Test and_then + assert_eq!( + CtOption::new(1, Choice::from(1)) + .and_then(|v| { + assert_eq!(v, 1); + CtOption::new(2, Choice::from(0)) + }) + .is_none() + .unwrap_u8(), + 1 + ); + assert_eq!( + CtOption::new(1, Choice::from(1)) + .and_then(|v| { + assert_eq!(v, 1); + CtOption::new(2, Choice::from(1)) + }) + .unwrap(), + 2 + ); + + assert_eq!( + CtOption::new(1, Choice::from(0)) + .and_then(|_| CtOption::new(2, Choice::from(0))) + .is_none() + .unwrap_u8(), + 1 + ); + assert_eq!( + CtOption::new(1, Choice::from(0)) + .and_then(|_| CtOption::new(2, Choice::from(1))) + .is_none() + .unwrap_u8(), + 1 + ); + + // Test or_else + assert_eq!( + CtOption::new(1, Choice::from(0)) + .or_else(|| CtOption::new(2, Choice::from(1))) + .unwrap(), + 2 + ); + assert_eq!( + CtOption::new(1, Choice::from(1)) + .or_else(|| CtOption::new(2, Choice::from(0))) + .unwrap(), + 1 + ); + assert_eq!( + CtOption::new(1, Choice::from(1)) + .or_else(|| CtOption::new(2, Choice::from(1))) + .unwrap(), + 1 + ); + assert!(bool::from( + CtOption::new(1, Choice::from(0)) + .or_else(|| CtOption::new(2, Choice::from(0))) + .is_none() + )); + + // Test (in)equality + assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 0); + assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 0); + assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0); + assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 0); + assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 1); + assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 1); + assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0); + assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0); + assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1); + assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1); +} + +#[test] +#[should_panic] +fn unwrap_none_ctoption() { + // This test might fail (in release mode?) if the + // compiler decides to optimize it away. + CtOption::new(10, Choice::from(0)).unwrap(); +} + +macro_rules! generate_greater_than_test { + ($ty: ty) => { + for _ in 0..100 { + let x = OsRng.next_u64() as $ty; + let y = OsRng.next_u64() as $ty; + let z = x.ct_gt(&y); + + println!("x={}, y={}, z={:?}", x, y, z); + + if x < y { + assert!(z.unwrap_u8() == 0); + } else if x == y { + assert!(z.unwrap_u8() == 0); + } else if x > y { + assert!(z.unwrap_u8() == 1); + } + } + } +} + +#[test] +fn greater_than_u8() { + generate_greater_than_test!(u8); +} + +#[test] +fn greater_than_u16() { + generate_greater_than_test!(u16); +} + +#[test] +fn greater_than_u32() { + generate_greater_than_test!(u32); +} + +#[test] +fn greater_than_u64() { + generate_greater_than_test!(u64); +} + +#[cfg(feature = "i128")] +#[test] +fn greater_than_u128() { + generate_greater_than_test!(u128); +} + +#[test] +/// Test that the two's compliment min and max, i.e. 0000...0001 < 1111...1110, +/// gives the correct result. (This fails using the bit-twiddling algorithm that +/// go/crypto/subtle uses.) +fn less_than_twos_compliment_minmax() { + let z = 1u32.ct_lt(&(2u32.pow(31)-1)); + + assert!(z.unwrap_u8() == 1); +} + +macro_rules! generate_less_than_test { + ($ty: ty) => { + for _ in 0..100 { + let x = OsRng.next_u64() as $ty; + let y = OsRng.next_u64() as $ty; + let z = x.ct_gt(&y); + + println!("x={}, y={}, z={:?}", x, y, z); + + if x < y { + assert!(z.unwrap_u8() == 0); + } else if x == y { + assert!(z.unwrap_u8() == 0); + } else if x > y { + assert!(z.unwrap_u8() == 1); + } + } + } +} + +#[test] +fn less_than_u8() { + generate_less_than_test!(u8); +} + +#[test] +fn less_than_u16() { + generate_less_than_test!(u16); +} + +#[test] +fn less_than_u32() { + generate_less_than_test!(u32); +} + +#[test] +fn less_than_u64() { + generate_less_than_test!(u64); +} + +#[cfg(feature = "i128")] +#[test] +fn less_than_u128() { + generate_less_than_test!(u128); +} -- cgit v1.2.3