def step_2_encrypt_votes(self) -> None: """ Using the `CiphertextElectionContext` encrypt ballots for the election """ # Configure the Encryption Device self.device = ElectionFactory.get_encryption_device() self.encrypter = EncryptionMediator(self.internal_manifest, self.context, self.device) self._assert_message( EncryptionDevice.__qualname__, f"Ready to encrypt at location: {self.device.location}", ) # Load some Ballots self.plaintext_ballots = BallotFactory().get_simple_ballots_from_file() self._assert_message( PlaintextBallot.__qualname__, f"Loaded ballots: {len(self.plaintext_ballots)}", len(self.plaintext_ballots) > 0, ) # Encrypt the Ballots for plaintext_ballot in self.plaintext_ballots: encrypted_ballot = self.encrypter.encrypt(plaintext_ballot) self._assert_message( EncryptionMediator.encrypt.__qualname__, f"Ballot Id: {plaintext_ballot.object_id}", encrypted_ballot is not None, ) self.ciphertext_ballots.append(get_optional(encrypted_ballot))
class ElectionSampleDataGenerator: """ Generates sample data for an example election using the "Hamilton County" data set. """ election_factory: ElectionFactory ballot_factory: BallotFactory encryption_device: EncryptionDevice encrypter: EncryptionMediator def __init__(self) -> None: """Initialize the class""" self.election_factory = ElectionFactory() self.ballot_factory = BallotFactory() self.encryption_device = EncryptionDevice(f"polling-place-{uuid.uuid1}") def generate(self, number_of_ballots: int = DEFAULT_NUMBER_OF_BALLOTS): """ Generate the sample data set """ rmtree(RESULTS_DIR, ignore_errors=True) ( public_data, private_data, ) = self.election_factory.get_hamilton_election_with_encryption_context() plaintext_ballots = self.ballot_factory.generate_fake_plaintext_ballots_for_election( public_data.metadata, number_of_ballots ) self.encrypter = EncryptionMediator( public_data.metadata, public_data.context, self.encryption_device ) ciphertext_ballots: List[CiphertextBallot] = [] for plaintext_ballot in plaintext_ballots: ciphertext_ballots.append( get_optional(self.encrypter.encrypt(plaintext_ballot)) ) ballot_store = BallotStore() ballot_box = BallotBox(public_data.metadata, public_data.context, ballot_store) accepted_ballots: List[CiphertextAcceptedBallot] = [] for ballot in ciphertext_ballots: if randint(0, 100) % 10 == 0: accepted_ballots.append(ballot_box.spoil(ballot)) else: accepted_ballots.append(ballot_box.cast(ballot)) ciphertext_tally = get_optional( tally_ballots(ballot_store, public_data.metadata, public_data.context) ) decrypter = DecryptionMediator( public_data.metadata, public_data.context, ciphertext_tally ) for guardian in private_data.guardians: decrypter.announce(guardian) plaintext_tally = get_optional(decrypter.get_plaintext_tally()) publish( public_data.description, public_data.context, public_data.constants, accepted_ballots, ciphertext_tally, plaintext_tally, public_data.guardians, ) publish_private_data( plaintext_ballots, ciphertext_ballots, private_data.guardians )
def __init__(self) -> None: """Initialize the class""" self.election_factory = ElectionFactory() self.ballot_factory = BallotFactory() self.encryption_device = EncryptionDevice(f"polling-place-{uuid.uuid1}")
class ElectionSampleDataGenerator: """ Generates sample data for an example election using the "Hamilton County" data set. """ election_factory: ElectionFactory ballot_factory: BallotFactory encryption_device: EncryptionDevice encrypter: EncryptionMediator def __init__(self) -> None: """Initialize the class""" self.election_factory = ElectionFactory() self.ballot_factory = BallotFactory() self.encryption_device = EncryptionDevice( f"polling-place-{str(uuid.uuid1())}") def generate( self, number_of_ballots: int = DEFAULT_NUMBER_OF_BALLOTS, cast_spoil_ratio: int = CAST_SPOIL_RATIO, ): """ Generate the sample data set """ # Clear the results directory rmtree(RESULTS_DIR, ignore_errors=True) # Configure the election ( public_data, private_data, ) = self.election_factory.get_hamilton_election_with_encryption_context( ) plaintext_ballots = self.ballot_factory.generate_fake_plaintext_ballots_for_election( public_data.metadata, number_of_ballots) self.encrypter = EncryptionMediator(public_data.metadata, public_data.context, self.encryption_device) # Encrypt some ballots ciphertext_ballots: List[CiphertextBallot] = [] for plaintext_ballot in plaintext_ballots: ciphertext_ballots.append( get_optional(self.encrypter.encrypt(plaintext_ballot))) ballot_store = BallotStore() ballot_box = BallotBox(public_data.metadata, public_data.context, ballot_store) # Randomly cast/spoil the ballots accepted_ballots: List[CiphertextAcceptedBallot] = [] for ballot in ciphertext_ballots: if randint(0, 100) % cast_spoil_ratio == 0: accepted_ballots.append(ballot_box.spoil(ballot)) else: accepted_ballots.append(ballot_box.cast(ballot)) # Tally ciphertext_tally = get_optional( tally_ballots(ballot_store, public_data.metadata, public_data.context)) # Decrypt decrypter = DecryptionMediator(public_data.metadata, public_data.context, ciphertext_tally) for i, guardian in enumerate(private_data.guardians): if i < QUORUM or not THRESHOLD_ONLY: decrypter.announce(guardian) plaintext_tally = get_optional(decrypter.get_plaintext_tally()) # Publish publish( public_data.description, public_data.context, public_data.constants, [self.encryption_device], accepted_ballots, ciphertext_tally.spoiled_ballots.values(), publish_ciphertext_tally(ciphertext_tally), plaintext_tally, public_data.guardians, ) publish_private_data(plaintext_ballots, ciphertext_ballots, private_data.guardians)