def generatrice(parite): """Methode pour donner la generatrice en fonction de la matrice de parite passee a reorganise, en supposant nbligne < nbcolonne""" dic = parite.reorganise() M = dic["tasse"] rang = len(dic["permut"]) #On decompose M en produit par bloc U,V puis W,Z avec U carre inversible de dim rang U = M.bloc(1,1,rang,rang) V = M.bloc(1,rang+1,rang,M.nbcolonne) Uinv=U.inverse() #On a K de dim n dans le noyau, on le decompose en X,Y de dim resp rang, nbcolonne - rang #La relation fondamentale est X = - U^-1VY #On stocke la transposee de G dans tableau tableau = [] for i in range(M.nbcolonne - rang): Y = matrice(M.nbcolonne - rang,1,[elt(((i+1)//(k+1)) * ((k+1)//(i+1)),2) for k in range(M.nbcolonne-rang)]) X = Uinv*(V*Y) tableau += X.tableau + Y.tableau #On a construit la matrice G' telle que MG'=0 mais M est la tassee G = matrice(M.nbcolonne-rang,M.nbcolonne,tableau).transpose() #On utilise que permut donne acces a P tq M=LHC, L chgt de lignes et C chgt de colonne #MG'=0 LHCG=0 comme L inversible on a G = CG, on applique les chgts de colonnes de M en ligne pour G' for triple in dic["permut"][::-1]: G=G.echange(triple[0]+1,triple[2]+1) return G
def berlekamp(P,mod=2): """Algorithme de Berlekamp pour tester l'irreductibilite d'un polynome""" #Initialisation des outils card = 2**d(mod,0) tableau = [] degre = P.degre() #On regarde pour les racines doubles D = pgcd(P,derivation(P,mod)) if D != 1: return False #On fabrique la matrice de l'application Q -> Q^card modulo P calc = polynome([elt(1,mod)]) X = polynome([0,elt(1,mod)]) X = X.powmod(card,P) for i in xrange(degre): tableau += calc.liste + [0 for k in range(degre-1 - calc.degre())] calc = calc * X % P #On regarde si la matrice qu'on a construite a 1 comme valeur propre #On regarde donc si elle meme - Id possede un vecteur non trivial comme vecteur propre M = matrice(degre,degre,tableau) I =[0 for i in range(degre**2)] I[::degre+1] = [elt(1,mod) for i in range(degre)] I = matrice(degre,degre ,I) rang = len((M-I).gauss(False)["permut"]) return degre - rang == 1
def load(self,fichier): """Methode de chargement d'une clef goppa, l'indicage est le meme que pour la clef privee""" with open(fichier,'rb') as f: string = f.read() liste = string.split("1234567890") n = int(liste[6]) k = int(liste[7]) correction = int(liste[5]) mod = int(liste[4]) #Methode bizarre pour les listes, on enleve la tete, on retourne, on enleve la tete (queue initiale) et on remet dans le bon sens #Ensuite on split car le string initial est '[1,2,3]' gp =(((liste[2][1::])[::-1])[1::])[::-1].split(',') g = [] for i in gp: g.append(elt(int(i),mod)) g = polynome(g) support = [] supportp = (((liste[3][1::])[::-1])[1::])[::-1].split(',') for i in supportp: support.append(elt(int(i),mod)) G = matrice(n,k,string2blocbin(liste[0],k*n)[0].tableau) D = matrice(k,n,string2blocbin(liste[1],k*n)[0].tableau) L_fi = fi(g,support,mod) return clef_correcteur(G,D,g,support,L_fi,mod,correction)
def decodage(generatrice): """Methode pour donner la matrice k,n de decodage telle DG=Ik""" dic = generatrice.reorganise() M = dic["tasse"] rang = len(dic["permut"]) #Normalement si G' est bien concue, elle est de rang k mais autant verifier if rang != generatrice.nbcolonne: print "Toi tu vas avoir des problemes !" #On decompose G' en U,V avec U k,k et V n-k,k bien qu on ne se preoccupe pas de V U = M.bloc(1,1,rang,rang) Uinv = U.inverse() #La matrice D' de decodage est de taille k,n et composée d'abord de Uinv tab = Uinv.transpose().tableau tab +=[0 for i in range(rang * (generatrice.nbligne - rang))] D = matrice(generatrice.nbligne,rang,tab).transpose() #On retrouve D en remelangeant le tout for triple in dic["permut"][::-1]: D=D.echange_colonnes(triple[0]+1,triple[1]+1) D =D.echange(triple[0]+1,triple[2]+1) return D
def load(self,fichier): """Methode de chargement d'une clef publique""" with open(fichier,'rb') as f: string = f.read() liste = string.split("1234567890") correction = int(liste[0]) n = int(liste[1]) k = int(liste[2]) Gprime = matrice(n,k,string2blocbin(liste[3],k*n)[0].tableau) return clef_publique(Gprime,correction)
def chiffrer(self,f_source,f_cible): """Methode pour chiffrer le message Reste a savoir comment on se forme le message : liste de vecteurs""" message = file2blocbin(f_source,self.Gprime.nbcolonne) resultat = [] for vecteur in message: erreur = [0 for i in range(self.Gprime.nbligne)] for i in range(self.correction): erreur[randint(0,self.Gprime.nbligne-1)]=elt(1,2) erreur = matrice(self.Gprime.nbligne,1,erreur) resultat.append((self.Gprime * vecteur) + erreur) blocbin2file(f_cible,resultat,False)
def string2blocbin(string,k): """Convertit un string en bloc de binaire""" chaine = string2bin(string) liste = [] while chaine !='': morceau = chaine[:k:] chaine = chaine[k::] vecteur = [] for i in morceau: vecteur.append(elt(int(i),2)) vecteur = vecteur + [0 for i in range(k - len(vecteur))] liste.append(matrice(k,1,vecteur)) return liste
def parite(g,support,mod): """Methode de calcul de la matrice de parite a partir de g et du support""" #Initialisation des variables dg = g.degre() dmod = d(mod,0) card = 2**dmod M = [0 for i in xrange(dg*card*dmod)] L = [0 for i in xrange(dg*card)] #Fabrication de la matrice de parite dans galois cf p.99 04cc for i in xrange(card): h=1/g(support[i]) for j in xrange(dg): L[i+j*card]=h h *= support[i] #Transformation de la matrice dans Z/2Z for i in xrange(len(L)): for j in xrange(dmod): M[i% card + ((i//card)*dmod + j)*card] = elt(L[i].valeur>>j & 1,2) M = matrice(dmod*dg,card,M) return M