ISNJQR / TIPE-Cryptage

0 stars 0 forks source link

RSA #7

Open ISNJQR opened 7 years ago

ISNJQR commented 7 years ago

import random
from math import sqrt
from os import chdir
from os import getcwd

chdir("E:\\TIPE")

Entrée = open("Texte à coder.txt","r")
Sortie = open("Texte à décrypter.txt","w")

# Initialisation des fonctions

def modexp ( g, u, p ):
    s = 1
    while u != 0:
        if u & 1:
            s = (s * g)%p
        u >>= 1
        g = (g * g)%p
    return s

def eratosthene(n):
   """retourne la tableau des nombres premiers <= n (crible d'eratosthene)"""
   n += 1
   tableau = [0,0] + [i for i in range(2, n)]
   for i in range(2, n):
       if tableau[i] != 0:
           # c'est un nombre 1er: on garde, mais on supprime ses multiples
           for j in range(i*2, n, i):
               tableau[j] = 0
   return [p for p in tableau if p!=0]

def pgcd(a,b) :  
  while a%b != 0 : 
     a, b = b, a%b 
  return b

#Définition de p et q

nombre=random.randint(1000000,3000000)

L=eratosthene(nombre)

p=random.choice(L)
q=random.choice(L)

#RSA

N, M = p * q, (p-1) * (q-1)

# Puis on doit trouver C et U. Pour ça, on sait que C doit impérativement être
# premier avec M, et on sait aussi que U se détermine grâce à l'algorithme de
# Bézout

def bezout(a, b) -> tuple:
   r0, u0, v0 = a, 1, 0
   r1, u1, v1 = b, 0, 1
   while r1 != 0:
       u0, u1 = u1, u0 - (r0 // r1) * u1
       v0, v1 = v1, v0 - (r0 // r1) * v1
       r0, r1 = r1, r0 % r1
   return r0, u0, v0

# En fait, Bézout peut même dire si C et M sont premiers entre eux :

boycott = 256    # boycott sert juste à s'assurer qu'on ne passe pas des heures
while boycott:   # à chercher un C correct
   boycott -= 1

   C = random.randrange(M, N)

   r0, r1, U, u1 = C, M, 1, 0
   while r1:
       r0, r1, U, u1 = r1, r0 % r1, u1, U - (r0 // r1) * u1

   # On sait que si r0 vaut 1, alors C et M sont premiers entre eux.
   if r0 == 1:
       # Mais il est probable que U soit négatif.
       if U < 0:
           # Pour trouver son équivalent positif on doit trouver un
           # k négatif rendant vrai l'expression 2 < U - k * M < M
           k = -1
           while not 2 < U - k * M < M:
               k -= 1
           U = U - k * M
       # Enfin on a tous nos nombres pour les clés RSA
       break # On peut donc quitter la boucle while sans passer par le else.

else: # Si boycott a atteint 0, le mieux reste de le dire :
   raise RuntimeError

print("U= ",U)
print("N= ",N)

Texte=Entrée.read()
CodeASCII=[]

for j in range(0,len(Texte)):
   CodeASCII.append(0)

for i in range(0,len(Texte)):
   a=ord(Texte[i])
   CodeASCII[i]=(modexp(a,C,N))

texte_crypté=[]

for k in range(len(CodeASCII)):
   texte_crypté.append(str(CodeASCII[k]))

for k in range(len(CodeASCII)):
   Sortie.write(texte_crypté[k])
   Sortie.write(",")

Entrée.close()
Sortie.close()
LorisBerthelot45 commented 7 years ago

import random
from math import sqrt
from os import chdir
from os import getcwd

chdir("E:\\TIPE")

Entrée = open("Texte à décrypter.txt","r")
Sortie = open("Texte décrypté.txt","w")

def modexp ( g, u, p ):
  """computes s = (g ^ u) mod p
     args are base, exponent, modulus
     (see Bruce Schneier's book, _Applied Cryptography_ p. 244)"""
  s = 1
  while u != 0:
     if u & 1:
        s = (s * g)%p
     u >>= 1
     g = (g * g)%p;
  return s

u=input("Clef privée : U = ")
U=int(u)
n=input("Clef privée : N = ")
N=int(n)

Texte=Entrée.read()
CodeASCII=[]

Code=""
for i in range(len(Texte)):
    if Texte[i]==",":
        CodeASCII.append(int(Code))
        Code=""
    else:
        Code+=Texte[i]

ASCIItoLettres=""

for k in range(0,len(CodeASCII)):
    b=CodeASCII[k]
    ASCIItoLettres+=chr(modexp(b,U,N))

Sortie.write(ASCIItoLettres)
Entrée.close()
Sortie.close()