Criptare.cpp
#include<stdio.h>
#include<string>
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
#define Nb 4 //nr de coloane
#define Nk 4 //nr de cuvinte pt Cyper Key
#define Nr 10 //nr de runde
#define MAX 1000 //nr max de caractere din fisier
unsigned char key[16],in[4*Nb],temp[MAX],
w[Nb*(Nr+1)][Nb], //matrice in care retinem cate un cuvant de 32 biti pe fiecare linie
state[4][Nb];
unsigned char Rcon[4][10]= {0×01, 0×02, 0×04, 0×08, 0×10, 0×20, 0×40, 0×80, 0×1b, 0×36,
0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00,
0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00,
0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00 };
int k=0,//nr de caractere citite din fisier
b=0;//nr de blocuri de 128 biti
unsigned char SBox(unsigned char num)
{
int sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0×63, 0×7c, 0×77, 0×7b, 0xf2, 0×6b, 0×6f, 0xc5, 0×30, 0×01, 0×67, 0×2b, 0xfe, 0xd7, 0xab, 0×76, //0
0xca, 0×82, 0xc9, 0×7d, 0xfa, 0×59, 0×47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0×9c, 0xa4, 0×72, 0xc0, //1
0xb7, 0xfd, 0×93, 0×26, 0×36, 0×3f, 0xf7, 0xcc, 0×34, 0xa5, 0xe5, 0xf1, 0×71, 0xd8, 0×31, 0×15, //2
0×04, 0xc7, 0×23, 0xc3, 0×18, 0×96, 0×05, 0×9a, 0×07, 0×12, 0×80, 0xe2, 0xeb, 0×27, 0xb2, 0×75, //3
0×09, 0×83, 0×2c, 0×1a, 0×1b, 0×6e, 0×5a, 0xa0, 0×52, 0×3b, 0xd6, 0xb3, 0×29, 0xe3, 0×2f, 0×84, //4
0×53, 0xd1, 0×00, 0xed, 0×20, 0xfc, 0xb1, 0×5b, 0×6a, 0xcb, 0xbe, 0×39, 0×4a, 0×4c, 0×58, 0xcf, //5
0xd0, 0xef, 0xaa, 0xfb, 0×43, 0×4d, 0×33, 0×85, 0×45, 0xf9, 0×02, 0×7f, 0×50, 0×3c, 0×9f, 0xa8, //6
0×51, 0xa3, 0×40, 0×8f, 0×92, 0×9d, 0×38, 0xf5, 0xbc, 0xb6, 0xda, 0×21, 0×10, 0xff, 0xf3, 0xd2, //7
0xcd, 0×0c, 0×13, 0xec, 0×5f, 0×97, 0×44, 0×17, 0xc4, 0xa7, 0×7e, 0×3d, 0×64, 0×5d, 0×19, 0×73, //8
0×60, 0×81, 0×4f, 0xdc, 0×22, 0×2a, 0×90, 0×88, 0×46, 0xee, 0xb8, 0×14, 0xde, 0×5e, 0×0b, 0xdb, //9
0xe0, 0×32, 0×3a, 0×0a, 0×49, 0×06, 0×24, 0×5c, 0xc2, 0xd3, 0xac, 0×62, 0×91, 0×95, 0xe4, 0×79, //A
0xe7, 0xc8, 0×37, 0×6d, 0×8d, 0xd5, 0×4e, 0xa9, 0×6c, 0×56, 0xf4, 0xea, 0×65, 0×7a, 0xae, 0×08, //B
0xba, 0×78, 0×25, 0×2e, 0×1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0×74, 0×1f, 0×4b, 0xbd, 0×8b, 0×8a, //C
0×70, 0×3e, 0xb5, 0×66, 0×48, 0×03, 0xf6, 0×0e, 0×61, 0×35, 0×57, 0xb9, 0×86, 0xc1, 0×1d, 0×9e, //D
0xe1, 0xf8, 0×98, 0×11, 0×69, 0xd9, 0×8e, 0×94, 0×9b, 0×1e, 0×87, 0xe9, 0xce, 0×55, 0×28, 0xdf, //E
0×8c, 0xa1, 0×89, 0×0d, 0xbf, 0xe6, 0×42, 0×68, 0×41, 0×99, 0×2d, 0×0f, 0xb0, 0×54, 0xbb, 0×16 }; //F
return (unsigned char) sbox[num];
}
//ExpansionKey
void KeyExpansion()
{
unsigned char temp[Nb],aux;
int i=0;
//impartim key in 4 cuvinte w1,w2,w3,w4 – le retinem intr-o matrice pe fiecare linie cate un cuvant
while (i<Nk)
{
for(int j=0;j<4;j++)
w[i][j]=key[4*i+j];
i+=1;
}
//afisam cuvintele initiale formate din key
cout<<endl<<”Cuvintele initiale:”<<endl;
for(int m=0;m<Nk;m++)
{
cout<<”w["<<m<<"]=”;
for(int j=0;j<4;j++)
printf(“%02x”,w[m][j]);
cout<<endl;
}
cout<<endl;
//avem deja i=Nk
//urmatoarele runde se formeaza din rezultatul obtinut in runda anterioara
while (i<Nb*(Nr+1))
{
//primul temp este ultimul cuvant (w3) apoi se calculeaza pentru fiecare rezultat obtinut
for(int j=0;j<Nb;j++)
temp[j]=w[i-1][j];
if (i % Nk == 0)
{
//afisam temp
cout<<endl<<endl<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
//RotWord(temp)
aux=temp[0]; temp[0] = temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3]=aux;
//afisam temp dupa RotWord – muta primul byte la sfarsit
cout<<endl<<”Dupa RotWord:”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
//SubWord(RotWord(temp)) – se ablica s-box pentru fiecare particica din cuvant
for(int j=0;j<Nb;j++)
temp[j]=SBox(temp[j]);
//afisam temp dupa SubWord(RotWord(temp))
cout<<endl<<”Dupa SubWord(RotWord(temp)):”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
//afisam Rcon[i/Nk]
cout<<endl<<”Rcon[i/Nk]=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,Rcon[j][i/Nk-1]);//Rcon porneste de la pozitia 1
cout<<endl;
for(int j=0;j<Nb;j++)
temp[j]=temp[j]^Rcon[j][i/Nk-1];
//afisam temp dupa SubWord(RotWord(temp)) xor Rcon[i/Nk]
cout<<”Dupa SubWord(RotWord(temp)) xor Rcon[i/Nk]:”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
cout< 6 && i % Nk == 4)
{
//SubWord(temp) – se ablica s-box pentru fiecare particica din cuvant
for(int j=0;j<Nb;j++)
temp[j]=SBox(temp[j]);
//afisam temp dupa SubWord(temp)
cout<<endl<<”Dupa SubWord(temp):”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
}//if
//Afiseaza w[i-Nk]
/*cout<<”w*["<<i-Nk<<"]=”;
for(int j=0;j<Nb;j++){
printf(“%02x”,w[i-Nk][j]);}cout<<endl;*/
//w[i]=w[i-Nk] xor temp
for(int j=0;j<Nb;j++)
w[i][j]=w[i-Nk][j]^temp[j];
//Afiseaza cuvintele w[i]
cout<<”w["<<i<<"]=”;
for(int j=0;j<Nb;j++){
printf(“%02x”,w[i][j]);}cout<<endl;
i+=1;
}//while
}//ExpansionKey
//AddRoundKey
void AddRoundKey(int round)
{
//Afisam RoundKey value
cout<<”RoundKey:”<<endl;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,w[round * 4 + j][i]); //cuvintele le afisam pe coloana
}
cout<<endl;
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
state[j][i] = state[j][i] ^ w[round * 4 + i][j]; //trebuie sa ia fiecare cuv de la w[0] la w[44], cuvintele sunt aranjate pe linie
}
}
}
//SubByte
void SubBytes()
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
state[i][j] = SBox(state[i][j]);
}
}
}
//Shift Rows
void ShiftRows()
{
unsigned char aux,aux1;
//Prima linie ramane intacta
//Rotim a doua linie
aux=state[1][0];
for(int i=0;i<3;i++)
state[1][i]=state[1][i+1];
state[1][3]=aux;
// Rotim a treia linie
for(int j=0;j<2;j++)
{
aux=state[2][0];
for(int i=0;i<3;i++)
state[2][i]=state[2][i+1];
state[2][3]=aux;
}
// Rotim a patra linie
for(int j=0;j<3;j++)
{
aux=state[3][0];
for(int i=0;i<3;i++)
state[3][i]=state[3][i+1];
state[3][3]=aux;
}
}
unsigned char xtime(unsigned char x)
{
if(x<0×80) //daca x<10000000 -adica nu are pe primul bit 1 – mutam 0 la sfarsit (shiftam la stanga)
x=x<-10000000 – adica are pe primul bit 1 – shiftam la stanga (adaugam 0 la sfarsit) si adunam (xor) m(x)=100011011 .. 1 se reduc deci vom ramane cu 00011011 care este 0×1b
x=(x<<1)^0×1b; //extra xor
return (unsigned char) x;
}
//MixColumns — pt 03*S = S xor xtime(S) ; 02*S = xtime(S) ; 01*S = S
void MixColumns()
{
unsigned char s[4];
//Pentru fiecare coloana
for(int i=0;i<4;i++)
{
s[0]=xtime(state[0][i])^(state[1][i]^xtime(state[1][i]))^state[2][i]^state[3][i];
s[1]=state[0][i]^xtime(state[1][i])^(state[2][i]^xtime(state[2][i]))^state[3][i];
s[2]=state[0][i]^state[1][i]^xtime(state[2][i])^(state[3][i]^xtime(state[3][i]));
s[3]=(state[0][i]^xtime(state[0][i]))^state[1][i]^state[2][i]^xtime(state[3][i]);
//copiem in coloana respectiva valorile obtinute
for(int j=0;j<4;j++)
{
state[j][i]=s[j];
}
}
}
/*
void MixColumns()
{
int i;
unsigned char Tmp,Tm,t;
for(i=0;i<4;i++)
{
t=state[0][i];
Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;
Tm = state[0][i] ^ state[1][i] ;
Tm = xtime(Tm);
state[0][i] ^= Tm ^ Tmp ;
Tm = state[1][i] ^ state[2][i] ;
Tm = xtime(Tm);
state[1][i] ^= Tm ^ Tmp ;
Tm = state[2][i] ^ state[3][i] ;
Tm = xtime(Tm);
state[2][i] ^= Tm ^ Tmp ;
Tm = state[3][i] ^ t ;
Tm = xtime(Tm);
state[3][i] ^= Tm ^ Tmp ;
}
}
*/
//Cyper
void Cyper()
{
int round=0;
//Copiem in state inputul
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
state[j][i] = in[i*4 + j]; //se aseaza pe coloana
}
}
//Afisam inputul
cout<<endl;
cout<<”Input:”<<endl;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
AddRoundKey(round);
//Rundele Nr-1
for(round=1;round<Nr;round++)
{
//Afisam Inputul pt fiecare runda
cout<<endl;
printf(“Start of round:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
SubBytes();
//State dupa SubByte
printf(“Dupa SubByte:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
ShiftRows();
//State dupa ShiftRows
printf(“Dupa ShiftRows:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
MixColumns();
//State dupa MixColumns
printf(“Dupa MixColumns:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
AddRoundKey(round);
}//for
//Ultima runda – nu are MixColumns()
SubBytes();
//State dupa SubBytes
printf(“Dupa SubBytes:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
ShiftRows();
//State dupa ShiftRows
printf(“Dupa ShiftRows:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
AddRoundKey(Nr);
//Afisam outputul
cout<<endl;
cout<<”Output:”<<endl;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
}//Cyper
//Functie care citeste textul dintr-un fisier si il salveaza in alt fisier in format hexa
void Text2Hexa()
{
char text;
ifstream intext(“inputText.txt”,ios::in);
ofstream outtext(“inputTextHexa.txt”,ios::out);
while(intext.get(text))
{
outtext<<hex<<(unsigned int)(unsigned char) text;
}
intext.close();
outtext.close();
}
//Functia care citeste Key in format hexa si o saveaza intr-un vector key[16]
void citesteKey()
{
FILE *infile=fopen(“key.txt”, “r”);
rewind(infile);
for(int i=0;i<Nk*4 ;i++)
{
if(fscanf_s(infile,”%02x”,&key[i])!=EOF)
printf(“%02x “,key[i]);
}
cout<<endl;
fclose(infile);
}
//Functie care citeste textul in format hexa si il salvam intr-un vector temp[MAX]
void citesteHexaText()
{
FILE *infile=fopen(“inputTextHexa.txt”, “r”);
rewind(infile);
for(int i=0;i<sizeof(temp) ;i++){
if(fscanf_s(infile,”%02x”,&temp[i])!=EOF)
k++;
}
fclose(infile);
cout<<endl;
}
void afiseazaOutputHexa()
{
FILE *outfile=fopen(“outputTextCriptatHexa.txt”, “a” );
//feof(outfile);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
fprintf(outfile,”%02x”,state[j][i]);
fclose(outfile);
cout<<endl<<”Am salvat in outputTextCriptatHexa”<<endl;
}
void afiseazaOutputText()
{
FILE *outfile2=fopen(“outputTextCriptat.txt”, “a” );
feof(outfile2);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
fprintf(outfile2,”%c”,(unsigned int) state[j][i]);
cout<<(unsigned int) state[j][i];
}
fclose(outfile2);
cout<<endl<<”Am salvat in outputTextCriptat”<<endl;
}
//Functie care calculeaza numarul de blocuri de 128 de biti care se formeaza pentru textul din fisier
void nrBlocuri()
{
if(k%(Nb*4)==0)
b=k/(Nb*4);
else
b=(k/(Nb*4))+1;
cout<<”Nr de blocuri de 128 biti:”<<b<<endl;
}
//Functie care face o matrice in care pe fiecare linie este salvat un bloc de 128 biti si de aici criptam fiecare bloc
void blocuri()
{
unsigned char (*bloc)[Nb*4]=new unsigned char [b][Nb*4];
int m=0;
//elementele din vectorul temp sunt copiate in matrice
for(int j=0;j<b;j++)
for(int a=0;a<Nb*4;a++)
{
bloc[j][a]=temp[m];
m++;
}
//afisam matricea
for(int j=0;j<b;j++)
{
for(int a=0;a<Nb*4;a++)
printf(“%02x “,bloc[j][a]);
cout<<endl;
}
//lucram pe fiecare linie a matricii
for(int j=0;j<b;j++)
{
for(int a=0;a<Nb*4;a++)
//copiem linia curenta in vectorul in[] care este de fapt un bloc de 128 biti si il criptam
in[a]=bloc[j][a];
Cyper();
afiseazaOutputHexa();
afiseazaOutputText();
}
}
void main()
{
cout<<endl<<”Citim textul din fisier si il salvam in alt fisier in format hexa.”<<endl;
Text2Hexa();
cout<<endl<<”Citim key.”<<endl;
citesteKey();
cout<<endl<<”Citim textul in format hexa si il punem intr-un vector.”<<endl;
citesteHexaText();
cout<<endl<<”Calculam nr de blocuri.”<<endl;
nrBlocuri();
cout<<endl<<”ExpansionKey”<<endl;
KeyExpansion();
cout<<endl<<”Matrice cu toate blocurile de 128 de biti. Fiecare bloc este criptat separat.”<<endl;
blocuri();
}
***********************************************************************
Decriptare.cpp
#include<stdio.h>
#include<string>
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
#define Nb 4 //nr de coloane
#define Nk 4 //nr de cuvinte pt Cyper Key
#define Nr 10 //nr de runde
#define MAX 1000 //nr max de caractere din fisier
unsigned char key[16],in[4*Nb],temp[MAX],
w[Nb*(Nr+1)][Nb], //matrice in care retinem cate un cuvant de 32 biti pe fiecare linie
state[4][Nb];
unsigned char Rcon[4][10]= {0×01, 0×02, 0×04, 0×08, 0×10, 0×20, 0×40, 0×80, 0×1b, 0×36,
0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00,
0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00,
0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00 };
int k=0,//nr de caractere citite din fisier
b=0;//nr de blocuri de 128 biti
unsigned char SBox(unsigned char num)
{
int sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0×63, 0×7c, 0×77, 0×7b, 0xf2, 0×6b, 0×6f, 0xc5, 0×30, 0×01, 0×67, 0×2b, 0xfe, 0xd7, 0xab, 0×76, //0
0xca, 0×82, 0xc9, 0×7d, 0xfa, 0×59, 0×47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0×9c, 0xa4, 0×72, 0xc0, //1
0xb7, 0xfd, 0×93, 0×26, 0×36, 0×3f, 0xf7, 0xcc, 0×34, 0xa5, 0xe5, 0xf1, 0×71, 0xd8, 0×31, 0×15, //2
0×04, 0xc7, 0×23, 0xc3, 0×18, 0×96, 0×05, 0×9a, 0×07, 0×12, 0×80, 0xe2, 0xeb, 0×27, 0xb2, 0×75, //3
0×09, 0×83, 0×2c, 0×1a, 0×1b, 0×6e, 0×5a, 0xa0, 0×52, 0×3b, 0xd6, 0xb3, 0×29, 0xe3, 0×2f, 0×84, //4
0×53, 0xd1, 0×00, 0xed, 0×20, 0xfc, 0xb1, 0×5b, 0×6a, 0xcb, 0xbe, 0×39, 0×4a, 0×4c, 0×58, 0xcf, //5
0xd0, 0xef, 0xaa, 0xfb, 0×43, 0×4d, 0×33, 0×85, 0×45, 0xf9, 0×02, 0×7f, 0×50, 0×3c, 0×9f, 0xa8, //6
0×51, 0xa3, 0×40, 0×8f, 0×92, 0×9d, 0×38, 0xf5, 0xbc, 0xb6, 0xda, 0×21, 0×10, 0xff, 0xf3, 0xd2, //7
0xcd, 0×0c, 0×13, 0xec, 0×5f, 0×97, 0×44, 0×17, 0xc4, 0xa7, 0×7e, 0×3d, 0×64, 0×5d, 0×19, 0×73, //8
0×60, 0×81, 0×4f, 0xdc, 0×22, 0×2a, 0×90, 0×88, 0×46, 0xee, 0xb8, 0×14, 0xde, 0×5e, 0×0b, 0xdb, //9
0xe0, 0×32, 0×3a, 0×0a, 0×49, 0×06, 0×24, 0×5c, 0xc2, 0xd3, 0xac, 0×62, 0×91, 0×95, 0xe4, 0×79, //A
0xe7, 0xc8, 0×37, 0×6d, 0×8d, 0xd5, 0×4e, 0xa9, 0×6c, 0×56, 0xf4, 0xea, 0×65, 0×7a, 0xae, 0×08, //B
0xba, 0×78, 0×25, 0×2e, 0×1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0×74, 0×1f, 0×4b, 0xbd, 0×8b, 0×8a, //C
0×70, 0×3e, 0xb5, 0×66, 0×48, 0×03, 0xf6, 0×0e, 0×61, 0×35, 0×57, 0xb9, 0×86, 0xc1, 0×1d, 0×9e, //D
0xe1, 0xf8, 0×98, 0×11, 0×69, 0xd9, 0×8e, 0×94, 0×9b, 0×1e, 0×87, 0xe9, 0xce, 0×55, 0×28, 0xdf, //E
0×8c, 0xa1, 0×89, 0×0d, 0xbf, 0xe6, 0×42, 0×68, 0×41, 0×99, 0×2d, 0×0f, 0xb0, 0×54, 0xbb, 0×16 }; //F
return (unsigned char) sbox[num];
}
unsigned char InvSBox(unsigned char num)
{
int sbox[256] = {
0×52, 0×09, 0×6a, 0xd5, 0×30, 0×36, 0xa5, 0×38, 0xbf, 0×40, 0xa3, 0×9e, 0×81, 0xf3, 0xd7, 0xfb,
0×7c, 0xe3, 0×39, 0×82, 0×9b, 0×2f, 0xff, 0×87, 0×34, 0×8e, 0×43, 0×44, 0xc4, 0xde, 0xe9, 0xcb,
0×54, 0×7b, 0×94, 0×32, 0xa6, 0xc2, 0×23, 0×3d, 0xee, 0×4c, 0×95, 0×0b, 0×42, 0xfa, 0xc3, 0×4e,
0×08, 0×2e, 0xa1, 0×66, 0×28, 0xd9, 0×24, 0xb2, 0×76, 0×5b, 0xa2, 0×49, 0×6d, 0×8b, 0xd1, 0×25,
0×72, 0xf8, 0xf6, 0×64, 0×86, 0×68, 0×98, 0×16, 0xd4, 0xa4, 0×5c, 0xcc, 0×5d, 0×65, 0xb6, 0×92,
0×6c, 0×70, 0×48, 0×50, 0xfd, 0xed, 0xb9, 0xda, 0×5e, 0×15, 0×46, 0×57, 0xa7, 0×8d, 0×9d, 0×84,
0×90, 0xd8, 0xab, 0×00, 0×8c, 0xbc, 0xd3, 0×0a, 0xf7, 0xe4, 0×58, 0×05, 0xb8, 0xb3, 0×45, 0×06,
0xd0, 0×2c, 0×1e, 0×8f, 0xca, 0×3f, 0×0f, 0×02, 0xc1, 0xaf, 0xbd, 0×03, 0×01, 0×13, 0×8a, 0×6b,
0×3a, 0×91, 0×11, 0×41, 0×4f, 0×67, 0xdc, 0xea, 0×97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0×73,
0×96, 0xac, 0×74, 0×22, 0xe7, 0xad, 0×35, 0×85, 0xe2, 0xf9, 0×37, 0xe8, 0×1c, 0×75, 0xdf, 0×6e,
0×47, 0xf1, 0×1a, 0×71, 0×1d, 0×29, 0xc5, 0×89, 0×6f, 0xb7, 0×62, 0×0e, 0xaa, 0×18, 0xbe, 0×1b,
0xfc, 0×56, 0×3e, 0×4b, 0xc6, 0xd2, 0×79, 0×20, 0×9a, 0xdb, 0xc0, 0xfe, 0×78, 0xcd, 0×5a, 0xf4,
0×1f, 0xdd, 0xa8, 0×33, 0×88, 0×07, 0xc7, 0×31, 0xb1, 0×12, 0×10, 0×59, 0×27, 0×80, 0xec, 0×5f,
0×60, 0×51, 0×7f, 0xa9, 0×19, 0xb5, 0×4a, 0×0d, 0×2d, 0xe5, 0×7a, 0×9f, 0×93, 0xc9, 0×9c, 0xef,
0xa0, 0xe0, 0×3b, 0×4d, 0xae, 0×2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0×3c, 0×83, 0×53, 0×99, 0×61,
0×17, 0×2b, 0×04, 0×7e, 0xba, 0×77, 0xd6, 0×26, 0xe1, 0×69, 0×14, 0×63, 0×55, 0×21, 0×0c, 0×7d };
return (unsigned char) sbox[num];
}
//Functia care citeste Key in format hexa si o saveaza intr-un vector key[16]
void citesteKey()
{
FILE *infile=fopen(“key.txt”, “r”);
rewind(infile);
for(int i=0;i<Nk*4 ;i++)
{
if(fscanf_s(infile,”%02x”,&key[i])!=EOF)
printf(“%02x “,key[i]);
}
cout<<endl;
fclose(infile);
}
//Functie care citeste textul in format hexa si il salvam intr-un vector temp[MAX]
void citesteHexaText()
{
FILE *infile=fopen(“outputTextCriptatHexa.txt”, “r”);
rewind(infile);
for(int i=0;i<sizeof(temp) ;i++){
if(fscanf_s(infile,”%02x”,&temp[i])!=EOF)
k++;
}
fclose(infile);
cout<<endl;
}
void afiseazaOutputHexa()
{
FILE *outfile=fopen(“outputTextDecriptatHexa.txt”, “a” );
//feof(outfile);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(state[j][i]!=0×00)
fprintf(outfile,”%02x”,state[j][i]);
}
fclose(outfile);
cout<<endl<<”Am salvat in outputTextDecriptatHexa”<<endl;
}
void afiseazaOutputText()
{
FILE *outfile2=fopen(“outputTextDecriptat.txt”, “a” );
feof(outfile2);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(state[j][i]!=0×00)
fprintf(outfile2,”%c”,(unsigned int) state[j][i]);
//cout<<(unsigned int) state[j][i];
}
fclose(outfile2);
cout<<endl<<”Am salvat in outputTextDecriptat”<<endl;
}
//ExpansionKey
void KeyExpansion()
{
unsigned char temp[Nb],aux;
int i=0;
//impartim key in 4 cuvinte w1,w2,w3,w4 – le retinem intr-o matrice pe fiecare linie cate un cuvant
while (i<Nk)
{
for(int j=0;j<4;j++)
w[i][j]=key[4*i+j];
i+=1;
}
//afisam cuvintele initiale formate din key
cout<<endl<<”Cuvintele initiale:”<<endl;
for(int m=0;m<Nk;m++)
{
cout<<”w["<<m<<"]=”;
for(int j=0;j<4;j++)
printf(“%02x”,w[m][j]);
cout<<endl;
}
cout<<endl;
//avem deja i=Nk
//urmatoarele runde se formeaza din rezultatul obtinut in runda anterioara
while (i<Nb*(Nr+1))
{
//primul temp este ultimul cuvant (w3) apoi se calculeaza pentru fiecare rezultat obtinut
for(int j=0;j<Nb;j++)
temp[j]=w[i-1][j];
if (i % Nk == 0)
{
//afisam temp
cout<<endl<<endl<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
//RotWord(temp)
aux=temp[0]; temp[0] = temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3]=aux;
//afisam temp dupa RotWord – muta primul byte la sfarsit
cout<<endl<<”Dupa RotWord:”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
//SubWord(RotWord(temp)) – se ablica s-box pentru fiecare particica din cuvant
for(int j=0;j<Nb;j++)
temp[j]=SBox(temp[j]);
//afisam temp dupa SubWord(RotWord(temp))
cout<<endl<<”Dupa SubWord(RotWord(temp)):”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
//afisam Rcon[i/Nk]
cout<<endl<<”Rcon[i/Nk]=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,Rcon[j][i/Nk-1]);//Rcon porneste de la pozitia 1
cout<<endl;
for(int j=0;j<Nb;j++)
temp[j]=temp[j]^Rcon[j][i/Nk-1];
//afisam temp dupa SubWord(RotWord(temp)) xor Rcon[i/Nk]
cout<<”Dupa SubWord(RotWord(temp)) xor Rcon[i/Nk]:”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
cout< 6 && i % Nk == 4)
{
//SubWord(temp) – se ablica s-box pentru fiecare particica din cuvant
for(int j=0;j<Nb;j++)
temp[j]=SBox(temp[j]);
//afisam temp dupa SubWord(temp)
cout<<endl<<”Dupa SubWord(temp):”<<endl;
cout<<”temp=”;
for(int j=0;j<Nb;j++)
printf(“%02x”,temp[j]);
}//if
//Afiseaza w[i-Nk]
/*cout<<”w*["<<i-Nk<<"]=”;
for(int j=0;j<Nb;j++){
printf(“%02x”,w[i-Nk][j]);}cout<<endl;*/
//w[i]=w[i-Nk] xor temp
for(int j=0;j<Nb;j++)
w[i][j]=w[i-Nk][j]^temp[j];
//Afiseaza cuvintele w[i]
cout<<”w["<<i<<"]=”;
for(int j=0;j<Nb;j++){
printf(“%02x”,w[i][j]);}cout<<endl;
i+=1;
}//while
}//ExpansionKey
//Functie care calculeaza numarul de blocuri de 128 de biti care se formeaza pentru textul din fisier
void nrBlocuri()
{
if(k%(Nb*4)==0)
b=k/(Nb*4);
else
b=(k/(Nb*4))+1;
cout<<”Nr de blocuri de 128 biti:”<<b<<endl;
}
//AddRoundKey
void AddRoundKey(int round)
{
//Afisam RoundKey value
cout<<”RoundKey:”<<endl;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,w[round * 4 + j][i]); //cuvintele le afisam pe coloana
}
cout<<endl;
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
state[j][i] = state[j][i] ^ w[round * 4 + i][j]; //trebuie sa ia fiecare cuv de la w[0] la w[44], cuvintele sunt aranjate pe linie
}
}
}
//InvSubByte
void InvSubBytes()
{
for(int i=0;i<4;i++)
{
for(int j=0;j0;i–)
state[1][i]=state[1][i-1];
state[1][0]=aux;
// Rotim a treia linie
for(int j=0;j0;i–)
state[2][i]=state[2][i-1];
state[2][0]=aux;
}
// Rotim a patra linie
for(int j=0;j0;i–)
state[3][i]=state[3][i-1];
state[3][0]=aux;
}
}
unsigned char xtime(unsigned char x)
{
if(x<0×80) //daca x<10000000 -adica nu are pe primul bit 1 – mutam 0 la sfarsit (shiftam la stanga)
x=x<-10000000 – adica are pe primul bit 1 – shiftam la stanga (adaugam 0 la sfarsit) si adunam (xor) m(x)=100011011 .. 1 se reduc deci vom ramane cu 00011011 care este 0×1b
x=(x<<1)^0×1b; //extra xor
return (unsigned char) x;
}
//Functia InvMixColumns
void InvMixColumns()
{
unsigned char s[4];
//Pentru fiecare coloana
for(int i=0;i<4;i++)
{
s[0]= ((xtime(state[0][i]))^(xtime(xtime(state[0][i])))^(xtime(xtime(xtime(state[0][i]))))) ^ //0e*state[0][i]
(state[1][i]^(xtime(state[1][i]))^(xtime(xtime(xtime(state[1][i]))))) ^ //0b*state[1][i]
(state[2][i]^(xtime(xtime(state[2][i])))^(xtime(xtime(xtime(state[2][i]))))) ^ //0d*state[2][i]
(state[3][i]^(xtime(xtime(xtime(state[3][i]))))); //09*state[3][i]
s[1]= (state[0][i]^(xtime(xtime(xtime(state[0][i]))))) ^ //09*state[0][i]
((xtime(state[1][i]))^(xtime(xtime(state[1][i])))^(xtime(xtime(xtime(state[1][i]))))) ^ //0e*state[1][i]
(state[2][i]^(xtime(state[2][i]))^(xtime(xtime(xtime(state[2][i]))))) ^ //0b*state[2][i]
(state[3][i]^(xtime(xtime(state[3][i])))^(xtime(xtime(xtime(state[3][i]))))); //0d*state[2][i]
s[2]= (state[0][i]^(xtime(xtime(state[0][i])))^(xtime(xtime(xtime(state[0][i])))))^ //0d*state[0][i]
(state[1][i]^(xtime(xtime(xtime(state[1][i]))))) ^ //09*state[1][i]
((xtime(state[2][i]))^(xtime(xtime(state[2][i])))^(xtime(xtime(xtime(state[2][i]))))) ^ //0e*state[2][i]
(state[3][i]^(xtime(state[3][i]))^(xtime(xtime(xtime(state[3][i]))))); //0b*state[3][i]
s[3]= (state[0][i]^(xtime(state[0][i]))^(xtime(xtime(xtime(state[0][i])))))^ //0b*state[0][i]
(state[1][i]^(xtime(xtime(state[1][i])))^(xtime(xtime(xtime(state[1][i])))))^ //0d*state[1][i]
(state[2][i]^(xtime(xtime(xtime(state[2][i]))))) ^ //09*state[2][i]
((xtime(state[3][i]))^(xtime(xtime(state[3][i])))^(xtime(xtime(xtime(state[3][i]))))); //0e*state[3][i]
//copiem in coloana respectiva valorile obtinute
for(int j=0;j<4;j++)
{
state[j][i]=s[j];
}
}
}
/*
// xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}
#define xtime(x) ((x<>7) & 1) * 0×1b))
// Multiplty is a macro used to multiply numbers in the field GF(2^8)
#define Multiply(x,y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime(xtime(x))) ^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
void InvMixColumns()
{
int i;
unsigned char a,b,c,d;
for(i=0;i<4;i++)
{
a = state[0][i];
b = state[1][i];
c = state[2][i];
d = state[3][i];
state[0][i] = Multiply(a, 0×0e) ^ Multiply(b, 0×0b) ^ Multiply(c, 0×0d) ^ Multiply(d, 0×09);
state[1][i] = Multiply(a, 0×09) ^ Multiply(b, 0×0e) ^ Multiply(c, 0×0b) ^ Multiply(d, 0×0d);
state[2][i] = Multiply(a, 0×0d) ^ Multiply(b, 0×09) ^ Multiply(c, 0×0e) ^ Multiply(d, 0×0b);
state[3][i] = Multiply(a, 0×0b) ^ Multiply(b, 0×0d) ^ Multiply(c, 0×09) ^ Multiply(d, 0×0e);
}
}*/
//Cyper
void Cyper()
{
int round=Nr;
//Copiem in state inputul
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
state[j][i] = in[i*4 + j]; //se aseaza pe coloana
}
}
//Afisam inputul
cout<<endl;
cout<<”Input:”<<endl;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<0;round–)
{
//Afisam Inputul pt fiecare runda
cout<<endl;
printf(“Start of round:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
InvShiftRows();
//State dupa InvShiftRows
printf(“Dupa InvShiftRows:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
InvSubBytes();
//State dupa InvSubByte
printf(“Dupa InvSubByte:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
AddRoundKey(round);
InvMixColumns();
//State dupa InvMixColumns
printf(“Dupa InvMixColumns:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
}//for
//Ultima runda – nu are MixColumns()
InvShiftRows();
//State dupa InvShiftRows
printf(“Dupa InvShiftRows:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
InvSubBytes();
//State dupa InvSubBytes
printf(“Dupa InvSubBytes:\n”);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
AddRoundKey(round-1);
//Afisam outputul
cout<<endl;
cout<<”Output:”<<endl;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf(“%02x “,state[i][j]);
}
cout<<endl;
}
}//InvCyper
//Functie care face o matrice in care pe fiecare linie este salvat un bloc de 128 biti si de aici criptam fiecare bloc
void blocuri()
{
unsigned char (*bloc)[Nb*4]=new unsigned char [b][Nb*4];
int m=0;
//elementele din vectorul temp sunt copiate in matrice
for(int j=0;j<b;j++)
for(int a=0;a<Nb*4;a++)
{
bloc[j][a]=temp[m];
m++;
}
//afisam matricea
for(int j=0;j<b;j++)
{
for(int a=0;a<Nb*4;a++)
printf(“%02x “,bloc[j][a]);
cout<<endl;
}
//lucram pe fiecare linie a matricii
for(int j=0;j<b;j++)
{
for(int a=0;a<Nb*4;a++)
//copiem linia curenta in vectorul in[] care este de fapt un bloc de 128 biti si il criptam
in[a]=bloc[j][a];
Cyper();
afiseazaOutputHexa();
afiseazaOutputText();
}
}
void main()
{
cout<<endl<<”Citim key.”<<endl;
citesteKey();
cout<<endl<<”Citim textul in format hexa si il punem intr-un vector.”<<endl;
citesteHexaText();
cout<<endl<<”Calculam nr de blocuri.”<<endl;
nrBlocuri();
cout<<endl<<”ExpansionKey”<<endl;
KeyExpansion();
cout<<endl<<”Matrice cu toate blocurile de 128 de biti. Fiecare bloc este criptat separat.”<<endl;
blocuri();
cout<<endl;
}
***********************************************************************
Fisiere text:
- inputText.txt – orice text max 1000 caractere.
- inputTextHexa.txt – fisier gol
- key.txt – Cyper key: 32 de caractere hexa ( de ex: 2b7e151628aed2a6abf7158809cf4f3c)
- outputTextCriptatHexa.txt – fisier gol
- outputTextCriptat.txt – fisier gol
- outputTextDecriptatHexa.txt – fisiser gol
- outputTextDecriptat.txt – fisier gol
#include<stdio.h>
#include<string>
#include<iostream>
#include<fstream>
#include<iomanip>