Merge pull request #288 from dhardy/core

Add rand-core sub-crate and update version numbers
This commit is contained in:
Diggory Hardy 2018-03-14 10:46:58 +00:00 committed by GitHub
commit 336d224362
23 changed files with 656 additions and 313 deletions

View File

@ -12,25 +12,26 @@ matrix:
install:
script:
- cargo test --all --tests --no-default-features
- cargo test --all --features serde-1,log
- cargo test --features serde-1,log
- rust: stable
os: osx
install:
script:
- cargo test --all --tests --no-default-features
- cargo test --all --features serde-1,log
- cargo test --features serde-1,log
- rust: beta
install:
script:
- cargo test --all --tests --no-default-features
- cargo test --tests --no-default-features --features=serde-1
- rust: nightly
install:
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo test --tests --no-default-features --features=alloc
- cargo test --all --tests --no-default-features --features=alloc
- cargo test --all --features=alloc
- cargo test --all --features serde-1,log,nightly
- cargo test --features serde-1,log,nightly
- cargo test --benches
- cargo doc --no-deps --all-features
after_success:

View File

@ -1,6 +1,6 @@
[package]
name = "rand"
version = "0.4.2"
version = "0.5.0-pre.0"
authors = ["The Rust Project Developers"]
license = "MIT/Apache-2.0"
readme = "README.md"
@ -17,8 +17,8 @@ categories = ["algorithms"]
default = ["std"]
nightly = ["i128_support"] # enables all features requiring nightly rust
std = ["libc", "winapi"] # default feature; without this rand uses libcore
alloc = [] # enables Vec and Box support without std
std = ["rand-core/std", "winapi", "libc"] # default feature; without this rand uses libcore
alloc = ["rand-core/alloc"] # enables Vec and Box support without std
i128_support = [] # enables i128 and u128 support
@ -32,11 +32,16 @@ libc = { version = "0.2", optional = true }
winapi = { version = "0.3", features = ["minwindef", "ntsecapi", "profileapi", "winnt"], optional = true }
[dependencies]
rand-core = { path = 'rand-core', default-features = false }
log = { version = "0.4", optional = true }
serde = {version="1",optional=true}
serde_derive = {version="1", optional=true}
[workspace]
members = ["rand-core"]
[dev-dependencies]
# This is for testing serde, unfortunately
# we can't specify feature-gated dev deps yet,

View File

@ -33,8 +33,7 @@ build: false
test_script:
- cargo test --benches
- cargo test
- cargo test --features serde-1
- cargo test --features nightly
- cargo test --tests --no-default-features --features=alloc
- cargo test --all
- cargo test --features serde-1,log,nightly
- cargo test --all --tests --no-default-features --features=alloc
- cargo test --tests --no-default-features --features=serde-1

20
rand-core/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "rand-core"
version = "0.1.0-pre.0"
authors = ["The Rust Project Developers"]
license = "MIT/Apache-2.0"
readme = "README.md"
repository = "https://github.com/rust-lang-nursery/rand"
documentation = "https://docs.rs/rand"
homepage = "https://github.com/rust-lang-nursery/rand"
description = """
Core random number generator traits and tools for implementation.
"""
keywords = ["random", "rng"]
categories = ["algorithms"]
[features]
# Bug: https://github.com/rust-lang/cargo/issues/4361
# default = ["std"]
std = [] # use std library; should be default but for above bug
alloc = [] # enables Vec and Box support without std

201
rand-core/LICENSE-APACHE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
rand-core/LICENSE-MIT Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

27
rand-core/README.md Normal file
View File

@ -0,0 +1,27 @@
rand-core
====
Core traits and error types of the [rand] library, plus tools for implementing
RNGs.
This crate is intended for use when implementing the core trait, `RngCore`; it
defines the core traits to be implemented as well as several small functions to
aid in their implementation and types required for error handling.
The main [rand] crate re-exports most items defined in this crate, along with
tools to convert the integer samples generated by `RngCore` to many different
applications (including sampling from restricted ranges, conversion to floating
point, list permutations and secure initialisation of RNGs). Most users should
prefer to use the main [rand] crate.
[Documentation](https://docs.rs/rand-core)
[rand]: ..
# License
`rand` is primarily distributed under the terms of both the MIT
license and the Apache License (Version 2.0).
See LICENSE-APACHE, and LICENSE-MIT for details.

View File

@ -1,10 +1,10 @@
// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// 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.

View File

@ -19,9 +19,6 @@
//! to/from byte sequences, and since its purpose is reproducibility,
//! non-reproducible sources (e.g. `OsRng`) need not bother with it.
// TODO: eventually these should be exported somehow
#![allow(unused)]
use core::intrinsics::transmute;
use core::ptr::copy_nonoverlapping;
use core::slice;

View File

@ -13,10 +13,7 @@
//! Little-Endian order has been chosen for internal usage; this makes some
//! useful functions available.
// TODO: eventually these should be exported somehow
#![allow(unused)]
use core::{mem, ptr};
use core::ptr;
macro_rules! read_slice {
($src:expr, $dst:expr, $size:expr, $which:ident) => {{

308
rand-core/src/lib.rs Normal file
View File

@ -0,0 +1,308 @@
// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// 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.
//! Random number generation traits
//!
//! This crate is mainly of interest to crates publishing implementations of
//! `RngCore`. Other users are encouraged to use the [rand] crate instead
//! which re-exports the main traits and error types.
//!
//! `RngCore` is the core trait implemented by algorithmic pseudo-random number
//! generators and external random-number sources.
//!
//! `SeedableRng` is an extension trait for construction from fixed seeds and
//! other random number generators.
//!
//! `Error` is provided for error-handling. It is safe to use in `no_std`
//! environments.
//!
//! The `impls` and `le` sub-modules include a few small functions to assist
//! implementation of `RngCore`.
//!
//! [rand]: https://crates.io/crates/rand
#![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://docs.rs/rand-core/0.1")]
#![deny(missing_debug_implementations)]
#![cfg_attr(not(feature="std"), no_std)]
#![cfg_attr(all(feature="alloc", not(feature="std")), feature(alloc))]
#[cfg(feature="std")] extern crate core;
#[cfg(all(feature = "alloc", not(feature="std")))] extern crate alloc;
use core::default::Default;
use core::convert::AsMut;
#[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;
pub use error::{ErrorKind, Error};
mod error;
pub mod impls;
pub mod le;
/// The core of a random number generator.
///
/// This trait encapsulates the low-level functionality common to all
/// generators, and is the "back end", to be implemented by generators.
/// End users should normally use [`Rng`] from the [rand] crate, which is
/// automatically implemented for every type implementing `RngCore`.
///
/// Three different methods for generating random data are provided since the
/// optimal implementation of each is dependent on the type of generator. There
/// is no required relationship between the output of each; e.g. many
/// implementations of `fill_bytes` consume a whole number of `u32` or `u64`
/// values and drop any remaining unused bytes.
///
/// The `try_fill_bytes` method is a variant of `fill_bytes` allowing error
/// handling; it is not deemed sufficiently useful to add equivalents for
/// `next_u32` or `next_u64` since the latter methods are almost always used
/// with algorithmic generators (PRNGs), which are normally infallible.
///
/// Algorithmic generators implementing `SeedableRng` should normally have
/// *portable, reproducible* output, i.e. fix Endianness when converting values
/// to avoid platform differences, and avoid making any changes which affect
/// output (except by communicating that the release has breaking changes).
///
/// Typically implementators will implement only one of the methods available
/// in this trait directly, then use the helper functions from the [`impls`]
/// module to implement the other methods.
///
/// # Example
///
/// A simple example, obviously not generating very *random* output:
///
/// ```rust
/// use rand_core::{RngCore, Error, impls};
///
/// struct CountingRng(u64);
///
/// impl RngCore for CountingRng {
/// fn next_u32(&mut self) -> u32 {
/// self.next_u64() as u32
/// }
///
/// fn next_u64(&mut self) -> u64 {
/// self.0 += 1;
/// self.0
/// }
///
/// fn fill_bytes(&mut self, dest: &mut [u8]) {
/// impls::fill_bytes_via_u64(self, dest)
/// }
///
/// fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
/// Ok(self.fill_bytes(dest))
/// }
/// }
/// ```
///
/// [rand]: https://crates.io/crates/rand
/// [`Rng`]: https://docs.rs/rand/0.5/rand/trait.Rng.html
/// [`impls`]: impls/index.html
pub trait RngCore {
/// Return the next random `u32`.
///
/// RNGs must implement at least one method from this trait directly. In
/// the case this method is not implemented directly, it can be implemented
/// using `self.next_u64() as u32` or
/// [via `fill_bytes`](impls/fn.next_u32_via_fill.html).
fn next_u32(&mut self) -> u32;
/// Return the next random `u64`.
///
/// RNGs must implement at least one method from this trait directly. In
/// the case this method is not implemented directly, it can be implemented
/// [via `next_u32`](impls/fn.next_u64_via_u32.html) or
/// [via `fill_bytes`](impls/fn.next_u64_via_fill.html).
fn next_u64(&mut self) -> u64;
/// Fill `dest` with random data.
///
/// RNGs must implement at least one method from this trait directly. In
/// the case this method is not implemented directly, it can be implemented
/// [via `next_u32`](impls/fn.fill_bytes_via_u32.html) or
/// [via `next_u64`](impls/fn.fill_bytes_via_u64.html) or
/// via `try_fill_bytes`; if this generator can fail the implementation
/// must choose how best to handle errors here (e.g. panic with a
/// descriptive message or log a warning and retry a few times).
///
/// This method should guarantee that `dest` is entirely filled
/// with new data, and may panic if this is impossible
/// (e.g. reading past the end of a file that is being used as the
/// source of randomness).
fn fill_bytes(&mut self, dest: &mut [u8]);
/// Fill `dest` entirely with random data.
///
/// This is the only method which allows an RNG to report errors while
/// generating random data thus making this the primary method implemented
/// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used
/// directly to generate keys and to seed (infallible) PRNGs.
///
/// Other than error handling, this method is identical to [`fill_bytes`];
/// thus this may be implemented using `Ok(self.fill_bytes(dest))` or
/// `fill_bytes` may be implemented with
/// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
///
/// [`fill_bytes`]: trait.RngCore.html#method.fill_bytes
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
}
/// A marker trait for an `Rng` which may be considered for use in
/// cryptography.
///
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
/// satisfy an additional properties over other generators: given the first
/// *k* bits of an algorithm's output
/// sequence, it should not be possible using polynomial-time algorithms to
/// predict the next bit with probability significantly greater than 50%.
///
/// Some generators may satisfy an additional property, however this is not
/// required: if the CSPRNG's state is revealed, it should not be
/// computationally-feasible to reconstruct output prior to this. Some other
/// generators allow backwards-computation and are consided *reversible*.
///
/// Note that this trait is provided for guidance only and cannot guarantee
/// suitability for cryptographic applications. In general it should only be
/// implemented for well-reviewed code implementing well-regarded algorithms.
///
/// Note also that use of a `CryptoRng` does not protect against other
/// weaknesses such as seeding from a weak entropy source or leaking state.
pub trait CryptoRng: RngCore {}
/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
/// pseudo-random number generators (PRNGs, or algorithmic generators).
///
/// [rand]'s [`NewRng`] trait is automatically implemented for every type
/// implementing `SeedableRng`, providing a convenient `new()` method.
///
/// [rand]: https://crates.io/crates/rand
/// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html
pub trait SeedableRng: Sized {
/// Seed type, which is restricted to types mutably-dereferencable as `u8`
/// arrays (we recommend `[u8; N]` for some `N`).
///
/// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
/// which means an array of `[u8; 12]` or greater to avoid picking RNGs with
/// partially overlapping periods.
///
/// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
type Seed: Sized + Default + AsMut<[u8]>;
/// Create a new PRNG using the given seed.
///
/// PRNG implementations are allowed to assume that bits in the seed are
/// well distributed. That means usually that the number of one and zero
/// bits are about equal, and values like 0, 1 and (size - 1) are unlikely.
///
/// PRNG implementations are recommended to be reproducible. A PRNG seeded
/// using this function with a fixed seed should produce the same sequence
/// of output in the future and on different architectures (with for example
/// different endianness).
///
/// It is however not required that this function yield the same state as a
/// reference implementation of the PRNG given equivalent seed; if necessary
/// another constructor replicating behaviour from a reference
/// implementation can be added.
fn from_seed(seed: Self::Seed) -> Self;
/// Create a new PRNG seeded from another `Rng`.
///
/// This is the recommended way to initialize PRNGs with fresh entropy. The
/// [`NewRng`] trait provides a convenient new method based on `from_rng`.
///
/// Usage of this method is not recommended when reproducibility is required
/// since implementing PRNGs are not required to fix Endianness and are
/// allowed to modify implementations in new releases.
///
/// It is important to use a good source of randomness to initialize the
/// PRNG. Cryptographic PRNG may be rendered insecure when seeded from a
/// non-cryptographic PRNG or with insufficient entropy.
/// Many non-cryptographic PRNGs will show statistical bias in their first
/// results if their seed numbers are small or if there is a simple pattern
/// between them.
///
/// Prefer to seed from a strong external entropy source like [`OsRng`] or
/// from a cryptographic PRNG; if creating a new generator for cryptographic
/// uses you *must* seed from a strong source.
///
/// Seeding a small PRNG from another small PRNG is possible, but
/// something to be careful with. An extreme example of how this can go
/// wrong is seeding an [`XorShiftRng`] from another [`XorShiftRng`], which
/// will effectively clone the generator. In general seeding from a
/// generator which is hard to predict is probably okay.
///
/// PRNG implementations are allowed to assume that a good RNG is provided
/// for seeding, and that it is cryptographically secure when appropriate.
///
/// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html
/// [`OsRng`]: https://docs.rs/rand/0.5/rand/os/struct.OsRng.html
/// [`XorShiftRng`]: https://docs.rs/rand/0.5/rand/prng/xorshift/struct.XorShiftRng.html
fn from_rng<R: RngCore>(rng: &mut R) -> Result<Self, Error> {
let mut seed = Self::Seed::default();
rng.try_fill_bytes(seed.as_mut())?;
Ok(Self::from_seed(seed))
}
}
impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R {
#[inline]
fn next_u32(&mut self) -> u32 {
(**self).next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
(**self).next_u64()
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
(**self).fill_bytes(dest)
}
#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
(**self).try_fill_bytes(dest)
}
}
#[cfg(any(feature="std", feature="alloc"))]
impl<R: RngCore + ?Sized> RngCore for Box<R> {
#[inline]
fn next_u32(&mut self) -> u32 {
(**self).next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
(**self).next_u64()
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
(**self).fill_bytes(dest)
}
#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
(**self).try_fill_bytes(dest)
}
}

View File

@ -10,7 +10,7 @@
//! Entropy generator, or wrapper around external generators
use {RngCore, Error, impls};
use rand_core::{RngCore, Error, impls};
use {OsRng, JitterRng};
/// An RNG provided specifically for seeding PRNGs.

View File

@ -16,7 +16,7 @@
//! Non-physical true random number generator based on timing jitter.
use {RngCore, CryptoRng, Error, ErrorKind, impls};
use rand_core::{RngCore, CryptoRng, Error, ErrorKind, impls};
use core::{fmt, mem, ptr};
#[cfg(feature="std")]
@ -777,6 +777,10 @@ impl RngCore for JitterRng {
// themselves via `fill_bytes`.
impls::fill_bytes_via_u32(self, dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest))
}
}
impl CryptoRng for JitterRng {}

View File

@ -237,7 +237,7 @@
#![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://docs.rs/rand/0.4")]
html_root_url = "https://docs.rs/rand/0.5")]
#![deny(missing_debug_implementations)]
@ -257,6 +257,8 @@
#[macro_use]
extern crate stdweb;
extern crate rand_core;
#[cfg(feature = "log")] #[macro_use] extern crate log;
#[cfg(not(feature = "log"))] macro_rules! trace { ($($x:tt)*) => () }
#[cfg(not(feature = "log"))] macro_rules! debug { ($($x:tt)*) => () }
@ -266,7 +268,10 @@ extern crate stdweb;
use core::{marker, mem, slice};
#[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;
// re-exports from rand-core
pub use rand_core::{RngCore, CryptoRng, SeedableRng};
pub use rand_core::{ErrorKind, Error};
// external rngs
pub use jitter::JitterRng;
@ -278,9 +283,6 @@ pub use chacha::ChaChaRng;
pub use prng::XorShiftRng;
pub use prng::Hc128Rng;
// error types
pub use error::{ErrorKind, Error};
// convenience and derived rngs
#[cfg(feature="std")] pub use entropy_rng::EntropyRng;
#[cfg(feature="std")] pub use thread_rng::{ThreadRng, thread_rng};
@ -291,7 +293,6 @@ use distributions::range::SampleRange;
// public modules
pub mod distributions;
mod impls;
pub mod jitter;
pub mod mock;
#[cfg(feature="std")] pub mod os;
@ -310,9 +311,7 @@ pub mod isaac {
}
// private modules
mod le;
#[cfg(feature="std")] mod entropy_rng;
mod error;
mod prng;
#[cfg(feature="std")] mod thread_rng;
@ -330,139 +329,6 @@ pub trait Rand : Sized {
fn rand<R: Rng>(rng: &mut R) -> Self;
}
/// The core of a random number generator.
///
/// This trait encapsulates the low-level functionality common to all
/// generators, and is the "back end", to be implemented by generators.
/// End users should normally use [`Rng`] instead.
///
/// Unlike [`Rng`], this trait is object-safe. To use a type-erased [`Rng`] —
/// i.e. dynamic dispatch — this trait must be used, along with [`Rng`] to
/// use its generic functions:
///
/// ```
/// use rand::{Rng, RngCore};
///
/// fn use_rng(mut rng: &mut RngCore) -> u32 {
/// rng.gen_range(1, 7)
/// }
///
/// // or:
/// fn use_any_rng<R: RngCore>(rng: &mut R) -> char {
/// rng.gen()
/// }
/// ```
///
/// Several extension traits exist:
///
/// * [`Rng`] provides high-level functionality using generic functions
/// * [`SeedableRng`] is another low-level trait to be implemented by PRNGs
/// (algorithmic RNGs), concerning creation and seeding
/// * [`NewRng`] is a high-level trait providing a `new()` function, allowing
/// easy construction of freshly-seeded PRNGs
///
/// [`Rng`]: trait.Rng.html
/// [`SeedableRng`]: trait.SeedableRng.html
/// [`NewRng`]: trait.NewRng.html
pub trait RngCore {
/// Return the next random `u32`.
///
/// Implementations of this trait must implement at least one of
/// `next_u32`, `next_u64` and `fill_bytes` directly. In the case this
/// function is not implemented directly, it can be implemented using
/// `self.next_u64() as u32` or via `fill_bytes` (TODO: expose helper
/// function).
fn next_u32(&mut self) -> u32;
/// Return the next random `u64`.
///
/// Implementations of this trait must implement at least one of
/// `next_u32`, `next_u64` and `fill_bytes` directly. In the case this
/// function is not implemented directly, the default implementation will
/// generate values via `next_u32` in little-endian fashion, or this
/// function can be implemented via `fill_bytes` (TODO: expose helper
/// function).
///
/// Types wrapping an inner RNG must not use the default implementation,
/// since the inner RNG's implementation may produce different values.
fn next_u64(&mut self) -> u64 {
impls::next_u64_via_u32(self)
}
/// Fill `dest` with random data.
///
/// Implementations of this trait must implement at least one of
/// `next_u32`, `next_u64` and `fill_bytes` directly. In the case this
/// function is not implemented directly, the default implementation will
/// generate values via `next_u64` in little-endian fashion.
/// (TODO: expose helper function to allow implementation via `next_u32`.)
///
/// There is no requirement on how this method generates values relative to
/// `next_u32` or `next_u64`; e.g. a `u64` cast to bytes is not required to
/// have the same value as eight bytes filled via this function. There *is*
/// a requirement of portability for reproducible generators which implies
/// that any seedable generator must fix endianness when generating bytes.
///
/// Types wrapping an inner RNG must not use the default implementation,
/// since the inner RNG's implementation may produce different values.
///
/// This method should guarantee that `dest` is entirely filled
/// with new data, and may panic if this is impossible
/// (e.g. reading past the end of a file that is being used as the
/// source of randomness).
///
/// # Example
///
/// ```rust
/// use rand::{thread_rng, RngCore};
///
/// let mut v = [0u8; 13579];
/// thread_rng().fill_bytes(&mut v);
/// println!("{:?}", &v[..]);
/// ```
fn fill_bytes(&mut self, dest: &mut [u8]) {
impls::fill_bytes_via_u64(self, dest)
}
/// Fill `dest` entirely with random data.
///
/// This is the only method which allows an RNG to report errors while
/// generating random data; other methods either handle the error
/// internally or panic. This method is
/// the intended way to use external (true) RNGs, like `OsRng`. Its main
/// use-cases are to generate keys and to seed (infallible) PRNGs.
///
/// Other than error handling, this method is identical to [`fill_bytes`], and
/// has a default implementation simply wrapping [`fill_bytes`].
///
/// [`fill_bytes`]: trait.RngCore.html#method.fill_bytes
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest))
}
}
/// A marker trait for an `Rng` which may be considered for use in
/// cryptography.
///
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
/// satisfy an additional properties over other generators: given the first
/// *k* bits of an algorithm's output
/// sequence, it should not be possible using polynomial-time algorithms to
/// predict the next bit with probability significantly greater than 50%.
///
/// Some generators may satisfy an additional property, however this is not
/// required: if the CSPRNG's state is revealed, it should not be
/// computationally-feasible to reconstruct output prior to this. Some other
/// generators allow backwards-computation and are consided *reversible*.
///
/// Note that this trait is provided for guidance only and cannot guarantee
/// suitability for cryptographic applications. In general it should only be
/// implemented for well-reviewed code implementing well-regarded algorithms.
///
/// Note also that use of a `CryptoRng` does not protect against other
/// weaknesses such as seeding from a weak entropy source or leaking state.
pub trait CryptoRng: RngCore {}
/// An automatically-implemented extension trait on [`RngCore`] providing high-level
/// generic methods for sampling values and other convenience methods.
///
@ -506,7 +372,7 @@ pub trait CryptoRng: RngCore {}
/// }
/// ```
///
/// [`RngCore`]: trait.RngCore.html
/// [`RngCore`]: https://docs.rs/rand-core/0.1/rand-core/trait.RngCore.html
pub trait Rng: RngCore + Sized {
/// Fill `dest` entirely with random bytes (uniform value distribution),
/// where `dest` is any type supporting [`AsByteSliceMut`], namely slices
@ -528,7 +394,7 @@ pub trait Rng: RngCore + Sized {
/// thread_rng().try_fill(&mut arr[..]);
/// ```
///
/// [`fill_bytes`]: trait.RngCore.html#method.fill_bytes
/// [`fill_bytes`]: https://docs.rs/rand-core/0.1/rand-core/trait.RngCore.html#method.fill_bytes
/// [`try_fill`]: trait.Rng.html#method.try_fill
/// [`AsByteSliceMut`]: trait.AsByteSliceMut.html
fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) where Self: Sized {
@ -563,8 +429,8 @@ pub trait Rng: RngCore + Sized {
/// # try_inner().unwrap()
/// ```
///
/// [`ErrorKind`]: enum.ErrorKind.html
/// [`try_fill_bytes`]: trait.RngCore.html#method.try_fill_bytes
/// [`ErrorKind`]: https://docs.rs/rand-core/0.1/rand-core/enum.ErrorKind.html
/// [`try_fill_bytes`]: https://docs.rs/rand-core/0.1/rand-core/trait.RngCore.html#method.try_fill_bytes
/// [`fill`]: trait.Rng.html#method.fill
/// [`AsByteSliceMut`]: trait.AsByteSliceMut.html
fn try_fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) -> Result<(), Error> where Self: Sized {
@ -757,51 +623,6 @@ pub trait Rng: RngCore + Sized {
impl<R: RngCore> Rng for R {}
impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R {
#[inline]
fn next_u32(&mut self) -> u32 {
(**self).next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
(**self).next_u64()
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
(**self).fill_bytes(dest)
}
#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
(**self).try_fill_bytes(dest)
}
}
#[cfg(any(feature="std", feature="alloc"))]
impl<R: RngCore + ?Sized> RngCore for Box<R> {
#[inline]
fn next_u32(&mut self) -> u32 {
(**self).next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
(**self).next_u64()
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
(**self).fill_bytes(dest)
}
#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
(**self).try_fill_bytes(dest)
}
}
/// Trait for casting types to byte slices
///
/// This is used by the [`fill`] and [`try_fill`] methods.
@ -925,83 +746,6 @@ impl<R: RngCore> Iterator for AsciiGenerator<R> {
}
}
/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
/// pseudo-random number generators (PRNGs, or algorithmic generators).
///
/// Normally users should use the [`NewRng`] extension trait, excepting when a
/// fixed seed must be used, in which case usage of [`SeedableRng::from_seed`]
/// is recommended.
///
/// [`NewRng`]: trait.NewRng.html
/// [`SeedableRng::from_seed`]: #tymethod.from_seed
pub trait SeedableRng: Sized {
/// Seed type, which is restricted to types mutably-dereferencable as `u8`
/// arrays (we recommend `[u8; N]` for some `N`).
///
/// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
/// which means an array of `[u8; 12]` or greater to avoid picking RNGs with
/// partially overlapping periods.
///
/// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
type Seed: Sized + Default + AsMut<[u8]>;
/// Create a new PRNG using the given seed.
///
/// PRNG implementations are allowed to assume that bits in the seed are
/// well distributed. That means usually that the number of one and zero
/// bits are about equal, and values like 0, 1 and (size - 1) are unlikely.
///
/// PRNG implementations are recommended to be reproducible. A PRNG seeded
/// using this function with a fixed seed should produce the same sequence
/// of output in the future and on different architectures (with for example
/// different endianness).
///
/// It is however not required that this function yield the same state as a
/// reference implementation of the PRNG given equivalent seed; if necessary
/// another constructor can be used.
fn from_seed(seed: Self::Seed) -> Self;
/// Create a new PRNG seeded from another `Rng`.
///
/// This is the recommended way to initialize PRNGs with fresh entropy. The
/// [`NewRng`] trait provides a convenient new method based on `from_rng`.
///
/// Usage of this method is not recommended when reproducibility is required
/// since implementing PRNGs are not required to fix Endianness and are
/// allowed to modify implementations in new releases.
///
/// It is important to use a good source of randomness to initialize the
/// PRNG. Cryptographic PRNG may be rendered insecure when seeded from a
/// non-cryptographic PRNG or with insufficient entropy.
/// Many non-cryptographic PRNGs will show statistical bias in their first
/// results if their seed numbers are small or if there is a simple pattern
/// between them.
///
/// Prefer to seed from a strong external entropy source like [`OsRng`] or
/// from a cryptographic PRNG; if creating a new generator for cryptographic
/// uses you *must* seed from a strong source.
///
/// Seeding a small PRNG from another small PRNG is possible, but
/// something to be careful with. An extreme example of how this can go
/// wrong is seeding an [`XorShiftRng`] from another [`XorShiftRng`], which
/// will effectively clone the generator. In general seeding from a
/// generator which is hard to predict is probably okay.
///
/// PRNG implementations are allowed to assume that a good RNG is provided
/// for seeding, and that it is cryptographically secure when appropriate.
///
/// [`NewRng`]: trait.NewRng.html
/// [`OsRng`]: os/struct.OsRng.html
/// [`XorShiftRng`]: prng/xorshift/struct.XorShiftRng.html
fn from_rng<R: RngCore>(rng: &mut R) -> Result<Self, Error> {
let mut seed = Self::Seed::default();
rng.try_fill_bytes(seed.as_mut())?;
Ok(Self::from_seed(seed))
}
}
/// A convenient way to seed new algorithmic generators, otherwise known as
/// pseudo-random number generators (PRNGs).
@ -1021,8 +765,8 @@ pub trait SeedableRng: Sized {
/// println!("Random die roll: {}", rng.gen_range(1, 7));
/// ```
///
/// [`SeedableRng`]: trait.SeedableRng.html
/// [`SeedableRng::from_seed`]: trait.SeedableRng.html#tymethod.from_seed
/// [`SeedableRng`]: https://docs.rs/rand-core/0.1/rand-core/trait.SeedableRng.html
/// [`SeedableRng::from_seed`]: https://docs.rs/rand-core/0.1/rand-core/trait.SeedableRng.html#tymethod.from_seed
#[cfg(feature="std")]
pub trait NewRng: SeedableRng {
/// Creates a new instance, automatically seeded with fresh entropy.
@ -1220,6 +964,9 @@ mod test {
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.inner.fill_bytes(dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.inner.try_fill_bytes(dest)
}
}
pub fn rng(seed: u64) -> TestRng<StdRng> {

View File

@ -10,7 +10,7 @@
//! Mock random number generator
use {RngCore, Error, impls};
use rand_core::{RngCore, Error, impls};
/// A simple implementation of `RngCore` for testing purposes.
///

View File

@ -17,7 +17,7 @@ use std::io::Read;
#[allow(unused)] use std::path::Path;
#[allow(unused)] use std::sync::{Once, Mutex, ONCE_INIT};
use {RngCore, Error, ErrorKind, impls};
use rand_core::{RngCore, Error, ErrorKind, impls};
/// A random number generator that retrieves randomness straight from
/// the operating system.

View File

@ -11,8 +11,7 @@
//! The ChaCha random number generator.
use core::fmt;
use {RngCore, CryptoRng, SeedableRng};
use {impls, le};
use rand_core::{RngCore, CryptoRng, SeedableRng, Error, impls, le};
const SEED_WORDS: usize = 8; // 8 words for the 256-bit key
const STATE_WORDS: usize = 16;
@ -235,7 +234,6 @@ impl RngCore for ChaChaRng {
impls::next_u64_via_u32(self)
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut read_len = 0;
while read_len < dest.len() {
@ -251,6 +249,10 @@ impl RngCore for ChaChaRng {
read_len += filled_u8;
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest))
}
}
impl CryptoRng for ChaChaRng {}

View File

@ -11,8 +11,7 @@
//! The HC-128 random number generator.
use core::fmt;
use {RngCore, CryptoRng, SeedableRng};
use {impls, le};
use rand_core::{RngCore, CryptoRng, SeedableRng, Error, impls, le};
const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv
@ -392,6 +391,10 @@ impl RngCore for Hc128Rng {
read_len += filled_u8;
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest))
}
}
impl CryptoRng for Hc128Rng {}

