saleks28

kmzi3_feistel

Jan 29th, 2020
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.46 KB | None | 0 0
  1. #include "feistel.h"
  2.  
  3. namespace feistel
  4. {
  5.      const std::vector<int8_t> spPermutation{ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 };
  6.      
  7.      std::vector<std::vector<uint8_t>> CreateRoundKeys(const std::vector<uint8_t>& key)
  8.      {
  9.           const size_t halfWay = key.size() / 2;
  10.           std::vector<uint8_t> theta1(key.begin(), key.begin() + halfWay);
  11.           std::vector<uint8_t> theta2(key.begin() + halfWay, key.end());
  12.  
  13.           return std::vector<std::vector<uint8_t>>{theta1, theta2, theta1, theta2};
  14.      }
  15.  
  16.      std::vector<uint8_t> SPNetwork(const std::vector<uint8_t> x2,
  17.           const std::vector<uint8_t> roundKey)
  18.      {
  19.           std::vector<uint8_t> spResult(2);
  20.          
  21.           // XOR
  22.           for (size_t i = 0; i < 2; ++i)
  23.           {
  24.                spResult[i] = x2[i] ^ roundKey[i];
  25.           }
  26.          
  27.           // S - block
  28.           uint8_t buffer = 0x0;
  29.           uint8_t s1Result, s2Result, s3Result, s4Result;
  30.          
  31.           s1Result = spPermutation[spResult[0] >> 4];
  32.           s2Result = spPermutation[spResult[0] & 0xF];
  33.           s3Result = spPermutation[spResult[1] >> 4];
  34.           s4Result = spPermutation[spResult[1] & 0xF];
  35.  
  36.           buffer = s1Result;
  37.           buffer <<= 4;
  38.           buffer += s2Result;
  39.           spResult[0] = buffer;
  40.  
  41.           buffer = s3Result;
  42.           buffer <<= 4;
  43.           buffer += s4Result;
  44.           spResult[1] = buffer;
  45.              
  46.           // P - block
  47.           uint16_t pResult = 0x0;
  48.           uint16_t largeBuf = spResult[0];
  49.           largeBuf <<= 8;
  50.           largeBuf += spResult[1];
  51.          
  52.           for (int bit = 32768, j = 0; bit >= 1; bit /= 2, j++)
  53.           {
  54.                if ((bit & largeBuf) == bit)
  55.                {
  56.                     int idx = (13 * j + 1) % 16;
  57.                     pResult |= 32768 >> idx;
  58.                }
  59.           }
  60.  
  61.           spResult[0] = pResult >> 8;
  62.           spResult[1] = pResult & 0xFF;
  63.  
  64.           return spResult;
  65.      }
  66.  
  67.      void MakeWhitening(const std::vector<uint8_t> enteredKey, std::vector<uint8_t>& encryptedBlock)
  68.      {
  69.           std::vector<uint8_t> whiteKey;
  70.  
  71.           const size_t halfWay = enteredKey.size() / 2;
  72.  
  73.           std::vector<uint8_t> theta1(enteredKey.begin(), enteredKey.begin() + halfWay);
  74.           std::vector<uint8_t> theta2(enteredKey.begin() + halfWay, enteredKey.end());
  75.  
  76.           whiteKey.push_back(theta1[0] ^ theta2[0]);
  77.           whiteKey.push_back(theta1[1] ^ theta2[1]);
  78.           whiteKey.push_back(whiteKey[0]);
  79.           whiteKey.push_back(whiteKey[1]);
  80.  
  81.           for (size_t i = 0; i < encryptedBlock.size(); ++i)
  82.           {
  83.                encryptedBlock[i] ^= whiteKey[i];
  84.           }
  85.      }
  86.  
  87.      std::vector<uint8_t> FeistelXOR(const std::vector<uint8_t> x1, const std::vector<uint8_t> x2,
  88.           const std::vector<uint8_t> roundKey)
  89.      {
  90.           std::vector<uint8_t> spResult = SPNetwork(x2, roundKey);
  91.           std::vector<uint8_t> xorResult(2);
  92.  
  93.           for (size_t i = 0; i < 2; ++i)
  94.           {
  95.                xorResult[i] = spResult[i] ^ x1[i];
  96.           }
  97.  
  98.           return xorResult;
  99.      }
  100.  
  101.      std::vector<uint8_t> FeistelNetwork(const std::vector<uint8_t> block,
  102.           const std::vector<std::vector<uint8_t>>& roundKeys)
  103.      {
  104.           const size_t halfWay = block.size() / 2;
  105.           size_t roundCounter = 0;
  106.           std::vector<uint8_t> encryptedBlock;
  107.  
  108.           std::vector<uint8_t> x1(block.begin(), block.begin() + halfWay);
  109.           std::vector<uint8_t> x2(block.begin() + halfWay, block.end());
  110.  
  111.           // X2 || (X1 ^ f(X2))
  112.           for (auto &roundKey: roundKeys)
  113.           {
  114.                // Шаблон раунда
  115.                encryptedBlock.insert(encryptedBlock.begin(), x2.begin(), x2.end());
  116.                std::vector<uint8_t> xorResult = FeistelXOR(x1, x2, roundKey);
  117.                encryptedBlock.insert(encryptedBlock.end(), xorResult.begin(), xorResult.end());
  118.  
  119.                if ( roundCounter == 3 )
  120.                {
  121.                     return encryptedBlock;
  122.                }
  123.  
  124.                // Меняем x1 и x2
  125.                x1.clear(); x2.clear();
  126.  
  127.                x1.insert(x1.begin(), encryptedBlock.begin(), encryptedBlock.end() - halfWay);
  128.                x2.insert(x2.begin(), encryptedBlock.begin() + halfWay, encryptedBlock.end());
  129.                encryptedBlock.clear();
  130.                
  131.                ++roundCounter;
  132.           }
  133.          
  134.           return encryptedBlock;
  135.      }
  136.  
  137.  
  138.      void EncryptFunction(const std::vector<uint8_t>& plainText, std::vector<uint8_t>& cipherText,
  139.           const std::vector<uint8_t>& enteredKey)
  140.      {
  141.           std::vector<std::vector<uint8_t>> roundKeys(4);
  142.          
  143.           roundKeys = CreateRoundKeys(enteredKey);
  144.  
  145.           for (size_t i = 0; i <= plainText.size() - 4 - (plainText.size()) % 4; i += 4)
  146.           {
  147.                std::vector<uint8_t> bufBlock = { plainText[i], plainText[i + 1],
  148.                     plainText[i + 2], plainText[i + 3] };
  149.  
  150.                std::vector<uint8_t> encryptedBlock = FeistelNetwork(bufBlock, roundKeys);
  151.  
  152.                MakeWhitening(enteredKey, encryptedBlock);
  153.  
  154.                cipherText.insert(cipherText.end(), encryptedBlock.begin(), encryptedBlock.end());
  155.           }
  156.  
  157.           size_t szAddBlock = 32;
  158.  
  159.           if (plainText.size() % 4 != 0)
  160.           {
  161.                szAddBlock = plainText.size() % 4;
  162.                std::vector<uint8_t> bufBlock(plainText.end() - szAddBlock, plainText.end());
  163.  
  164.                while (bufBlock.size() != 4)
  165.                {
  166.                     bufBlock.push_back(static_cast<uint8_t>(0));
  167.                }
  168.                std::vector<uint8_t> encryptedBlock = FeistelNetwork(bufBlock, roundKeys);
  169.  
  170.                MakeWhitening(enteredKey, encryptedBlock);
  171.  
  172.                cipherText.insert(cipherText.end(), encryptedBlock.begin(), encryptedBlock.end());
  173.  
  174.                szAddBlock *= 8;
  175.           }
  176.  
  177.           std::vector<uint8_t> addBlock(4);
  178.           addBlock[0] = szAddBlock >> 24;
  179.           addBlock[1] = (szAddBlock >> 16) & 0xFF;
  180.           addBlock[2] = (szAddBlock >> 8) & 0xFF;
  181.           addBlock[3] = szAddBlock & 0xFF;
  182.  
  183.           std::vector<uint8_t> encryptedBlock = FeistelNetwork(addBlock, roundKeys);
  184.  
  185.           MakeWhitening(enteredKey, encryptedBlock);
  186.  
  187.           cipherText.insert(cipherText.end(), encryptedBlock.begin(), encryptedBlock.end());
  188.  
  189.      }
  190.  
  191. } ///< namespace feistel
Add Comment
Please, Sign In to add comment