forked from rust-random/rand
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib.rs
108 lines (95 loc) · 3.2 KB
/
lib.rs
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
// Copyright 2018 Developers of the Rand project.
// Copyright 2013-2015 The Rust Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Interface to the random number generator of the operating system.
//!
//! # Blocking and error handling
//!
//! It is possible that when used during early boot the first call to `OsRng`
//! will block until the system's RNG is initialised. It is also possible
//! (though highly unlikely) for `OsRng` to fail on some platforms, most
//! likely due to system mis-configuration.
//!
//! After the first successful call, it is highly unlikely that failures or
//! significant delays will occur (although performance should be expected to
//! be much slower than a user-space PRNG).
//!
//! [getrandom]: https://crates.io/crates/getrandom
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://rust-random.github.io/rand/")]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
#![no_std] // but see getrandom crate
pub use rand_core; // re-export
use getrandom::getrandom;
use rand_core::{CryptoRng, RngCore, Error, impls};
/// A random number generator that retrieves randomness from from the
/// operating system.
///
/// This is a zero-sized struct. It can be freely constructed with `OsRng`.
///
/// The implementation is provided by the [getrandom] crate. Refer to
/// [getrandom] documentation for details.
///
/// # Usage example
/// ```
/// use rand_os::{OsRng, rand_core::RngCore};
///
/// let mut key = [0u8; 16];
/// OsRng.fill_bytes(&mut key);
/// let random_u64 = OsRng.next_u64();
/// ```
///
/// [getrandom]: https://crates.io/crates/getrandom
#[derive(Clone, Copy, Debug, Default)]
pub struct OsRng;
impl OsRng {
/// Create a new `OsRng`.
#[deprecated(since="0.2.0", note="replace OsRng::new().unwrap() with just OsRng")]
pub fn new() -> Result<OsRng, Error> {
Ok(OsRng)
}
}
impl CryptoRng for OsRng {}
impl RngCore for OsRng {
fn next_u32(&mut self) -> u32 {
impls::next_u32_via_fill(self)
}
fn next_u64(&mut self) -> u64 {
impls::next_u64_via_fill(self)
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
if let Err(e) = self.try_fill_bytes(dest) {
panic!("Error: {}", e);
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
getrandom(dest).map_err(|e| {
#[cfg(feature="std")] {
rand_core::Error::from_cause(e)
}
#[cfg(not(feature="std"))] {
rand_core::Error::from_code(e.code())
}
})
}
}
#[test]
fn test_os_rng() {
let x = OsRng.next_u64();
let y = OsRng.next_u64();
assert!(x != 0);
assert!(x != y);
}
#[test]
fn test_construction() {
let mut rng = OsRng::default();
assert!(rng.next_u64() != 0);
}