This will enforce SCRIPT_VERIFY_LOW_S and SCRIPT_VERIFY_NULLDUMMY on all transactions when segwit is activated with BIP9
This PR replaces #8514
utACK 24c398f
needs 0.13.1 milestone tag?
64 | + 65 | +def highSifySig(sig): 66 | + assert(isCanonicalSig(sig)) 67 | + rsize = sig[3] 68 | + s = int.from_bytes(sig[6+rsize:-1], byteorder='big') 69 | + assert(s <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0)
Could we get constants for these long hex numbers?
166 | + assert mb_sig.raw[2] == 2 167 | + r_size = mb_sig.raw[3] 168 | + assert mb_sig.raw[4 + r_size] == 2 169 | + s_size = mb_sig.raw[5 + r_size] 170 | + s_value = int.from_bytes(mb_sig.raw[6+r_size:6+r_size+s_size], byteorder='big') 171 | + if s_value <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0:
Constants for these too?
@instagibbs edited
2383 | @@ -2384,9 +2384,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin 2384 | nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; 2385 | } 2386 | 2387 | - // Start enforcing WITNESS rules using versionbits logic. 2388 | + // Start enforcing WITNESS, NULLDUMMY, and LOW_S rules using versionbits logic. 2389 | if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus())) { 2390 | flags |= SCRIPT_VERIFY_WITNESS; 2391 | + flags |= SCRIPT_VERIFY_LOW_S;
A little worried this could allow some prankster to reorg testnet a huge amount. Side-effect of bundling the mainnet activation here.
An alternative is defining a separate BIP9 rollout for this, using the same bit on mainnet as segwit, but a different bit on testnet.
was exactly my thought. Kind of makes me cry for the 2 line SF, but oh well
There is currently no violating txs on testnet and we could start enforcing this on testnet now.
@instagibbs testnet is a testnet and it's being reorged massively all the time. In the last 3 months it's had about 3 major reorgs (>10,000 blocks). We should not be adding complexity for testnet.
@btcdrak it should not be policy to not care about massive reorgs and encourage them. That said, if testnet miners want to make sure none are included by softforking now, I wouldn't complain.
Ok the issue is moot now as rules are now enforced on testnet3.
tACK 26df793c3d94d3e0e9907f4455448e01f86e2dfa on my testnet pool
utACK
Tested ACK 26df793
Added script tests for some special S values
The newly added tests of 70fbd82 revealed some interesting properties of the current implementation of LOW_S. The LOW_S rule is enforced only if R and S are both below 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141. Otherwise, the CHECKSIG will return a False to the stack, instead of fail immediately.
You could find the examples here: https://github.com/jl2012/bips/blob/bip146outofrange/bip-0146.mediawiki#LOW_S
@jl2012 to clarify, the CHECKSIG operation can fail before a LOW_S signature is detected? Why is that an issue?
Is it because a LOW_S signature could get through conceivably if an alternative branch subsequently returns true?
Is that a bad thing? Or should we only allow canonical signatures to be allowed to be CHECKSIG'd? Meaning we'd need some kind of "pre-pass"...
@dcousens the problem is CHECKSIG won't fail immediately due to LOW_S if either R or S is out-of-range.
I think this is how it actually get processed:
So we have a weird condition that "if R overflows, we bypass LOW_S check"
Before this was discovered, we thought the rule was simply 0x01 <= S <= 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0. (as described in BIP62)
Now I have to use a page of text and examples to precisely describe it: https://github.com/jl2012/bips/blob/bip146outofrange/bip-0146.mediawiki#LOW_S and without any real use case. It is difficult to justify the softfork in current form.
We could fix that by, for example, making a simple byte-to-byte comparison with 0x7FFFF...20A0 , or fix the test in libsecp256k1. Or we could simply require a null signature for failed CHECKSIG operation (see #8634).
Having said that, there won't be any irreversible harm if the softfork had been done without this being discovered. It was still a softfork and it would work as we thought for 99.99999% of transactions on the blockchain. However, if an alternative implementation did not replicate this precisely, they would fork away due to the 0.00001% of transactions.
The plan is to do NULLDUMMY only (#8636), and leave LOW_S later, probably at the same time banning non-zero failing signature.
Please remove 0.13.1 tag