Skip to content

Commit

Permalink
Merge pull request #378 from trilitech/timelocks
Browse files Browse the repository at this point in the history
Create a separate page on timelocks
  • Loading branch information
timothymcmackin authored May 10, 2024
2 parents e55f9c5 + 9ace2b2 commit 6401e6a
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 57 deletions.
63 changes: 6 additions & 57 deletions docs/smart-contracts/data-types/crypto-data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Cryptographic data types
authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)'
last_update:
date: 5 October 2023
date: 9 April 2024
---

Tezos provides hash functions for cryptographic purposes.
Expand Down Expand Up @@ -37,65 +37,14 @@ It can also be used for identity-based cryptography, single-round multi-party ke
- SmartPy: [Cryptography](https://smartpy.io/manual/scenarios/cryptography#cryptography)
- Taquito: [Signing data](https://tezostaquito.io/docs/signing/)

## Timelocks
## Time-locks

A `timelock` is a cryptographic primitive that can be used as part of a **commit & reveal** scheme, to provide a guarantee that the information associated to the commit is eventually revealed.
A `timelock` is a cryptographic primitive that can be used as part of a commit-and-reveal scheme, to provide a guarantee that the information associated to the commit is eventually revealed.

### Classical commit & reveal scheme

Commit & reveal is a scheme that consists of two steps, involving one or more participants:

- Before a set deadline, each participant makes a decision and publishes a commitment, which is a proof that they have taken a decision that they won't be able to change.
The proof often takes the form of a hash of the data that corresponding to the decision.
- After the deadline, each participant reveals the data corresponding to their commitment.
Other participants can check that the hash of this data indeed corresponds to their previous commitment.

This scheme makes it possible to prove that a certain decision was taken before some information was revealed.
This information may be the decision of other participants, or some external independent information.

As an example, imagine that two players want to play the game [rock, paper, scissors](https://en.wikipedia.org/wiki/Rock_paper_scissors) via a smart contract.
As it is impossible to force and verify that the two players reveal their choice between rock, paper or scissors simultaneously, they can use a commit & reveal scheme to do so.

During the first step, they pick their choice, identified by a number from 1 to 3, put it in a pair with some random data, compute a hash of the result.
This hash is the commitment that they can then send to the contract.

After both players have sent their commitment, they can reveal by sending the actual data to the contract including the random data.
The contract can verify that the hash of this data matches the previous commitment.
When the two players have revealed their data, the smart contract determines the outcome of the game and distributes rewards accordingly.

### Not revealing

One issue with the classical commit & reveal scheme is that after the first step is closed and some information is revealed, one participant may find it advantageous to not reveal at all.
Why reveal if it will only make you lose? For some use cases, this can ruin the whole process.

One way to address this problem is by setting a financial incentive, such as tokens that people deposit along with their commitments.
After they reveal, they get the tokens back, which encourages them to reveal.

### Forcing the reveal with a time lock

In some cases, a financial incentive is not enough by itself.
For example, the benefit of not revealing may outweigh the benefit of revealing, or multiple participants may collaborate and decide not to reveal.

In this case, you can use a time lock to produce a commitment and force the reveal.

In this case, instead of using a hash, the data is encrypted using an encryption method that can be cracked with a known algorithm.
The amount of time that it takes to crack the encryption is bounded, which provides a time limit.

The algorithm used to crack it can't be parallelized, which means there is a limit to how much computing power can be applied to it.
You can estimate the time that it takes for an ordinary computer to crack it and for the fastest possible dedicated hardware to crack it.
Then you can set the time limit by setting the number of iterations in the data encryption.

For example, assume that you encrypt data in a time lock that you know takes between 10 minutes and 10 hours to decrypt, depending on the hardware.
You can use a commit phase that takes less than 10 minutes, which is not enough time to crack the encryption, so no one can decrypt anyone's commitment.
Then you can use a reveal phase that gives the participants a few minutes to reveal their data.
If a participant doesn't reveal, you can provide a financial reward (funded by the non-revealed participants' deposits) to anyone else to crack the encryption and reveal the data.

Because it's possible to reveal the data eventually, all participants have an incentive to reveal because they will eventually lose their deposit when someone else cracks and reveals the data.
In this way, time locks work as a deterrent; in practice, participants nearly always reveal rather than forcing someone else to crack the encryption.

Some use cases involve collectively generating a random value or preventing [BPEV attacks](https://opentezos.com/smart-contracts/avoiding-flaws/#6-not-protecting-against-bots-bpev-attacks).
For information about using time-locks, see [Timelocks](../timelocks).

## Implementation details

- Michelson: [Operations on timelock](https://tezos.gitlab.io/active/michelson.html#operations-on-timelock)
- Michelson: [Time-lock](https://tezos.gitlab.io/active/timelock.html)
- Archetype: [Timelock](https://archetype-lang.org/docs/language-basics/crypto#timelock)
- LIGO: [Timelock](https://ligolang.org/docs/reference/current-reference/?lang=jsligo#timelock)
103 changes: 103 additions & 0 deletions docs/smart-contracts/timelocks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: Timelocks
authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)'
last_update:
date: 9 May 2024
---

Timelocks are a way to prevent exploits known as _front-running_, or more properly, _extractable value (EV) attacks_.
In general, these attacks happen when a client uses information about an upcoming transaction to make a profit at its expense.

:::note

Within decentralized finance, the term "front-running" can be misleading because it implies a relationship between clients and block producers where none may exist.

In traditional finance, front-running often relies on malicious brokers profiting from advance, nonpublic information about their clients' trades.
For example, a malicious stockbroker may buy a security for themselves before they execute a client's large buy order, knowing that the client's buy order will drive the price of the security up.

In decentralized finance, anyone can see incoming transactions, so front-running does not always mean that block producers are acting maliciously or sharing private information with clients.
EV attacks can come from bots that watch for incoming transactions and insert their own transactions before the incoming transaction runs.

However, block producers may still be able to profit from advance information about transactions.
For example, they may craft blocks that include a client's transaction and one of their own in an order that guarantees a gain to the block producer.
This type of attack is called a block producer extractable value (BPEV) attack.

:::

For more information about this kind of attack, see [An analysis of Ethereum front-running and its defense solutions](https://medium.com/degate/an-analysis-of-ethereum-front-running-and-its-defense-solutions-34ef81ba8456).

## Preventing EV attacks with timelocks

Tezos developers can prevent EV attacks with timelock encryption, which encrypts a message so it can be decrypted in two ways:

- The author of the encrypted message provides the unencrypted message and proof that it matches the encrypted message.
- Anyone else can decrypt the message with a certain number of operations.

With timelocks, an author can encrypt a message in such a way that anyone else can reveal the message, but only after a certain amount of time.
This duration is based on the time it takes for a single computer to decrypt the commitments because the decryption algorithm can’t be parallelized.
That means that computers can’t easily work together to decrypt it and that adversaries cannot break it even with significant computing power.

dApps that use timelocks to prevent EV attacks work in this general way:

1. A user sends a timelock-encrypted transaction or operation to the dApp.
1. The dApp adds the transaction to its queue before anyone can see what the transaction is.
To everyone else, including bakers, bots, and the dApp itself, the transaction is encrypted and unreadable.
No one else can decrypt the transaction quickly, so they can’t take advantage of it in an EV attack.
1. In the background, the dApp begins decrypting the transaction.
1. One of two things happen:

- The user submits the decrypted transaction and the proof that the decryption is accurate to the dApp before the dApp decrypts the transaction.
- The dApp decrypts the transaction before the user submits the decrypted transaction, such as if prices changed and the user doesn't want to execute the transaction anymore.
In this case, the dApp takes a penalty charge from the transaction for making it waste processing power on decrypting it.
1. The dApp fulfills the decrypted transactions in its queue in the order that they were submitted.

In practice, DeFi users nearly always submit their decrypted transactions before anyone else decrypts them.
They don’t want to pay the penalty and they know how long it will take the dApp to break the transaction’s encryption.

## Flow of timelocks in a typical commit-and-reveal scheme

Timelocks are often used to ensure that a group of users each submit information while keeping their submissions secret for a certain amount of time.
Sometimes this process is called a _commit and reveal scheme_ because all users commit to their choice without seeing the others' choices.

This is the typical usage pattern of a timelock:

1. In the first time period, a contract collects timelock encrypted values from users along with some valuable deposit, such as tez.
2. In the second time period, after the values are collected, users submit a decryption of the value they submitted with a proof that the decryption is correct.
This prevents users from changing their values.
3. In the third time period, if any value isn't decrypted, anyone can claim some of the deposit by submitting a decryption of the value.
This prevents users from profiting by not revealing their decrypted values or blocking the process.
This period needs to be long enough so that people have enough time to perform the timelock decryption.
4. Finally, the contract runs some logic based on the decrypted data.
For example, it might distribute funds to a winner or run an operation that the majority of the users secretly voted for.

Contracts can assess different penalties for not revealing, depending on whether the user merely failed to submit a decryption for their value or if they also intentionally encrypted invalid data.
They can also distribute different rewards for submitting a correct decryption.

Because it's possible to reveal the data eventually, all participants have an incentive to reveal because they will eventually lose their deposit when someone else cracks and reveals the data.
In this way, timelocks work as a deterrent; in practice, participants nearly always reveal rather than forcing someone else to crack the encryption.
However, the second period needs to be long enough so that bakers cannot easily censor submission of the decryption in a bid to later claim the reward.

Also, contracts should burn part of a deposit when another user submits a decryption of someone else's value.
Burning a part of the deposit limits attacks where a user gets back their whole deposit by providing the decryption, but in a way that delays everyone else.

## Example

Timelocks make it possible to prove that a certain decision was taken before some information was revealed.
This information may be the decision of other participants or some external independent information.

As an example, imagine that two players want to play the game [rock, paper, scissors](https://en.wikipedia.org/wiki/Rock_paper_scissors) via a smart contract.
If one player can see another player's choice before they choose, they will win every time.
Because it is impossible to force and verify that the two players reveal their choice simultaneously, they can use a commit-and-reveal scheme.

During the first step, they pick their choice and put it in a pair with some random data.
Then they compute a hash of the result to create a timelock and send this value to the contract as a commitment.

After both players have sent their commitment, they can reveal by sending the actual data to the contract including the random data.
The contract can verify that the hash of this data matches the previous commitment.
When the two players have revealed their data, the smart contract determines the outcome of the game and distributes rewards accordingly.

## References

- [Timelock puzzles and timed release Crypto](http://www.hashcash.org/papers/timelock.pdf)
- [Not protecting against bots (BPEV attacks)](https://opentezos.com/smart-contracts/avoiding-flaws/#6-not-protecting-against-bots-bpev-attacks)
- [How Tezos timelocks help protect DeFi transactions](https://spotlight.tezos.com/timelocks-defi/)
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ const sidebars = {
'smart-contracts/events',
'smart-contracts/delegation',
'smart-contracts/multisig',
'smart-contracts/timelocks',
'smart-contracts/oracles',
],
},
Expand Down

0 comments on commit 6401e6a

Please sign in to comment.