diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-16 17:26:30 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-16 17:26:30 -0800 |
commit | 8350ac6afb2d678b74581000a6aafe1994b72231 (patch) | |
tree | 2330da01a806921b3849c9e64d2b9f506495e2c0 /rand/rand_xoshiro/src/common.rs | |
parent | d6652b913b33e432a748187f9f5623cec1e9926e (diff) | |
download | nitrocli-8350ac6afb2d678b74581000a6aafe1994b72231.tar.gz nitrocli-8350ac6afb2d678b74581000a6aafe1994b72231.tar.bz2 |
Update nitrokey crate to 0.3.3
This change updates the nitrokey crate to version 0.3.3. Along with that
change we update rand to 0.6.4 because rand 0.6.1 does not yet contain a
publicly accessible rand_os. Note that we no longer require all
crates in rand's workspace, but only rand_os and rand_core, which is a
significant reduction in the number of lines of code compiled.
Import subrepo nitrokey/:nitrokey at 7cf747d56ddc0b7eeedc3caf36dcc909907a171c
Import subrepo rand/:rand at 4336232dda03323634b10ec72ddf27914aebc3a2
Diffstat (limited to 'rand/rand_xoshiro/src/common.rs')
-rw-r--r-- | rand/rand_xoshiro/src/common.rs | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/rand/rand_xoshiro/src/common.rs b/rand/rand_xoshiro/src/common.rs new file mode 100644 index 0000000..9ee09e2 --- /dev/null +++ b/rand/rand_xoshiro/src/common.rs @@ -0,0 +1,243 @@ +// 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. + +/// Initialize a RNG from a `u64` seed using `SplitMix64`. +macro_rules! from_splitmix { + ($seed:expr) => { { + let mut rng = ::SplitMix64::seed_from_u64($seed); + Self::from_rng(&mut rng).unwrap() + } } +} + +/// Apply the ** scrambler used by some RNGs from the xoshiro family. +macro_rules! starstar_u64 { + ($x:expr) => { + $x.wrapping_mul(5).rotate_left(7).wrapping_mul(9) + } +} + +/// Apply the ** scrambler used by some RNGs from the xoshiro family. +macro_rules! starstar_u32 { + ($x:expr) => { + $x.wrapping_mul(0x9E3779BB).rotate_left(5).wrapping_mul(5) + } +} + +/// Implement a jump function for an RNG from the xoshiro family. +macro_rules! impl_jump { + (u32, $self:expr, [$j0:expr, $j1:expr]) => { + const JUMP: [u32; 2] = [$j0, $j1]; + let mut s0 = 0; + let mut s1 = 0; + for j in &JUMP { + for b in 0..32 { + if (j & 1 << b) != 0 { + s0 ^= $self.s0; + s1 ^= $self.s1; + } + $self.next_u32(); + } + } + $self.s0 = s0; + $self.s1 = s1; + }; + (u64, $self:expr, [$j0:expr, $j1:expr]) => { + const JUMP: [u64; 2] = [$j0, $j1]; + let mut s0 = 0; + let mut s1 = 0; + for j in &JUMP { + for b in 0..64 { + if (j & 1 << b) != 0 { + s0 ^= $self.s0; + s1 ^= $self.s1; + } + $self.next_u64(); + } + } + $self.s0 = s0; + $self.s1 = s1; + }; + (u32, $self:expr, [$j0:expr, $j1:expr, $j2:expr, $j3:expr]) => { + const JUMP: [u32; 4] = [$j0, $j1, $j2, $j3]; + let mut s0 = 0; + let mut s1 = 0; + let mut s2 = 0; + let mut s3 = 0; + for j in &JUMP { + for b in 0..32 { + if (j & 1 << b) != 0 { + s0 ^= $self.s[0]; + s1 ^= $self.s[1]; + s2 ^= $self.s[2]; + s3 ^= $self.s[3]; + } + $self.next_u32(); + } + } + $self.s[0] = s0; + $self.s[1] = s1; + $self.s[2] = s2; + $self.s[3] = s3; + }; + (u64, $self:expr, [$j0:expr, $j1:expr, $j2:expr, $j3:expr]) => { + const JUMP: [u64; 4] = [$j0, $j1, $j2, $j3]; + let mut s0 = 0; + let mut s1 = 0; + let mut s2 = 0; + let mut s3 = 0; + for j in &JUMP { + for b in 0..64 { + if (j & 1 << b) != 0 { + s0 ^= $self.s[0]; + s1 ^= $self.s[1]; + s2 ^= $self.s[2]; + s3 ^= $self.s[3]; + } + $self.next_u64(); + } + } + $self.s[0] = s0; + $self.s[1] = s1; + $self.s[2] = s2; + $self.s[3] = s3; + }; + (u64, $self:expr, [$j0:expr, $j1:expr, $j2:expr, $j3:expr, + $j4:expr, $j5:expr, $j6:expr, $j7:expr]) => { + const JUMP: [u64; 8] = [$j0, $j1, $j2, $j3, $j4, $j5, $j6, $j7]; + let mut s = [0; 8]; + for j in &JUMP { + for b in 0..64 { + if (j & 1 << b) != 0 { + s[0] ^= $self.s[0]; + s[1] ^= $self.s[1]; + s[2] ^= $self.s[2]; + s[3] ^= $self.s[3]; + s[4] ^= $self.s[4]; + s[5] ^= $self.s[5]; + s[6] ^= $self.s[6]; + s[7] ^= $self.s[7]; + } + $self.next_u64(); + } + } + $self.s = s; + }; +} + +/// Implement the xoroshiro iteration. +macro_rules! impl_xoroshiro_u32 { + ($self:expr) => { + $self.s1 ^= $self.s0; + $self.s0 = $self.s0.rotate_left(26) ^ $self.s1 ^ ($self.s1 << 9); + $self.s1 = $self.s1.rotate_left(13); + } +} + +/// Implement the xoroshiro iteration. +macro_rules! impl_xoroshiro_u64 { + ($self:expr) => { + $self.s1 ^= $self.s0; + $self.s0 = $self.s0.rotate_left(24) ^ $self.s1 ^ ($self.s1 << 16); + $self.s1 = $self.s1.rotate_left(37); + } +} + +/// Implement the xoshiro iteration for `u32` output. +macro_rules! impl_xoshiro_u32 { + ($self:expr) => { + let t = $self.s[1] << 9; + + $self.s[2] ^= $self.s[0]; + $self.s[3] ^= $self.s[1]; + $self.s[1] ^= $self.s[2]; + $self.s[0] ^= $self.s[3]; + + $self.s[2] ^= t; + + $self.s[3] = $self.s[3].rotate_left(11); + } +} + +/// Implement the xoshiro iteration for `u64` output. +macro_rules! impl_xoshiro_u64 { + ($self:expr) => { + let t = $self.s[1] << 17; + + $self.s[2] ^= $self.s[0]; + $self.s[3] ^= $self.s[1]; + $self.s[1] ^= $self.s[2]; + $self.s[0] ^= $self.s[3]; + + $self.s[2] ^= t; + + $self.s[3] = $self.s[3].rotate_left(45); + } +} + +/// Implement the large-state xoshiro iteration. +macro_rules! impl_xoshiro_large { + ($self:expr) => { + let t = $self.s[1] << 11; + + $self.s[2] ^= $self.s[0]; + $self.s[5] ^= $self.s[1]; + $self.s[1] ^= $self.s[2]; + $self.s[7] ^= $self.s[3]; + $self.s[3] ^= $self.s[4]; + $self.s[4] ^= $self.s[5]; + $self.s[0] ^= $self.s[6]; + $self.s[6] ^= $self.s[7]; + + $self.s[6] ^= t; + + $self.s[7] = $self.s[7].rotate_left(21); + } +} + +/// Map an all-zero seed to a different one. +macro_rules! deal_with_zero_seed { + ($seed:expr, $Self:ident) => { + if $seed.iter().all(|&x| x == 0) { + return $Self::seed_from_u64(0); + } + } +} + +/// 512-bit seed for a generator. +/// +/// This wrapper is necessary, because some traits required for a seed are not +/// implemented on large arrays. +#[derive(Clone)] +pub struct Seed512(pub [u8; 64]); + +use core; +impl Seed512 { + /// Return an iterator over the seed. + pub fn iter(&self) -> core::slice::Iter<u8> { + self.0.iter() + } +} + +impl core::fmt::Debug for Seed512 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0[..].fmt(f) + } +} + +impl Default for Seed512 { + fn default() -> Seed512 { + Seed512([0; 64]) + } +} + +impl AsMut<[u8]> for Seed512 { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0 + } +} + |