In a typical application of the package, this function is not called
directly by the user and the function is called from setVectorSeed()
.
The function is made available in order to simplify testing correctness
of the package and the documentation of this function explains the exact
algorithm used by setVectorSeed()
.
generateInitialization(vseed, m)
Vector of length m
of integer type suitable for substituting into
the components of .Random.seed
. This means that the components
are integers from the interval [-2^31 + 1, 2^31 - 1]
or NA
,
which represents -2^31
. If m == 624
, the output vector is
suitable as the initial state of Mersenne-Twister to be copied into
.Random.seed[3:626]
.
If m1 < m2
, then generateInitialization(vseed, m1)
is equal
to the first m1
components of generateInitialization(vseed, m2)
.
Numeric vector of an arbitrary nonzero length, whose components
have integer values from [0, 2^32 - 1]
.
Numeric, the length of the required output integer vector.
The function transforms an input vector vseed
of an arbitrary length
to a random integer vector of length m
using Advanced Encryption
Standard (AES) block cipher. The function setVectorSeed()
calls
generateInitialization(vseed, 624)
and uses its output as an initial
state of the R base Mersenne-Twister random number generator.
The vector vseed
is first replaced by c(vseed, length(vseed))
in order to guarantee that if vseed1
is a prefix of vseed2
,
but they have a different length, then the outputs are unrelated. If the length
of the resulting vector is not divisible by 8, the vector is padded by zeros
to the nearest larger length divisible by 8 in order to meet the requirements
of the AES algorithm. The resulting vector is splitted into blocks of length 8
and these blocks are used as 256-bit keys in AES. Each of these keys is used
to encrypt a counter sequence of length ceiling(m/4)
. The encrypted
values of these sequences are combined by XOR to a single sequence of
ceiling(m/4)
values, each of which is a sequence of 16 bytes. These
sequences are splitted into subsequences of 4 bytes, each of which encodes
a 32-bit integer in an endianness independent way. The first m
of the
obtained integers form the output.
If length(vseed) <= 7
, then the above algorithm uses AES in counter
mode suggested in Fortuna random number generator as described at
https://en.wikipedia.org/wiki/Fortuna_(PRNG) with a key specified
by the user.
If length(vseed) >= 8
, the algorithm uses XOR of the outputs
of several Fortuna generators with keys formed from disjoint parts of
the input vector and disjoint counter sequences.
https://en.wikipedia.org/wiki/Advanced_Encryption_Standard, https://en.wikipedia.org/wiki/Fortuna_(PRNG).
setVectorSeed
s1 <- generateInitialization(1, 3)
s2 <- generateInitialization(c(1, 0), 3)
s3 <- generateInitialization(c(1, 0, 0), 3)
stopifnot(s1 == c(2054882070, -83320660, -37036705))
stopifnot(s2 == c(-1435341980, 1760892082, 970206446))
stopifnot(s3 == c(1941187208, 915534877, -365000103))
Run the code above in your browser using DataLab