Advertisement
Guest User

Untitled

a guest
Jan 24th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.57 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <Windows.h>
  6.  
  7. #define openTextFile "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\input.txt"
  8. #define cipherTextFile "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\CipherText.txt"
  9. #define decryptText "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\DecryptText.txt"
  10. #define keyFile "C:\\Users\\Станислав\\Documents\\Visual Studio 2015\\Projects\\Feistel\\Feistel\\Key"
  11.  
  12. using namespace std;
  13.  
  14. typedef unsigned short u16;
  15. typedef int u32;
  16.  
  17. _inline u32 invert_bit(u32 block, u32 bit)
  18. {
  19.     return block ^ 1 << (31 - bit);
  20. }
  21.  
  22. vector<char> GetText(int mode)
  23. {
  24.     string fileName;
  25.     ifstream fin;
  26.     char t;
  27.     vector<char> text;
  28.     int i = 0, size;
  29.     if (mode == 1)
  30.         fileName = cipherTextFile;
  31.     else
  32.         fileName = openTextFile;
  33.     fin.open(fileName, ios::binary);
  34.     fin.seekg(0, std::ios::end);
  35.     size = fin.tellg();
  36.     fin.seekg(0, std::ios::beg);
  37.  
  38.     if (fin)
  39.     {
  40.         t = fin.get();
  41.         while (i < size)
  42.         {
  43.             text.emplace_back(t);
  44.             t = fin.get();
  45.             i++;
  46.         }
  47.     }
  48.     else
  49.         printf("bad encrypt file\n");
  50.     fin.close();
  51.     return text;
  52. }
  53.  
  54. u32 CharToU32(vector <char> block)
  55. {
  56.     u32 dword_block = 0;
  57.     unsigned int tmp;
  58.  
  59.     tmp = block[3] & 0x000000ff;
  60.     dword_block += tmp;
  61.  
  62.     tmp = (block[2] << 8) & 0x0000ffff;
  63.     dword_block += tmp;
  64.  
  65.     tmp = (block[1] << 16) & 0x00ffffff;
  66.     dword_block += tmp;
  67.  
  68.     tmp = (block[0] << 24) & 0xffffffff;
  69.     dword_block += tmp;
  70.  
  71.     return dword_block;
  72. }
  73.  
  74. vector <char> U32ToChar(u32 block)
  75. {
  76.     vector <char> char_block(4);
  77.     unsigned int tmp;
  78.  
  79.     tmp = block >> 24;
  80.     char_block[0] = tmp;
  81.     tmp <<= 24;
  82.     block -= tmp;
  83.  
  84.     tmp = block >> 16;
  85.     char_block[1] = tmp;
  86.     tmp <<= 16;
  87.     block -= tmp;
  88.  
  89.     tmp = block >> 8;
  90.     char_block[2] = tmp;
  91.     tmp <<= 8;
  92.     block -= tmp;
  93.  
  94.     char_block[3] = block;
  95.  
  96.     return char_block;
  97. }
  98.  
  99. u16 f(u16 block, u16 key)
  100. {
  101.     int sblocks[] = { 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11 };
  102.     int res[4];
  103.     int pblocks[16];
  104.     u16 lala = 0;
  105.     int bb[4];
  106.     block ^= key;
  107.     bb[0] = (block & 0xF000);
  108.     bb[0] = bb[0] >> 12;
  109.     bb[1] = (block & 0xF00);
  110.     bb[1] = bb[1] >> 8;
  111.     bb[2] = (block & 0xF0);
  112.     bb[2] = bb[2] >> 4;
  113.     bb[3] = (block & 0xF);
  114.  
  115.     for (int i = 0; i < 16; i++)
  116.     {
  117.         pblocks[i] = (11 * i + 5) % 16;
  118.     }
  119.     //подстановка
  120.     for (int i = 0; i < 4; i++)
  121.     {
  122.         res[i] = sblocks[bb[i]];
  123.         lala |= res[i];
  124.         if (i != 3) lala = lala << 4;
  125.     }
  126.     u16 tmp = 0xffff;
  127.     //перестановка
  128.     for (int i = 0; i < 16; i++)
  129.     {
  130.         if (lala & (1 << pblocks[i])) //  если pblocks[i] бит  равен 1
  131.         {
  132.             tmp |= 1 << i;
  133.         }
  134.         else
  135.             tmp &= ~(1 << i);//  если pblocks[i] бит  равен 0;
  136.     }
  137.     //printf("block %d\t res  %d\n", block, tmp);
  138.     return tmp;
  139. }
  140.  
  141. u32 Feistel(u32 b, u16 k)
  142. {
  143.     u32 p0 = b & 0xffff, p1 = b >> 16 & 0xffff;
  144.     u32 r0 = p1, r1 = p0 ^ f(p1, k);
  145.     return (r1 << 16) | r0;
  146. }
  147.  
  148. u32 EncryptBlock(u32 b, u32 key, u32 rounds)
  149. {
  150.     if (rounds >= 1)
  151.     {
  152.         b = Feistel(b, key >> 16 & 0xffff);
  153.         if (rounds >= 2)
  154.         {
  155.             b = Feistel(b, key & 0xffff);
  156.             if (rounds >= 3)
  157.             {
  158.                 b = Feistel(b, ~(key >> 16 & 0xffff));
  159.                 if (rounds >= 4)
  160.                 {
  161.                     b = Feistel(b, ~(key & 0xffff));
  162.                 }
  163.             }
  164.         }
  165.         b = (b >> 16 & 0xffff) | ((b & 0xffff) << 16);
  166.     }
  167.  
  168.     return b;
  169. }
  170.  
  171. u32 DecryptBlock(u32 b, u32 key, u32 rounds)
  172. {
  173.     if (rounds >= 1)
  174.     {
  175.         b = Feistel(b, ~(key & 0xffff));
  176.         if (rounds >= 2)
  177.         {
  178.             b = Feistel(b, ~(key >> 16 & 0xffff));
  179.             if (rounds >= 3)
  180.             {
  181.                 b = Feistel(b, key & 0xffff);
  182.                 if (rounds >= 4)
  183.                 {
  184.                     b = Feistel(b, key >> 16 & 0xffff);
  185.                 }
  186.             }
  187.         }
  188.         b = (b >> 16 & 0xFFFF) | ((b & 0xffff) << 16);
  189.     }
  190.  
  191.     return b;
  192. }
  193.  
  194. void FeistelEncrypt(const vector<char> &plainText, u32 key, u32 rounds)
  195. {
  196.     vector<char> block(4), prev_block(4), last;
  197.     int i, j, check, count, check_d, block_num;
  198.     u32 temp_block = 0;
  199.     ofstream cipher;
  200.     vector<char> cipherText(plainText.size());
  201.     block_num = plainText.size() / 4;
  202.     if (plainText.size() % 4 != 0) block_num++;
  203.     if (plainText.size() < 5)
  204.     {
  205.         cout << "Text must have at least 2 blocks!\n";
  206.         system("pause");
  207.         exit(0);
  208.     }
  209.  
  210.     for (i = 0, count = block_num; i < plainText.size(); i += 4, count--)
  211.     {
  212.         check = plainText.size() - i;
  213.  
  214.         if (count == 2)
  215.         {
  216.             check_d = plainText.size() - i - 4;
  217.             if (check_d < 4)
  218.             {
  219.                 for (j = 0; j < 4; j++)
  220.                     prev_block[j] = plainText[i + j];
  221.  
  222.                 temp_block = CharToU32(prev_block);
  223.                 temp_block = EncryptBlock(temp_block, key, rounds);
  224.                 prev_block = U32ToChar(temp_block);
  225.  
  226.                 for (j = 0; j < check_d; j++)
  227.                     block[j] = plainText[i + 4 + j];
  228.                 for (j = check_d; j < 4; j++)
  229.                     block[j] = prev_block[j];
  230.  
  231.                 temp_block = CharToU32(block);
  232.                 temp_block = EncryptBlock(temp_block, key, rounds);
  233.                 block = U32ToChar(temp_block);
  234.  
  235.                 last.resize(check_d);
  236.                 for (j = 0; j < last.size(); j++)
  237.                     last[j] = prev_block[j];
  238.  
  239.                 for (j = 0; j < 4; j++)
  240.                     cipherText[i + j] = block[j];
  241.                 for (j = 0; j < last.size(); j++)
  242.                     cipherText[i + 4 + j] = last[j];
  243.  
  244.                 break;
  245.             }
  246.         }
  247.  
  248.         for (j = 0; j < 4; j++)
  249.             block[j] = plainText[i + j];
  250.  
  251.         temp_block = CharToU32(block);
  252.         temp_block = EncryptBlock(temp_block, key, rounds);
  253.         block = U32ToChar(temp_block);
  254.        
  255.         for (j = 0; j < 4; j++)
  256.             cipherText[i + j] = block[j];
  257.     }
  258.  
  259.     cipher.open(cipherTextFile, ios::binary);
  260.  
  261.     for (i = 0; i < cipherText.size(); i++)
  262.         cipher << cipherText[i];
  263.  
  264.     cipher.close();
  265. }
  266.  
  267. void FeistelDecrypt(const vector<char> &cipherText, u32 key, u32 rounds)
  268. {
  269.     vector<char> block(4), last(4), prev_block(4);
  270.     int i, j, check, check_d, count, block_num;
  271.     u32 temp_block = 0;
  272.     ofstream plain;
  273.     vector<char> plainText(cipherText.size());
  274.  
  275.     if (cipherText.size() < 5)
  276.     {
  277.         cout << "Text must have at least 2 blocks!\n";
  278.         system("pause");
  279.         exit(0);
  280.     }
  281.     block_num = cipherText.size() / 4;
  282.     if (cipherText.size() % 4 != 0) block_num++;
  283.  
  284.     for (i = 0, count = block_num; i < cipherText.size(); i += 4, count--)
  285.     {
  286.         check = cipherText.size() - i;
  287.         if (count == 2)
  288.         {
  289.             check_d = cipherText.size() - i - 4;
  290.             if (check_d < 4)
  291.             {
  292.                 for (j = 0; j < 4; j++)
  293.                     prev_block[j] = cipherText[i + j];
  294.  
  295.                 temp_block = CharToU32(prev_block);
  296.                 temp_block = DecryptBlock(temp_block, key, rounds);
  297.                 prev_block = U32ToChar(temp_block);
  298.                
  299.                 for (j = 0; j < check_d; j++)
  300.                     block[j] = cipherText[i + 4 + j];
  301.                 for (j = check_d; j < 4; j++)
  302.                     block[j] = prev_block[j];
  303.  
  304.                 temp_block = CharToU32(block);
  305.                 temp_block = DecryptBlock(temp_block, key, rounds);
  306.                 block = U32ToChar(temp_block);
  307.                
  308.                 last.resize(check_d);
  309.                 for (j = 0; j < last.size(); j++)
  310.                     last[j] = prev_block[j];
  311.  
  312.                 for (j = 0; j < 4; j++)
  313.                     plainText[i + j] = block[j];
  314.                 for (j = 0; j < last.size(); j++)
  315.                     plainText[i + 4 + j] = last[j];
  316.  
  317.                 break;
  318.             }
  319.         }
  320.  
  321.         for (j = 0; j < 4; j++)
  322.             block[j] = cipherText[i + j];
  323.  
  324.         temp_block = CharToU32(block);
  325.         temp_block = DecryptBlock(temp_block, key, rounds);
  326.         block = U32ToChar(temp_block);
  327.        
  328.         for (j = 0; j < 4; j++)
  329.             plainText[i + j] = block[j];
  330.     }
  331.  
  332.     plain.open(decryptText, ios::binary);
  333.     for (i = 0; i < plainText.size(); i++)
  334.         plain << plainText[i];
  335.     plain.close();
  336. }
  337.  
  338. u32 GetKey()
  339. {
  340.     vector <char> key(4);
  341.     ifstream fin;
  342.     u32 u32_key;
  343.  
  344.     fin.open(keyFile, ios::in | ios::binary);
  345.  
  346.     if (fin)
  347.         for (int i = 0; i < 4; i++)
  348.             key[i] = fin.get();
  349.     else
  350.         printf("bad key\n");
  351.    
  352.     fin.close();
  353.     u32_key = CharToU32(key);
  354.     return u32_key;
  355. }
  356.  
  357. u32 CheckError()
  358. {
  359.     u32 key = 0x10B9C2A1;
  360.     u32 rounds = 1;
  361.     u32 D = 0;
  362.     for (; rounds < 5; rounds++)
  363.     {
  364.         std::cout << "\nround[" << rounds << "] ";
  365.         for (u32 i = 0; i < 1/*32*/; i++)
  366.         {
  367.             std::cout << ".";
  368.             for (u32 j = 0; j < UINT32_MAX; j++)
  369.             {
  370.                 u32 y_j = EncryptBlock(j, key, rounds);
  371.                 u32 y_j_i = EncryptBlock(invert_bit(j, i), key, rounds);
  372.                 D |= (y_j ^ y_j_i);
  373.                 if ((y_j ^ y_j_i) == 0xFFFFFFFF)
  374.                 {
  375.                     return rounds;
  376.                 }
  377.             }
  378.         }
  379.         std::cout << "\nD: " << D;
  380.     }
  381.     return 6;
  382. }
  383.  
  384. int main()
  385. {
  386.     u32 key = GetKey(), round;
  387.     vector<char> text;
  388.     int choice;
  389.     cout << "Choose mode:\n1 - Encrypt\n2 - Decrypt\n3 - Find time\n";
  390.     cin >> choice;
  391.     switch (choice)
  392.     {
  393.     case 1:
  394.         text = GetText(0);
  395.         FeistelEncrypt(text, key, 4);
  396.         break;
  397.     case 2:
  398.         text = GetText(1);
  399.         FeistelDecrypt(text, key, 4);
  400.         break;
  401.     case 3:
  402.         round = CheckError();
  403.         cout << round << '\n';
  404.         break;
  405.     default:
  406.         break;
  407.     }
  408.     system("pause");
  409.     return 0;
  410. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement