Author(s): Bruce Schneier

ISBN: 0471128457

Publication Date: 01/01/96

Previous | Table of Contents | Next |

Other Stream Ciphers and Real Random-Sequence Generators

RC4 is a variable-key-size stream cipher developed in 1987 by Ron Rivest for RSA Data Security, Inc. For seven years it was proprietary, and details of the algorithm were only available after signing a nondisclosure agreement.

In September, 1994 someone posted source code to the Cypherpunks mailing list—anonymously. It quickly spread to the Usenet newsgroup sci.crypt, and via the Internet to ftp sites around the world. Readers with legal copies of RC4 confirmed compatibility. RSA Data Security, Inc. tried to put the genie back into the bottle, claiming that it was still a trade secret even though it was public; it was too late. It has since been discussed and dissected on Usenet, distributed at conferences, and taught in cryptography courses.

RC4 is simple to describe. The algorithm works in OFB: The keystream is independent of the plaintext. It has a 8 * 8 S-box: *S*_{0}, *S*_{1},..., *S*_{255}. The entries are a permutation of the numbers 0 through 255, and the permutation is a function of the variable-length key. It has two counters, *i* and *j*, initialized to zero.

To generate a random byte, do the following:

*i*= (*i*+ 1) mod 256*j*= (*j*+*S*_{i}) mod 256- swap
*S*_{i}and*S*_{j} *t*= (*S*_{i}+*S*_{j}) mod 256*K*=*S*_{t}

The byte *K* is XORed with the plaintext to produce ciphertext or XORed with the ciphertext to produce plaintext. Encryption is fast—about 10 times faster than DES.

Initializing the S-box is also easy. First, fill it linearly: *S*_{0} = 0, *S*_{1} = 1,..., *S*_{255} = 255. Then fill another 256-byte array with the key, repeating the key as necessary to fill the entire array: *K*_{0}, *K*_{1},..., *K*_{255}. Set the index *j* to zero. Then:

- for
*i*= 0 to 255: *j*= (*j*+*S*_{i}+*K*_{i}) mod 256- swap
*S*_{i}and*S*_{j}

And that’s it. RSADSI claims that the algorithm is immune to differential and linear cryptanalysis, doesn’t seem to have any small cycles, and is highly nonlinear. (There are no public cryptanalytic results. RC4 can be in about 2^{1700} (256! × 256^{2}) possible states: an enormous number.) The S-box slowly evolves with use: *i* ensures that every element changes and *j* ensures that the elements change randomly. The algorithm is simple enough that most programmers can quickly code it from memory.

It should be possible to generalize this idea to larger S-boxes and word sizes. The previous version is 8-bit RC4. There’s no reason why you can’t define 16-bit RC4 with a 16 * 16 S-box (100K of memory) and a 16-bit word. You’d have to iterate the initial setup a lot more times—65,536 to keep with the stated design—but the resulting algorithm should be faster.

RC4 has special export status if its key length is 40 bits or under (see Section 13.8). This special export status has nothing to do with the secrecy of the algorithm, although RSA Data Security, Inc. has hinted for years that it does. The name is trademarked, so anyone who writes his own code has to call it something else. Various internal documents by RSA Data Security, Inc. have not yet been made public [1320,1337].

So, what’s the deal with RC4? It’s no longer a trade secret, so presumably anyone can use it. However, RSA Data Security, Inc. will almost certainly sue anyone who uses unlicensed RC4 in a commercial product. They probably won’t win, but they will certainly make it cheaper for a company to license than fight.

RC4 is in dozens of commercial cryptography products, including Lotus Notes, Apple Computer’s AOCE, and Oracle Secure SQL. It is part of the Cellular Digital Packet Data specification [37].

SEAL is a software-efficient stream cipher designed at IBM by Phil Rogaway and Don Coppersmith [1340]. The algorithm was optimized for 32-bit processors: To run well it needs eight 32-bit registers and a cache of a few kilobytes. Using a relatively slow operation, SEAL preprocesses the key operation into a set of tables. These tables are then used to speed up encryption and decryption.

*Pseudo-random Function Family*

One novel feature of SEAL is that is isn’t really a traditional stream cipher: it is a **pseudo-random function family**. Given a 160-bit key *k*, and a 32-bit *n*, SEAL stretches *n* into an *L-*bit string *k*(*n*). *L* can take any value less than 64 kilobytes. SEAL is supposed to enjoy the property that if *k* is selected at random, then *k(n*) should be computationally indistinguishable from a random *L-*bit function of *n*.

The practical effect of SEAL being a pseudo-random function family is that it is useful in applications where traditional stream ciphers are not. With most stream ciphers you generate a sequence of bits in one direction: Knowing the key and a position *i*, the only way to determine the *i*th bit generated is to generate all the bits up until the *i*th one. But a pseudo-random function family is different: You get easy access at any desired position in the key stream. This is very useful.

Imagine you need to secure a hard drive. You want to encrypt each and every 512-byte sector. With a pseudo-random function family like SEAL, you can encrypt the contents of sector *n* by XORing it with *k*(*n*). It is as though the entire disk is XORed with a long pseudo-random string, where any piece of that long string can be computed without any trouble.

A pseudo-random function family also simplifies the synchronization problem encountered with standard stream ciphers. Suppose you send encrypted messages over a channel that sometimes drops messages. With a pseudo-random function family, you can encrypt under *k* the *n*th message you transmit, *x*_{n}, as *n* together with the XOR of *x*_{n} and *k*(*n*). The receiver doesn’t need to store any state to recover *x*_{n}, nor does he need to worry about lost messages affecting the message decryption process.

*Description of SEAL*

The inner loop of SEAL is shown by Figure 17.1. Three key-derived tables, called *R, S*, and *T*, drive the algorithm. The preprocessing step maps the key *k*, to these tables using a procedure based on SHA (see Section 18.7). The 2-kilobyte table, *T*, is a 9 * 32 bit S-box.

Previous | Table of Contents | Next |