As promised, now we're going to look at the first major block
cipher: the DES. DES stands for "data encryption standard"; DES was the first encryption system standardized by the US government for official use. It's an excellent example of a strong encryption system; to this day, while there are several theoretical attacks, there's no feasible attack on a single DES-encrypted message that's better than brute force. The main problem with DES is the shortness of its key: only 56 bits, which makes it downright practical to implement brute-force attacks against it using today's hardware.
DES works with 64 bit blocks, and a 56 bit key. As an interesting aside, there are some serious questions about just why the standard key was 56 bits. Officially, the key length is 64 bits, but during the standardization process, the key was modified at the request of the NSA so that 8 of the bits were used as parity checks - that is, as extra bits that could be used for checking the validity of a key. 8 bits for parity checking on a 56 bit key is really overkill - in fact, putting parity checks into the key at all is really rather questionable. There's been a lot of speculation that either
the NSA knew some kind of trick that could be used against a 56 bit key, or that 56 bits put the encryption within the range of what they could crack using a brute force attack. But no one has ever admitted to either solution, and as far as I know, no one knows of any way that a 56 bit key could have been feasibly cracked using brute force with the technology of the time.
Anyway - getting past the politics of it, it's still a really interesting
system. It's a rather elegant combination of simplicity and complexity. It's got a simple repetitive structure based on lookup tables, which gives it its deceptive simplicity; but those lookup tables are actually an implementation of a very complex non-linear discrete mathematical system.
The basic structure is a three-step process: permute the input data,
run it through a sequence of 16 passes using a ladder-like data flow structure,
and then reverse the initial permutation.
The permutation is an interesting step: it doesn't really add
anything to the encryption as such. What it does is add a step to the computation: since there's no known attack short of brute force,
it serves to increase the time it takes to perform a brute-force attack. To crack a message, you need to do the encryption and/or decryption process, and that means doing the permutations - which take time. All that the permutations at
the start and finish of the process do is add computation time, so that cracking
the encryption by brute force requires more work.
The interesting thing is what comes after the permutation. You split the
input block into two 32-bit sub-blocks, which each contain half of the permuted
block. Then you pass the subblocks through an encryption ladder called a Feistel structure, where at each step, one of the two blocks is put through
something called a Feistel block. The output from the Feistel structure is then exclusive-or'ed with the result of the previous step. This is illustrated by the diagram to the right.
The Feistel-box folds the encryption key into the process. What happens
in each F-box is illustrated in the diagram to the right. You get a 32 bit
half-block, and a 48-bit subkey. (I'll explain about getting the subkeys in
a moment.) The Feistel-box does four things:
- Expand the input half-block from 32 to 48 bits by reshuffling and copying some bits. If you number the bits from 0 to 31, the expanded 48-bit block
consists of the numbered bits: [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16,
15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 22, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0]. So you start with a copy of bit 31, and then do the bits roughly in order, duplicating the pairs (3,4), (7,8), (11,12), (19,20), (22,23),
(27,28), and ending with bit 0.
- Exclusive-or the expanded half-block with the subkey;
- Break the resulting 48 bits into 8 six-bit micro-blocks.
- Run each six-bit micro-block through a substitution box (or S-box), generating a 4 bit result.
The result of the S-boxes are concatenated together, resulting in a
32 bit result, which is then put through a permutation, giving the final
output of the F-box.
You can think of the expansion, X-or, and S-box complex as a sort of substitution cipher; and the final permutation is, obviously, a permutation cipher. So the full process of DES can be thought of a rather complicated series of permutations and substitutions. One of the key roles of the encryption key is that it effectively selects where the copied bits are really going to be passed through into the output of the S-boxes: since each S-box takes 6 bits, but loses two of them, it's really doing a four-bit substitution. But which four bits? That's really controlled by the subkey.
The purpose of the whole Feistel function rigamarole - the splitting of
the block, the shuffling through the ladder of F-boxes, the expansion, contraction, and permutation of the half-block as it moves through the F-box, was
described in terms of information theory by Claude Shannon rather elegantly,
as part of a general description of how encryption worked in terms of information theory: "confusion and diffusion". That's exactly what's going on: shuffle things around, diffuse the bits of the plaintext message all over the place,
so that without knowing how the key guided it, the end-result is a very complex string of information, which mixes the plaintext, the encryption key, and various information about the particulars of the S-boxes in a thoroughly confused and diffused way. That's a big part of what makes this a good encryption system: there's a lot of information being added to the string, and without the key, you don't know how the separate the information you want from the information you don't.
And where do the subkeys come from? It's a process vaguely similar to the
ladder process connecting the F-boxes. You start with the 56 bit key, which you
permute, and then split in half. Then you push the two halves through a
left-bitshift and a permutation, generating the first subkey. Then you shift and
permute again, getting the second subkey. And again, getting the third. And so on.
The basic process is illustrated in the figure.
Alas, all of this is rather vague, because I haven't described the specific permutation functions, or the S-box functions. But they're actually pretty boring:
just lots of complicated tables. If you really want to see them, there's a decent list of the tables on the Wikipedia page on DES supplementary material.
And all this is just the one-block encryption! We haven't even gotten into how the various modes of operation enter the picture. That's the next post.