def pmul(self, a, b):
    'Multiplication between polynomials\n        '
    if (not (a.deg == b.deg)):
        a = self.reduc(a)
        b = self.reduc(b)
    A = a.poly.coef
    B = b.poly.coef
    k = (self.deg - 1)
    if ((k == 2) and (self.F.rep == 'A')):
        (a0, a1, b0, b1) = (A[0].val, A[1].val, B[0].val, B[1].val)
        p = self.char
        v0 = (a0 * b0)
        v1 = (a1 * b1)
        c0 = (((((a0 + a1) * (b0 + b1)) - v0) - v1) % p)
        c1 = ((v1 - v0) % p)
        c0e = FieldElem(c0, self.F)
        c1e = FieldElem(c1, self.F)
        cp = polynom(self.F, [c0e, c1e])
        C = ExtensionFieldElem(self, cp)
        return C
    elif (k == 2):
        a0 = A[0]
        a1 = A[1]
        b0 = B[0]
        b1 = B[1]
        beta = (- self.irpoly.coef[(- 1)])
        v0 = self.F.pmul(a0, b0)
        v1 = self.F.pmul(a1, b1)
        c0 = ((self.F.pmul((a0 + a1), (b0 + b1)) - v0) - v1)
        c1 = (v1 + self.F.pmul(v0, beta))
        cp = polynom(self.F, [c0, c1])
        C = ExtensionFieldElem(self, cp)
        return C
    elif (k == 3):
        (a0, a1, a2) = A
        (b0, b1, b2) = B
        beta = (- self.irpoly.coef[(- 1)])
        (v0, v1, v2) = (self.F.pmul(a0, b0), self.F.pmul(a1, b1), self.F.pmul(a2, b2))
        c0 = (((self.F.pmul((a0 + a2), (b0 + b2)) - v0) + v1) - v2)
        c1 = (((self.F.pmul((a2 + a1), (b2 + b1)) - v2) - v1) + self.F.pmul(beta, v0))
        c2 = (v2 + self.F.pmul(beta, ((self.F.pmul((a1 + a0), (b1 + b0)) - v1) - v0)))
        cp = polynom(self.F, [c0, c1, c2])
        C = ExtensionFieldElem(self, cp)
        return C
    else:
        prod = convolve(A, B)
        return self.reduc2(prod)
Multiplication between polynomials
def pmul(self, a, b):
    '\n        '
    if (not (a.deg == b.deg)):
        a = self.reduc(a)
        b = self.reduc(b)
    A = a.poly.coef
    B = b.poly.coef
    k = (self.deg - 1)
    if ((k == 2) and (self.F.rep == 'A')):
        (a0, a1, b0, b1) = (A[0].val, A[1].val, B[0].val, B[1].val)
        p = self.char
        v0 = (a0 * b0)
        v1 = (a1 * b1)
        c0 = (((((a0 + a1) * (b0 + b1)) - v0) - v1) % p)
        c1 = ((v1 - v0) % p)
        c0e = FieldElem(c0, self.F)
        c1e = FieldElem(c1, self.F)
        cp = polynom(self.F, [c0e, c1e])
        C = ExtensionFieldElem(self, cp)
        return C
    elif (k == 2):
        a0 = A[0]
        a1 = A[1]
        b0 = B[0]
        b1 = B[1]
        beta = (- self.irpoly.coef[(- 1)])
        v0 = self.F.pmul(a0, b0)
        v1 = self.F.pmul(a1, b1)
        c0 = ((self.F.pmul((a0 + a1), (b0 + b1)) - v0) - v1)
        c1 = (v1 + self.F.pmul(v0, beta))
        cp = polynom(self.F, [c0, c1])
        C = ExtensionFieldElem(self, cp)
        return C
    elif (k == 3):
        (a0, a1, a2) = A
        (b0, b1, b2) = B
        beta = (- self.irpoly.coef[(- 1)])
        (v0, v1, v2) = (self.F.pmul(a0, b0), self.F.pmul(a1, b1), self.F.pmul(a2, b2))
        c0 = (((self.F.pmul((a0 + a2), (b0 + b2)) - v0) + v1) - v2)
        c1 = (((self.F.pmul((a2 + a1), (b2 + b1)) - v2) - v1) + self.F.pmul(beta, v0))
        c2 = (v2 + self.F.pmul(beta, ((self.F.pmul((a1 + a0), (b1 + b0)) - v1) - v0)))
        cp = polynom(self.F, [c0, c1, c2])
        C = ExtensionFieldElem(self, cp)
        return C
    else:
        prod = convolve(A, B)
        return self.reduc2(prod)