#################### vorgegebene Alphabete ########################### A1 := [ '1','2','3','4','5','6','7','8','9', '0','A', 'B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',')' , '(' , ',' , '.', '=','!','?','a','b','c','d','e','f','g','h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' ']; A2 := [ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']; A3 := ['0','1']; NumbersToText := function(L,alphabet) return(List(L, i-> alphabet[i+1])); end; TextToNumbers := function(text,alphabet) return(List(text, i-> (Position(alphabet,i)-1))); end; TextAnalysis := function(text,alphabet) return(List(alphabet, i-> [i,Length(Filtered(text, j-> j=i))])); end; SplitText := function(text,n,alphabet) local fill,t,T; T := ListSplit(text,n); t := Length(T[Length(T)]); fill := alphabet[Length(alphabet)]; Append(T[Length(T)], List([t+1..n], i-> fill)); return(T); end; Vigenere := function(Block, key,alphabet) local S,B,Cipher; S := TextToNumbers(key,alphabet); B := TextToNumbers(Block, alphabet); Cipher := NumbersToText(List([1..Length(S)], i-> (S[i]+B[i]) mod Length(alphabet)), alphabet); return(Cipher); end; InverseKey := function(key,alphabet) return(NumbersToText(List(TextToNumbers(key,alphabet), i-> -i mod Length(alphabet)),alphabet)); end; Addition := function(B1,B2,alphabet) local A1,A2,Add; A1 := TextToNumbers(B1, alphabet); A2 := TextToNumbers(B2, alphabet); Add := List([1..Length(A1)], i-> (A1[i]+A2[i]) mod Length(alphabet)); Add := NumbersToText(Add, alphabet); return(Add); end; Subtraction := function(B1,B2,alphabet) local A1,A2,Sub; A1 := TextToNumbers(B1, alphabet); A2 := TextToNumbers(B2, alphabet); Sub := List([1..Length(A1)], i-> (A1[i]-A2[i]) mod Length(alphabet)); Sub := NumbersToText(Sub, alphabet); return(Sub); end; Permutation := function(Block, key, alphabet) local L; L := TextToNumbers(Block,alphabet); L := NumbersToText(List(key, i-> L[i]),alphabet); return(L); end; AffinLinear := function(Block, key,alphabet) local A,b,x,y,Cipher; A := key[1]; b := MatTrans(Mat(TextToNumbers(key[2], alphabet))); x := MatTrans(Mat([TextToNumbers(Block, alphabet)])); y := List(MatToColList(MatTrans(A*x + b)), i-> i[1]); y := List(y, i-> i mod Length(alphabet)); Cipher := NumbersToText(y,alphabet); return(Cipher); end; AffinInverse := function(M,alphabet) local a,b,L; a := Length(alphabet); b := Filtered([1..a], i-> (i*MatDet(M) mod a =1))[1]; L := List(MatToRowList(MatInv(M)), i-> List(i, j-> j*Den(j) mod a)); return(b*Mat(L)); end; ################################### ECB ######################################### ### Encipher: ECB(text, method, key, alphabet) #### ### Ex. : c := ECB("HEUTE GEHT ES MIR GUT", Vigenere, "WIE", A1); #### ### #### ### Decipher: ECB(text, method, InverseKey(key), alphabet); #### ### Ex. : ECB(c, Vigenere, InverseKey("WIE",A1), A1); #### ##################################################################################### ECB := function(text, method, key, alphabet) local ListOfBlocks,BlockCipher,n; n := Length(key); ListOfBlocks := SplitText(text,n,alphabet); BlockCipher := Concatenation(List(ListOfBlocks, i-> method(i, key, alphabet))); BlockCipher := List([1..Length(text)], i-> BlockCipher[i]); return(BlockCipher); end; ################################### CBC ################################################ ### Encipher: CBC(text, method, Initialvektor, key, alphabet) #### ### Ex. : c := CBC("HEUTE GEHT ES MIR GUT", Vigenere, "INITIALVEK", "SCHLUESSEL",A1); #### ### #### ### Decipher: PlainCBC(text, method, Initialvektor, key, alphabet) #### ### Ex. : PlainCBC(c, Vigenere, "INITIALVEK", "SCHLUESSEL",A1); #### ############################################################################################### CBC := function(text, method, IV, key, alphabet) local n,Cipher,ListOfBlocks,xx; n := Length(key); Cipher := []; Cipher[1] := IV; ListOfBlocks := [ IV ]; Append(ListOfBlocks,SplitText(text,n,alphabet)); for xx in [2..Length(ListOfBlocks)] do Cipher[xx] := method( Addition(Cipher[xx-1] , ListOfBlocks[xx], alphabet), key, alphabet); od; Cipher := Concatenation(List([2..Length(Cipher)], i-> Cipher[i])); Cipher := List([1..Length(text)], i-> Cipher[i]); return(Cipher); end; PlainCBC := function(text, method, IV, key, alphabet) local n,Cipher,Plain,xx; n := Length(key); Cipher := []; Cipher := [IV]; Append(Cipher, SplitText(text,n,alphabet)); Plain := []; for xx in [2..Length(Cipher)] do Plain[xx-1] := Subtraction( method(Cipher[xx],InverseKey(key,alphabet), alphabet), Cipher[xx-1], alphabet); od; Plain := Concatenation(Plain); Plain := List([1..Length(text)], i-> Plain[i]); return(Plain); end; ChiffreAnalyse := function(text, blocklength, alphabet) local TBlock, L,xx; if Length(text) mod blocklength <> 0 then Print("Blocklength should divide textlengt \n"); Sleep(1); return([]); fi; TBlock := ListSplit(text,blocklength); L := List([1..blocklength], i-> List(alphabet, k-> [k, Length(Filtered(List(TBlock, j-> j[i]),l-> l=k)) ])); for xx in [1..Length(alphabet)] do Print(alphabet[xx], " | "); od; Print("\n"); return(L); end; b_adicRep := function(n,a) local T,lambda1,zz,j,k; if IsInt(a) and IsInt(n) and a > 1 then lambda1 := n mod a; T := []; T[1] := lambda1; zz := 2; while Sum(List([1..Length(T)], i-> T[i]*a^(i-1))) < n do k := n mod a^zz; j := (k-lambda1)/(a^(zz-1)); T[zz] := j; lambda1 := k; zz := zz+1; od; return(Reversed(T)); else Print("Error, usage: b_adicRep(, ) \n"); fi; end; PermMut := function(P1,P2) return(List([1..Length(P2)], i-> P1[P2[i]])); end; InversPerm := function(P) local id,T,xx,I; id := [1..Length(P)]; T := Copy(P); xx := 1; I := id; while T <> id do I := T; T := PermMut(T,P); xx := xx+1; od; return(I); end; E := function(key,text) local P,L; L := ECB(text, Vigenere, key, A1); P := [2,1,3]; return(ECB(L, Permutation, P, A1)); end; D := function(key,text) local P,L; P := [2,1,3]; L := ECB(text, Permutation,InversPerm(P),A1); return(ECB(L, Vigenere, InverseKey(key,A1),A1)); end;