Advertisement
cataleena

DES_PAO

May 9th, 2024
673
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.15 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <cstdint>
  4. #include <chrono>
  5. #include <omp.h> // Include OpenMP header
  6. #include "keys.h"
  7. #include "permutation.h"
  8. #include "sbox.h"
  9.  
  10. class TripleDES {
  11. public:
  12.     TripleDES(const uint64_t* key1, const uint64_t* key2, const uint64_t* key3) : key1(key1), key2(key2), key3(key3) {
  13.         obtainRoundKeys(*key1, roundKeys1, 16);
  14.         obtainRoundKeys(*key2, roundKeys2, 16);
  15.         obtainRoundKeys(*key3, roundKeys3, 16);
  16.     }
  17.  
  18.     void encryptFile(const char* inputFile, const char* outputFile);
  19.     uint64_t generateNextCounterValue(uint64_t counter);
  20.     uint64_t getMillisTimestamp();
  21.  
  22. private:
  23.     const uint64_t* key1;
  24.     const uint64_t* key2;
  25.     const uint64_t* key3;
  26.     unsigned long long roundKeys1[16], roundKeys2[16], roundKeys3[16];
  27.  
  28.     void encryptBlocks(const uint64_t* counter, uint64_t* ciphertextBlock);
  29. };
  30.  
  31. void TripleDES::encryptFile(const char* inputFile, const char* outputFile) {
  32.     std::ifstream inFile(inputFile, std::ios::binary);
  33.     std::ofstream outFile(outputFile, std::ios::binary);
  34.  
  35.     if (!inFile.is_open() || !outFile.is_open()) {
  36.         std::cerr << "Error opening files." << std::endl;
  37.         return;
  38.     }
  39.  
  40.     constexpr size_t blockSize = 8; // 64 bits
  41.     uint64_t plaintextBlock[8], ciphertextBlock[8];
  42.     uint64_t counter[8] = {0, 1, 2, 3, 4, 5, 6, 7}; // Initial counter values
  43.     bool keepProcessing = true;
  44.  
  45. #pragma omp parallel // Start parallel region
  46.     {
  47.         while (keepProcessing) {
  48.             // Read multiple blocks in a thread-safe manner
  49.             bool readSuccessful = true;
  50. #pragma omp critical
  51.             {
  52.                 for (int i = 0; i < 8; ++i) {
  53.                     readSuccessful &= inFile.read(reinterpret_cast<char*>(&plaintextBlock[i]), blockSize).good();
  54.                 }
  55.             }
  56.  
  57.             if (!readSuccessful) {
  58.                 keepProcessing = false;
  59.             }
  60.  
  61.             // Encrypt multiple blocks in parallel
  62.             encryptBlocks(counter, ciphertextBlock);
  63.  
  64.             // Write the ciphertext blocks in a thread-safe manner
  65. #pragma omp critical
  66.             {
  67.                 if (keepProcessing) {
  68.                     for (int i = 0; i < 8; ++i) {
  69.                         outFile.write(reinterpret_cast<char*>(&ciphertextBlock[i]), blockSize);
  70.                     }
  71.                 }
  72.             }
  73.  
  74.             // Update the counter after processing the blocks
  75.             for (int i = 0; i < 8; ++i) {
  76.                 counter[i] = generateNextCounterValue(counter[i]);
  77.             }
  78.         }
  79.     } // End of parallel region
  80.  
  81.     inFile.close();
  82.     outFile.close();
  83. }
  84.  
  85. void TripleDES::encryptBlocks(const uint64_t* counter, uint64_t* ciphertextBlock) {
  86.     // First encryption
  87. #pragma omp simd
  88.     for (int i = 0; i < 8; ++i) {
  89.         uint64_t permutedBlock = performLongToLongPermutation(counter[i], initialPerm, initialPermSize);
  90.         for (int j = 0; j < 16; ++j) {
  91.             unsigned long long expandedBlock = performLongToLongPermutation(permutedBlock, expandRight, expandRightSize);
  92.             unsigned long long xorResult = expandedBlock ^ roundKeys1[j];
  93.             unsigned int sboxResult = performSboxCalculation(xorResult);
  94.             uint64_t permutedSboxResult = performIntToLongPermutation(sboxResult, finalSboxPerm, finalSboxPermSize);
  95.             permutedBlock ^= permutedSboxResult;
  96.         }
  97.         ciphertextBlock[i] = performLongToLongPermutation(permutedBlock, keyPermFinal, keyPermFinalSize);
  98.     }
  99.  
  100.     // Second encryption
  101. #pragma omp simd
  102.     for (int i = 0; i < 8; ++i) {
  103.         uint64_t permutedBlock = performLongToLongPermutation(ciphertextBlock[i], initialPerm, initialPermSize);
  104.         for (int j = 0; j < 16; ++j) {
  105.             unsigned long long expandedBlock = performLongToLongPermutation(permutedBlock, expandRight, expandRightSize);
  106.             unsigned long long xorResult = expandedBlock ^ roundKeys2[j];
  107.             unsigned int sboxResult = performSboxCalculation(xorResult);
  108.             uint64_t permutedSboxResult = performIntToLongPermutation(sboxResult, finalSboxPerm, finalSboxPermSize);
  109.             permutedBlock ^= permutedSboxResult;
  110.         }
  111.         ciphertextBlock[i] = performLongToLongPermutation(permutedBlock, keyPermFinal, keyPermFinalSize);
  112.     }
  113.  
  114.     // Third encryption
  115. #pragma omp simd
  116.     for (int i = 0; i < 8; ++i) {
  117.         uint64_t permutedBlock = performLongToLongPermutation(ciphertextBlock[i], initialPerm, initialPermSize);
  118.         for (int j = 0; j < 16; ++j) {
  119.             unsigned long long expandedBlock = performLongToLongPermutation(permutedBlock, expandRight, expandRightSize);
  120.             unsigned long long xorResult = expandedBlock ^ roundKeys3[j];
  121.             unsigned int sboxResult = performSboxCalculation(xorResult);
  122.             uint64_t permutedSboxResult = performIntToLongPermutation(sboxResult, finalSboxPerm, finalSboxPermSize);
  123.             permutedBlock ^= permutedSboxResult;
  124.         }
  125.         ciphertextBlock[i] = performLongToLongPermutation(permutedBlock, keyPermFinal, keyPermFinalSize);
  126.     }
  127. }
  128.  
  129. uint64_t TripleDES::generateNextCounterValue(uint64_t counter) {
  130.     return counter + 8; // Increment by the number of blocks processed
  131. }
  132.  
  133. uint64_t TripleDES::getMillisTimestamp() {
  134.     auto now = std::chrono::system_clock::now();
  135.     auto duration = now.time_since_epoch();
  136.     auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
  137.     return millis;
  138. }
  139.  
  140. int main() {
  141.     const char* inputFile = "../data/input1MB.txt";
  142.     const char* outputFile = "../data/output1MB_encrypted.txt";
  143.     uint64_t key1[3] = {0xA4B92905A4B92905, 0x0000000000000000, 0xA4B92905A4B92905};
  144.     uint64_t key2[3] = {0xC567A1F3C567A1F3, 0x0000000000000000, 0xC567A1F3C567A1F3};
  145.     uint64_t key3[3] = {0xE3D17F253E3D17F2, 0x0000000000000000, 0xE3D17F253E3D17F2};
  146.  
  147.     TripleDES des(key1, key2, key3);
  148.  
  149.     auto begin = des.getMillisTimestamp();
  150.     des.encryptFile(inputFile, outputFile);
  151.     auto end = des.getMillisTimestamp();
  152.  
  153.     auto duration_ms = end - begin;
  154.     std::cout << "Encryption completed in " << duration_ms << " ms." << std::endl;
  155.  
  156.     return 0;
  157. }
  158.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement