How do you encrypt a file such that it can be decrypted after a date, but not before? Use serial computations for proof-of-work using successive squaring, chained hashes, or witness encryption on blockchains. finished certainty : highly likely importance : 8

In cryptography, it is easy to adjust encryption of data so that one, some, or all people can decrypt it, or some combination thereof. It is not so easy to achieve adjustable decryptability over time, a “time-lock crypto”: for some uses (data escrow, leaking, insurance, last-resort Bitcoin backups etc), one wants data which is distributed only after a certain point in time. I survey techniques for time-lock crypto. Proposals often resort to trusted-third-parties, which are vulnerabilities. A better time-lock crypto proposal replaces trusted-third-parties with forcibly serial proof-of-work using number squaring and guaranteeing unlocking not after a certain point in time but after sufficient computation-time has been spent; it’s unclear how well number-squaring resists optimization or shortcuts. I suggest a new time-lock crypto based on chained hashes; hashes have been heavily attacked for other purposes, and may be safer than number-squaring. Finally, I cover obfuscation & witness-encryption which, combined with proof-of-work, can be said to solve time-lock crypto but currently remain infeasible.

Julian Assange & Wikileaks made headlines in 2010 when they released an “insurance file”, an 1.4GB AES-256-encrypted file available through BitTorrent. It’s generally assumed that copies of the encryption key have been left with Wikileaks supporters who will, in the appropriate contingency like Assange being assassinated, leak the key online to the thousands of downloaders of the insurance file, who will then read and publicize whatever contents as in it (speculated to be additional US documents Manning gave Wikileaks); this way, if the worst happens and Wikileaks cannot afford to keep digesting the files to eventually release them at its leisure in the way it calculates will have the most impact, the files will still be released and someone will be very unhappy.

Of course, this is an all-or-nothing strategy. Wikileaks has no guarantees that the file will not be released prematurely, nor guarantees that it will eventually be released. Any one of those Wikileaks supporters could become disaffected and leak the key at any time—or if there’s only 1 supporter, they might lose the key to a glitch or become disaffected in the opposite direction and refuse to transmit the key to anyone. (Hope Wikileaks kept backups of the key!) If one trusts the person with the key absolutely, that’s fine. But wouldn’t it be nice if one didn’t have to trust another person like that? Cryptography does really well at eliminating the need to trust others, so maybe there’re better schemes.

Now, it’s hard to imagine how some abstract math could observe an assassination and decrypt embarrassing files. Perhaps a different question could be answered—can you design an encryption scheme which requires no trusted parties but can only be broken after a certain date?

Weak keys Let’s think about alternatives to successive squaring. The first approach that jumps to mind and seems to be crypto folklore is to encrypt the file, but with a relatively short or weak key, one which will take years to bruteforce. Instead of a symmetrical key at 256 bits, perhaps one of 50 bits or 70 bits? This fails for two major reasons: variance: we realize that we can guarantee on average how much work it will take to bruteforce the key, but we cannot guarantee how much time it will take. A weak key could be cracked at any time given good luck, and across many uses of time-lock crypto, there will be instances where a weak key would be cracked almost immediately, to the potentially extreme harm of the encrypter. differing amounts of computing resources, particularly parallel computing: It may take a CPU years to bruteforce a chosen key-length, but take a cluster of CPUs just months. Or worse than that, without invoking clusters or supercomputers—devices can differ dramatically now even in the same computers; to take the example of Bitcoin mining, my laptop’s 2GHz CPU can search for hashes at 4k/sec, or its single outdated GPU can search at 54M/second . This 1200x speedup is not because the GPU’s clockspeed is 2400GHz or anything like that, it is because the GPU has hundreds of small specialized processors which are able to compute hashes, and the particular application does not require the processors to coordinate or anything like that which might slow them down. Incidentally, this imbalance between CPUs and highly-parallel specialized chips has had the negative effect of centralizing Bitcoin mining power, reducing the security of the network. Many scientific applications have moved to clusters of GPUs because they offer such great speedups; as have a number of cryptographic applications such as generating rainbow tables. Someone who tries to time-lock a file using a parallelizable form of work renders themselves vulnerable to any attackers like the NSA or botnets with large numbers of computers, but may also render themselves vulnerable to an ordinary computer-gamer with 2 new GPUs: it would not be very useful to have a time-lock which guarantees the file will be locked between a year and a millennium, depending on how many & what kind of people bother to attack it and whether Moore’s law continues to increase the parallel-processing power available. There doesn’t seem to be any obvious way to solve this with a key mechanism. Even if one is using 100 layers of encryption, each short key can be brute-forced almost arbitrarily fast by a well-resourced or even state-level actor. Many weak keys We can solve the variance problem by requiring multiple short keys to decrypt; 1 short key will be cracked ‘quickly’ an unacceptable fraction of instances, but if 100 short keys are all required to decrypt, then the binomial probability of all 100 being cracked ‘quickly’ by chance is acceptably low. (Requiring multiple keys can be done by multiple layers of encryption on the file, onion-style, or by defining the decryption key as all the weak keys XORed together.) This doesn’t solve the serial/computing-power objection: some actors will be able to crack each short key much faster by using highly parallel resources, and it makes little difference whether it’s one weak key or many—they will still open it earlier than other actors. So public or symmetrical encryption may not be directly usable as the time-lock primitive. We want an approach which is inherently serial and unparallelizable.

Hashing Serial For example, one could take a hash like bcrypt, give it a random input, and hash it for a month. Each hash depends on the previous hash, and there’s no way to skip from the first hash to the trillionth hash. After a month, you use the final hash as the encryption key, and then release the encrypted file and the random input to all the world. The first person who wants to decrypt the file has no choice but to redo the trillion hashes in serial order to reach the same encryption key you used. Nor can the general public (or the NSA) exploit any parallelism they have available, because each hash depends sensitively on the hash before it—the avalanche effect is a key property to cryptographic hashes. This is simple to implement: take a seed, hash it, and feed the resulting hash into the algorithm repeatedly until enough time or iterations have passed; then encrypt the file with it as a passphrase. Here is a straightforward shell implementation using SHA-512 & number of iterations: timelock () { local -i I= " $1 " local HASH_SEED= " $2 " while [ $I -gt 0 ] do HASH_SEED=$( echo $HASH_SEED | sha512sum | cut --delimiter= ' ' --fields=1 ) I= $[ $I - 1] done echo $HASH_SEED } timelock_encrypt () { local KEY=$( timelock $1 $2) local PLAINTEXT_FILE= " $3 " echo " $KEY " | gpg --passphrase-fd 0 --symmetric --output $PLAINTEXT_FILE .gpg $PLAINTEXT_FILE } # same as timelock_encrypt except the GPG command changes to do decryption timelock_decrypt () { local KEY=$( timelock $1 $2) local ENCRYPTED_FILE= " $3 " echo " $KEY " | gpg --passphrase-fd 0 --decrypt $ENCRYPTED_FILE } # Example usage: # $ rm foo.* # $ echo "this is a test" > foo.txt # $ timelock_encrypt 100 random_seed foo.txt # Reading passphrase from file descriptor 0 # $ rm foo.txt # $ timelock_decrypt 100 random_seed foo.txt.gpg # Reading passphrase from file descriptor 0 # gpg: CAST5 encrypted data # gpg: encrypted with 1 passphrase # this is a test Another simple implementation of serial hashing (SHA-256) for time-locking has been written in Python. Chained hashes On the other hand, there seems to be a way that the original person running this algorithm can run it in parallel: one generates n random inputs (for n CPUs, presumably), and sets them hashing as before for m iterations (say, a month). Then, one sets up a chain between the n results—the final hash of seed 1 is used as a key to encrypt seed 2, the final hash of which was the encryption for seed 3, and so on. Then one releases the encrypted file, first seed, and the n−1 encrypted seeds. Now the public has to hash the first seed for a month, and only then can it decrypt the second seed, and start hashing that for a month, and so on. Since the encryption for each seed is uncrackable, and there’s no way to “jump forward” in successive hashing, there is no way to reach the final result faster than a single hash can be computed the n*m times in serial by a single processor/circuit. Karl Gluck suggests that like repeated squaring, it’s even possible to add error-detection to the procedure . (A somewhat similar scheme, “A Guided Tour Puzzle for Denial of Service Prevention”, uses network latency rather than hash outputs as the chained data—clients bounce from resources to resource—but this obviously requires an online server and is unsuitable for our purposes, among other problems.) This is pretty clever. If one has a thousand CPUs handy, one can store up 3 years’ of computation-resistance in just a day. This satisfies a number of needs. (Maybe; please do not try to use this for a real application before getting a proof from a cryptographer that chained hashing is secure.) Specifically, you could use a hash for which highly optimized implementations have already been created and put into mass production as ASICs, which have been hand-optimized down to the minimal number of gates possible (probably a few thousand). Because of Bitcoin mining, SHA-256 is a plausible candidate here. (There is one proposal for slightly faster circuits, but it would be unusable for time-locks on its own because it would deterministically fail on some hashes, which would likely be encountered while following a hash-chain.) Serial speedups would lead to proportional reductions in time to unlock. To allow for increases in computing power, it’s probably not necessary to adjust for Moore’s law: serial speeds and clock frequencies have stagnated considerably in recent years, with most of the gains going to parallelism or energy efficiency, neither of which helps with a hash-chain. More concerning is exotic technology like superconducting logic or graphene for implementing circuits in the gigahertz or terahertz range. (Such an exotic chip might cost a lot, but only a few would be necessary to compute hash-chains far faster than expected.) Implementing chained hashing is not as easy as single-threaded hashing, but there are currently 2 implementations: Peter Todd & Amir Taaki: implementation in Python (announcement with bounties on example time-locked files; Reddit & HN discussion), with some clever Bitcoin integration Dorian Johnson, implementation in Go It is not impossible to combine the decrypter programs with a specified time-locked file, creating a self-extracting archive—which stores data safely encrypted; cannot be decrypted before a certain time period; and requires no third-parties whatsoever. In other words, chained-hashes satisfy our original desire for a self-decrypting file. Improvements But what about people who only have a normal computer? Fundamentally, this repeated hashing requires you to put in as much computation as you want your public to expend reproducing the computation, which may not be enough even with a GPU implementation. One may not want ‘merely’ a ratio of 1:100 like that a standard desktop GPU might be able to provide, but much higher—1:10000 or more. (Offhand, I can’t think of any application for time-lock crypto which requires such high ratios, but it may be necessary for doing time-locks at any kind of industrial scale or for exotic applications.) We want to force the public to expend more computation—potentially much more—than we put in. How can we do this? It’s hard to see. At least, I haven’t thought of anything clever. Homomorphic encryption promises to let us encode arbitrary computations into an encrypted file, so one could imagine implementing the above hash chains inside the homomorphic computation, or perhaps just encoding a loop counting up to a large number. There are two problems with trying to apply homomorphic encryption: I don’t know how one would let the public decrypt the result of the homomorphic encryption without also letting them tamper with the loop. Suppose one specifies that the final output is encrypted to a weak key, so one simply has to run the homomorphic system to completion and then put in a little effort to break the homomorphic encryption to get the key which unlocks a file; what stops someone from breaking the homomorphic encryption at the very start, manually examining the running program, and shortcutting to the end result? Of course, one could postulate that what was under the homomorphic encryption was something like a hash-chain where predicting the result is impossible—but then why bother with the homomorphic encryption? Just use that instead! and in any case, homomorphic encryption as of 2013 is a net computational loss: it takes as much or more time to create such a program as it would take to run the program, and is no good.

