[Feature]: DKG key verification step pre-rotate-key #1300
Labels
breaking-protocol
Breaking protocol changes
sbtc signer binary
The sBTC Bootstrap Signer.
signer coordination
The actions executed by the signer coordinator.
Milestone
Feature - DKG key verification step
1. Description
We should introduce a form of verification that raises confidence that the signers, together with their newly generated key shares, can generate a proper signature and that it correctly unlocks a UTXO locked by the new scriptPubKey.
Quick links:
1.1 Context & Purpose
When the signers have re-run DKG and are going to sweep from the current UTXO locked by the
current
key to a new UTXO locked by thenew
key, there are currently no verifications in place to ensure that, according to Bitcoin validation rules, that the new UTXO would indeed be spendable in a new transaction when the input is signed using WSTS prior to moving the funds.There are three proposals for solving this to various degrees (summarized from discussions on Slack):
1.1.1 Alternative 1
Require a sweep transaction from
current
to a UTXO locked bynew
to include a deposit that spends the signers' new UTXO. Bitcoin core would then reject the transaction if its validation and/or consensus rules determine that the new UTXO can't be spent by the new transaction.This is the least-effort change of the proposed solutions, however there are some considerations:
new
key to trigger this validation. In the case of a compromised key, we may have to (ourselves) make a deposit to trigger this logic. If the caps are reached, we have to modify caps and risk other deposits sneaking in.current
key and withdrawals, but deposits locked by thenew
key may get stuck and need to be reclaimed.1.1.2 Alternative 2
Require a check that the
new
signers' scriptPubKey is spendable when an input is signed with the new key over WSTS. This would entail creating two valid transactions that Bitcoin core would accept into the mempool (i.e. they need to be well-formed and spend valid UTXO's):current
UTXO to a new UTXO locked by thenew
scriptPubKey. This would simulate the sweep transaction transferring ownership to thenew
key.new
scriptPubKey, to a new UTXO also locked by thenew
scriptPubKey. This would simulate subsequent sweep transactions during normal operation (i.e. no key change).These transactions would then be submitted to the Bitcoin Core node via the testmempoolaccept RPC endpoint for testing whether or not the node would accept them into the mempool (this does not broadcast the transactions). This endpoint can accept transaction packages which means that these two chained transactions can be constructed, packaged together and placed into the same RPC request, meaning that T1 doesn't need to be in the mempool for T2 to be tested.
This involves WSTS signing of two separate transactions, which in itself isn't an issue, but it is extremely important that these transactions be constructed in a way that Bitcoin Core would accept them but the likelihood of them being mined is essentially zero. This is because these would be valid transactions spending the signers' UTXO's which could be broadcast to the mempool by a malicious signer.
To ensure that the transactions would not be relayed/mined in the event they were broadcast, the most obvious approach would be to spend the entire UTXO's (i.e. set zero fee), which the signers would validate prior to signing in addition to that the UTXO's are spent to the correct scriptPubKey. The largest potential issue with this approach is that it requires configuring Bitcoin Core to use
minrelaytxfee=0.0
which may be prohibitive for some operators of sBTC signers. Otherwise, it is non-standard to relay zero-fee transactions, which also decreases the likelihood that if broadcast that these transactions would successfully propagate through the network.1.1.3 Alternative 3
Similar in nature to Alternative 2, require a check that the
new
signers' scriptPubKey is spendable when an input is signed with the new key over WSTS by using bitcoinconsensus to perform local validations using bindings to Bitcoin Core's own verification code.This also involves WSTS signing, however only one round (transaction) where the transaction has an input attempting to spend the
new
signers' scriptPubKey. The transaction template would be well-known (hardcoded) to all of the signers and invalid (spending a nonexistent UTXO), so each signer would construct the transaction themselves for the verification test. The only information needed to be provided by the signing coordinator to participants would then be the taproot sighash, which each signer can independently verify matches the sighash that they expect prior to signing. These measures eliminate the risks of signing valid Bitcoin transactions.While this alternative is lower risk and doesn't require any communication with Bitcoin Core, it can't offer 100% guarantee that the node would indeed accept the transaction into the mempool as alternative 1 can. However, the cryptographic verifications all use
libsecp256k1
under the hood both in Bitcoin Core, andbitcoinconsensus
uses direct bindings to Bitcoin Core's code, so the risks of these operations differing are relatively low. The greater risk would be to policy and consensus rules causing the cryptographic verification to succeed but mempool accept to fail; these kinds of issues should be remediable via code updates, however.Important to note that
libbitcoinconsensus
was deprecated in 27.0 and removed in 28.0:2. Technical Details:
To be detailed in the chosen implementation.
2.1 Acceptance Criteria:
3. Related Issues and Pull Requests (optional):
The text was updated successfully, but these errors were encountered: