<p>As I suspected the error was the <code>+</code> sign on two points instead point addition is required, so I modified the code like this:</p>
<pre class="lang-python prettyprint-override"><code>def addp(P,Q):
    point1 = Point(curve, P[0], P[1])
    point2 = Point(curve, Q[0], Q[1])
    # Perform point addition
    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)
    a = addp(y,b)
    x = a % n
    # Check if the calculated point matches the R component of the signature
    if x == r:
        print(&quot;Signature is valid&quot;)
    else:
        print(&quot;Signature is invalid&quot;)
</code></pre>
<p>And it works.</p>

CC BY-SA 4.0
2023-10-08T13:46:51.190Z
2023-10-08T14:05:28.793Z
2023-10-08T14:05:28.793Z
Alexio puk2sefu
<p>Maybe I got the formula wrong but I heard that <code>x = (z*s^-1)*G+(r*s^-1)*K</code> is the equation for verifying an ECDSA signature but my code says signature is invalid but the values are from a valid bitcoin transaction.</p>
<pre class="lang-python prettyprint-override"><code>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(&quot;Signature is valid&quot;)
    else:
        print(&quot;Signature is invalid&quot;)

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
</code></pre>
<p>Given these:</p>
<pre class="lang-python prettyprint-override"><code>R=0x0089848a1c90ee587b1d8b71c9bafccbc072613e41b3fd38cc2b1cf3041e3792bc
S=0x45305be296870b32cca5dac0f0972cac820090214158652581f406fc70ef30f3
Z= 0x3d4a58fa8e5f94e9b8ed1d79a2d584ce45803153b75d43d7bcdbf49171d90992
priv1 = 1
</code></pre>
<p>When I do this:</p>
<pre class="lang-python prettyprint-override"><code>pk = bitcoin.fast_multiply(bitcoin.G, priv1)
verfy(R,S,pk,Z)
</code></pre>
<p>I get signature is invalid but why?
What am I doing wrong?</p>

CC BY-SA 4.0
2023-10-08T11:25:58.870Z
What is the module `bitcoin` you are using? That would be helpful for anyone who wants to reproduce the problem.
Pieter Wuille
CC BY-SA 4.0
2023-10-08T13:02:18.373Z
@PieterWuille standard bitcoin module, just imported via import bitcoin and pip install
Alexio puk2sefu
CC BY-SA 4.0
2023-10-08T13:04:41.007Z
i think the culprit is y = a+b which should be ECC point addition
Alexio puk2sefu
<signature><python><ecdsa><message-verification>
How to manually verify an ECDSA signature in Python?
Alexio puk2sefu
# How to manually verify an ECDSA signature in Python?

(Asked by: username_0 on 2023-10-08)

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?

**Tags:** signature, python, ecdsa, message-verification

> **Comments:**
> **username_1**: What is the module `bitcoin` you are using? That would be helpful for anyone who wants to reproduce the problem.  
> **username_0**: @PieterWuille standard bitcoin module, just imported via import bitcoin and pip install  
> **username_0**: i think the culprit is y = a+b which should be ECC point addition  

---

## 1 answers

### Answer by username_0 on 2023-10-08. Score: 4 | Accepted answer

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])
    # Perform point addition
    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)
    a = addp(y,b)
    x = a % 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")

And it works.


---

