Various Random things (Was: Java 8 RFC 7189139: BigInteger's staticRandom field can be a source of bottlenecks)

Paul Sandoz paul.sandoz at oracle.com
Thu Sep 5 14:50:33 UTC 2013


On Sep 5, 2013, at 7:02 AM, Alan Eliasen <eliasen at mindspring.com> wrote:

> On 09/04/2013 05:26 PM, Brian Burkhalter wrote:
>> I have updated the webrev
>> 
>> http://cr.openjdk.java.net/~bpb/7189139/
>> 
>> to add the two-parameter version of isProbablePrime() which was
>> discussed. Naturally a CCC request would be needed in the event this
>> were to go forward.
> 
>   The change to pass in the random number generator appears fine.
> There's probably no need for a strong random number generator in this
> case, though.  Rabin-Miller is a robust algorithm and the probability of
> its failure can be easily made so that it's far more probable that the
> computer's hardware fails while running the test.  (I wrote an article
> about this if you're interested.)  The particular random numbers that it
> chooses are not terribly crucial as long as there's enough margin, and
> as long as random numbers aren't repeated pathologically.
> 

If that is the case why not just leave the method as is and replace SecureRandom with ThreadLocalRandom?


>   However, the primality tests could be made more efficient and more
> certain.  For smallish numbers, the Rabin-Miller test performs a large
> number of random tests, with some low probability of failure.
> 
>   It's known, however, for numbers less than 341,550,071,728,321, (or
> larger, see references below,) that there are minimal sets of bases we
> need to test with a Rabin-Miller test to *prove* primality.  (This would
> also allow us to eliminate generating random numbers entirely, in these
> cases, to perform a much smaller number of Rabin-Miller rounds, and let
> us skip the Lucas test entirely as well, and enable a *proof* of
> primality for numbers smaller than this.)
> 
>   For example, if the number n is less than 4,759,123,141 (this
> encompasses all ints) then you only need to test that n is a strong
> probable prime to bases 2,7, and 61 to *prove* primality.  This would be
> much faster than the code now


> (which may do 50 rounds, and won't do
> *more* than 50 rounds, no matter what certainty you request, which is
> almost certainly a bug in the current code.)

Right, but IIUC 50 rounds will result in a probability of 1 - 1 / 4^50 that the number under test is a prime. If so is there any point in more rounds? we could just clarify the docs.

Paul.
 

>  It would also be more
> correct than the current code, which admits a low probability of failure.
> 
>   There are references which show the exact bases to test for smaller
> numbers in a Rabin-Miller test to *prove* primality here:
> 
> http://primes.utm.edu/prove/prove2_3.html#quick
> http://priv.ckp.pl/wizykowski/sprp.pdf
> http://math.crg4.com/primes.html
> http://www.gpgpgpu.com/gecco2009/6.pdf
> 
>   Further, to *prove* primality of everything that will fit into an
> unsigned long (2^64), you only need to test all prime bases <= 37.  See:
> http://oeis.org/A014233
> 
>   There could be a fast path to do the tests for smallish numbers in a
> long or an int.  You'll want a modPow function.  Here's one for ints:
> 
>   /** Compute x^y mod m.  Assumes m >= 2. */
>   public static int modPow(int x, int y, int m)
>   {
>      long acc = 1;
>      long z = x % m;
>      while (y != 0)
>      {
>         if ((y & 1) != 0)
>            acc = (acc * z) % m;
>         z = (z * z) % m;
>         y >>= 1;
>      }
>      return (int) acc;
>   }
> 
> -- 
>  Alan Eliasen
>  eliasen at mindspring.com
>  http://futureboy.us/



More information about the core-libs-dev mailing list