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
Support external inputs #1080
Support external inputs #1080
Conversation
This seems significant in terms of UX: we are deliberately introducing a failure mode where the trusted device can say "please confirm -> signing ... -> signing failed!". This is almost exactly the thing that was exploited in the recent BIP-143 vulnerability. OTOH if we implement the proposed "success" screen at the end of every flow, this becomes less significant.
This is a very interesting idea. It might interfere with Suite wrt #35 though: no good way to report user progress to the host while streaming data. |
I don't see a problem here. Let's assume we would have an error dialog for failed signing on Trezor and an attacker used the new code to invoke this dialog after user confirmation. Since the signing takes place after |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
partial review, i'll still need to go back to the Bitcoin
and Verifier
classes
I'm not claiming this is exploitable on the technical level. |
There is also the fact that we would require |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this is all from me 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to be OK in terms of security and compliance.
I added a few comments mostly suggesting better naming.
text = Text("Joint transaction", ui.ICON_SEND, ui.GREEN) | ||
text.normal("You are contributing:") | ||
text.bold(format_coin_amount(spending, coin)) | ||
text.normal("to the total amount:") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I consider the "total amount" misleading since it includes external change outputs but not your change output. I can's see any benefit in showing such an amount.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the sum of the outputs that the user confirmed, plus the fee. Including the user's change output wouldn't make any sense. It would just confuse the user, because the number would look totally random to him given that his change output is hidden from the confirmation process. An alternative I was considering is below. But what I'd be most interested in is investigating the possibility of hiding the external change outputs as I explained above. It's up for discussion. I copied it into the CoinJoin document we were looking at yesterday so that it doesn't get lost.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Including the user's change output wouldn't make any sense
I'm not saying it makes any sense.
I copied it into the CoinJoin document we were looking at yesterday so that it doesn't get lost.
Great.
… in bgold, bcash and zcash.
dce49d9
to
de46895
Compare
Implements #1052
This PR implements support for signing transactions with external inputs on Trezor. The external input must either be pre-signed or accompanied with a proof of (non-)ownership. This should work for all Bitcoinlike coins except Decred, which didn't seem worth the effort as it has a signing flow of its own.
@onvej please review SLIP-0019 spec compliance and security in general, namely in terms of changes to the signing flow and correctness of signature verification.
@matejcik please review the overall design and organization of the code, protobuf messages and changes to the signing flow from the perspective of the protocol.
Test coverage
For pre-signed inputs the test coverage should be fairly complete, but I am using transactions generated by Trezor, which means that they might not actually be fully valid, as we discussed. Nevertheless this still tests the relevant functionality, so it's not a problem, I am just not very happy about introducing more of these. For external inputs with proofs of ownership I implemented only two device tests and those are for P2WPKH. I am leaving the other script types for later when we decide on a general approach to constructing fully valid testing transactions. However, the other script types are covered by unit tests, so that should actually be sufficient.
UI
total
and we would only check thattotal >= spending
. Seems rather risky though, needs further analysis.Signature verification
There are several ways to go about implementing signature verification. The easy way would be to delegate the parsing of the witness/scriptSig to client software and then just call some pre-existing functions in Trezor to check the hashes. I chose to parse the scripts in the firmware, because it seems to me that it's not that much trouble and considering that in time we will probably be implementing PSBT in Trezor, this approach seemed more future-proof, because we would need to do it anyway.
Verifying validity of external inputs
The validity of external inputs can be verified before or after user confirmation. I chose to do it after confirmation.
Advantages:
Disadvantages:
Verifying all previous transactions after confirmation
I haven't implemented this, but am in favor of doing so, especially if we are unable to speed up the prev_tx streaming. The disadvantages are the same as above (mainly one additional TxRequest per input). Ideally we could even do the prev_tx verification in the background while the confirmation dialogs are showing up, which would require these kind of changes to the code anyway. All of this can be done in a separate task, but I wanted to bring it up here, given that it's closely related.
Changes to test vectors
You will notice that due to some refactoring around
hash143_preimage_hash()
, I had to regenerate the test vectors, because I couldn't figure out the preimage to the pubkey hashes. I used the firmware to regenerate them, so if anyone cares to check them with a 3rd party tool, you are welcome to do so.