Calculate a valid signature

secp256k1signature

I am trying to create a signature that is valid on https://etherscan.io/verifySig, but it shows always that my signature is invalid:

enter image description here

I created a random private and public key:

private key: 0xb9b2098efa21fd9fa0595c589c8487af8e2feb96569d8ed7dea3d3942f9e86ee
public key: 0x9b6eafcfec58f95f3771d5c2f9042ff80e491fd04a3aa1a847e7fd8442f1ee8c197f65b0d783b8a6f4c5d5ceaa4c027bc7e3ee36706af488972690fab52434b3

The address should be:

address: 0x98f13dc425811444c9c288cf366acfaf7e3b6d52

Now I try to sign the message "Test_Signature" by using the equations provided here:
https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages

The message hash is calculated with eth_utils:

msg = b"Test_Signature"
h = eth_utils.keccak(msg)
h = int.from_bytes(h, "big")

After generating a random integer, I use the equations to calculate r, s, v directly:

from tinyec.ec import SubGroup, Curve


# secp256k1 properties
p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
n = 115792089237316195423570985008687907852837564279074904382605163141518161494337
G = (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424)

field = SubGroup(p=p, g=G, n=n, h=1)
curve = Curve(a=0, b=7, field=field, name='secp256k1')

# private key
priv_key = 83992441735806437997249052063040008803625856260092149954869332104473242142446

# public key
P = (70304058118741863582262393380291673246306160516057781381001139033552194760332, 11532912635836483492238225363108614691575607518644120117126194555700524627123)

# message hash
h = 87606763373646199415553583347194012180136404149033607198826021616865742156857

# random integer
k = 3721177852896846111935695432081468296180303375615453253386435739478984180396

R = k * curve.g
r = R.x
v = 27 + (R.y % 2)
s = pow(k, -1, n) * (h + r*priv_key) % n

The outputs are:

r: 29336491788943161357283692504069157144877470785894834840899135746381367540519
v: 27
s: 12775157475818852054720297346653863004672088843187914057777144577979593234619
r:  0x40dbddadd4d5faf1743ff01ddae18d12d5a61b3b230aee8dbb06b7179c20fb27
s:  0x1c3e7b9eda633d88aceff79ca9887e88022f1aeca2813784250e8ff4b62398bb
v:  0x1b
signature: 40dbddadd4d5faf1743ff01ddae18d12d5a61b3b230aee8dbb06b7179c20fb271c3e7b9eda633d88aceff79ca9887e88022f1aeca2813784250e8ff4b62398bb1b

Why is the signature marked as invalid on the website? Are there any errors in the calculation?

Best Answer

The problem was the wrongly calculated address.

signerPrivKey = eth_keys.keys.PrivateKey(priv_key.to_bytes(32, "big"))
signerPubKey = signerPrivKey.public_key
print("address: ", signerPubKey.to_checksum_address())
#address:  0xE144236EFb7932bDaE617eBAAFD24aF962152c77
Related Topic