CS419:Computer Security Assignment10 (Project 3)
This assignment contains three parts:
- In part 1, you will implement a binary version of the Vigenère polyaplhabetic substitution cipher.
- In part 2, you will implement a stream cipher that uses a linear congruential keystream generator and a hashed key as a seed.
- In part 3, you will modify the cipher in part 2 to operate as a block cipher that will shuffle pairs of bytes within each block based on the keystream and will apply cipher block chaining(CBC) between blocks.
This is an individual project. All work should be your own except for the referenced code for the hash function.
You may use Go, Python, Java, C, or C++ in your implementation.
You should be able to implement this on any platform but you are responsible to make sure that the program runs on Rutgers iLab systems with no extra software.
Part 1: Binary Vigenère Cipher
We covered the Vigenère cipher in class. It was designed for manual cryptography (pencil and paper) and used a repeating key on a grid.
Each row contains the alphabet rotated one additional position to the left from the previous alphabet.
To encrypt, you:
- Find the row indexed by the plaintext letter.
- Find the column indexed by the next character of the key.
- The ciphertext letter is the intersection. The key is repeated to make it the same length as the message.
Your program will create a binary version of this cipher. The key can be either text or, preferably, binary data and is stored in a key file.
The usage of the command is:
vencrypt keyfile plaintext ciphertext
This encrypts the plaintext file using the key in keyfile and produces the file ciphertext. Here’s what you need to do:
- Create a 256x256 grid. a. Row 0 contains 00 .. 0xff b. Row 1 contains 01 .. 0xff , 00 c. Row 2 contains 02 .. 0xff , 00 , 01 d. Row 255 contains 0xff , 00 .. 0xfe
- To encrypt a byte n of plaintext, look up its value in the table: ciphertext = table [row=plaintext ] [column=ciphertext ] If you think about the operations that take place, you will discover that you don’t even need a table since you can easily derive the value of the ciphertext from the key byte and plaintext byte. Then, create a decryption function: vdecrypt keyfile ciphertext plaintext n n n mod length(ciphertext)
If you think about the operations that take place, you will discover that you don’t even need a table since you can easily derive the value of the ciphertext from the key byte and plaintext byte.
Then, create a decryption function:
vdecrypt keyfile ciphertext plaintext
This reads the key from keyfile and decrypts the contents in cipherfile into the file message.
Hints & testing
If you find this program getting long, you might be approaching it incorrectly. If you think about the problem, you will realize that you don’t need a table. The entire encryption can be one while loop with one line of code within it! You can implement a table if you’d like but it’s not necessary.
Test your programs thoroughly. Come up with different test cases and validate them.
With this cipher, a key with bytes of 0 will always produce plaintext. A key with bytes of 1 will produce shifted data. For example, the string ABC will produce the ciphertext BCD .
Printing input & output of data (as hex #s, for example) can help you see what’s going on in your program.
The Linux (and macOS) od command dumps binary data and may be useful for inspecting your output. The command
od –t xC keyfile
shows the contents of keyfile as a series of hexadecimal bytes.
Part 2: Stream cipher
We also covered stream ciphers in class. This type of cipher simulates the one-time pad by using a keystream generator to create a keystream that is the same length as the message.
The keystream generator is a pseudorandom number generator and the seed will be derived from the password. You will always see the same sequence of numbers for the same seed.
To implement this cipher, you will:
(a) Implement a linear congruential generator
This is a trivial formula that is described here. This is one of the best-known and widely-used pseudorandom number generators. Each pseudorandom number is function of the previous one and defined as:
X = aX + c mod m
where: X is the next pseudorandom # in the sequence X is the number before that in the sequence m is a modulus. We will be working only on bytes in this assignment, so you will use 256 for the modulus.
The values a and c are magic parameters. Certain values were found to produce better sequences of data. You will use the same parameters that are used in ANSI C, C99, and many other places:
Modulus, m = 256 (1 byte) Multiplier, a = 1103515245 Increment, c = 12345
Implementing this generator is only three lines of code!
By using a well-known formula, your output should be the same regardless of the programming language or operating system you use.
(b) Convert the password to a seed
The seed for a pseudorandom number generator is just a number. For this program, instead of asking users to use a number as a key, you will let them use a textual password. You will then apply a hash function to this password to create a seed for the keystream generator.
To create the seed, we will use a hash function that works well and is easy to implement. This is the sbdm hash that is used in gawk, the sbdm database, Berkeley DB, and many other places
You should be able to translate it to whatever language you’re programming in pretty easily. This implementation is also three lines of code! As with the previous step, this implementation should ensure that your output will be the same regardless of the programmer,
programming language, or operating system
(c) Apply the stream cipher
Part 3: Block encryption with cipher block chaining and padding
Cipher block chaining