/** * This method returns the index of the first clear bit in the search * array that occurs at or after start. It will not search past the * specified limit. It returns -1 if there is no such clear bit. */ private int sieveSearch(int limit, int start) { if (start >= limit) return -1; int index = start; do { if (!get(index)) return index; index++; } while(index < limit-1); return -1; }
/** * Construct a "small sieve" with a base of 0. This constructor is * used internally to generate the set of "small primes" whose multiples * are excluded from sieves generated by the main (package private) * constructor, BitSieve(BigInteger base, int searchLen). The length * of the sieve generated by this constructor was chosen for performance; * it controls a tradeoff between how much time is spent constructing * other sieves, and how much time is wasted testing composite candidates * for primality. The length was chosen experimentally to yield good * performance. */ private BitSieve() { length = 150 * 64; bits = new long[(unitIndex(length - 1) + 1)]; // Mark 1 as composite set(0); int nextIndex = 1; int nextPrime = 3; // Find primes and remove their multiples from sieve do { sieveSingle(length, nextIndex + nextPrime, nextPrime); nextIndex = sieveSearch(length, nextIndex + 1); nextPrime = 2*nextIndex + 1; } while((nextIndex > 0) && (nextPrime < length)); }
bits = new long[(unitIndex(searchLen-1) + 1)]; length = searchLen; int start = 0; int step = smallSieve.sieveSearch(smallSieve.length, start); int convertedStep = (step *2) + 1; if (start%2 == 0) start += convertedStep; sieveSingle(searchLen, (start-1)/2, convertedStep); step = smallSieve.sieveSearch(smallSieve.length, step+1); convertedStep = (step *2) + 1; } while (step > 0);
/** * Find a random number of the specified bitLength that is probably prime. * This method is more appropriate for larger bitlengths since it uses * a sieve to eliminate most composites before using a more expensive * test. */ private static BigInteger largePrime(int bitLength, int certainty, Random rnd) { BigInteger p; p = new BigInteger(bitLength, rnd).setBit(bitLength-1); p.mag[p.mag.length-1] &= 0xfffffffe; // Use a sieve length likely to contain the next prime number int searchLen = (bitLength / 20) * 64; BitSieve searchSieve = new BitSieve(p, searchLen); BigInteger candidate = searchSieve.retrieve(p, certainty, rnd); while ((candidate == null) || (candidate.bitLength() != bitLength)) { p = p.add(BigInteger.valueOf(2*searchLen)); if (p.bitLength() != bitLength) p = new BigInteger(bitLength, rnd).setBit(bitLength-1); p.mag[p.mag.length-1] &= 0xfffffffe; searchSieve = new BitSieve(p, searchLen); candidate = searchSieve.retrieve(p, certainty, rnd); } return candidate; }
/** * Sieve a single set of multiples out of the sieve. Begin to remove * multiples of the specified step starting at the specified start index, * up to the specified limit. */ private void sieveSingle(int limit, int start, int step) { while(start < limit) { set(start); start += step; } }
bits = new long[(unitIndex(searchLen-1) + 1)]; length = searchLen; int start = 0; int step = smallSieve.sieveSearch(smallSieve.length, start); int convertedStep = (step *2) + 1; if (start%2 == 0) start += convertedStep; sieveSingle(searchLen, (start-1)/2, convertedStep); step = smallSieve.sieveSearch(smallSieve.length, step+1); convertedStep = (step *2) + 1; } while (step > 0);
/** * Find a random number of the specified bitLength that is probably prime. * This method is more appropriate for larger bitlengths since it uses * a sieve to eliminate most composites before using a more expensive * test. */ private static BigInteger largePrime(int bitLength, int certainty, Random rnd) { BigInteger p; p = new BigInteger(bitLength, rnd).setBit(bitLength-1); p.mag[p.mag.length-1] &= 0xfffffffe; // Use a sieve length likely to contain the next prime number int searchLen = (bitLength / 20) * 64; BitSieve searchSieve = new BitSieve(p, searchLen); BigInteger candidate = searchSieve.retrieve(p, certainty, rnd); while ((candidate == null) || (candidate.bitLength() != bitLength)) { p = p.add(BigInteger.valueOf(2*searchLen)); if (p.bitLength() != bitLength) p = new BigInteger(bitLength, rnd).setBit(bitLength-1); p.mag[p.mag.length-1] &= 0xfffffffe; searchSieve = new BitSieve(p, searchLen); candidate = searchSieve.retrieve(p, certainty, rnd); } return candidate; }
/** * Sieve a single set of multiples out of the sieve. Begin to remove * multiples of the specified step starting at the specified start index, * up to the specified limit. */ private void sieveSingle(int limit, int start, int step) { while(start < limit) { set(start); start += step; } }
/** * Construct a "small sieve" with a base of 0. This constructor is * used internally to generate the set of "small primes" whose multiples * are excluded from sieves generated by the main (package private) * constructor, BitSieve(BigInteger base, int searchLen). The length * of the sieve generated by this constructor was chosen for performance; * it controls a tradeoff between how much time is spent constructing * other sieves, and how much time is wasted testing composite candidates * for primality. The length was chosen experimentally to yield good * performance. */ private BitSieve() { length = 150 * 64; bits = new long[(unitIndex(length - 1) + 1)]; // Mark 1 as composite set(0); int nextIndex = 1; int nextPrime = 3; // Find primes and remove their multiples from sieve do { sieveSingle(length, nextIndex + nextPrime, nextPrime); nextIndex = sieveSearch(length, nextIndex + 1); nextPrime = 2*nextIndex + 1; } while((nextIndex > 0) && (nextPrime < length)); }
/** * This method returns the index of the first clear bit in the search * array that occurs at or after start. It will not search past the * specified limit. It returns -1 if there is no such clear bit. */ private int sieveSearch(int limit, int start) { if (start >= limit) return -1; int index = start; do { if (!get(index)) return index; index++; } while(index < limit-1); return -1; }