Advertisement
saleks28

kmzi4_feistel

Jan 29th, 2020
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.06 KB | None | 0 0
  1. #include "feistel.h"
  2.  
  3. namespace feistel
  4. {
  5.  
  6.      std::vector<uint8_t> GetKey()
  7.      {
  8.           std::string sKey;
  9.           std::vector<uint8_t> vKey;
  10.  
  11.           std::cout << "Enter key: ";
  12.           std::cin >> sKey;
  13.  
  14.           for (char& e : sKey)
  15.           {
  16.                vKey.push_back(static_cast<uint8_t>(e));
  17.           }
  18.  
  19.           return vKey;
  20.      }
  21.  
  22.      std::vector<std::vector<uint8_t>> CreateRoundKeys(const std::vector<uint8_t> key)
  23.      {
  24.           const size_t halfWay = key.size() / 2;
  25.           std::vector<uint8_t> theta1(key.begin(), key.begin() + halfWay);
  26.           std::vector<uint8_t> theta2(key.begin() + halfWay, key.end());
  27.  
  28.           return std::vector<std::vector<uint8_t>>{theta1, theta2, theta1, theta2};
  29.      }
  30.  
  31.      std::vector<uint8_t> SPNetwork(const std::vector<uint8_t> x2,
  32.           const std::vector<uint8_t> roundKey)
  33.      {
  34.           std::vector<uint8_t> spResult(2);
  35.          
  36.           // XOR
  37.           for (size_t i = 0; i < 2; ++i)
  38.           {
  39.                spResult[i] = x2[i] ^ roundKey[i];
  40.           }
  41.          
  42.           // S - block
  43.           uint8_t buffer = 0x0;
  44.           uint8_t s1Result, s2Result, s3Result, s4Result;
  45.          
  46.           s1Result = spPermutation[spResult[0] >> 4];
  47.           s2Result = spPermutation[spResult[0] & 0xF];
  48.           s3Result = spPermutation[spResult[1] >> 4];
  49.           s4Result = spPermutation[spResult[1] & 0xF];
  50.  
  51.           buffer = s1Result;
  52.           buffer <<= 4;
  53.           buffer += s2Result;
  54.           spResult[0] = buffer;
  55.  
  56.           buffer = s3Result;
  57.           buffer <<= 4;
  58.           buffer += s4Result;
  59.           spResult[1] = buffer;
  60.              
  61.           // P - block
  62.           uint16_t pResult = 0x0;
  63.           uint16_t largeBuf = spResult[0];
  64.           largeBuf <<= 8;
  65.           largeBuf += spResult[1];
  66.          
  67.           for (int bit = 32768, j = 0; bit >= 1; bit /= 2, j++)
  68.           {
  69.                if ((bit & largeBuf) == bit)
  70.                {
  71.                     int idx = (13 * j + 1) % 16;
  72.                     pResult |= 32768 >> idx;
  73.                }
  74.           }
  75.  
  76.           spResult[0] = pResult >> 8;
  77.           spResult[1] = pResult & 0xFF;
  78.  
  79.           return spResult;
  80.      }
  81.  
  82.      void MakeWhitening(const std::vector<uint8_t> enteredKey, std::vector<uint8_t>& encryptedBlock)
  83.      {
  84.           std::vector<uint8_t> whiteKey;
  85.  
  86.           const size_t halfWay = enteredKey.size() / 2;
  87.  
  88.           std::vector<uint8_t> theta1(enteredKey.begin(), enteredKey.begin() + halfWay);
  89.           std::vector<uint8_t> theta2(enteredKey.begin() + halfWay, enteredKey.end());
  90.  
  91.           whiteKey.push_back(theta1[0] ^ theta2[0]);
  92.           whiteKey.push_back(theta1[1] ^ theta2[1]);
  93.           whiteKey.push_back(whiteKey[0]);
  94.           whiteKey.push_back(whiteKey[1]);
  95.  
  96.           for (size_t i = 0; i < encryptedBlock.size(); ++i)
  97.           {
  98.                encryptedBlock[i] ^= whiteKey[i];
  99.           }
  100.      }
  101.  
  102.      std::vector<uint8_t> FeistelXOR(const std::vector<uint8_t> x1, const std::vector<uint8_t> x2,
  103.           const std::vector<uint8_t> roundKey)
  104.      {
  105.           std::vector<uint8_t> spResult = SPNetwork(x2, roundKey);
  106.           std::vector<uint8_t> xorResult(2);
  107.  
  108.           for (size_t i = 0; i < 2; ++i)
  109.           {
  110.                xorResult[i] = spResult[i] ^ x1[i];
  111.           }
  112.  
  113.           return xorResult;
  114.      }
  115.  
  116.      std::vector<uint8_t> FeistelNetwork(const std::vector<uint8_t> block,
  117.           const std::vector<std::vector<uint8_t>>& roundKeys)
  118.      {
  119.           const size_t halfWay = block.size() / 2;
  120.           size_t roundCounter = 0;
  121.           std::vector<uint8_t> encryptedBlock;
  122.  
  123.           std::vector<uint8_t> x1(block.begin(), block.begin() + halfWay);
  124.           std::vector<uint8_t> x2(block.begin() + halfWay, block.end());
  125.  
  126.           // X2 || (X1 ^ f(X2))
  127.           for (auto &roundKey: roundKeys)
  128.           {
  129.                // Шаблон раунда
  130.                encryptedBlock.insert(encryptedBlock.begin(), x2.begin(), x2.end());
  131.                std::vector<uint8_t> xorResult = FeistelXOR(x1, x2, roundKey);
  132.                encryptedBlock.insert(encryptedBlock.end(), xorResult.begin(), xorResult.end());
  133.  
  134.                if (roundCounter == 3)
  135.                {
  136.                     return encryptedBlock;
  137.                }
  138.  
  139.                // Меняем x1 и x2
  140.                x1.clear(); x2.clear();
  141.  
  142.                x1.insert(x1.begin(), encryptedBlock.begin(), encryptedBlock.end() - halfWay);
  143.                x2.insert(x2.begin(), encryptedBlock.begin() + halfWay, encryptedBlock.end());
  144.                encryptedBlock.clear();
  145.                roundCounter++;
  146.           }
  147.          
  148.           return encryptedBlock;
  149.      }
  150.  
  151.  
  152.      std::vector<uint8_t> EncryptFunction(const std::vector<uint8_t>& plainText, const std::vector<std::vector<uint8_t>>& roundKeys,
  153.           std::vector<uint8_t> enteredKey)
  154.      {
  155.           std::vector<uint8_t> cipherText;
  156.  
  157.           for (size_t i = 0; i <= plainText.size() - 4; i += 4)
  158.           {
  159.                std::vector<uint8_t> bufBlock = { plainText[i], plainText[i + 1],
  160.                     plainText[i + 2], plainText[i + 3] };
  161.  
  162.                std::vector<uint8_t> encryptedBlock = FeistelNetwork(bufBlock, roundKeys);
  163.  
  164.                MakeWhitening(enteredKey, encryptedBlock);
  165.  
  166.                cipherText.insert(cipherText.end(), encryptedBlock.begin(), encryptedBlock.end());
  167.           }
  168.          
  169.           return cipherText;
  170.      }
  171.  
  172.    
  173.      std::vector<uint8_t> OFB(std::vector<uint8_t> synchroPackage, std::vector<uint8_t> plainText,
  174.           bool operationFlag)
  175.      {
  176.           std::vector<uint8_t> cipherText;
  177.           std::vector<uint8_t> enteredKey = GetKey();
  178.           std::vector<std::vector<uint8_t>> roundKeys(4);
  179.           roundKeys = CreateRoundKeys(enteredKey);
  180.  
  181.           // Add addition block
  182.           if (operationFlag == ENCRYPT_OPER)
  183.           {
  184.                size_t szAddBlock = 32;
  185.  
  186.                // Addition block
  187.                if (plainText.size() % 4 != 0)
  188.                {
  189.                     szAddBlock = plainText.size() % 4;
  190.  
  191.                     while (plainText.size() % 4 != 0)
  192.                     {
  193.                          plainText.push_back(static_cast<uint8_t>(0));
  194.                     }
  195.  
  196.                     szAddBlock *= 8;
  197.                }
  198.  
  199.                std::vector<uint8_t> addBlock(4);
  200.                addBlock[0] = szAddBlock >> 24;
  201.                addBlock[1] = (szAddBlock >> 16) & 0xFF;
  202.                addBlock[2] = (szAddBlock >> 8) & 0xFF;
  203.                addBlock[3] = szAddBlock & 0xFF;
  204.  
  205.                plainText.insert(plainText.end(), addBlock.begin(), addBlock.end());
  206.           }
  207.  
  208.           // OFB
  209.           std::vector<std::vector<uint8_t>> gammaVectors;
  210.           gammaVectors.push_back(EncryptFunction(synchroPackage, roundKeys, enteredKey));
  211.  
  212.           for (size_t i = 0, j = 1; i < plainText.size() / 4 - 1; ++i, ++j)
  213.           {
  214.                gammaVectors.push_back(EncryptFunction(gammaVectors[j - 1], roundKeys, enteredKey));
  215.           }
  216.          
  217.           for (size_t i = 0, j = 0; i < gammaVectors.size(); ++i)
  218.           {
  219.                for (auto& elem : gammaVectors[i])
  220.                {
  221.                     cipherText.push_back(elem ^ plainText[j]);
  222.                     ++j;
  223.                }
  224.           }
  225.  
  226.           // Delete addition block
  227.           if (operationFlag == DECRYPT_OPER)
  228.           {
  229.                size_t szAddBlock = 0;
  230.                for (size_t j = 4; j > 0; --j)
  231.                {
  232.                     szAddBlock += cipherText[cipherText.size() - j];
  233.                     szAddBlock << 8;
  234.                }
  235.                
  236.                for (size_t j = 0; j < 4; ++j)
  237.                     cipherText.pop_back();
  238.  
  239.                szAddBlock /= 8;
  240.                if (szAddBlock == 4)
  241.                     return cipherText;
  242.  
  243.                for (size_t j = 0; j < szAddBlock; ++j)
  244.                {
  245.                     cipherText.pop_back();
  246.                }
  247.           }
  248.  
  249.           return cipherText;
  250.      }
  251. } ///< namespace feistel
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement