docs: def encrypt_cfb(self, data, init_vector):
      """
      Return an iterator that encrypts `data` using the Cipher Feedback (CFB)
      mode of operation.
      
      CFB mode can operate on `data` of any length.
      
      Each iteration, except the last, always returns a block-sized :obj:`bytes`
      object (i.e. 8 bytes). The last iteration may return a :obj:`bytes` object
      with a length less than the block-size, if `data` is not a multiple of the
      block-size in length.
      
      `init_vector` is the initialization vector and should be a
      :obj:`bytes`-like object with exactly 8 bytes.
      If it is not, a :exc:`ValueError` exception is raised.
      
      `data` should be a :obj:`bytes`-like object (of any length).
      """
      S1, S2, S3, S4 = self.S
      P = self.P
      
      u4_1_pack = self._u4_1_pack
      u1_4_unpack = self._u1_4_unpack
      encrypt = self._encrypt
      
      u4_2_pack = self._u4_2_pack
      
      data_len = len(data)
      extra_bytes = data_len % 8
      last_block_stop_i = data_len - extra_bytes
      
      try:
        prev_cipher_L, prev_cipher_R = self._u4_2_unpack(init_vector)
      except struct_error:
        raise ValueError("initialization vector is not 8 bytes in length")
      
      for plain_L, plain_R in self._u4_2_iter_unpack(
        data[0:last_block_stop_i]
      ):
        prev_cipher_L, prev_cipher_R = encrypt(
          prev_cipher_L, prev_cipher_R,
          P, S1, S2, S3, S4,
          u4_1_pack, u1_4_unpack
        )      
        prev_cipher_L ^= plain_L
        prev_cipher_R ^= plain_R
        yield u4_2_pack(prev_cipher_L, prev_cipher_R)
        
      if extra_bytes:
        yield bytes(
          b ^ n for b, n in zip(
            data[last_block_stop_i:],
            u4_2_pack(
              *encrypt(
                prev_cipher_L, prev_cipher_R,
                P, S1, S2, S3, S4,
                u4_1_pack, u1_4_unpack
              )
            )
          )
        )