public override 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.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) { IntArray uzCopy = uz; uz = vz; vz = uzCopy; 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 F2mFieldElement(this.m, this.k1, this.k2, this.k3, g2z)); }