Distributed time-lock systems Pooling key-cracking Gregory Maxwell has a February 2013 sketch for an altcoin which allows cooperative distributed solving of time-locks (as opposed to solo efforts to tick through a hash-chain): POW which turns the distributed computation into ticking for timelock encryption An infinite sequence of nothing-up-my-sleeve numbers are taken as an infinite sequence of ECC public keys. Searching the pow involves finding distinguished points along a Pollard’s rho DLP solution trying to crack the key. When the key is cracked the problem is advanced to the next key.

public keys. Searching the pow involves finding distinguished points along a Pollard’s rho solution trying to crack the key. When the key is cracked the problem is advanced to the next key. People can then encrypt messages with all of the keys between now and sometime in the future and network will crack them, achieving a timelock.

Probably incompatible with merged mining and other POW schemes.

schemes. Making the difficulty adaptive either makes far in the future messages impossible (because the problem size wouldn’t be known long in advance), or requires increasingly big headers as the difficulty would require working on multiple problems concurrently.

The obvious constructions using ECDLP as the asymmetric problem are not progress free. To explain this idea in a little less jargony form, as best as I understand it: take some standard PRNG; come up with a seed in some publicly acceptable way, such as using the binary expansion of the constant π; define every, say, 100 bits of the output as a public key (with an as-yet-unknown corresponding private key); anyone who wants to timelock a file can encrypt the file using one of these “public keys” and releases the encrypted file to the public as normal; now, people interested in unlocking them (“miners”) work on brute-forcing each chunk of 100 bits one by one, and then the messages for that key can be read by anyone; depending on how much computing power is collectively being spent by the miners, you specify intervals by picking a public key X keys in the future (eg if each 100 bit key takes 1 month to crack and you want to delay opening by a year/12 months, then you encrypt your file to the 12th uncracked key). Or if you are worried about people ‘skipping ahead’ and targeting a future key specifically, the protocol could be that each file is encrypted to all successive keys (so it would be an onion of encryption layers: #1(#2(#3(…(#12(plaintext file))))), so it can only be directly attacked by a loner when the first 11 keys have been cracked). A timelock altcoin could incentivize participation in unlocking files and be more predictable than solo hash-chain files. (A similar idea may or may not have been proposed in the Chinese-language publication Ke et al 2014.) Bitcoin as a clock Obfuscation If one could create a program which is a blackbox such that running the program reveals nothing about its contents besides its output, then one has the start of a time-lock: create a normal encrypted archive, create a blackbox which only emits its content after certain conditions are met, stick the key inside the blackbox, and distribute both the blackbox and the archive. The encrypted archive is uncrackable on its own, and if the blackbox really does obfuscate its contents beyond recognition, the key is safe too. But once the proper conditions are met, anyone with a copy of both can reveal the data. What are proper conditions and how does a program tell the true time? The local computer’s clock is a lie, and trusting any timestamp servers reintroduces trusted third-parties. But this is the same problem as digital currency faces, and the solution can be the same: rely on proof-of-work as embodied in the Bitcoin blockchain! The blackbox can ask a copy of the blockchain and check that n blocks have passed and thus a ungodly number of hashes have been spent to create this blockchain; to the extent that no entity has as much hashpower as the Bitcoin blockchain’s miners collectively do, this is a reliable and trustworthy ‘clock’. (Amusingly, anyone who wanted to spend hashpower to try to open the blackbox early, would be best off becoming a Bitcoin miner, to both defray their expenses and to cause a short speedup of blocks until the mining difficulty ratchets up to compensate.) With time is redefined as blocks which happen every ~10 minutes, someone who wants to release data in a year could include the current block’s hash and specify that the blackbox wants at least, say, 52596 more valid blocks before it will unlock & print the decryption key . Such a blackbox could be created by “indistinguishability obfuscation” (recently developed & related to homomorphic encryption) as pointed out by Liu et al 2015 & Liu et al 2018 This scheme gains several benefits over chained-hashes/multiple-weak-keys/successive-squaring/Maxwell’s-distributed-key-cracking: no one needs to invest computations to create the time-lock (aside from creating the blackbox), no one (much less redundant decrypters) needs to invest computations to unlock it on schedule (as long as the Bitcoin blockchain keeps ticking, it will unlock ‘on its own’), and the timing can be made much more precise (likely down to the day given the stochastic nature of finding blocks which uncertainty is much less than that in how much computing powers decrypters would invest or how optimized their implementations of squaring etc would be). The user wouldn’t even need to install crypto software or download the full Bitcoin blockchain since the blackbox could be combined with the encrypted archive and a Internet API to the blockchain to create a secure, one-click convenient, self-decrypting self-extracting file. The blackbox approach is the best of all worlds and could be said to entirely solve time-lock crypto. Unfortunately, obfuscation (like homomorphic encryption) is so cutting-edge that it may still be insecure computationally impractical as of 2017, and no one could ever successfully execute such a blackbox So it works in principle but not in practice. Random encodings Bitansky et al 2015 show that given obfuscation, one can construct a normal proof-of-work time-lock without using an external clock, where the blackbox stalls for many time-steps before spitting out the key, but without the potentially-expensive setup of chained-hashes. Witnesses Fortunately, indistinguishability obfuscation may be overkill. A weaker but more computable crypto, witness encryption, has also recently popped up: where an obfuscated blackbox can make its computation/requirement arbitrarily complicated and is Turing-complete, witness encryption instead lets one encrypt a file such that the decryption key is the solution to a (possibly unsolved) NP-complete problem like 3SAT. This raises the question: is it possible to encode a check of future Bitcoin blockchain length as a NP problem and thus create an encrypted file which can only be decrypted after enough ticks of the Bitcoin clock? Liu et al 2015 answer: yes! Liu show that a check of the blockchain (specifically, that the SHA-256 hash included in each block represents adequate proof-of-work) can be encoded, and so the construction is at least possible (although feasibility remains unclear), and Liu et al 2015 provide a C program to check proof-of-work which can be compiled into a conjunctive normal form formula whose solution is NP-complete and hence is usable as a witness encryption. Thus, Liu et al indicate that witness encryption could help provide the best of both worlds: the ticking clock is still done by proof-of-work as in successive squaring, but the PoW is a now-hyper-optimized hash so there is little risk of future optimization opening the time-lock early like in chained hashes, and since the Bitcoin blockchain will continue to be built regardless of any interest in time-locks, the clock keeps ticking without the risk of no-one caring enough to try to open the time-lock as the time-lock is piggybacking on the bruteforcing already being done. The two main downsides are that the hashes are not necessarily inherently serialized or unique, and the need for exotic witness encryption. The first means that the security offered by a Bitcoin blockchain time-lock is going to be, like PoW on transactions, an economic kind of security: hypothetically, a powerful actor could if it really wanted to, construct an entire fake ‘chain’ (ie a set of hashes with sufficient leading zeroes); if the time-lock encodes the consensus rules, they can exploit the difficulty adjustment to ratchet difficulty down as fast as possible to eventually generate hashes for free. As of 2018, to create valid Bitcoin PoW hashes at all requires vast mining farms and for almost all intents & purposes, this is adequate security, much as it is for the financial transactions on the Bitcoin blockchain. One could probably include additional conditions like “difficulty cannot decrease more than 50% total for the blocks” (equivalent to specifying a minimum number of leading zeroes for all hashes involved), although this then risks opening too late (what if Bitcoin difficulty crashes for years to come because of a bubble?), and the time-locker is forced to make a tradeoff. Depending on the exact encoding, there may be still other ways to cheat—could one use hashes from other blockchains or past hashes? So there are details which need to be worked out. Secondly, unfortunately, as is common with new & exotic cryptography, the current implementations of witness encryption seem to be slow enough that like obfuscation, witnesses are not yet a viable solution. However, witness encryption seems likely to be optimized much further and it is possible that there are more specialized solutions for blockchains, so it is an approach well worth watching. Distributed secret-sharing with smart contracts A simple way to try to improve on the standard third-party secret-sharing method for time-locking would be to implement them on smart contracts/blockchains like Ethereum in order to support easy decentralized operation by many participants and to allow crypto-economic methods. An Ethereum implementation (Bitcoin smart contracts might be too limited to support the necessary functionality) might go like this: a locker sends an ETH fee to a time-locking smart contract for encrypting a specific file until Ethereum block t (using the blockchain as the clock) One could also try to make a time-lock token on top of Ethereum under the logic that an exchange rate serves as an additional way to penalize attackers, but of course this adds complexity and potentially additional vulnerability—an attacker could buy in, run attacks while collecting fees, exploit decrypted data for profit, sell their stake, set up shorts, and then deliberately reveal successful attacks to crash the token exchange rates and profit 3 different ways from the attack. a quorum of n participants volunteer to be a secret-sharer and each one provides a public key plus a large deposit of ETH when a quorum forms, the public keys in a k-of-m secret-sharing public key, which provides a new public key which the locker can encrypt their file to; presumably they do so and distribute it off-blockchain somehow if one of the secret keys is sent to the contract before t arrives, the sender receives a fraction of the respective deposit, and the rest is destroyed if anyone obtains a secret key from a secret-sharer (eg by hacking them or buying it from them), they have an incentive to betray them by revealing the secret key early and claiming the fraction of their deposit. This provides crypto-economic security against early revelation of secret keys by avoiding “nothing at stake”. after t arrives, within a few blocks, each secret-sharer provides their private key on blockchain to the smart contract, which verifies that they are valid private keys and sends back to the secret-sharer their deposit + a fraction of the fee; now anyone can read off k shares and decrypt the file after time t if a secret-sharer fails to provide their share, their large deposit is destroyed to penalize them This contract seems like it would indeed ensure that keys are released after time t, which is one half of a working time-lock (reliable global decrypting after a certain point without further participation by the original locker). But the other half, reliable non-decryption before time t, appears to be flawed: unfortunately, this doesn’t seem like it would work because despite the deposit-precommitment+defection-incentive, there is still “nothing at stake” for a participant because there’s no way to prove on-blockchain that the file hasn’t been decrypted before time t. On-blockchain visibility is adequate for Proof-of-Work and Proof-of-Stake because participants in PoW can observe any double-spending and punish the PoW owners (who own ASICs and large capital investments) via social mechanisms like forks, and for Casper-style slashing PoS because double-validating can be proven on-chain and their stakes slashed, but the invisibility of decryption means that a defrauded locker can never prove that any or all of the secret-sharers have defrauded them by colluding & decrypting early. Because of this, the contract is vulnerable to Sybil attacks: if the contract is profitable and the ETH fees cover the cost to participants of making deposits/key storage/uptime, then a large entity can by definition profitably participate while pretending to be most/all participants, and easily decrypt many files even if lockers require a large k to decrypt. (The require capital might be quite small; JoinMarket only required $32k Bitcoin capital to de-anonymize transactions, well within the capability of many individuals, never mind attackers like blockchain analysis companies.) A large entity also benefits from some degree of economies of scale compared to a truly distributed quorum, as it only needs 1 blockchain copy, and can more easily invest in 100% uptime to avoid accidentally losing deposits to downtime, allowing it to outcompete; it can further increase profits potentially enormously by systematically decrypting & exploiting anything locked (as it is likely that any file anyone is going to the trouble of time-locking is a valuable file to someone, otherwise why bother?). So such a contract is vulnerable to a self-funding, undetectable, unpreventable, permanent Sybil attack. The vulnerability may extend to actual distributed quorums as well: individual shares can be bribed and attacked, and it’s not clear that the deposit mechanism can prevent all counter-measures or computations. (They probably aren’t as efficient as the main Sybil attack, but would allow attacking prior time-locks or for attacking just a few time-locks.) For example, an attacker can try to defuse the slashing condition and buy shares from k secret-sharers simply by publishing Ethereum contracts with exactly the same mechanism but providing an additional deposit+fee-share from the attacker; this insures the secret-sharers from defection—they can sell their share to the attacker and if the attacker ‘defects’, they merely claim the second deposit and are made whole; thus, either way they get back their deposit and their share of the fee, and since the attacker no longer benefits on net, the attacker won’t defect. Counter-contracts may not be stable (the sharer could defect in turn), but an attacker has additional options: like secret-sharing itself, an attacker could take advantage of multi-party computation to enable bribed sharers to reconstruct the full key in secret without risking revealing their individual shares & thus their deposits. More attacks may be possible, and the smart contract must be robust to all possible attacks and counter-contracts bribing the secret-sharers. Vulnerability of one-way functions As it turns out, “Time-Lock Puzzles in the Random Oracle Model” (Mahmoody, Moran, and Vadhan 2011; slides) directly & formally analyzes the general power of one-way functions used for time-lock puzzles assuming a random oracle. Unfortunately, they find an opponent can exploit the oracle to gain speedups. Fortunately, the cruder scheme where one ‘stores up’ computation (repeatedly asking the oracle at inputs based on its previous output) still works under their assumptions: A time-lock puzzle with a linear gap in parallel time. Although our negative results rule out ‘strong’ time-lock puzzles, they still leave open the possibility for a weaker version: one that can be generated with n parallel queries to the oracle but requires n rounds of adaptive queries to solve. In a positive result, we show that such a puzzle can indeed be constructed…Although this work rules out black-box constructions (with a super-constant gap) from one-way permutations and collision-resistant hash functions, we have no reason to believe that time-lock puzzles based on other concrete problems (e.g., lattice-based problems) do not exist. Extending our approach to other general assumptions (e.g., trapdoor permutations) is also an interesting open problem. That is, the puzzle constructor can construct the puzzle in parallel, and the solver has to solve it serially.