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)
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 ) )
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))