def encrypt_ballots(request: EncryptBallotsRequest = Body(...)) -> Any:
    """
    Encrypt one or more ballots
    """
    ballots = [
        PlaintextBallot.from_json_object(ballot) for ballot in request.ballots
    ]
    description = InternalElectionDescription(
        ElectionDescription.from_json_object(request.description))
    context = CiphertextElectionContext.from_json_object(request.context)
    seed_hash = read_json_object(request.seed_hash, ElementModQ)
    nonce: Optional[ElementModQ] = (read_json_object(
        request.nonce, ElementModQ) if request.nonce else None)

    encrypted_ballots = []
    current_hash = seed_hash

    for ballot in ballots:
        encrypted_ballot = encrypt_ballot(ballot, description, context,
                                          current_hash, nonce)
        if not encrypted_ballot:
            raise HTTPException(status_code=500,
                                detail="Ballot failed to encrypt")
        encrypted_ballots.append(encrypted_ballot)
        current_hash = get_optional(encrypted_ballot.tracking_hash)

    response = EncryptBallotsResponse(
        encrypted_ballots=[
            ballot.to_json_object() for ballot in encrypted_ballots
        ],
        next_seed_hash=write_json_object(current_hash),
    )
    return response
def create_guardian_backup(request: GuardianBackupRequest) -> GuardianBackup:
    """
    Generate all election partial key backups based on existing public keys
    :param request: Guardian backup request
    :return: Guardian backup
    """
    encrypt = identity if request.override_rsa else rsa_encrypt
    backups: List[Any] = []
    for auxiliary_public_key in request.auxiliary_public_keys:
        backup = generate_election_partial_key_backup(
            request.guardian_id,
            read_json_object(request.election_polynomial, ElectionPolynomial),
            AuxiliaryPublicKey(
                auxiliary_public_key.owner_id,
                auxiliary_public_key.sequence_order,
                auxiliary_public_key.key,
            ),
            encrypt,
        )
        if not backup:
            raise HTTPException(status_code=500, detail="Backup failed to be generated")
        backups.append(write_json_object(backup))

    return GuardianBackup(
        id=request.guardian_id,
        election_partial_key_backups=backups,
    )
Exemple #3
0
def combine_election_keys(request: CombineElectionKeysRequest) -> ElectionJointKey:
    """
    Combine public election keys into a final one
    :return: Combine Election key
    """
    public_keys = []
    for key in request.election_public_keys:
        public_keys.append(int_to_p_unchecked(key))
    joint_key = elgamal_combine_public_keys(public_keys)
    return ElectionJointKey(joint_key=write_json_object(joint_key))
def create_backup_challenge(request: BackupChallengeRequest) -> Any:
    challenge = generate_election_partial_key_challenge(
        read_json_object(request.election_partial_key_backup, ElectionPartialKeyBackup),
        read_json_object(request.election_polynomial, ElectionPolynomial),
    )
    if not challenge:
        raise HTTPException(
            status_code=500, detail="Backup challenge generation failed"
        )

    return write_json_object(challenge)
def verify_challenge(request: ChallengeVerificationRequest) -> Any:
    verification = verify_election_partial_key_challenge(
        request.verifier_id,
        read_json_object(
            request.election_partial_key_challenge, ElectionPartialKeyChallenge
        ),
    )
    if not verification:
        raise HTTPException(
            status_code=500, detail="Challenge verification process failed"
        )
    return write_json_object(verification)
    def test_read_and_write_json_object(self) -> None:
        # Act
        json_object = write_json_object(JSON_DATA)

        # Assert
        self.assertEqual(json_object, EXPECTED_JSON_OBJECT)

        # Act
        read_json_data = read_json_object(json_object, DataModel)

        # Assert
        self.assertEqual(read_json_data, JSON_DATA)
def verify_backup(request: BackupVerificationRequest) -> Any:
    decrypt = identity if request.override_rsa else rsa_decrypt
    verification = verify_election_partial_key_backup(
        request.verifier_id,
        read_json_object(request.election_partial_key_backup, ElectionPartialKeyBackup),
        read_json_object(request.auxiliary_key_pair, AuxiliaryKeyPair),
        decrypt,
    )
    if not verification:
        raise HTTPException(
            status_code=500, detail="Backup verification process failed"
        )
    return write_json_object(verification)
def generate_election_keys(request: ElectionKeyPairRequest) -> ElectionKeyPair:
    """
    Generate election key pairs for use in election process
    :param request: Election key pair request
    :return: Election key pair
    """
    keys = generate_election_key_pair(
        request.quorum,
        int_to_q_unchecked(request.nonce)
        if request.nonce is not None else None,
    )
    if not keys:
        raise HTTPException(
            status_code=500,
            detail="Election keys failed to be generated",
        )
    return ElectionKeyPair(
        public_key=str(keys.key_pair.public_key),
        secret_key=str(keys.key_pair.secret_key),
        proof=write_json_object(keys.proof),
        polynomial=write_json_object(keys.polynomial),
    )
def create_guardian(request: GuardianRequest) -> Guardian:
    """
    Create a guardian for the election process with the associated keys
    """
    election_keys = generate_election_key_pair(
        request.quorum,
        int_to_q_unchecked(request.nonce) if request.nonce is not None else None,
    )
    if request.auxiliary_key_pair is None:
        auxiliary_keys = generate_rsa_auxiliary_key_pair()
    else:
        auxiliary_keys = request.auxiliary_key_pair
    if not election_keys:
        raise HTTPException(
            status_code=500,
            detail="Election keys failed to be generated",
        )
    if not auxiliary_keys:
        raise HTTPException(
            status_code=500, detail="Auxiliary keys failed to be generated"
        )
    return Guardian(
        id=request.id,
        sequence_order=request.sequence_order,
        number_of_guardians=request.number_of_guardians,
        quorum=request.quorum,
        election_key_pair=ElectionKeyPair(
            public_key=str(election_keys.key_pair.public_key),
            secret_key=str(election_keys.key_pair.secret_key),
            proof=write_json_object(election_keys.proof),
            polynomial=write_json_object(election_keys.polynomial),
        ),
        auxiliary_key_pair=AuxiliaryKeyPair(
            public_key=auxiliary_keys.public_key, secret_key=auxiliary_keys.secret_key
        ),
    )
Exemple #10
0
def build_election_context(request: ElectionContextRequest = Body(...)) -> Any:
    """
    Build a CiphertextElectionContext for a given election
    """
    description: ElectionDescription = ElectionDescription.from_json_object(
        request.description)
    elgamal_public_key: ElementModP = read_json_object(
        request.elgamal_public_key, ElementModP)
    number_of_guardians = request.number_of_guardians
    quorum = request.quorum

    context = make_ciphertext_election_context(number_of_guardians, quorum,
                                               elgamal_public_key,
                                               description.crypto_hash())

    return write_json_object(context)
def decrypt_share(
    request: DecryptTallyShareRequest = Body(...),
    scheduler: Scheduler = Depends(get_scheduler),
) -> Any:
    """
    Decrypt a single guardian's share of a tally
    """
    description = InternalElectionDescription(
        ElectionDescription.from_json_object(request.description)
    )
    context = CiphertextElectionContext.from_json_object(request.context)
    guardian = convert_guardian(request.guardian)
    tally = convert_tally(request.encrypted_tally, description, context)

    share = compute_decryption_share(guardian, tally, context, scheduler)

    return write_json_object(share)
def decrypt_ballots(request: DecryptBallotsRequest = Body(...)) -> Any:
    ballots = [
        CiphertextAcceptedBallot.from_json_object(ballot)
        for ballot in request.encrypted_ballots
    ]
    context: CiphertextElectionContext = CiphertextElectionContext.from_json_object(
        request.context)

    all_shares: List[BallotDecryptionShare] = [
        read_json_object(share, BallotDecryptionShare)
        for shares in request.shares.values() for share in shares
    ]
    shares_by_ballot = index_shares_by_ballot(all_shares)

    extended_base_hash = context.crypto_extended_base_hash
    decrypted_ballots = {
        ballot.object_id:
        decrypt_ballot(ballot, shares_by_ballot[ballot.object_id],
                       extended_base_hash)
        for ballot in ballots
    }

    return write_json_object(decrypted_ballots)
Exemple #13
0
def decrypt_ballot_shares(
    request: DecryptBallotSharesRequest = Body(...),
    scheduler: Scheduler = Depends(get_scheduler),
) -> Any:
    """
    Decrypt this guardian's share of one or more ballots
    """
    ballots = [
        CiphertextAcceptedBallot.from_json_object(ballot)
        for ballot in request.encrypted_ballots
    ]
    context = CiphertextElectionContext.from_json_object(request.context)
    guardian = convert_guardian(request.guardian)

    shares = [
        compute_decryption_share_for_ballot(guardian, ballot, context, scheduler)
        for ballot in ballots
    ]

    response = DecryptBallotSharesResponse(
        shares=[write_json_object(share) for share in shares]
    )

    return response
Exemple #14
0
def serialize_as_dict(obj, include_private: bool = False) -> object:
    return write_json_object(obj, not include_private)
Exemple #15
0
def serialize(obj, include_private: bool = False):
    return write_json_object(obj, not include_private)