Skip to content

Instantly share code, notes, and snippets.

@Goatghosts
Last active March 15, 2026 10:05
Show Gist options
  • Select an option

  • Save Goatghosts/e1b71b7d5d1e9798fe724d373345fb9d to your computer and use it in GitHub Desktop.

Select an option

Save Goatghosts/e1b71b7d5d1e9798fe724d373345fb9d to your computer and use it in GitHub Desktop.
Many people know how to get a private key from a nonce. But I did not find information on how to get a nonce from a private key. If someone also does not know how to search, then here is a ready-made solution. And here is what I took as a basis: https://asecuritysite.com/ecdsa/ecd3
import ecdsa
import random
import libnum
import hashlib
G = ecdsa.SECP256k1.generator
ORDER = G.order()
def get_k_from_pkey(valid_pkey, sign, z):
s_inv = libnum.invmod(sign.s, ORDER)
return (s_inv * ((valid_pkey * sign.r) + z)) % ORDER
def get_pkey_from_k(valid_k, sign, z):
r_inv = libnum.invmod(sign.r, ORDER)
return (r_inv * ((valid_k * sign.s) - z)) % ORDER
def main():
valid_private_key = random.randrange(1, ORDER)
Public_key = ecdsa.ecdsa.Public_key(G, G * valid_private_key)
Private_key = ecdsa.ecdsa.Private_key(Public_key, valid_private_key)
valid_k = random.randrange(1, 2**127)
msg = "Hello"
z = int(hashlib.sha256(msg.encode()).hexdigest(), base=16)
sign = Private_key.sign(z, valid_k)
print("Sign")
print(f"R: {sign.r}")
print(f"S: {sign.s}")
print(f"Z: {z}")
print()
found_private_key = get_pkey_from_k(valid_k, sign, z)
assert found_private_key == valid_private_key
print(f"Private key: {valid_private_key} == {found_private_key}")
found_k = get_k_from_pkey(valid_private_key, sign, z)
assert found_k == valid_k
print(f"K (Nonce): {valid_k} == {found_k}")
if __name__ == "__main__":
main()
import ecdsa
import random
import libnum
import hashlib
G = ecdsa.SECP256k1.generator
ORDER = G.order()
def get_pkey_from_k(valid_k, r, s, z):
r_inv = libnum.invmod(r, ORDER)
return (r_inv * ((valid_k * s) - z)) % ORDER
def main():
priv = random.randrange(1, ORDER)
Public_key = ecdsa.ecdsa.Public_key(G, G * priv)
x1 = ecdsa.ecdsa.Private_key(Public_key, priv)
k1 = random.randrange(1, 2**127)
k2 = k1
z1 = int(hashlib.sha256("Hello".encode()).hexdigest(), base=16)
z2 = int(hashlib.sha256("Bye".encode()).hexdigest(), base=16)
sig1 = x1.sign(z1, k1)
sig2 = x1.sign(z2, k2)
r1, s1 = sig1.r, sig1.s
r2, s2 = sig2.r, sig2.s
print(f"Signature r={r1}, s={s1}, z={z1}")
print(f"Signature r={r2}, s={s2}, z={z2}")
valinv = libnum.invmod((s1 - s2), ORDER)
k1rec = ((z1 - z2) * valinv) % ORDER
print("K: ", k1)
print("K recovered ", k1rec)
print("Private key", priv)
recovery_priv = get_pkey_from_k(k1rec, r1, s1, z1)
print("Recovery private key", recovery_priv)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment