Advertisement
Guest User

Untitled

a guest
Nov 27th, 2014
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.48 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5.  
  6.  
  7. #define maxShortValue   65537
  8. #define fuyi    65536
  9.  
  10.  
  11. #define one     65535
  12. #define roundsCount 8
  13.  
  14.  
  15. int ReadBuffer(FILE *f, unsigned long fsize, unsigned inputBlock[5]);
  16. int WriteBuffer(FILE *f, unsigned outputBlock[5]);
  17.  
  18. void Cypher(unsigned inputBlock[5],unsigned outputBlock[5], unsigned subKeys[7][10]);
  19. void BuildKey(short unsigned uskey[9], unsigned subKeys[7][10]);
  20. void BuildDecryptKey(unsigned subKeys[7][10], unsigned decryptedSubKeys[7][10]);
  21.  
  22. unsigned Inversion(unsigned inputX);
  23. unsigned Multiplication(unsigned a, unsigned b);
  24.  
  25. int main(int argc, char **argv)
  26. {
  27.     int i, j, x, reverse, operTrig;
  28.    
  29.     unsigned subKeys[7][10], decryptedSubKeys[7][10], inputInfo[5], outputInfo[5];
  30.     short unsigned userKey[9];
  31.     unsigned long fileSize   = 0;
  32.     FILE *fInput, *fOutput;
  33.  
  34.     if (argc < 3)
  35.     {
  36.         exit(0);
  37.     }
  38.    
  39.     fInput = fopen(argv[1], "rb");
  40.     fOutput = fopen(argv[2], "wb");
  41.  
  42.     fseek(fInput, 0, SEEK_END);
  43.     fileSize = ftell(fInput);
  44.     fseek(fInput, 0, SEEK_SET);
  45.    
  46.     printf("file size: %lu\n", fileSize);
  47.    
  48.     //for(i = 1; i <= roundsCount; i++) userKey[i]=i;
  49.  
  50.    
  51.     printf("enter the BuildKey: ");
  52.     for (i = 1; i <= roundsCount; i++)  // read user BuildKey in hex format
  53.     {
  54.         scanf("%hx", &userKey[i]);
  55.     }
  56.  
  57.    
  58.     BuildKey(userKey,subKeys);  /* first step:  generate 52 encryption subkeys Z[i][r] */
  59.    
  60.     printf("\n-------------------------------------------------------------------\n");
  61.     printf("\nEncryption keys\t  KEY1\t  KEY2\t  KEY3\t  KEY4\t  KEY5\t  KEY6\n");
  62.     for(j = 1; j <= 9; j++)
  63.     {
  64.         printf("\n round # %1d:",j);
  65.         if(j == 9)  // need only 4 sub-keys on last iteration
  66.         {
  67.             for(i = 1; i <= 4; i++) printf("\t%6X",subKeys[i][j]);
  68.         }
  69.         else
  70.         {
  71.             for(i = 1; i <= 6; i++) printf("\t%6X",subKeys[i][j]);
  72.         }
  73.     }
  74.    
  75.     BuildDecryptKey(subKeys,decryptedSubKeys);  /* compute decryption subkeys decryptedSubKeys[i][r] */
  76.    
  77.     printf("\n-------------------------------------------------------------------\n");
  78.     printf("\n\n\n\nDecryption keys\t  dKey1\t  dKey2\t  dKey3\t  dKey4\t  dKey5\t  dKey6\n");
  79.    
  80.     for(j = 1; j <= 9; j++)
  81.     {
  82.         printf("\n round # %1d:",j);
  83.         if(j == 9) // need only 4 sub-keys on last iteration
  84.         {
  85.             for(i = 1; i <= 4; i++) printf("\t%6X",decryptedSubKeys[i][j]);
  86.         }
  87.         else
  88.         {
  89.             for(i = 1; i <= 6; i++) printf("\t%6X",decryptedSubKeys[i][j]);
  90.         }
  91.     }
  92.    
  93.     printf("\n-------------------------------------------------------------------\n");
  94.     printf("\n\n\n\t       Choose your operation: ");
  95.     printf("\n\n\t\t1 - Make Crypt\n\t\t2 - Make Decrypt\n\t    : ");
  96.     scanf("%d", &operTrig);
  97.    
  98.     switch(operTrig)
  99.     {
  100.         case 1:
  101.            reverse = 0;
  102.            break;
  103.         case 2:
  104.            reverse = 1;
  105.            break;
  106.         default :
  107.            exit(0);
  108.     }
  109.    
  110.     printf("\n-------------------------------------------------------------------\n");
  111.    
  112.     while (ReadBuffer(fInput, fileSize, inputInfo))
  113.     {
  114.         if (!reverse)
  115.         {
  116.             Cypher(inputInfo,outputInfo,subKeys);   /* encrypt inputInfo to outputInfo with BuildKey Z */
  117.         }
  118.         else
  119.         {
  120.             Cypher(inputInfo,outputInfo,decryptedSubKeys);  /* decrypt */
  121.         }
  122.  
  123.         WriteBuffer(fOutput, outputInfo); /* write outputInfo to file */
  124.        
  125.         printf("\n\n Cipher Text Y \t%6X\t%6X\t%6X\t%6X\n",
  126.            outputInfo[1],outputInfo[2],outputInfo[3],outputInfo[4]);
  127.            
  128.          printf("\n=================================================\n");
  129.     }
  130.    
  131.     fclose(fInput);
  132.     fclose(fOutput);
  133.    
  134.     return 0;
  135. }
  136.  
  137. int ReadBuffer(FILE *f, unsigned long fileSize, unsigned inputBlock[5])
  138. {
  139.     unsigned char c[2];
  140.     int i = 0;
  141.    
  142.     if (ftell(f) == fileSize)
  143.         return 0;
  144.    
  145.     for (i = 1; i <= 4; i++)
  146.     {
  147.        
  148.         fscanf(f, "%c", &c[1]);
  149.         if (feof(f)) c[1] = 0;
  150.         fscanf(f, "%c", &c[0]);
  151.         if (feof(f)) c[0] = 0;
  152.        
  153.         inputBlock[i] = *((unsigned short *)c);
  154.         //sscanf(c, "%x", &inputBlock[i]);
  155.     }
  156.  
  157.     printf("\n\n Plain Text:  X  %6X\t%6X\t%6X\t%6X\n",
  158.            inputBlock[1],inputBlock[2],inputBlock[3],inputBlock[4]);
  159.  
  160.     return 1;
  161.  
  162. }
  163.  
  164. int WriteBuffer(FILE *f, unsigned outputBlock[5])
  165. {
  166.     unsigned char *c;
  167.     int i = 0;
  168.  
  169.     for (i = 1; i <= 4; i++)
  170.     {
  171.         c = (unsigned char *)&outputBlock[i];
  172.  
  173.         fprintf(f, "%c", c[1]);
  174.         fprintf(f, "%c", c[0]);
  175.     }
  176.    
  177.     return 0;
  178. }
  179.  
  180. /* encrypt algorithm */
  181. void Cypher(unsigned inputBlock[5],unsigned outputBlock[5],unsigned subKeys[7][10]) // 4 интовыйх числа(индексация с 1) каждой из которых являет собой 16 бит шифруемой последовательности
  182. {
  183.     unsigned r, x1, x2, x3, x4, kk, t1, t2, a;  
  184.     x1 = inputBlock[1]; x2 = inputBlock[2]; x3 = inputBlock[3]; x4 = inputBlock[4];
  185.      
  186.     for(r = 1; r <= 8; r++)  // 8 raunds of encryption
  187.     {
  188.         /* the group operation on 64-bits block */
  189.         x1 = Multiplication(x1, subKeys[1][r]);    
  190.         x4 = Multiplication(x4, subKeys[4][r]);
  191.         x2 = (x2 + subKeys[2][r]) & one;   
  192.         x3 = (x3 + subKeys[3][r]) & one;
  193.         /* the function of the MA structure */
  194.         kk = Multiplication(subKeys[5][r], (x1^x3));
  195.         t1 = Multiplication(subKeys[6][r], (kk+(x2^x4)) & one);
  196.         t2 = (kk + t1) & one;
  197.         /* the Inversionolutary permutation PI */
  198.         x1 = x1^t1;    
  199.         x4=x4^t2;
  200.         a  = x2^t2;    
  201.         x2=x3^t1;  
  202.         x3=a;
  203.        
  204.         printf("\n\tround %1u  %6X\t%6X\t%6X\t%6X",r,x1,x2,x3,x4);
  205.     }
  206.    
  207.     /* the output transformation */
  208.     outputBlock[1] = Multiplication(x1, subKeys[1][roundsCount+1]);  // 9-th round
  209.     outputBlock[4] = Multiplication(x4, subKeys[4][roundsCount+1]);
  210.     outputBlock[2] = (x3 + subKeys[2][roundsCount+1]) & one;
  211.     outputBlock[3] = (x2 + subKeys[3][roundsCount+1]) & one;
  212. }
  213.  
  214. /* Multiplication using the Low-High algorithm */
  215.  
  216. unsigned Multiplication(unsigned a,unsigned b)   // multiplication on modulo (2^16 + 1)
  217. {
  218.     long int p;
  219.     long unsigned q;
  220.    
  221.     if(a == 0)
  222.         p = maxShortValue - b;
  223.     else
  224.         if(b == 0)
  225.         {
  226.             p = maxShortValue - a;
  227.         }
  228.         else
  229.         {
  230.             q = (unsigned long)a * (unsigned long)b;
  231.             p = (q & one) - (q >> 16);
  232.             if (p <= 0)
  233.             {
  234.                 p = p + maxShortValue;
  235.             }
  236.         }
  237.     return (unsigned)(p & one);
  238. }
  239.  
  240. /* compute Inversionerse of xin by Euclidean gcd alg. */
  241.  
  242.  
  243. // 5 по модулю 7: результат мультипликативной инверсии (число, на каторое нужно умножить 5, чтобы при делении на 7 остаток был равен 1)
  244. // 5*x mod 7 = 1;   x - ?
  245. unsigned Inversion(unsigned inputX)  // нахождение мультипликативной инверсии
  246. {  
  247.     long n1,n2,q,r,b1,b2,t;
  248.    
  249.     // maxShortValue is modulo in our case
  250.    
  251.     if (inputX == 0)
  252.     {
  253.         b2 = 0;
  254.     }
  255.     else
  256.     {
  257.         n1 = maxShortValue;
  258.         n2 = inputX;
  259.         b2 = 1;
  260.         b1 = 0;
  261.         do
  262.         {
  263.             r = (n1 % n2);
  264.             q = (n1 - r) / n2;
  265.            
  266.             if(r == 0)
  267.             {
  268.                 if(b2 < 0)
  269.                 {
  270.                     b2 = maxShortValue + b2;
  271.                 }
  272.             }
  273.             else
  274.             {
  275.                 n1 = n2;
  276.                 n2 = r;
  277.                 t = b2;
  278.                 b2 = b1 - q * b2;
  279.                 b1 = t;
  280.             }
  281.         } while (r != 0);
  282.     }
  283.     return (unsigned)b2;
  284. }
  285.  
  286.  
  287. void BuildKey(short unsigned userKey[9], unsigned subKeys[7][10])
  288. {
  289.     short unsigned S[54];  // 54 t.k indexing from 1 and (equal )
  290.     int i,j,r;
  291.    
  292.     for(i = 1; i < 9; i++)
  293.     {  
  294.         S[i-1] = userKey[i];   // first 8 - without changes
  295.     }
  296.    
  297.     // each BuildKey has 16 bit size
  298.     // after that shift all bits for 25 to left (циклически)
  299.     // на кажом сдвиге формируем 8 подключей заново из 128 измененых бит
  300.     // на последнем 6м сдвиге формируем только 4 ключа
  301.    
  302.    
  303.     for(i = 8; i < 54; i++)
  304.     {
  305.         if (((i+2) % 8) == 0)  
  306.         {
  307.             S[i] = ((S[i-7] << 9) ^ (S[i-14] >> 7)) & one;
  308.         }
  309.         else
  310.         {
  311.             if (((i+1) % 8) == 0)  
  312.             {
  313.                 S[i] = ((S[i-15] << 9) ^ (S[i-14] >> 7)) & one;
  314.             }
  315.             else
  316.             {
  317.                 S[i] = ((S[i-7] << 9) ^ (S[i-6] >> 7)) & one;
  318.             }
  319.         }
  320.     }
  321.    
  322.     for (r = 1; r <= roundsCount+1; r++)
  323.     {
  324.         for(j = 1;j < 7;j++)
  325.         {
  326.             subKeys[j][r] = S[6*(r-1)+j-1];
  327.         }
  328.     }
  329. }
  330.  
  331. void BuildDecryptKey(unsigned subKeys[7][10],unsigned decryptedSubKeys[7][10])  // 6-x keys for each of 9 rounds (indexing from 1 instead 0)
  332. {
  333.     int j;
  334.    
  335.     for(j = 1;j <= roundsCount + 1; j++)
  336.     {
  337.         decryptedSubKeys[1][roundsCount-j+2] = Inversion(subKeys[1][j]);  // мультипликативная инверсия
  338.         decryptedSubKeys[4][roundsCount-j+2] = Inversion(subKeys[4][j]);
  339.        
  340.         if (j == 1 || j == roundsCount+1) {
  341.             decryptedSubKeys[2][roundsCount-j+2] = (fuyi-subKeys[2][j]) & one;   // аддитивная инверсия
  342.             decryptedSubKeys[3][roundsCount-j+2] = (fuyi-subKeys[3][j]) & one;
  343.         } else {
  344.             decryptedSubKeys[2][roundsCount-j+2] = (fuyi-subKeys[3][j]) & one;   //
  345.             decryptedSubKeys[3][roundsCount-j+2] = (fuyi-subKeys[2][j]) & one;
  346.         }
  347.     }
  348.    
  349.     for(j = 1; j <= roundsCount+1; j++)
  350.     {
  351.         decryptedSubKeys[5][roundsCount+1-j] = subKeys[5][j];
  352.         decryptedSubKeys[6][roundsCount+1-j] = subKeys[6][j];
  353.     }
  354. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement