I have a script that converts a bitcoin private key into x and y coordinate with parameters of a Secp256k1 curve. Here's the script:
a = 0
b = 7
#Order of the finite field
prime = 2**256 - 2**32 - 977
#G coordinates
gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
#Order of the group G
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
#n -1 => is the number of all possible private keys
def addition(currentX, currentY, gx, gy, a, b, prime):
if gy == 0:
return (None, None)
elif currentX is None and currentY is None:
return (gx, gy)
elif currentX == gx and currentY != gy:
return (None, None)
elif currentX == gx and currentY == gy and currentY == 0:
return (None, None)
elif currentX == gx and currentY == gy:
s1 = (3 * pow(gx, 2, prime) + a) % prime
s2 = (gy * 2) % prime
s = (s1 * pow(s2, (prime - 2), prime)) % prime
currentX = (s ** 2 - 2 * gx) % prime
currentY = (s * (gx - currentX) - gy) % prime
elif currentX != gx:
s1 = (currentY - gy)
s2 = (currentX - gx)
s = (s1 * pow(s2, (prime - 2), prime)) % prime
currentX = ((s ** 2) - gx - currentX) % prime
currentY = ((s * (gx - currentX)) - gy) % prime
return (currentX, currentY)
def secp256k1BinaryExpansion(privateKey, gx, gy, a, b, prime):
if pow(gy, 2, prime) != (pow(gx, 3, prime) + a * gx + b) % prime:
return "The point is not on the curve"
counter = 0
coef = privateKey
currentX, currentY = gx, gy
resultX, resultY = None, None
while coef:
if coef & 1:
resultX, resultY = addition(resultX, resultY, currentX, currentY, a, b, prime)
counter += 1
currentX, currentY = addition(currentX, currentY, currentX, currentY, a, b, prime)
counter <<= 1
coef >>= 1
print("Counter", hex(counter))
return (resultX, resultY)
priv = 0x45300f2b990d332c0ee0efd69f2c21c323d0e2d20e7bfa7b1970bbf169174c82
xPub, yPub = secp256k1BinaryExpansion(priv, gx, gy, a, b, prime)
However I cannot correctly count how many addition there has been after the function is completed. By definition, there has to be
0x45300f2b990d332c0ee0efd69f2c21c323d0e2d20e7bfa7b1970bbf169174c82
additions (The same number as the private key). The counter
variable in the function counts how many times the addition has been made. However the print("Counter", hex(counter))
outputs:
0x4132e8968fdd0e98de5fde704b470bc4c38434f96bf7077034ccb099d4f00ca2
Which is incorrect. How to fix that error?
counter
- was that deliberate? (bit-shifting a counter rarely makes sense IMHO)