def test_publish(self) -> None: # Arrange now = datetime.now(timezone.utc) description = ElectionDescription( "", ElectionType.unknown, now, now, [], [], [], [], [], [] ) context = CiphertextElectionContext(1, 1, ONE_MOD_P, ONE_MOD_Q) constants = ElectionConstants() devices = [] coefficients = [CoefficientValidationSet("", [], [])] encrypted_ballots = [] tally = PlaintextTally("", [], []) # Act publish( description, context, constants, devices, encrypted_ballots, CiphertextTally("", description, context), tally, coefficients, ) # Assert self.assertTrue(path.exists(RESULTS_DIR)) # Cleanup rmtree(RESULTS_DIR)
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 publish_results(self) -> None: """ Publish results/artifacts of the election """ self.guardian_records = [ guardian.publish() for guardian in self.guardians ] publish( self.manifest, self.context, self.constants, [self.device], self.ballot_store.all(), self.plaintext_spoiled_ballots.values(), self.ciphertext_tally.publish(), self.plaintext_tally, self.guardian_records, RESULTS_DIR, ) self._assert_message( "Publish", f"Artifacts published to: {RESULTS_DIR}", path.exists(RESULTS_DIR), )
def test_publish(self) -> None: # Arrange now = datetime.now(timezone.utc) manifest = Manifest("", ElectionType.unknown, now, now, [], [], [], [], [], []) context = make_ciphertext_election_context( 1, 1, ONE_MOD_P, ONE_MOD_Q, ONE_MOD_Q ) constants = ElectionConstants() devices = [] guardian_records = [GuardianRecord("", "", ONE_MOD_Q, [], [])] encrypted_ballots = [] spoiled_ballots = [] plaintext_tally = PlaintextTally("", []) ciphertext_tally = CiphertextTally("", manifest, context) # Act publish( manifest, context, constants, devices, encrypted_ballots, spoiled_ballots, ciphertext_tally.publish(), plaintext_tally, guardian_records, ) # Assert self.assertTrue(path.exists(RESULTS_DIR)) # Cleanup rmtree(RESULTS_DIR)
def publish_results(self) -> None: """ Publish results/artifacts of the election """ publish( self.description, self.context, self.constants, [self.device], self.ballot_store.all(), self.ciphertext_tally.spoiled_ballots.values(), publish_ciphertext_tally(self.ciphertext_tally), self.plaintext_tally, self.coefficient_validation_sets, ) self._assert_message( "Publish", f"Artifacts published to: {RESULTS_DIR}", path.exists(RESULTS_DIR), )
def publish_results(self) -> None: """ Publish results/artifacts of the election """ publish( self.description, self.context, self.constants, self.ciphertext_ballots, self.ciphertext_tally, self.plaintext_tally, self.coefficient_validation_sets, ) self._assert_message( "Publish", f"Artifacts published to: {RESULTS_DIR}", path.exists(RESULTS_DIR), ) if self.REMOVE_OUTPUT: rmtree(RESULTS_DIR)
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)
def generate( self, number_of_ballots: int = DEFAULT_NUMBER_OF_BALLOTS, spoil_rate: int = DEFAULT_SPOIL_RATE, use_all_guardians: bool = DEFAULT_USE_ALL_GUARDIANS, ): """ Generate the sample data set """ # Clear the results directory rmtree(RESULTS_DIR, ignore_errors=True) # Configure the election ( manifest, private_data, ) = self.election_factory.get_hamilton_manifest_with_encryption_context() plaintext_ballots = ( self.ballot_factory.generate_fake_plaintext_ballots_for_election( manifest.internal_manifest, number_of_ballots ) ) self.encrypter = EncryptionMediator( manifest.internal_manifest, manifest.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 = DataStore() ballot_box = BallotBox( manifest.internal_manifest, manifest.context, ballot_store ) # Randomly cast/spoil the ballots submitted_ballots: List[SubmittedBallot] = [] for ballot in ciphertext_ballots: if randint(0, 100) < spoil_rate: submitted_ballots.append(ballot_box.spoil(ballot)) else: submitted_ballots.append(ballot_box.cast(ballot)) # Tally spoiled_ciphertext_ballots = get_ballots(ballot_store, BallotBoxState.SPOILED) ciphertext_tally = get_optional( tally_ballots(ballot_store, manifest.internal_manifest, manifest.context) ) # Decrypt mediator = DecryptionMediator("sample-manifest-decrypter", manifest.context) available_guardians = ( private_data.guardians if use_all_guardians else private_data.guardians[0:QUORUM] ) DecryptionHelper.perform_decryption_setup( available_guardians, mediator, manifest.context, ciphertext_tally, spoiled_ciphertext_ballots, ) plaintext_tally = get_optional(mediator.get_plaintext_tally(ciphertext_tally)) plaintext_spoiled_ballots = get_optional( mediator.get_plaintext_ballots(spoiled_ciphertext_ballots) ) # Publish publish( manifest.manifest, manifest.context, manifest.constants, [self.encryption_device], submitted_ballots, plaintext_spoiled_ballots.values(), ciphertext_tally.publish(), plaintext_tally, manifest.guardians, ) publish_private_data( plaintext_ballots, ciphertext_ballots, private_data.guardians )