Changeset View
Changeset View
Standalone View
Standalone View
doc/abc/replay-protected-sighash.md
# BUIP-HF Digest for replay protected signature verification across hard forks | # BUIP-HF Digest for replay protected signature verification across hard forks | ||||
Version 1.2, 2017-07-16 | Version 1.2, 2017-07-16 | ||||
## Abstract | ## Abstract | ||||
This document describes proposed requirements and design for a reusable signing mechanism ensuring replay protection in the event of a hard fork. It provides a way for users to create transactions which are invalid on forks lacking support for the mechanism and a fork-specific ID. | This document describes proposed requirements and design for a reusable signing mechanism ensuring replay protection in the event of a hard fork. It provides a way for users to create transactions which are invalid on forks lacking support for the mechanism and a fork-specific ID. | ||||
The proposed digest algorithm is adapted from BIP143[[1]](#bip143) as it minimizes redundant data hashing in verification, covers the input value by the signature and is already implemented in a wide variety of applications[[2]](#bip143Motivation). | The proposed digest algorithm is adapted from [BIP143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki) as it minimizes redundant data hashing in verification, covers the input value by the signature and is already implemented in a [wide variety of applications](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Motivation). | ||||
The proposed digest algorithm is used when the `SIGHASH_FORKID` bit is set in the signature's sighash type. The verification of signatures which do not set this bit is not affected. | The proposed digest algorithm is used when the `SIGHASH_FORKID` bit is set in the signature's sighash type. The verification of signatures which do not set this bit is not affected. | ||||
## Specification | ## Specification | ||||
### Activation | ### Activation | ||||
The proposed digest algorithm is only used when the `SIGHASH_FORKID` bit in the signature sighash's type is set. It is defined as follows: | The proposed digest algorithm is only used when the `SIGHASH_FORKID` bit in the signature sighash's type is set. It is defined as follows: | ||||
````cpp | ````cpp | ||||
// ... | // ... | ||||
SIGHASH_SINGLE = 3, | SIGHASH_SINGLE = 3, | ||||
SIGHASH_FORKID = 0x40, | SIGHASH_FORKID = 0x40, | ||||
SIGHASH_ANYONECANPAY = 0x80, | SIGHASH_ANYONECANPAY = 0x80, | ||||
// ... | // ... | ||||
```` | ```` | ||||
In presence of the `SIGHASH_FORKID` flag in the signature's sighash type, the proposed algorithm is used. | In presence of the `SIGHASH_FORKID` flag in the signature's sighash type, the proposed algorithm is used. | ||||
Signatures using `SIGHASH_FORKID` must be rejected before [UAHF](https://github.com/Bitcoin-UAHF/spec/blob/master/uahf-technical-spec.md) is activated. | Signatures using `SIGHASH_FORKID` must be rejected before [UAHF](uahf-technical-spec.md) is activated. | ||||
In order to ensure proper activation, the reference implementation uses the `SCRIPT_ENABLE_SIGHASH_FORKID` flag when executing `EvalScript` . | In order to ensure proper activation, the reference implementation uses the `SCRIPT_ENABLE_SIGHASH_FORKID` flag when executing `EvalScript` . | ||||
### Digest algorithm | ### Digest algorithm | ||||
The proposed digest algorithm computes the double SHA256 of the serialization of: | The proposed digest algorithm computes the double SHA256 of the serialization of: | ||||
1. nVersion of the transaction (4-byte little endian) | 1. nVersion of the transaction (4-byte little endian) | ||||
2. hashPrevouts (32-byte hash) | 2. hashPrevouts (32-byte hash) | ||||
3. hashSequence (32-byte hash) | 3. hashSequence (32-byte hash) | ||||
4. outpoint (32-byte hash + 4-byte little endian) | 4. outpoint (32-byte hash + 4-byte little endian) | ||||
5. scriptCode of the input (serialized as scripts inside CTxOuts) | 5. scriptCode of the input (serialized as scripts inside CTxOuts) | ||||
6. value of the output spent by this input (8-byte little endian) | 6. value of the output spent by this input (8-byte little endian) | ||||
7. nSequence of the input (4-byte little endian) | 7. nSequence of the input (4-byte little endian) | ||||
8. hashOutputs (32-byte hash) | 8. hashOutputs (32-byte hash) | ||||
9. nLocktime of the transaction (4-byte little endian) | 9. nLocktime of the transaction (4-byte little endian) | ||||
10. sighash type of the signature (4-byte little endian) | 10. sighash type of the signature (4-byte little endian) | ||||
Items 1, 4, 7 and 9 have the same meaning as in the original algorithm[[3]](#OP_CHECKSIG). | Items 1, 4, 7 and 9 have the same meaning as in the [original algorithm](https://en.bitcoin.it/wiki/OP_CHECKSIG). | ||||
#### hashPrevouts | #### hashPrevouts | ||||
* If the `ANYONECANPAY` flag is not set, `hashPrevouts` is the double SHA256 of the serialization of all input outpoints; | * If the `ANYONECANPAY` flag is not set, `hashPrevouts` is the double SHA256 of the serialization of all input outpoints; | ||||
* Otherwise, `hashPrevouts` is a `uint256` of `0x0000......0000`. | * Otherwise, `hashPrevouts` is a `uint256` of `0x0000......0000`. | ||||
#### hashSequence | #### hashSequence | ||||
Show All 18 Lines | |||||
#### hashOutputs | #### hashOutputs | ||||
* If the sighash type is neither `SINGLE` nor `NONE`, `hashOutputs` is the double SHA256 of the serialization of all output amount (8-byte little endian) with `scriptPubKey` (serialized as scripts inside CTxOuts); | * If the sighash type is neither `SINGLE` nor `NONE`, `hashOutputs` is the double SHA256 of the serialization of all output amount (8-byte little endian) with `scriptPubKey` (serialized as scripts inside CTxOuts); | ||||
* 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; | * 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; | ||||
* Otherwise, `hashOutputs` is a `uint256` of `0x0000......0000`. | * Otherwise, `hashOutputs` is a `uint256` of `0x0000......0000`. | ||||
Notes: | Notes: | ||||
1. In the [original algorithm][3], a `uint256` of `0x0000......0001` is committed if the input index for a `SINGLE` signature is greater than or equal to the number of outputs. In this BIP a `0x0000......0000` is committed, without changing the semantics. | 1. In the [original algorithm](https://en.bitcoin.it/wiki/OP_CHECKSIG), a `uint256` of `0x0000......0001` is committed if the input index for a `SINGLE` signature is greater than or equal to the number of outputs. In this BIP a `0x0000......0000` is committed, without changing the semantics. | ||||
#### sighash type | #### sighash type | ||||
The sighash type is altered to include a 24-bit *fork id* in its most significant bits. | The sighash type is altered to include a 24-bit *fork id* in its most significant bits. | ||||
````cpp | ````cpp | ||||
ss << ((GetForkID() << 8) | nHashType); | ss << ((GetForkID() << 8) | nHashType); | ||||
```` | ```` | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | ````cpp | ||||
} else { | } else { | ||||
// Drop the signature in scripts when SIGHASH_FORKID is not used. | // Drop the signature in scripts when SIGHASH_FORKID is not used. | ||||
scriptCode.FindAndDelete(CScript(vchSig)); | scriptCode.FindAndDelete(CScript(vchSig)); | ||||
} | } | ||||
```` | ```` | ||||
## Note | ## Note | ||||
In the UAHF, a `fork id` of 0 is used (see [[4]](#uahfspec) REQ-6-2 NOTE 4), i.e. | In the UAHF, a `fork id` of 0 is used (see [UAHF Technical Specification](uahf-technical-spec.md) REQ-6-2 NOTE 4), i.e. | ||||
the GetForkID() function returns zero. | the GetForkID() function returns zero. | ||||
In that case the code can be simplified to omit the function. | In that case the code can be simplified to omit the function. | ||||
## References | |||||
<a name="bip143">[1]</a> https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki | |||||
<a name="bip143Motivation">[2]</a> https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Motivation | |||||
<a name="OP_CHECKSIG">[3]</a> https://en.bitcoin.it/wiki/OP_CHECKSIG | |||||
<a name="uahfspec">[4]</a> https://github.com/Bitcoin-UAHF/spec/blob/master/uahf-technical-spec.md |