Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- #include <Windows.h>
- #define openTextFile "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\input.txt"
- #define cipherTextFile "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\CipherText.txt"
- #define decryptText "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\DecryptText.txt"
- #define keyFile "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\Key"
- using namespace std;
- typedef unsigned short u16;
- typedef int u32;
- _inline u32 invert_bit(u32 block, u32 bit)
- {
- return block ^ 1 << (31 - bit);
- }
- vector<char> GetText(int mode)
- {
- string fileName;
- ifstream fin;
- char t;
- vector<char> text;
- int i = 0, size;
- if (mode == 1)
- fileName = cipherTextFile;
- else
- fileName = openTextFile;
- fin.open(fileName, ios::binary);
- fin.seekg(0, std::ios::end);
- size = fin.tellg();
- fin.seekg(0, std::ios::beg);
- if (fin)
- {
- t = fin.get();
- while (i < size)
- {
- text.emplace_back(t);
- t = fin.get();
- i++;
- }
- }
- else
- printf("bad encrypt file\n");
- fin.close();
- return text;
- }
- u32 CharToU32(vector <char> block)
- {
- u32 dword_block = 0;
- unsigned int tmp;
- tmp = block[3] & 0x000000ff;
- dword_block += tmp;
- tmp = (block[2] << 8) & 0x0000ffff;
- dword_block += tmp;
- tmp = (block[1] << 16) & 0x00ffffff;
- dword_block += tmp;
- tmp = (block[0] << 24) & 0xffffffff;
- dword_block += tmp;
- return dword_block;
- }
- vector <char> U32ToChar(u32 block)
- {
- vector <char> char_block(4);
- unsigned int tmp;
- tmp = block >> 24;
- char_block[0] = tmp;
- tmp <<= 24;
- block -= tmp;
- tmp = block >> 16;
- char_block[1] = tmp;
- tmp <<= 16;
- block -= tmp;
- tmp = block >> 8;
- char_block[2] = tmp;
- tmp <<= 8;
- block -= tmp;
- char_block[3] = block;
- return char_block;
- }
- u16 f(u16 block, u16 key)
- {
- int sblocks[] = { 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11 };
- int res[4];
- int pblocks[16];
- u16 lala = 0;
- int bb[4];
- block ^= key;
- bb[0] = (block & 0xF000);
- bb[0] = bb[0] >> 12;
- bb[1] = (block & 0xF00);
- bb[1] = bb[1] >> 8;
- bb[2] = (block & 0xF0);
- bb[2] = bb[2] >> 4;
- bb[3] = (block & 0xF);
- for (int i = 0; i < 16; i++)
- {
- pblocks[i] = (11 * i + 5) % 16;
- }
- //подстановка
- for (int i = 0; i < 4; i++)
- {
- res[i] = sblocks[bb[i]];
- lala |= res[i];
- if (i != 3) lala = lala << 4;
- }
- u16 tmp = 0xffff;
- //перестановка
- for (int i = 0; i < 16; i++)
- {
- if (lala & (1 << pblocks[i])) // если pblocks[i] бит равен 1
- {
- tmp |= 1 << i;
- }
- else
- tmp &= ~(1 << i);// если pblocks[i] бит равен 0;
- }
- //printf("block %d\t res %d\n", block, tmp);
- return tmp;
- }
- u32 Feistel(u32 b, u16 k)
- {
- u32 p0 = b & 0xffff, p1 = b >> 16 & 0xffff;
- u32 r0 = p1, r1 = p0 ^ f(p1, k);
- return (r1 << 16) | r0;
- }
- u32 EncryptBlock(u32 b, u32 key, u32 rounds)
- {
- if (rounds >= 1)
- {
- b = Feistel(b, key >> 16 & 0xffff);
- if (rounds >= 2)
- {
- b = Feistel(b, key & 0xffff);
- if (rounds >= 3)
- {
- b = Feistel(b, ~(key >> 16 & 0xffff));
- if (rounds >= 4)
- {
- b = Feistel(b, ~(key & 0xffff));
- }
- }
- }
- b = (b >> 16 & 0xffff) | ((b & 0xffff) << 16);
- }
- return b;
- }
- u32 DecryptBlock(u32 b, u32 key, u32 rounds)
- {
- if (rounds >= 1)
- {
- b = Feistel(b, ~(key & 0xffff));
- if (rounds >= 2)
- {
- b = Feistel(b, ~(key >> 16 & 0xffff));
- if (rounds >= 3)
- {
- b = Feistel(b, key & 0xffff);
- if (rounds >= 4)
- {
- b = Feistel(b, key >> 16 & 0xffff);
- }
- }
- }
- b = (b >> 16 & 0xFFFF) | ((b & 0xffff) << 16);
- }
- return b;
- }
- void FeistelEncrypt(const vector<char> &plainText, u32 key, u32 rounds)
- {
- vector<char> block(4), prev_block(4), last;
- int i, j, check, count, check_d, block_num;
- u32 temp_block = 0;
- ofstream cipher;
- vector<char> cipherText(plainText.size());
- block_num = plainText.size() / 4;
- if (plainText.size() % 4 != 0) block_num++;
- if (plainText.size() < 5)
- {
- cout << "Text must have at least 2 blocks!\n";
- system("pause");
- exit(0);
- }
- for (i = 0, count = block_num; i < plainText.size(); i += 4, count--)
- {
- check = plainText.size() - i;
- if (count == 2)
- {
- check_d = plainText.size() - i - 4;
- if (check_d < 4)
- {
- for (j = 0; j < 4; j++)
- prev_block[j] = plainText[i + j];
- temp_block = CharToU32(prev_block);
- temp_block = EncryptBlock(temp_block, key, rounds);
- prev_block = U32ToChar(temp_block);
- for (j = 0; j < check_d; j++)
- block[j] = plainText[i + 4 + j];
- for (j = check_d; j < 4; j++)
- block[j] = prev_block[j];
- temp_block = CharToU32(block);
- temp_block = EncryptBlock(temp_block, key, rounds);
- block = U32ToChar(temp_block);
- last.resize(check_d);
- for (j = 0; j < last.size(); j++)
- last[j] = prev_block[j];
- for (j = 0; j < 4; j++)
- cipherText[i + j] = block[j];
- for (j = 0; j < last.size(); j++)
- cipherText[i + 4 + j] = last[j];
- break;
- }
- }
- for (j = 0; j < 4; j++)
- block[j] = plainText[i + j];
- temp_block = CharToU32(block);
- temp_block = EncryptBlock(temp_block, key, rounds);
- block = U32ToChar(temp_block);
- for (j = 0; j < 4; j++)
- cipherText[i + j] = block[j];
- }
- cipher.open(cipherTextFile, ios::binary);
- for (i = 0; i < cipherText.size(); i++)
- cipher << cipherText[i];
- cipher.close();
- }
- void FeistelDecrypt(const vector<char> &cipherText, u32 key, u32 rounds)
- {
- vector<char> block(4), last(4), prev_block(4);
- int i, j, check, check_d, count, block_num;
- u32 temp_block = 0;
- ofstream plain;
- vector<char> plainText(cipherText.size());
- if (cipherText.size() < 5)
- {
- cout << "Text must have at least 2 blocks!\n";
- system("pause");
- exit(0);
- }
- block_num = cipherText.size() / 4;
- if (cipherText.size() % 4 != 0) block_num++;
- for (i = 0, count = block_num; i < cipherText.size(); i += 4, count--)
- {
- check = cipherText.size() - i;
- if (count == 2)
- {
- check_d = cipherText.size() - i - 4;
- if (check_d < 4)
- {
- for (j = 0; j < 4; j++)
- prev_block[j] = cipherText[i + j];
- temp_block = CharToU32(prev_block);
- temp_block = DecryptBlock(temp_block, key, rounds);
- prev_block = U32ToChar(temp_block);
- for (j = 0; j < check_d; j++)
- block[j] = cipherText[i + 4 + j];
- for (j = check_d; j < 4; j++)
- block[j] = prev_block[j];
- temp_block = CharToU32(block);
- temp_block = DecryptBlock(temp_block, key, rounds);
- block = U32ToChar(temp_block);
- last.resize(check_d);
- for (j = 0; j < last.size(); j++)
- last[j] = prev_block[j];
- for (j = 0; j < 4; j++)
- plainText[i + j] = block[j];
- for (j = 0; j < last.size(); j++)
- plainText[i + 4 + j] = last[j];
- break;
- }
- }
- for (j = 0; j < 4; j++)
- block[j] = cipherText[i + j];
- temp_block = CharToU32(block);
- temp_block = DecryptBlock(temp_block, key, rounds);
- block = U32ToChar(temp_block);
- for (j = 0; j < 4; j++)
- plainText[i + j] = block[j];
- }
- plain.open(decryptText, ios::binary);
- for (i = 0; i < plainText.size(); i++)
- plain << plainText[i];
- plain.close();
- }
- u32 GetKey()
- {
- vector <char> key(4);
- ifstream fin;
- u32 u32_key;
- fin.open(keyFile, ios::in | ios::binary);
- if (fin)
- for (int i = 0; i < 4; i++)
- key[i] = fin.get();
- else
- printf("bad key\n");
- fin.close();
- u32_key = CharToU32(key);
- return u32_key;
- }
- u32 CheckError()
- {
- u32 key = 0x10B9C2A1;
- u32 rounds = 1;
- u32 D = 0;
- for (; rounds < 5; rounds++)
- {
- std::cout << "\nround[" << rounds << "] ";
- for (u32 i = 0; i < 1/*32*/; i++)
- {
- std::cout << ".";
- for (u32 j = 0; j < UINT32_MAX; j++)
- {
- u32 y_j = EncryptBlock(j, key, rounds);
- u32 y_j_i = EncryptBlock(invert_bit(j, i), key, rounds);
- D |= (y_j ^ y_j_i);
- if ((y_j ^ y_j_i) == 0xFFFFFFFF)
- {
- return rounds;
- }
- }
- }
- std::cout << "\nD: " << D;
- }
- return 6;
- }
- int main()
- {
- u32 key = GetKey(), round;
- vector<char> text;
- int choice;
- cout << "Choose mode:\n1 - Encrypt\n2 - Decrypt\n3 - Find time\n";
- cin >> choice;
- switch (choice)
- {
- case 1:
- text = GetText(0);
- FeistelEncrypt(text, key, 4);
- break;
- case 2:
- text = GetText(1);
- FeistelDecrypt(text, key, 4);
- break;
- case 3:
- round = CheckError();
- cout << round << '\n';
- break;
- default:
- break;
- }
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement