aboutsummaryrefslogtreecommitdiff
path: root/rand/rand_isaac
diff options
context:
space:
mode:
Diffstat (limited to 'rand/rand_isaac')
-rw-r--r--rand/rand_isaac/CHANGELOG.md21
-rw-r--r--rand/rand_isaac/COPYRIGHT12
-rw-r--r--rand/rand_isaac/Cargo.toml31
-rw-r--r--rand/rand_isaac/LICENSE-APACHE201
-rw-r--r--rand/rand_isaac/LICENSE-MIT26
-rw-r--r--rand/rand_isaac/README.md47
-rw-r--r--rand/rand_isaac/src/isaac.rs476
-rw-r--r--rand/rand_isaac/src/isaac64.rs466
-rw-r--r--rand/rand_isaac/src/isaac_array.rs136
-rw-r--r--rand/rand_isaac/src/lib.rs27
10 files changed, 0 insertions, 1443 deletions
diff --git a/rand/rand_isaac/CHANGELOG.md b/rand/rand_isaac/CHANGELOG.md
deleted file mode 100644
index 0a5591f..0000000
--- a/rand/rand_isaac/CHANGELOG.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Changelog
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## [0.2.0] - 2019-06-12
-- Bump minor crate version since rand_core bump is a breaking change
-- Switch to Edition 2018
-
-## [0.1.2] - 2019-06-06 - yanked
-- Bump `rand_core` version
-- Remove deprecated code
-- Adjust usage of `#[inline]`
-
-## [0.1.1] - 2018-11-26
-- Fix `rand_core` version requirement
-- Fix doc links
-
-## [0.1.0] - 2018-10-17
-- Pulled out of the Rand crate
diff --git a/rand/rand_isaac/COPYRIGHT b/rand/rand_isaac/COPYRIGHT
deleted file mode 100644
index 468d907..0000000
--- a/rand/rand_isaac/COPYRIGHT
+++ /dev/null
@@ -1,12 +0,0 @@
-Copyrights in the Rand project are retained by their contributors. No
-copyright assignment is required to contribute to the Rand project.
-
-For full authorship information, see the version control history.
-
-Except as otherwise noted (below and/or in individual files), Rand is
-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 option.
-
-The Rand project includes code from the Rust project
-published under these same licenses.
diff --git a/rand/rand_isaac/Cargo.toml b/rand/rand_isaac/Cargo.toml
deleted file mode 100644
index c11c305..0000000
--- a/rand/rand_isaac/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-name = "rand_isaac"
-version = "0.2.0"
-authors = ["The Rand Project Developers", "The Rust Project Developers"]
-license = "MIT OR Apache-2.0"
-readme = "README.md"
-repository = "https://github.com/rust-random/rand"
-documentation = "https://rust-random.github.io/rand/rand_isaac/"
-homepage = "https://crates.io/crates/rand_isaac"
-description = """
-ISAAC random number generator
-"""
-keywords = ["random", "rng", "isaac"]
-categories = ["algorithms", "no-std"]
-edition = "2018"
-
-[badges]
-travis-ci = { repository = "rust-random/rand" }
-appveyor = { repository = "rust-random/rand" }
-
-[features]
-serde1 = ["serde", "rand_core/serde1"]
-
-[dependencies]
-rand_core = { path = "../rand_core", version = "0.5" }
-serde = { version = "1", features = ["derive"], optional = true }
-
-[dev-dependencies]
-# This is for testing serde, unfortunately we can't specify feature-gated dev
-# deps yet, see: https://github.com/rust-lang/cargo/issues/1596
-bincode = "1"
diff --git a/rand/rand_isaac/LICENSE-APACHE b/rand/rand_isaac/LICENSE-APACHE
deleted file mode 100644
index 17d7468..0000000
--- a/rand/rand_isaac/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- 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.
diff --git a/rand/rand_isaac/LICENSE-MIT b/rand/rand_isaac/LICENSE-MIT
deleted file mode 100644
index d93b5ba..0000000
--- a/rand/rand_isaac/LICENSE-MIT
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018 Developers of the Rand project
-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.
diff --git a/rand/rand_isaac/README.md b/rand/rand_isaac/README.md
deleted file mode 100644
index c16c63f..0000000
--- a/rand/rand_isaac/README.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# rand_isaac
-
-[![Build Status](https://travis-ci.org/rust-random/rand.svg)](https://travis-ci.org/rust-random/rand)
-[![Build Status](https://ci.appveyor.com/api/projects/status/github/rust-random/rand?svg=true)](https://ci.appveyor.com/project/rust-random/rand)
-[![Latest version](https://img.shields.io/crates/v/rand_isaac.svg)](https://crates.io/crates/rand_isaac)
-[![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/)
-[![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand_isaac)
-[![API](https://docs.rs/rand_isaac/badge.svg)](https://docs.rs/rand_isaac)
-[![Minimum rustc version](https://img.shields.io/badge/rustc-1.32+-lightgray.svg)](https://github.com/rust-random/rand#rust-version-requirements)
-
-Implements the ISAAC and ISAAC-64 random number generators.
-
-ISAAC stands for "Indirection, Shift, Accumulate, Add, and Count" which are
-the principal bitwise operations employed. It is the most advanced of a
-series of array based random number generator designed by Robert Jenkins
-in 1996[^1][^2].
-
-ISAAC is notably fast and produces excellent quality random numbers for
-non-cryptographic applications.
-
-Links:
-
-- [API documentation (master)](https://rust-random.github.io/rand/rand_isaac)
-- [API documentation (docs.rs)](https://docs.rs/rand_isaac)
-- [Changelog](https://github.com/rust-random/rand/blob/master/rand_isaac/CHANGELOG.md)
-
-[rand]: https://crates.io/crates/rand
-[^1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number generator*](http://burtleburtle.net/bob/rand/isaacafa.html)
-[^2]: Bob Jenkins, [*ISAAC and RC4*](http://burtleburtle.net/bob/rand/isaac.html)
-
-
-## Crate Features
-
-`rand_isaac` is `no_std` compatible. It does not require any functionality
-outside of the `core` lib, thus there are no features to configure.
-
-The `serde1` feature includes implementations of `Serialize` and `Deserialize`
-for the included RNGs.
-
-
-# License
-
-`rand_isaac` is distributed under the terms of both the MIT license and the
-Apache License (Version 2.0).
-
-See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT), and
-[COPYRIGHT](COPYRIGHT) for details.
diff --git a/rand/rand_isaac/src/isaac.rs b/rand/rand_isaac/src/isaac.rs
deleted file mode 100644
index 2caf61a..0000000
--- a/rand/rand_isaac/src/isaac.rs
+++ /dev/null
@@ -1,476 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-// Copyright 2013-2018 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.
-
-//! The ISAAC random number generator.
-
-use core::{fmt, slice};
-use core::num::Wrapping as w;
-#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
-use rand_core::{RngCore, SeedableRng, Error, le};
-use rand_core::block::{BlockRngCore, BlockRng};
-use crate::isaac_array::IsaacArray;
-
-#[allow(non_camel_case_types)]
-type w32 = w<u32>;
-
-const RAND_SIZE_LEN: usize = 8;
-const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
-
-/// A random number generator that uses the ISAAC algorithm.
-///
-/// ISAAC stands for "Indirection, Shift, Accumulate, Add, and Count" which are
-/// the principal bitwise operations employed. It is the most advanced of a
-/// series of array based random number generator designed by Robert Jenkins
-/// in 1996[^1][^2].
-///
-/// ISAAC is notably fast and produces excellent quality random numbers for
-/// non-cryptographic applications.
-///
-/// In spite of being designed with cryptographic security in mind, ISAAC hasn't
-/// been stringently cryptanalyzed and thus cryptographers do not not
-/// consensually trust it to be secure. When looking for a secure RNG, prefer
-/// `Hc128Rng` from the [`rand_hc`] crate instead, which, like ISAAC, is an
-/// array-based RNG and one of the stream-ciphers selected the by eSTREAM
-///
-/// In 2006 an improvement to ISAAC was suggested by Jean-Philippe Aumasson,
-/// named ISAAC+[^3]. But because the specification is not complete, because
-/// there is no good implementation, and because the suggested bias may not
-/// exist, it is not implemented here.
-///
-/// ## Overview of the ISAAC algorithm:
-/// (in pseudo-code)
-///
-/// ```text
-/// Input: a, b, c, s[256] // state
-/// Output: r[256] // results
-///
-/// mix(a,i) = a ^ a << 13 if i = 0 mod 4
-/// a ^ a >> 6 if i = 1 mod 4
-/// a ^ a << 2 if i = 2 mod 4
-/// a ^ a >> 16 if i = 3 mod 4
-///
-/// c = c + 1
-/// b = b + c
-///
-/// for i in 0..256 {
-/// x = s_[i]
-/// a = f(a,i) + s[i+128 mod 256]
-/// y = a + b + s[x>>2 mod 256]
-/// s[i] = y
-/// b = x + s[y>>10 mod 256]
-/// r[i] = b
-/// }
-/// ```
-///
-/// Numbers are generated in blocks of 256. This means the function above only
-/// runs once every 256 times you ask for a next random number. In all other
-/// circumstances the last element of the results array is returned.
-///
-/// ISAAC therefore needs a lot of memory, relative to other non-crypto RNGs.
-/// 2 * 256 * 4 = 2 kb to hold the state and results.
-///
-/// This implementation uses [`BlockRng`] to implement the [`RngCore`] methods.
-///
-/// ## References
-/// [^1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number generator*](
-/// http://burtleburtle.net/bob/rand/isaacafa.html)
-///
-/// [^2]: Bob Jenkins, [*ISAAC and RC4*](
-/// http://burtleburtle.net/bob/rand/isaac.html)
-///
-/// [^3]: Jean-Philippe Aumasson, [*On the pseudo-random generator ISAAC*](
-/// https://eprint.iacr.org/2006/438)
-///
-/// [`rand_hc`]: https://docs.rs/rand_hc
-#[derive(Clone, Debug)]
-#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
-pub struct IsaacRng(BlockRng<IsaacCore>);
-
-impl RngCore for IsaacRng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- self.0.next_u32()
- }
-
- #[inline]
- fn next_u64(&mut self) -> u64 {
- self.0.next_u64()
- }
-
- #[inline]
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- self.0.fill_bytes(dest)
- }
-
- #[inline]
- fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- self.0.try_fill_bytes(dest)
- }
-}
-
-impl SeedableRng for IsaacRng {
- type Seed = <IsaacCore as SeedableRng>::Seed;
-
- #[inline]
- fn from_seed(seed: Self::Seed) -> Self {
- IsaacRng(BlockRng::<IsaacCore>::from_seed(seed))
- }
-
- /// Create an ISAAC random number generator using an `u64` as seed.
- /// If `seed == 0` this will produce the same stream of random numbers as
- /// the reference implementation when used unseeded.
- #[inline]
- fn seed_from_u64(seed: u64) -> Self {
- IsaacRng(BlockRng::<IsaacCore>::seed_from_u64(seed))
- }
-
- #[inline]
- fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
- BlockRng::<IsaacCore>::from_rng(rng).map(|rng| IsaacRng(rng))
- }
-}
-
-/// The core of [`IsaacRng`], used with [`BlockRng`].
-#[derive(Clone)]
-#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
-pub struct IsaacCore {
- #[cfg_attr(feature="serde1",serde(with="super::isaac_array::isaac_array_serde"))]
- mem: [w32; RAND_SIZE],
- a: w32,
- b: w32,
- c: w32,
-}
-
-// Custom Debug implementation that does not expose the internal state
-impl fmt::Debug for IsaacCore {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "IsaacCore {{}}")
- }
-}
-
-impl BlockRngCore for IsaacCore {
- type Item = u32;
- type Results = IsaacArray<Self::Item>;
-
- /// Refills the output buffer, `results`. See also the pseudocode desciption
- /// of the algorithm in the `IsaacRng` documentation.
- ///
- /// Optimisations used (similar to the reference implementation):
- ///
- /// - The loop is unrolled 4 times, once for every constant of mix().
- /// - The contents of the main loop are moved to a function `rngstep`, to
- /// reduce code duplication.
- /// - We use local variables for a and b, which helps with optimisations.
- /// - We split the main loop in two, one that operates over 0..128 and one
- /// over 128..256. This way we can optimise out the addition and modulus
- /// from `s[i+128 mod 256]`.
- /// - We maintain one index `i` and add `m` or `m2` as base (m2 for the
- /// `s[i+128 mod 256]`), relying on the optimizer to turn it into pointer
- /// arithmetic.
- /// - We fill `results` backwards. The reference implementation reads values
- /// from `results` in reverse. We read them in the normal direction, to
- /// make `fill_bytes` a memcopy. To maintain compatibility we fill in
- /// reverse.
- fn generate(&mut self, results: &mut IsaacArray<Self::Item>) {
- self.c += w(1);
- // abbreviations
- let mut a = self.a;
- let mut b = self.b + self.c;
- const MIDPOINT: usize = RAND_SIZE / 2;
-
- #[inline]
- fn ind(mem:&[w32; RAND_SIZE], v: w32, amount: usize) -> w32 {
- let index = (v >> amount).0 as usize % RAND_SIZE;
- mem[index]
- }
-
- #[inline]
- fn rngstep(mem: &mut [w32; RAND_SIZE],
- results: &mut [u32; RAND_SIZE],
- mix: w32,
- a: &mut w32,
- b: &mut w32,
- base: usize,
- m: usize,
- m2: usize) {
- let x = mem[base + m];
- *a = mix + mem[base + m2];
- let y = *a + *b + ind(&mem, x, 2);
- mem[base + m] = y;
- *b = x + ind(&mem, y, 2 + RAND_SIZE_LEN);
- results[RAND_SIZE - 1 - base - m] = (*b).0;
- }
-
- let mut m = 0;
- let mut m2 = MIDPOINT;
- for i in (0..MIDPOINT/4).map(|i| i * 4) {
- rngstep(&mut self.mem, results, a ^ (a << 13), &mut a, &mut b, i + 0, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 6 ), &mut a, &mut b, i + 1, m, m2);
- rngstep(&mut self.mem, results, a ^ (a << 2 ), &mut a, &mut b, i + 2, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 16), &mut a, &mut b, i + 3, m, m2);
- }
-
- m = MIDPOINT;
- m2 = 0;
- for i in (0..MIDPOINT/4).map(|i| i * 4) {
- rngstep(&mut self.mem, results, a ^ (a << 13), &mut a, &mut b, i + 0, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 6 ), &mut a, &mut b, i + 1, m, m2);
- rngstep(&mut self.mem, results, a ^ (a << 2 ), &mut a, &mut b, i + 2, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 16), &mut a, &mut b, i + 3, m, m2);
- }
-
- self.a = a;
- self.b = b;
- }
-}
-
-impl IsaacCore {
- /// Create a new ISAAC random number generator.
- ///
- /// The author Bob Jenkins describes how to best initialize ISAAC here:
- /// <https://rt.cpan.org/Public/Bug/Display.html?id=64324>
- /// The answer is included here just in case:
- ///
- /// "No, you don't need a full 8192 bits of seed data. Normal key sizes will
- /// do fine, and they should have their expected strength (eg a 40-bit key
- /// will take as much time to brute force as 40-bit keys usually will). You
- /// could fill the remainder with 0, but set the last array element to the
- /// length of the key provided (to distinguish keys that differ only by
- /// different amounts of 0 padding). You do still need to call `randinit()`
- /// to make sure the initial state isn't uniform-looking."
- /// "After publishing ISAAC, I wanted to limit the key to half the size of
- /// `r[]`, and repeat it twice. That would have made it hard to provide a
- /// key that sets the whole internal state to anything convenient. But I'd
- /// already published it."
- ///
- /// And his answer to the question "For my code, would repeating the key
- /// over and over to fill 256 integers be a better solution than
- /// zero-filling, or would they essentially be the same?":
- /// "If the seed is under 32 bytes, they're essentially the same, otherwise
- /// repeating the seed would be stronger. randinit() takes a chunk of 32
- /// bytes, mixes it, and combines that with the next 32 bytes, et cetera.
- /// Then loops over all the elements the same way a second time."
- #[inline]
- fn init(mut mem: [w32; RAND_SIZE], rounds: u32) -> Self {
- fn mix(a: &mut w32, b: &mut w32, c: &mut w32, d: &mut w32,
- e: &mut w32, f: &mut w32, g: &mut w32, h: &mut w32) {
- *a ^= *b << 11; *d += *a; *b += *c;
- *b ^= *c >> 2; *e += *b; *c += *d;
- *c ^= *d << 8; *f += *c; *d += *e;
- *d ^= *e >> 16; *g += *d; *e += *f;
- *e ^= *f << 10; *h += *e; *f += *g;
- *f ^= *g >> 4; *a += *f; *g += *h;
- *g ^= *h << 8; *b += *g; *h += *a;
- *h ^= *a >> 9; *c += *h; *a += *b;
- }
-
- // These numbers are the result of initializing a...h with the
- // fractional part of the golden ratio in binary (0x9e3779b9)
- // and applying mix() 4 times.
- let mut a = w(0x1367df5a);
- let mut b = w(0x95d90059);
- let mut c = w(0xc3163e4b);
- let mut d = w(0x0f421ad8);
- let mut e = w(0xd92a4a78);
- let mut f = w(0xa51a3c49);
- let mut g = w(0xc4efea1b);
- let mut h = w(0x30609119);
-
- // Normally this should do two passes, to make all of the seed effect
- // all of `mem`
- for _ in 0..rounds {
- for i in (0..RAND_SIZE/8).map(|i| i * 8) {
- a += mem[i ]; b += mem[i+1];
- c += mem[i+2]; d += mem[i+3];
- e += mem[i+4]; f += mem[i+5];
- g += mem[i+6]; h += mem[i+7];
- mix(&mut a, &mut b, &mut c, &mut d,
- &mut e, &mut f, &mut g, &mut h);
- mem[i ] = a; mem[i+1] = b;
- mem[i+2] = c; mem[i+3] = d;
- mem[i+4] = e; mem[i+5] = f;
- mem[i+6] = g; mem[i+7] = h;
- }
- }
-
- Self { mem, a: w(0), b: w(0), c: w(0) }
- }
-}
-
-impl SeedableRng for IsaacCore {
- type Seed = [u8; 32];
-
- fn from_seed(seed: Self::Seed) -> Self {
- let mut seed_u32 = [0u32; 8];
- le::read_u32_into(&seed, &mut seed_u32);
- // Convert the seed to `Wrapping<u32>` and zero-extend to `RAND_SIZE`.
- let mut seed_extended = [w(0); RAND_SIZE];
- for (x, y) in seed_extended.iter_mut().zip(seed_u32.iter()) {
- *x = w(*y);
- }
- Self::init(seed_extended, 2)
- }
-
- /// Create an ISAAC random number generator using an `u64` as seed.
- /// If `seed == 0` this will produce the same stream of random numbers as
- /// the reference implementation when used unseeded.
- fn seed_from_u64(seed: u64) -> Self {
- let mut key = [w(0); RAND_SIZE];
- key[0] = w(seed as u32);
- key[1] = w((seed >> 32) as u32);
- // Initialize with only one pass.
- // A second pass does not improve the quality here, because all of the
- // seed was already available in the first round.
- // Not doing the second pass has the small advantage that if
- // `seed == 0` this method produces exactly the same state as the
- // reference implementation when used unseeded.
- Self::init(key, 1)
- }
-
- fn from_rng<R: RngCore>(mut rng: R) -> Result<Self, Error> {
- // Custom `from_rng` implementation that fills a seed with the same size
- // as the entire state.
- let mut seed = [w(0u32); RAND_SIZE];
- unsafe {
- let ptr = seed.as_mut_ptr() as *mut u8;
-
- let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE * 4);
- rng.try_fill_bytes(slice)?;
- }
- for i in seed.iter_mut() {
- *i = w(i.0.to_le());
- }
-
- Ok(Self::init(seed, 2))
- }
-}
-
-#[cfg(test)]
-mod test {
- use rand_core::{RngCore, SeedableRng};
- use super::IsaacRng;
-
- #[test]
- fn test_isaac_construction() {
- // Test that various construction techniques produce a working RNG.
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng1 = IsaacRng::from_seed(seed);
- assert_eq!(rng1.next_u32(), 2869442790);
-
- let mut rng2 = IsaacRng::from_rng(rng1).unwrap();
- assert_eq!(rng2.next_u32(), 3094074039);
- }
-
- #[test]
- fn test_isaac_true_values_32() {
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 57,48,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng1 = IsaacRng::from_seed(seed);
- let mut results = [0u32; 10];
- for i in results.iter_mut() { *i = rng1.next_u32(); }
- let expected = [
- 2558573138, 873787463, 263499565, 2103644246, 3595684709,
- 4203127393, 264982119, 2765226902, 2737944514, 3900253796];
- assert_eq!(results, expected);
-
- let seed = [57,48,0,0, 50,9,1,0, 49,212,0,0, 148,38,0,0,
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng2 = IsaacRng::from_seed(seed);
- // skip forward to the 10000th number
- for _ in 0..10000 { rng2.next_u32(); }
-
- for i in results.iter_mut() { *i = rng2.next_u32(); }
- let expected = [
- 3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
- 1576568959, 3507990155, 179069555, 141456972, 2478885421];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac_true_values_64() {
- // As above, using little-endian versions of above values
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 57,48,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng = IsaacRng::from_seed(seed);
- let mut results = [0u64; 5];
- for i in results.iter_mut() { *i = rng.next_u64(); }
- let expected = [
- 3752888579798383186, 9035083239252078381,18052294697452424037,
- 11876559110374379111, 16751462502657800130];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac_true_bytes() {
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 57,48,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng = IsaacRng::from_seed(seed);
- let mut results = [0u8; 32];
- rng.fill_bytes(&mut results);
- // Same as first values in test_isaac_true_values as bytes in LE order
- let expected = [82, 186, 128, 152, 71, 240, 20, 52,
- 45, 175, 180, 15, 86, 16, 99, 125,
- 101, 203, 81, 214, 97, 162, 134, 250,
- 103, 78, 203, 15, 150, 3, 210, 164];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac_new_uninitialized() {
- // Compare the results from initializing `IsaacRng` with
- // `seed_from_u64(0)`, to make sure it is the same as the reference
- // implementation when used uninitialized.
- // Note: We only test the first 16 integers, not the full 256 of the
- // first block.
- let mut rng = IsaacRng::seed_from_u64(0);
- let mut results = [0u32; 16];
- for i in results.iter_mut() { *i = rng.next_u32(); }
- let expected: [u32; 16] = [
- 0x71D71FD2, 0xB54ADAE7, 0xD4788559, 0xC36129FA,
- 0x21DC1EA9, 0x3CB879CA, 0xD83B237F, 0xFA3CE5BD,
- 0x8D048509, 0xD82E9489, 0xDB452848, 0xCA20E846,
- 0x500F972E, 0x0EEFF940, 0x00D6B993, 0xBC12C17F];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac_clone() {
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 57,48,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng1 = IsaacRng::from_seed(seed);
- let mut rng2 = rng1.clone();
- for _ in 0..16 {
- assert_eq!(rng1.next_u32(), rng2.next_u32());
- }
- }
-
- #[test]
- #[cfg(feature="serde1")]
- fn test_isaac_serde() {
- use bincode;
- use std::io::{BufWriter, BufReader};
-
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 57,48,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng = IsaacRng::from_seed(seed);
-
- let buf: Vec<u8> = Vec::new();
- let mut buf = BufWriter::new(buf);
- bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");
-
- let buf = buf.into_inner().unwrap();
- let mut read = BufReader::new(&buf[..]);
- let mut deserialized: IsaacRng = bincode::deserialize_from(&mut read).expect("Could not deserialize");
-
- for _ in 0..300 { // more than the 256 buffered results
- assert_eq!(rng.next_u32(), deserialized.next_u32());
- }
- }
-}
diff --git a/rand/rand_isaac/src/isaac64.rs b/rand/rand_isaac/src/isaac64.rs
deleted file mode 100644
index 7d4b88c..0000000
--- a/rand/rand_isaac/src/isaac64.rs
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-// Copyright 2013-2018 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.
-
-//! The ISAAC-64 random number generator.
-
-use core::{fmt, slice};
-use core::num::Wrapping as w;
-#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
-use rand_core::{RngCore, SeedableRng, Error, le};
-use rand_core::block::{BlockRngCore, BlockRng64};
-use crate::isaac_array::IsaacArray;
-
-#[allow(non_camel_case_types)]
-type w64 = w<u64>;
-
-const RAND_SIZE_LEN: usize = 8;
-const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
-
-/// A random number generator that uses ISAAC-64, the 64-bit variant of the
-/// ISAAC algorithm.
-///
-/// ISAAC stands for "Indirection, Shift, Accumulate, Add, and Count" which are
-/// the principal bitwise operations employed. It is the most advanced of a
-/// series of array based random number generator designed by Robert Jenkins
-/// in 1996[^1].
-///
-/// ISAAC-64 is mostly similar to ISAAC. Because it operates on 64-bit integers
-/// instead of 32-bit, it uses twice as much memory to hold its state and
-/// results. Also it uses different constants for shifts and indirect indexing,
-/// optimized to give good results for 64bit arithmetic.
-///
-/// ISAAC-64 is notably fast and produces excellent quality random numbers for
-/// non-cryptographic applications.
-///
-/// In spite of being designed with cryptographic security in mind, ISAAC hasn't
-/// been stringently cryptanalyzed and thus cryptographers do not not
-/// consensually trust it to be secure. When looking for a secure RNG, prefer
-/// `Hc128Rng` from the [`rand_hc`] crate instead, which, like ISAAC, is an
-/// array-based RNG and one of the stream-ciphers selected the by eSTREAM
-///
-/// ## Overview of the ISAAC-64 algorithm:
-/// (in pseudo-code)
-///
-/// ```text
-/// Input: a, b, c, s[256] // state
-/// Output: r[256] // results
-///
-/// mix(a,i) = !(a ^ a << 21) if i = 0 mod 4
-/// a ^ a >> 5 if i = 1 mod 4
-/// a ^ a << 12 if i = 2 mod 4
-/// a ^ a >> 33 if i = 3 mod 4
-///
-/// c = c + 1
-/// b = b + c
-///
-/// for i in 0..256 {
-/// x = s_[i]
-/// a = mix(a,i) + s[i+128 mod 256]
-/// y = a + b + s[x>>3 mod 256]
-/// s[i] = y
-/// b = x + s[y>>11 mod 256]
-/// r[i] = b
-/// }
-/// ```
-///
-/// This implementation uses [`BlockRng64`] to implement the [`RngCore`] methods.
-///
-/// See for more information the documentation of [`IsaacRng`].
-///
-/// [^1]: Bob Jenkins, [*ISAAC and RC4*](
-/// http://burtleburtle.net/bob/rand/isaac.html)
-///
-/// [`IsaacRng`]: crate::isaac::IsaacRng
-/// [`rand_hc`]: https://docs.rs/rand_hc
-/// [`BlockRng64`]: rand_core::block::BlockRng64
-#[derive(Clone, Debug)]
-#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
-pub struct Isaac64Rng(BlockRng64<Isaac64Core>);
-
-impl RngCore for Isaac64Rng {
- #[inline]
- fn next_u32(&mut self) -> u32 {
- self.0.next_u32()
- }
-
- #[inline]
- fn next_u64(&mut self) -> u64 {
- self.0.next_u64()
- }
-
- #[inline]
- fn fill_bytes(&mut self, dest: &mut [u8]) {
- self.0.fill_bytes(dest)
- }
-
- #[inline]
- fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
- self.0.try_fill_bytes(dest)
- }
-}
-
-impl SeedableRng for Isaac64Rng {
- type Seed = <Isaac64Core as SeedableRng>::Seed;
-
- #[inline]
- fn from_seed(seed: Self::Seed) -> Self {
- Isaac64Rng(BlockRng64::<Isaac64Core>::from_seed(seed))
- }
-
- /// Create an ISAAC random number generator using an `u64` as seed.
- /// If `seed == 0` this will produce the same stream of random numbers as
- /// the reference implementation when used unseeded.
- #[inline]
- fn seed_from_u64(seed: u64) -> Self {
- Isaac64Rng(BlockRng64::<Isaac64Core>::seed_from_u64(seed))
- }
-
- #[inline]
- fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
- BlockRng64::<Isaac64Core>::from_rng(rng).map(|rng| Isaac64Rng(rng))
- }
-}
-
-/// The core of `Isaac64Rng`, used with `BlockRng`.
-#[derive(Clone)]
-#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
-pub struct Isaac64Core {
- #[cfg_attr(feature="serde1",serde(with="super::isaac_array::isaac_array_serde"))]
- mem: [w64; RAND_SIZE],
- a: w64,
- b: w64,
- c: w64,
-}
-
-// Custom Debug implementation that does not expose the internal state
-impl fmt::Debug for Isaac64Core {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Isaac64Core {{}}")
- }
-}
-
-impl BlockRngCore for Isaac64Core {
- type Item = u64;
- type Results = IsaacArray<Self::Item>;
-
- /// Refills the output buffer, `results`. See also the pseudocode desciption
- /// of the algorithm in the `Isaac64Rng` documentation.
- ///
- /// Optimisations used (similar to the reference implementation):
- ///
- /// - The loop is unrolled 4 times, once for every constant of mix().
- /// - The contents of the main loop are moved to a function `rngstep`, to
- /// reduce code duplication.
- /// - We use local variables for a and b, which helps with optimisations.
- /// - We split the main loop in two, one that operates over 0..128 and one
- /// over 128..256. This way we can optimise out the addition and modulus
- /// from `s[i+128 mod 256]`.
- /// - We maintain one index `i` and add `m` or `m2` as base (m2 for the
- /// `s[i+128 mod 256]`), relying on the optimizer to turn it into pointer
- /// arithmetic.
- /// - We fill `results` backwards. The reference implementation reads values
- /// from `results` in reverse. We read them in the normal direction, to
- /// make `fill_bytes` a memcopy. To maintain compatibility we fill in
- /// reverse.
- fn generate(&mut self, results: &mut IsaacArray<Self::Item>) {
- self.c += w(1);
- // abbreviations
- let mut a = self.a;
- let mut b = self.b + self.c;
- const MIDPOINT: usize = RAND_SIZE / 2;
-
- #[inline]
- fn ind(mem:&[w64; RAND_SIZE], v: w64, amount: usize) -> w64 {
- let index = (v >> amount).0 as usize % RAND_SIZE;
- mem[index]
- }
-
- #[inline]
- fn rngstep(mem: &mut [w64; RAND_SIZE],
- results: &mut [u64; RAND_SIZE],
- mix: w64,
- a: &mut w64,
- b: &mut w64,
- base: usize,
- m: usize,
- m2: usize) {
- let x = mem[base + m];
- *a = mix + mem[base + m2];
- let y = *a + *b + ind(&mem, x, 3);
- mem[base + m] = y;
- *b = x + ind(&mem, y, 3 + RAND_SIZE_LEN);
- results[RAND_SIZE - 1 - base - m] = (*b).0;
- }
-
- let mut m = 0;
- let mut m2 = MIDPOINT;
- for i in (0..MIDPOINT/4).map(|i| i * 4) {
- rngstep(&mut self.mem, results, !(a ^ (a << 21)), &mut a, &mut b, i + 0, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 5 ), &mut a, &mut b, i + 1, m, m2);
- rngstep(&mut self.mem, results, a ^ (a << 12), &mut a, &mut b, i + 2, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 33), &mut a, &mut b, i + 3, m, m2);
- }
-
- m = MIDPOINT;
- m2 = 0;
- for i in (0..MIDPOINT/4).map(|i| i * 4) {
- rngstep(&mut self.mem, results, !(a ^ (a << 21)), &mut a, &mut b, i + 0, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 5 ), &mut a, &mut b, i + 1, m, m2);
- rngstep(&mut self.mem, results, a ^ (a << 12), &mut a, &mut b, i + 2, m, m2);
- rngstep(&mut self.mem, results, a ^ (a >> 33), &mut a, &mut b, i + 3, m, m2);
- }
-
- self.a = a;
- self.b = b;
- }
-}
-
-impl Isaac64Core {
- /// Create a new ISAAC-64 random number generator.
- fn init(mut mem: [w64; RAND_SIZE], rounds: u32) -> Self {
- fn mix(a: &mut w64, b: &mut w64, c: &mut w64, d: &mut w64,
- e: &mut w64, f: &mut w64, g: &mut w64, h: &mut w64) {
- *a -= *e; *f ^= *h >> 9; *h += *a;
- *b -= *f; *g ^= *a << 9; *a += *b;
- *c -= *g; *h ^= *b >> 23; *b += *c;
- *d -= *h; *a ^= *c << 15; *c += *d;
- *e -= *a; *b ^= *d >> 14; *d += *e;
- *f -= *b; *c ^= *e << 20; *e += *f;
- *g -= *c; *d ^= *f >> 17; *f += *g;
- *h -= *d; *e ^= *g << 14; *g += *h;
- }
-
- // These numbers are the result of initializing a...h with the
- // fractional part of the golden ratio in binary (0x9e3779b97f4a7c13)
- // and applying mix() 4 times.
- let mut a = w(0x647c4677a2884b7c);
- let mut b = w(0xb9f8b322c73ac862);
- let mut c = w(0x8c0ea5053d4712a0);
- let mut d = w(0xb29b2e824a595524);
- let mut e = w(0x82f053db8355e0ce);
- let mut f = w(0x48fe4a0fa5a09315);
- let mut g = w(0xae985bf2cbfc89ed);
- let mut h = w(0x98f5704f6c44c0ab);
-
- // Normally this should do two passes, to make all of the seed effect
- // all of `mem`
- for _ in 0..rounds {
- for i in (0..RAND_SIZE/8).map(|i| i * 8) {
- a += mem[i ]; b += mem[i+1];
- c += mem[i+2]; d += mem[i+3];
- e += mem[i+4]; f += mem[i+5];
- g += mem[i+6]; h += mem[i+7];
- mix(&mut a, &mut b, &mut c, &mut d,
- &mut e, &mut f, &mut g, &mut h);
- mem[i ] = a; mem[i+1] = b;
- mem[i+2] = c; mem[i+3] = d;
- mem[i+4] = e; mem[i+5] = f;
- mem[i+6] = g; mem[i+7] = h;
- }
- }
-
- Self { mem, a: w(0), b: w(0), c: w(0) }
- }
-}
-
-impl SeedableRng for Isaac64Core {
- type Seed = [u8; 32];
-
- fn from_seed(seed: Self::Seed) -> Self {
- let mut seed_u64 = [0u64; 4];
- le::read_u64_into(&seed, &mut seed_u64);
- // Convert the seed to `Wrapping<u64>` and zero-extend to `RAND_SIZE`.
- let mut seed_extended = [w(0); RAND_SIZE];
- for (x, y) in seed_extended.iter_mut().zip(seed_u64.iter()) {
- *x = w(*y);
- }
- Self::init(seed_extended, 2)
- }
-
- fn seed_from_u64(seed: u64) -> Self {
- let mut key = [w(0); RAND_SIZE];
- key[0] = w(seed);
- // Initialize with only one pass.
- // A second pass does not improve the quality here, because all of the
- // seed was already available in the first round.
- // Not doing the second pass has the small advantage that if
- // `seed == 0` this method produces exactly the same state as the
- // reference implementation when used unseeded.
- Self::init(key, 1)
- }
-
- fn from_rng<R: RngCore>(mut rng: R) -> Result<Self, Error> {
- // Custom `from_rng` implementation that fills a seed with the same size
- // as the entire state.
- let mut seed = [w(0u64); RAND_SIZE];
- unsafe {
- let ptr = seed.as_mut_ptr() as *mut u8;
- let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE * 8);
- rng.try_fill_bytes(slice)?;
- }
- for i in seed.iter_mut() {
- *i = w(i.0.to_le());
- }
-
- Ok(Self::init(seed, 2))
- }
-}
-
-#[cfg(test)]
-mod test {
- use rand_core::{RngCore, SeedableRng};
- use super::Isaac64Rng;
-
- #[test]
- fn test_isaac64_construction() {
- // Test that various construction techniques produce a working RNG.
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng1 = Isaac64Rng::from_seed(seed);
- assert_eq!(rng1.next_u64(), 14964555543728284049);
-
- let mut rng2 = Isaac64Rng::from_rng(rng1).unwrap();
- assert_eq!(rng2.next_u64(), 919595328260451758);
- }
-
- #[test]
- fn test_isaac64_true_values_64() {
- let seed = [1,0,0,0, 0,0,0,0, 23,0,0,0, 0,0,0,0,
- 200,1,0,0, 0,0,0,0, 210,30,0,0, 0,0,0,0];
- let mut rng1 = Isaac64Rng::from_seed(seed);
- let mut results = [0u64; 10];
- for i in results.iter_mut() { *i = rng1.next_u64(); }
- let expected = [
- 15071495833797886820, 7720185633435529318,
- 10836773366498097981, 5414053799617603544,
- 12890513357046278984, 17001051845652595546,
- 9240803642279356310, 12558996012687158051,
- 14673053937227185542, 1677046725350116783];
- assert_eq!(results, expected);
-
- let seed = [57,48,0,0, 0,0,0,0, 50,9,1,0, 0,0,0,0,
- 49,212,0,0, 0,0,0,0, 148,38,0,0, 0,0,0,0];
- let mut rng2 = Isaac64Rng::from_seed(seed);
- // skip forward to the 10000th number
- for _ in 0..10000 { rng2.next_u64(); }
-
- for i in results.iter_mut() { *i = rng2.next_u64(); }
- let expected = [
- 18143823860592706164, 8491801882678285927, 2699425367717515619,
- 17196852593171130876, 2606123525235546165, 15790932315217671084,
- 596345674630742204, 9947027391921273664, 11788097613744130851,
- 10391409374914919106];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac64_true_values_32() {
- let seed = [1,0,0,0, 0,0,0,0, 23,0,0,0, 0,0,0,0,
- 200,1,0,0, 0,0,0,0, 210,30,0,0, 0,0,0,0];
- let mut rng = Isaac64Rng::from_seed(seed);
- let mut results = [0u32; 12];
- for i in results.iter_mut() { *i = rng.next_u32(); }
- // Subset of above values, as an LE u32 sequence
- let expected = [
- 3477963620, 3509106075,
- 687845478, 1797495790,
- 227048253, 2523132918,
- 4044335064, 1260557630,
- 4079741768, 3001306521,
- 69157722, 3958365844];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac64_true_values_mixed() {
- let seed = [1,0,0,0, 0,0,0,0, 23,0,0,0, 0,0,0,0,
- 200,1,0,0, 0,0,0,0, 210,30,0,0, 0,0,0,0];
- let mut rng = Isaac64Rng::from_seed(seed);
- // Test alternating between `next_u64` and `next_u32` works as expected.
- // Values are the same as `test_isaac64_true_values` and
- // `test_isaac64_true_values_32`.
- assert_eq!(rng.next_u64(), 15071495833797886820);
- assert_eq!(rng.next_u32(), 687845478);
- assert_eq!(rng.next_u32(), 1797495790);
- assert_eq!(rng.next_u64(), 10836773366498097981);
- assert_eq!(rng.next_u32(), 4044335064);
- // Skip one u32
- assert_eq!(rng.next_u64(), 12890513357046278984);
- assert_eq!(rng.next_u32(), 69157722);
- }
-
- #[test]
- fn test_isaac64_true_bytes() {
- let seed = [1,0,0,0, 0,0,0,0, 23,0,0,0, 0,0,0,0,
- 200,1,0,0, 0,0,0,0, 210,30,0,0, 0,0,0,0];
- let mut rng = Isaac64Rng::from_seed(seed);
- let mut results = [0u8; 32];
- rng.fill_bytes(&mut results);
- // Same as first values in test_isaac64_true_values as bytes in LE order
- let expected = [100, 131, 77, 207, 155, 181, 40, 209,
- 102, 176, 255, 40, 238, 155, 35, 107,
- 61, 123, 136, 13, 246, 243, 99, 150,
- 216, 167, 15, 241, 62, 149, 34, 75];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac64_new_uninitialized() {
- // Compare the results from initializing `IsaacRng` with
- // `seed_from_u64(0)`, to make sure it is the same as the reference
- // implementation when used uninitialized.
- // Note: We only test the first 16 integers, not the full 256 of the
- // first block.
- let mut rng = Isaac64Rng::seed_from_u64(0);
- let mut results = [0u64; 16];
- for i in results.iter_mut() { *i = rng.next_u64(); }
- let expected: [u64; 16] = [
- 0xF67DFBA498E4937C, 0x84A5066A9204F380, 0xFEE34BD5F5514DBB,
- 0x4D1664739B8F80D6, 0x8607459AB52A14AA, 0x0E78BC5A98529E49,
- 0xFE5332822AD13777, 0x556C27525E33D01A, 0x08643CA615F3149F,
- 0xD0771FAF3CB04714, 0x30E86F68A37B008D, 0x3074EBC0488A3ADF,
- 0x270645EA7A2790BC, 0x5601A0A8D3763C6A, 0x2F83071F53F325DD,
- 0xB9090F3D42D2D2EA];
- assert_eq!(results, expected);
- }
-
- #[test]
- fn test_isaac64_clone() {
- let seed = [1,0,0,0, 0,0,0,0, 23,0,0,0, 0,0,0,0,
- 200,1,0,0, 0,0,0,0, 210,30,0,0, 0,0,0,0];
- let mut rng1 = Isaac64Rng::from_seed(seed);
- let mut rng2 = rng1.clone();
- for _ in 0..16 {
- assert_eq!(rng1.next_u64(), rng2.next_u64());
- }
- }
-
- #[test]
- #[cfg(feature="serde1")]
- fn test_isaac64_serde() {
- use bincode;
- use std::io::{BufWriter, BufReader};
-
- let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
- 57,48,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
- let mut rng = Isaac64Rng::from_seed(seed);
-
- let buf: Vec<u8> = Vec::new();
- let mut buf = BufWriter::new(buf);
- bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");
-
- let buf = buf.into_inner().unwrap();
- let mut read = BufReader::new(&buf[..]);
- let mut deserialized: Isaac64Rng = bincode::deserialize_from(&mut read).expect("Could not deserialize");
-
- for _ in 0..300 { // more than the 256 buffered results
- assert_eq!(rng.next_u64(), deserialized.next_u64());
- }
- }
-}
diff --git a/rand/rand_isaac/src/isaac_array.rs b/rand/rand_isaac/src/isaac_array.rs
deleted file mode 100644
index cbe4a59..0000000
--- a/rand/rand_isaac/src/isaac_array.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-// Copyright 2017-2018 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.
-
-//! ISAAC helper functions for 256-element arrays.
-
-// Terrible workaround because arrays with more than 32 elements do not
-// implement `AsRef`, `Default`, `Serialize`, `Deserialize`, or any other
-// traits for that matter.
-
-#[cfg(feature="serde")] use serde::{Serialize, Deserialize};
-
-const RAND_SIZE_LEN: usize = 8;
-const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
-
-
-#[derive(Copy, Clone)]
-#[allow(missing_debug_implementations)]
-#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
-pub struct IsaacArray<T> {
- #[cfg_attr(feature="serde",serde(with="isaac_array_serde"))]
- #[cfg_attr(feature="serde", serde(bound(
- serialize = "T: Serialize",
- deserialize = "T: Deserialize<'de> + Copy + Default")))]
- inner: [T; RAND_SIZE]
-}
-
-impl<T> ::core::convert::AsRef<[T]> for IsaacArray<T> {
- #[inline(always)]
- fn as_ref(&self) -> &[T] {
- &self.inner[..]
- }
-}
-
-impl<T> ::core::convert::AsMut<[T]> for IsaacArray<T> {
- #[inline(always)]
- fn as_mut(&mut self) -> &mut [T] {
- &mut self.inner[..]
- }
-}
-
-impl<T> ::core::ops::Deref for IsaacArray<T> {
- type Target = [T; RAND_SIZE];
- #[inline(always)]
- fn deref(&self) -> &Self::Target {
- &self.inner
- }
-}
-
-impl<T> ::core::ops::DerefMut for IsaacArray<T> {
- #[inline(always)]
- fn deref_mut(&mut self) -> &mut [T; RAND_SIZE] {
- &mut self.inner
- }
-}
-
-impl<T> ::core::default::Default for IsaacArray<T> where T: Copy + Default {
- fn default() -> IsaacArray<T> {
- IsaacArray { inner: [T::default(); RAND_SIZE] }
- }
-}
-
-
-#[cfg(feature="serde")]
-pub(super) mod isaac_array_serde {
- const RAND_SIZE_LEN: usize = 8;
- const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
-
- use serde::{Deserialize, Deserializer, Serialize, Serializer};
- use serde::de::{Visitor,SeqAccess};
- use serde::de;
-
- use core::fmt;
-
- pub fn serialize<T, S>(arr: &[T;RAND_SIZE], ser: S) -> Result<S::Ok, S::Error>
- where
- T: Serialize,
- S: Serializer
- {
- use serde::ser::SerializeTuple;
-
- let mut seq = ser.serialize_tuple(RAND_SIZE)?;
-
- for e in arr.iter() {
- seq.serialize_element(&e)?;
- }
-
- seq.end()
- }
-
- #[inline]
- pub fn deserialize<'de, T, D>(de: D) -> Result<[T;RAND_SIZE], D::Error>
- where
- T: Deserialize<'de>+Default+Copy,
- D: Deserializer<'de>,
- {
- use core::marker::PhantomData;
- struct ArrayVisitor<T> {
- _pd: PhantomData<T>,
- };
- impl<'de,T> Visitor<'de> for ArrayVisitor<T>
- where
- T: Deserialize<'de>+Default+Copy
- {
- type Value = [T; RAND_SIZE];
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("Isaac state array")
- }
-
- #[inline]
- fn visit_seq<A>(self, mut seq: A) -> Result<[T; RAND_SIZE], A::Error>
- where
- A: SeqAccess<'de>,
- {
- let mut out = [Default::default();RAND_SIZE];
-
- for i in 0..RAND_SIZE {
- match seq.next_element()? {
- Some(val) => out[i] = val,
- None => return Err(de::Error::invalid_length(i, &self)),
- };
- }
-
- Ok(out)
- }
- }
-
- de.deserialize_tuple(RAND_SIZE, ArrayVisitor{_pd: PhantomData})
- }
-}
diff --git a/rand/rand_isaac/src/lib.rs b/rand/rand_isaac/src/lib.rs
deleted file mode 100644
index 84cdf21..0000000
--- a/rand/rand_isaac/src/lib.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// 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.
-
-//! The ISAAC and ISAAC-64 random number generators.
-
-#![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))))]
-
-#![cfg_attr(not(all(feature="serde", test)), no_std)]
-
-pub mod isaac;
-pub mod isaac64;
-
-mod isaac_array;
-
-pub use self::isaac::IsaacRng;
-pub use self::isaac64::Isaac64Rng;