Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello!
Problem
As you know, due to BIP-146 https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki#user-content-LOW_S, we should use only a lower S
And there is a check in the code (
if lengthS == 33 {...}
) that converts higher S to lower S, but there are a few problems with itAbout second problem: sometimes, with some circumstances, after this check and calculating lower S, encoded lower S has length 31 bytes (that is valid for S too), but
encodeBigInt
function in this case unconditionally adds a leading zero byte, to make length equal 32 bytes, and if before adding zero byte, the s signature had leading byte less than 0x7F byte (that means that we have zero leading bit and is being considered as a positive), it leads to-26: mandatory-script-verify-flag-failed (Non-canonical DER signature)
in bitcoinThis check fails https://github.com/bitcoin/bitcoin/blob/80ad135a5e54e8a065fee5ef36e57034679111ab/src/script/interpreter.cpp#L159
Solution
So the solution in this MR is to explicitly check if we have a high S at the start, and if so, we calculating the low S at this point, and after that we don't need to have check of
if lengthS == 33 {...}