Mastering Algorithms With C - Kyle Loudon [183]
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
S-Box 7
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
S-Box 8
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
Once we have completed the S-box substitutions, the result is a 32-bit value that we permute using a P-box, as shown in Table 15.7. (This table is read like Table 15.1.)
Table 15.7. The P-Box Permutation for Data Blocks in DES
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
At this point, it is convenient to think of the operations in the round as a function, typically denoted as f. If bj is the j th six-bit block of Rint , Sj is the j th S-box, and P is the P-box permutation, this function is defined as:
f = P(S1(b1), S2(b2),. . ., S8(b8))
The last operation in each round is to compute the XOR of the 32-bit result of f and the original left block passed into the round, L i - 1. Once this is complete, we swap the left and right blocks and begin the next round. In the last round, however, we do not swap the left and right blocks. All together, the computations for Li and Ri in each round can be concisely expressed as follows:
When all 16 rounds have been completed, we concatenate the final right block, R 16, with the final left block, L 16, to produce the 64-bit block R 16 L 16. (Recall that the left and right blocks are not swapped in the final round; thus, we have the last right block on the left and the last left block on the right.) The final step is to permute R 16 L 16 as shown in Table 15.8. This permutation is aptly named the final permutation . It simply undoes what the initial permutation did earlier. When enciphering data, the result is a 64-bit block of ciphertext; when deciphering data, it is the original 64-bit block of plaintext.
Table 15.8. The Final Permutation for Data Blocks in DES
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
Interface for DES
Name
des_encipher
Synopsis
void des_encipher(const unsigned char *plaintext, unsigned char *ciphertext,
unsigned char *key);
Return Value
None.
Description
Uses DES to encipher one 64-bit block of plaintext specified by plaintext. Specify the 64-bit key in key. (Recall that every eighth bit of this key is ignored, resulting in a 56-bit key.) The 64-bit block of ciphertext is returned in ciphertext. It is the responsibility of the caller to manage the storage required in ciphertext. To encipher a large buffer of data, call des_encipher in accordance with a block cipher mode (see the example later in this chapter). For efficiency, des_encipher can reuse the subkeys computed during a previous call. To enable this, set key to NULL in subsequent calls.
Complexity
O (1)
Name
des_decipher
Synopsis
void des_decipher(const unsigned char *ciphertext, unsigned char *plaintext,
unsigned char *key);
Return Value
None.
Description
Uses DES to decipher one 64-bit block of ciphertext specified by ciphertext. It is assumed that ciphertext contains data previously enciphered with des_encipher. Specify the 64-bit key in key. (Recall that every eighth bit of this key is ignored, resulting