I'd like to know if there is an easy way (maybe a library) to write constant-time programs in Python. In particular, I'd like to be able to specify that an if-else flow must always last the same time either the if condition is True
or False
.
For instance:
if condition:
foo1()
else:
foo2()
foo3()
The idea of constant-time is that in the execution, the time that takes until it hits f3()
should take the same time independently of the result of the evaluation of condition
. This would prevent leakage of time as a side-channel to reveal other information (cf. timing attacks).
An algorithm is said to be constant time (also written as time) if the value of is bounded by a value that does not depend on the size of the input. For example, accessing any single element in an array takes constant time as only one operation has to be performed to locate it.
Here, you can use List comprehension technique to create the factor list, due to the fact that List comprehension is faster than looping statements. Also, you can just iterate till square root of the Number, instead of looping till number itself, thereby reducing time complexity exponentially.
In order to calculate the time elapsed in executing a code, the time module can be used. Save the timestamp at the beginning of the code start using time() . Save the timestamp at the end of the code end . Find the difference between the end and start, which gives the execution time.
Since your question is about security, I assume we can leave aside performance and very naively introduce a minimal time to spend on all possible branches.One way to achieve this is with context managers:
Your problem could be then written as:
with ConstantTime(0.1):
if condition:
foo1()
else:
foor2()
foo3()
Using a context manager defined like this:
import threading
import time
class ConstantTime():
def __init__(self, length):
self.length = length
def __enter__(self):
self.timer = threading.Thread(target=time.sleep, args=[self.length])
self.timer.start()
def __exit__(self, exc_type, exc_value, traceback):
self.timer.join()
You would of course have to adjust the actual time to realistic values, depending on what you are doing.
In general you can't be sure your minimal time won't be exceeded by the chosen branch, since Python is a very high level language and you're probably not running it in a real-time OS, but if you manage to cover the average runtime, you should significantly reduce the information gathered from timing analysis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With