Cryptographie

Cryptographie

vonneumann = "enmathematiquesonnecomprendpasleschosesonsyhabitue"
russell="Les mathématiques sont la seule science où on ne sait pas de quoi on parle ni si ce qu'on dit est vrai."
shadok="En essayant continuellement on finit par réussir. Donc : plus ça rate, plus on a de chance que ça marche."

## Chaines

def chaine_vers_liste(s):
    l=[]
    for lettre in s:
        l.append(ord(lettre))
    return l

def liste_vers_chaine(l):
    s=""
    for n in l:
        s += chr(n)
    return s

## Cesar
def code_cesar(message,n):
    result = ''
    for lettre in message:
        code = 97+((ord(lettre)+n-97)%26)
        result += chr(code)
    return result

def decode_cesar(message,n):
    result = ''
    for lettre in message:
        code = 97+((ord(lettre)-n-97)%26)
        result += chr(code)
    return result

def cryptanalyse_cesar1(message):
    for k in range(1,60):
        print(decode_cesar(message,k))

## Vigenere
def code_vigenere(message,clef):
    result = ''
    for i in range(len(message)):
        lettre = message[i]
        code = code_cesar(lettre,ord(clef[i%len(clef)])-97)
        result += code
    return result

def decode_vigenere(message,clef):
    result = ''
    for i in range(len(message)):
        lettre = message[i]
        code = decode_cesar(lettre,ord(clef[i%len(clef)])-97)
        result += code
    return result

## RSA

import random as rd

def isPrime(n):
    if n<=1: return False
    if n%2 == 0: return False
    if n%3 == 0: return False
    k=5
    while (k*k <= n):
        if n % k ==0: return False
        if n % (k+2) == 0: return False
        k+=6
    return True

def euclide(a,b):
    n=a
    m=b
    while m>0:
        n,m = m,n%m
    return n

def bezout(a,b):
    u,v,uu,vv = 1,0,0,1
    while b>0:
        q,rr = a//b,a % b
        a,b = b,rr
        u,uu = uu,u-q*uu
        v,vv = vv,v-q*vv
    return a,u,v

min=100
max=999

def gen_keys():
    # Generation des nombres premiers
    p = rd.randint(min,max)
    while not isPrime(p):
        p = rd.randint(min,max)
    q = rd.randint(min,max)
    while (not isPrime(q)) or q==p:
        q = rd.randint(min,max)
    n = p*q
    phi = (p-1)*(q-1)
    # Generation de e et d
    d = rd.randint(phi//2,phi)
    gcd,_,e=bezout(phi,d)
    while not (gcd==1):
        d = rd.randint(phi//2,phi)
        gcd,_,e = bezout(phi,d)
    if e<0: e +=phi
    # print(phi)
    return ([n,e],[n,d])

pubkey,privkey = gen_keys()
print(pubkey,privkey)

def code_rsa_simple(message,pubkey):
    n,e = pubkey
    message = [ord(s) for s in message]
    code = [pow(num,e,n) for num in message]
    return " ".join([str(k) for k in code])

def decode_rsa_simple(message,privkey):
    n,d = privkey
    message = message.split(' ')
    decode = [pow(int(num),d,n) for num in message]
    decode = [chr(num) for num in decode]
    decode = "".join(decode)
    return decode

exm_simple = code_rsa_simple(russell,pubkey)

def troischiffres(s):
    if len(s)==1:
        return '00'+str(s)
    if len(s)==2:
        return '0'+str(s)
    if len(s)==3:
        return s

def message_bloc(s):
    message = [troischiffres(str(ord(lettre))) for lettre in s]
    message = ''.join(message)
    n=len(message)
    if n%4 == 1:
        message = '000'+message
    if n%4 == 2:
        message = '00'+message
    if n%4 == 3:
        message = '0'+message
    message = [int(message[i:i+4]) for i in range(0,len(message),4)]
    return message

def code_rsa(message,pubkey):
    n,e = pubkey
    message = message_bloc(message)
    code = [pow(lettre,e,n) for lettre in message]
    return " ".join([str(num) for num in code])

def quatrechiffres(s):
    if len(s)==1:
        return '000'+str(s)
    if len(s)==2:
        return '00'+str(s)
    if len(s)==3:
        return '0'+str(s)
    if len(s)==4:
        return s

def message_unbloc(s):
    message = [quatrechiffres(str(num)) for num in s]
    message = ''.join(message)
    n=len(message)
    if n%3 == 1:
        message = message[1:]
    if n%3 == 2:
        message = message[2:]
    message = [int(message[i:i+3]) for i in range(0,len(message),3)]
    return message

def decode_rsa(message,privkey):
    n,d= privkey
    message = message.split(sep=' ')
    decode = [pow(int(s),d,n) for s in message]
    decode = message_unbloc(decode)
    if decode[0]==0:
        decode = decode[1:]
    return "".join([chr(num) for num in decode])
    # return pow(message,d,n)

foo = code_rsa(russell,pubkey)

## Analyse frequencielle

def analyse_freq(s):
    stats = [0 for k in range(26)]
    lettres = [chr(k) for k in range(97,97+26)]
    for lettre in s:
        if not (ord(lettre) >= 97 and ord(lettre)<=97+26):
            print(lettre)
        stats[ord(lettre)-97] += 1
    return list(zip(stats,lettres))

verne = open("/home/kevin/Code/Python/Python_vrac/Verne.txt",'r')
ligne = verne.read()
verne.close()

tab = analyse_freq(ligne)
tot=0
for f,let in tab:
    tot+=f

for i in range(26):
    tab[i] = (tab[i][0]/tot,tab[i][1])

import matplotlib.pyplot as plt

# plt.bar([j for i,j in tab],[i for i,j in tab])
# plt.show()

def max_et_reste(l):
    m=0
    j = 0
    for i in range(len(l)):
        freq,lettre = l[i]
        if freq > m:
            j = i
            m=freq
    return l[j][1],l[0:j]+l[j+1:]

def analyse_cesar(message):
    stats = analyse_freq(message)
    max=0
    for i in range(26):
        if stats[i] > stats[max]:
            max = i
    lettremax = chr(max+97)
    tabfreq = tab
    b=False
    while not b:
        lettre,tabfreq = max_et_reste(tabfreq)
        print("Déchiffrement avec la clef",ord(lettre)-97)
        clef = ord(lettremax) - ord(lettre)
        print(decode_cesar(message,clef))
        b = bool(int(input("Message valide ? (0 non, 1 oui)\n")))
    return 0

analyse_cesar(code_cesar(vonneumann,10))