Author

Topic: Ultimate Replay Protection BIP (Read 383 times)

newbie
Activity: 18
Merit: 0
October 26, 2017, 01:45:11 PM
#5
> While this would work to make the transaction that spends these outputs to be
> replay protected, the transaction containing these outputs themselves are not
> replay protected. The output scripts of a transaction are not executed until
> they are spent from because output scripts are only partial scripts. So a
> transaction that creates such outputs could be replayed and such replay would
> cause loss of funds because the output would be unspendable on one chain.

What if to use the origin approach - to put opcode and block hash in scriptSig
of the consuming transaction - but only for SegWit transactions? So, that the
" OP_BLOCKHASHEXIST" is still present in scriptSig, but the
signatures (the witness data) are separate.

For P2PKH pre-hard fork output
Blockchain1x: scriptSig = OP_BLOCKHASHEXIST
Blockchain2x: scriptSig = OP_BLOCKHASHEXIST

In this case, the " OP_BLOCKHASHEXIST" prefix is signed
by witness signatures and cannot be altered.
staff
Activity: 3458
Merit: 6793
Just writing some code
October 26, 2017, 01:08:42 PM
#4
Agree. The " OP_BLOCKHASHEXIST" prefix should be part of
scriptPubKey of the newly created transaction. That is:

For new transaction that consumes P2PK, P2PKH or P2SH pre-hard fork output
Blockchain1x: scriptPubKey = OP_BLOCKHASHEXIST
Blockchain2x: scriptPubKey = OP_BLOCKHASHEXIST
While this would work to make the transaction that spends these outputs to be replay protected, the transaction containing these outputs themselves are not replay protected. The output scripts of a transaction are not executed until they are spent from because output scripts are only partial scripts. So a transaction that creates such outputs could be replayed and such replay would cause loss of funds because the output would be unspendable on one chain.
newbie
Activity: 18
Merit: 0
October 26, 2017, 12:21:44 PM
#3
> First of all, BIPs should be submitted to the bitcoin-dev mailing list
> and must be in the BIP format as specified in BIPs 1 and 2.

Agree. I'll do it after gathering some comments here.

> Also, the block hash should be pushed to the stack before OP_BLOCKHASHEXIST
> is called. Otherwise OP_BLOCKHASHEXIST cannot consume anything in its
> operation as the thing it is supposed to check comes after it is executed.

Agree. The sequence should be " OP_BLOCKHASHEXIST".

> Secondly, your proposal is flawed and does not provide replay protection.
> Scriptsig's are not protected by the digital signature so the data in a
> scriptsig other than the signature and public key can be modified without
> invalidating the transaction.

Agree. The " OP_BLOCKHASHEXIST" prefix should be part of
scriptPubKey of the newly created transaction. That is:

For new transaction that consumes P2PK, P2PKH or P2SH pre-hard fork output
Blockchain1x: scriptPubKey = OP_BLOCKHASHEXIST
Blockchain2x: scriptPubKey = OP_BLOCKHASHEXIST
staff
Activity: 3458
Merit: 6793
Just writing some code
October 26, 2017, 12:10:47 PM
#2
First of all, BIPs should be submitted to the bitcoin-dev mailing list and must be in the BIP format as specified in BIPs 1 and 2

Secondly, your proposal is flawed and does not provide replay protection. Scriptsig's are not protected by the digital signature so the data in a scriptsig other than the signature and public key can be modified without invalidating the transaction. So one could simply change the value for pushed after OP_BLOCKHASHEXIST to be the block for the other chain and the transaction would still be valid. Sure the txid would change, but it would still result in transaction replay in that essentially the same transaction is broadcast on both chains and results in the same spends on both chains.

Also, the block hash should be pushed to the stack before OP_BLOCKHASHEXIST is called. Otherwise OP_BLOCKHASHEXIST cannot consume anything in its operation as the thing it is supposed to check comes after it is executed.
newbie
Activity: 18
Merit: 0
October 26, 2017, 12:00:46 PM
#1
Ultimate Replay Protection BIP
==============================

I've just read the article by Jimmy Song "How to Protect Against Replay Attacks".
Link: https://bitcointechtalk.com/how-to-protect-against-replay-attacks-7a00bd2fe52f.
He explains possible replay protection approaches in case the hard fork does not
implement replay protection at all.

Jimmy Song suggested the below approaches:
  • Replay-protected UTXO (RePro-UTXO):
    Use coinbase-derived output (aka replay-protected UTXO) as one of the inputs
    of replay-protected transaction.
  • Simultaneous Submission
    Submit two transactions simultaneously, each for its own blockchain.
  • Utilizing locktime
    Helps in case one blockchain is longer that the other by (preferably)
    at leaset 6 blocks.

Unfortunately, all the above approaches are far from being ideal.
Why? Here's why...
Problems with replay protection approaches:
  • Replay-protected UTXO (RePro-UTXO):
    Privacy killer! All your own UTXO-s become tightly coupled with one RePro-UTXO
    or a (small) number of RePro-UTXO-s.
  • Simultaneous Submission
    May not work under heavy replay attack or needs to be repeated a number
    of times (headache!).
  • Utilizing locktime
    Does not help in case hard-forked blockchains grow at the same pace.

While, RePro-UTXO may be relatively easy implemented for exchanges,
it cannot be easily done by personal wallets, unless a market emerges
that trades RePro-UTXO-s for a low price.

So, I propose this BIP for ultimate replay-protection technique that can
be relatively easy implemented in Bitcoin Core and other projects.

A new script opcode is introduced "OP_BLOCKHASHEXIST" that makes
a transaction spendable only if the specific block hash exists
in the blockchain.

Let's assume that Bitcoin is hard-forked to blockchain1x and blockchain2x
and first mined blocks on both chains are block1x and block2x.

Then, to consume pre-hard fork P2PKH output on blockchain1x, the scriptPubKey
of the new consuming transaction will be:
scriptPubKey = OP_BLOCKHASHEXIST
and for blockchain2x, apparently:
scriptPubKey = OP_BLOCKHASHEXIST

The byte-cost for this replay-protection is 21 bytes (1-byte opcode and
20-byte hash) and this cost has to be paid only once per hard-fork (for every
pre-hard fork UTXO or a group of pre-hard fork UTXO-s).

This approach does not contaminate memory pool as the newly incoming transction
with non-existing may be dropped immediately.

Also, this approach does not increase the chance of DoS attack as block header
hashes take a small amount of memory (about 1MB per year: 6 * 24 * 365 / 1024).

I believe this BIP may be relatively easy implemented and, hopefully, will
be accepted by development community.
Jump to: