def test_decrypt_selection_valid_input_succeeds(
        self,
        selection_description: Tuple[str, SelectionDescription],
        keypair: ElGamalKeyPair,
        nonce_seed: ElementModQ,
        random_seed: int,
    ):

        # Arrange
        random = Random(random_seed)
        _, description = selection_description
        data = ballot_factory.get_random_selection_from(description, random)

        # Act
        subject = encrypt_selection(data, description, keypair.public_key, nonce_seed)
        self.assertIsNotNone(subject)

        result_from_key = decrypt_selection_with_secret(
            subject, description, keypair.public_key, keypair.secret_key
        )
        result_from_nonce = decrypt_selection_with_nonce(
            subject, description, keypair.public_key
        )
        result_from_nonce_seed = decrypt_selection_with_nonce(
            subject, description, keypair.public_key, nonce_seed
        )

        # Assert
        self.assertIsNotNone(result_from_key)
        self.assertIsNotNone(result_from_nonce)
        self.assertIsNotNone(result_from_nonce_seed)
        self.assertEqual(data.plaintext, result_from_key.plaintext)
        self.assertEqual(data.plaintext, result_from_nonce.plaintext)
        self.assertEqual(data.plaintext, result_from_nonce_seed.plaintext)
    def test_encrypt_simple_selection_malformed_data_fails(self):

        # Arrange
        keypair = elgamal_keypair_from_secret(int_to_q(2))
        nonce = randbelow(Q)
        metadata = SelectionDescription("some-selection-object-id",
                                        "some-candidate-id", 1)
        hash_context = metadata.crypto_hash()

        subject = selection_from(metadata)
        self.assertTrue(subject.is_valid(metadata.object_id))

        # Act
        result = encrypt_selection(subject, metadata, keypair.public_key,
                                   nonce)

        # tamper with the description_hash
        malformed_description_hash = deepcopy(result)
        malformed_description_hash.description_hash = TWO_MOD_Q

        # remove the proof
        missing_proof = deepcopy(result)
        missing_proof.proof = None

        # Assert
        self.assertFalse(
            malformed_description_hash.is_valid_encryption(
                hash_context, keypair.public_key))
        self.assertFalse(
            missing_proof.is_valid_encryption(hash_context,
                                              keypair.public_key))
    def test_decrypt_selection_tampered_nonce_fails(
        self,
        selection_description: Tuple[str, SelectionDescription],
        keypair: ElGamalKeyPair,
        nonce_seed: ElementModQ,
        random_seed: int,
    ):

        # Arrange
        random = Random(random_seed)
        _, description = selection_description
        data = ballot_factory.get_random_selection_from(description, random)

        # Act
        subject = encrypt_selection(data, description, keypair.public_key, nonce_seed)
        self.assertIsNotNone(subject)

        # Tamper with the nonce by setting it to an aribtrary value
        subject.nonce = nonce_seed

        result_from_nonce_seed = decrypt_selection_with_nonce(
            subject, description, keypair.public_key, nonce_seed
        )

        # Assert
        self.assertIsNone(result_from_nonce_seed)
示例#4
0
    def test_encrypt_selection_valid_input_succeeds(
        self,
        selection_description: Tuple[str, SelectionDescription],
        keypair: ElGamalKeyPair,
        seed: ElementModQ,
        random_seed: int,
    ):

        # Arrange
        _, description = selection_description
        random = Random(random_seed)
        subject = ballot_factory.get_random_selection_from(description, random)

        # Act
        result = encrypt_selection(
            subject, description, keypair.public_key, ONE_MOD_Q, seed
        )

        # Assert
        self.assertIsNotNone(result)
        self.assertIsNotNone(result.ciphertext)
        self.assertTrue(
            result.is_valid_encryption(
                description.crypto_hash(), keypair.public_key, ONE_MOD_Q
            )
        )
