literate-crypto 0.0.3

Literate Cryptography by 12hbender
Documentation
use {
    super::fortuna::NoEntropy,
    crate::{shuffle, uniform_random, util::CollectVec, Aes256, Fortuna, Sha256},
    std::{collections::HashSet, ops::Range},
};

/// Test that outputs generated by [`uniform_random`] are within the requested
/// range.
#[test]
fn random_within_range() {
    let rng = Fortuna::new(NoEntropy, Aes256::default(), Sha256::default()).unwrap();
    let mut iter = rng.into_iter();
    test_range(&mut iter, 0..1);
    test_range(&mut iter, 0..2);
    test_range(&mut iter, 5..50);
}

/// Test that outputs generated by [`uniform_random`] are within the requested
/// range.
#[test]
fn random_empty_range_returns_zero() {
    let rng = Fortuna::new(NoEntropy, Aes256::default(), Sha256::default()).unwrap();
    let mut iter = rng.into_iter();
    let draw = uniform_random(&mut iter, 0..0);
    assert_eq!(draw, 0);
}

/// Assert that shuffling a slice contains the exact same elements, but in a
/// different order.
#[test]
fn random_shuffle() {
    let rng = Fortuna::new(NoEntropy, Aes256::default(), Sha256::default()).unwrap();
    let mut iter = rng.into_iter();

    let original = (0..100).collect_vec();
    let mut shuffled = original.clone();

    shuffle(&mut iter, &mut shuffled);

    // The chance that the order is not changed after shuffling is negligible.
    assert_ne!(original, shuffled);

    // The slices should still contain the same elements.
    assert!(original.iter().all(|x| shuffled.contains(x)));
    assert!(shuffled.iter().all(|x| original.contains(x)));
}

fn test_range(iter: &mut impl Iterator<Item = u8>, range: Range<u32>) {
    let mut draws = HashSet::new();
    for _ in 0..100 {
        let draw = uniform_random(iter, range.clone());
        draws.insert(draw);
        assert!(range.contains(&draw));
    }

    if range.len() > 1 {
        // The chance that all of the iterations above returned the same value is
        // negligible. Ensure that different random values are being returned.
        assert!(draws.len() > 1);
    }
}