So (who would believe

it didn't work. can you please provide more signatures? like upto 10? I have a script to generate them if you want.
I can provide a million of them, but I feel like I'll be wasting my time.
Idk man, maybe i did something wrong in my script. can you verify that it randomly generates signatures with random utpo 200 bit key and nonce?
If you send me the sigs.json file (the output of the script) i can predict the private key using my other script.
import hashlib
import random
import os
import json
BIT_RANGE = 200
class EllipticCurve:
def __init__(self, name, p, a, b, g, n, h):
self.name = name
self.p = p
self.a = a
self.b = b
self.g = g
self.n = n
self.h = h
class ECDSA:
def __init__(self, curve):
self.curve = curve
def inverse_mod(self, k, p):
if k == 0:
raise ZeroDivisionError('division by zero')
if k < 0:
return p - self.inverse_mod(-k, p)
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = p, k
while r != 0:
quotient = old_r // r
old_r, r = r, old_r - quotient * r
old_s, s = s, old_s - quotient * s
old_t, t = t, old_t - quotient * t
return old_s % p
def point_add(self, point1, point2):
if point1 is None:
return point2
if point2 is None:
return point1
x1, y1 = point1
x2, y2 = point2
if x1 == x2 and y1 != y2:
return None
m = (y1 - y2) * self.inverse_mod(x1 - x2, self.curve.p) if x1 != x2 else \
(3 * x1 * x1 + self.curve.a) * self.inverse_mod(2 * y1, self.curve.p)
x3 = m * m - x1 - x2
y3 = y1 + m * (x3 - x1)
return (x3 % self.curve.p, -y3 % self.curve.p)
def scalar_mult(self, k, point):
if k % self.curve.n == 0 or point is None:
return None
if k < 0:
return self.scalar_mult(-k, (point[0], -point[1] % self.curve.p))
result = None
addend = point
while k:
if k & 1:
result = self.point_add(result, addend)
addend = self.point_add(addend, addend)
k >>= 1
return result
def make_keypair(self, private):
public_key = self.scalar_mult(private, self.curve.g)
return private, public_key
def hash_message(self, message):
message_hash = hashlib.sha512(message).digest()
e = int.from_bytes(message_hash, 'big')
return e >> (e.bit_length() - self.curve.n.bit_length())
def sign_message(self, private_key, message, nonce):
z = self.hash_message(message)
k = nonce
x, y = self.scalar_mult(k, self.curve.g)
r = x % self.curve.n
s = ((z + r * private_key) * self.inverse_mod(k, self.curve.n)) % self.curve.n
return r, s, z
def generate_signatures(self, priv, num_signatures=10):
sigs = []
for _ in range(num_signatures):
nonce = random.randrange(1, 2**BIT_RANGE)
note = str(os.urandom(25)) + str(nonce)
msg = bytes(note, 'utf-8')
private_key, public_key = self.make_keypair(priv)
r, s, z = self.sign_message(priv, msg, nonce)
sigs.append((z, r, s))
return sigs
def main():
curve = EllipticCurve(
'secp256k1',
p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
a=0,
b=7,
g=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
n=0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
h=1,
)
ecdsa = ECDSA(curve)
priv = random.randrange(2**(BIT_RANGE-1), 2**BIT_RANGE)
signatures = ecdsa.generate_signatures(priv)
with open("sigs.json", 'w') as f:
sigs_hex = [[hex(x) if isinstance(x, int) else x for x in sig] for sig in signatures]
json.dump(sigs_hex, f)
print(f"Private Key = {hex(priv)}")
if __name__ == "__main__":
main()