private static int[] mult128(int[] a,int[] b){
  int[] result=new int[8];
  int[] a0=new int[2];
  System.arraycopy(a,0,a0,0,Math.min(2,a.length));
  int[] a1=new int[2];
  if (a.length > 2) {
    System.arraycopy(a,2,a1,0,Math.min(2,a.length - 2));
  }
  int[] b0=new int[2];
  System.arraycopy(b,0,b0,0,Math.min(2,b.length));
  int[] b1=new int[2];
  if (b.length > 2) {
    System.arraycopy(b,2,b1,0,Math.min(2,b.length - 2));
  }
  if (a1[1] == 0 && b1[1] == 0) {
    if (a1[0] != 0 || b1[0] != 0) {
      int[] c=mult32(a1[0],b1[0]);
      result[5]^=c[1];
      result[4]^=c[0];
      result[3]^=c[1];
      result[2]^=c[0];
    }
  }
 else {
    int[] c=mult64(a1,b1);
    result[7]^=c[3];
    result[6]^=c[2];
    result[5]^=c[1] ^ c[3];
    result[4]^=c[0] ^ c[2];
    result[3]^=c[1];
    result[2]^=c[0];
  }
  a1[0]^=a0[0];
  a1[1]^=a0[1];
  b1[0]^=b0[0];
  b1[1]^=b0[1];
  if (a1[1] == 0 && b1[1] == 0) {
    int[] d=mult32(a1[0],b1[0]);
    result[3]^=d[1];
    result[2]^=d[0];
  }
 else {
    int[] d=mult64(a1,b1);
    result[5]^=d[3];
    result[4]^=d[2];
    result[3]^=d[1];
    result[2]^=d[0];
  }
  if (a0[1] == 0 && b0[1] == 0) {
    int[] e=mult32(a0[0],b0[0]);
    result[3]^=e[1];
    result[2]^=e[0];
    result[1]^=e[1];
    result[0]^=e[0];
  }
 else {
    int[] e=mult64(a0,b0);
    result[5]^=e[3];
    result[4]^=e[2];
    result[3]^=e[1] ^ e[3];
    result[2]^=e[0] ^ e[2];
    result[1]^=e[1];
    result[0]^=e[0];
  }
  return result;
}

private static int [ ] mult128 ( int [ ] a , int [ ] b ) { int [ ] result = new int [ 8 ] ; int [ ] a0 = new int [ 2 ] ; System . arraycopy ( a , 0 , a0 , 0 , Math . min ( 2 , a . length ) ) ; int [ ] a1 = new int [ 2 ] ; if ( a . length > 2 ) { System . arraycopy ( a , 2 , a1 , 0 , Math . min ( 2 , a . length - 2 ) ) ; } int [ ] b0 = new int [ 2 ] ; System . arraycopy ( b , 0 , b0 , 0 , Math . min ( 2 , b . length ) ) ; int [ ] b1 = new int [ 2 ] ; if ( b . length > 2 ) { System . arraycopy ( b , 2 , b1 , 0 , Math . min ( 2 , b . length - 2 ) ) ; } if ( a1 [ 1 ] == 0 && b1 [ 1 ] == 0 ) { if ( a1 [ 0 ] != 0 || b1 [ 0 ] != 0 ) { int [ ] c = mult32 ( a1 [ 0 ] , b1 [ 0 ] ) ; result [ 5 ] ^= c [ 1 ] ; result [ 4 ] ^= c [ 0 ] ; result [ 3 ] ^= c [ 1 ] ; result [ 2 ] ^= c [ 0 ] ; } } else { int [ ] c = mult64 ( a1 , b1 ) ; result [ 7 ] ^= c [ 3 ] ; result [ 6 ] ^= c [ 2 ] ; result [ 5 ] ^= c [ 1 ] ^ c [ 3 ] ; result [ 4 ] ^= c [ 0 ] ^ c [ 2 ] ; result [ 3 ] ^= c [ 1 ] ; result [ 2 ] ^= c [ 0 ] ; } a1 [ 0 ] ^= a0 [ 0 ] ; a1 [ 1 ] ^= a0 [ 1 ] ; b1 [ 0 ] ^= b0 [ 0 ] ; b1 [ 1 ] ^= b0 [ 1 ] ; if ( a1 [ 1 ] == 0 && b1 [ 1 ] == 0 ) { int [ ] d = mult32 ( a1 [ 0 ] , b1 [ 0 ] ) ; result [ 3 ] ^= d [ 1 ] ; result [ 2 ] ^= d [ 0 ] ; } else { int [ ] d = mult64 ( a1 , b1 ) ; result [ 5 ] ^= d [ 3 ] ; result [ 4 ] ^= d [ 2 ] ; result [ 3 ] ^= d [ 1 ] ; result [ 2 ] ^= d [ 0 ] ; } if ( a0 [ 1 ] == 0 && b0 [ 1 ] == 0 ) { int [ ] e = mult32 ( a0 [ 0 ] , b0 [ 0 ] ) ; result [ 3 ] ^= e [ 1 ] ; result [ 2 ] ^= e [ 0 ] ; result [ 1 ] ^= e [ 1 ] ; result [ 0 ] ^= e [ 0 ] ; } else { int [ ] e = mult64 ( a0 , b0 ) ; result [ 5 ] ^= e [ 3 ] ; result [ 4 ] ^= e [ 2 ] ; result [ 3 ] ^= e [ 1 ] ^ e [ 3 ] ; result [ 2 ] ^= e [ 0 ] ^ e [ 2 ] ; result [ 1 ] ^= e [ 1 ] ; result [ 0 ] ^= e [ 0 ] ; } return result ; }
4 - integer version of karatzuba multiplication .
