Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Лістинг програми






Симетричні алгоритми шифрування

 

 

Виконав:

студент гр. КІ-08-3

Ткач М.Ю.

Перевірив:

Джулій В.М.

 

 

Хмельницький 2012


 

Мета. Програмна реалізація методу симетричного алгоритму шифрування

Завдання

Розробити власний симетричний алгоритм шифрування на основі мережі Фейстеля та реалізувати на одній з мов програмування.

 

Лістинг програми

#include < fstream>

#include < iostream>

#include < bitset>

 

#define ROUNDS 17

#define MAGIC_NUMBER 29

 

using namespace std;

 

 

////////////////////////////////////////////////////////////////////////////////

inline int foo(const int & x, const int & k)

{

return (int)((((x < < 7) ^ (k > > 2) + 0ll) * (x > > 5) ^ (k < < 4)) % 1000000007);

}

 

 

inline int s_box(const bitset < 48 > & r_key)

{

int s[ 4 ][ 16 ] = {

14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,

0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,

4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,

15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13

};

int res = 0;

 

for (int i = 0; i < 48; i += 6)

{

int k = r_key[ i ] * 2 + r_key[ i + 5 ],

j = r_key[ i + 1 ] * 8 + r_key[ i + 2 ] * 4 + r_key[ i + 3 ] * 2 + r_key[ i + 4 ];

res < < = 4;

res |= s[ k ][ j ];

}

return res;

}

 

inline int gen_key(const bitset < 56 > & key, int round)

{

bitset < 48 > k;

for (int i = 47, j = round; i > = 0; --i, j += round + MAGIC_NUMBER)

k [ i ] = key[ j % 56 ];

return s_box(k);

}

 

 

////////////////////////////////////////////////////////////////////////////////

bitset < 64 > feistel(const bitset < 64 > & msg, const bitset < 56 > & key, const bool & e)

{

int round = e? 1: ROUNDS,

delta = e? 1: -1,

left = 0,

right = 0;

 

for (int b = 63; b > = 0; --b)

b > 31?

left = (left < < 1) | msg[ b ]:

right = (right < < 1) | msg[ b ];

 

for (int i = 1; i < = ROUNDS; ++i)

{

if (i! = ROUNDS)

{

int temp = left;

left = right ^ foo(left, gen_key(key, round));

right = temp;

}

else

{

right ^= foo(left, gen_key(key, round));

}

round += delta;

}

 

bitset < 64 > res;

for (int i = 63; i > = 0; --i)

res[ i ] = i > 31? (left > > (i - 32)) & 1: (right > > i) & 1;

 

return res;

}

 

 

////////////////////////////////////////////////////////////////////////////////

bitset < 64 > encrypt(const bitset < 64 > & msg, const bitset < 56 > & key)

{

return feistel(msg, key, true);

}

 

bitset < 64 > decrypt(const bitset < 64 > & cph, const bitset < 56 > & key)

{

return feistel(cph, key, false);

}

 

 

////////////////////////////////////////////////////////////////////////////////

void call_encrypt()

{

ifstream keyin(" 56key.dat", ios:: in | ios:: binary),

msgin(" plaintext.dat", ios:: in | ios:: binary);

ofstream ciphout(" ciphertext.dat", ios:: out | ios:: binary);

 

keyin.unsetf(ios_base:: skipws);

msgin.unsetf(ios_base:: skipws);

 

bitset < 56 > key;

for (unsigned char c, i = 0; i++ < 7;)

{

keyin > > c;

key < < = 8;

key |= c;

}

 

msgin.seekg(0, ios:: end);

int size = (int)msgin.tellg();

msgin.seekg(0, ios:: beg);

 

unsigned char c, flag = 0;

while (size > 0 || flag == 0)

{

bitset < 64 > msg, cphr;

 

for (int i = 0; i < 8; ++i)

{

if (size > 0)

{

msgin > > c;

msg < < = 8;

msg |= c;

--size;

}

else if (flag)

msg < < = 8;

else

{

msg < < = 8;

msg |= 128u;

flag = 1;

}

}

 

cphr = encrypt(msg, key);

 

c = 0;

for (int i = 63; i > = 0; --i)

{

c = (c < < 1) | cphr[ i ];

if (i % 8 == 0)

{

ciphout < < c;

c = 0;

}

}

}

 

keyin.close();

msgin.close();

ciphout.close();

}

 

 

void call_decrypt()

{

ifstream keyin(" 56key.dat", ios:: in | ios:: binary),

ciphin(" ciphertext.dat", ios:: in | ios:: binary);

ofstream deciphout(" decrypttext.dat", ios:: out | ios:: binary);

 

keyin.unsetf(ios_base:: skipws);

ciphin.unsetf(ios_base:: skipws);

 

bitset < 56 > key;

for (unsigned char c, i = 0; i++ < 7;)

{

keyin > > c;

key < < = 8;

key |= c;

}

 

ciphin.seekg(0, ios:: end);

int size = (int)ciphin.tellg();

ciphin.seekg(0, ios:: beg);

 

while (size > 0)

{

unsigned char c;

bitset < 64 > cph, dcrpt;

 

size -= 8;

for (int i = 0; i++ < 8;)

{

ciphin > > c;

cph < < = 8;

cph |= c;

}

 

dcrpt = decrypt(cph, key);

 

c = 0;

 

int N = 0;

if (size < 1)

{

for (int i = 0; i < 64 & & N == 0; ++i)

if (dcrpt[ i ] == 1)

N = i + 1;

}

for (int i = 63; i > = N; --i)

{

c = (c < < 1) | dcrpt[ i ];

if (i % 8 == 0)

{

deciphout < < c;

c = 0;

}

}

}

 

keyin.close();

ciphin.close();

deciphout.close();

}

 

 

////////////////////////////////////////////////////////////////////////////////

int main()

{

void (*foo[ 2 ])() = { call_encrypt, call_decrypt };

char choise;

 

while (true)

{

cout < < " 1.Encrypt\n2.Decrypt\nX.Exit\n";

cin > > choise;

if (unsigned(choise - 49) < 2)

{

foo[ choise - 49 ]();

cout < < " OK" < < endl;

cin.get(); cin.get();

}

else

break;

}

 

return 0;

}

 

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.015 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал