Struct rand_isaac::isaac::IsaacCore

source ·
pub struct IsaacCore {
    mem: [Wrapping<u32>; 256],
    a: Wrapping<u32>,
    b: Wrapping<u32>,
    c: Wrapping<u32>,
}
Expand description

The core of IsaacRng, used with BlockRng.

Fields§

§mem: [Wrapping<u32>; 256]§a: Wrapping<u32>§b: Wrapping<u32>§c: Wrapping<u32>

Implementations§

source§

impl IsaacCore

source

fn init(mem: [Wrapping<u32>; 256], rounds: u32) -> Self

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.”

Trait Implementations§

source§

impl BlockRngCore for IsaacCore

source§

fn generate(&mut self, results: &mut 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.
source§

type Item = u32

Results element type, e.g. u32.
source§

type Results = IsaacArray<<IsaacCore as BlockRngCore>::Item>

Results type. This is the ‘block’ an RNG implementing BlockRngCore generates, which will usually be an array like [u32; 16].
source§

impl Clone for IsaacCore

source§

fn clone(&self) -> IsaacCore

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for IsaacCore

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for IsaacCore

source§

fn eq(&self, other: &IsaacCore) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl SeedableRng for IsaacCore

source§

fn seed_from_u64(seed: u64) -> Self

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.

source§

type Seed = [u8; 32]

Seed type, which is restricted to types mutably-dereferenceable as u8 arrays (we recommend [u8; N] for some N). Read more
source§

fn from_seed(seed: Self::Seed) -> Self

Create a new PRNG using the given seed. Read more
source§

fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error>

Create a new PRNG seeded from another Rng. Read more
source§

fn from_entropy() -> Self

Creates a new instance of the RNG seeded via getrandom. Read more
source§

impl Eq for IsaacCore

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

source§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.