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

Taproot in Trezor T #1891

Merged
merged 36 commits into from
Nov 13, 2021
Merged

Taproot in Trezor T #1891

merged 36 commits into from
Nov 13, 2021

Conversation

andrewkozlik
Copy link
Contributor

This PR implements the main Taproot functionality (#1656) in trezor-core, and fixes some bugs that I stubled on along the way:

  • Implements BIP-340 key tweaking functions.
  • Implements GetAddress for Taproot.
  • Implements the BIP-341 common signature message computation and Taproot signing.
  • Implements support for replacement transactions with Taproot inputs.
  • Implements support for pre-signed external Taproot inputs.
  • Disables prevtx streaming if all internal inputs are Taproot.
  • Renames Hash143 to SigHasher and replaces preimage_hash() with two functions hash143() and hash341().
  • Adds warning dialog in SignMessage if a non-standard path is used, e.g. GreenAddress or Casa. This is not critical, but seems reasonable to do simply for consistency with how other messages are treated. Once we implement Taproot message signing this will probably become more important, see below.
  • Fixes an off-by-one bug in OP_PUSH writing.
  • Fixes a number of bugs in the TxWeightCalculator and adds unit tests which would have caught them. I also added support for external inputs in TxWeightCalculator. After these fixes the CoinJoin approver needs to account for the weight of the coordinator's output when considering the fair distribution of the fees, which also required a fix.

This PR does not implement any Taproot functionality in trezor-legacy. It also does not implement any of the following in trezor-core:

  • Generating ownership proofs for Taproot addresses.
  • Support for external Taproot inputs with an ownership proof.
  • Message signing and verification for Taproot.
  • Multisig support for Taproot.

One item that is open for discussion is how to behave when a Taproot path is used with ECDSA or when a non-Taproot path is used with Schnorr signatures. The current implementation will only show an "unknown path" warning dialog in these cases. Using the same key in two different algorithms is generally not recommended, at least not without deeper analysis. As far as we known there is no known attack when using the same private key in ECDSA and Schnorr [1], [2], [3]. We could be more strict and allow these scenarios only if safety checks are disabled. On the other hand I am not sure yet how Taproot message signing works in bitcoin-core. If it allows using ECDSA, then being strict in Trezor might pose a problem.

@onvej-sl please review the changes in the C code (trezor-crypto and the trezorcrypto.bip340 module) and review the rest of the code from a security perspective.
@matejcik please review the Python code overall (design, security, etc.).

[1] https://bitcoin.stackexchange.com/a/107928
[2] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018384.html
[3] https://crypto.stackexchange.com/questions/54660/is-it-safe-to-use-same-private-key-in-two-or-more-ec-signature-algorithms

@andrewkozlik andrewkozlik added core Trezor Core firmware. Runs on Trezor Model T and T2B1. bitcoin Bitcoin related HIGH labels Nov 3, 2021
core/SConscript.unix Outdated Show resolved Hide resolved
crypto/zkp_bip340.c Show resolved Hide resolved
@matejcik matejcik added this to To be reviewed in Pull Requests via automation Nov 4, 2021
Pull Requests automation moved this from To be reviewed to Finalizing Nov 4, 2021
@onvej-sl
Copy link
Contributor

onvej-sl commented Nov 9, 2021

Two high level notes:

@andrewkozlik
Copy link
Contributor Author

I was under the impression that we don't have to stream all previous transactions provided there is at least one taproot input [...]

In 21f0bf8 I expanded the corresponding code comment. I also switched the two branches of the if for better legibility, but the code is the same.

Pull Requests automation moved this from In progress to Finalizing Nov 10, 2021
Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

i have a bunch of style comments and a few questions I'd like clarified

plus the thing about signmessage path warnings

core/src/apps/bitcoin/sign_tx/tx_info.py Outdated Show resolved Hide resolved
core/src/apps/bitcoin/get_ownership_id.py Show resolved Hide resolved
core/src/apps/bitcoin/common.py Show resolved Hide resolved
core/src/apps/bitcoin/scripts.py Outdated Show resolved Hide resolved
core/src/apps/bitcoin/sign_message.py Show resolved Hide resolved
core/tests/test_apps.bitcoin.segwit.bip341.p2tr.py Outdated Show resolved Hide resolved
tests/device_tests/test_msg_getaddress_segwit_native.py Outdated Show resolved Hide resolved
tests/device_tests/test_msg_signtx_taproot.py Show resolved Hide resolved
core/src/apps/bitcoin/sign_tx/bitcoin.py Show resolved Hide resolved
core/src/apps/bitcoin/sign_tx/bitcoin.py Show resolved Hide resolved
Pull Requests automation moved this from Finalizing to In progress Nov 10, 2021
@onvej-sl
Copy link
Contributor

In 21f0bf8 I expanded the corresponding code comment. I also switched the two branches of the if for better legibility, but the code is the same.

If I understand it correctly, it turned out that the conjecture written on Slack isn't true because of external inputs and replacement transactions.

@andrewkozlik
Copy link
Contributor Author

If I understand it correctly, it turned out that the conjecture written on Slack isn't true because of external inputs and replacement transactions.

Not only that. Although the attack that was disclosed in June 2020 would not be feasible in it's original form, it would be feasible if in addition the attacker provided invalid information about the script types.

Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, modulo sign_message which will be resolved by rebasing

Pull Requests automation moved this from In progress to Finalizing Nov 12, 2021
- Refactor TxWeightCalculator to count inputs and outputs itself.
- Fix witness data weight by adding the weight of the witness stack item count
  for each input in segwit transactions and removing the weight of the
  nonsensical extra inputs count.
- Get multisig pubkey count from multisig.nodes or multisig.pubkeys like in
  multisig_get_pubkeys().
- Fix size of multisig script length encoding in segwit (varint vs. OP_PUSH).
- Improve comments.
After fixing the TxWeightCalculator the approver needs to account for the
weight of the coordinator's output.
@andrewkozlik andrewkozlik merged commit 221977a into master Nov 13, 2021
Pull Requests automation moved this from Finalizing to Merged Nov 13, 2021
@andrewkozlik andrewkozlik deleted the andrewkozlik/taproot-core branch November 13, 2021 12:33
@prusnak prusnak added this to DONE in Taproot 🥕 Nov 14, 2021
This was referenced Nov 15, 2021
@hynek-jina hynek-jina added this to the Taproot 🥕 milestone Dec 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bitcoin Bitcoin related core Trezor Core firmware. Runs on Trezor Model T and T2B1.
Projects
Development

Successfully merging this pull request may close these issues.

None yet

5 participants