Ejemplo n.º 1
0
    def test_publish_election_backup_challenge(self):
        # Arrange
        guardian = Guardian(
            SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        recipient_guardian = Guardian(
            RECIPIENT_GUARDIAN_ID,
            RECIPIENT_SEQUENCE_ORDER,
            NUMBER_OF_GUARDIANS,
            QUORUM,
        )

        guardian.save_auxiliary_public_key(
            recipient_guardian.share_auxiliary_public_key()
        )
        guardian.generate_election_partial_key_backups(identity_auxiliary_encrypt)

        # Act
        challenge = guardian.publish_election_backup_challenge(RECIPIENT_GUARDIAN_ID)

        # Assert
        self.assertIsNotNone(challenge)
        self.assertIsNotNone(challenge.value)
        self.assertEqual(challenge.owner_id, SENDER_GUARDIAN_ID)
        self.assertEqual(challenge.designated_id, RECIPIENT_GUARDIAN_ID)
        self.assertEqual(len(challenge.coefficient_commitments), QUORUM)
        self.assertEqual(len(challenge.coefficient_proofs), QUORUM)
        for proof in challenge.coefficient_proofs:
            proof.is_valid()
Ejemplo n.º 2
0
    def test_reset(self):
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)
        expected_number_of_guardians = 10
        expected_quorum = 4

        # Act
        guardian.reset(expected_number_of_guardians, expected_quorum)

        # Assert
        self.assertEqual(expected_number_of_guardians,
                         guardian.ceremony_details.number_of_guardians)
        self.assertEqual(expected_quorum, guardian.ceremony_details.quorum)
Ejemplo n.º 3
0
    def test_share_election_public_key(self):
        # Arrange
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)

        # Act
        public_key = guardian.share_election_public_key()

        # Assert
        self.assertIsNotNone(public_key)
        self.assertIsNotNone(public_key.key)
        self.assertEqual(public_key.owner_id, SENDER_GUARDIAN_ID)
        self.assertTrue(public_key.proof.is_valid())
Ejemplo n.º 4
0
    def test_share_auxiliary_public_key(self):
        # Arrange
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)

        # Act
        public_key = guardian.share_auxiliary_public_key()

        # Assert
        self.assertIsNotNone(public_key)
        self.assertIsNotNone(public_key.key)
        self.assertEqual(public_key.owner_id, SENDER_GUARDIAN_ID)
        self.assertEqual(public_key.sequence_order, SENDER_SEQUENCE_ORDER)
Ejemplo n.º 5
0
    def test_share_public_keys(self):
        # Arrange
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)

        # Act
        public_keys = guardian.share_public_keys()

        # Assert
        self.assertIsNotNone(public_keys)
        self.assertIsNotNone(public_keys.auxiliary_public_key)
        self.assertIsNotNone(public_keys.election_public_key)
        self.assertEqual(public_keys.owner_id, SENDER_GUARDIAN_ID)
        self.assertEqual(public_keys.sequence_order, SENDER_SEQUENCE_ORDER)
        self.assertTrue(public_keys.election_public_key_proof.is_valid())
Ejemplo n.º 6
0
 def create_guardians(ceremony_details: CeremonyDetails) -> List[Guardian]:
     return [
         Guardian(
             "guardian_" + str(i + 1),
             i + 1,
             ceremony_details.number_of_guardians,
             ceremony_details.quorum,
         ) for i in range(ceremony_details.number_of_guardians)
     ]
Ejemplo n.º 7
0
    def test_all_public_keys_received(self):
        # Arrange
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)
        other_guardian = Guardian(RECIPIENT_GUARDIAN_ID,
                                  RECIPIENT_SEQUENCE_ORDER,
                                  NUMBER_OF_GUARDIANS, QUORUM)
        public_keys = other_guardian.share_public_keys()

        # Act
        self.assertFalse(guardian.all_public_keys_received())
        guardian.save_guardian_public_keys(public_keys)

        # Assert
        self.assertTrue(guardian.all_public_keys_received())
