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

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

OK. So that would make the wrapper essentially the same as JDKRandom. I have 
verified that adding this extra constructor works:
{code:java}
public JDKRandom(Random random) {
    this.delegate = random;
}

@Test
public void testRandomConstructor() throws NoSuchAlgorithmException {
    JDKRandom random = new 
JDKRandom(SecureRandom.getInstance("NativePRNGNonBlocking"));
    RandomProviderState s = random.saveState();
    random.restoreState(s);
}
{code}

So that is the minimum implementation. I.e. the SecureRandom respects the 
serialization code.

But that would put the modification into rng-core and not rng-simple next to 
the JDKRandomBridge. If you put the same implementation into rng-simple and 
call it JDKRandomWrapper then the amount of code duplication is higher than my 
simple pass-through wrapper as the save/restore state code is about 15 lines 
verses the 6 I put into the pass-through wrapper for nextLong(long). Either way 
it is not much code duplication.

However reading the base implementation of SecureRandom shows that next(int 
bits) is implemented by calling nextBytes(byte[]) for the required number of 
bytes in 8-bit chunks (i.e. if bits is smaller than 9 then only 1 byte is used, 
etc). The nextBytes(byte[]) method is then overridden to call the underlying 
SecureRandom implementation. So the SecureRandom primary output is nextBytes 
and this is done in provider implementations. As such when wrapping a Random 
with the intention of mainly supporting wrapping a SecureRandom at least the 
nextBytes(byte[]) method should be passed through from the underlying random. 
And if you do this and leave the rest with the IntProvider implementation then 
it is a mix of two implementations. If you don't pass through nextBytes(byte[]) 
then calling that method will be slow as it will round trip everything to an 
int and back again, and may change the output (I'd have to check). If the 
output is changed then the goal of collecting randomness from {{/dev/urandom}} 
is only partially achieved as the byte source is not output exactly. Although 
this is mute if the source is truly random.

A second nit I have is that the save/restore state function of a SecureRandom 
configured to read from {{/dev/urandom}} would not function as I would expect. 
If the state is saved I would expect that when I use it to restore the state 
then the output will match each time I restore the state. This will not be the 
case for such a generator. I do note that the Restorable documentation does not 
make this guarantee. Only that the state can be saved and restored. It does not 
promise what the effect of a state restore would be. It's a grey area.

Thus I think it better for the wrapper to not support the 
RestoreableUniformRandomProvider interface. The primary goal is to offer up the 
output from a Random in the form of the UniformRandomProvider interface. This 
would rule out extending IntProvider (which is restorable) and then necessitate 
at least some code duplication in the wrapper implementation of the 
UniformRandomProvider interface. The unit test in the PR ensures that this 
small piece of duplicated code functions the same.

Note: Currently the JDKRandom implementation of save/restore does not satisfy 
the Restoreable condition implied by restore() that the state can be obtained 
from a different object of the same class. In this edge case the restore will 
error as the state size is set when the state is saved. Thus if applied to 
restore another object of the same class where the state has not beed saved it 
will not know the state size. This can be fixed by also saving the state size 
to the state, reading that first when restoring the state and then reading the 
rest of the state. I can fix this with another ticket.


> System generator (/dev/random)
> ------------------------------
>
>                 Key: RNG-19
>                 URL: https://issues.apache.org/jira/browse/RNG-19
>             Project: Commons RNG
>          Issue Type: Wish
>            Reporter: Emmanuel Bourg
>            Priority: Minor
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> Commons RNG could include a random number generator based on the output of 
> /dev/random or /dev/urandom on Unix systems.
> Commons Crypto has an implementation that could be used as a starting point:
> https://github.com/apache/commons-crypto/blob/master/src/main/java/org/apache/commons/crypto/random/OsCryptoRandom.java



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

Reply via email to