View File

@ -13,8 +13,7 @@
use core::{fmt, slice};
use core::num::Wrapping as w;
use {RngCore, SeedableRng, Error};
use {impls, le};
use rand_core::{RngCore, SeedableRng, Error, impls, le};
#[allow(non_camel_case_types)]
type w32 = w<u32>;
@ -234,7 +233,6 @@ impl RngCore for IsaacRng {
impls::next_u64_via_u32(self)
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut read_len = 0;
while read_len < dest.len() {
@ -250,6 +248,10 @@ impl RngCore for IsaacRng {
read_len += filled_u8;
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest))
}
}
/// Creates a new ISAAC random number generator.

View File

@ -13,8 +13,7 @@
use core::{fmt, slice};
use core::num::Wrapping as w;
use {RngCore, SeedableRng, Error};
use {impls, le};
use rand_core::{RngCore, SeedableRng, Error, impls, le};
#[allow(non_camel_case_types)]
type w64 = w<u64>;
@ -253,6 +252,10 @@ impl RngCore for Isaac64Rng {
read_len += filled_u8;
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest))
}
}
/// Creates a new ISAAC-64 random number generator.

View File

@ -12,8 +12,7 @@
use core::num::Wrapping as w;
use core::{fmt, slice};
use {RngCore, SeedableRng, Error};
use {impls, le};
use rand_core::{RngCore, SeedableRng, Error, impls, le};
/// An Xorshift[1] random number
/// generator.
@ -78,6 +77,10 @@ impl RngCore for XorShiftRng {
fn fill_bytes(&mut self, dest: &mut [u8]) {
impls::fill_bytes_via_u32(self, dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
Ok(self.fill_bytes(dest))
}
}
impl SeedableRng for XorShiftRng {

View File

@ -12,7 +12,7 @@
use std::io::Read;
use {RngCore, Error, ErrorKind, impls};
use rand_core::{RngCore, Error, ErrorKind, impls};
/// An RNG that reads random bytes straight from a `Read`. This will

View File

@ -4,21 +4,20 @@ set -ex
main() {
if [ ! -z $DISABLE_TESTS ]; then
if [ ! -z $DISABLE_STD ]; then
cross build --all --no-default-features --target $TARGET --release
else
cross build --all --features log,serde-1 --target $TARGET
cross build --all --no-default-features --target $TARGET --release
if [ -z $DISABLE_STD ]; then
cross build --features log,serde-1 --target $TARGET
fi
return
fi
if [ ! -z $NIGHTLY ]; then
cross test --all --tests --no-default-features --features alloc --target $TARGET
cross test --all --features serde-1,log,nightly --target $TARGET
cross test --features serde-1,log,nightly --target $TARGET
cross test --all --benches --target $TARGET
else
cross test --all --tests --no-default-features --target $TARGET
cross test --all --features serde-1,log --target $TARGET
cross test --features serde-1,log --target $TARGET
fi
}