public ECFieldElement add(final ECFieldElement b) {
   // No check performed here for performance reasons. Instead the
   // elements involved are checked in ECPoint.F2m
   // checkFieldElements(this, b);
   IntArray iarrClone = (IntArray) this.x.clone();
   F2m bF2m = (F2m) b;
   iarrClone.addShifted(bF2m.x, 0);
   return new F2m(m, k1, k2, k3, iarrClone);
 }
  public IntArray multiply(IntArray other, int m) {
    // Lenght of c is 2m bits rounded up to the next int (32 bit)
    int t = (m + 31) >> 5;
    if (m_ints.length < t) {
      m_ints = resizedInts(t);
    }

    IntArray b = new IntArray(other.resizedInts(other.getLength() + 1));
    IntArray c = new IntArray((m + m + 31) >> 5);
    // IntArray c = new IntArray(t + t);
    int testBit = 1;
    for (int k = 0; k < 32; k++) {
      for (int j = 0; j < t; j++) {
        if ((m_ints[j] & testBit) != 0) {
          // The kth bit of m_ints[j] is set
          c.addShifted(b, j);
        }
      }
      testBit <<= 1;
      b.shiftLeft();
    }
    return c;
  }
    public ECFieldElement invert() {
      // Inversion in F2m using the extended Euclidean algorithm
      // Input: A nonzero polynomial a(z) of degree at most m-1
      // Output: a(z)^(-1) mod f(z)

      // u(z) := a(z)
      IntArray uz = (IntArray) this.x.clone();

      // v(z) := f(z)
      IntArray vz = new IntArray(t);
      vz.setBit(m);
      vz.setBit(0);
      vz.setBit(this.k1);
      if (this.representation == PPB) {
        vz.setBit(this.k2);
        vz.setBit(this.k3);
      }

      // g1(z) := 1, g2(z) := 0
      IntArray g1z = new IntArray(t);
      g1z.setBit(0);
      IntArray g2z = new IntArray(t);

      // while u != 0
      while (!uz.isZero())
      // while (uz.getUsedLength() > 0)
      // while (uz.bitLength() > 1)
      {
        // j := deg(u(z)) - deg(v(z))
        int j = uz.bitLength() - vz.bitLength();

        // If j < 0 then: u(z) <-> v(z), g1(z) <-> g2(z), j := -j
        if (j < 0) {
          final IntArray uzCopy = uz;
          uz = vz;
          vz = uzCopy;

          final IntArray g1zCopy = g1z;
          g1z = g2z;
          g2z = g1zCopy;

          j = -j;
        }

        // u(z) := u(z) + z^j * v(z)
        // Note, that no reduction modulo f(z) is required, because
        // deg(u(z) + z^j * v(z)) <= max(deg(u(z)), j + deg(v(z)))
        // = max(deg(u(z)), deg(u(z)) - deg(v(z)) + deg(v(z))
        // = deg(u(z))
        // uz = uz.xor(vz.shiftLeft(j));
        // jInt = n / 32
        int jInt = j >> 5;
        // jInt = n % 32
        int jBit = j & 0x1F;
        IntArray vzShift = vz.shiftLeft(jBit);
        uz.addShifted(vzShift, jInt);

        // g1(z) := g1(z) + z^j * g2(z)
        // g1z = g1z.xor(g2z.shiftLeft(j));
        IntArray g2zShift = g2z.shiftLeft(jBit);
        g1z.addShifted(g2zShift, jInt);
      }
      return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, g2z);
    }