Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #define maxShortValue 65537
- #define fuyi 65536
- #define one 65535
- #define roundsCount 8
- int ReadBuffer(FILE *f, unsigned long fsize, unsigned inputBlock[5]);
- int WriteBuffer(FILE *f, unsigned outputBlock[5]);
- void Cypher(unsigned inputBlock[5],unsigned outputBlock[5], unsigned subKeys[7][10]);
- void BuildKey(short unsigned uskey[9], unsigned subKeys[7][10]);
- void BuildDecryptKey(unsigned subKeys[7][10], unsigned decryptedSubKeys[7][10]);
- unsigned Inversion(unsigned inputX);
- unsigned Multiplication(unsigned a, unsigned b);
- int main(int argc, char **argv)
- {
- int i, j, x, reverse, operTrig;
- unsigned subKeys[7][10], decryptedSubKeys[7][10], inputInfo[5], outputInfo[5];
- short unsigned userKey[9];
- unsigned long fileSize = 0;
- FILE *fInput, *fOutput;
- if (argc < 3)
- {
- exit(0);
- }
- fInput = fopen(argv[1], "rb");
- fOutput = fopen(argv[2], "wb");
- fseek(fInput, 0, SEEK_END);
- fileSize = ftell(fInput);
- fseek(fInput, 0, SEEK_SET);
- printf("file size: %lu\n", fileSize);
- //for(i = 1; i <= roundsCount; i++) userKey[i]=i;
- printf("enter the BuildKey: ");
- for (i = 1; i <= roundsCount; i++) // read user BuildKey in hex format
- {
- scanf("%hx", &userKey[i]);
- }
- BuildKey(userKey,subKeys); /* first step: generate 52 encryption subkeys Z[i][r] */
- printf("\n-------------------------------------------------------------------\n");
- printf("\nEncryption keys\t KEY1\t KEY2\t KEY3\t KEY4\t KEY5\t KEY6\n");
- for(j = 1; j <= 9; j++)
- {
- printf("\n round # %1d:",j);
- if(j == 9) // need only 4 sub-keys on last iteration
- {
- for(i = 1; i <= 4; i++) printf("\t%6X",subKeys[i][j]);
- }
- else
- {
- for(i = 1; i <= 6; i++) printf("\t%6X",subKeys[i][j]);
- }
- }
- BuildDecryptKey(subKeys,decryptedSubKeys); /* compute decryption subkeys decryptedSubKeys[i][r] */
- printf("\n-------------------------------------------------------------------\n");
- printf("\n\n\n\nDecryption keys\t dKey1\t dKey2\t dKey3\t dKey4\t dKey5\t dKey6\n");
- for(j = 1; j <= 9; j++)
- {
- printf("\n round # %1d:",j);
- if(j == 9) // need only 4 sub-keys on last iteration
- {
- for(i = 1; i <= 4; i++) printf("\t%6X",decryptedSubKeys[i][j]);
- }
- else
- {
- for(i = 1; i <= 6; i++) printf("\t%6X",decryptedSubKeys[i][j]);
- }
- }
- printf("\n-------------------------------------------------------------------\n");
- printf("\n\n\n\t Choose your operation: ");
- printf("\n\n\t\t1 - Make Crypt\n\t\t2 - Make Decrypt\n\t : ");
- scanf("%d", &operTrig);
- switch(operTrig)
- {
- case 1:
- reverse = 0;
- break;
- case 2:
- reverse = 1;
- break;
- default :
- exit(0);
- }
- printf("\n-------------------------------------------------------------------\n");
- while (ReadBuffer(fInput, fileSize, inputInfo))
- {
- if (!reverse)
- {
- Cypher(inputInfo,outputInfo,subKeys); /* encrypt inputInfo to outputInfo with BuildKey Z */
- }
- else
- {
- Cypher(inputInfo,outputInfo,decryptedSubKeys); /* decrypt */
- }
- WriteBuffer(fOutput, outputInfo); /* write outputInfo to file */
- printf("\n\n Cipher Text Y \t%6X\t%6X\t%6X\t%6X\n",
- outputInfo[1],outputInfo[2],outputInfo[3],outputInfo[4]);
- printf("\n=================================================\n");
- }
- fclose(fInput);
- fclose(fOutput);
- return 0;
- }
- int ReadBuffer(FILE *f, unsigned long fileSize, unsigned inputBlock[5])
- {
- unsigned char c[2];
- int i = 0;
- if (ftell(f) == fileSize)
- return 0;
- for (i = 1; i <= 4; i++)
- {
- fscanf(f, "%c", &c[1]);
- if (feof(f)) c[1] = 0;
- fscanf(f, "%c", &c[0]);
- if (feof(f)) c[0] = 0;
- inputBlock[i] = *((unsigned short *)c);
- //sscanf(c, "%x", &inputBlock[i]);
- }
- printf("\n\n Plain Text: X %6X\t%6X\t%6X\t%6X\n",
- inputBlock[1],inputBlock[2],inputBlock[3],inputBlock[4]);
- return 1;
- }
- int WriteBuffer(FILE *f, unsigned outputBlock[5])
- {
- unsigned char *c;
- int i = 0;
- for (i = 1; i <= 4; i++)
- {
- c = (unsigned char *)&outputBlock[i];
- fprintf(f, "%c", c[1]);
- fprintf(f, "%c", c[0]);
- }
- return 0;
- }
- /* encrypt algorithm */
- void Cypher(unsigned inputBlock[5],unsigned outputBlock[5],unsigned subKeys[7][10]) // 4 интовыйх числа(индексация с 1) каждой из которых являет собой 16 бит шифруемой последовательности
- {
- unsigned r, x1, x2, x3, x4, kk, t1, t2, a;
- x1 = inputBlock[1]; x2 = inputBlock[2]; x3 = inputBlock[3]; x4 = inputBlock[4];
- for(r = 1; r <= 8; r++) // 8 raunds of encryption
- {
- /* the group operation on 64-bits block */
- x1 = Multiplication(x1, subKeys[1][r]);
- x4 = Multiplication(x4, subKeys[4][r]);
- x2 = (x2 + subKeys[2][r]) & one;
- x3 = (x3 + subKeys[3][r]) & one;
- /* the function of the MA structure */
- kk = Multiplication(subKeys[5][r], (x1^x3));
- t1 = Multiplication(subKeys[6][r], (kk+(x2^x4)) & one);
- t2 = (kk + t1) & one;
- /* the Inversionolutary permutation PI */
- x1 = x1^t1;
- x4=x4^t2;
- a = x2^t2;
- x2=x3^t1;
- x3=a;
- printf("\n\tround %1u %6X\t%6X\t%6X\t%6X",r,x1,x2,x3,x4);
- }
- /* the output transformation */
- outputBlock[1] = Multiplication(x1, subKeys[1][roundsCount+1]); // 9-th round
- outputBlock[4] = Multiplication(x4, subKeys[4][roundsCount+1]);
- outputBlock[2] = (x3 + subKeys[2][roundsCount+1]) & one;
- outputBlock[3] = (x2 + subKeys[3][roundsCount+1]) & one;
- }
- /* Multiplication using the Low-High algorithm */
- unsigned Multiplication(unsigned a,unsigned b) // multiplication on modulo (2^16 + 1)
- {
- long int p;
- long unsigned q;
- if(a == 0)
- p = maxShortValue - b;
- else
- if(b == 0)
- {
- p = maxShortValue - a;
- }
- else
- {
- q = (unsigned long)a * (unsigned long)b;
- p = (q & one) - (q >> 16);
- if (p <= 0)
- {
- p = p + maxShortValue;
- }
- }
- return (unsigned)(p & one);
- }
- /* compute Inversionerse of xin by Euclidean gcd alg. */
- // 5 по модулю 7: результат мультипликативной инверсии (число, на каторое нужно умножить 5, чтобы при делении на 7 остаток был равен 1)
- // 5*x mod 7 = 1; x - ?
- unsigned Inversion(unsigned inputX) // нахождение мультипликативной инверсии
- {
- long n1,n2,q,r,b1,b2,t;
- // maxShortValue is modulo in our case
- if (inputX == 0)
- {
- b2 = 0;
- }
- else
- {
- n1 = maxShortValue;
- n2 = inputX;
- b2 = 1;
- b1 = 0;
- do
- {
- r = (n1 % n2);
- q = (n1 - r) / n2;
- if(r == 0)
- {
- if(b2 < 0)
- {
- b2 = maxShortValue + b2;
- }
- }
- else
- {
- n1 = n2;
- n2 = r;
- t = b2;
- b2 = b1 - q * b2;
- b1 = t;
- }
- } while (r != 0);
- }
- return (unsigned)b2;
- }
- void BuildKey(short unsigned userKey[9], unsigned subKeys[7][10])
- {
- short unsigned S[54]; // 54 t.k indexing from 1 and (equal )
- int i,j,r;
- for(i = 1; i < 9; i++)
- {
- S[i-1] = userKey[i]; // first 8 - without changes
- }
- // each BuildKey has 16 bit size
- // after that shift all bits for 25 to left (циклически)
- // на кажом сдвиге формируем 8 подключей заново из 128 измененых бит
- // на последнем 6м сдвиге формируем только 4 ключа
- for(i = 8; i < 54; i++)
- {
- if (((i+2) % 8) == 0)
- {
- S[i] = ((S[i-7] << 9) ^ (S[i-14] >> 7)) & one;
- }
- else
- {
- if (((i+1) % 8) == 0)
- {
- S[i] = ((S[i-15] << 9) ^ (S[i-14] >> 7)) & one;
- }
- else
- {
- S[i] = ((S[i-7] << 9) ^ (S[i-6] >> 7)) & one;
- }
- }
- }
- for (r = 1; r <= roundsCount+1; r++)
- {
- for(j = 1;j < 7;j++)
- {
- subKeys[j][r] = S[6*(r-1)+j-1];
- }
- }
- }
- void BuildDecryptKey(unsigned subKeys[7][10],unsigned decryptedSubKeys[7][10]) // 6-x keys for each of 9 rounds (indexing from 1 instead 0)
- {
- int j;
- for(j = 1;j <= roundsCount + 1; j++)
- {
- decryptedSubKeys[1][roundsCount-j+2] = Inversion(subKeys[1][j]); // мультипликативная инверсия
- decryptedSubKeys[4][roundsCount-j+2] = Inversion(subKeys[4][j]);
- if (j == 1 || j == roundsCount+1) {
- decryptedSubKeys[2][roundsCount-j+2] = (fuyi-subKeys[2][j]) & one; // аддитивная инверсия
- decryptedSubKeys[3][roundsCount-j+2] = (fuyi-subKeys[3][j]) & one;
- } else {
- decryptedSubKeys[2][roundsCount-j+2] = (fuyi-subKeys[3][j]) & one; //
- decryptedSubKeys[3][roundsCount-j+2] = (fuyi-subKeys[2][j]) & one;
- }
- }
- for(j = 1; j <= roundsCount+1; j++)
- {
- decryptedSubKeys[5][roundsCount+1-j] = subKeys[5][j];
- decryptedSubKeys[6][roundsCount+1-j] = subKeys[6][j];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement