3

Why can't "we" fix the quadratic hashing problem with OP_CHECKSIG with a soft fork?

Update NO_OPx to OP_CHECKSIG2 with soft fork, where OP_CHECKSIG2 doesn't quadratically hash (uses a single tx hash of all data for each input maybe?). Create a new transaction type for the new process like P2SH and after wide enough network adoption, soft-fork to invalidate any old OP_CHECKSIG transactions the way BIP 66 worked?

Or is there a fundamental problem with my assumption that "uses a single tx hash of all data for each input maybe" is possible at all?

3

You can fix it this way, and someone is in the process of doing so.

The problem with hashing the entire transaction is that in order to create a transaction hash, you must know the signature. However, in order to create the signature, you need to know the transaction hash. To make this work, you need to avoid hashing the scriptSig. This is what Bitcoin does, but the way it's implemented prevents you from taking the hash for one output and using it for another.

BIP143 (part of segregated witness) proposes a system where data is (mostly) hashed once.

A new transaction digest algorithm is defined, but only applicable to sigops in version 0 witness program:

Double SHA256 of the serialization of:

  1. nVersion of the transaction (4-byte little endian)
  2. hashPrevouts (32-byte hash)
  3. hashSequence (32-byte hash)
  4. outpoint (32-byte hash + 4-byte little endian)
  5. scriptCode of the input (serialized as scripts inside CTxOuts)
  6. value of the output spent by this input (8-byte little endian)
  7. nSequence of the input (4-byte little endian)
  8. hashOutputs (32-byte hash)
  9. nLocktime of the transaction (4-byte little endian)
  10. sighash type of the signature (4-byte little endian)

This gets run for each input. Every part of this is fixed length, except for scriptCode, but there's no way to make one scriptCode be hashed by multiple inputs. There are three inputs based on variable-length information, hashPrevouts, hashSequence, and hashOutputs, but there's limited potential for mischief there. All methods of computing them either hash one input/output, or are shared by the entire transaction, or are all zeroes.

Validating very large BIP143 transactions will take linear time, and be dominated by signature verification. However, BIP143 transactions cannot be made right now, as segregated witness has not been accepted by the miners.

  • I understand that signatures can't be signed, I guess I don't know why the hash for each input Sig is different? If all sigs are removed prior to hashing, why isn't the whole blob hashed just once for the entire transaction? – pinhead Feb 9 '17 at 21:47
  • Because each hash is hashing something slightly different. The references of BIP143 go into more detail about this, but you should especially look at en.bitcoin.it/wiki/OP_CHECKSIG TL;DR: the input you're signing for has a part of the scriptPubKey of the previous transaction in it. This is consensus-critical; changing it requires a hardfork or the creation of a new way of signing transactions. – Nick ODell Feb 9 '17 at 22:28
  • But it's only critical to consensus for OP_CHECKSIG right? What if there was just a new op code that signed differently? – pinhead Feb 9 '17 at 22:31
  • That's only for OP_CHECKSIG, correct. The new opcode is a data push of one byte of 0 to 16. – Nick ODell Feb 9 '17 at 22:36
  • Right so why not add a OP_CHECKSIG2 and new tx/address type as a soft fork that hashes the whole tx minus sigs one time and uses that hash for each input? – pinhead Feb 9 '17 at 22:43
0

I don't think you can softfork CHECKSIG like that. Script would look like this

sig pubkey DUP HASH keyhash EQUALVERIFY NOPX/CHECKSIG2

New client would verify this and end up with a valid tx. Old client would do nothing at NOPX and end up with an invalid tx.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.