1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::sync::Arc;
use std::sync::atomic::{AtomicPtr, Ordering};
use std::thread::{spawn};
use std::time::{SystemTime, UNIX_EPOCH};

use rand::{Rng, RngCore, SeedableRng};
use rand::distributions::{Distribution, Standard};
use rand::distributions::uniform::{SampleRange, SampleUniform};
use rand::rngs::StdRng;
#[derive(Clone)]
pub struct DataraceRNG {
    state: u128,
}
impl Default for DataraceRNG {
    fn default() -> Self {
        let start = SystemTime::now();
        let seed = start
            .duration_since(UNIX_EPOCH)
            .expect("Time went backwards").as_nanos();
        let state = Self::basic_hash(seed);
        Self { state }
    }
}
impl DataraceRNG {
    pub fn new(seed: u128) -> Self {
        let state = Self::basic_hash(seed);
        Self { state }
    }
    fn basic_hash(seed: u128) -> u128 {
        let mut seed = seed;
        seed ^= seed.wrapping_shr(26);
        seed ^= seed.wrapping_shl(13);
        seed ^= seed.wrapping_shr(23);
        seed
    }
    fn mutate(&mut self) {
        self.state = Self::data_race(self.state);
    }
    pub fn data_race(state: u128) -> u128{
        let mut state = state;
        let state = Arc::new(AtomicPtr::new(&mut state));
        unsafe {
            let mut thread_pool = Vec::new();
            for i in 0..12u32 {
                let state = state.clone();
                let t = spawn(move || {
                    for e in 0..1024 {
                        let state_value = *state.load(Ordering::Relaxed);
                        let new_value = Self::basic_hash(!1945678154678958719829601872597819u128.wrapping_mul(i.wrapping_shr(e) as u128).wrapping_shl(e.wrapping_pow(i)) ^ state_value);
                        let mut newer_value = u128::from_le_bytes(new_value.to_be_bytes());
                        state.store(&mut newer_value, Ordering::Release);
                    }
                });
                thread_pool.push(t);
            }
            for thread in thread_pool{
                thread.join().unwrap();
            }
            *state.load(Ordering::Relaxed)
        }
    }

    fn blake3(data: u128) -> u128 {
        let mut hasher = blake3::Hasher::new();
        hasher.update(&data.to_be_bytes());
        let result = hasher.finalize();
        let bytes: [u8; 16] = slice_to_fixed_array(result.as_bytes());
        u128::from_le_bytes(bytes)
    }
    fn blake3_raw(data: u128) -> [u8; 32] {
        let mut hasher = blake3::Hasher::new();
        hasher.update(&data.to_be_bytes());
        let result = hasher.finalize();
        *result.as_bytes()
    }
    fn result(&self) -> u128{
        Self::blake3(self.state)
    }
    pub fn gen<T>(&mut self) -> T
        where Standard: Distribution<T>{
        let mut rng = StdRng::from_seed(Self::blake3_raw(self.result()));
        self.mutate();
        rng.gen()
    }

    pub fn gen_range<T, R>(&mut self, range: R) -> T
        where T: SampleUniform, R: SampleRange<T>,{
        let mut rng = StdRng::from_seed(Self::blake3_raw(self.result()));
        self.mutate();
        rng.gen_range(range)
    }
}
impl RngCore for DataraceRNG {
    fn next_u32(&mut self) -> u32 {
        self.gen()
    }

    fn next_u64(&mut self) -> u64 {
        self.gen()
    }

    fn fill_bytes(&mut self, dest: &mut [u8]) {
        let mut rng = StdRng::from_seed(Self::blake3_raw(self.result()));
        self.mutate();
        rng.fill_bytes(dest);
    }

    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
        let mut rng = StdRng::from_seed(Self::blake3_raw(self.result()));
        self.mutate();
        rng.fill_bytes(dest);
        Ok(())
    }
}
fn slice_to_fixed_array(source_slice: &[u8]) -> [u8; 16] {
    let mut target_array: [u8; 16] = [0; 16];

    // If the source_slice is longer than the target_array, truncate it.
    let slice_len = source_slice.len().min(16);
    target_array[..slice_len].copy_from_slice(&source_slice[..slice_len]);

    target_array
}