示例#5
0
    def test_encrypt_selection_valid_input_tampered_encryption_fails(
        self,
        selection_description: Tuple[str, SelectionDescription],
        keypair: ElGamalKeyPair,
        seed: ElementModQ,
        random_seed: int,
    ):

        # Arrange
        _, description = selection_description
        random = Random(random_seed)
        subject = ballot_factory.get_random_selection_from(description, random)

        # Act
        result = encrypt_selection(
            subject,
            description,
            keypair.public_key,
            ONE_MOD_Q,
            seed,
            should_verify_proofs=False,
        )
        self.assertTrue(
            result.is_valid_encryption(description.crypto_hash(),
                                       keypair.public_key, ONE_MOD_Q))

        # tamper with the encryption
        malformed_encryption = deepcopy(result)
        malformed_message = malformed_encryption.ciphertext._replace(
            pad=mult_p(result.ciphertext.pad, TWO_MOD_P))
        malformed_encryption.ciphertext = malformed_message

        # tamper with the proof
        malformed_proof = deepcopy(result)
        altered_a0 = mult_p(result.proof.proof_zero_pad, TWO_MOD_P)
        malformed_disjunctive = DisjunctiveChaumPedersenProof(
            altered_a0,
            malformed_proof.proof.proof_zero_data,
            malformed_proof.proof.proof_one_pad,
            malformed_proof.proof.proof_one_data,
            malformed_proof.proof.proof_zero_challenge,
            malformed_proof.proof.proof_one_challenge,
            malformed_proof.proof.challenge,
            malformed_proof.proof.proof_zero_response,
            malformed_proof.proof.proof_one_response,
        )
        malformed_proof.proof = malformed_disjunctive

        # Assert
        self.assertFalse(
            malformed_encryption.is_valid_encryption(description.crypto_hash(),
                                                     keypair.public_key,
                                                     ONE_MOD_Q))
        self.assertFalse(
            malformed_proof.is_valid_encryption(description.crypto_hash(),
                                                keypair.public_key, ONE_MOD_Q))
    def test_decrypt_selection_valid_input_tampered_fails(
        self,
        selection_description: Tuple[str, SelectionDescription],
        keypair: ElGamalKeyPair,
        seed: ElementModQ,
        random_seed: int,
    ):

        # Arrange
        _, description = selection_description
        random = Random(random_seed)
        data = ballot_factory.get_random_selection_from(description, random)

        # Act
        subject = encrypt_selection(data, description, keypair.public_key,
                                    seed)

        # tamper with the encryption
        malformed_encryption = deepcopy(subject)
        malformed_message = malformed_encryption.ciphertext._replace(
            pad=mult_p(subject.ciphertext.pad, TWO_MOD_P))
        malformed_encryption.ciphertext = malformed_message

        # tamper with the proof
        malformed_proof = deepcopy(subject)
        altered_a0 = mult_p(subject.proof.a0, TWO_MOD_P)
        malformed_disjunctive = DisjunctiveChaumPedersenProof(
            altered_a0,
            malformed_proof.proof.b0,
            malformed_proof.proof.a1,
            malformed_proof.proof.b1,
            malformed_proof.proof.c0,
            malformed_proof.proof.c1,
            malformed_proof.proof.v0,
            malformed_proof.proof.v1,
        )
        malformed_proof.proof = malformed_disjunctive

        result_from_key_malformed_encryption = decrypt_selection_with_secret(
            malformed_encryption, description, keypair.public_key,
            keypair.secret_key)

        result_from_key_malformed_proof = decrypt_selection_with_secret(
            malformed_proof, description, keypair.public_key,
            keypair.secret_key)

        result_from_nonce_malformed_encryption = decrypt_selection_with_nonce(
            malformed_encryption, description, keypair.public_key)
        result_from_nonce_malformed_proof = decrypt_selection_with_nonce(
            malformed_proof, description, keypair.public_key)

        # Assert
        self.assertIsNone(result_from_key_malformed_encryption)
        self.assertIsNone(result_from_key_malformed_proof)
        self.assertIsNone(result_from_nonce_malformed_encryption)
        self.assertIsNone(result_from_nonce_malformed_proof)
    def test_encrypt_selection_valid_input_tampered_encryption_fails(
        self,
        selection_description: Tuple[str, SelectionDescription],
        keypair: ElGamalKeyPair,
        seed: ElementModQ,
        random_seed: int,
    ):

        # Arrange
        _, description = selection_description
        random = Random(random_seed)
        subject = ballot_factory.get_random_selection_from(description, random)

        # Act
        result = encrypt_selection(subject,
                                   description,
                                   keypair.public_key,
                                   seed,
                                   should_verify_proofs=False)
        self.assertTrue(
            result.is_valid_encryption(description.crypto_hash(),
                                       keypair.public_key))

        # tamper with the encryption
        malformed_encryption = deepcopy(result)
        malformed_message = malformed_encryption.message._replace(
            alpha=mult_p(result.message.alpha, TWO_MOD_P))
        malformed_encryption.message = malformed_message

        # tamper with the proof
        malformed_proof = deepcopy(result)
        malformed_disjunctive = malformed_proof.proof._replace(
            a0=mult_p(result.proof.a0, TWO_MOD_P))
        malformed_proof.proof = malformed_disjunctive

        # Assert
        self.assertFalse(
            malformed_encryption.is_valid_encryption(description.crypto_hash(),
                                                     keypair.public_key))
        self.assertFalse(
            malformed_proof.is_valid_encryption(description.crypto_hash(),
                                                keypair.public_key))
    def test_encrypt_simple_selection_succeeds(self):

        # Arrange
        keypair = elgamal_keypair_from_secret(int_to_q(2))
        nonce = randbelow(Q)
        metadata = SelectionDescription("some-selection-object-id",
                                        "some-candidate-id", 1)
        hash_context = metadata.crypto_hash()

        subject = selection_from(metadata)
        self.assertTrue(subject.is_valid(metadata.object_id))

        # Act
        result = encrypt_selection(subject, metadata, keypair.public_key,
                                   nonce)

        # Assert
        self.assertIsNotNone(result)
        self.assertIsNotNone(result.message)
        self.assertTrue(
            result.is_valid_encryption(hash_context, keypair.public_key))