Low budget SegWit Safari
Low Budget SegWit Safari⌗
The Segregated Witness soft-fork (segwit) includes a wide range of features, some of which are documented and explored below.
BIP 141 - Segregated Witness (Consensus layer)
BIP 143 - Transaction Signature Verification for Version 0 Witness Program
BIP 144 - Segregated Witness (Peer Services)
BIP 173 - Base32 address format for native v0-16 witness outputs
Abstract from BIP 141⌗
This BIP defines a new structure called a "witness" that is committed to blocks separately from the transaction merkle tree. This structure contains data required to check transaction validity but not required to determine transaction effects. In particular, scripts and signatures are moved into this new structure.
The witness is committed in a tree that is nested into the block’s existing merkle root via the coinbase transaction for the purpose of making this BIP soft fork compatible. A future hard fork can place this tree in its own branch.
Motivation from BIP 141⌗
The entirety of the transaction’s effects are determined by output consumption (spends) and new output creation. Other transaction data, and signatures in particular, are only required to validate the blockchain state, not to determine it.
By removing this data from the transaction structure committed to the transaction merkle tree, several problems are fixed:
-
Nonintentional malleability becomes impossible. Since signature data is no longer part of the transaction hash, changes to how the transaction was signed are no longer relevant to transaction identification. As a solution of transaction malleability, this is superior to the canonical signature approach (BIP62):
-
It prevents involuntary transaction malleability for any type of scripts, as long as all inputs are signed (with at least one
CHECKSIG
orCHECKMULTISIG
operation) -
In the case of an m-of-n
CHECKMULTISIG
script, a transaction is malleable only with agreement of m private key holders (as opposed to only 1 private key holder with BIP62) -
It prevents involuntary transaction malleability due to unknown ECDSA signature malleability
-
It allows creation of unconfirmed transaction dependency chains without counterparty risk, an important feature for offchain protocols such as the Lightning Network
-
-
Transmission of signature data becomes optional. It is needed only if a peer is trying to validate a transaction instead of just checking its existence. This reduces the size of SPV proofs and potentially improves the privacy of SPV clients as they can download more transactions using the same bandwidth.
-
Some constraints could be bypassed with a soft fork by moving part of the transaction data to a structure unknown to current protocol, for example:
-
Size of witness could be ignored / discounted when calculating the block size, effectively increasing the block size to some extent
-
Hard coded constants, such as maximum data push size (520 bytes) or sigops limit could be reevaluated or removed
-
New script system could be introduced without any limitation from the existing script semantic. For example, a new transaction digest algorithm for transaction signature verification is described in BIP143
-
Problems SegWit sought to address⌗
Malleability⌗
This was a crucial problem to be fixed because many applications rely on monitoring the blockchain for specific a txid, or otherwise building chains of transactions on top of an unconfirmed transactions.
For example in Lightning the punishment transaction requires an immutable commitment txid so that in the event of fraud the breach rememdy transaction can be used by the honest party. The breach rememdy is a transaction that spends the output of the counterparty’s commitment transaction.
First party malleability (where the signer changes something related to the signature) is still possible. The primary focus of SegWit was to fix third party malleability.
Before segwit the data being hashed to generate the txid was the following:
nVersion | txins | txouts | nLockTime
…where signature data (scriptSigs) was embedded in the txins field.
After SegWit the following data is used to create the witness transaction id ("wtxid"):
nVersion | marker | flag | txins | txouts | witness | nLockTime
…where the signature data is taken out from txins
and put in its own witness
field. This is why a SegWit transaction’s txid, where the txins
now contain empty signatures, cannot be malleated by changing the signatures.
The marker MUST be a 1-byte zero value: 0x00
.
The flag MUST be a 1-byte non-zero value. Currently, 0x01
MUST be used.
A non-witness program (defined hereinafter) txin MUST be associated with an empty witness field, represented by a 0x00
. If all txins are not witness program, a transaction’s wtxid is equal to its txid.
Quadratic sighashing⌗
The issue is that it was previously possible to construct transactions that take a long time to verify.
To verify a transaction Bitcoin Core was required replacing the input script it was checking with the script of the output it was trying to spend, then (double) SHA256 the resulting transaction and check the signature signs the hash (source). The Bitcoin Core code was also making a new copy of the transaction for each new input (hash verification), also adding to the time required to verify.
This means that essentially sighash operations scaled at O(n2).
Segwit resolves this (for SegWit transactions only!) by changing the calculation of the transaction hash for signatures so that each byte of a transaction only needs to be hashed at most twice. This provides the same functionality more efficiently, so that large transactions can still be generated without running into problems due to signature hashing, even if they are generated maliciously or much larger blocks (and therefore larger transactions) are supported.
This is introduced as per BIP 143 "Transaction Signature Verification for Version 0 Witness Program".
This means that SegWit sighash operations scale linearly, O(n).
Better P2SH Security⌗
Multisig payments currently use P2SH which is secured by the 160-bit HASH160 algorithm (RIPEMD of SHA256). However, if one of the signers wishes to steal all the funds, they can find a collision between a valid address as part of a multisig script and a script that simply pays them all the funds with only 80-bits (280) worth of work, which is already within the realm of possibility for an extremely well-resourced attacker. (For comparison, at a sustained 1 exahash/second, the Bitcoin mining network does 80-bits worth of work every two weeks)
Segwit resolves this by using HASH160 only for payments direct to a single public key (where this sort of attack is useless), while using 256-bit SHA256 hashes for payments to a script hash.
Script Versioning⌗
Changes to Bitcoin’s script allow for both improved security and improved functionality. However, the design of script only allows backwards-compatible (soft-forking) changes to be implemented by replacing one of the ten extra OP_NOP
opcodes with a new opcode that can conditionally fail the script, but which otherwise does nothing. This is sufficient for many changes – such as introducing a new signature method or a feature like OP_CLTV
, but it is both slightly hacky (for example, OP_CLTV
usually has to be accompanied by an OP_DROP
) and cannot be used to enable even features as simple as joining two strings.
Segwit resolves this by including a version number for scripts, so that additional opcodes that would have required a hard-fork to be used in non-segwit transactions can instead be supported by simply increasing the script version.
This is acheived by attributing special meaning to witness
validation logic: if the witness
data begins with a 1 byte push opcode, which enables the range of (versions) 0 to 16 to be used and is then followed by a data push between 2 and 40 bytes it can take on special meanings:
-
If the
version
byte is0
and the witness program is 20 bytes:-
It is interpreted as a pay-to-witness-public-key-hash (P2WPKH) program.
-
The witness much consist of exactly 2 items (≤ 520 bytes each). The first one a signature, and the second one a public key.
-
The HASH160 of the public key must match the 20-byte witness program.
-
After normal script evaluation, the signature is verified against the public key with
CHECKSIG
operation. The verification must result in a singleTRUE
on the stack.
-
-
If the
version
byte is0
and the witness program is 32 bytes:-
It is interpreted as a pay-to-witness-script-hash (P2WSH) program.
-
The witness must consist of an input stack to feed to the script, followed by a serialized script (
witnessScripts
). -
The
witnessScript
(≤ 10,000 bytes) is popped off the initial witness stack. SHA256 of thewitnessScript
must match the 32-byte witness program. -
The
witnessScript
is deserialized, and executed after normal script evaluation with the remaining witness stack (≤ 520 bytes for each stack item). -
The script must not fail, and result in exactly a single
TRUE
on the stack.
-
-
If the
version
byte is0
, but the witness program is neither 20 nor 32 bytes, the script must fail. -
If the
version
byte is1
to16
, no further interpretation of the witness program or witness stack happens, and there is no size restriction for the witness stack. These versions are reserved for future extensions.
BIP 341 - Taproot: SegWit version 1 spending rules, builds on this very script upgradability assigning itself SegWit Version script Version 1. It details how taproot spends will use a combination of being SegWit version 1 plus a 32 byte witness program.