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);
    }