예제 #1
0
 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)
예제 #2
0
    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)
예제 #3
0
    def test_cryptosystem_new_with_task_monitor(self):
        """
        Test that EGCryptoSystem.new(...) correctly reports progress using 
        task monitor.
        """
        # Get new counter and logger objects
        counter = Counter()
        logger = Logger()

        # Create a task monitor
        task_monitor = TaskMonitor()

        # Register callbacks for:

        # 1) logging subtask creation,
        def task_start_cb(tm):
            tm_p = tm.parent
            msg = "New task started: \"%s\" " \
                  "(Subtask #%d of %d for task \"%s\")\n" % \
                  (tm.task_name, tm_p.current_subtask_num, \
                   tm_p.num_subtasks, tm_p.task_name)
            logger.log(msg)

        task_monitor.add_on_task_start_callback(task_start_cb)

        # 2) logging subtask completion,
        def task_end_cb(tm):
            msg = "Task completed: \"%s\"\n" % tm.task_name
            logger.log(msg)

        task_monitor.add_on_task_end_callback(task_end_cb)

        # 3) counting the number of ticks of progress
        task_monitor.add_on_tick_callback(lambda tm: counter.increment(),
                                          num_ticks=1)

        # Note:
        # EGCryptoSystem.new(...) does not provide progress percent monitoring

        # We call EGCryptoSystem.new(...) with our task monitor object
        # We use the *insecure* size of 256bits for performance reasons
        EGCryptoSystem.new(nbits=256, task_monitor=task_monitor)

        # Check that the logged match the expected output of our callbacks:
        expected_log = \
"""New task started: \"Generate safe prime\" (Subtask #1 of 1 for task \"Root\")
Task completed: \"Generate safe prime\"
New task started: \"Obtain a generator for the cyclic group\" (Subtask #2 of 2 for task \"Root\")
Task completed: \"Obtain a generator for the cyclic group\"
"""
        self.assertEqual(str(logger), expected_log)

        # Also, each of the two subtask produces a progress tick before testing
        # each safe prime or generator candidate (respectively). So counter
        # must have registered at least two ticks (likely more)
        self.assertTrue(counter.value >= 2)
예제 #4
0
    def test_cryptosystem_new_with_task_monitor(self):
        """
        Test that EGCryptoSystem.new(...) correctly reports progress using 
        task monitor.
        """
        # Get new counter and logger objects
        counter = Counter()
        logger = Logger()
        
        # Create a task monitor
        task_monitor = TaskMonitor()
        
        # Register callbacks for:
        
        # 1) logging subtask creation,
        def task_start_cb(tm):
            tm_p = tm.parent
            msg = "New task started: \"%s\" " \
                  "(Subtask #%d of %d for task \"%s\")\n" % \
                  (tm.task_name, tm_p.current_subtask_num, \
                   tm_p.num_subtasks, tm_p.task_name)
            logger.log(msg)
           
        task_monitor.add_on_task_start_callback(task_start_cb)
        
        # 2) logging subtask completion,
        def task_end_cb(tm):
            msg = "Task completed: \"%s\"\n" % tm.task_name
            logger.log(msg)
           
        task_monitor.add_on_task_end_callback(task_end_cb)
        
        # 3) counting the number of ticks of progress
        task_monitor.add_on_tick_callback(lambda tm: counter.increment(), 
                                               num_ticks = 1)
        
        # Note:
        # EGCryptoSystem.new(...) does not provide progress percent monitoring 
        
        # We call EGCryptoSystem.new(...) with our task monitor object 
        # We use the *insecure* size of 256bits for performance reasons
        EGCryptoSystem.new(nbits=256, task_monitor=task_monitor)
        
        # Check that the logged match the expected output of our callbacks:
        expected_log = \
"""New task started: \"Generate safe prime\" (Subtask #1 of 1 for task \"Root\")
Task completed: \"Generate safe prime\"
New task started: \"Obtain a generator for the cyclic group\" (Subtask #2 of 2 for task \"Root\")
Task completed: \"Obtain a generator for the cyclic group\"
"""
        self.assertEqual(str(logger),expected_log)
        
        # Also, each of the two subtask produces a progress tick before testing 
        # each safe prime or generator candidate (respectively). So counter 
        # must have registered at least two ticks (likely more)
        self.assertTrue(counter.value >= 2)
예제 #5
0
 def test_encryption_decryption_w_task_monitor(self):
     """
     Test that encryption and decryption can be monitored using a 
     TaskMonitor object.
     """
     # Get a new task monitor and two counters, one for encryption and one 
     # for decryption
     task_monitor = TaskMonitor()
     encryptionCounter = Counter()
     decryptionCounter = Counter()
     
     # Register a task monitor callback to increment encryptionCounter once 
     # for each 5% progress of encryption
     def encryption_callback(tm):
         encryptionCounter.increment()
     
     task_monitor.add_on_progress_percent_callback(encryption_callback, 
                                                   percent_span = 5.0)
     
     # Encrypt the test message, passing the task monitor
     ciphertext = self.public_key.encrypt_text(self.message, 
                                               task_monitor=task_monitor)
     
     # Unregister the encryption callback from the monitor and register 
     # a callback to increment decryptionCounter once for each 5% progress 
     # of decryption.
     task_monitor.remove_callback(encryption_callback)
     
     def decryption_callback(tm):
         decryptionCounter.increment()
     
     task_monitor.add_on_progress_percent_callback(decryption_callback, 
                                                   percent_span = 5.0)
     
     # Decrypt the message, passing the task monitor:
     self.private_key.decrypt_to_text(ciphertext, task_monitor=task_monitor)
     
     # Check that both counters have been incremented 100/5 = 20 times
     self.assertEqual(encryptionCounter.value, 20)
     self.assertEqual(decryptionCounter.value, 20)
예제 #6
0
def run_tool(nbits, filename, name, description):
    """
	Runs the plonevote.gen_cryptosys tool and generates a new cryptosystem.
	"""

    # Define callbacks for the TaskMonitor for progress monitoring
    def cb_task_start(task):
        print task.task_name + ":"

    def cb_task_progress(task):
        sys.stdout.write(".")
        sys.stdout.flush()

    def cb_task_end(task):
        print ""

    # Create new TaskMonitor and register the callbacks
    taskmon = TaskMonitor()
    taskmon.add_on_task_start_callback(cb_task_start)
    taskmon.add_on_tick_callback(cb_task_progress)
    taskmon.add_on_task_end_callback(cb_task_end)

    # Generate a new cryptosystem of the requested size
    try:
        cryptosys = EGCryptoSystem.new(nbits, task_monitor=taskmon)
    except KeyLengthTooLowError:
        print "ERROR: The given bit size does not meet PloneVoteCryptoLib "\
           "minimum security requirements (too short)."
    except KeyLengthNonBytableError:
        print "ERROR: The given bit size must be a multiple of 8."

    # Save the cryptosystem to file
    print "\nSaving cryptosystem to %s..." % filename,

    cryptosys.to_file(name, description, filename)

    print "SAVED.\n"
예제 #7
0
def run_tool(nbits, filename, name, description):
	"""
	Runs the plonevote.gen_cryptosys tool and generates a new cryptosystem.
	"""
	# Define callbacks for the TaskMonitor for progress monitoring
	def cb_task_start(task):
		print task.task_name + ":"

	def cb_task_progress(task):
		sys.stdout.write(".")
		sys.stdout.flush()

	def cb_task_end(task):
		print ""
	
	# Create new TaskMonitor and register the callbacks
	taskmon = TaskMonitor()
	taskmon.add_on_task_start_callback(cb_task_start)
	taskmon.add_on_tick_callback(cb_task_progress)
	taskmon.add_on_task_end_callback(cb_task_end)
	
	# Generate a new cryptosystem of the requested size
	try:
		cryptosys = EGCryptoSystem.new(nbits, task_monitor = taskmon)
	except KeyLengthTooLowError:
		print "ERROR: The given bit size does not meet PloneVoteCryptoLib "\
			  "minimum security requirements (too short)."
	except KeyLengthNonBytableError:
		print "ERROR: The given bit size must be a multiple of 8."
	
	# Save the cryptosystem to file
	print "\nSaving cryptosystem to %s..." % filename,
	
	cryptosys.to_file(name, description, filename)
	
	print "SAVED.\n"
예제 #8
0
	# Define callbacks for the TaskMonitor for monitoring the decryption process
	if(len(in_file) <= 50):
		short_in_filename = in_file
	else:
		short_in_filename = os.path.split(in_file)[-1]
		if(len(short_in_filename) > 50):
			# Do ellipsis shortening
			short_in_filename = short_in_filename[0,20] + "..." + \
								short_in_filename[-20,-1]
	
	def cb_task_percent_progress(task):
		print "  %.2f%% of %s decrypted..." % \
				(task.get_percent_completed(), short_in_filename)
	
	# Create new TaskMonitor and register the callbacks
	taskmon = TaskMonitor()
	taskmon.add_on_progress_percent_callback(cb_task_percent_progress, \
											 percent_span = 5)
	
	# Decrypt to bitstream
	print "Decrypting..."	
	try:
		bitstream = private_key.decrypt_to_bitstream(ciphertext, task_monitor = taskmon)
	except IncompatibleCiphertextError, e:
		print "Incompatible private key and ciphertext error: %s" % s.msg
	
	# Save the resulting plaintext to the output file
	print "Writing decrypted data..."
	try:
		out_f = open(out_file, 'wb')
	except Exception, e:
예제 #9
0
    # Define callbacks for the TaskMonitor for monitoring the encryption process
    if (len(in_file) <= 50):
        short_in_filename = in_file
    else:
        short_in_filename = os.path.split(in_file)[-1]
        if (len(short_in_filename) > 50):
            # Do ellipsis shortening
            short_in_filename = short_in_filename[0,20] + "..." + \
                 short_in_filename[-20,-1]

    def cb_task_percent_progress(task):
        print "  %.2f%% of %s encrypted..." % \
          (task.get_percent_completed(), short_in_filename)

    # Create new TaskMonitor and register the callbacks
    taskmon = TaskMonitor()
    taskmon.add_on_progress_percent_callback(cb_task_percent_progress, \
               percent_span = 5)

    # Encrypt bitstream
    print "Encrypting..."
    ciphertext = public_key.encrypt_bitstream(bitstream, task_monitor=taskmon)

    # Save the ciphertext to the output file
    try:
        ciphertext.to_file(out_file)
    except Exception, e:
        print "Problem while saving the output file %s: %s" % (in_file, e.msg)


def main():
예제 #10
0
 def setUp(self):
     """
     Unit test setup method.
     """
     self.task_monitor = TaskMonitor()
예제 #11
0
class TestTaskMonitor(unittest.TestCase):
    """
    Test the class: plonevotecryptolib.utilities.TaskMonitor.TaskMonitor
    """
    
    def setUp(self):
        """
        Unit test setup method.
        """
        self.task_monitor = TaskMonitor()
    
    def test_report_ticks(self):
        """
        Test that TaskMonitor can be used to report the number of steps (ticks) 
        performed by a "TaskMonitor-enabled" function.
        """
        # We register a callback that increments a counter by one and is 
        # called every 10 ticks
        counter = Counter()
        self.task_monitor.add_on_tick_callback(lambda tm: counter.increment(), 
                                               num_ticks = 10)
        
        # Now, we call the tme_fibonacci function with our task monitor, asking 
        # for the 100th Fibonacci number
        tme_fibonacci(100, self.task_monitor)
        
        # The counter should have been updated once for every 10 numbers in the 
        # sequence from 0 to our desired number, inclusive. So counter should 
        # be 100/10 = 10.
        self.assertEqual(counter.value, 10)
          
    def test_report_percent(self):
        """
        Test that TaskMonitor can be used to report the completion percentage 
        of a "TaskMonitor-enabled" function that allows percentage monitoring.
        """
        # We register a callback that increments a counter by one and is 
        # called every 5% progress
        counter = Counter()
        self.task_monitor.add_on_progress_percent_callback( \
                            lambda tm: counter.increment(), 
                            percent_span = 5.0)
        
        # Now, we call the tme_fibonacci function with our task monitor, asking 
        # for the 100th Fibonacci number
        tme_fibonacci(100, self.task_monitor)
        
        # The counter should have been updated once for every 5% advance in the 
        # called function. This gives us 20 updates.
        self.assertEqual(counter.value, 20)
        
    def test_task_without_percent_reporting(self):
        """
        Test how add_on_tick_callback(...) *and* 
        add_on_progress_percent_callback(...) work when the task does not 
        provide progress percent reporting (ie. a variable length task).
        """
        # We register a callback that increments a counter by one and is 
        # called every 10 ticks
        counter1 = Counter()
        self.task_monitor.add_on_tick_callback(lambda tm: counter1.increment(), 
                                               num_ticks = 10)
        
        # We register a callback that increments a counter by one and is 
        # called every 5% progress
        counter2 = Counter()
        self.task_monitor.add_on_progress_percent_callback( \
                            lambda tm: counter2.increment(), 
                            percent_span = 5.0)
        
        # Now, we call the tme_search_in_list function with our task monitor, 
        # asking for the position of element 100 in range(0,300)
        tme_search_in_list(range(0,300), 100, self.task_monitor)
        
        # counter1 should have been update 10 times, one for each 10 ticks of 
        # a total of 100 ticks (100 is the 100th element of range(0,300))
        self.assertEqual(counter1.value, 10)
        
        # counter2 should have never been updated, since tme_search_in_list 
        # does not provide progress percent monitoring
        self.assertEqual(counter2.value, 0)
        
    def test_subtask_reporting(self):
        """
        Test complex reporting on a task with subtasks.
        This includes:
            * Test task start/end callbacks.
            * Test getting the name and number of each subtask.
            * Test reporting percent progress of the whole task and each 
              subtask.
        """
        # Construct a logger object
        logger = Logger()
        
        # Set up callbacks to log messages on:
        
        # subtask creation,
        def task_start_cb(tm):
            tm_p = tm.parent
            msg = "New task started: \"%s\" " \
                  "(Subtask #%d of %d for task \"%s\")\n" % \
                  (tm.task_name, tm_p.current_subtask_num, \
                   tm_p.num_subtasks, tm_p.task_name)
            logger.log(msg)
           
        self.task_monitor.add_on_task_start_callback(task_start_cb)
        
        # subtask completion,
        def task_end_cb(tm):
            msg = "Task completed: \"%s\"\n" % tm.task_name
            logger.log(msg)
           
        self.task_monitor.add_on_task_end_callback(task_end_cb)
        
        # and progress percent (20%)
        def task_percent_cb(tm):
            msg = "\"%s\"... %d%% completed.\n" % \
                  (tm.task_name, tm.get_percent_completed())
            logger.log(msg)
           
        self.task_monitor.add_on_progress_percent_callback(task_percent_cb)
        
        # We also count the total number of ticks
        counter = Counter()
        self.task_monitor.add_on_tick_callback(lambda tm: counter.increment(), 
                                               num_ticks = 1)
        
        # Call tme_fibonacci_subtasks using the task monitor
        tme_fibonacci_subtasks(self.task_monitor)
        
        # and compare the logged output with the expected one
        expected_output = \
"""New task started: \"Multiple Fibonacci Tasks\" (Subtask #1 of 1 for task \"Root\")
New task started: \"Fibonacci(300)\" (Subtask #1 of 3 for task \"Multiple Fibonacci Tasks\")
New task started: \"Calculating the 300th Fibonacci number\" (Subtask #1 of 1 for task \"Fibonacci(300)\")
\"Calculating the 300th Fibonacci number\"... 5% completed.
\"Calculating the 300th Fibonacci number\"... 10% completed.
\"Calculating the 300th Fibonacci number\"... 15% completed.
\"Calculating the 300th Fibonacci number\"... 20% completed.
\"Calculating the 300th Fibonacci number\"... 25% completed.
\"Calculating the 300th Fibonacci number\"... 30% completed.
\"Calculating the 300th Fibonacci number\"... 35% completed.
\"Calculating the 300th Fibonacci number\"... 40% completed.
\"Calculating the 300th Fibonacci number\"... 45% completed.
\"Calculating the 300th Fibonacci number\"... 50% completed.
\"Calculating the 300th Fibonacci number\"... 55% completed.
\"Calculating the 300th Fibonacci number\"... 60% completed.
\"Calculating the 300th Fibonacci number\"... 65% completed.
\"Calculating the 300th Fibonacci number\"... 70% completed.
\"Calculating the 300th Fibonacci number\"... 75% completed.
\"Calculating the 300th Fibonacci number\"... 80% completed.
\"Calculating the 300th Fibonacci number\"... 85% completed.
\"Calculating the 300th Fibonacci number\"... 90% completed.
\"Calculating the 300th Fibonacci number\"... 95% completed.
\"Calculating the 300th Fibonacci number\"... 100% completed.
Task completed: \"Calculating the 300th Fibonacci number\"
Task completed: \"Fibonacci(300)\"
New task started: \"Fibonacci(500)\" (Subtask #2 of 3 for task \"Multiple Fibonacci Tasks\")
New task started: \"Calculating the 500th Fibonacci number\" (Subtask #1 of 1 for task \"Fibonacci(500)\")
\"Calculating the 500th Fibonacci number\"... 5% completed.
\"Calculating the 500th Fibonacci number\"... 10% completed.
\"Calculating the 500th Fibonacci number\"... 15% completed.
\"Calculating the 500th Fibonacci number\"... 20% completed.
\"Calculating the 500th Fibonacci number\"... 25% completed.
\"Calculating the 500th Fibonacci number\"... 30% completed.
\"Calculating the 500th Fibonacci number\"... 35% completed.
\"Calculating the 500th Fibonacci number\"... 40% completed.
\"Calculating the 500th Fibonacci number\"... 45% completed.
\"Calculating the 500th Fibonacci number\"... 50% completed.
\"Calculating the 500th Fibonacci number\"... 55% completed.
\"Calculating the 500th Fibonacci number\"... 60% completed.
\"Calculating the 500th Fibonacci number\"... 65% completed.
\"Calculating the 500th Fibonacci number\"... 70% completed.
\"Calculating the 500th Fibonacci number\"... 75% completed.
\"Calculating the 500th Fibonacci number\"... 80% completed.
\"Calculating the 500th Fibonacci number\"... 85% completed.
\"Calculating the 500th Fibonacci number\"... 90% completed.
\"Calculating the 500th Fibonacci number\"... 95% completed.
\"Calculating the 500th Fibonacci number\"... 100% completed.
Task completed: \"Calculating the 500th Fibonacci number\"
Task completed: \"Fibonacci(500)\"
New task started: \"Fibonacci(200)\" (Subtask #3 of 3 for task \"Multiple Fibonacci Tasks\")
New task started: \"Calculating the 200th Fibonacci number\" (Subtask #1 of 1 for task \"Fibonacci(200)\")
\"Calculating the 200th Fibonacci number\"... 5% completed.
\"Calculating the 200th Fibonacci number\"... 10% completed.
\"Calculating the 200th Fibonacci number\"... 15% completed.
\"Calculating the 200th Fibonacci number\"... 20% completed.
\"Calculating the 200th Fibonacci number\"... 25% completed.
\"Calculating the 200th Fibonacci number\"... 30% completed.
\"Calculating the 200th Fibonacci number\"... 35% completed.
\"Calculating the 200th Fibonacci number\"... 40% completed.
\"Calculating the 200th Fibonacci number\"... 45% completed.
\"Calculating the 200th Fibonacci number\"... 50% completed.
\"Calculating the 200th Fibonacci number\"... 55% completed.
\"Calculating the 200th Fibonacci number\"... 60% completed.
\"Calculating the 200th Fibonacci number\"... 65% completed.
\"Calculating the 200th Fibonacci number\"... 70% completed.
\"Calculating the 200th Fibonacci number\"... 75% completed.
\"Calculating the 200th Fibonacci number\"... 80% completed.
\"Calculating the 200th Fibonacci number\"... 85% completed.
\"Calculating the 200th Fibonacci number\"... 90% completed.
\"Calculating the 200th Fibonacci number\"... 95% completed.
\"Calculating the 200th Fibonacci number\"... 100% completed.
Task completed: \"Calculating the 200th Fibonacci number\"
Task completed: \"Fibonacci(200)\"
Task completed: \"Multiple Fibonacci Tasks\"
"""

        self.assertEqual(str(logger), expected_output)
        
        # Including ticks for the 0th number in each succession..
        self.assertEqual(counter.value, 1003)

    def test_remove_callback(self):
        """
        Test the remove_callback method of TaskMonitor.
        """
        # We will run a new Task Monitor to monitor the tme_fibonacci_subtasks 
        # function.
        
        # First, we define a callback to count all ticks for our task
        counter = Counter()
        def tick_counter_cb(tm):
            counter.increment()
         
        self.task_monitor.add_on_tick_callback(tick_counter_cb, 
                                               num_ticks = 1)
                                               
        # Then, we define a callback to be called whenever a subtask starts
        # This callback will remove our previous "tick counter" callback as 
        # soon as the task named "Fibonacci(500)" starts.
        def task_start_cb(tm):
            if(tm.task_name == "Fibonacci(500)"):
                tm.remove_callback(tick_counter_cb)
           
        self.task_monitor.add_on_task_start_callback(task_start_cb)
        
        # Note that since remove_callback removes the callback solely for the 
        # task for which it was called and its subtasks, our tick counter 
        # callback will still be called for the "Fibonacci(200)" subtask of 
        # tme_fibonacci_subtasks.
        
        # Lets run tme_fibonacci_subtasks:
        tme_fibonacci_subtasks(self.task_monitor)
        
        # Check that the counter has registered 301 ticks for Fibonacci(300) 
        # (and subtasks) and 201 for Fibonacci(200) (and subtasks), but no 
        # ticks for Fibonacci(500):
        self.assertEqual(counter.value, 502)
예제 #12
0
def run_tool(key_file, in_file, out_file):
    """
	Runs the plonevote.encrypt tool and encrypts in_file into out_file.
	"""
    # Load the public key
    print("Loading public key...")
    try:
        public_key = PublicKey.from_file(key_file)
    except InvalidPloneVoteCryptoFileError as e:
        print("Invalid public key file (%s): %s" % (key_file, e.msg))
        sys.exit(2)

    # Open the input file
    print("Reading input file...")
    try:
        in_f = open(in_file, 'rb')
    except Exception as e:
        print("Problem while opening input file %s: %s" % (in_file, e))

    # Read the whole file into a bitstream
    bitstream = BitStream()
    try:
        read_quantum = 1024  # KB at a time
        bytes = in_f.read(read_quantum)
        while (bytes):
            for byte in bytes:
                bitstream.put_byte(ord(byte))
            bytes = in_f.read(read_quantum)
    except Exception as e:
        print("Problem while reading from input file %s: %s" % (in_file, e))

    in_f.close()

    # Define callbacks for the TaskMonitor for monitoring the encryption process
    if (len(in_file) <= 50):
        short_in_filename = in_file
    else:
        short_in_filename = os.path.split(in_file)[-1]
        if (len(short_in_filename) > 50):
            # Do ellipsis shortening
            short_in_filename = short_in_filename[0,20] + "..." + \
                 short_in_filename[-20,-1]

    def cb_task_percent_progress(task):
        print("  %.2f%% of %s encrypted..." % \
          (task.get_percent_completed(), short_in_filename))

    # Create new TaskMonitor and register the callbacks
    taskmon = TaskMonitor()
    taskmon.add_on_progress_percent_callback(cb_task_percent_progress, \
               percent_span = 5)

    # Encrypt bitstream
    print("Encrypting...")
    ciphertext = public_key.encrypt_bitstream(bitstream, task_monitor=taskmon)

    # Save the ciphertext to the output file
    try:
        ciphertext.to_file(out_file)
    except Exception as e:
        print("Problem while saving the output file %s: %s" % (in_file, e.msg))
