docs: def gf_poly_square(poly):
      '''Linear time implementation of polynomial squaring. For details, see paper: "A fast software implementation for arithmetic operations in GF (2n)". De Win, E., Bosselaers, A., Vandenberghe, S., De Gersem, P., & Vandewalle, J. (1996, January). In Advances in Cryptology - Asiacrypt'96 (pp. 65-76). Springer Berlin Heidelberg.'''
      length = len(poly)
      out = bytearray(2*length - 1)
      for i in xrange(length-1):
          p = poly[i]
          k = 2*i
          if p != 0:
              #out[k] = gf_exp[(2*gf_log[p]) % field_charac] # not necessary to modulo (2^r)-1 since gf_exp is duplicated up to 510.
              out[k] = gf_exp[2*gf_log[p]]
          #else: # not necessary since the output is already initialized to an array of 0
              #out[k] = 0
      out[2*length-2] = gf_exp[2*gf_log[poly[length-1]]]
      if out[0] == 0: out[0] = 2*poly[1] - 1
      return out