Exp.
No: 9
Data encryption and decryption using Data Encryption Standard algorithm
22.05.25
Aim
To encrypt and decrypt the data using Data Encryption Standard algorithm in C.
Software Required
Turbo C/Dev-C++
DES Algorithm
Step 1: Initialization
• Define 64-bit key and required tables: PC1, PC2, IP, FP, E-table, P-Box, S-Boxes,
and shift schedule.
Step 2: Key Scheduling
• Apply PC1 to key → get 56-bit key.
• Split into halves (C, D); perform left shifts per round.
• Apply PC2 to generate 16 subkeys (48-bit each).
Step 3: Initial Permutation
• Apply IP to 64-bit plaintext.
• Split into 32-bit halves: L and R.
Step 4: 16 Encryption Rounds
For each round:
• Expand R to 48 bits using E-table.
• XOR with round subkey.
• Substitute using S-Boxes → 32-bit result.
• Apply P-Box permutation.
• XOR with L → new R; swap L and R.
Step 5: Final Permutation
• Combine L and R; apply FP → ciphertext.
Step 6: Decryption
• Same process as encryption, using subkeys in reverse.
OUTPUT:
Enter 8-character key: security
Enter 16-digit hexadecimal plaintext: 012345678ABCD789
Round Keys (16 keys of 48 bits each):
Round 1 key: 512CACE2720B
Round 2 key: 51ACAC2B8CD3
Round 3 key: D1ACAE0BC413
Round 4 key: F1AEAE0F4400
Round 5 key: F1BEA6884140
Round 6 key: F0BEA680C204
Round 7 key: F0B626D02784
Round 8 key: E09626B8238D
Round 9 key: E0B6222724E5
Round 10 key: E196222EA8C7
Round 11 key: E1928A26E4D7
Round 12 key: 31928A2BA5C7
Round 13 key: 31188AAAE587
Round 14 key: 31288C6A6787
Round 15 key: 112C8CFA618B
Round 16 key: 512C8C27ACF7
Plaintext: 012345678ABCD789
Ciphertext: AA8A3A3FB588F04A
Decrypted: 012345678ABCD789
Program:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int PC1[56] = {
57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4
};
int PC2[48] = {
14,17,11,24,1,5,
3,28,15,6,21,10,
23,19,12,4,26,8,
16,7,27,20,13,2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32
};
int IP[64] = {
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7
};
int FP[64] = {
40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25
};
int E[48] = {
32,1,2,3,4,5,
4,5,6,7,8,9,
8,9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32,1
};
int P[32] = {
16,7,20,21,
29,12,28,17,
1,15,23,26,
5,18,31,10,
2,8,24,14,
32,27,3,9,
19,13,30,6,
22,11,4,25
};
int S[8][4][16] = {
{
{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
{0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
{4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
{15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}
},
{
{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
{3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
{0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
{13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}
},
{
{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},
{13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
{13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},
{1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}
},
{
{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},
{13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
{10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},
{3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}
},
{
{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
{14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},
{4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
{11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}
},
{
{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
{10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},
{9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
{4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}
},
{
{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
{13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},
{1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
{6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}
},
{
{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
{1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},
{7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
{2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}
}
};
int shiftTable[16] = {
1,1,2,2,2,2,2,2,
1,2,2,2,2,2,2,1
};
uint64_t permute(uint64_t input, int* table, int n) {
uint64_t output = 0;
for (int i = 0; i < n; i++) {
output <<= 1;
output |= (input >> (64 - table[i])) & 1;
}
return output;
}
uint32_t sBoxSubstitution(uint64_t input) {
uint32_t output = 0;
for (int i = 0; i < 8; i++) {
int row = ((input >> (42 - 6 * i)) & 0x20) | ((input >> (42 - 6 * i - 5)) & 1);
row = (row >> 4) | (row & 1);
int col = (input >> (43 - 6 * i - 1)) & 0xF;
output <<= 4;
output |= S[i][row][col];
}
return output;
}
void keySchedule(const char* key, uint64_t roundKeys[16]) {
uint64_t keyBits = 0;
for (int i = 0; i < 8; i++) {
keyBits = (keyBits << 8) | (uint8_t)key[i];
}
uint64_t permKey = permute(keyBits, PC1, 56);
uint32_t C = (permKey >> 28) & 0xFFFFFFF;
uint32_t D = permKey & 0xFFFFFFF;
for (int i = 0; i < 16; i++) {
C = ((C << shiftTable[i]) | (C >> (28 - shiftTable[i]))) & 0xFFFFFFF;
D = ((D << shiftTable[i]) | (D >> (28 - shiftTable[i]))) & 0xFFFFFFF;
uint64_t CD = ((uint64_t)C << 28) | D;
roundKeys[i] = permute(CD, PC2, 48);
}
}
uint64_t desEncryptBlock(uint64_t block, const uint64_t roundKeys[16]) {
block = permute(block, IP, 64);
uint32_t L = block >> 32;
uint32_t R = block & 0xFFFFFFFF;
for (int i = 0; i < 16; i++) {
uint64_t expandedR = permute((uint64_t)R << 32, E, 48);
expandedR ^= roundKeys[i];
uint32_t substituted = sBoxSubstitution(expandedR);
substituted = permute((uint64_t)substituted << 32, P, 32);
uint32_t temp = R;
R = L ^ substituted;
L = temp;
}
uint64_t combined = ((uint64_t)R << 32) | L;
return permute(combined, FP, 64);
}
uint64_t desDecryptBlock(uint64_t block, const uint64_t roundKeys[16]) {
block = permute(block, IP, 64);
uint32_t L = block >> 32;
uint32_t R = block & 0xFFFFFFFF;
for (int i = 15; i >= 0; i--) {
uint64_t expandedR = permute((uint64_t)R << 32, E, 48);
expandedR ^= roundKeys[i];
uint32_t substituted = sBoxSubstitution(expandedR);
substituted = permute((uint64_t)substituted << 32, P, 32);
uint32_t temp = R;
R = L ^ substituted;
L = temp;
}
uint64_t combined = ((uint64_t)R << 32) | L;
return permute(combined, FP, 64);
}
int main() {
char key[9]; // 8 characters + null terminator
uint64_t plaintext;
printf("Enter 8-character key: ");
scanf("%8s", key); // Read up to 8 characters
printf("Enter 16-digit hexadecimal plaintext: ");
scanf("%llx", &plaintext); // Read 64-bit hex
uint64_t roundKeys[16];
keySchedule(key, roundKeys);
printf("\nRound Keys (16 keys of 48 bits each):\n");
for (int i = 0; i < 16; i++) {
printf("Round %2d key: %012llX\n", i + 1, roundKeys[i] & 0xFFFFFFFFFFFFULL);
}
printf("\nPlaintext: %016llX\n", plaintext);
uint64_t ciphertext = desEncryptBlock(plaintext, roundKeys);
printf("Ciphertext: %016llX\n", ciphertext);
// Regenerate keys for decryption (optional, same key reused)
keySchedule(key, roundKeys);
uint64_t decrypted = desDecryptBlock(ciphertext, roundKeys);
printf("Decrypted: %016llX\n", decrypted);
return 0;
}
Inference:
DES is a symmetric key algorithm that encrypts 64-bit data blocks using a 56-bit key.
It uses initial/final permutations, 16 Feistel rounds with expansion, substitution (S-boxes),
and permutation.
Round keys are generated from the original key through shifting and compression.
Decryption mirrors encryption using keys in reverse.
Though once standard, DES is now considered insecure due to its short key length.
Result:
Thus the data was encrypted and decrypted using Data Encryption Standard Algorithm
(DES) in C and the output was verified.