Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

1. Vernam Encryption Write a program in C that will encrypt a file use XOR and a

ID: 3760282 • Letter: 1

Question

1. Vernam Encryption Write a program in C that will encrypt a file use XOR and a Vernam key. A Vernam key is a short string. (The real system used a much longer random sequence.) Read the input at low level, as binary data (hint unsigned char is useful here.) Then xor each character in the binary data with the character in the key. When you get to the end of the key reuse the key from the beginning. The program should take command line arguments for the key, input and output. ./vern abc input.clear output.encrypted Note that the cipher should decrypt its own output. The command: ./vern abc output.encrypted input.clear should recover the original input. If you use open to create the output file, you may want to also set O RDWR or O WRONLY as well as O CREAT. You could also use fread and fwrite for this problem.

2. Finding the period This cipher is vulnerable if the key repeats, and with a short key, like abc above, it will repeat many times for any reasonably sized input. The incidence of coincidence slides the cipher along itself and counts the number of times the same symbol is seen.

ABCABCABC ABCABCABC then shift 1 ABCABCABC ABCABCABC then shift 2 ABCABCABC ABCABCABC then shift 3 count is 9 count is 0 count is 0 ABCABCABC count is 6 ABCABCABC Clearly the period is 3.

Write the code to do that. The file classcipher.vrn is in my directory for this.

3. EXTRA CREDIT The character ’ ’ (space) is most common in English text. After finding the period count the most common character for each period and recover the key by XOR’ing it with ’ ’.

Explanation / Answer

1.

// First, the bytes of the input file are read:

byte[] originalBytes;

using (FileStream fs = new FileStream(originalFile, FileMode.Open))

{

    originalBytes = new byte[fs.Length];

    fs.Read(originalBytes, 0, originalBytes.Length);

}

byte[] keyBytes = new byte[originalBytes.Length];

Random random = new Random();

random.NextBytes(keyBytes);

// Write the key to the file:

using (FileStream fs = new FileStream(keyFile, FileMode.Create))

{

    fs.Write(keyBytes, 0, keyBytes.Length);

}

// The encryption - for decryption the same algorithm is used - is straightforward, by using XOR.

private void DoVernam(byte[] inBytes, byte[] keyBytes, ref byte[] outBytes)

{

    // Check arguments:

    if ((inBytes.Length != keyBytes.Length) ||

        (keyBytes.Length != outBytes.Length))

        throw new ArgumentException("Byte-array are not of same length");

    // Encrypt/decrypt by XOR:

    for (int i = 0; i < inBytes.Length; i++)

        outBytes[i] = (byte)(inBytes[i] ^ keyBytes[i]);

}

using gfoidl.Security;

// Create an instance of the class:

Vernam vernam = new Vernam();

// Test with an image:

vernam.EncryptFile("Image.gif", "Image_encrypted.gif", "Key01.dat");

vernam.DecryptFile("Image_encrypted.gif", "Key01.dat", "Image_decrypted.gif");

// Test with text file:

vernam.EncryptFile("Text.txt", "Text_encrypted.txt", "Key02.dat");

vernam.DecryptFile("Text_encrypted.txt", "Key02.dat", Text_decrypted.txt");

// Test with pdf file:

vernam.EncryptFile("Text.pdf", "Text_encrypted.pdf", "Key03.dat");

vernam.DecryptFile("Text_encrypted.pdf", "Key03.dat", "Text_decrypted.pdf");

2.

One of the most significant developments was the "polyalphabetic substitution cipher", which was described in its definitive form in a paper published in 1586 by a French diplomat named Blaise de Vigenere. A "Vigenere cipher" uses 26 substitution ciphers, organized using a "Vigenere square" as shown below, with some spacing added here to make it legible:

        a bcd efgh ijk lmno pqr stuv wyxz

   01: A BCD EFGH IJK LMNO PQR STUV WXYZ

   02: B CDE FGHI JKL MNOP QRS TUVW XYZA

   03: C DEF GHIJ KLM NOPQ RST UVWX YZAB

   04: D EFG HIJK LMN OPQR STU VWXY ZABC

   05: E FGH IJKL MNO PQRS TUV WXYZ ABCD

   06: F GHI JKLM NOP QRST UVW XYZA BCDE

   07: G HIJ KLMN OPQ RSTU VWX YZAB CDEF

   08: H IJK LMNO PQR STUV WXY ZABC DEFG

   09: I JKL MNOP QRS TUVW XYZ ABCD EFGH

   10: J KLM NOPQ RST UVWX YZA BCDE FGHI

   11: K LMN OPQR STU VWXY ZAB CDEF GHIJ

   12: L MNO PQRS TUV WXYZ ABC DEFG HIJK

   13: M NOP QRST UVW XYZA BCD EFGH IJKL

   14: N OPQ RSTU VWX YZAB CDE FGHI JKLM

   15: O PQR STUV WXY ZABC DEF GHIJ KLMN

   16: P QRS TUVW XYZ ABCD EFG HIJK LMNO

   17: Q RST UVWX YZA BCDE FGH IJKL MNOP

   18: R STU VWXY ZAB CDEF GHI JKLM NOPQ

   19: S TUV WXYZ ABC DEFG HIJ KLMN OPQR

   20: T UVW XYZA BCD EFGH IJK LMNO PQRS

   21: U VWX YZAB CDE FGHI JKL MNOP QRST

   22: V WXY ZABC DEF GHIJ KLM NOPQ RSTU

   23: W XYZ ABCD EFG HIJK LMN OPQR STUV

   24: X YZA BCDE FGH IJKL MNO PQRS TUVW

   25: Y ZAB CDEF GHI JKLM NOP QRST UVWX

   26: Z ABC DEFG HIJ KLMN OPQ RSTU VWXY

        a bcd efgh ijk lmno pqr stuv wyxz

This defines 26 different Caesar shift ciphers, each of which is weak in itself but which in combination result in a much more secure cipher. The idea in the Vigenere cipher is to use a cipher key to select different cipher alphabets in succession as letters are enciphered. Suppose Alice wants to encipher the phrase:

use the force luke-- with a Vigenere cipher, using the cipher keyword "WARTHOG". All she has to do is scan down the square defined above and match the cipher alphabet letter to a particular row, then select the cipher character matching the plaintext letter for that row:

   W: cipher alphabet 23 gives u -> Q

   A: cipher alphabet 01 gives s -> S

   R: cipher alphabet 18 gives e -> V

   T: cipher alphabet 20 gives t -> M

   H: cipher alphabet 08 gives h -> O

   O: cipher alphabet 15 gives e -> S

   G: cipher alphabet 07 gives f -> L

   W: cipher alphabet 23 gives o -> K

   A: cipher alphabet 01 gives r -> R

   R: cipher alphabet 18 gives c -> T

   T: cipher alphabet 20 gives e -> X

   H: cipher alphabet 08 gives l -> S

   O: cipher alphabet 15 gives u -> I

   G: cipher alphabet 07 gives k -> Q

   W: cipher alphabet 23 gives e -> A

This gives:

   QSV MOS LKRTX SIQA