def handle(self): # self.request is the TCP socket connected to the client # generate key global a command = read_message(self.request) if command == b"GENERATE_KEY": data4key = { 'g': to_binary(G), 'p': to_binary(P), 'A': to_binary(powmod(G, a, P)) } send_message(self.request, pack_message(data4key)) data4key = read_message(self.request) KEY = powmod(from_binary(unpack_message(data4key)), a, P) print("key created: ", KEY) KEY = to_binary(KEY) sess_key = to_binary(crypto.get_random_bytes(SESS_KEY_LENGTH)) send_message(self.request, sess_key) data = unpack_message(read_message(self.request)) account = db.auth(data[0], data[1], sess_key) send_message(self.request, pack_message(account)) if account is not None: db.set_sesskey(account[1], binascii.b2a_hex(KEY).decode()) a = crypto.gen_big_prime(KEY_LENGTH) print("<bin key>", KEY) elif command == b"COMMUNICATION": login = unpack_message(read_message(self.request))[0] KEY = db.get_sesskey(login) if KEY is None: print("No Sess Key") self.request.close() return KEY = binascii.a2b_hex(KEY) print("<key from db>", KEY) rc4 = ARC4.new(KEY) data = read_message(self.request) decrypted = rc4.decrypt(data) d = unpack_message(decrypted) if 'cmd' in d and 'args' in d: #print(d['args']) res = funcs[d['cmd']](*d['args']) data2recv = pack_message(res) encrypted_res = rc4.encrypt(data2recv) send_message(self.request, encrypted_res) else: data2recv = pack_message(b"null") encrypted_res = rc4.encrypt(data2recv) send_message(self.request, encrypted_res) self.request.close()
def generate_key(self, fd): self._send_message(fd, b"GENERATE_KEY") b = crypto.gen_big_prime(KEY_LENGTH) data4key = self._read_message(fd) data4key = unpack_message(data4key) g, p, A = from_binary(data4key['g']), from_binary( data4key['p']), from_binary(data4key['A']) B = powmod(g, b, p) self._send_message(fd, pack_message(to_binary(B))) KEY = powmod(A, b, p) KEY = to_binary(KEY) self.KEY = KEY
def decode(a, b, c1, c2, pkey1, pkey2): m1 = pow(c1, a, pkey1.n) print(gmpy2.invert(c2, pkey1.n)) m2 = pow(c2, b, pkey1.n) plain = m1 * m2 % pkey1.n mes = gmpy2.to_binary(plain) print(mes.decode("utf-8"))
def hash_flat2(h, obj): if isinstance(obj, collections.Iterable): for x in obj: hash_flat2(h, x) # end for else: h.update(to_binary(mpz(obj)))
def decrypt_from_factors(c, e, p, q, N=0): if N == 0: N = p * q c = mpz(c) d = gmpy2.invert(e, (p - 1) * (q - 1)) m = gmpy2.powmod(c, d, N) # check that it as correct c2 = gmpy2.powmod(m, e, N) if c2 != c: print "Decryption failed!" return None # Undo PKCS with separator 00 (not FF!) # Have to reverse string and slice off header applied by gmpy2 m = gmpy2.to_binary(m)[:1:-1] if ord(m[0]) != 2: print "Invalid PKCS header found" return None start = m.find(chr(0)) if start < 0: print "Could not find end of pad" return None return m[start:]
def challenge4(RSAValues): """ RSA Decryption challenge. Use previously found values of q and p to decrypt a provided message """ print("> Challenge 4") e = gmpy2.mpz(65537) c = gmpy2.mpz(22096451867410381776306561134883418017410069787892831071731839143676135600120538004282329650473509424343946219751512256465839967942889460764542040581564748988013734864120452325229320176487916666402997509188729971690526083222067771600019329260870009579993724077458967773697817571267229951148662959627934791540) # Runs challenge 1 again to obtain the values p, q, N = RSAValues Nphi = gmpy2.mpz((p - 1)*(q - 1)) # Private key generation d = gmpy2.invert(e, Nphi) m = gmpy2.powmod(c, d, N) m = gmpy2.to_binary(m)[::-1] # PKCS1 printing = False for byte in m: # Split character used here is \x00 if byte == 0: printing = True if printing: print(chr(byte), end='') print()
def generate_p_q(L, N): g = N # g >= 160 n = (L - 1) // g #n es igual cociente entre 1023/160 = 6 b = (L - 1) % g #b es igual al residuo entre 1023/160 = 63 while True: # generate q while True: s = xmpz( randrange(1, 2**(g)) ) #randrange es una funcion que brinda un numero aleatorio entre 1 y 2^160 a = sha1(to_binary(s)).hexdigest( ) #se convierte s a binario y se le saca el hash en hexadecimal zz = xmpz( (s + 1) % (2**g) ) #se ubica un numero + 1 a s y se confirma que este en el cuerpo de 2^160 z = sha1(to_binary(zz)).hexdigest( ) #se convierte zz a binario y se le sacah el hash en hexadecimal U = int(a, 16) ^ int( z, 16 ) #se covierte los hashes a enteros en base 16 y se realiza una operacion XOR mask = 2**( N - 1 ) + 1 #se genera una mascara que sea un bit menos a 2^160 osea (2^159) + 1 q = U | mask #se realiza una operacion OR entre U y la mascara if is_prime(q, 20): #se verifica si q es primo de 20 break # generate p i = 0 # counter j = 2 # offset while i < 4096: V = [] for k in range(n + 1): arg = xmpz((s + j + k) % (2**g)) zzv = sha1(to_binary(arg)).hexdigest() V.append(int(zzv, 16)) W = 0 for qq in range(0, n): W += V[qq] * 2**(160 * qq) W += (V[n] % 2**b) * 2**(160 * n) X = W + 2**(L - 1) c = X % (2 * q) p = X - c + 1 # p = X - (c - 1) if p >= 2**(L - 1): if is_prime(p, 10): return p, q i += 1 j += n + 1
def gmpy_serialize(obj: GmpyTypes, **_kwargs: Any) -> bytes: r""" Function for serializing gmpy objects :param obj: gmpy object to serialize :param \**_kwargs: optional extra keyword arguments :return: serialized object """ return gmpy2.to_binary(obj)
def to_bytes(self, byteorder="big"): self.digits() print(format(self.fpo, "A")) ctx = gmpy2.ieee(self.length * 8) gmpy2.set_context(ctx) b = gmpy2.to_binary(self.fpo) return b
def set_rand_seed(numList): h = SHA256.new() for x in numList: h.update(to_binary(mpz(x))) # not thread-safe! # Not using Crypto.random because: # 1. Need to set seed; # 2. It's predictable anyway... rand.seed(h.hexdigest())
def four(): ct = mpz('22096451867410381776306561134883418017410069787892831071731839143676135600120538004282329650473509424343946219751512256465839967942889460764542040581564748988013734864120452325229320176487916666402997509188729971690526083222067771600019329260870009579993724077458967773697817571267229951148662959627934791540') p,q,N = one() p = sub(p,mpz('1')) q = sub(q,mpz('1')) e = mpz('65537') fi = mul(p,q) d = invert(e,fi) pkcs = to_binary(powmod(ct,d,N)) #Big-endian representation print "4. " + pkcs[::-1].encode('hex').split('00')[-1].decode('hex')
def four(): ct = mpz( '22096451867410381776306561134883418017410069787892831071731839143676135600120538004282329650473509424343946219751512256465839967942889460764542040581564748988013734864120452325229320176487916666402997509188729971690526083222067771600019329260870009579993724077458967773697817571267229951148662959627934791540' ) p, q, N = one() p = sub(p, mpz('1')) q = sub(q, mpz('1')) e = mpz('65537') fi = mul(p, q) d = invert(e, fi) pkcs = to_binary(powmod(ct, d, N)) #Big-endian representation print "4. " + pkcs[::-1].encode('hex').split('00')[-1].decode('hex')
def generate_p_q(L, N): g = N # g >= 160 n = (L - 1) // g b = (L - 1) % g while True: # generate q while True: s = xmpz(randrange(1, 2**(g))) a = sha1(to_binary(s)).hexdigest() zz = xmpz((s + 1) % (2**g)) z = sha1(to_binary(zz)).hexdigest() U = int(a, 16) ^ int(z, 16) mask = 2**(N - 1) + 1 q = U | mask if is_prime(q, 20): break # generate p i = 0 # counter j = 2 # offset while i < 4096: V = [] for k in range(n + 1): arg = xmpz((s + j + k) % (2**g)) zzv = sha1(to_binary(arg)).hexdigest() V.append(int(zzv, 16)) W = 0 for qq in range(0, n): W += V[qq] * 2**(160 * qq) W += (V[n] % 2**b) * 2**(160 * n) X = W + 2**(L - 1) c = X % (2 * q) p = X - c + 1 # p = X - (c - 1) if p >= 2**(L - 1): if is_prime(p, 10): return p, q i += 1 j += n + 1
def generate_p_q(self,L,N): #生成一个素数因子 g=N n=(L-1)//g b=(L-1)%g while True: while True: s=xmpz(randrange(1,2**(g))) #生成一个大素数g a=sha1(to_binary(s)).hexdigest() zz=xmpz((s+1)%(2**g)) z = sha1(to_binary(zz)).hexdigest() #hash值为160bit,通过生成随机字符串将 | 链接起来新城新的字符串来实现p和q的生成 U = int(a, 16) ^ int(z, 16) mask = 2 ** (N - 1) + 1 q = U | mask if is_prime(q, 20): #is_prime用来判断是否为素数因子 break # generate p #生成p i = 0 # counter j = 2 # offset while i < 4096: V = [] for k in range(n + 1): arg = xmpz((s + j + k) % (2 ** g)) zzv = sha1(to_binary(arg)).hexdigest() V.append(int(zzv, 16)) W = 0 for qq in range(0, n): W += V[qq] * 2 ** (160 * qq) W += (V[n] % 2 ** b) * 2 ** (160 * n) X = W + 2 ** (L - 1) c = X % (2 * q) p = X - c + 1 # p = X - (c - 1) if p >= 2 ** (L - 1): if is_prime(p, 10): return p, q #生成一个素数p:2^L-1<p<2^L,L为64的倍数 选取p-1的一个素数因子q,2^159<q<2^160 i += 1 j += n + 1
def xgcd(a, b): """return (g, x, y) such that a*x + b*y = g = gcd(a, b)""" x0, x1, y0, y1 = 0, 1, 1, 0 while a != 0: q, b, a = b // a, a, b % a y0, y1 = y1, y0 - q * y1 x0, x1 = x1, x0 - q * x1 return b, x0, y0 c = gmpy2.mpz(int(open(sys.argv[1]).readline().strip(), 16)) pk = open(sys.argv[2]) n = gmpy2.mpz(int(pk.readline().strip()[2:], 16)) e = gmpy2.mpz(int(pk.readline().strip()[2:], 16)) p, q = fermat_factorise(n) phi = (p - 1) * (q - 1) gcd, d, b = xgcd(e, phi) plaintext = gmpy2.powmod(c, gmpy2.mpz(d), n) bin = bytearray(gmpy2.to_binary(plaintext)) print('p = {}\n\nq = {}\n'.format(p, q)) print('d = {}\n'.format(d)) print('Plaintext (little endian): {}'.format(bin)) bin.reverse() print('Plaintext (big endian): {}'.format(bin))
#!/usr/bin/env python3 # Import libraries from gmpy2 import mpz, invert, powmod, to_binary from pwn import log # Import handcrafted modules from utl_converters import Converter # Define used constants, where P and Q are obtained with factordb.com N = mpz( 70736025239265239976315088690174594021646654881626421461009089480870633400973 ) E = mpz(3) C = mpz( 28822365203577929536184039125870638440692316100772583657817939349051546473185 ) P = mpz(238324208831434331628131715304428889871) Q = mpz(296805874594538235115008173244022912163) # Decrypt ciphertext phi = mpz((P - 1) * (Q - 1)) d = invert(E, phi) m = powmod(C, d, N) # Print decrypted message log.success("The decrypted message is: {}".format( Converter.bytes_to_string(to_binary(m))[::-1]))
def q_to_bytes(e: ElementModQ) -> bytes: """ Returns a byte sequence from the element. """ return to_binary(e.elem)
def base_n_decode(bytes_in, base): bytes_out = to_binary(mpz(bytes_in, base=base))[:1:-1] return bytes_out
# Q3 print("Q3") N3 = mpz( "720062263747350425279564435525583738338084451473999841826653057981916355690188337790423408664187663938485175264994017897083524079135686877441155132015188279331812309091996246361896836573643119174094961348524639707885238799396839230364676670221627018353299443241192173812729276147530748597302192751375739387929" ) A3 = isqrt(6 * N3) for i in range(1, 2**10): Ap = A3 + i x = isqrt(Ap * Ap - 6 * N3) p = (A3 - x) // 3 q = (A3 + x) // 2 check = p * q == N3 if check: print("smaller: ", p) break # Q4 ciphertext = mpz( "22096451867410381776306561134883418017410069787892831071731839143676135600120538004282329650473509424343946219751512256465839967942889460764542040581564748988013734864120452325229320176487916666402997509188729971690526083222067771600019329260870009579993724077458967773697817571267229951148662959627934791540" ) phiN = (p1 - 1) * (q1 - 1) sk = invert(65537, phiN) if sk == 0: raise Exception("Invalid") plain = powmod(ciphertext, sk, N1) plain_bytes = to_binary(plain) plain_bytes = bytes([x for x in reversed(plain_bytes)]) print("plaintext: ", plain_bytes)
p, q = q3_factorization e = mpz('65537') fi = gmpy2.mul(p - 1, q - 1) # Tìm (g,d,t) thỏa mãn e*d=1 (mod fi), hay g=e*d+fi* t (Trong đó g=1) # In[13]: g, d, t = gmpy2.gcdext(e, fi) print(g, d, sep='\n') # RSA Decryption sử dụng d tìm được ở trên # In[14]: plain = gmpy2.powmod(cipher, d, n1) #2 bytes đầu chứa thông tin của mpz object, lọai bỏ plain_hex = bytearray(gmpy2.to_binary(plain)[2:]) print(plain_hex) # Sửa lại thứ tự các bytes # ### Kết quả: # In[15]: plain_hex.reverse() print(plain_hex) # **Kết quả là:** # *"Factoring lets us break RSA."*
p = A - Xr[0] q = A + Xr[0] assert gmpy2.mul(p, q) == N print(p) ct = mpz( "22096451867410381776306561134883418017410069787892831071731839143676135600120538004282329650473509424343946219751512256465839967942889460764542040581564748988013734864120452325229320176487916666402997509188729971690526083222067771600019329260870009579993724077458967773697817571267229951148662959627934791540" ) e = mpz(65537) fN = N - p - q + 1 d = gmpy2.invert(e, fN) assert gmpy2.powmod(gmpy2.mul(e, d), 2, fN) == 1 ptm = gmpy2.powmod(ct, d, N) assert gmpy2.powmod(ptm, e, N) == ct bts = gmpy2.to_binary(ptm) bts = bytes(reversed(bts)) print(bts) encode = codecs.encode(bts, "hex_codec").decode("ascii") print(encode) N = mpz( "648455842808071669662824265346772278726343720706976263060439070378797308618081116462714015276061417569195587321840254520655424906719892428844841839353281972988531310511738648965962582821502504990264452100885281673303711142296421027840289307657458645233683357077834689715838646088239640236866252211790085787877" ) SN = gmpy2.isqrt(N) i = mpz(0) while True: i += 1 A = SN + i if gmpy2.mul(A, A) < N:
bob_public_exponent = bob_public_key.e bob_modulus = bob_public_key.n # Log RSA parameters log.info("Alice public key has public exponent {} and modulus {}".format( alice_public_exponent, alice_modulus)) log.info("Bob public key has public exponent {} and modulus {}".format( bob_public_exponent, bob_modulus)) # Get K1 and K2 in multi-precision form res_k1 = iroot(mpz(Converter.bytes_to_int(c1)), alice_public_exponent) res_k2 = iroot(mpz(Converter.bytes_to_int(c2)), bob_public_exponent) if (res_k1[1] and res_k2[1]): # Convert results to bytes k1 = Converter.swap_endianness(to_binary(res_k1[0]))[:-2] k2 = Converter.swap_endianness(to_binary(res_k2[0]))[:-2] # Log log.success("Finded K1, with effective length of {} bits, is {}".format( bit_length(res_k1[0]), Converter.bytes_to_hex(k1))) log.success("Finded k2, with effective length of {} bits, is: {}".format( bit_length(res_k2[0]), Converter.bytes_to_hex(k2))) else: # Force exitW log.failure("Failed to obtain K1 and K2") exit(0) # Compute key used in AES