Advertisement
saleks28

kmzi5

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