def recover_key(c1,sig1,c2,sig2,pubkey): #using the same variable names as in: #http://en.wikipedia.org/wiki/Elliptic_Curve_DSA curve_order = pubkey.curve.order n = curve_order s1 = string_to_number(sig1[-48:]) print "s1: " + str(s1) s2 = string_to_number(sig2[-48:]) print "s2: " + str(s2) r = string_to_number(sig1[-96:--48]) print "r: " + str(r) print "R values match: " + str(string_to_number(sig2[-96:--48]) == r) z1 = string_to_number(sha1(c1)) z2 = string_to_number(sha1(c2)) sdiff_inv = inverse_mod(((s1-s2)%n),n) k = ( ((z1-z2)%n) * sdiff_inv) % n r_inv = inverse_mod(r,n) da = (((((s1*k) %n) -z1) %n) * r_inv) % n print "Recovered Da: " + hex(da) recovered_private_key_ec = SigningKey.from_secret_exponent(da, curve=NIST384p) return recovered_private_key_ec.to_pem()
def recover_key(c1,sig1,c2,sig2,pubkey): #using the same variable names as in: #http://en.wikipedia.org/wiki/Elliptic_Curve_DSA curve_order = pubkey.curve.order n = curve_order s1 = int(sig1[96:],16) print("s1: " + str(s1)) s2 = int(sig2[96:],16) print("s2: " + str(s2)) r = int(sig1[:-96], 16) print("r: " + str(r)) print("R values match: " + str(int(sig2[:-96],16) == r)) z1 = string_to_number(sha256(c1)) z2 = string_to_number(sha256(c2)) #magical math stuff sdiff_inv = inverse_mod(((s1-s2)%n),n) k = ( ((z1-z2)%n) * sdiff_inv) % n r_inv = inverse_mod(r,n) da = (((((s1*k) %n) -z1) %n) * r_inv) % n print("Recovered Da: " + hex(da)) #turn the private key into a signing key recovered_private_key_ec = SigningKey.from_secret_exponent(da, curve=NIST384p) return recovered_private_key_ec
def curve25519_affine_double(x1, y1): if (x1, y1) == (1, 0): return (1, 0) x2 = (3 * x1 ** 2 + 2 * CURVE_A * x1 + 1) ** 2 * inverse_mod((2 * y1) ** 2, CURVE_P) - CURVE_A - x1 - x1 y2 = (2 * x1 + x1 + CURVE_A) * (3 * x1 ** 2 + 2 * CURVE_A * x1 + 1) * inverse_mod(2 * y1, CURVE_P) - \ (3 * x1 ** 2 + 2 * CURVE_A * x1 + 1) ** 3 * inverse_mod((2 * y1) ** 3, CURVE_P) - y1 return x2 % CURVE_P, y2 % CURVE_P
def _extract_public_pair(generator, recid, r, s, value): """ Using the already-decoded parameters of the bitcoin signature, return the specific public key pair used to sign this message. Caller must verify this pubkey is what was expected. """ assert 0 <= recid < 4, recid G = generator n = G.order() curve = G.curve() order = G.order() p = curve.p() x = r + (n * (recid // 2)) alpha = (pow(x, 3, p) + curve.a() * x + curve.b()) % p beta = numbertheory.modular_sqrt(alpha, p) inv_r = numbertheory.inverse_mod(r, order) y = beta if ((beta - recid) % 2 == 0) else (p - beta) minus_e = -value % order R = ellipticcurve.Point(curve, x, y, order) Q = inv_r * (s * R + minus_e * G) public_pair = (Q.x(), Q.y()) # check that this is the RIGHT public key? No. Leave that for the caller. return public_pair
def from_signature(klass, sig, recid, h, curve): # TODO use libsecp?? """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """ from ecdsa import util, numbertheory from . import msqr curveFp = curve.curve G = curve.generator order = G.order() # extract r,s from signature r, s = util.sigdecode_string(sig, order) # 1.1 x = r + (recid//2) * order # 1.3 alpha = ( x * x * x + curveFp.a() * x + curveFp.b() ) % curveFp.p() beta = msqr.modular_sqrt(alpha, curveFp.p()) y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta # 1.4 the constructor checks that nR is at infinity try: R = Point(curveFp, x, y, order) except: raise InvalidECPointException() # 1.5 compute e from message: e = string_to_number(h) minus_e = -e % order # 1.6 compute Q = r^-1 (sR - eG) inv_r = numbertheory.inverse_mod(r,order) try: Q = inv_r * ( s * R + minus_e * G ) except: raise InvalidECPointException() return klass.from_public_point( Q, curve )
def curve25519_affine_add(x1, y1, x2, y2): if (x1, y1) == (1, 0): return x2, y2 if (x2, y2) == (1, 0): return x1, y1 if x1 == x2 and y1 != y2: return (1, 0) if x1 == x2 and y1 == y2: return curve25519_affine_double(x1, y1) t1 = (y2 - y1) ** 2 % CURVE_P t2 = (x2 - x1) ** 2 % CURVE_P x3 = (t1 * inverse_mod(t2, CURVE_P) - 486662 - x1 - x2) % CURVE_P t1 = (2 * x1 + x2 + 486662) % CURVE_P t2 = (y2 - y1) % CURVE_P t3 = (x2 - x1) % CURVE_P y3 = t1 * (y2 - y1) * inverse_mod((x2 - x1) % CURVE_P, CURVE_P) - \ t2 ** 3 * inverse_mod(t3 ** 3 % CURVE_P, CURVE_P) - y1 y3 = y3 % CURVE_P return x3, y3
def verify_message(self, address, signature, message): """ See http://www.secg.org/download/aid-780/sec1-v2.pdf for the math """ from ecdsa import numbertheory, ellipticcurve, util import msqr curve = curve_secp256k1 G = generator_secp256k1 order = G.order() # extract r,s from signature sig = base64.b64decode(signature) if len(sig) != 65: raise BaseException("Wrong encoding") r, s = util.sigdecode_string(sig[1:], order) nV = ord(sig[0]) if nV < 27 or nV >= 35: raise BaseException("Bad encoding") if nV >= 31: compressed = True nV -= 4 else: compressed = False recid = nV - 27 # 1.1 x = r + (recid / 2) * order # 1.3 alpha = (x * x * x + curve.a() * x + curve.b()) % curve.p() beta = msqr.modular_sqrt(alpha, curve.p()) y = beta if (beta - recid) % 2 == 0 else curve.p() - beta # 1.4 the constructor checks that nR is at infinity R = ellipticcurve.Point(curve, x, y, order) # 1.5 compute e from message: h = Hash(self.msg_magic(message)) e = string_to_number(h) minus_e = -e % order # 1.6 compute Q = r^-1 (sR - eG) inv_r = numbertheory.inverse_mod(r, order) Q = inv_r * (s * R + minus_e * G) public_key = ecdsa.VerifyingKey.from_public_point(Q, curve=SECP256k1) # check that Q is the public key public_key.verify_digest(sig[1:], h, sigdecode=ecdsa.util.sigdecode_string) # check that we get the original signing address addr = public_key_to_bc_address(encode_point(public_key, compressed)) if address != addr: raise BaseException("Bad signature")
def verify_message(address, signature, message): """ See http://www.secg.org/download/aid-780/sec1-v2.pdf for the math """ curve = ecdsa.curves.SECP256k1.curve # curve_secp256k1 G = ecdsa.curves.SECP256k1.generator order = G.order() # extract r,s from signature if len(signature) != 65: raise BaseException("Wrong signature") r, s = util.sigdecode_string(signature[1:], order) nV = ord(signature[0]) if nV < 27 or nV >= 35: raise BaseException("Bad encoding") if nV >= 31: compressed = True nV -= 4 else: compressed = False recid = nV - 27 # 1.1 x = r + (recid / 2) * order # 1.3 alpha = (x * x * x + curve.a() * x + curve.b()) % curve.p() beta = ecdsa.numbertheory.square_root_mod_prime(alpha, curve.p()) y = beta if (beta - recid) % 2 == 0 else curve.p() - beta # 1.4 the constructor checks that nR is at infinity R = ellipticcurve.Point(curve, x, y, order) # 1.5 compute e from message: h = sha256(sha256(message_magic(message)).digest()).digest() e = util.string_to_number(h) minus_e = -e % order # 1.6 compute Q = r^-1 (sR - eG) inv_r = numbertheory.inverse_mod(r, order) Q = inv_r * (s * R + minus_e * G) public_key = ecdsa.VerifyingKey.from_public_point(Q, curve=ecdsa.curves.SECP256k1) # check that Q is the public key public_key.verify_digest(signature[1:], h, sigdecode=ecdsa.util.sigdecode_string) if address: address_type = int(binascii.hexlify(tools.b58decode(address, None)[0]), 16) addr = tools.public_key_to_bc_address('\x04' + public_key.to_string(), address_type, compress=compressed) if address != addr: raise Exception("Invalid signature")
def from_signature(cls, sig, recid, h, curve): """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """ curveFp = curve.curve G = curve.generator order = G.order() # extract r,s from signature r, s = util.sigdecode_string(sig, order) # 1.1 x = r + (recid / 2) * order # 1.3 alpha = (x * x * x + curveFp.a() * x + curveFp.b()) % curveFp.p() beta = msqr.modular_sqrt(alpha, curveFp.p()) y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta # 1.4 the constructor checks that nR is at infinity R = Point(curveFp, x, y, order) # 1.5 compute e from message: e = string_to_number(h) minus_e = -e % order # 1.6 compute Q = r^-1 (sR - eG) inv_r = numbertheory.inverse_mod(r, order) Q = inv_r * (s * R + minus_e * G) return cls.from_public_point(Q, curve)
def _my_sign(generator, secret_exponent, val, _k=None): """ Return a signature for the provided hash (val), using the provided random nonce, _k or generate a deterministic K as needed. May raise RuntimeError, in which case retrying with a new random value k is in order. """ G = generator n = G.order() k = _k or deterministic_make_k(n, secret_exponent, val) p1 = k * G r = p1.x() if r == 0: raise RuntimeError("amazingly unlucky random number r") s = (numbertheory.inverse_mod(k, n) * (val + (secret_exponent * r) % n)) % n if s == 0: raise RuntimeError("amazingly unlucky random number s") return (r, s, p1.y() % 2)
def from_signature(klass, sig, recid, h, curve): """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """ from ecdsa import util, numbertheory from . import msqr curveFp = curve.curve G = curve.generator order = G.order() # extract r,s from signature r, s = util.sigdecode_string(sig, order) # 1.1 x = r + (recid // 2) * order # 1.3 alpha = (x * x * x + curveFp.a() * x + curveFp.b()) % curveFp.p() beta = msqr.modular_sqrt(alpha, curveFp.p()) y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta # 1.4 the constructor checks that nR is at infinity R = Point(curveFp, x, y, order) # 1.5 compute e from message: e = string_to_number(h) minus_e = -e % order # 1.6 compute Q = r^-1 (sR - eG) inv_r = numbertheory.inverse_mod(r, order) Q = inv_r * (s * R + minus_e * G) return klass.from_public_point(Q, curve)
from ecdsa import numbertheory, util from ecdsa import VerifyingKey, SigningKey PUBLIC_KEY = """ -----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEgTxPtDMGS8oOT3h6fLvYyUGq/BWeKiCB sQPyD0+2vybIT/Xdl6hOqQd74zr4U2dkj+2q6+vwQ4DCB1X7HsFZ5JczfkO7HCdY I7sGDvd9eUias/xPdSIL3gMbs26b0Ww0 -----END PUBLIC KEY----- """ vk = VerifyingKey.from_pem(PUBLIC_KEY.strip()) msg1 = 'help' sig1 = binascii.unhexlify('c0e1fc4e3858ac6334cc8798fdec40790d7ad361ffc691c26f2902c41f2b7c2fd1ca916de687858953a6405423fe156cfd7287caf75247c9a32e52ab8260e7ff1e46e55594aea88731bee163035f9ee31f2c2965ac7b2cdfca6100d10ba23826') msg2 = 'time' sig2 = binascii.unhexlify('c0e1fc4e3858ac6334cc8798fdec40790d7ad361ffc691c26f2902c41f2b7c2fd1ca916de687858953a6405423fe156c0cbebcec222f83dc9dd5b0d4d8e698a08ddecb79e6c3b35fc2caaa4543d58a45603639647364983301565728b504015d') r = util.string_to_number(sig1[:48]) s1 = util.string_to_number(sig1[48:]) z1 = util.string_to_number(hashlib.sha256(msg1).digest()) s2 = util.string_to_number(sig2[48:]) z2 = util.string_to_number(hashlib.sha256(msg2).digest()) k = (z1 - z2) * numbertheory.inverse_mod(s1 - s2, vk.pubkey.order) % vk.pubkey.order d = (s1 * k - z1) * numbertheory.inverse_mod(r, vk.pubkey.order) % vk.pubkey.order sk = SigningKey.from_secret_exponent(d, curve=vk.curve, hashfunc=hashlib.sha256) msg3 = 'read %s' % sys.argv[1] print '%s:%s' % (msg3, binascii.hexlify(sk.sign(msg3, k=k)))
s2 = int(p.recvline(), 16) p << 'a\nb\n' >> "test=" test = int(p.recvline(), 16) print("test", hex(test)) print("s1", hex(s1)) print("s2", hex(s2)) assert r1 == r2 h1 = hash_message("message1") h2 = hash_message("message2") for v in (s1 - s2, s1 + s2, -s1 - s2, -s1 + s2): k = inverse_mod(v, ecdsa.generator_secp256k1.order()) * ( h1 - h2) % ecdsa.generator_secp256k1.order() d = inverse_mod(r1, ecdsa.generator_secp256k1.order()) * ( k * s1 - h1) % ecdsa.generator_secp256k1.order() g = ecdsa.generator_secp256k1 pub = ecdsa.Public_key(g, g * d) priv = ecdsa.Private_key(pub, d) if pub.verifies(h1, ecdsa.Signature(r1, s1)): break sig = priv.sign(test, 1) p >> 'r? ' << hex(sig.r) << '\n' p >> 's? ' << hex(sig.s) << '\n' flag = p.recvline().decode('utf8')
def verify_message(self, address, signature, message): """Creates a public key from a message signature and verifies message Bitcoin uses a compact format for message signatures (for tx sigs it uses normal DER format). The format has the normal r and s parameters that ECDSA signatures have but also includes a prefix which encodes extra information. Using the prefix the public key can be reconstructed from the signature. | Prefix values: | 27 - 0x1B = first key with even y | 28 - 0x1C = first key with odd y | 29 - 0x1D = second key with even y | 30 - 0x1E = second key with odd y If key is compressed add 4 (31 - 0x1F, 32 - 0x20, 33 - 0x21, 34 - 0x22 respectively) Raises ------ ValueError If signature is invalid """ sig = b64decode(signature.encode('utf-8')) if len(sig) != 65: raise ValueError('Invalid signature size') # get signature prefix, compressed and recid (which key is odd/even) prefix = sig[0] if prefix < 27 or prefix > 35: return False if prefix >= 31: compressed = True recid = prefix - 31 else: compressed = False recid = prefix - 27 # create message digest -- note double hashing message_magic = add_magic_prefix(message) message_digest = hashlib.sha256( hashlib.sha256(message_magic).digest()).digest() # # use recid, r and s to get the point in the curve # # get signature's r and s r, s = sigdecode_string(sig[1:], _order) # ger R's x coordinate x = r + (recid // 2) * _order # get R's y coordinate (y**2 = x**3 + 7) y_values = sqrt_mod((x**3 + 7) % _p, _p, True) if (y_values[0] - recid) % 2 == 0: y = y_values[0] else: y = y_values[1] # get R (recovered ephemeral key) from x,y R = ellipticcurve.Point(_curve, x, y, _order) # get e (hash of message encoded as big integer) e = int(hexlify(message_digest), 16) # compute public key Q = r^-1 (sR - eG) # because Point substraction is not defined we will instead use: # Q = r^-1 (sR + (-eG) ) minus_e = -e % _order inv_r = numbertheory.inverse_mod(r, _order) Q = inv_r * (s * R + minus_e * _G) # instantiate the public key and verify message public_key = VerifyingKey.from_public_point(Q, curve=SECP256k1) key_hex = hexlify(public_key.to_string()).decode('utf-8') pubkey = PublicKey.from_hex('04' + key_hex) if not pubkey.verify(signature, message): return False # confirm that the address provided corresponds to that public key if pubkey.get_address(compressed=compressed).to_string() != address: return False return True
"=======================================================================================================" ) print( "=======================================================================================================" ) print("Finding Flag - Calc R2") print("\tFind v for u such that (u,v) is in G.") print("\tSince k is just incremented then we add A to (u,v) in G.") print("\tFind R_2 to be the x value of A+(u,v) =\t", r2) print( "=======================================================================================================" ) print( "=======================================================================================================" ) print("Finding Flag - Calc Private Key") top = (s2 * x1 - s1 * x2 + s1 * s2) % order print("\tTop = S_2*X_1 - S_1*X_2 + S_1*S_2 =\t", top) bottom_inv = (r2 * s1 - r1 * s2) % order print("\tBottom_Inv = R_2*S_1 - R_1*S_2 =\t", bottom_inv) bottom = inverse_mod(bottom_inv, order) print("\tBottom = Bottom_t Inverse in Z_order =\t", bottom) priv_key_calc = (top * bottom) % order print("\tCalulated Flag:\t\t\t", priv_key_calc) print("\tFlag Correct:\t\t\t\t", priv_key_calc == priv_key.privkey.secret_multiplier) print( "=======================================================================================================" )
tn.write(b'B\n') tn.read_until(b'Signature: ') sig2 = tn.read_until(b'\n')[:-1].decode() r1 = int(sig1[:48], 16) r2 = int(sig2[:48], 16) if r1 != r2: print("r isnt reused. Try again.") exit(1) s1 = int(sig1[48:], 16) s2 = int(sig2[48:], 16) z1 = int(HASH('A'), 16) z2 = int(HASH('B'), 16) k = (((z1 - z2) % n) * inverse_mod(s1 - s2, n)) % n print(f"k: {k}") dA = ((((s1 * k) % n) - z1) * inverse_mod(r1, n)) % n print(f"dA: {dA}") priv = SigningKey.from_secret_exponent(dA, curve=curve) sig = priv.sign(b'please_give_me_the_flag', k=1337) tn.read_until(PROMPT) tn.write(b'3\n') tn.read_until(b'signature> ') tn.write(binascii.hexlify(sig) + b'\n') tn.interact()
def curve25519_eckcdsa_keygen(secret): s = from_le32(clamp(secret)) x, y = curve25519_affine_mult(s, CURVE_G_X, CURVE_G_Y) signing_key = inverse_mod(s if is_negative(y) else -s, CURVE_ORDER) return le32(x), le32(signing_key), le32(s)
def curve25519_eckcdsa_keygen(self, secret): # print(secret) s = self._from_le32(self._clamp(secret)) x, y = self._curve25519_affine_mult(s, self.CURVE_G_X, self.CURVE_G_Y) signing_key = inverse_mod(s if self._is_negative(y) else -s, self.CURVE_ORDER) return self._le32(x), self._le32(signing_key), self._le32(s)
) sig2 = sigdecode_der(sig2, n) print "(r1, s2):" print sig2 r1 = sig1[0] s1 = sig1[1] z1 = int(hexlify(sha256(msg1).digest()), 16) r2 = sig2[0] s2 = sig2[1] z2 = int(hexlify(sha256(msg2).digest()), 16) if r1 == r2: print "\nr1 = r2 - vulnerable ECDSA signature\n" k = (z1 - z2) * inverse_mod(s1 - s2, n) % n print "Got k: 0x{:x}\n".format(k) dA = (s1 * k - z1) * inverse_mod(r1, n) % n print "Got dA: 0x{:x}\n".format(dA) sk = SigningKey.from_secret_exponent(dA, curve=curves.SECP256k1, hashfunc=sha256) print "Signing Key: \n" + sk.to_pem() #vk = sk.get_verifying_key() #vk.verify(sig2, msg2, hashfunc=sha256, sigdecode = sigdecode_der) #print vk.to_pem() print "Test (r1, s1):"
密码学中描述一条有限域上的椭圆曲线常用到六个参量: T=(p,a,b,G,n,h)以及公钥和私钥 都放在p384-key.pem文件里面了(对,私钥也在) PubKey = PrivKey*generator_384(G) 不过这个算法并不是【正规的椭圆曲线】,所以不要直接上网找脚本哦。这边给出这个椭圆曲线的加密方式: x1 = int(codecs.encode(flag[:12],'hex'),16) x2 = int(codecs.encode(flag[12:],'hex'),16) X = (x1,x2) k = randrange(1, n-1) y0 = k*generator_384 KPoint = k*PubKey Y = (X[0] * KPoint.x() % _p, X[1]*KPoint.y() % _p) 密文就是 Y=({},{}) y0=({},{}) """.format(Y[0], Y[1], y0.x() % _p, y0.y() % _p) fd = open("ECC.enc", 'wt', encoding='utf-8') fd.write(text) fd.close() C = d * y0 x0 = (Y[0] * numbertheory.inverse_mod(C.x(), _p)) % _p x1 = Y[1] * numbertheory.inverse_mod(C.y(), _p) % _p print(codecs.decode(hex(x0)[2:], 'hex') + codecs.decode(hex(x1)[2:], 'hex')) # print(hex(x0)[:2], hex(x1))
# Read message 2: with open("msg2.txt", "rb") as msg: msg2 = msg.read() # Parse signature of message 1: with open("msg1.sig", "rb") as sig: r1, s1 = parse_sig(sig.read()) # Parse signature from message 2: with open("msg2.sig", "rb") as sig: r2, s2 = parse_sig(sig.read()) if r1 != r2: print("Cannot retrieve private key from signatures with distinct r parts") quit() # r == r1 == r2 r = r1 # Get hashes of messages: h1 = int(sha1(msg1).hexdigest(), 16) h2 = int(sha1(msg2).hexdigest(), 16) # Solve the system in order to find the value of k: k = (((h1 - h2) % n) * inverse_mod(s1 - s2, n)) % n # Replace k by its value on the first equation in order to find the private key d: d = (((s1 * k - h1) % n) * inverse_mod(r, n)) % n # Print the private key in PEM format: print(SigningKey.from_secret_exponent(d, NIST256p).to_pem().decode())
print("r: %d, s: %d, z: %d" % (r, s, z)) privkey = None generator = pubkey.curve.generator pubkey_point = pubkey.pubkey.point k_bytes = b'\x00' * 28 + b'four' k = int.from_bytes(k_bytes, byteorder='big', signed=False) % order print("k is: 0x%x" % k) print("Checking that (G * k).x == r. %d == %d" % ((generator * k).x(), r)) assert ((generator * k).x() == r) for i in range(2): privkey_maybe = ((-1**i * s) * k - z) * nt.inverse_mod(r, order) privkey_maybe %= order print("pubkey: %s, privkey: %x, G * privkey: %s" % (pubkey_point, privkey_maybe, (generator * privkey_maybe))) if pubkey_point == generator * privkey_maybe: privkey = privkey_maybe privkey_bytes = binascii.unhexlify('%x' % privkey) sk = ecdsa.SigningKey.from_string(privkey_bytes, curve=ecdsa.SECP256k1) print(sk.to_pem().decode()) hex_privkey = binascii.hexlify(privkey_bytes) print('hex private key: %s, hex sha256 private key: %s' % (hex_privkey, sha256(hex_privkey).hexdigest())) sig = sk.sign(b'message') pubkey.verify(sig, b'message')
from ecdsa.numbertheory import inverse_mod from Crypto.Cipher import AES import binascii n = 115792089210356248762697446949407573529996955224135760342422259061068512044369 r = 50394691958404671760038142322836584427075094292966481588111912351250929073849 s1 = 26685296872928422980209331126861228951100823826633336689685109679472227918891 s2 = 40762052781056121604891649645502377037837029273276315084687606790921202237960 z1 = 777971358777664237997807487843929900983351335441289679035928005996851307115 z2 = 91840683637030200077344423945857298017410109326488651848157059631440788354195 ct = b'f3ccfd5877ec7eb886d5f9372e97224c43f4412ca8eaeb567f9b20dd5e0aabd5' sdelta_inv = inverse_mod(((s1 - s2) % n), n) k = (((z1 - z2) % n) * sdelta_inv) % n inverse_r = inverse_mod(r, n) da = (((((s1 * k) % n) - z1) % n) * inverse_r) % n print(da) #secret = SigningKey.from_secret_exponent(da) secret = int(da) print(secret) aes_key = secret.to_bytes(64, byteorder='little')[0:16] IV = b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' cipher = AES.new(aes_key, AES.MODE_CBC, IV) pt = cipher.decrypt(binascii.unhexlify(ct)) print(pt)
#m_1 corresponds to s_1 and the same goes for m_2 m_1 = "iSsuZJOq1FNKMuK4wm88UEkr21wgsypW" m_2 = "x3wqOnaetBPO66TrBaMyr3NQIDbhvK0w" z_1 = int(binascii.hexlify(hashlib.sha1(m_1).digest()), 16) z_2 = int(binascii.hexlify(hashlib.sha1(m_2).digest()), 16) s_1 = convert_to_int("c1ilypdV4aDLRLIlVaCCkHsuN6EAet0+") s_2 = convert_to_int("SvNuLoc421+3BZMMFukNTOztlpj9kf4e") r = convert_to_int("BRXVEpTGwCo1HsaTNmhJ5NynvUsdhFzv") order = NIST192p.order #The following calculations are based on the explanation in https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm #It took a while to figure out that where the writer had put a = b/c, he really meant a = b * inversemod(c, order) mod order k_1 = (z_1 - z_2) * numbertheory.inverse_mod((s_1 - s_2), order) % order d_A = (s_1 * k_1 - z_1) * numbertheory.inverse_mod(r, order) % order priv_key = ecdsa.SigningKey.from_secret_exponent(d_A) #test with pcap sigs sig = priv_key.sign(m_1, k=k_1) sig = base64.b64encode(sig) print sig print original #nonce from server sig = priv_key.sign("wOi3CWK6p6TM4aqcg2KcTFhNhjKGeoOY") sig = base64.b64encode(sig)
def calcPart(a: int, b: int) -> int: p = (a - b) % baseN res = (a * numbertheory.inverse_mod(p, baseN)) % baseN return res
from ecdsa.curves import SECP256k1 from ecdsa import SigningKey from hashlib import sha1 from ecdsa.numbertheory import inverse_mod n = SECP256k1.order r1 = int('0589abade28762eea832854f89f6f144e4ef8ba27c03026f38eac070349b98a1', 16) s1 = int('4fd569a35deea668c3cf758048a281297e0c48851c8306f90ed84d35fa0a143f', 16) m1 = '8' z1 = int(sha1(m1.encode('utf-8')).hexdigest(), 16) r2 = int('0589abade28762eea832854f89f6f144e4ef8ba27c03026f38eac070349b98a1', 16) s2 = int('698363e6fb3c744571e95ead78e269b0f4deba0e43b8faf9842c6eed261185a5', 16) m2 = '9' z2 = int(sha1(m2.encode('utf-8')).hexdigest(), 16) # Calculate k k = (((z1 - z2) % n) * inverse_mod(s1 - s2, n)) % n print("k: 0x{:x}".format(k)) # Calculate private key private_key = ((((s1 * k) % n) - z1) * inverse_mod(r1, n)) % n print("private key: 0x{:x}".format(private_key)) # create admin signature sk = SigningKey.from_secret_exponent(private_key,curve=SECP256k1) admin_enc = "admin".encode() sig = sk.sign(admin_enc,k=k) print(str(sig.hex()))
m2 = bytes.fromhex( 'd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70' ) r2 = 0x557a787642ece2fe307b7de417d7d3c7bfe92313020a58e49771be515c4cadc s2 = 0xda91bba782f6e63aadd53f74bd989f194664a8273d431d4e104b55e01d355296 assert r1 == r2 assert s1 != s2 h1 = bytes_to_long(m1) h2 = bytes_to_long(m2) r = r1 # Precomputed values for minor optimisation r_inv = inverse_mod(r, order) h = (h1 - h2) % order # # Signature is still valid whether s or -s mod curve_order (or n) # s*k-h # Try different possible values for "random" k until hit for k_try in (s1 - s2, s1 + s2, -s1 - s2, -s1 + s2): # Retrieving actual k k = (h * inverse_mod(k_try, order)) % order # Secret exponent secexp = (((((s1 * k) % order) - h1) % order) * r_inv) % order print(decryptFlag(secexp, iv, ciphertext))