def encrypt_contest(contest: PlaintextBallotContest, contest_description: ContestDescriptionWithPlaceholders, elgamal_public_key: ElementModP, crypto_extended_base_hash: ElementModQ, nonce_seed: ElementModQ, should_verify_proofs: bool=True) -> Optional[CiphertextBallotContest]:
    "\n    Encrypt a specific `BallotContest` in the context of a specific `Ballot`.\n\n    This method accepts a contest representation that only includes `True` selections.\n    It will fill missing selections for a contest with `False` values, and generate `placeholder`\n    selections to represent the number of seats available for a given contest.  By adding `placeholder`\n    votes\n\n    :param contest: the contest in the valid input form\n    :param contest_description: the `ContestDescriptionWithPlaceholders`\n        from the `ContestDescription` which defines this contest's structure\n    :param elgamal_public_key: the public key (k) used to encrypt the ballot\n    :param crypto_extended_base_hash: the extended base hash of the election\n    :param nonce_seed: an `ElementModQ` used as a header to seed the `Nonce` generated for this contest.\n                 this value can be (or derived from) the Ballot nonce, but no relationship is required\n    :param should_verify_proofs: specify if the proofs should be verified prior to returning (default True)\n    "
    if (not contest.is_valid(contest_description.object_id, len(contest_description.ballot_selections), contest_description.number_elected, contest_description.votes_allowed)):
        log_warning(f'malformed input contest: {contest}')
        return None
    if (not contest_description.is_valid()):
        log_warning(f'malformed contest description: {contest_description}')
        return None
    contest_description_hash = contest_description.crypto_hash()
    nonce_sequence = Nonces(contest_description_hash, nonce_seed)
    contest_nonce = nonce_sequence[contest_description.sequence_order]
    chaum_pedersen_nonce = next(iter(nonce_sequence))
    encrypted_selections: List[CiphertextBallotSelection] = list()
    selection_count = 0
    for description in contest_description.ballot_selections:
        has_selection = False
        encrypted_selection = None
        for selection in contest.ballot_selections:
            if (selection.object_id == description.object_id):
                has_selection = True
                selection_count += selection.vote
                encrypted_selection = encrypt_selection(selection, description, elgamal_public_key, crypto_extended_base_hash, contest_nonce)
                break
        if (not has_selection):
            encrypted_selection = encrypt_selection(selection_from(description), description, elgamal_public_key, crypto_extended_base_hash, contest_nonce)
        if (encrypted_selection is None):
            return None
        encrypted_selections.append(get_optional(encrypted_selection))
    for placeholder in contest_description.placeholder_selections:
        select_placeholder = False
        if (selection_count < contest_description.number_elected):
            select_placeholder = True
            selection_count += 1
        encrypted_selection = encrypt_selection(selection=selection_from(description=placeholder, is_placeholder=True, is_affirmative=select_placeholder), selection_description=placeholder, elgamal_public_key=elgamal_public_key, crypto_extended_base_hash=crypto_extended_base_hash, nonce_seed=contest_nonce, is_placeholder=True, should_verify_proofs=True)
        if (encrypted_selection is None):
            return None
        encrypted_selections.append(get_optional(encrypted_selection))
    if ((contest_description.votes_allowed is not None) and (selection_count < contest_description.votes_allowed)):
        log_warning('mismatching selection count: only n-of-m style elections are currently supported')
    encrypted_contest = make_ciphertext_ballot_contest(object_id=contest.object_id, description_hash=contest_description_hash, ballot_selections=encrypted_selections, elgamal_public_key=elgamal_public_key, crypto_extended_base_hash=crypto_extended_base_hash, proof_seed=chaum_pedersen_nonce, number_elected=contest_description.number_elected, nonce=contest_nonce)
    if ((encrypted_contest is None) or (encrypted_contest.proof is None)):
        return None
    if (not should_verify_proofs):
        return encrypted_contest
    if encrypted_contest.is_valid_encryption(contest_description_hash, elgamal_public_key, crypto_extended_base_hash):
        return encrypted_contest
    log_warning(f'mismatching contest proof for contest {encrypted_contest.object_id}')
    return None
Encrypt a specific `BallotContest` in the context of a specific `Ballot`.

This method accepts a contest representation that only includes `True` selections.
It will fill missing selections for a contest with `False` values, and generate `placeholder`
selections to represent the number of seats available for a given contest.  By adding `placeholder`
votes

:param contest: the contest in the valid input form
:param contest_description: the `ContestDescriptionWithPlaceholders`
    from the `ContestDescription` which defines this contest's structure
:param elgamal_public_key: the public key (k) used to encrypt the ballot
:param crypto_extended_base_hash: the extended base hash of the election
:param nonce_seed: an `ElementModQ` used as a header to seed the `Nonce` generated for this contest.
             this value can be (or derived from) the Ballot nonce, but no relationship is required
:param should_verify_proofs: specify if the proofs should be verified prior to returning (default True)
def encrypt_contest(contest: PlaintextBallotContest, contest_description: ContestDescriptionWithPlaceholders, elgamal_public_key: ElementModP, crypto_extended_base_hash: ElementModQ, nonce_seed: ElementModQ, should_verify_proofs: bool=True) -> Optional[CiphertextBallotContest]:
    "\n    Encrypt a specific `BallotContest` in the context of a specific `Ballot`.\n\n    This method accepts a contest representation that only includes `True` selections.\n    It will fill missing selections for a contest with `False` values, and generate `placeholder`\n    selections to represent the number of seats available for a given contest.  By adding `placeholder`\n    votes\n\n    :param contest: the contest in the valid input form\n    :param contest_description: the `ContestDescriptionWithPlaceholders`\n        from the `ContestDescription` which defines this contest's structure\n    :param elgamal_public_key: the public key (k) used to encrypt the ballot\n    :param crypto_extended_base_hash: the extended base hash of the election\n    :param nonce_seed: an `ElementModQ` used as a header to seed the `Nonce` generated for this contest.\n                 this value can be (or derived from) the Ballot nonce, but no relationship is required\n    :param should_verify_proofs: specify if the proofs should be verified prior to returning (default True)\n    "
    if (not contest.is_valid(contest_description.object_id, len(contest_description.ballot_selections), contest_description.number_elected, contest_description.votes_allowed)):
        log_warning(f'malformed input contest: {contest}')
        return None
    if (not contest_description.is_valid()):
        log_warning(f'malformed contest description: {contest_description}')
        return None
    contest_description_hash = contest_description.crypto_hash()
    nonce_sequence = Nonces(contest_description_hash, nonce_seed)
    contest_nonce = nonce_sequence[contest_description.sequence_order]
    chaum_pedersen_nonce = next(iter(nonce_sequence))
    encrypted_selections: List[CiphertextBallotSelection] = list()
    selection_count = 0
    for description in contest_description.ballot_selections:
        has_selection = False
        encrypted_selection = None
        for selection in contest.ballot_selections:
            if (selection.object_id == description.object_id):
                has_selection = True
                selection_count += selection.vote
                encrypted_selection = encrypt_selection(selection, description, elgamal_public_key, crypto_extended_base_hash, contest_nonce)
                break
        if (not has_selection):
            encrypted_selection = encrypt_selection(selection_from(description), description, elgamal_public_key, crypto_extended_base_hash, contest_nonce)
        if (encrypted_selection is None):
            return None
        encrypted_selections.append(get_optional(encrypted_selection))
    for placeholder in contest_description.placeholder_selections:
        select_placeholder = False
        if (selection_count < contest_description.number_elected):
            select_placeholder = True
            selection_count += 1
        encrypted_selection = encrypt_selection(selection=selection_from(description=placeholder, is_placeholder=True, is_affirmative=select_placeholder), selection_description=placeholder, elgamal_public_key=elgamal_public_key, crypto_extended_base_hash=crypto_extended_base_hash, nonce_seed=contest_nonce, is_placeholder=True, should_verify_proofs=True)
        if (encrypted_selection is None):
            return None
        encrypted_selections.append(get_optional(encrypted_selection))
    if ((contest_description.votes_allowed is not None) and (selection_count < contest_description.votes_allowed)):
        log_warning('mismatching selection count: only n-of-m style elections are currently supported')
    encrypted_contest = make_ciphertext_ballot_contest(object_id=contest.object_id, description_hash=contest_description_hash, ballot_selections=encrypted_selections, elgamal_public_key=elgamal_public_key, crypto_extended_base_hash=crypto_extended_base_hash, proof_seed=chaum_pedersen_nonce, number_elected=contest_description.number_elected, nonce=contest_nonce)
    if ((encrypted_contest is None) or (encrypted_contest.proof is None)):
        return None
    if (not should_verify_proofs):
        return encrypted_contest
    if encrypted_contest.is_valid_encryption(contest_description_hash, elgamal_public_key, crypto_extended_base_hash):
        return encrypted_contest
    log_warning(f'mismatching contest proof for contest {encrypted_contest.object_id}')
    return None