Merge rust-bitcoin/rust-bitcoin#1567: Use `sha256d::Hash` type for sighash encoding

49e8b8da32 Use write_all for sighash encoding (Tobin C. Harding)

Pull request description:

  From BIP143:

  > If sighash type is SINGLE and the input index is smaller than the number of outputs, hashOutputs is the double SHA256 of the output amount with scriptPubKey of the same index as the input;

  Currently we are using a `Sighash` which wraps double sha256 so while technically correct this means we are relying on `Sighash` to implement `Encodable`. We can remove this requirement by directly using the `sha256d::Hash` type to hash the outputs data.

  Fix: #1549

ACKs for top commit:
  Kixunil:
    ACK 49e8b8da32
  apoelstra:
    ACK 49e8b8da32

Tree-SHA512: 8dd0037245a7cf180ba8a6eceeadad912d4adc14fc3f49df9008856de262624666d7d575195eea4868b2a5252dc565590e6be78471053b5e6367f3d2363310e8
This commit is contained in:
Andrew Poelstra 2023-01-24 14:39:50 +00:00
commit 1b8f52a804
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 3 additions and 3 deletions

View File

@ -69,7 +69,6 @@ See [`hashes::Hash::DISPLAY_BACKWARD`] for more details.
impl_hashencode!(Txid); impl_hashencode!(Txid);
impl_hashencode!(Wtxid); impl_hashencode!(Wtxid);
impl_hashencode!(BlockHash); impl_hashencode!(BlockHash);
impl_hashencode!(Sighash);
impl_hashencode!(TxMerkleNode); impl_hashencode!(TxMerkleNode);
impl_hashencode!(WitnessMerkleNode); impl_hashencode!(WitnessMerkleNode);

View File

@ -729,9 +729,10 @@ impl<R: Deref<Target = Transaction>> SighashCache<R> {
} else if sighash == EcdsaSighashType::Single && input_index < self.tx.output.len() { } else if sighash == EcdsaSighashType::Single && input_index < self.tx.output.len() {
let mut single_enc = Sighash::engine(); let mut single_enc = Sighash::engine();
self.tx.output[input_index].consensus_encode(&mut single_enc)?; self.tx.output[input_index].consensus_encode(&mut single_enc)?;
Sighash::from_engine(single_enc).consensus_encode(&mut writer)?; let hash = Sighash::from_engine(single_enc);
writer.write_all(&hash[..])?;
} else { } else {
zero_hash.consensus_encode(&mut writer)?; writer.write_all(&zero_hash[..])?;
} }
self.tx.lock_time.consensus_encode(&mut writer)?; self.tx.lock_time.consensus_encode(&mut writer)?;