Ejemplo n.º 8
0
    def test_share_election_partial_key_backup(self):
        # Arrange
        guardian = Guardian(
            SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        other_guardian = Guardian(
            RECIPIENT_GUARDIAN_ID, RECIPIENT_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )

        # Act
        guardian.save_auxiliary_public_key(other_guardian.share_auxiliary_public_key())
        guardian.generate_election_partial_key_backups(identity_auxiliary_encrypt)
        key_backup = guardian.share_election_partial_key_backup(RECIPIENT_GUARDIAN_ID)

        # Assert
        self.assertIsNotNone(key_backup)
        self.assertIsNotNone(key_backup.encrypted_value)
        self.assertEqual(key_backup.owner_id, SENDER_GUARDIAN_ID)
        self.assertEqual(key_backup.designated_id, RECIPIENT_GUARDIAN_ID)
Ejemplo n.º 9
0
    def test_save_election_public_key(self):
        # Arrange
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)
        other_guardian = Guardian(RECIPIENT_GUARDIAN_ID,
                                  RECIPIENT_SEQUENCE_ORDER,
                                  NUMBER_OF_GUARDIANS, QUORUM)
        public_key = other_guardian.share_election_public_key()

        # Act
        guardian.save_election_public_key(public_key)

        # Assert
        self.assertTrue(guardian.all_election_public_keys_received())
Ejemplo n.º 10
0
    def process_message(self, message_type: str, message: dict,
                        context: Context):
        context.build_election(message)

        guardian_ids = [trustee['name'] for trustee in message['trustees']]
        context.guardian_ids = set(guardian_ids)
        order = guardian_ids.index(context.guardian_id)
        context.guardian = Guardian(context.guardian_id, order,
                                    context.number_of_guardians,
                                    context.quorum)

        self.next_step = ProcessTrusteeElectionKeys()
        return serialize(context.guardian.share_public_keys())
Ejemplo n.º 11
0
    def test_share_election_partial_key_backup(self):
        # Arrange
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)
        other_guardian = Guardian(RECIPIENT_GUARDIAN_ID,
                                  RECIPIENT_SEQUENCE_ORDER,
                                  NUMBER_OF_GUARDIANS, QUORUM)

        # Act
        guardian.save_auxiliary_public_key(
            other_guardian.share_auxiliary_public_key())
        guardian.generate_election_partial_key_backups()
        key_backup = guardian.share_election_partial_key_backup(
            RECIPIENT_GUARDIAN_ID)

        # Assert
        self.assertIsNotNone(key_backup)
        self.assertIsNotNone(key_backup.encrypted_value)
        self.assertEqual(key_backup.owner_id, SENDER_GUARDIAN_ID)
        self.assertEqual(key_backup.designated_id, RECIPIENT_GUARDIAN_ID)
        self.assertEqual(len(key_backup.coefficient_commitments), QUORUM)
        self.assertEqual(len(key_backup.coefficient_proofs), QUORUM)
        for proof in key_backup.coefficient_proofs:
            proof.is_valid()
Ejemplo n.º 12
0
    def setupGuardians(self):
        # Setup Guardians
        for i in range(self.NUMBER_OF_GUARDIANS):
            sequence = i + 2
            self.guardians.append(
                Guardian(
                    "guardian_" + str(sequence),
                    sequence,
                    self.NUMBER_OF_GUARDIANS,
                    self.QUORUM,
                ))

        # Attendance (Public Key Share)
        for guardian in self.guardians:
            self.key_ceremony_mediator.announce(guardian)
Ejemplo n.º 13
0
    def test_publish_private_data(self) -> None:
        # Arrange
        plaintext_ballots = [PlaintextBallot("", "", [])]
        encrypted_ballots = [CiphertextBallot("", "", "", "", [])]
        guardians = [Guardian("", 1, 1, 1)]

        # Act
        publish_private_data(
            plaintext_ballots, encrypted_ballots, guardians,
        )

        # Assert
        self.assertTrue(path.exists(RESULTS_DIR))

        # Cleanup
        rmtree(RESULTS_DIR)
Ejemplo n.º 14
0
    def get_hamilton_election_with_encryption_context(
        self, ) -> Tuple[AllPublicElectionData, AllPrivateElectionData]:
        guardians: List[Guardian] = []
        coefficient_validation_sets: List[CoefficientValidationSet] = []

        # Configure the election builder
        description = self.get_hamilton_election_from_file()
        builder = ElectionBuilder(NUMBER_OF_GUARDIANS, QUORUM, description)

        # Setup Guardians
        for i in range(NUMBER_OF_GUARDIANS):
            guardians.append(
                Guardian(
                    "hamilton-county-canvass-board-member-" + str(i),
                    i,
                    NUMBER_OF_GUARDIANS,
                    QUORUM,
                ))

        # Run the key ceremony
        mediator = KeyCeremonyMediator(guardians[0].ceremony_details)
        for guardian in guardians:
            mediator.announce(guardian)
        mediator.orchestrate()
        mediator.verify()

        # Joint Key
        joint_key = mediator.publish_joint_key()

        # Save Validation Keys
        for guardian in guardians:
            coefficient_validation_sets.append(
                guardian.share_coefficient_validation_set())

        builder.set_public_key(get_optional(joint_key).joint_public_key)
        builder.set_commitment_hash(get_optional(joint_key).commitment_hash)
        metadata, context = get_optional(builder.build())
        constants = ElectionConstants()

        return (
            AllPublicElectionData(description, metadata, context, constants,
                                  coefficient_validation_sets),
            AllPrivateElectionData(guardians),
        )
Ejemplo n.º 15
0
    def test_generate_auxiliary_key_pair(self):
        # Arrange
        guardian = Guardian(SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER,
                            NUMBER_OF_GUARDIANS, QUORUM)
        first_public_key = guardian.share_auxiliary_public_key()

        # Act
        guardian.generate_auxiliary_key_pair()
        second_public_key = guardian.share_auxiliary_public_key()

        # Assert
        self.assertIsNotNone(second_public_key)
        self.assertIsNotNone(second_public_key.key)
        self.assertNotEqual(first_public_key.key, second_public_key.key)
Ejemplo n.º 16
0
    def process_message(
        self,
        message_type: Literal["create_election"],
        message: dict,
        context: TrusteeContext,
    ) -> Tuple[List[Content], ElectionStep]:
        context.build_election(message)

        guardian_ids: List[GUARDIAN_ID] = [
            trustee["slug"] for trustee in message["trustees"]
        ]
        context.guardian_ids = guardian_ids
        context.guardian = Guardian(
            context.guardian_id,
            guardian_ids.index(context.guardian_id) + 1,
            context.number_of_guardians,
            context.quorum,
        )

        return [], ProcessStartKeyCeremony()
