We have
- the ECDSA equation ([1])
- Base64 signature with a recid so we had:
- r = 0x37bb22d3f7afe8668e9b28561332d9e3734a8139bfe139d2c094741456403609
- s = 0x50ca4a3efdeb86e9252b4c32114d77ae71911f4f5ed3ce13e5f82bdfd30658ab
- v = 0x01
- z aka e is calculated easily from the message: 0xfb917a8e7c3dd70b329d7671cc388329749f5e90a39b7f2670a1311e90bb516a
- k = 2020
Also the above equation could be changed to by knowing the basic properties of modular arithmetic:
s*k=z+rdA (mod n) => s*k - z = rdA (mod n) => (s*k - z)r-1 = dA (mod n)
First thing to know is that all of the above is "modular arithmetic" so x-1 or 1/x is not as simple as 1 divided by x. It is modular multiplicative inverse. That means 1/2 (mod n) is not 0.5 but instead it is 57896044618658097711785492504343953926418782139537452191302581570759080747169
ModInverse() method is found in all cryptography libraries.
With that we can calculate dA (that is the private key) as
By the way when redid-27 is bigger than 4 that means the compressed public key was used.
So something must have been wrong. It takes us back to recid. recid-27 is 5 and when you subtract 4 (the fixed value added to indicate compressed public key) you'll get 1. This could be an indication that negative s was used instead.
As I posted above, In bitcoin to prevent malleability there is a consensus rule that mandates usage of low S values in signatures. Which is basically a simple modular subtraction.
With the new (s = secp256k1.N - s) we get a new key value:
But where is the reward?
A single private key corresponds to a single public key point and from that public key you can create multiple script types (for simplicity addresses) one of which is P2WPKH which is known as a native SegWit address.
public key: 022c17a18e7e6b625506ee24f09ed0e4475ae399cd7b16d25693490c07ab2fe94f
address: bc1qyt8g2aucnnd00wmwruxzw6eluf5ut4cmd0ljuz
And the final "mystery" was that if you look at the private key posted here more closely or with another "eye" you can see that it is a simple human readable string! All you have to do is to convert the base58 or base16 to UTF8 to get: