Post
Topic
Board Development & Technical Discussion
Re: I found a method to reverse public keys to private keys
by
dexizer7799
on 02/05/2025, 06:59:50 UTC
Test this script, it created by me, this can recover up to 249 bits for up to 256 private key.

https://github.com/dexizer7799/lattice-attack-secp256k1


Hello. Looks like topic deleted. Nothing to try. Can you provide script for testing?


Hi yes I can provide that script write to me personal message.

Hi ,

I hope this message finds you well. I came across your project that involves recovering up to 249 bits for a 256-bit private key. Unfortunately, I found that the GitHub link you provided is not working.

Would you be able to share the script with me directly? I would really appreciate it, as I’m very interested in your work.

Thank you for your time!

Best regards,

fix this >>>User 'dexizer7799' has not chosen to allow messages from newbies. You should post in their relevant thread to remind them to enable this setting. 

This script will recover full random nonces with up to 249, sometimes 250 bits and up to 256 bits private key.

Quote
"""

This code created by Dexizer

It will recover Ecdsa Secp256K1 private key up to 249 bits and with up to 256 bits k nonces.

"""

import random

p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
K = GF(p)
a = K(0x0000000000000000000000000000000000000000000000000000000000000000)
b = K(0x0000000000000000000000000000000000000000000000000000000000000007)
E = EllipticCurve(K, (a, b))
G = E(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)

q = E.order()

n = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

def identityPlus2(u, elem=1):
   result = [[0] * (u + 2) for _ in range(u)]
   
   for i in range(u):
      result = elem
   
   return result

def basis():
   matrix = identityPlus2(len(signatures), p)
   
   t = []
   
   for signature in signatures:
      t.append(signature[0] * inverse_mod(signature[1], p))
   
   t.append(B / q)
   t.append(0)
   
   a = []
   
   for signature in signatures:
      a.append(signature[2] * inverse_mod(signature[1], p))
   
   a.append(0)
   a.append(B)
   
   matrix.append(t)
   matrix.append(a)

   return Matrix(QQ, matrix)

def attack():
   M = basis()
   
   positiveKeys = []
   unPositiveKeys = []
   
   for r in M.LLL():
      for key in r:
         key = int(key)
      
         if key != 0 and key != q:
            if key > 0:
               positiveKeys.append(key)
            else:
               unPositiveKeys.append(key)

   recoveredPrivateKey = 0
   
   for key in positiveKeys:
      for signature in signatures:
         if key != 0:
            d = int((signature[1] * Mod(key, p) - signature[2]) * inverse_mod(signature[0], p))
            
            if d == secret:
               recoveredPrivateKey = d
   
   if recoveredPrivateKey == 0:
      k = M.LLL()[1][0]
   
      if k != 0:
         recoveredPrivateKey = (signatures[0][1] * Mod(k, p) - signatures[0][2]) * inverse_mod(signatures[0][0], p)

   return int(recoveredPrivateKey)

num = 180

secret = random.randrange(1, n)

Q = secret * G

print('Private Key:', secret, 'Bit Length:', int(secret).bit_length())

print()

kbits = 249

B = 1

z = [random.randrange(1, n) for i in range(num)]
nonces = [random.randrange(1, 2 ** kbits) for i in range(num)]
sigsR = [int((G * int(nonces)).xy()[0]) for i in range(num)]
modInvNonces = [inverse_mod(nonces, p) for i in range(num)]
sigsS = [(z + secret * sigsR) * modInvNonces % n for i in range(num)]
sinv = [inverse_mod(s, p) for s in sigsS]

signatures = []

for i in range(len(sigsR)):
   signatures.append([sigsR, sigsS, z])

d = attack()

print('Recovered Private Key:', d, 'Bit Length:', int(d).bit_length())

if d == secret:
   print()
   print('Private Key Found!!!')
   print('Private Key Successfully Recovered:', d, 'Bit Length:', int(d).bit_length())