/
encrypt.c
291 lines (246 loc) · 7.06 KB
/
encrypt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LENGTH 5
#define HALF_LENGTH ((LENGTH % 2 == 0)? (LENGTH / 2) : (LENGTH / 2) + 1)
void print(unsigned char str[], int size)
{
int i;
for(i = 0; i < size - 1; i++)
{
printf ("%02X ", str[i] & 0xFF);
}
printf("\n");
}
void getLeft(unsigned char arr[], unsigned char *left)
{
int i;
for(i = 0; i < LENGTH/2; i++)
{
*left++ = arr[i];
}
*left = '\0';
}
void getRight(unsigned char arr[], unsigned char *right)
{
int i;
for(i = LENGTH/2; i < LENGTH - 1; i++)
{
*right++ = arr[i];
}
*right = '\0';
}
void leftCircularShift16Bit(unsigned char arr[])
{
unsigned char mask = 0x80;
unsigned char MSBH = (((arr[0] & mask) == 0) ? 0 : 1);
unsigned char MSBL = (((arr[1] & mask) == 0) ? 0 : 1);
arr[0] = arr[0] << 1;
arr[1] = arr[1] << 1;
arr[0] |= MSBL;
arr[1] |= MSBH;
}
void leftCircularShift32Bit(unsigned char arr[])
{
unsigned char mask = 0x80;
unsigned char MSB0 = (((arr[0] & mask) == 0) ? 0 : 1);
unsigned char MSB1 = (((arr[1] & mask) == 0) ? 0 : 1);
unsigned char MSB2 = (((arr[2] & mask) == 0) ? 0 : 1);
unsigned char MSB3 = (((arr[3] & mask) == 0) ? 0 : 1);
arr[0] = arr[0] << 1;
arr[1] = arr[1] << 1;
arr[2] = arr[2] << 1;
arr[3] = arr[3] << 1;
arr[0] |= MSB1;
arr[1] |= MSB2;
arr[2] |= MSB3;
arr[3] |= MSB0;
}
void rightCircularShift16Bit(unsigned char arr[])
{
unsigned char mask = 0x01;
unsigned char LSBH = (((arr[0] & mask) == 0) ? 0 : 0x80);
unsigned char LSBL = (((arr[1] & mask) == 0) ? 0 : 0x80);
arr[0] = arr[0] >> 1;
arr[1] = arr[1] >> 1;
arr[0] |= LSBL;
arr[1] |= LSBH;
}
void rightCircularShift32Bit(unsigned char arr[])
{
unsigned char mask = 0x01;
unsigned char LSB0 = (((arr[0] & mask) == 0) ? 0 : 0x80);
unsigned char LSB1 = (((arr[1] & mask) == 0) ? 0 : 0x80);
unsigned char LSB2 = (((arr[2] & mask) == 0) ? 0 : 0x80);
unsigned char LSB3 = (((arr[3] & mask) == 0) ? 0 : 0x80);
arr[0] = arr[0] >> 1;
arr[1] = arr[1] >> 1;
arr[2] = arr[2] >> 1;
arr[3] = arr[3] >> 1;
arr[0] |= LSB3;
arr[1] |= LSB0;
arr[2] |= LSB1;
arr[3] |= LSB2;
}
void getPermutationPosition(int position[])
{
int i;
int p[32] = {30,8,2,15,19,20,27,29,31,0,7,14,16,22,5,25,28,12,1,11,26,10,3,13,18,23,24,6,9,17,21,4};
for(i = 0; i < 32; i++)
position[i] = p[i];
}
void permutation(unsigned char original[], unsigned char derived[], int position[], int size)
{
int i;
int j;
unsigned char mask;
unsigned char val;
unsigned char bit;
for(i = 0; i < size/8; i++)
derived[i] = 0;
for(i = 0; i < size; i++)
{
if(i < 8)
val = original[0];
else if(i < 16)
val = original[1];
else if(i < 24)
val = original[2];
else
val = original[3];
mask = 0x01;
mask = mask << (7-(i%8));
bit = (((val & mask) == 0) ? 0 : 1);
if(bit == 1)
{
bit = bit << (7-(position[i] % 8));
if(position[i] < 8)
derived[0] |= bit;
else if(position[i] < 16)
derived[1] |= bit;
else if(position[i] < 24)
derived[2] |= bit;
else
derived[3] |= bit;
}
}
}
void deriveKey(unsigned char iv[], unsigned char key[])
{
int i;
unsigned char liv[HALF_LENGTH];
unsigned char riv[HALF_LENGTH];
unsigned char temp[HALF_LENGTH];
key[0] = 0;
key[1] = 0;
key[2] = 0;
key[3] = 0;
// permutation position
int position[16] = {8,10,5,12,7,15,9,11,13,2,1,0,3,4,6,14};
// split key
getLeft(iv, liv);
getRight(iv, riv);
// left rotate the left key twice
for (i = 0; i < 2; i++)
{
rightCircularShift16Bit(liv);
leftCircularShift16Bit(riv);
}
// liv becomes right part of the derived key
for(i = 0; i < 2; i++)
key[i + 2] = liv[i];
// apply permutation
permutation(riv, temp, position, 16);
// xor temp with liv to form left part of the derived key
for(i = 0; i < HALF_LENGTH - 1; i++)
key[i] = temp[i]^liv[i];
}
void encrypt(unsigned char iv[], unsigned char plain[], unsigned char cipher[])
{
unsigned char key[LENGTH];
unsigned char inter[LENGTH];
int i;
int position[32];
// get permutation position info
getPermutationPosition(position);
// derive key
deriveKey(iv, key);
//Applying RightCircular shift to key
rightCircularShift32Bit(key);
// xor plain text with derived key
for(i = 0; i < LENGTH - 1; i++)
inter[i] = plain[i]^key[i];
// apply permutation
permutation(inter, cipher, position, 32);
// apply left rotation thrice
for(i = 0; i < 3; i++)
leftCircularShift32Bit(cipher);
}
void init (unsigned char arr[], int size)
{
int i;
for(i = 0; i < size; i++)
arr[i] = '\0';
}
void convertHex(unsigned char initkey[], unsigned char iv[])
{
int i;
for(i = 0; i < 8; i++)
if(initkey[i] >= 0x30 && initkey[i] <= 0x39)
if(i%2 == 0)
iv[i/2] |= ((initkey[i] & 0x0F) << 4);
else
iv[i/2] |= (initkey[i] & 0x0F);
else if((initkey[i] >= 0x41 && initkey[i] <= 0x46) || (initkey[i] >= 0x61 && initkey[i] <= 0x66))
if(i%2 == 0)
iv[i/2] |= (((initkey[i] & 0x0F) + 9) << 4);
else
iv[i/2] |= ((initkey[i] & 0x0F) + 9);
}
void main(int argc, char *argv[])
{
unsigned char initkey[9];
int i;
FILE * pFile;
unsigned char iv[LENGTH];
unsigned char ciphertxt[LENGTH];
unsigned char plaintxt[LENGTH];
//Reading the key given at command line and storing it in our initial vector
for(i=0;i<8;i++)
{
initkey[i]=*(argv[1]+i);
}
initkey[8]='\0';
init(iv, LENGTH);
init(ciphertxt, LENGTH);
init(plaintxt, LENGTH);
convertHex(initkey, iv);
// checking to see if the key has been extracted correctly
print(iv, LENGTH);
// Reading plain text from file
pFile = fopen (argv[2] , "r");
if (pFile == NULL) perror ("Error opening file");
else {
if ( fgets (plaintxt , LENGTH , pFile) != NULL )
fclose (pFile);
}
printf("Plain Text : %s\n\n", plaintxt);
encrypt(iv, plaintxt, ciphertxt);
//Applying RightCircular shift
rightCircularShift32Bit(iv);
//Copying Cipher Text to Plain Text
strcpy(plaintxt,ciphertxt);
//updated Plain text is now used for encryption
encrypt(iv, plaintxt, ciphertxt);
//Applying the same set of operations again
rightCircularShift32Bit(iv);
strcpy(plaintxt,ciphertxt);
encrypt(iv, plaintxt, ciphertxt);
// print cipher
printf("Encrypting...\n");
printf("Cipher Text : %s\n\n", ciphertxt);
//Copying Cipher text to output file
pFile = fopen (argv[3],"w");
fputs (ciphertxt,pFile);
fclose (pFile);
}