Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "feistel.h"
- namespace feistel
- {
- std::vector<uint8_t> GetKey()
- {
- std::string sKey;
- std::vector<uint8_t> vKey;
- std::cout << "Enter key: ";
- std::cin >> sKey;
- for (char& e : sKey)
- {
- vKey.push_back(static_cast<uint8_t>(e));
- }
- return vKey;
- }
- std::vector<std::vector<uint8_t>> CreateRoundKeys(const std::vector<uint8_t> key)
- {
- const size_t halfWay = key.size() / 2;
- std::vector<uint8_t> theta1(key.begin(), key.begin() + halfWay);
- std::vector<uint8_t> theta2(key.begin() + halfWay, key.end());
- return std::vector<std::vector<uint8_t>>{theta1, theta2, theta1, theta2};
- }
- std::vector<uint8_t> SPNetwork(const std::vector<uint8_t> x2,
- const std::vector<uint8_t> roundKey)
- {
- std::vector<uint8_t> spResult(2);
- // XOR
- for (size_t i = 0; i < 2; ++i)
- {
- spResult[i] = x2[i] ^ roundKey[i];
- }
- // S - block
- uint8_t buffer = 0x0;
- uint8_t s1Result, s2Result, s3Result, s4Result;
- s1Result = spPermutation[spResult[0] >> 4];
- s2Result = spPermutation[spResult[0] & 0xF];
- s3Result = spPermutation[spResult[1] >> 4];
- s4Result = spPermutation[spResult[1] & 0xF];
- buffer = s1Result;
- buffer <<= 4;
- buffer += s2Result;
- spResult[0] = buffer;
- buffer = s3Result;
- buffer <<= 4;
- buffer += s4Result;
- spResult[1] = buffer;
- // P - block
- uint16_t pResult = 0x0;
- uint16_t largeBuf = spResult[0];
- largeBuf <<= 8;
- largeBuf += spResult[1];
- for (int bit = 32768, j = 0; bit >= 1; bit /= 2, j++)
- {
- if ((bit & largeBuf) == bit)
- {
- int idx = (13 * j + 1) % 16;
- pResult |= 32768 >> idx;
- }
- }
- spResult[0] = pResult >> 8;
- spResult[1] = pResult & 0xFF;
- return spResult;
- }
- void MakeWhitening(const std::vector<uint8_t> enteredKey, std::vector<uint8_t>& encryptedBlock)
- {
- std::vector<uint8_t> whiteKey;
- const size_t halfWay = enteredKey.size() / 2;
- std::vector<uint8_t> theta1(enteredKey.begin(), enteredKey.begin() + halfWay);
- std::vector<uint8_t> theta2(enteredKey.begin() + halfWay, enteredKey.end());
- whiteKey.push_back(theta1[0] ^ theta2[0]);
- whiteKey.push_back(theta1[1] ^ theta2[1]);
- whiteKey.push_back(whiteKey[0]);
- whiteKey.push_back(whiteKey[1]);
- for (size_t i = 0; i < encryptedBlock.size(); ++i)
- {
- encryptedBlock[i] ^= whiteKey[i];
- }
- }
- std::vector<uint8_t> FeistelXOR(const std::vector<uint8_t> x1, const std::vector<uint8_t> x2,
- const std::vector<uint8_t> roundKey)
- {
- std::vector<uint8_t> spResult = SPNetwork(x2, roundKey);
- std::vector<uint8_t> xorResult(2);
- for (size_t i = 0; i < 2; ++i)
- {
- xorResult[i] = spResult[i] ^ x1[i];
- }
- return xorResult;
- }
- std::vector<uint8_t> FeistelNetwork(const std::vector<uint8_t> block,
- const std::vector<std::vector<uint8_t>>& roundKeys)
- {
- const size_t halfWay = block.size() / 2;
- size_t roundCounter = 0;
- std::vector<uint8_t> encryptedBlock;
- std::vector<uint8_t> x1(block.begin(), block.begin() + halfWay);
- std::vector<uint8_t> x2(block.begin() + halfWay, block.end());
- // X2 || (X1 ^ f(X2))
- for (auto &roundKey: roundKeys)
- {
- // Шаблон раунда
- encryptedBlock.insert(encryptedBlock.begin(), x2.begin(), x2.end());
- std::vector<uint8_t> xorResult = FeistelXOR(x1, x2, roundKey);
- encryptedBlock.insert(encryptedBlock.end(), xorResult.begin(), xorResult.end());
- if (roundCounter == 3)
- {
- return encryptedBlock;
- }
- // Меняем x1 и x2
- x1.clear(); x2.clear();
- x1.insert(x1.begin(), encryptedBlock.begin(), encryptedBlock.end() - halfWay);
- x2.insert(x2.begin(), encryptedBlock.begin() + halfWay, encryptedBlock.end());
- encryptedBlock.clear();
- roundCounter++;
- }
- return encryptedBlock;
- }
- std::vector<uint8_t> EncryptFunction(const std::vector<uint8_t>& plainText, const std::vector<std::vector<uint8_t>>& roundKeys,
- std::vector<uint8_t> enteredKey)
- {
- std::vector<uint8_t> cipherText;
- for (size_t i = 0; i <= plainText.size() - 4; i += 4)
- {
- std::vector<uint8_t> bufBlock = { plainText[i], plainText[i + 1],
- plainText[i + 2], plainText[i + 3] };
- std::vector<uint8_t> encryptedBlock = FeistelNetwork(bufBlock, roundKeys);
- MakeWhitening(enteredKey, encryptedBlock);
- cipherText.insert(cipherText.end(), encryptedBlock.begin(), encryptedBlock.end());
- }
- return cipherText;
- }
- std::vector<uint8_t> OFB(std::vector<uint8_t> synchroPackage, std::vector<uint8_t> plainText,
- bool operationFlag)
- {
- std::vector<uint8_t> cipherText;
- std::vector<uint8_t> enteredKey = GetKey();
- std::vector<std::vector<uint8_t>> roundKeys(4);
- roundKeys = CreateRoundKeys(enteredKey);
- // Add addition block
- if (operationFlag == ENCRYPT_OPER)
- {
- size_t szAddBlock = 32;
- // Addition block
- if (plainText.size() % 4 != 0)
- {
- szAddBlock = plainText.size() % 4;
- while (plainText.size() % 4 != 0)
- {
- plainText.push_back(static_cast<uint8_t>(0));
- }
- szAddBlock *= 8;
- }
- std::vector<uint8_t> addBlock(4);
- addBlock[0] = szAddBlock >> 24;
- addBlock[1] = (szAddBlock >> 16) & 0xFF;
- addBlock[2] = (szAddBlock >> 8) & 0xFF;
- addBlock[3] = szAddBlock & 0xFF;
- plainText.insert(plainText.end(), addBlock.begin(), addBlock.end());
- }
- // OFB
- std::vector<std::vector<uint8_t>> gammaVectors;
- gammaVectors.push_back(EncryptFunction(synchroPackage, roundKeys, enteredKey));
- for (size_t i = 0, j = 1; i < plainText.size() / 4 - 1; ++i, ++j)
- {
- gammaVectors.push_back(EncryptFunction(gammaVectors[j - 1], roundKeys, enteredKey));
- }
- for (size_t i = 0, j = 0; i < gammaVectors.size(); ++i)
- {
- for (auto& elem : gammaVectors[i])
- {
- cipherText.push_back(elem ^ plainText[j]);
- ++j;
- }
- }
- // Delete addition block
- if (operationFlag == DECRYPT_OPER)
- {
- size_t szAddBlock = 0;
- for (size_t j = 4; j > 0; --j)
- {
- szAddBlock += cipherText[cipherText.size() - j];
- szAddBlock << 8;
- }
- for (size_t j = 0; j < 4; ++j)
- cipherText.pop_back();
- szAddBlock /= 8;
- if (szAddBlock == 4)
- return cipherText;
- for (size_t j = 0; j < szAddBlock; ++j)
- {
- cipherText.pop_back();
- }
- }
- return cipherText;
- }
- } ///< namespace feistel
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement