Archive for the ‘Securitatea informatiei’ Category

h1

Guillou-Guisquater Scheme (GQ)

ianuarie 9, 2009

Project TA

Class Main.java

package TA;
import java.math.BigInteger;

import java.util.Random;

import java.io.*;

import java.io.*;

import java.net.*;

import java.util.*;

public class Main extends Thread {

static BigInteger p = new BigInteger(“0″), q = new BigInteger(“0″), n = new BigInteger(“0″);

static BigInteger t = new BigInteger(“0″), b = new BigInteger(“0″), s = new BigInteger(“0″);

static Random random = new Random();

static BigInteger ZERO = new BigInteger(“0″);

static BigInteger UNU = new BigInteger(“1″);

static BigInteger DOI = new BigInteger(“2″);

String Ja2, Ia, read;

SHA sha = new SHA();

BigInteger Ja,Ja_inv,sa;

private static ServerSocket serverSocket = null;

private Socket clientSocket = null;

public static final int PORT = 1987;

static void getParameters() {

while (n.bitLength() <= 160) {

while (p.compareTo(UNU) == -1 || q.compareTo(UNU) == -1) {

p = BigInteger.probablePrime(128, random);

q = BigInteger.probablePrime(128, random);

}

n = p.multiply(q);

}

t = p.subtract(UNU).multiply(q.subtract(UNU));

while (b.compareTo(new BigInteger(“3″)) == -1 || b.gcd(t).compareTo(UNU) != 0 || b.compareTo(t.subtract(UNU)) == 1) {

b = BigInteger.probablePrime(t.subtract(UNU).bitLength(), random);

}

s = b.modInverse(t);

}

static void afisareParam() {

System.out.println(“p:” + p);

System.out.println(“q:” + q);

System.out.println(“n:” + n + ” lungime:” + n.bitLength());

System.out.println(“t:” + t);

System.out.println(“b:” + b);

System.out.println(“gcd(b,t)=” + b.gcd(t));

System.out.println(“s:” + s);

System.out.println(“b*s=” + b.multiply(s).mod(t) + ” mod t”);

}

public void run() {

//Executa solicitarea clientului

try {

BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

PrintWriter out = new PrintWriter(clientSocket.getOutputStream());

read = in.readLine();

System.out.println(read);

out.write(“Hello from TA”+”\n”);

out.flush();

Ia = in.readLine();

System.out.println(“Ia: ” + Ia);

Ja2 = sha.SHA2(Ia);

System.out.println(“Ja string: ” + Ja2);

Ja = sha.SHA1(Ia);

System.out.println(“Ja BigInteger: ” + Ja + ” lungime: “+ Ja.bitLength());

Ja_inv=Ja.modInverse(n);

System.out.println(“Ja_inv: ” + Ja_inv);

sa=Ja_inv.modPow(s, n);

System.out.println(“s_a: ” + sa);

out.write(n+”\n”);

out.write(b+”\n”);

out.write(sa+”\n”);

out.flush();

} catch (Exception e) {

System.err.println(e);

} finally {

// Inchid socketul deschis pentru clientul curent

try {

clientSocket.close();

} catch (IOException e) {

System.err.println(“Socketul nu poate fi inchis \n” + e);

}

}

}

public Main() throws IOException {

getParameters();

afisareParam();

// while (true) {

serverSocket = new ServerSocket(PORT);

System.out.println(” TA -> initiated!”);

try {

//Asteapta un client

clientSocket = serverSocket.accept();

//Executa solicitarea clientului intr-un fir de executie

new Thread(this).start();

} finally {

serverSocket.close();

System.out.println(” TA -> finished!”);

}

// }

}

public static void main(String[] args) throws IOException {

Main m = new Main();

}

}

Class SHA.java

package TA;

import java.io.UnsupportedEncodingException;

import java.math.BigInteger;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

public class SHA {

private static String convertToHex(byte[] data) {

StringBuffer buf = new StringBuffer();

for (int i = 0; i < data.length; i++) {

int halfbyte = (data[i] >>> 4) & 0×0F;

int two_halfs = 0;

do {

if ((0 <= halfbyte) && (halfbyte <= 9)) {

buf.append((char) (‘0′ + halfbyte));

} else {

buf.append((char) (‘a’ + (halfbyte – 10)));

}

halfbyte = data[i] & 0×0F;

} while (two_halfs++ < 1);

}

return buf.toString();

}

public static BigInteger convertToBigInteger(byte[] input) {

BigInteger r = new BigInteger(input);

return r;

}

public static BigInteger SHA1(String text)

throws NoSuchAlgorithmException, UnsupportedEncodingException {

MessageDigest md;

md = MessageDigest.getInstance(“SHA-1″);

byte[] sha1hash = new byte[40];

md.update(text.getBytes(“iso-8859-1″), 0, text.length());

sha1hash = md.digest();

return convertToBigInteger(sha1hash);

}

public static String SHA2(String text)

throws NoSuchAlgorithmException, UnsupportedEncodingException {

MessageDigest md;

md = MessageDigest.getInstance(“SHA-1″);

byte[] sha1hash = new byte[40];

md.update(text.getBytes(“iso-8859-1″), 0, text.length());

sha1hash = md.digest();

return convertToHex(sha1hash);

}

}

Project A

Class Main.java

package A;

import java.net.*;

import java.io.*;

import java.math.BigInteger;

import java.util.Random;

public class Main {

String identitate = “Eu sunt A”,raspuns=”accept”;

String Ja2, sa2, n2, b2,r2;

BigInteger Ja, sa, n, b, k = new BigInteger(“0″),alfa= new BigInteger(“0″),r,y=new BigInteger(“0″);

byte[] aux;

SHA sha = new SHA();

Random random = new Random();

int NR_VERIFICARI,incercari=0;

static BigInteger ZERO = new BigInteger(“0″);

static BigInteger UNU = new BigInteger(“1″);

static BigInteger DOI = new BigInteger(“2″);

public void Communication() throws Exception {

System.out.println(” A -> initiated!”);

String adresaServer = “127.0.0.1″;

int PORT = 1987;

Socket clientSocket = null;

PrintWriter out = null;

BufferedReader in = null;

try {

clientSocket = new Socket(adresaServer, PORT);

out = new PrintWriter(clientSocket.getOutputStream(), true);

in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

out.write(“Hello from A” + “\n”);

out.write(identitate + “\n”);

out.flush();

String read = in.readLine();

System.out.println(read);

Ja2 = sha.SHA2(identitate);

System.out.println(“Ja string: ” + Ja2);

Ja = sha.SHA1(identitate);

System.out.println(“Ja BigInteger: ” + Ja);

n2 = in.readLine();

n = new BigInteger(n2, 10);

System.out.println(“n: ” + n);

b2 = in.readLine();

b = new BigInteger(b2, 10);

System.out.println(“b: ” + b);

sa2 = in.readLine();

sa = new BigInteger(sa2, 10);

System.out.println(“sa: ” + sa);

} catch (Exception e) {

System.err.println(e);

System.exit(1);

} finally {

if (out != null) {

out.close();

}

if (in != null) {

in.close();

}

if (clientSocket != null) {

clientSocket.close();

}

}

clientSocket = null;

out = null;

in = null;

PORT = 1988;

try {

clientSocket = new Socket(adresaServer, PORT);

out = new PrintWriter(clientSocket.getOutputStream(), true);

in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

String read = in.readLine();

System.out.println(read);

NR_VERIFICARI=Integer.parseInt(in.readLine());

System.out.println(“Nr verificari: “+ NR_VERIFICARI);

out.write(“Hello from A” + “\n”);

out.flush();

while(raspuns.compareTo(“accept”)==0 && incercari<NR_VERIFICARI)

{

incercari++;

out.write(identitate + “\n”);

out.flush();

int lungime = n.bitLength();

int random_lungime = 0;

while (k.compareTo(UNU) == -1 || k.compareTo(n) >= 0) {

while (random_lungime == 0) {

random_lungime = random.nextInt(lungime);

}

k = BigInteger.probablePrime(random_lungime, random);

}

System.out.println(“k: ” + k);

alfa=k.modPow(b, n);

System.out.println(“alfa: ” + alfa);

out.write(n+”\n”);

out.write(b+”\n”);

out.write(alfa+”\n”);

out.flush();

r2 = in.readLine();

r = new BigInteger(r2, 10);

System.out.println(“r: ” + r);

y=sa.modPow(r, n).multiply(k).mod(n);

System.out.println(“y: ” + y);

out.write(y+”\n”);

out.flush();

raspuns=in.readLine();

System.out.println(“raspuns “+raspuns);

}

} catch (Exception e) {

System.err.println(e);

System.exit(1);

} finally {

if (out != null) {

out.close();

}

if (in != null) {

in.close();

}

if (clientSocket != null) {

clientSocket.close();

}

}

System.out.println(” A -> finished!”);

}

public static void main(String[] args) throws Exception {

Main m = new Main();

m.Communication();

}

}

Class SHA – la fel ca cea de la TA

Project B

Class Main.java

package B;

import java.math.BigInteger;
import java.util.Random;
import java.io.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class Main extends Thread {

static Random random = new Random();
static SHA sha = new SHA();
static BigInteger ZERO = new BigInteger(“0″);
static BigInteger UNU = new BigInteger(“1″);
static BigInteger DOI = new BigInteger(“2″);
BigInteger verificare = new BigInteger(“0″), Ja, alfa = new BigInteger(“0″), n, b, r = new BigInteger(“0″), y = new BigInteger(“0″);
String Ia, read, alfa2, n2, b2, y2, Ja2;
private static ServerSocket serverSocket = null;
private Socket clientSocket = null;
public static final int PORT = 1988;
int NR_VERIFICARI = 4;
boolean respins = false;

public void run() {
int accepta = 0;
//Executa solicitarea clientului
try {
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());

out.write(“Hello from B” + “\n”);
out.write(NR_VERIFICARI+”\n”);
out.flush();

read = in.readLine();
System.out.println(read);

while (accepta < NR_VERIFICARI && respins == false) {
Ia = in.readLine();
System.out.println(“Ia: ” + Ia);

n2 = in.readLine();
n = new BigInteger(n2, 10);
System.out.println(“n: ” + n);

b2 = in.readLine();
b = new BigInteger(b2, 10);
System.out.println(“b: ” + b);

alfa2 = in.readLine();
alfa = new BigInteger(alfa2, 10);
System.out.println(“alfa: ” + alfa);

int lungime = n.bitLength();
int random_lungime = 0;
while (r.compareTo(UNU) == -1 || r.compareTo(b) > 0) {
while (random_lungime == 0) {
random_lungime = random.nextInt(lungime);
}
r = BigInteger.probablePrime(random_lungime, random);
}
System.out.println(“r: ” + r);

out.write(r + “\n”);
out.flush();

y2 = in.readLine();
y = new BigInteger(y2, 10);
System.out.println(“y: ” + y);

Ja2 = sha.SHA2(Ia);
System.out.println(“Ja: ” + Ja2);
Ja = sha.SHA1(Ia);
System.out.println(“Ja: ” + Ja);

verificare = Ja.modPow(r, n).multiply(y.modPow(b, n)).mod(n);
System.out.println(“Verificare: ” + verificare);

if (verificare.compareTo(alfa) == 0) {
accepta++;
System.out.println(“Accept !!! “);
out.write(“accept” + “\n”);
out.flush();
} else {
respins = true;
out.write(“respins” + “\n”);
out.flush();
System.out.println(“Reject !!! “);
}
}

if(accepta==NR_VERIFICARI)
{
System.out.println(“IDENTIFICARE REUSITA !!! “);
}
else
{
System.out.println(“IDENTIFICARE ESUATA !!! “);
}

} catch (Exception e) {
System.err.println(e);
} finally {
// Inchid socketul deschis pentru clientul curent
try {
clientSocket.close();
} catch (IOException e) {
System.err.println(“Socketul nu poate fi inchis \n” + e);
}
}
}

public Main() throws IOException {

//  while (true) {
serverSocket = new ServerSocket(PORT);

try {
//Asteapta un client
clientSocket = serverSocket.accept();
System.out.println(” B -> initiated!”);
//Executa solicitarea clientului intr-un fir de executie
new Thread(this).start();

} finally {
serverSocket.close();
System.out.println(” B -> finished!”);
}
// }

}

public static void main(String[] args) throws IOException {
Main m = new Main();
}
}
Class SHA - la fel ca la TA

h1

ElGamal

noiembrie 8, 2008
#include<stdio.h>
#include<iostream>

#include<conio.h>

#include<NTL/ZZ.h>

#include<fstream>

using namespace std;

using namespace NTL;

long l,k;

class A

