#![cfg(feature = "rand")] extern crate num_bigint_dig as num_bigint; extern crate num_traits; extern crate rand; extern crate rand_chacha; extern crate rand_isaac; extern crate rand_xorshift; mod biguint { use num_bigint::{BigUint, RandBigInt, RandomBits}; use num_traits::Zero; use rand::distributions::Uniform; use rand::{Rng, SeedableRng}; #[cfg(feature = "std")] fn thread_rng() -> impl Rng { rand::thread_rng() } #[cfg(not(feature = "std"))] fn thread_rng() -> impl Rng { // Chosen by fair dice roll rand::rngs::StdRng::seed_from_u64(4) } #[test] fn test_rand() { let mut rng = thread_rng(); let n: BigUint = rng.gen_biguint(137); assert!(n.bits() <= 137); assert!(rng.gen_biguint(0).is_zero()); } #[test] fn test_rand_bits() { let mut rng = thread_rng(); let n: BigUint = rng.sample(&RandomBits::new(137)); assert!(n.bits() <= 137); let z: BigUint = rng.sample(&RandomBits::new(0)); assert!(z.is_zero()); } #[test] fn test_rand_range() { let mut rng = thread_rng(); for _ in 0..10 { assert_eq!( rng.gen_biguint_range(&BigUint::from(236u32), &BigUint::from(237u32)), BigUint::from(236u32) ); } let l = BigUint::from(403469000u32 + 2352); let u = BigUint::from(403469000u32 + 3513); for _ in 0..1000 { let n: BigUint = rng.gen_biguint_below(&u); assert!(n < u); let n: BigUint = rng.gen_biguint_range(&l, &u); assert!(n >= l); assert!(n < u); } } #[test] #[should_panic] fn test_zero_rand_range() { thread_rng().gen_biguint_range(&BigUint::from(54u32), &BigUint::from(54u32)); } #[test] #[should_panic] fn test_negative_rand_range() { let mut rng = thread_rng(); let l = BigUint::from(2352u32); let u = BigUint::from(3513u32); // Switching u and l should fail: let _n: BigUint = rng.gen_biguint_range(&u, &l); } #[test] fn test_rand_uniform() { let mut rng = thread_rng(); let tiny = Uniform::new(BigUint::from(236u32), BigUint::from(237u32)); for _ in 0..10 { assert_eq!(rng.sample(&tiny), BigUint::from(236u32)); } let l = BigUint::from(403469000u32 + 2352); let u = BigUint::from(403469000u32 + 3513); let below = Uniform::new(BigUint::zero(), u.clone()); let range = Uniform::new(l.clone(), u.clone()); for _ in 0..1000 { let n: BigUint = rng.sample(&below); assert!(n < u); let n: BigUint = rng.sample(&range); assert!(n >= l); assert!(n < u); } } fn seeded_value_stability(expected: &[&str]) { let mut seed = ::default(); for (i, x) in seed.as_mut().iter_mut().enumerate() { *x = (i as u8).wrapping_mul(191); } let mut rng = R::from_seed(seed); for (i, &s) in expected.iter().enumerate() { let n: BigUint = s.parse().unwrap(); let r = rng.gen_biguint((1 << i) + i); assert_eq!(n, r, "expected {}, got {}", n, r); } } #[cfg(not(feature = "u64_digit"))] const EXPECTED_CHACHA: &[&str] = &[ "0", "0", "52", "84", "23780", "86502865016", "187057847319509867386", "34045731223080904464438757488196244981910", "23813754422987836414755953516143692594193066497413249270287126597896871975915808", "57401636903146945411652549098818446911814352529449356393690984105383482703074355\ 67088360974672291353736011718191813678720755501317478656550386324355699624671", ]; #[cfg(feature = "u64_digit")] const EXPECTED_CHACHA: &[&str] = &[ "0", "0", "8", "1861", "172076", "5194801951", "259202797457072892019", "2806086822955830608275100562233284760859", "28771276448190704455825316568337256462972770861366848469339788407170414346460023", "501572804396703231264118826164515310701005506447150057229826006447721882571235378\ 4765127362270091441643338804096337494157874113908470083557122824480944132407", ]; #[test] fn test_chacha_value_stability() { use rand_chacha::ChaChaRng; seeded_value_stability::(EXPECTED_CHACHA); } #[cfg(not(feature = "u64_digit"))] const EXPECTED_ISAAC: &[&str] = &[ "1", "4", "3", "649", "89116", "7730042024", "20773149082453254949", "35999009049239918667571895439206839620281", "10191757312714088681302309313551624007714035309632506837271600807524767413673006", "37805949268912387809989378008822038725134260145886913321084097194957861133272558\ 43458183365174899239251448892645546322463253898288141861183340823194379722556", ]; #[cfg(feature = "u64_digit")] const EXPECTED_ISAAC: &[&str] = &[ "1", "2", "51", "1198", "29707", "35688018574", "365090200586541225112", "14051533166427520604648370582738617763816", "26319846996091585801307964353534339679417889504909644767909019559631059772127122", "14567336733062747693583250833667292276083519237160662196899060257293814346680656\ 30951609693408423310563908301065751714778956255122249041917698392245727713420", ]; #[test] fn test_isaac_value_stability() { use rand_isaac::IsaacRng; seeded_value_stability::(EXPECTED_ISAAC); } #[cfg(not(feature = "u64_digit"))] const EXPECTED_XOR: &[&str] = &[ "1", "0", "37", "395", "181116", "122718231117", "1068467172329355695001", "28246925743544411614293300167064395633287", "12750053187017853048648861493745244146555950255549630854523304068318587267293038", "53041498719137109355568081064978196049094604705283682101683207799515709404788873\ 53417136457745727045473194367732849819278740266658219147356315674940229288531", ]; #[cfg(feature = "u64_digit")] const EXPECTED_XOR: &[&str] = &[ "0", "1", "36", "970", "940965", "61158366130", "590484965100191554896", "34050066418951688801044382442803594076612", "29147581645599998811521651062569705291155276949983132826461704326818089074318948", "4990842894093964353439376569956547459232523176881032246435842690389845516810345611554402412893818283310117202233021355634125020654279500443420515862554775828", ]; #[test] fn test_xorshift_value_stability() { use rand_xorshift::XorShiftRng; seeded_value_stability::(EXPECTED_XOR); } } mod bigint { use num_bigint::{BigInt, RandBigInt, RandomBits}; use num_traits::Zero; use rand::distributions::Uniform; use rand::{Rng, SeedableRng}; #[cfg(feature = "std")] fn thread_rng() -> impl Rng { rand::thread_rng() } #[cfg(not(feature = "std"))] fn thread_rng() -> impl Rng { // Chosen by fair dice roll rand::rngs::StdRng::seed_from_u64(4) } #[test] fn test_rand() { let mut rng = thread_rng(); let n: BigInt = rng.gen_bigint(137); assert!(n.bits() <= 137); assert!(rng.gen_bigint(0).is_zero()); } #[test] fn test_rand_bits() { let mut rng = thread_rng(); let n: BigInt = rng.sample(&RandomBits::new(137)); assert!(n.bits() <= 137); let z: BigInt = rng.sample(&RandomBits::new(0)); assert!(z.is_zero()); } #[test] fn test_rand_range() { let mut rng = thread_rng(); for _ in 0..10 { assert_eq!( rng.gen_bigint_range(&BigInt::from(236), &BigInt::from(237)), BigInt::from(236) ); } fn check(l: BigInt, u: BigInt) { let mut rng = thread_rng(); for _ in 0..1000 { let n: BigInt = rng.gen_bigint_range(&l, &u); assert!(n >= l); assert!(n < u); } } let l: BigInt = BigInt::from(403469000 + 2352); let u: BigInt = BigInt::from(403469000 + 3513); check(l.clone(), u.clone()); check(-l.clone(), u.clone()); check(-u.clone(), -l.clone()); } #[test] #[should_panic] fn test_zero_rand_range() { thread_rng().gen_bigint_range(&BigInt::from(54), &BigInt::from(54)); } #[test] #[should_panic] fn test_negative_rand_range() { let mut rng = thread_rng(); let l = BigInt::from(2352); let u = BigInt::from(3513); // Switching u and l should fail: let _n: BigInt = rng.gen_bigint_range(&u, &l); } #[test] fn test_rand_uniform() { let mut rng = thread_rng(); let tiny = Uniform::new(BigInt::from(236u32), BigInt::from(237u32)); for _ in 0..10 { assert_eq!(rng.sample(&tiny), BigInt::from(236u32)); } fn check(l: BigInt, u: BigInt) { let mut rng = thread_rng(); let range = Uniform::new(l.clone(), u.clone()); for _ in 0..1000 { let n: BigInt = rng.sample(&range); assert!(n >= l); assert!(n < u); } } let l: BigInt = BigInt::from(403469000 + 2352); let u: BigInt = BigInt::from(403469000 + 3513); check(l.clone(), u.clone()); check(-l.clone(), u.clone()); check(-u.clone(), -l.clone()); } fn seeded_value_stability(expected: &[&str]) { let mut seed = ::default(); for (i, x) in seed.as_mut().iter_mut().enumerate() { *x = (i as u8).wrapping_mul(191); } let mut rng = R::from_seed(seed); for (i, &s) in expected.iter().enumerate() { let n: BigInt = s.parse().unwrap(); let r = rng.gen_bigint((1 << i) + i); assert_eq!(n, r, "expected {}, got {}", n, r); } } #[cfg(not(feature = "u64_digit"))] const EXPECTED_CHACHA: &[&str] = &[ "0", "-6", "-1", "1321", "-147247", "8486373526", "-272736656290199720696", "2731152629387534140535423510744221288522", "-28820024790651190394679732038637785320661450462089347915910979466834461433196572", "501454570554170484799723603981439288209930393334472085317977614690773821680884844\ 8530978478667288338327570972869032358120588620346111979053742269317702532328", ]; #[cfg(feature = "u64_digit")] const EXPECTED_CHACHA: &[&str] = &[ "0", "-7", "-62", "105", "13025", "-33857814162", "768483926407291599143", "-42356168828789885585553598574661841382586", "28813250216034838684899917677182169473483558650956121225920149068989083656174824", "27056553770481404639717657695702187062015359344716548489861498121037858109133467\ 99640556108506718020020878739044048067894089601665199172215093468287730555599", ]; #[test] fn test_chacha_value_stability() { use rand_chacha::ChaChaRng; seeded_value_stability::(EXPECTED_CHACHA); } #[cfg(not(feature = "u64_digit"))] const EXPECTED_ISAAC: &[&str] = &[ "1", "0", "5", "113", "-132240", "-36348760761", "-365690596708430705434", "-14090753008246284277803606722552430292432", "-26313941628626248579319341019368550803676255307056857978955881718727601479436059", "-14563174552421101848999036239003801073335703811160945137332228646111920972691151\ 88341090358094331641182310792892459091016794928947242043358702692294695845817", ]; #[cfg(feature = "u64_digit")] const EXPECTED_ISAAC: &[&str] = &[ "-1", "-4", "-29", "1621", "23872", "-40371956434", "-350815272425024298187", "-38554888817044546636456097200348998322457", "7474426176220721712055446211154990065592106428397966654956172383998793852911545", "6168955541726830487961394166772329653532583907235825721475483003506842180688827\ 391385624898257369023912466314791483731902392667906094226608113824795883754631", ]; #[test] fn test_isaac_value_stability() { use rand_isaac::IsaacRng; seeded_value_stability::(EXPECTED_ISAAC); } #[cfg(not(feature = "u64_digit"))] const EXPECTED_XOR: &[&str] = &[ "-1", "-4", "11", "-1802", "966495", "-62592045703", "-602281783447192077116", "-34335811410223060575607987996861632509125", "29156580925282215857325937227200350542000244609280383263289720243118706105351199", "49920038676141573457451407325930326489996232208489690499754573826911037849083623\ 24546142615325187412887314466195222441945661833644117700809693098722026764846", ]; #[cfg(feature = "u64_digit")] const EXPECTED_XOR: &[&str] = &[ "-1", "-3", "4", "-228", "377276", "32032893086", "885120221048601050706", "33404877924318663206979407569537287223622", "-15253093455306269007559295940333933266263385975865952571271093251749752787075084", "4502641950394305250103130679458759592222756470562408577296380915684757985604969904\ 381774527626485128207406911227296090734227576935034372181808818486328078978", ]; #[test] fn test_xorshift_value_stability() { use rand_xorshift::XorShiftRng; seeded_value_stability::(EXPECTED_XOR); } } #[cfg(feature = "prime")] mod prime { use num_bigint::prime::probably_prime; use num_bigint::RandPrime; use rand::prelude::*; #[test] fn test_prime_small() { let mut rng = StdRng::from_seed([0u8; 32]); for n in 2..10 { let p = rng.gen_prime(n); assert_eq!(p.bits(), n); assert!(probably_prime(&p, 32)); } } #[test] fn test_gen_prime_1024() { let mut rng = StdRng::from_seed([0u8; 32]); let p = rng.gen_prime(1024); assert_eq!(p.bits(), 1024); } }