blob: be6123a58a799583c3606f1c4c03b88dbbdcf62d [file] [log] [blame]
#![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 crate::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<R: SeedableRng + RandBigInt>(expected: &[&str]) {
let mut seed = <R::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::<ChaChaRng>(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::<IsaacRng>(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::<XorShiftRng>(EXPECTED_XOR);
}
}
mod bigint {
use crate::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<R: SeedableRng + RandBigInt>(expected: &[&str]) {
let mut seed = <R::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::<ChaChaRng>(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::<IsaacRng>(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::<XorShiftRng>(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);
}
}