Encryption/Decryption Using Stream Ciphers
This document is in MS-Word 97 Format.  You can get it by clicking here.
 

Data encryption ciphers are grouped into two categories:
 

1. stream ciphers
A stream cipher is a single-character-in, single-character-out cipher. That is, it does the encryption one character at a time.
2. block ciphers:
A block cipher encrypts whole blocks of data at a time.
We will focus on the stream cipher since stream ciphers are more suitable for hardware implementation and real-time systems where bits of data are received serially.
 
 
 
Stream Ciphers

Stream ciphers convert plaintext to ciphertext one bit at a time. An example of a stream cipher implementation is the XOR algorithm. Refer to Figure 3.1. In this implementation, the keystream generator outputs a stream of bits: k1, k2, k3, . . ., ki. Then this keystream is XORed with a stream of plaintext bits (p1, p2, p3, . . ., pi) to produce the stream of ciphertext bits. This operation is described by the formula: ci = pi xor ki

To recover the plaintext bits at the decryption end, the ciphertext bits are XORed with an identical keystream. This operation is described by: pi = ci xor ki.
 


 

VHDL source code for an XOR stream cipher:

stream_cipher_pkg.vhd -- package containing all of the stream cipher components

stream_cipher.vhd -- top-level stream cipher entity

reg2_1.vhd -- register required to synchronize data latching for the stream cipher
 
 
 

Shift Registers

As shown in the diagram above, a keystream generator is required.  There are many possibilities for implementing a keystream generator.
The one discussed here is a keystream generator based on linear feedback shift registers (LFSRs).

The linear feedback shift register is made up of two parts: a shift register and a feedback function. The shift register is initialized with n bits (called the key), and each time a keystream bit is required, all of the bits in the register are shifted 1 bit to the right. So the least significant bit is the output bit. The new left-most bit is computed as the XOR of certain bits in the register. This arrangement can potentially produce a 2n-1 bit-long pseudo-random sequence (referred to as the period) before repeating. To make this maximal-period LFSR, the polynomial formed from the tap sequence (bits that are XORed together) plus the constant 1 must be a primitive polynomial (irreducible polynomial that divides x2^(n-1)+1, but not xd+1 for any d that divides 2n-1) mod 2. The degree of the polynomial is the length of the shift register.

The example implementation shown below uses an 8-bit register with the primitive modulo 2 polynomial x8+x4+x3+x2+1. Therefore, the tap sequence consists of bit 8, bit 4, bit 3, and bit 2. By XORing these bits together, the resultant LFSR will be maximal length, so it will cycle through 28-1 values before repeating. Refer to Figure 3.2 below. Two other shift registers of length 11 bits and 13 bits are used as well. The primitive polynomials modulo 2 are x11+x2+1 and x13+x4+x3+x1+1, respectively.
 


 

VHDL source code for the three LFSRs:

shift_reg8.vhd

shift_reg11.vhd

shift_reg13.vhd
 
 
 

Keystream generator

By combining LFSRs of different lengths (i.e. different feedback polynomials), a keystream generator is made. To create a maximal length generator, the lengths of the constituent LFSRs must be relatively prime, and all of the feedback polynomials must be primitive modulo 2. Each time a keystream bit is required, the LFSRs are shifted once and an output bit is produced as a function of the output bits of each LFSR.

The keystream generator shown below is the Geffe Generator. This keystream generator uses three LFSRs combined in a nonlinear manner. Refer to Figure 3.3. Two of the LFSRs are inputs into a multiplexer, and the third LFSR controls the output of the multiplexer. Suppose a1, a2, and a3 are the outputs of the three LFSRs, then the output of the Geffe generator is the following:

b = (a1 ^ a2) xor ((~a1) ^ a3)

where ^ represents "AND"

     ~ represents "NOT"
 
 

The period of this combination keystream generator is the least common multiple of the periods of the three generators:

n = n1 * n2 * n3

= 13 * 11 * 8

= 1144
 
 
 

VHDL source code for a 2-1 multiplexer and the Geffe keystream generator:

mux2_1.vhd

key_generator.vhd
 
 
 
 

Serial-to-Parallel Converter

The stream cipher produces a serial output. If the output required is parallel, a serial-to-parallel converter must be used. The converter described below takes in 8 valid bits serially for 8 clock cycles, then outputs all 8 bits in parallel during the 9th clock cycle. A valid_out signal is used to indicate when the output is valid.

VHDL source code for a serial-to-parallel converter:

s_to_p_data_conv.vhd
 
 
 
 

Serial-to-Parallel Stream Cipher

The serial-to-parallel converter is incorporated with the stream cipher by connecting the output of the stream cipher to the input of the converter.

VHDL source code for the complete stream cipher:

p_out_stream_cipher_pkg.vhd -- package containing components of parallel output stream cipher

p_out_stream_cipher.vhd -- parallel output stream cipher top-level entity
 
 
 
 

References

Bruce Schneier, Applied Cryptography, 2nd edition, John Wiley & Sons, Inc., 1996

http://www.tccsecure.com/voicetx.htm