My team (Ideal Labs) has recently completed a w3f grant to build a consensus mechanism that uses identity based encryption and DLEQ proofs to leak IBE secret keys in block headers, on top of which we implemented a timelock encryption scheme. If you’re familiar with drand, our implementation is a little similar conceptually. You can read our (completed) grant proposal here, as well as find links to github and documentation here. As part of the grant, we created a timelock auction proof-of-concept, which you can check out here.
We’ve already submitted a followup grant proposal, however, I want to discuss our next steps and gather input from the community. Our goal is to develop a ‘delayed transactions’ framework using timelock encryption, where transactions can be locked until specific blocks, after which a scheduler (e.g. pallet_scheduler) can decrypt and add the transactions to the transaction pool. This can act as a basis for trustless MPC protocols (as smart contracts), where many participants secretly commit to some input to the protocol (a transaction), and where each input is revealed only when the protocol terminates (by reaching a specific future block).
In our grant, we developed a proof of authority version of our consensus, where each authority is an IBE master key custodian. While this is simple and works, it’s not an optimal solution since there is no clear incentive for authorities to act honesty and it’s really easy for one of them to leak the master key. Instead, a better approach would be to use secret sharing techniques. In particular, we have been looking into using a dynamic-committee proactive secret sharing protocol to be able to 1) split the secret among members of the authority set and 2) share those secrets with a potentially non-overlapping authority set. This could ensure that the master IBE key in both our poa and pos style consensus mechanisms can’t be so easily leaked. With a few changes to our timelock encryption implementation, we can account for this with minimal changes. Specifically, we are looking at the schemes proposed both (here)[https://eprint.iacr.org/2022/971.pdf] and (here)[https://eprint.iacr.org/2019/017.pdf].
There are several mechanisms in place in substrate/polkadot to delay transaction execution, for example with the scheduler pallet, prototypes on a delayed xcm queue, and the time-delay proxy, but each solution is vulnerable to front-running attacks, among other implications of ‘knowing the future’. We propose to secure this process with timelock encryption, ensuring that transactions remain encrypted until a scheduled future block. Apart from front-running protections, this also enables the development of trustless, “atomic” MPC protocols within smart contracts. That is, contracts which allow multiple parties to commit to a protocol without revealing their input, and for that protocol to complete with no further interaction from the participants. In addition, delayed transactions can add secure, decentralized escrow capabilities, for example by transferring a balance to a pure proxy and scheduling a timelocked transaction to add another address (recipient of the balance) and remove yourself (sender of the balance), while the transfer could still be stopped at any time prior to execution.
The general idea is that we will modify the scheduler pallet so that it can perform decryption of encrypted, scheduled transactions (transactions are created through the usage of our etf-sdk). When encrypting transactions for future blocks in the chain, we run into the issue of nonce generation and verification. Normally, transaction nonces are monotonically increasing sequences starting at 1 (or 0). Any origin that encrypts a transaction for a future block must specify a nonce in the transaction, say
k for example. By committing to this nonce, the account must only use at most nonce
k-1 before the future transaction is executed, otherwise the transactions with nonce
k will be invalid (if
k is already used). This is quite a major limitation for an account, as it essentially means the account needs to, at some point, not be able to execute anything.
A fairly simple way to solve this, without changing how nonces work, is by using a chain of three accounts, A → B → C where A proxies B proxies C. Likely, C would be a soft-derived account from A. The idea is that we first build a transaction for account C, TX_C. Then we wrap that in a proxy call through C’s proxy, B, producing TX_C’. Then A would encrypt the transaction and produce a ciphertext CT, which A then schedules through an extrinsic. The scheduler pallet takes it away from there, performing decryption as previously discussed.