Author

Topic: How to convert High-S value to Low-S value? (Read 178 times)

legendary
Activity: 3444
Merit: 10558
August 06, 2020, 11:33:43 PM
#7
How do I replace it? I don’t get it. Is there step by step tutorial? My S value doesn’t look like anything like what your just sent.

with palpable integers:
Code:
N = 23
s = 18 -> -s = -18
-18 ≡ 5 (mod 23)

If you are doing this by hand, don't forget to change the length before the S value.
things like this should never be done by hand Smiley
you missed the sequence length in your first (high s) signature which should have been 0x45 and also it is easy to miss the data push size and scriptsig length that come before all this which should also be reduced by one (or more) each. the new s may also be smaller than 32 bytes and need another size (eg 0x19) or need the positive sign byte (0x00) if its highest bit is set.
staff
Activity: 3374
Merit: 6530
Just writing some code
How do I replace it? I don’t get it. Is there step by step tutorial? My S value doesn’t look like anything like what your just sent.
How are you making the signature? What software are you using?



Here is a signature with high S:
Code:
30440220534d4f17b88e62b097ba36720ecee6d3389d1192f2018546aa5d23bf2f234a27022100871b3da3d77564f2589fedfce761a42a912b186d78a4da291a2eaaacbf5eb31201
The S value is:
Code:
00871b3da3d77564f2589fedfce761a42a912b186d78a4da291a2eaaacbf5eb312

In python:
Code:
>>> hex(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - 0x00871b3da3d77564f2589fedfce761a42a912b186d78a4da291a2eaaacbf5eb312)
'0x78e4c25c288a9b0da7601203189e5bd42983c47936a3c612a5a3b3e010d78e2f'
The new signature with low S is
Code:
30440220534d4f17b88e62b097ba36720ecee6d3389d1192f2018546aa5d23bf2f234a27022078e4c25c288a9b0da7601203189e5bd42983c47936a3c612a5a3b3e010d78e2f01

If you are doing this by hand, don't forget to change the length before the S value.
copper member
Activity: 23
Merit: 32
divide s by N-s ?
Not quite. You simply make s equal to N-s.

If s is greater than N/2, then you would replace s with -s. Since we are using modular arthimetic, -s becomes N-s.

Here's the relevant text from BIP62:

The value S in signatures must be between 0x1 and 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0 (inclusive). If S is too high, simply replace it by S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S.

How do I replace it? I don’t get it. Is there step by step tutorial? My S value doesn’t look like anything like what your just sent.
legendary
Activity: 1946
Merit: 1427
divide s by N-s ?
Not quite. You simply make s equal to N-s.

If s is greater than N/2, then you would replace s with -s. Since we are using modular arthimetic, -s becomes N-s.

Here's the relevant text from BIP62:

The value S in signatures must be between 0x1 and 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0 (inclusive). If S is too high, simply replace it by S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S.
Sorry, you're right. Subtract is what it should've been :O, Not sure where i came up with divide (and s by N-s.. :O), Terrible!  Roll Eyes
legendary
Activity: 2268
Merit: 18586
divide s by N-s ?
Not quite. You simply make s equal to N-s.

If s is greater than N/2, then you would replace s with -s. Since we are using modular arthimetic, -s becomes N-s.

Here's the relevant text from BIP62:

The value S in signatures must be between 0x1 and 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0 (inclusive). If S is too high, simply replace it by S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S.
legendary
Activity: 1946
Merit: 1427
It seems like the most-used solution is to check if s > N/2, and if so, subtract N by S, so it becomes N-s

This library seems to support it, but i don't use python so don't quote me on that.
https://github.com/warner/python-ecdsa/search?q=sigencode_der_canonize&type=
Code: (src/ecdsa/util.py)
def sigencode_der_canonize(r, s, order):
    if s > order / 2:
        s = order - s
copper member
Activity: 23
Merit: 32
I created a bitcoin transaction but I'm getting an error when trying to broadcast it:

mandatory-script-verify-flag-failed (Non-canonical signature: S value is unnecessarily high) (code 16)

I googled it and seems the problem is that S value in ScriptSig is High. I didn't find a working method to convert my High-S value to Low-s value. Could someone help me with that? Any help would be appreciated and well rewarded Cheesy. Maybe there is some python script that can convert High-S value to Low.
Jump to: