2

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?

3
  • 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

1 Answer 1

4

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.