Advertisement
Guest User

Untitled

a guest
Feb 24th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.26 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <omp.h>
  3. #include <numeric>
  4. #include <cmath>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <cstdio>
  8.  
  9. #include "tables.h"
  10. #include "des.h"
  11.  
  12. #define MAXIMUM_THREADS 8
  13. using namespace std;
  14.  
  15. float sb0 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[0][plainByte ^ key]); }
  16. float sb1 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[1][plainByte ^ key]); }
  17. float sb2 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[2][plainByte ^ key]); }
  18. float sb3 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[3][plainByte ^ key]); }
  19. float sb4 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[4][plainByte ^ key]); }
  20. float sb5 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[5][plainByte ^ key]); }
  21. float sb6 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[6][plainByte ^ key]); }
  22. float sb7 (uint8_t plainByte, uint8_t key) { return (float)__builtin_popcount(Sb[7][plainByte ^ key]); }
  23.  
  24. typedef float (*sboxFunctionPointer) (uint8_t plainByte, uint8_t key);
  25.  
  26. void readTimeData(char* realtimeFilename, vector<float>& realTime, long numberOfEncryptions){
  27.     FILE *timingFile;
  28.     double currentTiming;
  29.    
  30.     timingFile = fopen(realtimeFilename,"r");
  31.     printf("%ld timings.\n",numberOfEncryptions);
  32.     for (long i = 0; i < numberOfEncryptions; i++){
  33.         fscanf(timingFile,"%lf\n",&currentTiming);
  34.         realTime[i] = (float)currentTiming;    
  35.     }
  36.    
  37.     fclose(timingFile);
  38. }
  39.  
  40.  
  41. void readPlaintextData(char* plaintextFilename,vector< vector<uint8_t> > &rightExpanded, long numberOfEncryptions, int bytesNumber, int keyCandidates){
  42.     FILE *plaintextFile;
  43.     uint32_t Right = 0;
  44.     uint64_t iteratorIP = 0x0ULL;
  45.     uint64_t iteratorExpandedR = 0x0ULL;
  46.    
  47.     plaintextFile = fopen(plaintextFilename, "r");
  48.     printf("%d plaintexts.\n",numberOfEncryptions);
  49.  
  50.     for (long i = 0; i < numberOfEncryptions; i++){
  51.         fscanf(plaintextFile,"%llX",&iteratorIP);
  52.         Right = performInitialPermutation(iteratorIP) & 0xffffffff;
  53.         iteratorExpandedR = performExpansion(Right);
  54.            
  55.         for (int j=0; j<bytesNumber; j++)
  56.             rightExpanded[j][i] = (iteratorExpandedR >> ((bytesNumber - j - 1)*(unsigned int)log2(keyCandidates))) & (keyCandidates-1);
  57.        
  58.     }
  59.     fclose(plaintextFile);
  60. }
  61.  
  62. void resizeVectors(vector<vector<uint8_t> > &rightExpanded, vector< vector<double> > &correlationResults, int bytesNumber, int numberOfEncryptions, vector<float> &realTime, vector<float> &model, vector<uint8_t> &key, int keyCandidates){
  63.     model.resize(numberOfEncryptions);
  64.     realTime.resize(numberOfEncryptions);
  65.     key.resize(numberOfEncryptions);
  66.    
  67.  
  68.     correlationResults.resize(bytesNumber);
  69.     for (int i = 0; i < bytesNumber; i++)
  70.         correlationResults[i].resize(keyCandidates);
  71.  
  72.     rightExpanded.resize(bytesNumber);
  73.     for (int i = 0; i < bytesNumber; i++)
  74.         rightExpanded[i].resize(numberOfEncryptions);
  75. }
  76.  
  77. void populateTimingMode(vector<vector<uint8_t> > &rightExpanded, unsigned int numberOfEncryptions, vector<float> &generatedTimingPredictionModel, vector<uint8_t> &key, int SboxNum){
  78.     int threadCounter = 0;
  79.     sboxFunctionPointer chooseSbox[] = {sb0, sb1, sb2, sb3, sb4, sb5, sb6, sb7};
  80.  
  81.     omp_set_num_threads(MAXIMUM_THREADS);
  82.     int totalNumberOfThreads = omp_get_num_threads();
  83.  
  84.     #pragma omp parallel default(none) shared(totalNumberOfThreads, rightExpanded, generatedTimingPredictionModel, key, chooseSbox)
  85.     {
  86.             int tid     = omp_get_thread_num();
  87.             int nitems  = numberOfEncryptions/totalNumberOfThreads;
  88.             int start   = tid*nitems;
  89.             int end     = start + nitems;
  90.  
  91.             if (tid == totalNumberOfThreads-1) end = numberOfEncryptions;
  92.  
  93.             #pragma omp for
  94.             for (threadCounter=0; threadCounter<totalNumberOfThreads; threadCounter++)
  95.                 std::transform (rightExpanded[SboxNum].begin()+start, rightExpanded[SboxNum].begin()+end, key.begin()+start, generatedTimingPredictionModel.begin()+start, chooseSbox[SboxNum]);
  96.     }
  97. }
  98.  
  99.  
  100. double calculateCorrelation(vector<float> &x, vector<float> &y){
  101.     double sumX = 0.0,  sumY = 0.0;
  102.     double sumX2 = 0.0, sumY2 = 0.0;
  103.     double sumXY = 0.0;
  104.     const unsigned int num = x.size();
  105.     const double init = 0;
  106.    
  107.     double correlationValue = 0.0;
  108.     int nthreads = 0;
  109.  
  110.     omp_set_dynamic(0);
  111.     omp_set_num_threads(MAXIMUM_THREADS);
  112.    
  113.     #pragma omp parallel
  114.     #pragma omp single
  115.     nthreads = omp_get_num_threads();
  116.  
  117.     #pragma omp parallel default(none) reduction(+:sumX, sumX2, sumY, sumY2, sumXY) shared(nthreads,x,y)
  118.     {
  119.             int tid     = omp_get_thread_num();
  120.             int nitems  = num/nthreads;
  121.             int start   = tid*nitems;
  122.             int end     = start + nitems;
  123.            
  124.             if (tid == nthreads-1) end = num;
  125.  
  126.             #pragma omp for
  127.             for (int i=0; i<nthreads; i++){
  128.                 sumX2   += std::inner_product( x.begin() + start, x.begin()+end, x.begin()+start, init);
  129.                 sumX    += std::accumulate(x.begin()+start, x.begin()+end, init);
  130.                 sumY2   += std::inner_product( y.begin() + start,y.begin()+end, y.begin()+start, init);
  131.                 sumY    += std::accumulate(y.begin()+start, y.begin()+end, init);
  132.                 sumXY   += std::inner_product( x.begin() + start, x.begin()+end, y.begin()+start, init);
  133.             }
  134.     }
  135.    
  136.     correlationValue = (sumXY - sumX*sumY/num) / sqrt((sumX2 - sumX * sumX / num) * (sumY2 - sumY * sumY / num));
  137.    
  138.     if (!isnan(correlationValue))
  139.         return correlationValue;
  140.     else{
  141.         return 0;
  142.     }
  143.    
  144.     return 0;
  145. }
  146.  
  147. double saveResultsToFile(const char * resultFilename, int keyCandidates, vector< vector<double> > &pcc, uint8_t SboxNum){
  148.     FILE *resultsFile; 
  149.     resultsFile = fopen(resultFilename,"w");
  150.     fprintf(resultsFile,"#\t\tPrediction\n");
  151.     for (int i = 0; i < keyCandidates; i++)
  152.         fprintf(resultsFile,"%d\t%12f\n",i, pcc[SboxNum][i]*pcc[SboxNum][i]*100000);
  153.        
  154.     fclose(resultsFile);
  155. }
  156.  
  157. void singleSboxTimingAttack(unsigned int numberOfEncryptions, char* realtimeFilename, char* plaintextFilename, const char* resultFilename, uint8_t SboxNum){
  158.     const int keyCandidates = 64;
  159.     const int bytesNumber = 8;
  160.    
  161.     vector< vector<double> > correlationResults;                            /*The resulted likelihood information*/
  162.     vector<float> timingData;                               /*Explicit real time*/
  163.     vector<float> generatedTimingPredictionModel;           /*Timing model that is used as a prediction*/
  164.     vector<uint8_t> key;                                /*Key value*/
  165.     vector<vector<uint8_t> > rightExpanded;                             /*Expanded R, i.e. E(R) permutation of DES*/
  166.  
  167.     resizeVectors(rightExpanded, correlationResults, bytesNumber, numberOfEncryptions, timingData, generatedTimingPredictionModel, key, keyCandidates);
  168.     readTimeData(realtimeFilename, timingData, numberOfEncryptions);
  169.     readPlaintextData(plaintextFilename, rightExpanded, numberOfEncryptions, bytesNumber, keyCandidates);
  170.    
  171.     //create model
  172.     for (int i = 0; i < keyCandidates; i++){
  173.         std::fill(key.begin(),key.end(),i); //Entire key is composed of the same key candidate
  174.  
  175.         populateTimingMode(rightExpanded, numberOfEncryptions, generatedTimingPredictionModel, key, SboxNum);
  176.         correlationResults[SboxNum][i] = calculateCorrelation(timingData, generatedTimingPredictionModel);
  177.        
  178.         printf("Working...\t %.2lf%%\r\n",(double)(i+1)*(double)100/(double)(keyCandidates));
  179.         fflush(stdout);
  180.     }
  181.    
  182.     saveResultsToFile(resultFilename, keyCandidates, correlationResults, SboxNum); //write to file
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement