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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use byteorder::ByteOrder;
#[cfg(target_arch = "wasm32")]
use getrandom::getrandom;
#[cfg(not(target_arch = "wasm32"))]
use ring::rand::{generate, SystemRandom};
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct UnspecifiedRandError;
pub fn gen_random_bytes(buffer: &mut [u8]) -> Result<(), UnspecifiedRandError> {
let mut cursor = 0;
let mut remaining_len = buffer.len();
while remaining_len >= 32 {
buffer[cursor..(cursor + 32)].copy_from_slice(&gen_32_bytes()?[..]);
cursor += 32;
remaining_len -= 32;
}
while remaining_len >= 16 {
buffer[cursor..(cursor + 16)].copy_from_slice(&gen_16_bytes()?[..]);
cursor += 16;
remaining_len -= 16;
}
if remaining_len > 0 {
buffer[cursor..].copy_from_slice(&gen_16_bytes()?[..remaining_len]);
}
Ok(())
}
#[cfg(target_arch = "wasm32")]
#[cfg(not(tarpaulin_include))]
#[inline]
pub fn gen_u32() -> Result<u32, UnspecifiedRandError> {
let mut random_bytes = [0u8; 4];
getrandom(&mut random_bytes[..]).map_err(|_| UnspecifiedRandError)?;
Ok(byteorder::BigEndian::read_u32(&random_bytes))
}
#[cfg(not(target_arch = "wasm32"))]
#[inline]
pub fn gen_u32() -> Result<u32, UnspecifiedRandError> {
let random_bytes =
generate::<[u8; 4]>(&SystemRandom::new()).map_err(|_| UnspecifiedRandError)?;
Ok(byteorder::BigEndian::read_u32(&random_bytes.expose()))
}
#[cfg(target_arch = "wasm32")]
#[cfg(not(tarpaulin_include))]
#[inline]
pub fn gen_16_bytes() -> Result<[u8; 16], UnspecifiedRandError> {
let mut random_bytes = [0u8; 16];
getrandom(&mut random_bytes[..]).map_err(|_| UnspecifiedRandError)?;
Ok(random_bytes)
}
#[cfg(not(target_arch = "wasm32"))]
#[inline]
pub fn gen_16_bytes() -> Result<[u8; 16], UnspecifiedRandError> {
let random_bytes =
generate::<[u8; 16]>(&SystemRandom::new()).map_err(|_| UnspecifiedRandError)?;
Ok(random_bytes.expose())
}
#[cfg(target_arch = "wasm32")]
#[cfg(not(tarpaulin_include))]
#[inline]
pub fn gen_32_bytes() -> Result<[u8; 32], UnspecifiedRandError> {
let mut random_bytes = [0u8; 32];
getrandom(&mut random_bytes[..]).map_err(|_| UnspecifiedRandError)?;
Ok(random_bytes)
}
#[cfg(not(target_arch = "wasm32"))]
#[inline]
pub fn gen_32_bytes() -> Result<[u8; 32], UnspecifiedRandError> {
let random_bytes =
generate::<[u8; 32]>(&SystemRandom::new()).map_err(|_| UnspecifiedRandError)?;
Ok(random_bytes.expose())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_gen_u32() -> Result<(), UnspecifiedRandError> {
assert_ne!(gen_u32()?, gen_u32()?);
Ok(())
}
#[test]
fn test_gen_random_bytes() -> Result<(), UnspecifiedRandError> {
let mut buffer = [0u8; 51];
gen_random_bytes(buffer.as_mut())?;
let mut buffer = [0u8; 48];
gen_random_bytes(buffer.as_mut())?;
Ok(())
}
}