blob: 6997b86cc4b248b3a894648d75e130c5bccf52bd [file] [log] [blame]
// Copyright (C) 2017-2018 Baidu, Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Baidu, Inc., nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use std::panic;
use sgx_rand::*;
// pub use os::SgxRng
pub fn test_rand_os_sgxrng(){
let mut os_rng = os::SgxRng::new().unwrap();
let mut checksum_u32 : u32 = 0;
let mut checksum_u64 : u64 = 0;
let testcount = 1000;
for _ in 0..testcount {
checksum_u32 |= os_rng.next_u32();
checksum_u64 |= os_rng.next_u64();
}
assert_ne!(checksum_u32, 0);
assert_ne!(checksum_u64, 0);
let mut rand_arr = [0;1000];
os_rng.fill_bytes(&mut rand_arr[..]);
let x = rand_arr.iter().fold(0, |sum, &x| sum ^ x);
assert_ne!(x, 0);
}
// pub mod distribution
// Too hard to test
pub fn test_rand_distributions () {
use sgx_rand::distributions::*;
use sgx_rand::distributions::Range;
use sgx_rand::*;
// From rust-src/librand/distributions/rand.rs
should_panic!(Range::new(10,10));
should_panic!(Range::new(10,5));
let mut rng = thread_rng();
macro_rules! t {
($($ty:ident),*) => {{
$(
let v: &[($ty, $ty)] = &[(0, 10),
(10, 127),
($ty::min_value(), $ty::max_value())];
for &(low, high) in v {
let mut sampler: Range<$ty> = Range::new(low, high);
for _ in 0..1000 {
let v = sampler.sample(&mut rng);
assert!(low <= v && v < high);
let v = sampler.ind_sample(&mut rng);
assert!(low <= v && v < high);
}
}
)*
}}
}
t!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
macro_rules! t {
($($ty:ty),*) => {{
$(
let v: &[($ty, $ty)] = &[(0.0, 100.0),
(-1e35, -1e25),
(1e-35, 1e-25),
(-1e35, 1e35)];
for &(low, high) in v {
let mut sampler: Range<$ty> = Range::new(low, high);
for _ in 0..1000 {
let v = sampler.sample(&mut rng);
assert!(low <= v && v < high);
let v = sampler.ind_sample(&mut rng);
assert!(low <= v && v < high);
}
}
)*
}}
}
t!(f32, f64);
let mut exp = Exp::new(10.0);
for _ in 0..1000 {
assert!(exp.sample(&mut rng) >= 0.0);
assert!(exp.ind_sample(&mut rng) >= 0.0);
}
should_panic!(Exp::new(0.0));
should_panic!(Exp::new(-10.0));
// gamma.rs
use sgx_rand::distributions::{ChiSquared, FisherF, StudentT};
let mut rng = thread_rng();
let mut chi = ChiSquared::new(1.0);
for _ in 0..1000 {
chi.sample(&mut rng);
chi.ind_sample(&mut rng);
}
let mut chi = ChiSquared::new(0.5);
for _ in 0..1000 {
chi.sample(&mut rng);
chi.ind_sample(&mut rng);
}
let mut chi = ChiSquared::new(30.0);
for _ in 0..1000 {
chi.sample(&mut rng);
chi.ind_sample(&mut rng);
}
should_panic!(ChiSquared::new(-1.0));
let mut rng = StdRng::new().unwrap();
let mut f = FisherF::new(2.0, 32.0);
for _ in 0..1000 {
f.sample(&mut rng);
f.ind_sample(&mut rng);
}
let mut t = StudentT::new(11.0);
for _ in 0..1000 {
t.sample(&mut rng);
t.ind_sample(&mut rng);
}
// normal.rs
use sgx_rand::distributions::{LogNormal, Normal};
let mut norm = Normal::new(10.0, 10.0);
for _ in 0..1000 {
norm.sample(&mut rng);
norm.ind_sample(&mut rng);
}
should_panic!(Normal::new(10.0, -1.0));
let mut lnorm = LogNormal::new(10.0, 10.0);
for _ in 0..1000 {
lnorm.sample(&mut rng);
lnorm.ind_sample(&mut rng);
}
should_panic!(LogNormal::new(10.0, -1.0));
use sgx_rand::distributions::{IndependentSample, RandSample, Sample, Weighted, WeightedChoice};
#[derive(PartialEq, Debug)]
struct ConstRand(usize);
impl Rand for ConstRand {
fn rand<R: Rng>(_: &mut R) -> ConstRand {
ConstRand(0)
}
}
// 0, 1, 2, 3, ...
struct CountingRng {
i: u32,
}
impl Rng for CountingRng {
fn next_u32(&mut self) -> u32 {
self.i += 1;
self.i - 1
}
fn next_u64(&mut self) -> u64 {
self.next_u32() as u64
}
}
let mut rand_sample = RandSample::<ConstRand>::new();
assert_eq!(rand_sample.sample(&mut rng), ConstRand(0));
assert_eq!(rand_sample.ind_sample(&mut rng), ConstRand(0));
macro_rules! t {
($items:expr, $expected:expr) => {{
let mut items = $items;
let wc = WeightedChoice::new(&mut items);
let expected = $expected;
let mut rng = CountingRng { i: 0 };
for &val in &expected {
assert_eq!(wc.ind_sample(&mut rng), val)
}
}}
}
t!(vec![Weighted { weight: 1, item: 10 }],
[10]);
// skip some
t!(vec![Weighted { weight: 0, item: 20 },
Weighted { weight: 2, item: 21 },
Weighted { weight: 0, item: 22 },
Weighted { weight: 1, item: 23 }],
[21, 21, 23]);
// different weights
t!(vec![Weighted { weight: 4, item: 30 },
Weighted { weight: 3, item: 31 }],
[30, 30, 30, 30, 31, 31, 31]);
// check that we're binary searching
// correctly with some vectors of odd
// length.
t!(vec![Weighted { weight: 1, item: 40 },
Weighted { weight: 1, item: 41 },
Weighted { weight: 1, item: 42 },
Weighted { weight: 1, item: 43 },
Weighted { weight: 1, item: 44 }],
[40, 41, 42, 43, 44]);
t!(vec![Weighted { weight: 1, item: 50 },
Weighted { weight: 1, item: 51 },
Weighted { weight: 1, item: 52 },
Weighted { weight: 1, item: 53 },
Weighted { weight: 1, item: 54 },
Weighted { weight: 1, item: 55 },
Weighted { weight: 1, item: 56 }],
[50, 51, 52, 53, 54, 55, 56]);
should_panic!(WeightedChoice::<isize>::new(&mut []));
should_panic!({
let mut t = [Weighted { weight: 0, item: 0 },Weighted { weight: 0, item: 1 }];
WeightedChoice::new(&mut t);
});
let x = (!0) as u32 / 2; // x + x + 2 is the overflow
should_panic!({
WeightedChoice::new(&mut [Weighted { weight: x, item: 0 },
Weighted { weight: 1, item: 1 },
Weighted { weight: x, item: 2 },
Weighted { weight: 1, item: 3 }]);});
}
// pub use isaac::{IsaacRng, Isaac64Rng};
// We cannot test because methods are private
pub fn test_rand_isaac_isaacrng () {
let mut unseeded_32 = IsaacRng::new_unseeded();
let mut u32_arr = [0;32];
for i in 0..32{
u32_arr[i] = unseeded_32.next_u32();
}
assert_eq!(u32_arr, [1909923794, 3041581799, 3564668249, 3277924858,
568073897, 1018722762, 3627754367, 4198294973, 2365883657,
3626931337, 3678742600, 3391154246, 1343199022, 250607936,
14072211, 3155345791, 3971560663, 4015545006, 1861263481,
249057481, 1397017464, 4117866301, 1748577758, 2418980344,
2932544972, 3384981086, 3677243665, 3631899496, 1984325203,
1082540525, 1970086400, 1634359601]);
let mut unseeded_64 = Isaac64Rng::new_unseeded();
let mut u64_arr = [0; 32];
for i in 0..32 {
u64_arr[i] = unseeded_64.next_u64();
}
assert_eq!(u64_arr, [17761629189777429372, 9558052838949843840,
18366607087662878139, 5554737638101975254, 9657764456686032042,
1042790411024899657, 18326046843346171767, 6155338025429880858,
604674934004978847, 15021509919615502100, 3524189203627442317,
3491674822202243807, 2812011890713530556, 6197411209201204330,
3423587972865533405, 13333204927595598570, 8278113110980066893,
16728828598150967100, 4739548913818718572, 12247507049266305179,
13400017821939308292, 14607632686415099658, 9600795998696455796,
5780363980783644600, 4671476687197924946, 1273203271378292130,
11668772324252115302, 5778980740914384907, 3192360781399669869,
8925632526356214095, 13227689911971237637, 16127447699671226298]);
unseeded_32.reseed(&[1,2,3,4]);
for i in 0..32{
u32_arr[i] = unseeded_32.next_u32();
}
assert_eq!(u32_arr, [3673720382, 1957022519, 2949967219, 2273082436,
2412264859, 1616913581, 4286187434, 1337573575, 3564981768,
3931377724, 180676801, 4234301014, 3123903540, 804531392,
1687941800, 3180870208, 3007460037, 1643580469, 1601966685,
385631690, 3412228283, 2633128738, 2786818767, 1385157572,
3925804522, 4251266711, 4219473709, 3054074232, 4185095632,
2891236088, 1792921516, 1421268925]);
unseeded_64.reseed(&[5,6,7,8]);
for i in 0..32{
u64_arr[i] = unseeded_64.next_u64();
}
assert_eq!(u64_arr, [1519553293257924390, 8496251504967724708,
4814852879883820893, 701662672566014897, 4253212733272379994,
14710390856535061408, 13525913188857210438, 4176812646507392158,
5274347845703478634, 7494101755291139543, 12433257569627749800,
13555030297923086622, 12912035290107031759, 10277213319518338357,
13212221592643678736, 14214333261821823450, 13451082182892489478,
17471061581144953786, 663937856451252907, 7794799705525010541,
8878465633657608553, 11684451817656999723, 3085412699425654134,
7996244368322668557, 9264264892592899720, 18202308129527220178,
14762563311397316905, 7967643698755143779, 13033364966409644229,
2619244012980533217, 2251084057656619285, 16661636750341142669]);
let mut from_seed_obj = IsaacRng::from_seed(&[1,2,3,4]);
for i in 0..32{
u32_arr[i] = from_seed_obj.next_u32();
}
assert_eq!(u32_arr, [3673720382, 1957022519, 2949967219, 2273082436,
2412264859, 1616913581, 4286187434, 1337573575, 3564981768,
3931377724, 180676801, 4234301014, 3123903540, 804531392,
1687941800, 3180870208, 3007460037, 1643580469, 1601966685,
385631690, 3412228283, 2633128738, 2786818767, 1385157572,
3925804522, 4251266711, 4219473709, 3054074232, 4185095632,
2891236088, 1792921516, 1421268925]);
let mut from_seed_obj_64 = Isaac64Rng::from_seed(&[5,6,7,8]);
for i in 0..32{
u64_arr[i] = from_seed_obj_64.next_u64();
}
assert_eq!(u64_arr, [1519553293257924390, 8496251504967724708,
4814852879883820893, 701662672566014897, 4253212733272379994,
14710390856535061408, 13525913188857210438, 4176812646507392158,
5274347845703478634, 7494101755291139543, 12433257569627749800,
13555030297923086622, 12912035290107031759, 10277213319518338357,
13212221592643678736, 14214333261821823450, 13451082182892489478,
17471061581144953786, 663937856451252907, 7794799705525010541,
8878465633657608553, 11684451817656999723, 3085412699425654134,
7996244368322668557, 9264264892592899720, 18202308129527220178,
14762563311397316905, 7967643698755143779, 13033364966409644229,
2619244012980533217, 2251084057656619285, 16661636750341142669]);
let mut isaac_rand = IsaacRng::rand(&mut unseeded_32);
for i in 0..32{
u32_arr[i] = isaac_rand.next_u32();
}
assert_eq!(u32_arr, [3731735955, 1060971802, 2060608277, 2017700212,
2906693947, 983683489, 2442131015, 1804959108, 133350985,
1854001588, 1536802647, 1681331746, 3926133099, 2418741330,
2933560360, 3445159402, 372862460, 584055518, 3889338902,
2010948997, 156911533, 1516660418, 2985909906, 2363648761,
3441715164, 1549975272, 1594543237, 4051120660, 4197709030,
3816779293, 3783690383, 2208018815]);
let mut isaac_rand64 = Isaac64Rng::rand(&mut unseeded_64);
for i in 0..32{
u64_arr[i] = isaac_rand64.next_u64();
}
assert_eq!(u64_arr, [9641310933002597978, 1377462969700517843,
505161414013526504, 15945732720326764686, 15418802195980990528,
16470443181580299993, 2257820220688421011, 11605056212052353438,
16446934715429265221, 2703881146695451334, 13779048927678904385,
3096257807787648519, 8078370161234145075, 11428361090362647425,
11163353455881119221, 2479568798082945555, 12997537085833811642,
15719812629115354877, 11384722140468426949, 1034436110230828879,
13933827272989341125, 16841927942905074390, 18283030736011842727,
18161628412401034420, 5992070539860306822, 14657980260306047343,
4240530741486241664, 16128750684074755458, 13382816331913570910,
1450784801074240917, 12172859719381448420, 11561024719408488519]);
}
// pub use chacha::ChaChaRng;
pub fn test_rand_chacharng () {
let mut chacha_obj = ChaChaRng::new_unseeded();
let mut arr_32 = [0;32];
let mut arr_64 = [0;32];
for i in 0..32 {
arr_32[i] = chacha_obj.next_u32();
arr_64[i] = chacha_obj.next_u64();
}
assert_eq!(arr_32, [2917185654, 683509331, 3438229160, 2370328401,
4105716586, 2254827186, 2090318488, 1768285000, 1981921065,
3577337972, 520806828, 3781961315, 2576249230, 1572053161,
4248444456, 3230977993, 1486888979, 180343358, 882336707,
772637944, 4294454303, 2115397425, 3755235835, 720939292,
261668430, 2229903491, 3478228973, 1178947740, 3612365086,
3675722242, 2702218887, 562719562]);
assert_eq!(arr_64, [10393729188386987328, 13265865887038934432,
14343251829215281626, 4602718913620007096, 2062956584559347651,
13755971968358175061, 939050496938282955, 4491151038014484018,
4850067409370051029, 2891290281678408273, 8020199878315477293,
635428310198806553, 14295220693338866608, 7509513789169826591,
2214742853367878259, 7093718481497530944, 7734567148921168085,
2355867238271518203, 11858361224218268717, 1394059717204795920,
6203934356551920360, 8397145010625398571, 12762635603290365669,
15798090700413956747, 14488165283315532822, 14534818617999799127,
5587461883115671776, 438217751243844519, 12085977715001316377,
14462731156256673612, 5957300949303581564, 9621633472041422470]);
let mut chacha_obj = ChaChaRng::new_unseeded();
chacha_obj.set_counter(0, 1234567890u64);
for i in 0..32 {
arr_32[i] = chacha_obj.next_u32();
arr_64[i] = chacha_obj.next_u64();
}
assert_eq!(arr_32, [3689073239, 2242961698, 417536494, 1503493075,
2585895478, 1865454281, 2938464816, 3998462791, 1427673087,
2023308892, 3934458784, 2154405649, 4261926467, 944974180,
1017947150, 1858486886, 2081637745, 6698551, 2593531725, 989113434,
952425310, 2821646029, 2012236296, 2466857171, 1705021287,
2712374590, 2467996873, 2529275143, 3691921567, 4164253542,
88339832, 3139246687]);
assert_eq!(arr_64, [5208214742801571470, 12560379081283373091,
16366572874613089836, 5810973028396244379, 5062530146601697561,
217785109116347749, 10945155018052356834, 3830068552016855006,
8631305173908678621, 2826768761480962968, 10354302052483333752,
14791155778847304997, 9236871951464247547, 10565693803420516117,
2303174007018927082, 11829861525625440339, 17157070760956407958,
18121029959197227032, 15895614391418239344, 16692872359552745709,
364895533855401959, 15289680275263377042, 14444259489219757497,
6497689978530420464, 7473989280813969277, 3566235157971589227,
5502428546971923888, 15258817180873710847, 1169964352668698116,
5863926115043645599, 15610749783507155661, 5502704700771473503]);
chacha_obj.reseed(&[1,2,3,4]);
for i in 0..32 {
arr_32[i] = chacha_obj.next_u32();
}
assert_eq!(arr_32, [3931434082, 34647919, 2091071039, 2892552082,
3564830854, 314912736, 3076587290, 3191577189, 2464328121,
2779997206, 4263592728, 2125004658, 1054360779, 3051661270,
3060579487, 3656634963, 1388834776, 581640397, 1637469323,
1640397641, 2995955648, 4048658223, 1600465837, 1968152875,
1014202063, 3686500314, 3021394822, 2541451384, 2305439270,
1469542314, 3487304956, 2286598508]);
let mut chacha_obj = ChaChaRng::from_seed(&[5,6,7,8]);
for i in 0..32 {
arr_32[i] = chacha_obj.next_u32();
}
assert_eq!(arr_32, [337897705, 1044901876, 2470587838, 3671677287,
1941090964, 2010394378, 3290836538, 1347698920, 2248500576,
2681774419, 1002813011, 65452860, 1850555370, 3036027713,
2306938851, 3450488430, 2195520755, 38533316, 692482625,
3410200303, 1052930979, 4087429478, 2501438173, 2495319620,
277097193, 1034107694, 2396644634, 3334027496, 3808708279,
3705622889, 874306690, 1237186790]);
let mut chacha_obj = ChaChaRng::rand(&mut chacha_obj);
for i in 0..32 {
arr_32[i] = chacha_obj.next_u32();
}
assert_eq!(arr_32, [1225539984, 2122523891, 4046438709, 2772996924,
2441149875, 4253841608, 2837944766, 1256279550, 134014938,
192621923, 4187133245, 45039689, 3455715024, 3744176230,
3194372814, 3469543760, 1107844861, 3990938641, 4095630261,
3461287666, 321560749, 934078781, 2671586377, 1048877492,
1523056052, 3373403085, 913407943, 2835509350, 3232974874,
3910156243, 3652032104, 442368320]);
}
// reseeding.rs
pub fn test_rand_reseeding() {
use std::prelude::v1::*;
use sgx_rand::reseeding::{ReseedWithDefault, ReseedingRng};
use sgx_rand::{Rng, SeedableRng};
struct Counter {
i: u32,
}
impl Rng for Counter {
fn next_u32(&mut self) -> u32 {
self.i += 1;
// very random
self.i - 1
}
}
impl Default for Counter {
/// Constructs a `Counter` with initial value zero.
fn default() -> Counter {
Counter { i: 0 }
}
}
impl SeedableRng<u32> for Counter {
fn reseed(&mut self, seed: u32) {
self.i = seed;
}
fn from_seed(seed: u32) -> Counter {
Counter { i: seed }
}
}
type MyRng = ReseedingRng<Counter, ReseedWithDefault>;
let mut rs = ReseedingRng::new(Counter { i: 0 }, 400, ReseedWithDefault);
let mut i = 0;
for _ in 0..1000 {
assert_eq!(rs.next_u32(), i % 100);
i += 1;
}
let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
let mut r: MyRng = SeedableRng::from_seed((ReseedWithDefault, 3));
let string1: String = r.gen_ascii_chars().take(100).collect();
r.reseed((ReseedWithDefault, 3));
let string2: String = r.gen_ascii_chars().take(100).collect();
assert_eq!(string1, string2);
const FILL_BYTES_V_LEN: usize = 13579;
let mut v = vec![0; FILL_BYTES_V_LEN];
let mut rng = StdRng::new().unwrap();
rng.fill_bytes(&mut v);
// Sanity test: if we've gotten here, `fill_bytes` has not infinitely
// recursed.
assert_eq!(v.len(), FILL_BYTES_V_LEN);
// To test that `fill_bytes` actually did something, check that the
// average of `v` is not 0.
let mut sum = 0.0;
for &x in &v {
sum += x as f64;
}
assert!(sum / v.len() as f64 != 0.0);
}
// No need for testing others
// Already included in the above tests