# How to manually verify an ECDSA signature in Python?

Maybe I got the formula wrong but I heard that `x = (z*s^-1)*G+(r*s^-1)*K` is the equation for verifying an ECDSA signature but my code says signature is invalid but the values are from a valid bitcoin transaction.

``````def gensig(d,k,h):
x = bitcoin.fast_multiply(bitcoin.G, k)
r = x[0] % n
k_inv = mod_inverse(k, n)
s = (k_inv * (h+(r*d))) % n
return r,s

def verfy(r,s,pk,h):
# Verify the signature
w = mod_inverse(s, n) # Calculate the modular multiplicative inverse of s
u = (h * w) % n
v = (r * w) % n
y = bitcoin.fast_multiply(bitcoin.G, u)
b= bitcoin.fast_multiply(pk, v)
a = y+b
x =a[0] % n
# Check if the calculated point matches the R component of the signature
if x == r:
print("Signature is valid")
else:
print("Signature is invalid")

def solve_k(h, r, x, s, n):
# Calculate the modular multiplicative inverse of s modulo n
s_inverse = mod_inverse(s, n)

if s_inverse is None:
return None  # No modular inverse exists

# Calculate k using the formula
k = (h + r *x ) * s_inverse % n
return k

def solve_d(s, k, h, r, n):
rinv = mod_inverse(r, n)
d = (((s * k) - h) * rinv) % n
return d
``````

Given these:

``````R=0x0089848a1c90ee587b1d8b71c9bafccbc072613e41b3fd38cc2b1cf3041e3792bc
S=0x45305be296870b32cca5dac0f0972cac820090214158652581f406fc70ef30f3
Z= 0x3d4a58fa8e5f94e9b8ed1d79a2d584ce45803153b75d43d7bcdbf49171d90992
priv1 = 1
``````

When I do this:

``````pk = bitcoin.fast_multiply(bitcoin.G, priv1)
verfy(R,S,pk,Z)
``````

I get signature is invalid but why? What am I doing wrong?

• What is the module `bitcoin` you are using? That would be helpful for anyone who wants to reproduce the problem. Oct 8, 2023 at 11:25
• @PieterWuille standard bitcoin module, just imported via import bitcoin and pip install Oct 8, 2023 at 13:02
• i think the culprit is y = a+b which should be ECC point addition Oct 8, 2023 at 13:04

As I suspected the error was the `+` sign on two points instead point addition is required, so I modified the code like this:

``````def addp(P,Q):
point1 = Point(curve, P[0], P[1])
point2 = Point(curve, Q[0], Q[1])
result_point = point1 + point2
return result_point.x()

def dub(Q):
point1 = Point(curve, Q[0], Q[1])
# Perform point doubling
result_point = point1.double()
return result_point

def verfy(r,s,pk,z):
# Verify the signature
w = mod_inverse(s, n) # Calculate the modular multiplicative inverse of s
u = (z * w) % n
v = (r * w) % n
y = bitcoin.fast_multiply(bitcoin.G, u)
b= bitcoin.fast_multiply(pk, v)