Skip to content

Commit afe9cb6

Browse files
committed
feat(rand): add rand crate integration
Signed-off-by: Roman Volosatovs <[email protected]>
1 parent afa66af commit afe9cb6

File tree

5 files changed

+102
-1
lines changed

5 files changed

+102
-1
lines changed

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ compiler_builtins = { version = "0.1", optional = true }
1919
core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" }
2020
rustc-std-workspace-alloc = { version = "1.0", optional = true }
2121

22+
# When built with `rand` crate integration
23+
rand = { version = "0.8.5", default-features = false, optional = true }
24+
2225
[features]
2326
default = ["std"]
2427
std = []
@@ -32,3 +35,7 @@ crate-type = ["cdylib"]
3235
[[example]]
3336
name = "http-proxy"
3437
crate-type = ["cdylib"]
38+
39+
[[example]]
40+
name = "rand"
41+
required-features = ["rand"]

examples/rand.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use std::io::Write as _;
2+
3+
use wasi::ext::rand::rand::Rng as _;
4+
use wasi::ext::rand::{HostInsecureRng, HostRng};
5+
6+
fn main() {
7+
let mut stdout = wasi::cli::stdout::get_stdout();
8+
9+
let r: u64 = HostRng.gen();
10+
stdout
11+
.write_all(format!("Cryptographically-secure random u64 is {r}\n").as_bytes())
12+
.unwrap();
13+
14+
let r: u64 = HostInsecureRng.gen();
15+
stdout
16+
.write_all(format!("Pseudo-random u64 is {r}\n").as_bytes())
17+
.unwrap();
18+
19+
stdout.flush().unwrap();
20+
}

src/ext/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#[cfg(feature = "std")]
22
mod std;
33

4+
#[cfg(feature = "rand")]
5+
pub mod rand;
6+
47
impl core::fmt::Display for crate::io::error::Error {
58
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69
f.write_str(&self.to_debug_string())

src/ext/rand.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
pub use rand;
2+
3+
use rand::{CryptoRng, RngCore};
4+
5+
/// The secure interface for cryptographically-secure random numbers
6+
pub struct HostRng;
7+
8+
impl CryptoRng for HostRng {}
9+
10+
impl RngCore for HostRng {
11+
#[inline]
12+
fn next_u32(&mut self) -> u32 {
13+
crate::random::random::get_random_u64() as _
14+
}
15+
16+
#[inline]
17+
fn next_u64(&mut self) -> u64 {
18+
crate::random::random::get_random_u64()
19+
}
20+
21+
fn fill_bytes(&mut self, dest: &mut [u8]) {
22+
let n = dest.len();
23+
if usize::BITS <= u64::BITS || n <= u64::MAX as _ {
24+
dest.copy_from_slice(&crate::random::random::get_random_bytes(n as _));
25+
} else {
26+
let (head, tail) = dest.split_at_mut(u64::MAX as _);
27+
head.copy_from_slice(&crate::random::random::get_random_bytes(u64::MAX));
28+
self.fill_bytes(tail);
29+
}
30+
}
31+
32+
#[inline]
33+
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
34+
self.fill_bytes(dest);
35+
Ok(())
36+
}
37+
}
38+
39+
/// The insecure interface for insecure pseudo-random numbers
40+
pub struct HostInsecureRng;
41+
42+
impl RngCore for HostInsecureRng {
43+
#[inline]
44+
fn next_u32(&mut self) -> u32 {
45+
crate::random::insecure::get_insecure_random_u64() as _
46+
}
47+
48+
#[inline]
49+
fn next_u64(&mut self) -> u64 {
50+
crate::random::insecure::get_insecure_random_u64()
51+
}
52+
53+
fn fill_bytes(&mut self, dest: &mut [u8]) {
54+
let n = dest.len();
55+
if usize::BITS <= u64::BITS || n <= u64::MAX as _ {
56+
dest.copy_from_slice(&crate::random::insecure::get_insecure_random_bytes(n as _));
57+
} else {
58+
let (head, tail) = dest.split_at_mut(u64::MAX as _);
59+
head.copy_from_slice(&crate::random::insecure::get_insecure_random_bytes(
60+
u64::MAX,
61+
));
62+
self.fill_bytes(tail);
63+
}
64+
}
65+
66+
#[inline]
67+
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
68+
self.fill_bytes(dest);
69+
Ok(())
70+
}
71+
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@
179179
#[cfg(feature = "std")]
180180
extern crate std;
181181

182-
mod ext;
182+
pub mod ext;
183183

184184
// These modules are all auto-generated by `./ci/regenerate.sh`
185185
mod bindings;

0 commit comments

Comments
 (0)