Ejemplo n.º 17
0
    def test_all_election_partial_key_backups_verified(self):
        # Arrange
        guardian = Guardian(
            SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        other_guardian = Guardian(
            RECIPIENT_GUARDIAN_ID, RECIPIENT_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        guardian.save_auxiliary_public_key(other_guardian.share_auxiliary_public_key())
        guardian.generate_election_partial_key_backups(identity_auxiliary_encrypt)
        key_backup = guardian.share_election_partial_key_backup(RECIPIENT_GUARDIAN_ID)
        other_guardian.save_election_partial_key_backup(key_backup)
        verification = other_guardian.verify_election_partial_key_backup(
            SENDER_GUARDIAN_ID, identity_auxiliary_decrypt
        )
        guardian.save_election_partial_key_verification(verification)

        # Act
        all_saved = guardian.all_election_partial_key_backups_verified()

        # Assert
        self.assertTrue(all_saved)
Ejemplo n.º 18
0
    def test_verify_election_partial_key_challenge(self):
        # Arrange
        guardian = Guardian(
            SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        recipient_guardian = Guardian(
            RECIPIENT_GUARDIAN_ID,
            RECIPIENT_SEQUENCE_ORDER,
            NUMBER_OF_GUARDIANS,
            QUORUM,
        )
        alternate_guardian = Guardian(
            ALTERNATE_VERIFIER_GUARDIAN_ID,
            ALTERNATE_VERIFIER_SEQUENCE_ORDER,
            NUMBER_OF_GUARDIANS,
            QUORUM,
        )
        guardian.save_auxiliary_public_key(
            recipient_guardian.share_auxiliary_public_key()
        )
        guardian.generate_election_partial_key_backups(identity_auxiliary_encrypt)
        challenge = guardian.publish_election_backup_challenge(RECIPIENT_GUARDIAN_ID)

        # Act
        verification = alternate_guardian.verify_election_partial_key_challenge(
            challenge
        )

        # Assert
        self.assertIsNotNone(verification)
        self.assertEqual(verification.owner_id, SENDER_GUARDIAN_ID)
        self.assertEqual(verification.designated_id, RECIPIENT_GUARDIAN_ID)
        self.assertEqual(verification.verifier_id, ALTERNATE_VERIFIER_GUARDIAN_ID)
        self.assertTrue(verification.verified)
Ejemplo n.º 19
0
    def test_verify_election_partial_key_backup(self):
        # Arrange
        guardian = Guardian(
            SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        other_guardian = Guardian(
            RECIPIENT_GUARDIAN_ID, RECIPIENT_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        guardian.save_auxiliary_public_key(other_guardian.share_auxiliary_public_key())
        guardian.generate_election_partial_key_backups(identity_auxiliary_encrypt)
        key_backup = guardian.share_election_partial_key_backup(RECIPIENT_GUARDIAN_ID)
        other_guardian.save_election_partial_key_backup(key_backup)

        # Act
        verification = other_guardian.verify_election_partial_key_backup(
            SENDER_GUARDIAN_ID, identity_auxiliary_decrypt
        )

        # Assert
        self.assertIsNotNone(verification)
        self.assertEqual(verification.owner_id, SENDER_GUARDIAN_ID)
        self.assertEqual(verification.designated_id, RECIPIENT_GUARDIAN_ID)
        self.assertEqual(verification.verifier_id, RECIPIENT_GUARDIAN_ID)
        self.assertTrue(verification.verified)
Ejemplo n.º 20
0
    def test_all_election_partial_key_backups_received(self):
        # Arrange
        guardian = Guardian(
            SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        other_guardian = Guardian(
            RECIPIENT_GUARDIAN_ID, RECIPIENT_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        guardian.save_auxiliary_public_key(other_guardian.share_auxiliary_public_key())
        guardian.generate_election_partial_key_backups(identity_auxiliary_encrypt)
        key_backup = guardian.share_election_partial_key_backup(RECIPIENT_GUARDIAN_ID)

        # Assert
        self.assertFalse(other_guardian.all_election_partial_key_backups_received())
        other_guardian.save_election_partial_key_backup(key_backup)
        self.assertTrue(other_guardian.all_election_partial_key_backups_received())
Ejemplo n.º 21
0
    def step_1_key_ceremony(self) -> None:
        """
        Using the NUMBER_OF_GUARDIANS, generate public-private keypairs and share
        representations of those keys with QUORUM of other Guardians.  Then, combine
        the public election keys to make a joint election key that is used to encrypt ballots
        """

        # Setup Guardians
        for i in range(self.NUMBER_OF_GUARDIANS):
            self.guardians.append(
                Guardian("guardian_" + str(i), i, self.NUMBER_OF_GUARDIANS,
                         self.QUORUM))

        # Setup Mediator
        self.mediator = KeyCeremonyMediator(self.guardians[0].ceremony_details)

        # Attendance (Public Key Share)
        for guardian in self.guardians:
            self.mediator.announce(guardian)

        self._assert_message(
            KeyCeremonyMediator.all_guardians_in_attendance.__qualname__,
            "Confirms all guardians have shared their public keys",
            self.mediator.all_guardians_in_attendance(),
        )

        # Run the Key Ceremony process,
        # Which shares the keys among the guardians
        orchestrated = self.mediator.orchestrate()
        self._assert_message(
            KeyCeremonyMediator.orchestrate.__qualname__,
            "Executes the key exchange between guardians",
            orchestrated is not None,
        )

        self._assert_message(
            KeyCeremonyMediator.all_election_partial_key_backups_available.
            __qualname__,
            "Confirm sall guardians have shared their partial key backups",
            self.mediator.all_election_partial_key_backups_available(),
        )

        # Verification
        verified = self.mediator.verify()
        self._assert_message(
            KeyCeremonyMediator.verify.__qualname__,
            "Confirms all guardians truthfully executed the ceremony",
            verified,
        )

        self._assert_message(
            KeyCeremonyMediator.
            all_election_partial_key_verifications_received.__qualname__,
            "Confirms all guardians have submitted a verification of the backups of all other guardians",
            self.mediator.all_election_partial_key_verifications_received(),
        )

        self._assert_message(
            KeyCeremonyMediator.all_election_partial_key_backups_verified.
            __qualname__,
            "Confirms all guardians have verified the backups of all other guardians",
            self.mediator.all_election_partial_key_backups_verified(),
        )

        # Joint Key
        joint_key = self.mediator.publish_joint_key()
        self._assert_message(
            KeyCeremonyMediator.publish_joint_key.__qualname__,
            "Publishes the Joint Election Key",
            joint_key is not None,
        )

        # Save Validation Keys
        for guardian in self.guardians:
            self.coefficient_validation_sets.append(
                guardian.share_coefficient_validation_set())

        # Build the Election
        self.election_builder.set_public_key(get_optional(joint_key))
        self.metadata, self.context = get_optional(
            self.election_builder.build())
        self.constants = ElectionConstants()
Ejemplo n.º 22
0
    def test_publish_joint_key(self):
        # Arrange
        guardian = Guardian(
            SENDER_GUARDIAN_ID, SENDER_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        other_guardian = Guardian(
            RECIPIENT_GUARDIAN_ID, RECIPIENT_SEQUENCE_ORDER, NUMBER_OF_GUARDIANS, QUORUM
        )
        guardian.save_auxiliary_public_key(other_guardian.share_auxiliary_public_key())
        guardian.generate_election_partial_key_backups(identity_auxiliary_encrypt)
        key_backup = guardian.share_election_partial_key_backup(RECIPIENT_GUARDIAN_ID)
        other_guardian.save_election_partial_key_backup(key_backup)
        verification = other_guardian.verify_election_partial_key_backup(
            SENDER_GUARDIAN_ID, identity_auxiliary_decrypt
        )

        # Act
        joint_key = guardian.publish_joint_key()

        # Assert
        self.assertIsNone(joint_key)

        # Act
        guardian.save_election_public_key(other_guardian.share_election_public_key())
        joint_key = guardian.publish_joint_key()

        # Assert
        self.assertIsNone(joint_key)

        # Act
        guardian.save_election_partial_key_verification(verification)
        joint_key = guardian.publish_joint_key()

        # Assert
        self.assertIsNotNone(joint_key)
        self.assertNotEqual(joint_key, guardian.share_election_public_key().key)
Ejemplo n.º 23
0
    CeremonyDetails,
    ElectionPartialKeyVerification,
    GuardianPair,
)
from electionguard.key_ceremony_mediator import KeyCeremonyMediator

identity_auxiliary_decrypt = lambda message, public_key: message
identity_auxiliary_encrypt = lambda message, private_key: message

NUMBER_OF_GUARDIANS = 2
QUORUM = 2
CEREMONY_DETAILS = CeremonyDetails(NUMBER_OF_GUARDIANS, QUORUM)
GUARDIAN_1_ID = "Guardian 1"
GUARDIAN_2_ID = "Guardian 2"
VERIFIER_ID = "Guardian 3"
GUARDIAN_1 = Guardian(GUARDIAN_1_ID, 1, NUMBER_OF_GUARDIANS, QUORUM)
GUARDIAN_2 = Guardian(GUARDIAN_2_ID, 2, NUMBER_OF_GUARDIANS, QUORUM)
VERIFIER = Guardian(VERIFIER_ID, 3, NUMBER_OF_GUARDIANS, QUORUM)
GUARDIAN_1.save_guardian_public_keys(GUARDIAN_2.share_public_keys())
GUARDIAN_2.save_guardian_public_keys(GUARDIAN_1.share_public_keys())
VERIFIER.save_guardian_public_keys(GUARDIAN_2.share_public_keys())
GUARDIAN_1.generate_election_partial_key_backups(identity_auxiliary_encrypt)
GUARDIAN_2.generate_election_partial_key_backups(identity_auxiliary_encrypt)


class TestKeyCeremonyMediator(TestCase):
    def test_reset(self):
        # Arrange
        mediator = KeyCeremonyMediator(CEREMONY_DETAILS)
        new_ceremony_details = CeremonyDetails(3, 3)
    def step_1_key_ceremony(self) -> None:
        """
        Using the NUMBER_OF_GUARDIANS, generate public-private keypairs and share
        representations of those keys with QUORUM of other Guardians.  Then, combine
        the public election keys to make a joint election key that is used to encrypt ballots
        """

        # Setup Guardians
        for i in range(self.NUMBER_OF_GUARDIANS):
            self.guardians.append(
                Guardian(
                    "guardian_" + str(i + 1),
                    i + 1,
                    self.NUMBER_OF_GUARDIANS,
                    self.QUORUM,
                ))

        # Setup Mediator
        self.mediator = KeyCeremonyMediator("mediator_1",
                                            self.guardians[0].ceremony_details)

        # ROUND 1: Public Key Sharing
        # Announce
        for guardian in self.guardians:
            self.mediator.announce(guardian.share_public_keys())

        # Share Keys
        for guardian in self.guardians:
            announced_keys = self.mediator.share_announced()
            for key_set in announced_keys:
                if guardian.id is not key_set.election.owner_id:
                    guardian.save_guardian_public_keys(key_set)

        self._assert_message(
            KeyCeremonyMediator.all_guardians_announced.__qualname__,
            "Confirms all guardians have shared their public keys",
            self.mediator.all_guardians_announced(),
        )

        # ROUND 2: Election Partial Key Backup Sharing
        # Share Backups
        for sending_guardian in self.guardians:
            sending_guardian.generate_election_partial_key_backups(
                identity_auxiliary_encrypt)
            backups = []
            for designated_guardian in self.guardians:
                if designated_guardian.id != sending_guardian.id:
                    backups.append(
                        sending_guardian.share_election_partial_key_backup(
                            designated_guardian.id))
            self.mediator.receive_backups(backups)
            self._assert_message(
                KeyCeremonyMediator.receive_backups.__qualname__,
                "Receive election partial key backups from key owning guardian",
                len(backups) == NUMBER_OF_GUARDIANS - 1,
            )

        self._assert_message(
            KeyCeremonyMediator.all_backups_available.__qualname__,
            "Confirm all guardians have shared their election partial key backups",
            self.mediator.all_backups_available(),
        )

        # Receive Backups
        for designated_guardian in self.guardians:
            backups = self.mediator.share_backups(designated_guardian.id)
            self._assert_message(
                KeyCeremonyMediator.share_backups.__qualname__,
                "Share election partial key backups for the designated guardian",
                len(backups) == NUMBER_OF_GUARDIANS - 1,
            )
            for backup in backups:
                designated_guardian.save_election_partial_key_backup(backup)

        # ROUND 3: Verification of Backups
        # Verify Backups
        for designated_guardian in self.guardians:
            verifications = []
            for backup_owner in self.guardians:
                if designated_guardian.id is not backup_owner.id:
                    verification = (
                        designated_guardian.verify_election_partial_key_backup(
                            backup_owner.id, identity_auxiliary_encrypt))
                    verifications.append(verification)
            self.mediator.receive_backup_verifications(verifications)

        self._assert_message(
            KeyCeremonyMediator.all_backups_verified.__qualname__,
            "Confirms all guardians have verified the backups of all other guardians",
            self.mediator.all_backups_verified(),
        )

        # FINAL: Publish Joint Key
        joint_key = self.mediator.publish_joint_key()
        self._assert_message(
            KeyCeremonyMediator.publish_joint_key.__qualname__,
            "Publishes the Joint Election Key",
            joint_key is not None,
        )

        # Build the Election
        self.election_builder.set_public_key(
            get_optional(joint_key).joint_public_key)
        self.election_builder.set_commitment_hash(
            get_optional(joint_key).commitment_hash)
        self.internal_manifest, self.context = get_optional(
            self.election_builder.build())
        self.constants = ElectionConstants()
    def setUp(self):

        self.key_ceremony = KeyCeremonyMediator(self.CEREMONY_DETAILS)

        self.guardians: List[Guardian] = []

        # Setup Guardians
        for i in range(self.NUMBER_OF_GUARDIANS):
            sequence = i + 2
            self.guardians.append(
                Guardian(
                    "guardian_" + str(sequence),
                    sequence,
                    self.NUMBER_OF_GUARDIANS,
                    self.QUORUM,
                ))

        # Attendance (Public Key Share)
        for guardian in self.guardians:
            self.key_ceremony.announce(guardian)

        self.key_ceremony.orchestrate(identity_auxiliary_encrypt)
        self.key_ceremony.verify(identity_auxiliary_decrypt)

        self.joint_public_key = self.key_ceremony.publish_joint_key()
        self.assertIsNotNone(self.joint_public_key)

        # setup the election
        self.election = election_factory.get_fake_election()
        builder = ElectionBuilder(self.NUMBER_OF_GUARDIANS, self.QUORUM,
                                  self.election)

        self.assertIsNone(
            builder.build())  # Can't build without the public key

        builder.set_public_key(self.joint_public_key)
        self.metadata, self.context = get_optional(builder.build())

        self.encryption_device = EncryptionDevice("location")
        self.ballot_marking_device = EncryptionMediator(
            self.metadata, self.context, self.encryption_device)

        # get some fake ballots
        self.fake_cast_ballot = ballot_factory.get_fake_ballot(
            self.metadata, "some-unique-ballot-id-cast")
        self.more_fake_ballots = []
        for i in range(10):
            self.more_fake_ballots.append(
                ballot_factory.get_fake_ballot(
                    self.metadata, f"some-unique-ballot-id-cast{i}"))
        self.fake_spoiled_ballot = ballot_factory.get_fake_ballot(
            self.metadata, "some-unique-ballot-id-spoiled")
        self.assertTrue(
            self.fake_cast_ballot.is_valid(
                self.metadata.ballot_styles[0].object_id))
        self.assertTrue(
            self.fake_spoiled_ballot.is_valid(
                self.metadata.ballot_styles[0].object_id))
        self.expected_plaintext_tally = accumulate_plaintext_ballots(
            [self.fake_cast_ballot] + self.more_fake_ballots)

        # Fill in the expected values with any missing selections
        # that were not made on any ballots
        selection_ids = set([
            selection.object_id for contest in self.metadata.contests
            for selection in contest.ballot_selections
        ])

        missing_selection_ids = selection_ids.difference(
            set(self.expected_plaintext_tally))

        for id in missing_selection_ids:
            self.expected_plaintext_tally[id] = 0

        # Encrypt
        encrypted_fake_cast_ballot = self.ballot_marking_device.encrypt(
            self.fake_cast_ballot)
        encrypted_fake_spoiled_ballot = self.ballot_marking_device.encrypt(
            self.fake_spoiled_ballot)
        self.assertIsNotNone(encrypted_fake_cast_ballot)
        self.assertIsNotNone(encrypted_fake_spoiled_ballot)
        self.assertTrue(
            encrypted_fake_cast_ballot.is_valid_encryption(
                self.context.crypto_extended_base_hash, self.joint_public_key))

        # encrypt some more fake ballots
        self.more_fake_encrypted_ballots = []
        for fake_ballot in self.more_fake_ballots:
            self.more_fake_encrypted_ballots.append(
                self.ballot_marking_device.encrypt(fake_ballot))

        # configure the ballot box
        ballot_store = BallotStore()
        ballot_box = BallotBox(self.metadata, self.context, ballot_store)
        ballot_box.cast(encrypted_fake_cast_ballot)
        ballot_box.spoil(encrypted_fake_spoiled_ballot)

        # Cast some more fake ballots
        for fake_ballot in self.more_fake_encrypted_ballots:
            ballot_box.cast(fake_ballot)

        # generate encrypted tally
        self.ciphertext_tally = tally_ballots(ballot_store, self.metadata,
                                              self.context)
Ejemplo n.º 26
0
from electionguard.guardian import Guardian
from electionguard.key_ceremony import (
    CeremonyDetails,
    ElectionPartialKeyVerification,
)
from electionguard.key_ceremony_mediator import KeyCeremonyMediator, GuardianPair
from electionguardtest.key_ceremony_helper import KeyCeremonyHelper
from electionguardtest.identity_encrypt import identity_auxiliary_decrypt

NUMBER_OF_GUARDIANS = 2
QUORUM = 2
CEREMONY_DETAILS = CeremonyDetails(NUMBER_OF_GUARDIANS, QUORUM)
GUARDIAN_1_ID = "Guardian 1"
GUARDIAN_2_ID = "Guardian 2"
GUARDIAN_1 = Guardian(GUARDIAN_1_ID, 1, NUMBER_OF_GUARDIANS, QUORUM)
GUARDIAN_2 = Guardian(GUARDIAN_2_ID, 2, NUMBER_OF_GUARDIANS, QUORUM)
GUARDIANS = [GUARDIAN_1, GUARDIAN_2]


class TestKeyCeremonyMediator(TestCase):
    """Key ceremony mediator tests"""
    def test_reset(self):
        # Arrange
        mediator = KeyCeremonyMediator("mediator_reset", CEREMONY_DETAILS)
        new_ceremony_details = CeremonyDetails(3, 3)

        mediator.reset(new_ceremony_details)
        self.assertEqual(mediator.ceremony_details, new_ceremony_details)

    def test_take_attendance(self):