Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Burnchain: Allow VRF public key reuse #1615

Closed
kantai opened this issue May 21, 2020 · 5 comments · Fixed by #1848
Closed

Burnchain: Allow VRF public key reuse #1615

kantai opened this issue May 21, 2020 · 5 comments · Fixed by #1848
Assignees
Milestone

Comments

@kantai
Copy link
Member

kantai commented May 21, 2020

Block commit operations are currently checked by matching the input address of the block commit to the output bytes of the VRF key register operation. However, this is not a sufficient check, because Bitcoin outputs could allow matching scriptsigs to validate for other kinds of outputs (e.g., an output that always validate).

There are (at least) two potential options:

  1. Require block commits to spend the exact UTXO generated by the VRF key register.
  2. Lookup the block commit's spent UTXO to obtain the output "scriptpubkey" and validate using that.

(1) would require miners to very specifically link UTXOs between VRF key registers and block commits.

(2) would require running a Bitcoin node with txindex=1

A radical alternative would be to revisit the necessity of one-time use VRF public keys. If my memory is correct, the rationale for one-time use public keys is that it prevents miners from assembling a large set of public keys, and using insights about the seed to chose a key. However, the VRF seed is hidden from everyone but the burnchain miner (and even, to a certain extent from them -- changing the public key they commit to will lead to a different vrf seed, because the proof-of-work hash will change).

@jcnelson
Copy link
Member

jcnelson commented May 21, 2020

To be clear, (2) would also require that the burnchain indexer make multiple (very slow and expensive) RPC calls to bitcoind to resolve each considered transactions' input's consumed output. Stacks 1.0 does this, and I consider it to be a design flaw because it not only slows down chain synchronization, but also makes it much more expensive for people to run their own bitcoin nodes to use Stacks. I'd like to avoid option (2) if at all possible.

I'm not sure that was the rationale. We can't stop a miner from assembling a large set of VRF public keys even if they're one-time-use, since they can just register a bunch of them under different addresses. Also, the VRF seed is public knowledge for the duration of the epoch right before the miner's tenure begins -- this is necessary in order to ensure that all miners have a chance to make their VRF proofs in order to submit their block-commits. There is a window of time during which the next epoch's seed is known only to the burnchain miner (and that may give them a chance to grind on VRF keys), but this advantage can be severely mitigated by requiring that the VRF key have a minimum number of confirmations before it can be paired with a block-commit (the code right now implicitly requires that the VRF key has at least 1 confirmation -- i.e. it must already be in the burn DB -- but this can be pushed back).

I'm open to revisiting the necessity to not re-use a VRF public key. If we can convince ourselves that it's safe to reuse them, then we don't need to require that a block-commit transaction is sent by the same principal that sent the VRF key (since only the principal who has the VRF private key can produce a valid Stacks block).

@kantai
Copy link
Member Author

kantai commented May 21, 2020

Also, the VRF seed is public knowledge for the duration of the epoch right before the miner's tenure begins -- this is necessary in order to ensure that all miners have a chance to make their VRF proofs in order to submit their block-commits. There is a window of time during which the next epoch's seed is known only to the burnchain miner (and that may give them a chance to grind on VRF keys), but this advantage can be severely mitigated by requiring that the VRF key have a minimum number of confirmations before it can be paired with a block-commit (the code right now implicitly requires that the VRF key has at least 1 confirmation -- i.e. it must already be in the burn DB -- but this can be pushed back).

Ah -- yes, I think I used the wrong terminology here -- I meant the value used for selecting the winner -- (roughly hash(vrf_seed || burn_block_hash)), which wouldn't be known until the burn block was assembled.

@jcnelson jcnelson changed the title Block commits must validate the spent UTXO Burnchain: Allow VRF public key reuse May 28, 2020
@jcnelson
Copy link
Member

I renamed this issue to reflect the growing consensus. It should be safe to reuse VRF public keys, which obviates this concern.

@diwakergupta
Copy link
Member

@psq is working on this, I'll update assignment to reflect that shortly.

@diwakergupta diwakergupta linked a pull request Sep 1, 2020 that will close this issue
psq added a commit that referenced this issue Sep 9, 2020
Implement #1615 by allowing key reuse
@diwakergupta
Copy link
Member

Fixed in #1848

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants