1 #![cfg(feature = "rand")]
2 
3 extern crate num_bigint;
4 extern crate num_traits;
5 extern crate rand;
6 
7 mod biguint {
8     use num_bigint::{BigUint, RandBigInt, RandomBits};
9     use num_traits::Zero;
10     use rand::distributions::Uniform;
11     use rand::thread_rng;
12     use rand::{Rng, SeedableRng};
13 
14     #[test]
test_rand()15     fn test_rand() {
16         let mut rng = thread_rng();
17         let n: BigUint = rng.gen_biguint(137);
18         assert!(n.bits() <= 137);
19         assert!(rng.gen_biguint(0).is_zero());
20     }
21 
22     #[test]
test_rand_bits()23     fn test_rand_bits() {
24         let mut rng = thread_rng();
25         let n: BigUint = rng.sample(&RandomBits::new(137));
26         assert!(n.bits() <= 137);
27         let z: BigUint = rng.sample(&RandomBits::new(0));
28         assert!(z.is_zero());
29     }
30 
31     #[test]
test_rand_range()32     fn test_rand_range() {
33         let mut rng = thread_rng();
34 
35         for _ in 0..10 {
36             assert_eq!(
37                 rng.gen_biguint_range(&BigUint::from(236u32), &BigUint::from(237u32)),
38                 BigUint::from(236u32)
39             );
40         }
41 
42         let l = BigUint::from(403469000u32 + 2352);
43         let u = BigUint::from(403469000u32 + 3513);
44         for _ in 0..1000 {
45             let n: BigUint = rng.gen_biguint_below(&u);
46             assert!(n < u);
47 
48             let n: BigUint = rng.gen_biguint_range(&l, &u);
49             assert!(n >= l);
50             assert!(n < u);
51         }
52     }
53 
54     #[test]
55     #[should_panic]
test_zero_rand_range()56     fn test_zero_rand_range() {
57         thread_rng().gen_biguint_range(&BigUint::from(54u32), &BigUint::from(54u32));
58     }
59 
60     #[test]
61     #[should_panic]
test_negative_rand_range()62     fn test_negative_rand_range() {
63         let mut rng = thread_rng();
64         let l = BigUint::from(2352u32);
65         let u = BigUint::from(3513u32);
66         // Switching u and l should fail:
67         let _n: BigUint = rng.gen_biguint_range(&u, &l);
68     }
69 
70     #[test]
test_rand_uniform()71     fn test_rand_uniform() {
72         let mut rng = thread_rng();
73 
74         let tiny = Uniform::new(BigUint::from(236u32), BigUint::from(237u32));
75         for _ in 0..10 {
76             assert_eq!(rng.sample(&tiny), BigUint::from(236u32));
77         }
78 
79         let l = BigUint::from(403469000u32 + 2352);
80         let u = BigUint::from(403469000u32 + 3513);
81         let below = Uniform::new(BigUint::zero(), u.clone());
82         let range = Uniform::new(l.clone(), u.clone());
83         for _ in 0..1000 {
84             let n: BigUint = rng.sample(&below);
85             assert!(n < u);
86 
87             let n: BigUint = rng.sample(&range);
88             assert!(n >= l);
89             assert!(n < u);
90         }
91     }
92 
seeded_value_stability<R: SeedableRng + RandBigInt>(expected: &[&str])93     fn seeded_value_stability<R: SeedableRng + RandBigInt>(expected: &[&str]) {
94         let mut seed = <R::Seed>::default();
95         for (i, x) in seed.as_mut().iter_mut().enumerate() {
96             *x = (i as u8).wrapping_mul(191);
97         }
98         let mut rng = R::from_seed(seed);
99         for (i, &s) in expected.iter().enumerate() {
100             let n: BigUint = s.parse().unwrap();
101             let r = rng.gen_biguint((1 << i) + i);
102             assert_eq!(n, r);
103         }
104     }
105 
106     #[test]
test_chacha_value_stability()107     fn test_chacha_value_stability() {
108         const EXPECTED: &[&str] = &[
109             "0",
110             "0",
111             "52",
112             "84",
113             "23780",
114             "86502865016",
115             "187057847319509867386",
116             "34045731223080904464438757488196244981910",
117             "23813754422987836414755953516143692594193066497413249270287126597896871975915808",
118             "57401636903146945411652549098818446911814352529449356393690984105383482703074355\
119              67088360974672291353736011718191813678720755501317478656550386324355699624671",
120         ];
121         use rand::prng::ChaChaRng;
122         seeded_value_stability::<ChaChaRng>(EXPECTED);
123     }
124 
125     #[test]
test_isaac_value_stability()126     fn test_isaac_value_stability() {
127         const EXPECTED: &[&str] = &[
128             "1",
129             "4",
130             "3",
131             "649",
132             "89116",
133             "7730042024",
134             "20773149082453254949",
135             "35999009049239918667571895439206839620281",
136             "10191757312714088681302309313551624007714035309632506837271600807524767413673006",
137             "37805949268912387809989378008822038725134260145886913321084097194957861133272558\
138              43458183365174899239251448892645546322463253898288141861183340823194379722556",
139         ];
140         use rand::prng::IsaacRng;
141         seeded_value_stability::<IsaacRng>(EXPECTED);
142     }
143 
144     #[test]
test_xorshift_value_stability()145     fn test_xorshift_value_stability() {
146         const EXPECTED: &[&str] = &[
147             "1",
148             "0",
149             "37",
150             "395",
151             "181116",
152             "122718231117",
153             "1068467172329355695001",
154             "28246925743544411614293300167064395633287",
155             "12750053187017853048648861493745244146555950255549630854523304068318587267293038",
156             "53041498719137109355568081064978196049094604705283682101683207799515709404788873\
157              53417136457745727045473194367732849819278740266658219147356315674940229288531",
158         ];
159         use rand::prng::XorShiftRng;
160         seeded_value_stability::<XorShiftRng>(EXPECTED);
161     }
162 }
163 
164 mod bigint {
165     use num_bigint::{BigInt, RandBigInt, RandomBits};
166     use num_traits::Zero;
167     use rand::distributions::Uniform;
168     use rand::thread_rng;
169     use rand::{Rng, SeedableRng};
170 
171     #[test]
test_rand()172     fn test_rand() {
173         let mut rng = thread_rng();
174         let n: BigInt = rng.gen_bigint(137);
175         assert!(n.bits() <= 137);
176         assert!(rng.gen_bigint(0).is_zero());
177     }
178 
179     #[test]
test_rand_bits()180     fn test_rand_bits() {
181         let mut rng = thread_rng();
182         let n: BigInt = rng.sample(&RandomBits::new(137));
183         assert!(n.bits() <= 137);
184         let z: BigInt = rng.sample(&RandomBits::new(0));
185         assert!(z.is_zero());
186     }
187 
188     #[test]
test_rand_range()189     fn test_rand_range() {
190         let mut rng = thread_rng();
191 
192         for _ in 0..10 {
193             assert_eq!(
194                 rng.gen_bigint_range(&BigInt::from(236), &BigInt::from(237)),
195                 BigInt::from(236)
196             );
197         }
198 
199         fn check(l: BigInt, u: BigInt) {
200             let mut rng = thread_rng();
201             for _ in 0..1000 {
202                 let n: BigInt = rng.gen_bigint_range(&l, &u);
203                 assert!(n >= l);
204                 assert!(n < u);
205             }
206         }
207         let l: BigInt = BigInt::from(403469000 + 2352);
208         let u: BigInt = BigInt::from(403469000 + 3513);
209         check(l.clone(), u.clone());
210         check(-l.clone(), u.clone());
211         check(-u.clone(), -l.clone());
212     }
213 
214     #[test]
215     #[should_panic]
test_zero_rand_range()216     fn test_zero_rand_range() {
217         thread_rng().gen_bigint_range(&BigInt::from(54), &BigInt::from(54));
218     }
219 
220     #[test]
221     #[should_panic]
test_negative_rand_range()222     fn test_negative_rand_range() {
223         let mut rng = thread_rng();
224         let l = BigInt::from(2352);
225         let u = BigInt::from(3513);
226         // Switching u and l should fail:
227         let _n: BigInt = rng.gen_bigint_range(&u, &l);
228     }
229 
230     #[test]
test_rand_uniform()231     fn test_rand_uniform() {
232         let mut rng = thread_rng();
233 
234         let tiny = Uniform::new(BigInt::from(236u32), BigInt::from(237u32));
235         for _ in 0..10 {
236             assert_eq!(rng.sample(&tiny), BigInt::from(236u32));
237         }
238 
239         fn check(l: BigInt, u: BigInt) {
240             let mut rng = thread_rng();
241             let range = Uniform::new(l.clone(), u.clone());
242             for _ in 0..1000 {
243                 let n: BigInt = rng.sample(&range);
244                 assert!(n >= l);
245                 assert!(n < u);
246             }
247         }
248         let l: BigInt = BigInt::from(403469000 + 2352);
249         let u: BigInt = BigInt::from(403469000 + 3513);
250         check(l.clone(), u.clone());
251         check(-l.clone(), u.clone());
252         check(-u.clone(), -l.clone());
253     }
254 
seeded_value_stability<R: SeedableRng + RandBigInt>(expected: &[&str])255     fn seeded_value_stability<R: SeedableRng + RandBigInt>(expected: &[&str]) {
256         let mut seed = <R::Seed>::default();
257         for (i, x) in seed.as_mut().iter_mut().enumerate() {
258             *x = (i as u8).wrapping_mul(191);
259         }
260         let mut rng = R::from_seed(seed);
261         for (i, &s) in expected.iter().enumerate() {
262             let n: BigInt = s.parse().unwrap();
263             let r = rng.gen_bigint((1 << i) + i);
264             assert_eq!(n, r);
265         }
266     }
267 
268     #[test]
test_chacha_value_stability()269     fn test_chacha_value_stability() {
270         const EXPECTED: &[&str] = &[
271             "0",
272             "-6",
273             "-1",
274             "1321",
275             "-147247",
276             "8486373526",
277             "-272736656290199720696",
278             "2731152629387534140535423510744221288522",
279             "-28820024790651190394679732038637785320661450462089347915910979466834461433196572",
280             "501454570554170484799723603981439288209930393334472085317977614690773821680884844\
281              8530978478667288338327570972869032358120588620346111979053742269317702532328",
282         ];
283         use rand::prng::ChaChaRng;
284         seeded_value_stability::<ChaChaRng>(EXPECTED);
285     }
286 
287     #[test]
test_isaac_value_stability()288     fn test_isaac_value_stability() {
289         const EXPECTED: &[&str] = &[
290             "1",
291             "0",
292             "5",
293             "113",
294             "-132240",
295             "-36348760761",
296             "-365690596708430705434",
297             "-14090753008246284277803606722552430292432",
298             "-26313941628626248579319341019368550803676255307056857978955881718727601479436059",
299             "-14563174552421101848999036239003801073335703811160945137332228646111920972691151\
300              88341090358094331641182310792892459091016794928947242043358702692294695845817",
301         ];
302         use rand::prng::IsaacRng;
303         seeded_value_stability::<IsaacRng>(EXPECTED);
304     }
305 
306     #[test]
test_xorshift_value_stability()307     fn test_xorshift_value_stability() {
308         const EXPECTED: &[&str] = &[
309             "-1",
310             "-4",
311             "11",
312             "-1802",
313             "966495",
314             "-62592045703",
315             "-602281783447192077116",
316             "-34335811410223060575607987996861632509125",
317             "29156580925282215857325937227200350542000244609280383263289720243118706105351199",
318             "49920038676141573457451407325930326489996232208489690499754573826911037849083623\
319              24546142615325187412887314466195222441945661833644117700809693098722026764846",
320         ];
321         use rand::prng::XorShiftRng;
322         seeded_value_stability::<XorShiftRng>(EXPECTED);
323     }
324 }
325