[ 
https://issues.apache.org/jira/browse/RNG-106?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16861020#comment-16861020
 ] 

Alex D Herbert commented on RNG-106:
------------------------------------

For the large array Well generators this is not currently a problem as the 
seeding routine in RandomSource.create(...) creates a seed of maximum 128. The 
self seeding of the generator will fill the rest.

If I repeat the test using a maximum of 128 for the seed size then there are no 
failures.

If I repeat the test using a bit pool of 19937 or 44497 respectively then there 
are no failures.

So just checking for a non-zero array seed in the SeedFactory will allow all 
the generators to be created with full length seeds output from the SeedFactory 
with the exception of the two large state Well generators where for:

19937: A seed of all zero except the last element would fail if the last 
element is < 2^31 - 1.

44497: A seed of all zero except the last element would fail if the last 
element is < 2^15 - 1.

So in the use case where a user creates a full length seed from the SeedFactory 
and uses it for the 19937 generator the probability of failure is less than 1 
in 2^19936 and for the 44497 generator is less than 1 in 2^44480 (probabilities 
are for creating a seed of zeros for all but the last element).

This is unlikely. So perhaps a warning for the user in the Javadoc of the 
RandomSource enum type for WELL_19937 and WELL_44497 generators that although 
the native seed size is 624/1391 the number of bits taken from the seed will be 
less than that and an input seed should contain non-zero bits in the first 
19937 or 44497 bits of the seed. Then any user creating a full length seed for 
these generators will have been warned.

 

> XorShiRo generators require non-zero input seeds
> ------------------------------------------------
>
>                 Key: RNG-106
>                 URL: https://issues.apache.org/jira/browse/RNG-106
>             Project: Commons RNG
>          Issue Type: Improvement
>          Components: core, simple
>    Affects Versions: 1.3
>            Reporter: Alex D Herbert
>            Assignee: Alex D Herbert
>            Priority: Major
>             Fix For: 1.3
>
>
> The following generators based on Xor shifts all require non-zero seeds:
> {noformat}
> XOR_SHIFT_1024_S
> XOR_SHIFT_1024_S_PHI
> XO_RO_SHI_RO_64_S
> XO_RO_SHI_RO_64_SS
> XO_SHI_RO_128_PLUS
> XO_SHI_RO_128_SS
> XO_RO_SHI_RO_128_PLUS
> XO_RO_SHI_RO_128_SS
> XO_SHI_RO_256_PLUS
> XO_SHI_RO_256_SS
> XO_SHI_RO_512_PLUS
> XO_SHI_RO_512_SS
> {noformat}
> A zero seed results in zero output for each call to the generator.
> Tests added to the rng-core module show that only a single bit is required to 
> be set and the generator is able to generate non-zero output. These tests are 
> simple and do not test the output for many cycles or do statistical analysis 
> on the output randomness. However the authors of the generators state that 
> they require a non-zero seed and are not any more specific so I assume that a 
> single bit is enough to maintain the internal state capable of randomness.
> This can be fixed with the following methods:
>  # Set the final bit in the seed to 1. This will be fast but loses 1 bit of 
> seed entropy.
>  # Check the seed array for zeros. If the entire array is zero then generate 
> a single seed value until it is non-zero in a loop and set it into the seed 
> array.
>  # Check the seed array for zeros. If the entire array is zero then 
> re-generate the seed using recursive method call.
> Note that this is an edge case. The smallest seed uses 64 bits, others use 
> 128, 256, 512, 1024 (the number of bits in the seed is the state size and is 
> the number in the enum). For the worst case this will occur 1 in 2^64 times.
> Here is the robust approach:
> {code:java}
> int[] seed;
> do {
>     seed = createSeed(); // Appropriate seed array generation
> } while (SeedFactory.isZero(seed);
> return seed;
> {code}
> This would add new isZero(int[]) and isZero(long[]) methods to the seed 
> factory. The entire method for creating a non-zero array seed could be added 
> to the SeedFactory.
> Here is the compromise approach:
> {code:java}
> int[] seed = createSeed(); // Appropriate seed array generation
> if (SeedFactory.isZero(seed)) {
>     do {
>         seed[0] = SeedFactory.createInt();
>     } while (seed[0] == 0);
> }
> {code}
> Given the loop will happen 1 in 2^64 times the speed of the two approaches 
> will differ due to how the JVM produces the final code for the hot path (i.e. 
> not the edge case).
> Here is the simple approach:
> {code:java}
> // Ensure non-zero (loses 1 bit of entropy)
> return createSeed() | 1;
> {code}
> Losing 1 bit of entropy is undesirable.
> A performance test of the approaches (and variants) should be done for 
> reference.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to