diff options
author | Daniel Mueller <deso@posteo.net> | 2020-04-04 14:39:19 -0700 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2020-04-04 14:39:19 -0700 |
commit | d0d9683df8398696147e7ee1fcffb2e4e957008c (patch) | |
tree | 4baa76712a76f4d072ee3936c07956580b230820 /rand/rand_isaac | |
parent | 203e691f46d591a2cc8acdfd850fa9f5b0fb8a98 (diff) | |
download | nitrocli-d0d9683df8398696147e7ee1fcffb2e4e957008c.tar.gz nitrocli-d0d9683df8398696147e7ee1fcffb2e4e957008c.tar.bz2 |
Remove vendored dependencies
While it appears that by now we actually can get successful builds
without Cargo insisting on Internet access by virtue of using the
--frozen flag, maintaining vendored dependencies is somewhat of a pain
point. This state will also get worse with upcoming changes that replace
argparse in favor of structopt and pull in a slew of new dependencies by
doing so. Then there is also the repository structure aspect, which is
non-standard due to the way we vendor dependencies and a potential
source of confusion.
In order to fix these problems, this change removes all the vendored
dependencies we have.
Delete subrepo argparse/:argparse
Delete subrepo base32/:base32
Delete subrepo cc/:cc
Delete subrepo cfg-if/:cfg-if
Delete subrepo getrandom/:getrandom
Delete subrepo lazy-static/:lazy-static
Delete subrepo libc/:libc
Delete subrepo nitrokey-sys/:nitrokey-sys
Delete subrepo nitrokey/:nitrokey
Delete subrepo rand/:rand
Diffstat (limited to 'rand/rand_isaac')
-rw-r--r-- | rand/rand_isaac/CHANGELOG.md | 21 | ||||
-rw-r--r-- | rand/rand_isaac/COPYRIGHT | 12 | ||||
-rw-r--r-- | rand/rand_isaac/Cargo.toml | 31 | ||||
-rw-r--r-- | rand/rand_isaac/LICENSE-APACHE | 201 | ||||
-rw-r--r-- | rand/rand_isaac/LICENSE-MIT | 26 | ||||
-rw-r--r-- | rand/rand_isaac/README.md | 47 | ||||
-rw-r--r-- | rand/rand_isaac/src/isaac.rs | 476 | ||||
-rw-r--r-- | rand/rand_isaac/src/isaac64.rs | 466 | ||||
-rw-r--r-- | rand/rand_isaac/src/isaac_array.rs | 136 | ||||
-rw-r--r-- | rand/rand_isaac/src/lib.rs | 27 |
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; |