def test_generate_publickey(self): """ Creates a new ThresholdEncryptionSetUp and generate commitments for all trustees add them to the ThresholdEncryptionSetUp and generate a public key """ cryptosystem = get_cryptosystem() commitments = [] # Generate a new instance of ThresholdEncryptionSetUp tSetUp = ThresholdEncryptionSetUp(cryptosystem, self.num_trustees, self.threshold) # Adding the keys from trustees for i in range(self.num_trustees): tSetUp.add_trustee_public_key(i, self.trustees[i].public_key) # Generate commitmes for trustees for i in range(self.num_trustees): commitments.append(tSetUp.generate_commitment()) # generate_commitment must raise ThresholdEncryptionSetUpStateError # if called without added commitments self.assertRaises(ThresholdEncryptionSetUpStateError, tSetUp.generate_public_key) # Adding the first self.num_trustees - 1 commitments from trustees for i in range(self.num_trustees - 1): tSetUp.add_trustee_commitment(i, commitments[i]) # generate_commitment must raise ThresholdEncryptionSetUpStateError # if called without all added commitments self.assertRaises(ThresholdEncryptionSetUpStateError, tSetUp.generate_public_key) # Add the last commitments from trustees tSetUp.add_trustee_commitment(self.num_trustees - 1, commitments[self.num_trustees - 1]) publickey = tSetUp.generate_public_key() # The generated public key must have the same cryptosystem, trustees # and threshold self.assertEqual(publickey.cryptosystem, cryptosystem) self.assertEqual(publickey.num_trustees, self.num_trustees) self.assertEqual(publickey.threshold, self.threshold) # Check that multiple calls generate the same public key publickey2 = tSetUp.generate_public_key() self.assertEqual(publickey2, publickey) self.assertEqual(publickey2.get_fingerprint(), publickey.get_fingerprint())
def test_generate_privatekey(self): """ Creates a new ThresholdEncryptionSetUp and generate commitments for all trustees add them to the ThresholdEncryptionSetUp and generate a private key """ cryptosystem = get_cryptosystem() commitments = [] # Generate a new instance of ThresholdEncryptionSetUp tSetUp = ThresholdEncryptionSetUp(cryptosystem, self.num_trustees, self.threshold) # Adding the keys from trustees for i in range(self.num_trustees): tSetUp.add_trustee_public_key(i, self.trustees[i].public_key) # Generate commitmes for trustees for i in range(self.num_trustees): commitments.append(tSetUp.generate_commitment()) # generate_private_key must raise ThresholdEncryptionSetUpStateError # if called without added commitments self.assertRaises(ThresholdEncryptionSetUpStateError, tSetUp.generate_private_key, 0, self.trustees[0].private_key) # Adding the first self.num_trustees - 1 commitments from trustees for i in range(self.num_trustees - 1): tSetUp.add_trustee_commitment(i, commitments[i]) # generate_private_key must raise ThresholdEncryptionSetUpStateError # if called without all added commitments self.assertRaises(ThresholdEncryptionSetUpStateError, tSetUp.generate_private_key, 0, self.trustees[0].private_key) # Add the last commitments from trustees tSetUp.add_trustee_commitment(self.num_trustees - 1, commitments[self.num_trustees - 1]) # Must fail if the trustee doenst have his corresponding private_key self.assertRaises(InvalidCommitmentError, tSetUp.generate_private_key, 0, self.trustees[1].private_key) privatekey = tSetUp.generate_private_key(0, self.trustees[0].private_key) # The privatekey atributes must be the expected from tSetUp self.assertTrue(privatekey.cryptosystem, cryptosystem) self.assertEqual(privatekey.num_trustees, self.num_trustees) self.assertEqual(privatekey.threshold, self.threshold) self.assertEqual(privatekey.public_key, tSetUp.generate_public_key())
def test_generate_privatekey(self): """ Creates a new ThresholdEncryptionSetUp and generate commitments for all trustees add them to the ThresholdEncryptionSetUp and generate a private key """ cryptosystem = get_cryptosystem() commitments = [] # Generate a new instance of ThresholdEncryptionSetUp tSetUp = ThresholdEncryptionSetUp(cryptosystem, self.num_trustees, self.threshold) # Adding the keys from trustees for i in range(self.num_trustees): tSetUp.add_trustee_public_key(i, self.trustees[i].public_key) # Generate commitmes for trustees for i in range(self.num_trustees): commitments.append(tSetUp.generate_commitment()) # generate_private_key must raise ThresholdEncryptionSetUpStateError # if called without added commitments self.assertRaises(ThresholdEncryptionSetUpStateError, tSetUp.generate_private_key, 0,self.trustees[0].private_key) # Adding the first self.num_trustees - 1 commitments from trustees for i in range(self.num_trustees - 1): tSetUp.add_trustee_commitment(i, commitments[i]) # generate_private_key must raise ThresholdEncryptionSetUpStateError # if called without all added commitments self.assertRaises(ThresholdEncryptionSetUpStateError, tSetUp.generate_private_key, 0,self.trustees[0].private_key) # Add the last commitments from trustees tSetUp.add_trustee_commitment(self.num_trustees - 1, commitments[self.num_trustees - 1]) # Must fail if the trustee doenst have his corresponding private_key self.assertRaises(InvalidCommitmentError,tSetUp.generate_private_key, 0,self.trustees[1].private_key) privatekey = tSetUp.generate_private_key(0,self.trustees[0].private_key) # The privatekey atributes must be the expected from tSetUp self.assertTrue(privatekey.cryptosystem, cryptosystem) self.assertEqual(privatekey.num_trustees, self.num_trustees) self.assertEqual(privatekey.threshold, self.threshold) self.assertEqual(privatekey.public_key, tSetUp.generate_public_key())
def test_partial_decryption(self): """ Create a ciphertext with the threshold public key and decrypt it and create others ciphertext to prove IncompatibleCiphertextError """ tprk = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) text_to_encrypt_dir = os.path.join( os.path.dirname(__file__), "TestThresholdPrivateKey.resources") text_to_encrypt = os.path.join(text_to_encrypt_dir, "text_to_encrypt") text_encrypted = self.tpkey.encrypt_text(text_to_encrypt) # Decrypt the file created with our public key must be fine tprk.generate_partial_decryption(text_encrypted) # Create another ThresholdEcryptuonSetUp with other 1024 bits # cryptosys to create a cypthertext that cant be decrypted second_cryptosys_file = os.path.join( os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test1024bits_second.pvcryptosys") # Load the cryptosystem from file second_cryptosys = EGCryptoSystem.from_file(second_cryptosys_file) secondtSetUp = ThresholdEncryptionSetUp(second_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): secondtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) secondcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): secondcommitments.append(secondtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): secondtSetUp.add_trustee_commitment(i, secondcommitments[i]) # Generate secon cryptosis publickey secondtpkey = secondtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey secondtext_encrypted = secondtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, secondtext_encrypted) # Create another ThresholdEcryptuonSetUp with other 512 bits # cryptosys to create a cypthertext that cant be decrypted third_cryptosys_file = os.path.join( os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test512bits.pvcryptosys") # Load the cryptosystem from file third_cryptosys = EGCryptoSystem.from_file(third_cryptosys_file) thirdtSetUp = ThresholdEncryptionSetUp(third_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): thirdtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) thirdcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): thirdcommitments.append(thirdtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): thirdtSetUp.add_trustee_commitment(i, thirdcommitments[i]) # Generate secon cryptosis publickey thirdtpkey = thirdtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey thirdtext_encrypted = thirdtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, thirdtext_encrypted)
class TestThresholdPrivateKey(unittest.TestCase): """ Test the class: plonevotecryptolib.Threshold.ThresholdPublicKey. ThresholdPublicKey """ def setUp(self): """ Unit test setup method. """ self.num_trustees = 5 self.threshold = 3 self.trustees = [] self.commitments = [] for i in range(self.num_trustees): self.trustees.append(Trustee()) # Generate a new instance of ThresholdEncryptionSetUp to be used # for generate publickeys cryptosystem = get_cryptosystem() self.tSetUp = ThresholdEncryptionSetUp(cryptosystem, self.num_trustees, self.threshold) # Adding the keys from trustees for i in range(self.num_trustees): self.tSetUp.add_trustee_public_key(i, self.trustees[i].public_key) # Generate commitmes for trustees for i in range(self.num_trustees): self.commitments.append(self.tSetUp.generate_commitment()) # Adding the trustees commitments for i in range(self.num_trustees): self.tSetUp.add_trustee_commitment(i, self.commitments[i]) self.tpkey = self.tSetUp.generate_public_key() def test_privatekey_generation(self): """ Create a new ThresholdPrivateKey, verify that is created correctly """ privatekey = ThresholdPrivateKey(self.tSetUp.cryptosystem, self.num_trustees, self.threshold, self.tpkey, self.trustees[0].private_key) # The values of the parameters must be the same we expect self.assertEquals(privatekey.cryptosystem, self.tSetUp.cryptosystem) self.assertEquals(privatekey.num_trustees, self.num_trustees) self.assertEquals(privatekey.threshold, self.threshold) self.assertEquals(privatekey.public_key, self.tpkey) self.assertEquals(privatekey._key, self.trustees[0].private_key) def test_partial_decryption(self): """ Create a ciphertext with the threshold public key and decrypt it and create others ciphertext to prove IncompatibleCiphertextError """ tprk = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) text_to_encrypt_dir = os.path.join( os.path.dirname(__file__), "TestThresholdPrivateKey.resources") text_to_encrypt = os.path.join(text_to_encrypt_dir, "text_to_encrypt") text_encrypted = self.tpkey.encrypt_text(text_to_encrypt) # Decrypt the file created with our public key must be fine tprk.generate_partial_decryption(text_encrypted) # Create another ThresholdEcryptuonSetUp with other 1024 bits # cryptosys to create a cypthertext that cant be decrypted second_cryptosys_file = os.path.join( os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test1024bits_second.pvcryptosys") # Load the cryptosystem from file second_cryptosys = EGCryptoSystem.from_file(second_cryptosys_file) secondtSetUp = ThresholdEncryptionSetUp(second_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): secondtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) secondcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): secondcommitments.append(secondtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): secondtSetUp.add_trustee_commitment(i, secondcommitments[i]) # Generate secon cryptosis publickey secondtpkey = secondtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey secondtext_encrypted = secondtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, secondtext_encrypted) # Create another ThresholdEcryptuonSetUp with other 512 bits # cryptosys to create a cypthertext that cant be decrypted third_cryptosys_file = os.path.join( os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test512bits.pvcryptosys") # Load the cryptosystem from file third_cryptosys = EGCryptoSystem.from_file(third_cryptosys_file) thirdtSetUp = ThresholdEncryptionSetUp(third_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): thirdtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) thirdcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): thirdcommitments.append(thirdtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): thirdtSetUp.add_trustee_commitment(i, thirdcommitments[i]) # Generate secon cryptosis publickey thirdtpkey = thirdtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey thirdtext_encrypted = thirdtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, thirdtext_encrypted) def test_partial_decryption_w_task_monitor(self): """ Test that partial decryption can be monitored using a TaskMonitor object. """ # Get a new task monitor and a counter task_monitor = TaskMonitor() partialDecryptionCounter = Counter() # Register a task monitor callback to increment the counter once # for each 5% progress of partial decryption def partial_decryption_callback(tm): partialDecryptionCounter.increment() task_monitor.add_on_progress_percent_callback( partial_decryption_callback, percent_span=5.0) # Generate a partial decryption passing the task_monitor object tprk = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) text_to_encrypt_dir = os.path.join( os.path.dirname(__file__), "TestThresholdPrivateKey.resources") text_to_encrypt = os.path.join(text_to_encrypt_dir, "text_to_encrypt") text_encrypted = self.tpkey.encrypt_text(text_to_encrypt) tprk.generate_partial_decryption(text_encrypted, task_monitor) # Check that the counter has been incremented 100/5 = 20 times self.assertEqual(partialDecryptionCounter.value, 20) def test_save_load_file(self): """ Test that we can correctly save a ThresholdPrivateKey to a file and load it back. """ # Get a new threshold private key object pkey = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) # Get a temporary file object using tempfile (file_object, file_path) = tempfile.mkstemp() # We close the file descriptor since we will not be using it, instead # PublicKey's methods take the filename and open/close the file as # needed. # Note that using mkstemp() instead tempfile.TemporaryFile means the # file remains in the filesystem even after it is closed. os.close(file_object) # Save the key using to_file(...) pkey.to_file(file_path) # Load it back using ThresholdPrivateKey.from_file(...) recovered_key = ThresholdPrivateKey.from_file(file_path) # Check that parameters and keys match (and thus they're the same key) self.assertEqual(pkey.cryptosystem, recovered_key.cryptosystem) self.assertEqual(pkey.num_trustees, recovered_key.num_trustees) self.assertEqual(pkey.threshold, recovered_key.threshold) self.assertEqual(pkey.public_key.get_fingerprint(), recovered_key.public_key.get_fingerprint()) self.assertEqual(pkey._key, recovered_key._key) # Delete the temporary file os.remove(file_path) def test_load_invalid_file(self): """ Test that loading a threshold private key from a file in an invalid format raises an appropriate exception. """ # Construct the path to the directory where our invalid test files are # located: invalid_files_dir = os.path.join(os.path.dirname(__file__), "TestThresholdPrivateKey.resources", "invalid_tprivatekey_xml_files") # Add invalid private key files as needed for file_name in [ "err_missing_pub_key_elem.pvpubkey", "err_not_valid_number_elem.pvpubkey", "err_prv_key_too_large.pvpubkey", "err_pub_key_too_large.pvpubkey", "err_par_pub_key_too_large.pvpubkey" ]: inv_file = os.path.join(invalid_files_dir, file_name) self.assertRaises(InvalidPloneVoteCryptoFileError, ThresholdPrivateKey.from_file, inv_file)
class TestThresholdPublicKey(unittest.TestCase): """ Test the class: plonevotecryptolib.Threshold.ThresholdPublicKey. ThresholdPublicKey """ def setUp(self): """ Unit test setup method. """ self.num_trustees = 5 self.threshold = 3 self.trustees = [] self.commitments = [] for i in range(self.num_trustees): self.trustees.append(Trustee()) # Generate a new instance of ThresholdEncryptionSetUp to be used # for generate publickeys cryptosystem = get_cryptosystem() self.tSetUp = ThresholdEncryptionSetUp(cryptosystem, self.num_trustees, self.threshold) # Adding the keys from trustees for i in range(self.num_trustees): self.tSetUp.add_trustee_public_key(i, self.trustees[i].public_key) # Generate commitmes for trustees for i in range(self.num_trustees): self.commitments.append(self.tSetUp.generate_commitment()) # Adding the first trustees commitments for i in range(self.num_trustees): self.tSetUp.add_trustee_commitment(i, self.commitments[i]) def test_publickey_generation(self): """ Create a new ThresholdPublicKey, verify that is created correctly and get_fingerpint and get_partial_public_key returns what spected """ # Generate public_key_value and verification_partial_public_keys as # generated at # ThresholEncryptionSetUp.ThresholdEncryptionSetUp.generate_public_key() key = 1 prime = self.tSetUp.cryptosystem.get_prime() for commitment in self.tSetUp._trustees_commitments: factor = pow(commitment.public_coefficients[0], 2, prime) key = (key * factor) % prime partial_public_keys = [] for trustee in range(1, self.tSetUp._num_trustees + 1): partial_pub_key = 1 for commitment in self.tSetUp._trustees_commitments: ppub_key_fragment = 1 for k in range(0, self.tSetUp._threshold): ppub_key_fragment *= pow(commitment.public_coefficients[k],\ 2*(trustee**k), prime) ppub_key_fragment = ppub_key_fragment % prime partial_pub_key = (partial_pub_key * ppub_key_fragment) % prime partial_public_keys.append(partial_pub_key) # ThresholdPublicKey shoul raise ValueError if threshold > num_trustees # and if len(verification_partial_public_keys) != num_trustees self.assertRaises(ValueError, ThresholdPublicKey, self.tSetUp.cryptosystem, self.tSetUp._num_trustees, self.tSetUp._threshold + self.tSetUp._num_trustees, key, partial_public_keys) self.assertRaises(ValueError, ThresholdPublicKey, self.tSetUp.cryptosystem, self.tSetUp._num_trustees +1 , self.tSetUp._threshold, key, partial_public_keys) # Generate a new ThresholdPublicKey pkey = ThresholdPublicKey(self.tSetUp.cryptosystem, self.tSetUp._num_trustees, self.tSetUp._threshold, key, partial_public_keys) finger = pkey.get_fingerprint() # The generated fingerprint must be an alphanumeric # becouse is hexadecimal self.assertTrue(finger.isalnum()) # Get a partial public key for some trustee k k = 3 ppk = pkey.get_partial_public_key(k) # The returned partial public key for k must be the same we generate self.assertEquals(ppk, partial_public_keys[k]) def test_save_load_file(self): """ Test that we can correctly save a ThresholdPublicKey to a file and load it back. """ # Get a new threshold public key object key = self.tSetUp.generate_public_key() # Get its fingerprint for comparison after deserialization original_fingerprint = key.get_fingerprint() # Get a temporary file object using tempfile (file_object, file_path) = tempfile.mkstemp() # We close the file descriptor since we will not be using it, instead # PublicKey's methods take the filename and open/close the file as # needed. # Note that using mkstemp() instead tempfile.TemporaryFile means the # file remains in the filesystem even after it is closed. os.close(file_object) # Save the key using to_file(...) key.to_file(file_path) # Load it back using PublicKey.from_file(...) recovered_key = ThresholdPublicKey.from_file(file_path) # Get the fingerprint of the recovered key recovered_fingerprint = recovered_key.get_fingerprint() # Check that the fingerprints match (and thus they're the same key) self.assertEqual(recovered_fingerprint, original_fingerprint) # Delete the temporary file os.remove(file_path) def test_load_invalid_file(self): """ Test that loading a threshold public key from a file in an invalid format raises an appropriate exception. """ # Construct the path to the directory where our invalid test files are # located: invalid_files_dir = os.path.join(os.path.dirname(__file__), "TestThresholdPublicKey.resources", "invalid_tpublickey_xml_files") # Add invalid private key files as needed for file_name in ["err_missing_pub_key_elem.pvpubkey", "err_single_public_key.pvpubkey", "err_not_number_prime_elem.pvpubkey", "err_pub_key_too_large.pvpubkey", "err_par_pub_key_too_large.pvpubkey"]: inv_file = os.path.join(invalid_files_dir, file_name) self.assertRaises(InvalidPloneVoteCryptoFileError, ThresholdPublicKey.from_file, inv_file)
def test_partial_decryption(self): """ Create a ciphertext with the threshold public key and decrypt it and create others ciphertext to prove IncompatibleCiphertextError """ tprk = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) text_to_encrypt_dir = os.path.join(os.path.dirname(__file__), "TestThresholdPrivateKey.resources") text_to_encrypt = os.path.join(text_to_encrypt_dir, "text_to_encrypt") text_encrypted = self.tpkey.encrypt_text(text_to_encrypt) # Decrypt the file created with our public key must be fine tprk.generate_partial_decryption(text_encrypted) # Create another ThresholdEcryptuonSetUp with other 1024 bits # cryptosys to create a cypthertext that cant be decrypted second_cryptosys_file = os.path.join(os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test1024bits_second.pvcryptosys") # Load the cryptosystem from file second_cryptosys = EGCryptoSystem.from_file(second_cryptosys_file) secondtSetUp = ThresholdEncryptionSetUp(second_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): secondtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) secondcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): secondcommitments.append(secondtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): secondtSetUp.add_trustee_commitment(i, secondcommitments[i]) # Generate secon cryptosis publickey secondtpkey = secondtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey secondtext_encrypted = secondtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, secondtext_encrypted) # Create another ThresholdEcryptuonSetUp with other 512 bits # cryptosys to create a cypthertext that cant be decrypted third_cryptosys_file = os.path.join(os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test512bits.pvcryptosys") # Load the cryptosystem from file third_cryptosys = EGCryptoSystem.from_file(third_cryptosys_file) thirdtSetUp = ThresholdEncryptionSetUp(third_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): thirdtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) thirdcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): thirdcommitments.append(thirdtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): thirdtSetUp.add_trustee_commitment(i, thirdcommitments[i]) # Generate secon cryptosis publickey thirdtpkey = thirdtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey thirdtext_encrypted = thirdtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, thirdtext_encrypted)
class TestThresholdPrivateKey(unittest.TestCase): """ Test the class: plonevotecryptolib.Threshold.ThresholdPublicKey. ThresholdPublicKey """ def setUp(self): """ Unit test setup method. """ self.num_trustees = 5 self.threshold = 3 self.trustees = [] self.commitments = [] for i in range(self.num_trustees): self.trustees.append(Trustee()) # Generate a new instance of ThresholdEncryptionSetUp to be used # for generate publickeys cryptosystem = get_cryptosystem() self.tSetUp = ThresholdEncryptionSetUp(cryptosystem, self.num_trustees, self.threshold) # Adding the keys from trustees for i in range(self.num_trustees): self.tSetUp.add_trustee_public_key(i, self.trustees[i].public_key) # Generate commitmes for trustees for i in range(self.num_trustees): self.commitments.append(self.tSetUp.generate_commitment()) # Adding the trustees commitments for i in range(self.num_trustees): self.tSetUp.add_trustee_commitment(i, self.commitments[i]) self.tpkey = self.tSetUp.generate_public_key() def test_privatekey_generation(self): """ Create a new ThresholdPrivateKey, verify that is created correctly """ privatekey = ThresholdPrivateKey(self.tSetUp.cryptosystem, self.num_trustees, self.threshold, self.tpkey, self.trustees[0].private_key) # The values of the parameters must be the same we expect self.assertEquals(privatekey.cryptosystem, self.tSetUp.cryptosystem) self.assertEquals(privatekey.num_trustees, self.num_trustees) self.assertEquals(privatekey.threshold, self.threshold) self.assertEquals(privatekey.public_key, self.tpkey) self.assertEquals(privatekey._key, self.trustees[0].private_key) def test_partial_decryption(self): """ Create a ciphertext with the threshold public key and decrypt it and create others ciphertext to prove IncompatibleCiphertextError """ tprk = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) text_to_encrypt_dir = os.path.join(os.path.dirname(__file__), "TestThresholdPrivateKey.resources") text_to_encrypt = os.path.join(text_to_encrypt_dir, "text_to_encrypt") text_encrypted = self.tpkey.encrypt_text(text_to_encrypt) # Decrypt the file created with our public key must be fine tprk.generate_partial_decryption(text_encrypted) # Create another ThresholdEcryptuonSetUp with other 1024 bits # cryptosys to create a cypthertext that cant be decrypted second_cryptosys_file = os.path.join(os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test1024bits_second.pvcryptosys") # Load the cryptosystem from file second_cryptosys = EGCryptoSystem.from_file(second_cryptosys_file) secondtSetUp = ThresholdEncryptionSetUp(second_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): secondtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) secondcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): secondcommitments.append(secondtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): secondtSetUp.add_trustee_commitment(i, secondcommitments[i]) # Generate secon cryptosis publickey secondtpkey = secondtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey secondtext_encrypted = secondtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, secondtext_encrypted) # Create another ThresholdEcryptuonSetUp with other 512 bits # cryptosys to create a cypthertext that cant be decrypted third_cryptosys_file = os.path.join(os.path.dirname(__file__), "TestThresholdEncryptionSetUp.resources", "test512bits.pvcryptosys") # Load the cryptosystem from file third_cryptosys = EGCryptoSystem.from_file(third_cryptosys_file) thirdtSetUp = ThresholdEncryptionSetUp(third_cryptosys, self.num_trustees, self.threshold) # Adding the keys from trustees for 2ndsetUp for i in range(self.num_trustees): thirdtSetUp.add_trustee_public_key(i, self.trustees[i].public_key) thirdcommitments = [] # Generate commitmes for trustees for 2ndsetUp for i in range(self.num_trustees): thirdcommitments.append(thirdtSetUp.generate_commitment()) # Adding the secont trustees commitments for i in range(self.num_trustees): thirdtSetUp.add_trustee_commitment(i, thirdcommitments[i]) # Generate secon cryptosis publickey thirdtpkey = thirdtSetUp.generate_public_key() # Encrypt the file with the secon cryptosis publickey thirdtext_encrypted = thirdtpkey.encrypt_text(text_to_encrypt) # Try to decryp something created with other ThresholdEcryptuonSetUp # must raise IncompatibleCiphertextError self.assertRaises(IncompatibleCiphertextError, tprk.generate_partial_decryption, thirdtext_encrypted) def test_partial_decryption_w_task_monitor(self): """ Test that partial decryption can be monitored using a TaskMonitor object. """ # Get a new task monitor and a counter task_monitor = TaskMonitor() partialDecryptionCounter = Counter() # Register a task monitor callback to increment the counter once # for each 5% progress of partial decryption def partial_decryption_callback(tm): partialDecryptionCounter.increment() task_monitor.add_on_progress_percent_callback( partial_decryption_callback, percent_span = 5.0) # Generate a partial decryption passing the task_monitor object tprk = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) text_to_encrypt_dir = os.path.join(os.path.dirname(__file__), "TestThresholdPrivateKey.resources") text_to_encrypt = os.path.join(text_to_encrypt_dir, "text_to_encrypt") text_encrypted = self.tpkey.encrypt_text(text_to_encrypt) tprk.generate_partial_decryption(text_encrypted, task_monitor) # Check that the counter has been incremented 100/5 = 20 times self.assertEqual(partialDecryptionCounter.value, 20) def test_save_load_file(self): """ Test that we can correctly save a ThresholdPrivateKey to a file and load it back. """ # Get a new threshold private key object pkey = self.tSetUp.generate_private_key(0, self.trustees[0].private_key) # Get a temporary file object using tempfile (file_object, file_path) = tempfile.mkstemp() # We close the file descriptor since we will not be using it, instead # PublicKey's methods take the filename and open/close the file as # needed. # Note that using mkstemp() instead tempfile.TemporaryFile means the # file remains in the filesystem even after it is closed. os.close(file_object) # Save the key using to_file(...) pkey.to_file(file_path) # Load it back using ThresholdPrivateKey.from_file(...) recovered_key = ThresholdPrivateKey.from_file(file_path) # Check that parameters and keys match (and thus they're the same key) self.assertEqual(pkey.cryptosystem, recovered_key.cryptosystem) self.assertEqual(pkey.num_trustees, recovered_key.num_trustees) self.assertEqual(pkey.threshold, recovered_key.threshold) self.assertEqual(pkey.public_key.get_fingerprint(), recovered_key.public_key.get_fingerprint()) self.assertEqual(pkey._key, recovered_key._key) # Delete the temporary file os.remove(file_path) def test_load_invalid_file(self): """ Test that loading a threshold private key from a file in an invalid format raises an appropriate exception. """ # Construct the path to the directory where our invalid test files are # located: invalid_files_dir = os.path.join(os.path.dirname(__file__), "TestThresholdPrivateKey.resources", "invalid_tprivatekey_xml_files") # Add invalid private key files as needed for file_name in ["err_missing_pub_key_elem.pvpubkey", "err_not_valid_number_elem.pvpubkey", "err_prv_key_too_large.pvpubkey", "err_pub_key_too_large.pvpubkey", "err_par_pub_key_too_large.pvpubkey"]: inv_file = os.path.join(invalid_files_dir, file_name) self.assertRaises(InvalidPloneVoteCryptoFileError, ThresholdPrivateKey.from_file, inv_file)