Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: Sergio_Demian_Lerner on August 22, 2012, 12:59:06 PM



Title: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: Sergio_Demian_Lerner on August 22, 2012, 12:59:06 PM
In the https://en.bitcoin.it/wiki/OP_CHECKSIG (https://en.bitcoin.it/wiki/OP_CHECKSIG) wiki, the process behind OP_CHECKSIG is described.

Why  TxPrev.PkScript is inserted into TxCopy ?
(In the source code the method is called SignatureHash() and the temporary tx is TxTmp not TxCopy, and the input is nIn.)

I think that the point is to "mark" the transaction input that is being signed to prevent one signature to be used for more than one input.
But why not only insert a single char '*' into the script of input nIn ? Why a big chunk of the  TxPrev.PkScript is inserted ?

What is the functionality I'm missing?

Thanks, Sergio.









Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: Pieter Wuille on August 22, 2012, 02:12:00 PM
Why  TxPrev.PkScript is inserted into TxCopy ?

Ask Satoshi...

(I suspect the answer is that it felt safer to him for some subjective and not very well-founded reason)


Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: Mike Hearn on August 22, 2012, 03:17:22 PM
I suspect this is left over from the first release of Bitcoin which had a broken way of running scripts - they were literally concatenated with an OP_CODESEPARATOR which meant you could steal anyones money by crafting a custom transaction. It may have been cruft left over from development at that point.


Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: Sergio_Demian_Lerner on August 22, 2012, 03:25:50 PM
Very interesting software archeology :)

Like a part of DNA of an extinguished specimen that got trapped in the DNA of Bitcoin.



Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: 2112 on August 22, 2012, 03:36:59 PM
Very interesting software archeology :)
Like a part of DNA of an extinguished specimen that got trapped in the DNA of Bitcoin.
Very wise statement. Bitcoin is like amber, the bugs inside are to be admired for their beauty as long as possible.
https://bitcointalk.org/index.php?topic=46498.msg556688#msg556688


Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: mmeijeri on December 24, 2013, 08:37:26 PM
I think that the point is to "mark" the transaction input that is being signed to prevent one signature to be used for more than one input.

Doesn't the signature already apply to the hash of the previous transaction and the index in it? Why would you need any additional data at all?


Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: Peter Todd on December 24, 2013, 11:53:45 PM
I think that the point is to "mark" the transaction input that is being signed to prevent one signature to be used for more than one input.

Doesn't the signature already apply to the hash of the previous transaction and the index in it? Why would you need any additional data at all?

Bitcoin prior to the v0.1 release (https://bitcointalk.org/index.php?topic=382374.msg4108647#msg4108647) had a system where the scriptSig and scriptPubKey were concatenated prior to evaluation; OP_CODESEPARATOR was included in scripts (or scriptSigs) explicitly to mark what part of that concatenated script was to be hashed. The mechanism was broken because OP_RETURN could be used in a scriptSig to return prematurely, but other than that oversight the idea was sound. (the actual v0.1 release inserted OP_CODESEPARATOR explicitly prior to calling EvalScript, breaking the idea, so I'm not sure if Satoshi actually realized what could have been made possible)

Inserting this script into the txcopy scriptSig was the mechanism by which items in the scriptSig could be included in the signature. Something interesting about SignatureHash is you can use non-standard hashtypes in a backwards compatible way: nHashType is ANDed with mask 0x1f, or 0b00011111, prior to testing against SIGHASH_SINGLE and SIGHASH_NONE, which means that if they are set to anything other than those two values the signature hash is calculated without modifying vout. Similarly bits 6 and 7 of nHashType are completely ignored. Had the original design been kept additional SignatureHash() flags could have easily and efficiently been added in a soft-fork, for instance:

scriptPubKey: <pubkey> OP_CHECKSIG
scriptSig: <additional hashed data> <signature>

OP_CHECKSIG has defunct code to remove the signature from the concatenated script prior to calling SignatureHash(), so the final concatenated script inserted into the txin scriptSig would be:

<additional hashed data> <pubkey> OP_CHECKSIG

That additional hashed data could have be, for instance, the hash of the values going into the transaction to allow for signatures to cover fees. Similarly it could have been used with SIGHASH_NONE to redefine how signatures worked. Though note that for this to be a soft fork failure to match that additional data would have to be handled with as an immediate fail, turning OP_CHECKSIG into OP_CHECKSIGVERIFY with respect to the new features.

Having said that we can still do this, although it gets less efficient. Basically you just make an entire second signature, ~72 bytes worth, and have the special signature hash bits trigger the OP_CHECKSIG code to check it as well. For instance:

scriptPubKey: <pubkey> OP_CHECKSIG
scriptSig: <sig2> <sig1>

Where sig1 uses the old signature algorithm, and sig2 uses a new algorithm. For pre-soft-fork nodes sig2 is just useless data and does nothing, but for post-soft-fork nodes if sig2 is invalid the transaction fails.


Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: mmeijeri on December 25, 2013, 11:37:03 AM
(the actual v0.1 release inserted OP_CODESEPARATOR explicitly prior to calling EvalScript, breaking the idea, so I'm not sure if Satoshi actually realized what could have been made possible)

It seems so needlessly complicated that it must have had a reason. I wonder if maybe he intended to add a 'sticky' flag that required conditions on an output to be concatenated onto any new outputs it was spent to. The whole thing is very confusing to me though, and I'm having great trouble understanding your post.


Title: Re: Why TxPrev.PkScript is inserted into TxCopy during signature check?
Post by: Peter Todd on December 26, 2013, 01:31:21 AM
(the actual v0.1 release inserted OP_CODESEPARATOR explicitly prior to calling EvalScript, breaking the idea, so I'm not sure if Satoshi actually realized what could have been made possible)

It seems so needlessly complicated that it must have had a reason. I wonder if maybe he intended to add a 'sticky' flag that required conditions on an output to be concatenated onto any new outputs it was spent to. The whole thing is very confusing to me though, and I'm having great trouble understanding your post.

It's confusing to me too; I didn't clue into the soft-fork stuff until about the third or fourth time I looked at that code.

Keep in mind Bitcoin had pretty poor software engineering in v0.1, so finding features that turned out to be poorly thought through shouldn't be surprising.