def gen_keys(): print "Début de la génération des clés..." print "Traitement en cours..." # find large Sophie Germain prime (safe prime) loop = True while loop: q = largePrime(512) if isPrime(q): p = 2 * q + 1 if isPrime(p): loop = False # find g1 and g2 loop = True while loop: g1, g2 = random.randint(2, p - 1), random.randint(2, p - 1) if pow(g1, (p - 1) / q) % p != 1: g1 = pow(g1, (p - 1) / q) % p if pow(g1, (p - 1) / q) % p != 1: g2 = pow(g2, (p - 1) / q) % p if g1 != g2: loop = False # generate x1, x2, y1, y2 and w (public key) x1, x2, y1, y2, w = random.randint(2, p - 1), random.randint(2, p - 1), random.randint(2, p - 1), random.randint(2, p - 1), random.randint( 2, p - 1) # compute X, Y and W (private key) X = (powmod(g1, x1, p) * powmod(g2, x2, p)) % p Y = (powmod(g1, y1, p) * powmod(g2, y2, p)) % p W = powmod(g1, w, p) # writing public and private keys into files print "Écriture de la clé publique dans le fichier 'key.pub'..." f = open("key.pub", "w") f.write("==========PUBLIC KEY==========\n") f.write("p:" + str(p) + "\n") f.write("g1:" + str(g1) + "\n") f.write("g2:" + str(g2) + "\n") f.write("X:" + str(X) + "\n") f.write("Y:" + str(Y) + "\n") f.write("W:" + str(W) + "\n") f.write("==========END==========") print "Écriture terminée." f.close() print "Écriture de la clé privée dans le fichier 'key.priv'" f = open("key.priv", "w") f.write("==========PRIVATE KEY==========\n") f.write("x1:" + str(x1) + "\n") f.write("x2:" + str(x2) + "\n") f.write("y1:" + str(y1) + "\n") f.write("y2:" + str(y2) + "\n") f.write("w:" + str(w) + "\n") f.write("p:" + str(p) + "\n") f.write("==========END==========") print "Écriture terminée." f.close() print "Génération des clés terminées (enfin !), passage aux choses sérieuses ^_^"
def encrypt(): with open( raw_input( "Saisir le nom du fichier de la clé publique (ou le chemin direct) : " ), 'rU') as pub: temp = pub.readlines() p = int(temp[1].split(":")[1]) g1 = int(temp[2].split(":")[1]) g2 = int(temp[3].split(":")[1]) X = int(temp[4].split(":")[1]) Y = int(temp[5].split(":")[1]) W = int(temp[6].split(":")[1]) m = lectureFichier() n = len(m) with open(raw_input("Saisir le nom du fichier chiffré : "), 'w') as f: print "Écriture des informations du message à chiffrer en cours, veuillez patienter..." f.write("==========ENCRYPTED MESSAGE==========\n") f.write("n:" + str(n) + "\n") for i in range(0, n): b = random.randint(2, p - 1) b1 = powmod(g1, b, p) b2 = powmod(g2, b, p) c = (powmod(W, b, p) * int(m[i], 2)) % p # blake2b hash computation # b1_hash = blake2b_hash(b1, sys.getsizeof(b1), 0, 512) # b2_hash = blake2b_hash(b2, sys.getsizeof(b2), 0, 512) # c_hash = blake2b_hash(c, sys.getsizeof(c), 0, 512) # beta = b1_hash + b2_hash + c_hash # sha_256 hashlib version # b1_hash = hashlib.sha_256(str(b1)).hexdigest() # b2_hash = hashlib.sha_256(str(b2)).hexdigest() # c_hash = hashlib.sha_256(str(c)).hexdigest() # beta = b1_hash + b2_hash + c_hash # beta2 = int(beta, 16) # sha256 hash computation b1_hash = sha_256(str(b1)) b2_hash = sha_256(str(b2)) c_hash = sha_256(str(c)) beta = b1_hash + b2_hash + c_hash v = (powmod(X, b, p) * powmod(Y, b * int(beta, 16), p)) % p f.write("=====BLOCK " + str(i + 1) + "=====\n") f.write("b1:" + str(b1) + "\n") f.write("b2:" + str(b2) + "\n") f.write("c:" + str(c) + "\n") f.write("v:" + str(v) + "\n") f.write("=====END BLOCK=====\n") f.write("==========END FILE==========\n") f.close() pub.close() print "Écriture terminée, gardez bien ce fichier au chaud pour pouvoir le déchiffrer..."
def decrypt(): with open( raw_input( "Saisir le nom du fichier de la clé privée (ou le chemin direct) : " ), 'rU') as priv: temp = priv.readlines() x1 = int(temp[1].split(":")[1]) x2 = int(temp[2].split(":")[1]) y1 = int(temp[3].split(":")[1]) y2 = int(temp[4].split(":")[1]) w = int(temp[5].split(":")[1]) p = int(temp[6].split(":")[1]) with open( raw_input( "Saisir le nom du fichier à déchiffrer (ou le chemin direct) : " ), 'rU') as chiffre: temp = chiffre.readlines() n = int(temp[1].split(":")[1]) ind_l = 3 with open(raw_input("Saisir le nom du fichier final : "), 'w') as f: # f.write("==========DECRYPTED MESSAGE==========\n") for i in range(0, n): b1 = int(temp[ind_l].split(":")[1]) ind_l += 1 b2 = int(temp[ind_l].split(":")[1]) ind_l += 1 c = int(temp[ind_l].split(":")[1]) ind_l += 1 v = int(temp[ind_l].split(":")[1]) # compute hash b1_hash = sha_256(str(b1)) b2_hash = sha_256(str(b2)) c_hash = sha_256(str(c)) beta = b1_hash + b2_hash + c_hash v2 = (powmod(b1, x1, p) * powmod(b2, x2, p) * powmod( powmod(b1, y1, p) * powmod(b2, y2, p), int(beta, 16), p)) % p # check v and v2 if v == v2: print "Vérification réussie, déchiffrement du bloc " + str( i + 1) + " en cours..." m = (modinv(powmod(b1, w, p), p) * c) % p if len(hex(m)[2:-1]) % 2 != 0: m = hex(m)[2:-1].zfill(len(hex(m)[2:-1]) + 1) m = m.decode("hex") f.write(str(m)) else: m = hex(m)[2:-1].decode("hex") f.write(str(m)) ind_l += 3 # f.write("\n==========END==========") f.close() priv.close() chiffre.close() print "Déchiffrement terminé, vous pouvez trouver le résultat dans le fichier 'message.dec'."
class Rsa: def bit_size(n): s = 1 while n >= 2: r = n % 2 q = n // 2 n = q s = s + 1 return s def rand_int(bitsize): i = 1 res = 1 while i < size: x = randint(0, 1) res = res * 2 + x i = i + 1 return res small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31] # etc. def is_probable_prime(n, k=25): """ Return True if n passes k rounds of the Miller-Rabin primality test(and is probably prime). Return False if n is proved to be composite. """ if n < 2: return False for p in small_primes: if n < p * p: return True if n % p == 0: return False r, s = 0, n - 1 while s % 2 == 0: r += 1 s //= 2 for _ in range(k): a = randrange(2, n - 1) x = pow(a, s, n) if x == 1 or x == n - 1: continue for _ in range(r - 1): x = pow(x, 2, n) if x == n - 1: break else: return False return True def probable_prime(bitsize): n = rand_int(bitsize) if n % 2 == 0: n = n + 1 while True: if is_probable_prime(n): return n else: n = n + 2 def current_time_ms(): return int(round(time.time() * 1000)) def euclide_extended(a, b): r = a rp = b u = 1 v = 0 up = 0 vp = 1 while rp != 0: q = r // rp rs = r us = u vs = v r = rp u = up v = vp rp = rs - q * rp up = us - q * up vp = vs - q * vp return(r, u, v) def write_bigint(f, e): r = e % 2**8 q = e // 2**8 while r != 0 or q != 0: f.write(struct.pack('B', r)) e = (e - r) / 2**8 r = e % 2**8 q = e // 2**8 def read_bigint(f): size = os.path.getsize(f.name) i = 0 a = [] while i < size: x = struct.unpack('B', f.read(1))[0] a.append(x) i = i + 1 a.reverse() res = 0 for y in a: res = res * 2**8 + y return res def gen_keys(): start_time = get_current_time() p = gen_prime(bits) after_p = get_current_time() t1 = (after_p - start_time) / 1000.0 print "p = " + str(p) print "p generated in " + str(t1) + " s" print "p size = " + str(get_size(p)) q = gen_prime(bits) after_q = get_current_time() t2 = (after_q - after_p) / 1000.0 print "q = " + str(q) print "q generated in " + str(t2) + " s" print "q size = " + str(get_size(q)) n = p * q print "n = " + str(n) print "n size = " + str(get_size(n)) f = open("rsa.n", "wb") write_bigint(f, n) f.close() euler = (p-1)*(q-1) print "euler = " + str(euler) print "euler size = " + str(get_size(euler)) e = randint(0, euler) while True: if gcd(e, euler) == 1: break else: e = randint(0, euler) print "e = " + str(e) print "e size = " + str(get_size(e)) f = open(output + ".public.key", "wb") write_bigint(f, e) f.close() (r,u,v) = euclide_extended(e, euler) while u < 0: u = u + euler d = u print "d = "+ str(d) print "d size = " + str(get_size(d)) f = open(output + ".private.key", "wb") write_bigint(f, d) f.close() x =(d * e) % euler print "x = " + str(x) message = 123456789 print "message = " + str(message) cypher = powmod(message, e, n) print "cypher = " + str(cypher) message_back = powmod(cypher, d, n) print "message back = " + str(message_back)