def recover_secret(shares): p_count = len(shares) x_s, y_s = zip(*shares) # Use lagrange interpolation product = lambda vals: reduce(lambda x, y: x*y, vals) nums = []; dens = []; for i in range(p_count): others = list(x_s) cur = others.pop(i) nums.append(product(0 - o for o in others)) dens.append(product(cur - o for o in others)) den = product(dens) num = sum([nums[i] * den * y_s[i] * inv(dens[i], P) % P for i in range(p_count)]) return num * inv(den, P) % P
def ecdsa_raw_sign_one_to_one(msghash, sender_priv, receiver_pub): z = bitcoin.hash_to_int(msghash) k = bitcoin.deterministic_generate_k(msghash, sender_priv) r, y = bitcoin.fast_multiply(bitcoin.decode_pubkey(receiver_pub), k) s = bitcoin.inv(k, N) * (z + r * bitcoin.decode_privkey(sender_priv)) % N v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < N else 1)), r, s if s * 2 < N else N - s return v, r, s
def lagrange_interpolate(x,y,n): k=len(y) constant=0 for j in range(k): numerator,denominator=1,1 for m in range(k): if(j != m): numerator = (numerator * x[m]) % n denominator = (denominator * (x[m]-x[j])) % n lsum = (y[j] * numerator * bitcoin.inv(denominator,n)) % n constant=(constant+lsum) % n return constant
def ecdsa_raw_verify_one_to_one(msghash, vrs, sender_pub, receiver_priv): v, r, s = vrs w = bitcoin.inv(s, N) z = bitcoin.hash_to_int(msghash) u1, u2 = z * w % N, r * w % N receiver_pub = bitcoin.decode_pubkey(bitcoin.privtopub(receiver_priv)) receiver_sender_shared = bitcoin.fast_multiply( bitcoin.decode_pubkey(sender_pub), bitcoin.decode_privkey(receiver_priv)) u1Qr = bitcoin.fast_multiply(receiver_pub, u1) u2Qs = bitcoin.fast_multiply(receiver_sender_shared, u2) x, y = bitcoin.fast_add(u1Qr, u2Qs) return bool(r == x and (r % N) and (s % N))
def sign_donation_tx(tx, i, priv): k = sign_k hashcode = btc.SIGHASH_ALL i = int(i) if len(priv) <= 33: priv = btc.safe_hexlify(priv) pub = btc.privkey_to_pubkey(priv) address = btc.pubkey_to_address(pub) signing_tx = btc.signature_form(tx, i, btc.mk_pubkey_script(address), hashcode) msghash = btc.bin_txhash(signing_tx, hashcode) z = btc.hash_to_int(msghash) #k = deterministic_generate_k(msghash, priv) r, y = btc.fast_multiply(btc.G, k) s = btc.inv(k, btc.N) * (z + r*btc.decode_privkey(priv)) % btc.N rawsig = 27+(y % 2), r, s sig = btc.der_encode_sig(*rawsig)+btc.encode(hashcode, 16, 2) #sig = ecdsa_tx_sign(signing_tx, priv, hashcode) txobj = btc.deserialize(tx) txobj["ins"][i]["script"] = btc.serialize_script([sig, pub]) return btc.serialize(txobj)
def sign(tx_hash: bytes, private_key: str): msg_hash = tx_hash z = bitcoin.hash_to_int(msg_hash) k = bitcoin.deterministic_generate_k(msg_hash, private_key) r, y = bitcoin.fast_multiply(bitcoin.G, k) s = bitcoin.inv(k, bitcoin.N) * ( z + r * bitcoin.decode_privkey(private_key)) % bitcoin.N v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < bitcoin.N else 1) ), r, s if s * 2 < bitcoin.N else bitcoin.N - s if 'compressed' in bitcoin.get_privkey_format(private_key): v += 4 hex_str_r = hex(r)[2:] if len(hex_str_r) < 64: hex_str_r = ((64 - len(hex_str_r)) * "0") + hex_str_r hex_str_s = hex(s)[2:] if len(hex_str_s) < 64: hex_str_s = ((64 - len(hex_str_s)) * "0") + hex_str_s signature = hex_str_r + hex_str_s recovery = v - 27 return signature, recovery
def sign_donation_tx(tx, i, priv): k = sign_k hashcode = btc.SIGHASH_ALL i = int(i) if len(priv) <= 33: priv = btc.safe_hexlify(priv) pub = btc.privkey_to_pubkey(priv) address = btc.pubkey_to_address(pub) signing_tx = btc.signature_form(tx, i, btc.mk_pubkey_script(address), hashcode) msghash = btc.bin_txhash(signing_tx, hashcode) z = btc.hash_to_int(msghash) #k = deterministic_generate_k(msghash, priv) r, y = btc.fast_multiply(btc.G, k) s = btc.inv(k, btc.N) * (z + r * btc.decode_privkey(priv)) % btc.N rawsig = 27 + (y % 2), r, s sig = btc.der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2) #sig = ecdsa_tx_sign(signing_tx, priv, hashcode) txobj = btc.deserialize(tx) txobj["ins"][i]["script"] = btc.serialize_script([sig, pub]) return btc.serialize(txobj)
def ecdsa_sign_k(z, d, k): r, y = bitcoin.fast_multiply(bitcoin.G, k) s = bitcoin.inv(k, bitcoin.N) * (z + r * d) % bitcoin.N v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < bitcoin.N else 1) ), r, s if s * 2 < bitcoin.N else bitcoin.N - s return v, r, s
r, y = bitcoin.fast_multiply(bitcoin.G, k) s = bitcoin.inv(k, bitcoin.N) * (z + r * d) % bitcoin.N v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < bitcoin.N else 1) ), r, s if s * 2 < bitcoin.N else bitcoin.N - s return v, r, s # Generate secret key & the corresponding public key and address sk = random.SystemRandom().randrange(1, bitcoin.N) Q = bitcoin.fast_multiply(bitcoin.G, sk) # Sign 2 differents messages with same k signing_k = random.SystemRandom().randrange(1, bitcoin.N) z1 = bitcoin.hash_to_int(hashlib.sha256('first_message').hexdigest()) z2 = bitcoin.hash_to_int(hashlib.sha256('second_message').hexdigest()) v1, r1, s1 = ecdsa_sign_k(z1, sk, signing_k) v2, r2, s2 = ecdsa_sign_k(z2, sk, signing_k) assert r1 == r2 print('+ R used = {:x}'.format(r1)) # Calculate k candidates k_candidates = [(z1 - z2) * bitcoin.inv(s1 - s2, bitcoin.N) % bitcoin.N, (z1 - z2) * bitcoin.inv(s1 + s2, bitcoin.N) % bitcoin.N] for k in k_candidates: priv_key = (s1 * k - z1) * bitcoin.inv(r1, bitcoin.N) % bitcoin.N if bitcoin.fast_multiply(bitcoin.G, priv_key) == Q: print('+ Calc key = {0}'.format(priv_key)) break else: print('An unknown error occured.')
assert pow(root, 3, p) == a % p return root if (p % 9) == 7: root = pow(a, (p + 2) / 9, p) assert pow(root, 3, p) == a % p return root else: print "Not implemented yet. See the second paper" # Generate secret key & the corresponding public key and address d = random.SystemRandom().randrange(1, N) (x, y) = fast_multiply(G, d) # Double Q, works only when A = 0 in ECDSA curve Q2 = ((9 * x**4 * inv(4 * y**2, P) - (2 * x)) % P, (9 * x**3 * inv(2 * y, P) - (27 * x**6) * inv(8 * y**3, P) - y) % P) assert Q2 == fast_multiply(G, d * 2) # Double and triple Qx, works only for secp256k1 curve Q2x = ((x**4 - 56 * x) * inv(4 * x**3 + 28, P)) % P Q3x = ( (x**9 - 672 * x**6 + 2352 * x**3 + 21952) * inv(9 * x**2 * (x**3 + 28)**2, P)) % P assert Q2x == fast_multiply(G, d * 2)[0] assert Q3x == fast_multiply(G, d * 3)[0] # Double Qx and add G Q2xp1 = (((Q2[0] * G[0]) * (Q2[0] + G[0]) - 2 * Q2[1] * G[1] + 14) * inv( (Q2[0] - G[0])**2, P)) % P assert Q2xp1 == fast_multiply(G, (d * 2) + 1)[0]
from bitcoin import fast_add, fast_multiply, G, hash_to_int, inv, N from hashlib import sha256 from random import SystemRandom # Generate secret key & the corresponding public key and address d = SystemRandom().randrange(1, N) Q = fast_multiply(G, d); # Choose a 2 random numbers a = SystemRandom().randrange(1, N) b = SystemRandom().randrange(1, N) # calculate a signature r = fast_add(fast_multiply(G, a), fast_multiply(Q, b))[0] s = r * inv(b, N) # Calculate the hash corresponding to the signature (r,s) h = a * r * inv(b, N) # calculate the hash of the message we want to sign z = hash_to_int(sha256('0xDEADBEEF').hexdigest()) # re-calculate s to sign z s_p = s * (z + d*r) * inv(h + d*r, N) # et voila w = inv(s_p, N) u1, u2 = z*w % N, r*w % N x, y = fast_add(fast_multiply(G, u1), fast_multiply(Q, u2)) assert(r == x and (r % N) and (s_p % N))
Q = fast_multiply(G, k) print("SEARCH - {0}".format(k)) # Pollard rho def new_xab(x, a, b): S = x[0] % 3 if S == 0: a = (a + 1) % N x = fast_add(x, G) elif S == 1: a = (a * 2) % N b = (b * 2) % N x = fast_add(x, x) elif S == 2: b = (b + 1) % N x = fast_add(x, Q) return x, a, b x=X=(0,0); a=A=0; b=B=0; for i in range(N): x, a, b = new_xab(x, a, b) X, A, B = new_xab(X, A, B) X, A, B = new_xab(X, A, B) if x == X: if b == B: print("NOT FOUND") else: k = ((a - A) * inv(B - b, N)) % N print("FOUND - {0}".format(k)) break
#!/usr/bin/env python from bitcoin import fast_add, fast_multiply, G, inv, N from random import SystemRandom # Generate random public key Q = fast_multiply(G, SystemRandom().randrange(1, N)) # Choose a 2 random numbers a = SystemRandom().randrange(1, N) b = SystemRandom().randrange(1, N) # calculate a signature r = fast_add(fast_multiply(G, a), fast_multiply(Q, b))[0] s = r * inv(b, N) # and now calculate the non hashed message from the result m = a * r * inv(b, N) # et voila w = inv(s, N) u1, u2 = m * w % N, r * w % N x, y = fast_add(fast_multiply(G, u1), fast_multiply(Q, u2)) assert (r == x and (r % N) and (s % N))