{

ZZ p,q,a,alfa,alfa2,beta,vector2;

unsigned char output[];

public:

A()

{l=0;}

void Key()

{

while(l<20)

l=RandomBnd(200);

cout<<endl<<”l=”<<l;

//generam q

GenGermainPrime(q,l,80);

cout<<endl<<”q=”<<q;

//aflam p

p=2*q+1;

cout<<endl<<”p=”<<p;

//generam a

while(a<1)

a=RandomBnd(q-2);

cout<<endl<<”a=”<<a;

//generam alfa,alfa2 rad primitiva

while(alfa2<2 && PowerMod(alfa2,2,p)!=1 && PowerMod(alfa2,q,p)!=1)

alfa2 = RandomBnd(q-2);

alfa=PowerMod(alfa2,(p-1)/q,p);

cout<<endl<<”alfa=”<<alfa;

 

//generam beta

PowerMod(beta,alfa,a,p);

cout<<endl<<”beta=”<<beta;

}

ZZ get_p()

{ return this->p; }

 

ZZ get_q()

{ return this->q; }

 

ZZ get_alfa()

{ return this->alfa; }

ZZ get_beta()

{ return this->beta; }

void outputText()

{

BytesFromZZ(output,vector2,k);

cout<<endl<<”vector_output=”<<vector2;

cout<<endl<<”output=”<<output;

outputText(“output.txt”);

}

void Decriptare(ZZ gama, ZZ delta)

{

ZZ m,h;

PowerMod(m,gama,a,p);

InvMod(h,m,p);

MulMod(vector2,h,delta,p);

}

void outputText(char *file)

{

/*ofstream on(file, ios::out);

on<<output;

on.close();*/

FILE *outfile=fopen(“output.txt”, “a” );

feof(outfile);

for(int j=0;j<k;j++){

fprintf(outfile,”%c”,output[j]);}

fclose(outfile);

}

};

 

class B

{

ZZ p,q,alfa,beta,lg,vector,r,delta,gama,z;

long i;

unsigned char input1[1000];

 

public:

B(A c,char *file)

{

for(int m=0;m<1000;m++) input1[m]=”;

i=0;

p=c.get_p();

q=c.get_q();

alfa=c.get_alfa();

beta=c.get_beta();

inputText(file);

 

 

 

while(input1[0]!=”)

{

k=0;vector=0;

while(NumBits(vector)<NumBits(p)-4 && input1[k]!=”)

{ ZZFromBytes(vector,input1,k); k++;}

genereaza(vector);

c.Decriptare(gama,delta);//a decripteaza textul

c.outputText();//a afiseaza textul

 

if(input1[k]!=”) {

k–;

for(int h=0;h<1000-k;h++)

input1[h]=input1[h+k];

for(int h=1000-k;h<1000;h++)

input1[h]=”;

}

else {for(int h=0;h<k;h++) input1[h]=”;}

}

 

/* BUN long k=0;

while(NumBits(vector)<=NumBits(p) && input1[k]!=”)

{ ZZFromBytes(vector,input1,k); k++;}

 

cout<<endl<<”vector input=”<<input1<<endl;

cout<<endl<<”p*=”<<NumBits(p)<<endl;

cout<<endl<<”v*=”<<NumBits(vector)<<endl;

 

genereaza();

c.Decriptare(gama,delta);//a decripteaza textul

c.outputText();//a afiseaza textul*/

}

void genereaza(ZZ vector)

{

//generam r

/*while(r<1)

r=RandomBnd(q-2);*/

r=315261752;

cout<<endl<<”r=”<<r;

 

//generam gama

PowerMod(gama,alfa,r,p);

cout<<endl<<”gama=”<<gama;

//generam omega

PowerMod(z,beta,r,p);

MulMod(delta,vector,z,p);

cout<<endl<<”delta=”<<delta;

}

void inputText(char *file)

{

//citim textul in input1;

ifstream in(file, ios::in);

cout<<endl;

while(!in.eof())

{

in>>input1[i];

i++;

}

i–;

in.close();

 

}

ZZ get_gama()

{return gama;}

 

ZZ get_delta()

{return delta;}

ZZ get_vector()

{return vector;}

};

class C

{

ZZ m,h,vector2,p;

unsigned char output[];

public:

C(A c)

{

p=c.get_p();

}

void Decriptare(ZZ gama1, ZZ delta1, ZZ gama2, ZZ delta2, ZZ vector)

{

InvMod(h,delta1,p);

MulMod(m,h,delta2,p);

MulMod(vector2,vector,m,p);

}

void outputText()

{

BytesFromZZ(output,vector2,36);

cout<<endl<<”vector_output=”<<vector2;

cout<<endl<<”output=”<<output;

}

};

void main()

{

A a; //cel care primeste ..

a.Key();//se genereaza cheia publica si cheia privata

B b(a,”input.txt”);//cel care trimite .. va lua cheia publica a celui caruia trebuie sa ii trimita mesajul

cout<<endl<<endl<<”****************** ATAC ***************************”<<endl;

B d(a,”input2.txt”);

 

C c(a);

c.Decriptare(b.get_gama(),b.get_delta(),d.get_gama(),d.get_delta(),b.get_vector());

c.outputText();

_getch();

}

 

 

 

Fisiere:

  • input.txt : advwqgasghvdhavgdacwwqvdsgdhvahdvawy
  • input2.txt

Atac pentru acelasi “r”.

 

 

h1

Advanced Encryption Standard

octombrie 24, 2008

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>