Implementing a Fast Fourier Transform in a Rabin-Miller Primality test.

I feel like one of those people that calls into a radio station, "Hi, I'm a long time listener, first time caller, my question is..."

I'm an undergraduate CS student working on a program that determines the primality of a number, and opted to use the Rabin-Miller test to check. On Wikipedia (http://en.wikipedia.org/wiki/Rabin-Miller_primality_test#Algorithm_and_running_time) it is mentioned that "FFT-based multiplication can push the running time down to ?k ?log^2 n)" but I can't find any resources online that explain how the FFT applies to multiplication and how it would fit into the algorithm I have already. I know there's methods already present in the API that will test primality, but I'd like to be able to write the code myself. Does anyone happen to have knowledge on this topic or where I can look to for more information?

Just in case, my code thus far is tagged below:

// Evan Senter, CS 20 HW 1, 04/07

// An implementation of the Miller-Rabin Pseudo-Primality Test.

// ************************************************************

// As a note, 3215031751 is the smallest number to falsely

// fail less than 2.5E13 due to no witnesses in the

// set of ints Z {2, 3, 5, 7}.

// The probability of an error is at most 4^(-confidence)

import java.math.BigInteger;

import java.math.BigDecimal;

publicclass BigIntegerPrimalityTest{

BigInteger zero = BigInteger.ZERO;

BigInteger one = BigInteger.ONE;

BigInteger two =new BigInteger("2");

public BigIntegerPrimalityTest(){}// The greatest constructor ever!

publicboolean is_a_prime (String aNumber,int aConfidence){

int powerCount = 0;

int compositeCounter = 0;

int confidence = aConfidence;// confidence = # of randNums to test for primality

BigInteger prime =new BigInteger(aNumber);

BigInteger primeMinusOne =new BigInteger(prime.subtract(one).toString());// prime - 1

BigDecimal doubleprimeM1 =new BigDecimal(primeMinusOne.toString());

BigInteger oddDivisor =new BigInteger(primeMinusOne.toString());

BigInteger randNum, randModPowerified;

if (prime.equals(two))returntrue;// Time management at its best

while ((oddDivisor.mod(two)).equals(zero)){// (2^powerCount)*oddDivisor == prime - 1

oddDivisor = oddDivisor.shiftRight(1);

powerCount++;

}

for (int i = 0; i < confidence; i++){// Repeat for i # of randNums where i = confidence

BigDecimal aRandomDouble =new BigDecimal(Double.toString(Math.random()));

BigDecimal tempRandomDouble =

new BigDecimal(((aRandomDouble.multiply(doubleprimeM1.subtract(BigDecimal.ONE))).add(BigDecimal.ONE)).toString());

randNum =new BigInteger((tempRandomDouble.toBigInteger()).toString());//1 < randNum < prime

randModPowerified =new BigInteger((randNum.modPow(oddDivisor, prime).toString()));// modPow returns y = (a^b)%n

if (randModPowerified.equals(one) ==false && randModPowerified.equals(primeMinusOne) ==false){

int loopCounter = 1;

while (loopCounter < powerCount && randModPowerified.equals(primeMinusOne) ==false){

randModPowerified = randModPowerified.modPow(two, prime);

if (randModPowerified.equals(one)) compositeCounter++;

loopCounter++;

}

if (randModPowerified.equals(primeMinusOne) ==false) compositeCounter++;

}

}

if (compositeCounter > 0)returnfalse;

elsereturntrue;

}

public String primeGenerator(String baseSize){

BigInteger probablePrime =new BigInteger(baseSize);

return (probablePrime.nextProbablePrime()).toString();

}

publicstaticvoid main (String[] console){

int conf = 7;

boolean isPrime =false;

String value ="1";

for (int c = 1; c < 1499; c++) value +="0";

value +="1";

BigIntegerPrimalityTest p =new BigIntegerPrimalityTest();

long time1 = System.currentTimeMillis();

String aPrime = p.primeGenerator(value);

long time2 = System.currentTimeMillis();

long time3 = System.currentTimeMillis();

isPrime = p.is_a_prime(aPrime, conf);

long time4 = System.currentTimeMillis();

System.out.println("The value you are testing for primality is: " +

aPrime +"\nThe length of the value is: " + aPrime.length());

if (isPrime) System.out.println("The value is prime with a total error of at most " + Math.pow(4, -conf));

else System.out.println("The value is composite with a total error of at most " + Math.pow(4, -conf));

System.out.println("The time to generate a prime larger than the input was " + (time2 - time1) +" ms");

System.out.println("The time to search for the value's primality was " + (time4 - time3) +" ms");

}

}

[8060 byte] By [evansentera] at [2007-11-27 2:31:03]
# 1

FFT-based algorithms for integer multiplication typically only help when the operands are enormous. There is a discussion of this is Knuth's "Seminumerical Algorithms". Also, the GNU MP (GMP) multi-precision integer arithmetic package includes FFT algorithms that will kick in when the operands are large enough. You could use that as a practical reference or actually use the GMP package if you create a JNI wrapper around it.

ghstarka at 2007-7-12 2:45:30 > top of Java-index,Security,Cryptography...