Encrypt plaintext using an oracle function that returns ``True`` if the
    provided ciphertext is correctly PKCS#7 padded after decryption. The
    cipher needs to operate in CBC mode.

    Args:
        oracle(callable): The oracle function. Will be called repeatedly with
            a chunk of ciphertext.
        plaintext(bytes): The plaintext data to encrypt.
        block_size(int): The cipher's block size in bits.
        pool(multiprocessing.Pool): A multiprocessing pool to use to
            parallelize the encryption. This pool is used to call the oracle
            function. Fairly heavy due to the required inter-process state
            synchronization. If ``None`` (the default), no multiprocessing
            will be used.

    Returns:
        bytes: The encrypted data.

    Raises:
        RuntimeError: Raised if the oracle behaves unpredictable.

def padding_oracle_encrypt(oracle, plaintext, block_size=128, pool=None):
    """
    Encrypt plaintext using an oracle function that returns ``True`` if the
    provided ciphertext is correctly PKCS#7 padded after decryption. The
    cipher needs to operate in CBC mode.

    Args:
        oracle(callable): The oracle function. Will be called repeatedly with
            a chunk of ciphertext.
        plaintext(bytes): The plaintext data to encrypt.
        block_size(int): The cipher's block size in bits.
        pool(multiprocessing.Pool): A multiprocessing pool to use to
            parallelize the encryption. This pool is used to call the oracle
            function. Fairly heavy due to the required inter-process state
            synchronization. If ``None`` (the default), no multiprocessing
            will be used.

    Returns:
        bytes: The encrypted data.

    Raises:
        RuntimeError: Raised if the oracle behaves unpredictable.
    """

    plaintext = bytearray(plaintext)
    block_len = block_size // 8

    padding_len = block_len - (len(plaintext) % block_len)
    plaintext.extend([padding_len] * padding_len)

    ciphertext = bytearray()

    chunk = bytearray(os.urandom(block_len))
    ciphertext[0:0] = chunk

    for plain_start in range(len(plaintext) - block_len, -1, -block_len):
        plain = plaintext[plain_start:plain_start + block_len]
        chunk = ciphertext[0:0] = encrypt_block(oracle, block_len, chunk, plain, pool)

    return bytes(ciphertext)