예제 #13
0
 def setUp(self):
     """
     Unit test setup method.
     """
     self.task_monitor = TaskMonitor()
예제 #14
0
class TestTaskMonitor(unittest.TestCase):
    """
    Test the class: plonevotecryptolib.utilities.TaskMonitor.TaskMonitor
    """
    def setUp(self):
        """
        Unit test setup method.
        """
        self.task_monitor = TaskMonitor()

    def test_report_ticks(self):
        """
        Test that TaskMonitor can be used to report the number of steps (ticks) 
        performed by a "TaskMonitor-enabled" function.
        """
        # We register a callback that increments a counter by one and is
        # called every 10 ticks
        counter = Counter()
        self.task_monitor.add_on_tick_callback(lambda tm: counter.increment(),
                                               num_ticks=10)

        # Now, we call the tme_fibonacci function with our task monitor, asking
        # for the 100th Fibonacci number
        tme_fibonacci(100, self.task_monitor)

        # The counter should have been updated once for every 10 numbers in the
        # sequence from 0 to our desired number, inclusive. So counter should
        # be 100/10 = 10.
        self.assertEqual(counter.value, 10)

    def test_report_percent(self):
        """
        Test that TaskMonitor can be used to report the completion percentage 
        of a "TaskMonitor-enabled" function that allows percentage monitoring.
        """
        # We register a callback that increments a counter by one and is
        # called every 5% progress
        counter = Counter()
        self.task_monitor.add_on_progress_percent_callback( \
                            lambda tm: counter.increment(),
                            percent_span = 5.0)

        # Now, we call the tme_fibonacci function with our task monitor, asking
        # for the 100th Fibonacci number
        tme_fibonacci(100, self.task_monitor)

        # The counter should have been updated once for every 5% advance in the
        # called function. This gives us 20 updates.
        self.assertEqual(counter.value, 20)

    def test_task_without_percent_reporting(self):
        """
        Test how add_on_tick_callback(...) *and* 
        add_on_progress_percent_callback(...) work when the task does not 
        provide progress percent reporting (ie. a variable length task).
        """
        # We register a callback that increments a counter by one and is
        # called every 10 ticks
        counter1 = Counter()
        self.task_monitor.add_on_tick_callback(lambda tm: counter1.increment(),
                                               num_ticks=10)

        # We register a callback that increments a counter by one and is
        # called every 5% progress
        counter2 = Counter()
        self.task_monitor.add_on_progress_percent_callback( \
                            lambda tm: counter2.increment(),
                            percent_span = 5.0)

        # Now, we call the tme_search_in_list function with our task monitor,
        # asking for the position of element 100 in range(0,300)
        tme_search_in_list(list(range(0, 300)), 100, self.task_monitor)

        # counter1 should have been update 10 times, one for each 10 ticks of
        # a total of 100 ticks (100 is the 100th element of range(0,300))
        self.assertEqual(counter1.value, 10)

        # counter2 should have never been updated, since tme_search_in_list
        # does not provide progress percent monitoring
        self.assertEqual(counter2.value, 0)

    def test_subtask_reporting(self):
        """
        Test complex reporting on a task with subtasks.
        This includes:
            * Test task start/end callbacks.
            * Test getting the name and number of each subtask.
            * Test reporting percent progress of the whole task and each 
              subtask.
        """
        # Construct a logger object
        logger = Logger()

        # Set up callbacks to log messages on:

        # subtask creation,
        def task_start_cb(tm):
            tm_p = tm.parent
            msg = "New task started: \"%s\" " \
                  "(Subtask #%d of %d for task \"%s\")\n" % \
                  (tm.task_name, tm_p.current_subtask_num, \
                   tm_p.num_subtasks, tm_p.task_name)
            logger.log(msg)

        self.task_monitor.add_on_task_start_callback(task_start_cb)

        # subtask completion,
        def task_end_cb(tm):
            msg = "Task completed: \"%s\"\n" % tm.task_name
            logger.log(msg)

        self.task_monitor.add_on_task_end_callback(task_end_cb)

        # and progress percent (20%)
        def task_percent_cb(tm):
            msg = "\"%s\"... %d%% completed.\n" % \
                  (tm.task_name, tm.get_percent_completed())
            logger.log(msg)

        self.task_monitor.add_on_progress_percent_callback(task_percent_cb)

        # We also count the total number of ticks
        counter = Counter()
        self.task_monitor.add_on_tick_callback(lambda tm: counter.increment(),
                                               num_ticks=1)

        # Call tme_fibonacci_subtasks using the task monitor
        tme_fibonacci_subtasks(self.task_monitor)

        # and compare the logged output with the expected one
        expected_output = \
"""New task started: \"Multiple Fibonacci Tasks\" (Subtask #1 of 1 for task \"Root\")
New task started: \"Fibonacci(300)\" (Subtask #1 of 3 for task \"Multiple Fibonacci Tasks\")
New task started: \"Calculating the 300th Fibonacci number\" (Subtask #1 of 1 for task \"Fibonacci(300)\")
\"Calculating the 300th Fibonacci number\"... 5% completed.
\"Calculating the 300th Fibonacci number\"... 10% completed.
\"Calculating the 300th Fibonacci number\"... 15% completed.
\"Calculating the 300th Fibonacci number\"... 20% completed.
\"Calculating the 300th Fibonacci number\"... 25% completed.
\"Calculating the 300th Fibonacci number\"... 30% completed.
\"Calculating the 300th Fibonacci number\"... 35% completed.
\"Calculating the 300th Fibonacci number\"... 40% completed.
\"Calculating the 300th Fibonacci number\"... 45% completed.
\"Calculating the 300th Fibonacci number\"... 50% completed.
\"Calculating the 300th Fibonacci number\"... 55% completed.
\"Calculating the 300th Fibonacci number\"... 60% completed.
\"Calculating the 300th Fibonacci number\"... 65% completed.
\"Calculating the 300th Fibonacci number\"... 70% completed.
\"Calculating the 300th Fibonacci number\"... 75% completed.
\"Calculating the 300th Fibonacci number\"... 80% completed.
\"Calculating the 300th Fibonacci number\"... 85% completed.
\"Calculating the 300th Fibonacci number\"... 90% completed.
\"Calculating the 300th Fibonacci number\"... 95% completed.
\"Calculating the 300th Fibonacci number\"... 100% completed.
Task completed: \"Calculating the 300th Fibonacci number\"
Task completed: \"Fibonacci(300)\"
New task started: \"Fibonacci(500)\" (Subtask #2 of 3 for task \"Multiple Fibonacci Tasks\")
New task started: \"Calculating the 500th Fibonacci number\" (Subtask #1 of 1 for task \"Fibonacci(500)\")
\"Calculating the 500th Fibonacci number\"... 5% completed.
\"Calculating the 500th Fibonacci number\"... 10% completed.
\"Calculating the 500th Fibonacci number\"... 15% completed.
\"Calculating the 500th Fibonacci number\"... 20% completed.
\"Calculating the 500th Fibonacci number\"... 25% completed.
\"Calculating the 500th Fibonacci number\"... 30% completed.
\"Calculating the 500th Fibonacci number\"... 35% completed.
\"Calculating the 500th Fibonacci number\"... 40% completed.
\"Calculating the 500th Fibonacci number\"... 45% completed.
\"Calculating the 500th Fibonacci number\"... 50% completed.
\"Calculating the 500th Fibonacci number\"... 55% completed.
\"Calculating the 500th Fibonacci number\"... 60% completed.
\"Calculating the 500th Fibonacci number\"... 65% completed.
\"Calculating the 500th Fibonacci number\"... 70% completed.
\"Calculating the 500th Fibonacci number\"... 75% completed.
\"Calculating the 500th Fibonacci number\"... 80% completed.
\"Calculating the 500th Fibonacci number\"... 85% completed.
\"Calculating the 500th Fibonacci number\"... 90% completed.
\"Calculating the 500th Fibonacci number\"... 95% completed.
\"Calculating the 500th Fibonacci number\"... 100% completed.
Task completed: \"Calculating the 500th Fibonacci number\"
Task completed: \"Fibonacci(500)\"
New task started: \"Fibonacci(200)\" (Subtask #3 of 3 for task \"Multiple Fibonacci Tasks\")
New task started: \"Calculating the 200th Fibonacci number\" (Subtask #1 of 1 for task \"Fibonacci(200)\")
\"Calculating the 200th Fibonacci number\"... 5% completed.
\"Calculating the 200th Fibonacci number\"... 10% completed.
\"Calculating the 200th Fibonacci number\"... 15% completed.
\"Calculating the 200th Fibonacci number\"... 20% completed.
\"Calculating the 200th Fibonacci number\"... 25% completed.
\"Calculating the 200th Fibonacci number\"... 30% completed.
\"Calculating the 200th Fibonacci number\"... 35% completed.
\"Calculating the 200th Fibonacci number\"... 40% completed.
\"Calculating the 200th Fibonacci number\"... 45% completed.
\"Calculating the 200th Fibonacci number\"... 50% completed.
\"Calculating the 200th Fibonacci number\"... 55% completed.
\"Calculating the 200th Fibonacci number\"... 60% completed.
\"Calculating the 200th Fibonacci number\"... 65% completed.
\"Calculating the 200th Fibonacci number\"... 70% completed.
\"Calculating the 200th Fibonacci number\"... 75% completed.
\"Calculating the 200th Fibonacci number\"... 80% completed.
\"Calculating the 200th Fibonacci number\"... 85% completed.
\"Calculating the 200th Fibonacci number\"... 90% completed.
\"Calculating the 200th Fibonacci number\"... 95% completed.
\"Calculating the 200th Fibonacci number\"... 100% completed.
Task completed: \"Calculating the 200th Fibonacci number\"
Task completed: \"Fibonacci(200)\"
Task completed: \"Multiple Fibonacci Tasks\"
"""

        self.assertEqual(str(logger), expected_output)

        # Including ticks for the 0th number in each succession..
        self.assertEqual(counter.value, 1003)

    def test_remove_callback(self):
        """
        Test the remove_callback method of TaskMonitor.
        """
        # We will run a new Task Monitor to monitor the tme_fibonacci_subtasks
        # function.

        # First, we define a callback to count all ticks for our task
        counter = Counter()

        def tick_counter_cb(tm):
            counter.increment()

        self.task_monitor.add_on_tick_callback(tick_counter_cb, num_ticks=1)

        # Then, we define a callback to be called whenever a subtask starts
        # This callback will remove our previous "tick counter" callback as
        # soon as the task named "Fibonacci(500)" starts.
        def task_start_cb(tm):
            if (tm.task_name == "Fibonacci(500)"):
                tm.remove_callback(tick_counter_cb)

        self.task_monitor.add_on_task_start_callback(task_start_cb)

        # Note that since remove_callback removes the callback solely for the
        # task for which it was called and its subtasks, our tick counter
        # callback will still be called for the "Fibonacci(200)" subtask of
        # tme_fibonacci_subtasks.

        # Lets run tme_fibonacci_subtasks:
        tme_fibonacci_subtasks(self.task_monitor)

        # Check that the counter has registered 301 ticks for Fibonacci(300)
        # (and subtasks) and 201 for Fibonacci(200) (and subtasks), but no
        # ticks for Fibonacci(500):
        self.assertEqual(counter.value, 502)