docs: def compute_key_composite(password=None, keyfile=None):
      """Compute composite key.
      Used in header verification and payload decryption."""
  
      # hash the password
      if password:
          password_composite = hashlib.sha256(password.encode('utf-8')).digest()
      else:
          password_composite = b''
      # hash the keyfile
      if keyfile:
          # try to read XML keyfile
          try:
              with open(keyfile, 'r') as f:
                  tree = etree.parse(f).getroot()
                  keyfile_composite = base64.b64decode(tree.find('Key/Data').text)
          # otherwise, try to read plain keyfile
          except (etree.XMLSyntaxError, UnicodeDecodeError):
              try:
                  with open(keyfile, 'rb') as f:
                      key = f.read()
  
                      try:
                          int(key, 16)
                          is_hex = True
                      except ValueError:
                          is_hex = False
                      # if the length is 32 bytes we assume it is the key
                      if len(key) == 32:
                          keyfile_composite = key
                      # if the length is 64 bytes we assume the key is hex encoded
                      elif len(key) == 64 and is_hex:
                          keyfile_composite =  codecs.decode(key, 'hex')
                      # anything else may be a file to hash for the key
                      else:
                          keyfile_composite = hashlib.sha256(key).digest()
              except:
                  raise IOError('Could not read keyfile')
  
      else:
          keyfile_composite = b''
  
      # create composite key from password and keyfile composites
      return hashlib.sha256(password_composite + keyfile_composite).digest()