def square(self, a):
    ' This algortihm returns the square of a in the field\n            using different methods if the degree of the extension\n            is 2,3 or more\n        '
    assert (a.F == self)
    if (not (a.deg == (self.deg - 1))):
        a = self.reduc(a)
    A = a.poly.coef
    k = (self.deg - 1)
    if ((k == 2) and (self.F.rep == 'A')):
        (a1, a0) = (A[0].val, A[1].val)
        p = self.char
        v0 = (a0 * a1)
        c0 = (((a0 + a1) * (a0 - a1)) % p)
        c1 = ((v0 + v0) % p)
        c0e = FieldElem(c0, self.F)
        c1e = FieldElem(c1, self.F)
        cp = polynom(self.F, [c1e, c0e])
        C = ExtensionFieldElem(self, cp)
        return C
    elif (k == 2):
        (a1, a0) = A
        beta = (- self.irpoly.coef[(- 1)])
        v0 = self.F.pmul(a0, a1)
        c0 = ((self.F.pmul((a0 + a1), (a0 + self.F.pmul(a1, beta))) - v0) - self.F.pmul(beta, v0))
        c1 = (v0 + v0)
        cp = polynom(self.F, [c1, c0])
        return ExtensionFieldElem(self, cp)
    elif (k == 3):
        (a2, a1, a0) = A
        assert (a0.F == self.F)
        beta = (- self.irpoly.coef[(- 1)])
        s0 = self.F.square(a0)
        t1 = self.F.pmul(a0, a1)
        s1 = (t1 + t1)
        s2 = self.F.square(((a0 - a1) + a2))
        t3 = (a1 * a2)
        s3 = (t3 + t3)
        s4 = self.F.square(a2)
        c0 = (s0 + self.F.pmul(beta, s3))
        c1 = (s1 + self.F.pmul(beta, s4))
        c2 = ((((s1 + s2) + s3) - s0) - s4)
        cp = polynom(self.F, [c2, c1, c0])
        return ExtensionFieldElem(self, cp)
    else:
        return self.F.pmul(a, a)
This algortihm returns the square of a in the field
using different methods if the degree of the extension
is 2,3 or more
def square(self, a):
    ' This algortihm returns the square of a in the field\n            using different methods if the degree of the extension\n            is 2,3 or more\n        '
    assert (a.F == self)
    if (not (a.deg == (self.deg - 1))):
        a = self.reduc(a)
    A = a.poly.coef
    k = (self.deg - 1)
    if ((k == 2) and (self.F.rep == 'A')):
        (a1, a0) = (A[0].val, A[1].val)
        p = self.char
        v0 = (a0 * a1)
        c0 = (((a0 + a1) * (a0 - a1)) % p)
        c1 = ((v0 + v0) % p)
        c0e = FieldElem(c0, self.F)
        c1e = FieldElem(c1, self.F)
        cp = polynom(self.F, [c1e, c0e])
        C = ExtensionFieldElem(self, cp)
        return C
    elif (k == 2):
        (a1, a0) = A
        beta = (- self.irpoly.coef[(- 1)])
        v0 = self.F.pmul(a0, a1)
        c0 = ((self.F.pmul((a0 + a1), (a0 + self.F.pmul(a1, beta))) - v0) - self.F.pmul(beta, v0))
        c1 = (v0 + v0)
        cp = polynom(self.F, [c1, c0])
        return ExtensionFieldElem(self, cp)
    elif (k == 3):
        (a2, a1, a0) = A
        assert (a0.F == self.F)
        beta = (- self.irpoly.coef[(- 1)])
        s0 = self.F.square(a0)
        t1 = self.F.pmul(a0, a1)
        s1 = (t1 + t1)
        s2 = self.F.square(((a0 - a1) + a2))
        t3 = (a1 * a2)
        s3 = (t3 + t3)
        s4 = self.F.square(a2)
        c0 = (s0 + self.F.pmul(beta, s3))
        c1 = (s1 + self.F.pmul(beta, s4))
        c2 = ((((s1 + s2) + s3) - s0) - s4)
        cp = polynom(self.F, [c2, c1, c0])
        return ExtensionFieldElem(self, cp)
    else:
        return self.F.pmul(a, a)