public FastInt multiply(FastInt val) {  
    int n = makePowerOfTwo(Math.max(mag.length,val.mag.length))*2;
    logN = logBaseTwo(n);		// Log of n base 2
    reverse = reverseArray(n,logN);	// initialize reversal lookup table
    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
    FFT(A,root,n);			// Leaves FFT result in A
    FFT(B,root,n);			// Leaves FFT result in B
    for (int i=0; i<n; i++) 
      A[i] = (int) (((long)A[i]*B[i]) % P); 	// Component-wise multiply
    reverseRoots(root);			// Reverse roots to create inverse roots
    inverseFFT(A,root,n);		// Leaves inverse FFT result in A
    propagateCarries(A);		// Convert A to right no. of bits/entry
    return new FastInt(signResult,A);
  }