public BigInt multiply(BigInt val) {
int n = makePowerOfTwo(Math.max(mag.length,val.mag.length))*2;
int signResult = signum * val.signum;
int[] A = padWithZeros(mag,n); // copies mag into A padded w/ 0's
int[] B = padWithZeros(val.mag,n); // copies val.mag into B padded w/ 0's
int[] root = rootsOfUnity(n); // creates all n roots of unity
int[] C = new int[n]; // result array for A*B
int[] AF = new int[n]; // result array for FFT of A
int[] BF = new int[n]; // result array for FFT of B
FFT(A,root,n,0,AF);
FFT(B,root,n,0,BF);
for (int i=0; i<n; i++)
AF[i] = (int)(((long)AF[i]*(long)BF[i]) % P); // Component multiply
reverseRoots(root); // Reverse roots to create inverse roots
inverseFFT(AF,root,n,0,C); // Leaves inverse FFT result in C
propagateCarries(C); // Convert C to right no. bits per entry
return new BigInt(signResult,C);
}