8000 Fix signature hash returned for sighash single bug by tcharding · Pull Request #860 · rust-bitcoin/rust-bitcoin · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix signature hash returned for sighash single bug #860

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

Merged
merged 4 commits into from
Mar 18, 2022

Conversation

tcharding
Copy link
Member
@tcharding tcharding commented Mar 8, 2022

Fix up the logic that handles correctly returning the special array 1,0,0,...,0 for signature hash when the sighash single bug is exploitable i.e., when signing a transaction with SIGHASH_SINGLE for an input index that does not have a corresponding transaction output of the same index.

  • Patch 1 and 2: Clean up
  • Patch 3: Implements the fix
  • Patch 4: Adds a passing test that fails if moved to before patch 3

Resolves: #817

@apoelstra
Copy link
Member

You could use this line of code as a citation: https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1647

But this is a well-known bit of Bitcoin folklore and doesn't really have a citation.

@tcharding tcharding force-pushed the 817-sighash-single-bug branch from 7bae60f to 6cd167c Compare March 8, 2022 20:30
@tcharding
Copy link
Member Author

That gave me a name for a const definition which I wanted to add and the words I needed for the commit logs. Thanks!

@tcharding tcharding marked this pull request as ready for review March 8, 2022 20:31
@tcharding tcharding force-pushed the 817-sighash-single-bug branch from 6cd167c to 4b96698 Compare March 8, 2022 20:38
apoelstra
apoelstra previously approved these changes Mar 8, 2022
Copy link
Member
@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK 4b96698000b2133515b10bb12c715e58f9c20a7b

Much better!

@tcharding
Copy link
Member Author

Sorry for the force push. The unit test uses 0 for the transaction version, it is more correct to use 1 or 2 (as mentioned in the docs of Transaction.version). That's the only change in it.

apoelstra
apoelstra previously approved these changes Mar 9, 2022
Copy link
Member
@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK f86baae69dcece93f545b02a17a6c9015cdbf92e

Copy link
Collaborator
@dr-orlovsky dr-orlovsky left a comment

Choose a reason for hiding this comment

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

One nit, please let me know @apoelstra are we ok with the use of explicit unwrap in the non-test code in this case. If we are ok, ACK f86baae69dcece93f545b02a17a6c9015cdbf92e

@@ -410,12 +409,24 @@ impl Transaction {
script_pubkey: &Script,
sighash_u32: u32
) -> SigHash {
if self.is_invalid_use_of_sighash_single(sighash_u32, input_index) {
return SigHash::from_slice(&UINT256_ONE).unwrap(); // Parse won't panic for const slice.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: we usually try to avoid any unwraps AFAIR:

Suggested change
return SigHash::from_slice(&UINT256_ONE).unwrap(); // Parse won't panic for const slice.
return SigHash::from_slice(&UINT256_ONE).expect("const-size array").

Copy link
Member

Choose a reason for hiding this comment

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

Might as well fix it since we need to rebase anyway, but no, I don't particularly care either way.

Typically we do not put a whitespace character before a `:` when using
explicit types.
Move helper function to above the test that uses it.

Refactor only, no logic changes.
When signing a transaction will result in the sighash single bug being
exploitable we should return the 1 array (equivalent to 1 as a uint256)
as the signature hash.

Currently we are using the correct array value but are re-hashing it,
instead we should directly return it.
When signing a transaction will result in the sighash single bug being
exploitable we should return the 'one array' (equivalent to 1 as a
uint256) as the signature hash.

Add a unit test to verify we return uint256 1 value when use of
SIGHASH_SINGLE is invalid.
@tcharding
Copy link
Member Author

Force push includes:

  • re-base on master.
  • Use expect instead of unwrap.

Copy link
Member
@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK d1abfd9

Copy link
Collaborator
@dr-orlovsky dr-orlovsky left a comment

Choose a reason for hiding this comment

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

ACK d1abfd9

@dr-orlovsky dr-orlovsky added bug code quality Makes code easier to understand and less likely to lead to problems RC fix labels Mar 18, 2022
@dr-orlovsky dr-orlovsky merged commit ebf9162 into rust-bitcoin:master Mar 18, 2022
@apoelstra
Copy link
Member

Somehow I didn't notice, when reviewing this, that it completely removes the sighash-single bug logic from encode_signing_data_to. Now if you use encode_signing_data_to with the sighash single bug it will produce an invalid hash.

@tcharding
Copy link
Member Author

That was by design, right? The initial problem was that having the sighash single bug handled in encode_signing_data_to was incorrect because that function produces output that is meant to be hashed before using, hence by definition we cannot handle the sighash single bug there. For rust-bitcoin this is sane because we only have one call site for encode_signing_data_to, inside signature_hash. Were you meaning that now we leave users of rust-bitcoin without a way to handle the sighash single bug easily? We should probably at lease document this in the dcos for encode_signing_data_to. FTR I'm not really seeing why encode_signing_data_to is a public function when it is pretty clearly a helper function for signature_hash - I just assumed there was some use case I was not aware of. Or am I missing something?

@apoelstra
Copy link
Member

@tcharding the issue is that encode_signing_data_to behaves incorrectly when it encounters the sighash_single bug.

I guess, this was the situation before this PR and continues to be the situation after this PR, so no harm done. But a better solution would be for encode_signing_data_to to return an error rather than doing the wrong thing.

@tcharding tcharding deleted the 817-sighash-single-bug branch March 28, 2022 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug code quality Makes code easier to understand and less likely to lead to problems
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Encoding a TX with the SIGHASH_SINGLE bug
3 participants
0