-
Notifications
You must be signed in to change notification settings - Fork 159
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
[ZIP 244] preserves a bug from BIP-143, forcing hardware wallets to verify all transparent prevouts #574
Comments
If we made this change, it would be specifically to
where the values of these digests depend on the sigtype. We would add the two new fields in between No change would need to be made for Sapling or Orchard signatures. As with ZIP 143 and ZIP 243, they are not subject to this bug, as shielded inputs are committed to directly (via the nullifier) instead of indirectly (via the prevout |
I came to the absolutely same conclusion as @str4d, when I was thinking about these changes in more detail. |
@str4d I think that these two fields should perhaps instead be one level lower, part of |
zcash/librustzcash#472 implements my suggestion here. @str4d if this looks reasonable I'll create a PR for the ZIP. cc/ @daira @teor2345 |
Looks good to me! Did you want to make the We'll want a v5
Similarly, a new v5 non-precompute function will need the output data for every input script validation call. There are some extra fields in each output that we're not signing, but it's easier to use the chain format, and discard those bytes. (Or parse them and not use the fields.) If it's easier, we can just add arguments to the existing |
The reason I said S.2 instead of S.2d is because the latter is specifically documented as (emphasis added):
The two new fields are not properties of the transparent input being signed; they are properties of the transaction as a whole. Hence it feels to me that they belong as commitments in the S.2 digest input (which covers the transparent parts of the transaction) rather than the S.2d digest input. The way I'd see the hash input for S.2 being defined now is That being said, it probably doesn't matter precisely where these commitments end up. Given that we designed the tree structure to enable chaining parts of the transaction to a block header, I'm wary of modifying the definition of |
I'm agnostic as to whether the new fields go in S.2 or S.2d. If the latter, then the documentation of what S.2d covers can easily be updated, and I am slightly inclined to prefer that. Either option works from a security point of view. |
My preference here is to redefine S.2d so as to preserve the relationship with the txid; I think the implementation reflects the semantics we want, which is that the signature part is computed on a per-input basis; it's just that we now want that per-input commitment to also commit to the specific breakdown of the full transparent value of the transaction. The lens I'm using here is "the context in which this input is being spent is considered a property of the input for the purposes of signing." |
In ZIP sync today, @daira, @nuttycom and I looked at BIP 341 more closely. We decided to make changes to bring the transparent part closer to BIP 341:
|
#577 implements the above changes. Additionally, while working on this with Daira, I noticed that ZIP 244 wasn't committing to |
Transparent UTXOs are referred as pair of previous txid and index. In order to verify UTXO's amount in HWW (hardware wallet), whole previous transaction containing this UTXO must be streamed into the device. This increases complexity of signing process significantly. zcash/zips#574 identifies this problem and suggests a modification to ZIP-244 to resolve this issue, by adding three new fields to section S.2 of the signature hash.
TL;DR: The signed data should include all prevout amounts and all prevout script public keys (unless
ANYONECANPAY
flag is set).Problem
Transparent UTXOs are referred as pair of previous txid and index. In order to verify UTXO's amount in HWW (hardware wallet), whole previous transaction containing this UTXO must be streamed into the device. This increases complexity of signing process significantly.
BIP-143 (SegWit) attempted to address this issue by concatenating input amount to signed data. Unfortunately, there is a bug, found by Saleem Rashid [1]. Due to this design flaw an attacker could create two Segwit transactions which, when combined together, can send the coins from wallet via a massive transaction fee.
Same bug repeats in ZIP-143, ZIP-243 and ZIP-244.
Solution
BIP-341 (Taproot) successfully fixed the issue by concatenating hash of all amounts to the signed data. Further, it also concatenates all public keys of previous outputs to prevent a similar type of attack related to external inputs [2].
I recommend modifying ZIP-244 to adapt BIP-341 approach to finally get rid of this issue.
Two new fields should be introduced:
amounts_digest
(32 bytes) - the hash of the serialization of all spent output amountsscriptpubkeys_digest
(32 bytes) - the hash of all spent outputs' scriptPubKeys, serialized as script insideCTxOut
These two fields should be part of signed data iff
ANYONECANPAY
flag is not set.@andrewkozlik @daira
The text was updated successfully, but these errors were encountered: