The fundamental problem that I wanted to solve is “how can I lock myself out of websites and programs without permanently locking myself out”. For example, there are neat apps that can monitor my YouTube consumption and close the app when I exceed my budget. Unfortunately, the purpose of these apps can be simply defeated by uninstalling them.
I use "Lock Me Out" on my Android phone, and they provide a feature to password lock the app while blocking is active. That prevents me from uninstalling the app, but of course setting a password is not too helpful if the person who you want to lock out is yourself. The developers suggest giving the password to a friend so that you cannot work around this mechanism. That's a good idea, but I am weirdly individualistic sometimes, and I prefer to keep the keys in my hand.
Ideally, I would have something like a time-lock where I write down the password, lock it in with a timer, and not access it until the time is over. People in this forum have suggested such a device. And again, while it is a good idea, I wouldn’t say I like the idea of having an additional piece of hardware to solve a digital problem.
Luckily, there is a straightforward digital solution. I want to think that I first come up with this idea by myself, but when I googled it a couple of years ago, I found that Gwern had already written about it in 2011. So, if you would like an in-depth explanation, click on that link (it’s the section about chained-hashes that is relevant for this post).
One way to implement a time-lock is to use hash functions. Hash functions take input and compute an output deterministically. The beauty is that you cannot predict the result. You have to do the work and execute the function. For example, you could start with the phrase “secret-password,” put it into your hash function and get the output “my-new-secret” in a certain amount of time, say one second.
By repeatedly using the output as the input for the same function, we can spend an arbitrary amount of time (or iterations) until we get a final string, our time password. We can use this password like a regular password, except we throw it away once we have used it to lock the app (or whatever our use-case is).
Lastly, to restore the password, we need to remember our initial input and the number of iterations we have executed. For example, here I am running one hundred million iterations which take about 90 seconds on my machine.
And at the end, I get a nice random time password. One could post-process the final string to allow only certain characters or shorten the length, as some websites require it.
Now, you can see whatever amount of time I am willing to spend initially; I will later have that same amount as a buffer to defeat Akrasia. I have noticed that waiting ten minutes to open up Reddit is already more than enough in practice.
λ → python timelock.py Enter count: 1e8 Password: Confirm password: 100000000 hashes done in 106.24s. Final result: fe90e6ccb7eb50ddf8237417b2ef8380396285a31d143a880572420206f041c9
Lastly, the code is on Gitea if you want to try it.