Why are SIGHASH flags signed as 4 bytes when only 1 byte is included in the transaction?

2

1

This article brought to my attention that SIGHASH flags are 4 bytes long when signed, but only the last byte is actually included in the transaction. Then OP_CHECKSIG adds 3 bytes 0x000000 back on before verifying the signature. The article describes a clever way to introduce a fork using those three truncated bytes -- so why are the SIGHASH flags 4 bytes long in the first place? Is that a design flaw or feature?

pinhead

Posted 2016-08-18T17:02:10.493

Reputation: 2 356

Answers

4

I assume it is simply the result of lazyness.

In the original client source code (and still today), the sighash type is represented as an int. The serialization framework by default serializes ints as 4 little-endian bytes.

I assume Bitcoin's creator did not bother converting it to a single byte before serializing.

If there is any other reason, I'm afraid you'll need to ask him.

Pieter Wuille

Posted 2016-08-18T17:02:10.493

Reputation: 54 032

Thanks Pieter that makes sense... but then when (in the code) is that int truncated to 1 byte? Is that just to reduce transaction size?pinhead 2016-08-18T21:15:57.280

Is it this line right here, casting nHashType as an unsigned char (1 byte): https://github.com/bitcoin/bitcoin/blob/d612837814020ae832499d18e6ee5eb919a87907/src/script/sign.cpp#L32

pinhead 2016-08-19T00:28:09.503

2Yes, my assumption is that Bitcoin's creator cared about signature size (although he didn't realize that using DER encoding added 6 bytes for no reason), and used 1 byte for the sighash type there, but didn't care enough to do the same for the sighash calculation.Pieter Wuille 2016-08-19T08:29:11.697