From c12f70c20a9665f92793dcfd70d7a6de7d5d3f3c Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Sat, 22 Oct 2022 02:45:44 -0700 Subject: [PATCH 1/3] Sharpen bounds in test_diff We can be much stricter without risking inadvertant failure. Signed-off-by: Joe Richey --- tests/common/mod.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index fecbbdff..9bfc9407 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -12,6 +12,18 @@ fn test_zero() { getrandom_impl(&mut [0u8; 0]).unwrap(); } +// Return the number of bits in which s1 and s2 differ +#[cfg(not(feature = "custom"))] +fn num_diff_bits(s1: &[u8], s2: &[u8]) -> usize { + assert_eq!(s1.len(), s2.len()); + let mut n = 0; + for i in 0..s1.len() { + n += (s1[i] ^ s2[i]).count_ones() as usize; + } + n +} + +// Tests the quality of calling getrandom on two large buffers #[test] #[cfg(not(feature = "custom"))] fn test_diff() { @@ -21,13 +33,11 @@ fn test_diff() { let mut v2 = [0u8; 1000]; getrandom_impl(&mut v2).unwrap(); - let mut n_diff_bits = 0; - for i in 0..v1.len() { - n_diff_bits += (v1[i] ^ v2[i]).count_ones(); - } - - // Check at least 1 bit per byte differs. p(failure) < 1e-1000 with random input. - assert!(n_diff_bits >= v1.len() as u32); + // Between 3.5 and 4.5 bits per byte should differ. Probability of failure: + // ~ 2^(-94) = 2 * CDF[BinomialDistribution[8000, 0.5], 3500] + let d = num_diff_bits(&v1, &v2); + assert!(d > 3500); + assert!(d < 4500); } #[test] From c83edb650b5a8a9e13c2ae4bae292982e64bf448 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Sat, 22 Oct 2022 03:05:40 -0700 Subject: [PATCH 2/3] Add quality tests for calling getrandom on small buffers Signed-off-by: Joe Richey --- tests/common/mod.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 9bfc9407..839c8eb5 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -40,6 +40,30 @@ fn test_diff() { assert!(d < 4500); } +// Tests the quality of calling getrandom repeatedly on small buffers +#[test] +#[cfg(not(feature = "custom"))] +fn test_small() { + // For each buffer size, get at least 256 bytes and check that between + // 3 and 5 bits per byte differ. Probability of failure: + // ~ 2^(-91) = 64 * 2 * CDF[BinomialDistribution[8*256, 0.5], 3*256] + for size in 1..=64 { + let mut num_bytes = 0; + let mut diff_bits = 0; + while num_bytes < 256 { + let mut s1 = vec![0u8; size]; + getrandom_impl(&mut s1).unwrap(); + let mut s2 = vec![0u8; size]; + getrandom_impl(&mut s2).unwrap(); + + num_bytes += size; + diff_bits += num_diff_bits(&s1, &s2); + } + assert!(diff_bits > 3 * num_bytes); + assert!(diff_bits < 5 * num_bytes); + } +} + #[test] fn test_huge() { let mut huge = [0u8; 100_000]; From b893cb9c778638844e6a1d9f2b185f7ed4b9ee70 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Sat, 22 Oct 2022 13:52:42 -0700 Subject: [PATCH 3/3] Use iterators for num_diff_bits Signed-off-by: Joe Richey --- tests/common/mod.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 839c8eb5..666f7f57 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -16,11 +16,10 @@ fn test_zero() { #[cfg(not(feature = "custom"))] fn num_diff_bits(s1: &[u8], s2: &[u8]) -> usize { assert_eq!(s1.len(), s2.len()); - let mut n = 0; - for i in 0..s1.len() { - n += (s1[i] ^ s2[i]).count_ones() as usize; - } - n + s1.iter() + .zip(s2.iter()) + .map(|(a, b)| (a ^ b).count_ones() as usize) + .sum() } // Tests the quality of calling getrandom on two large buffers