CS 241 Data Organization using C
Lab 6: LCG and Cipher


March 19, 2018

1 Project Overview

In this assignment, you will create an implementation of a Linear Congruential Generator to that can be used to create a sequence of “random” numbers. You will then use your LCG as part of a cipher algorithm to encrypt and decrypt text.

This assignment will give you some practice using structs, pointers, and header files.

2 Linear Congruential Generator

I am giving you a header file lcg.h which defines a structure for an LCG and functions to manipulate it. You must implement these functions in lcg.c

2.1 LCG Initialization

Given the values

we can define a Linear Congruential Generator:

Xn+1 = (aXn  +c) modm

Where

If the values given result in an invalid LCG, set all the fields to zero to indicate an error.

2.2 Finding Unique Prime Factors

This function returns all the prime factors of a given number. One way of doing this is through trial division:

  1. Let n  be the number of which to find the prime factors.
  2. Start with 2 as a test divisor.
  3. If the test divisor squared is greater than the current n  , then the current n  is either 1 or prime. Save it if prime and return.
  4. If the remainder of n  divided by the test divisor is zero, then:
    1. The test divisor is a prime factor of n  . Save it.
    2. Replace n  with n  divided by the test divisor.
    3. Repeat 4b until test divisor is no longer a factor of n  .
  5. If, in step 4, the remainder of n  divided by the test divisor was not zero, then increment the test divisor.
  6. Loop to step 3.

3 Cipher Program

Write a C program, cipher.c, that:

  1. Reads characters from the standard input stream using the standard library function getchar().
  2. Determines whether each line encodes a valid cipher direction, key pair and data.
  3. For each valid line use the described cipher algorithm either encrypt or decrypt the data. Send the result to the standard output stream.
  4. If the line contains an error, then skip to the end of the line, print an error message, and read the next line.
  5. Output will be checked by an automated script and must adhere to a strict format.
  6. Your cipher.c should include lcg.h and use your LCG implementation to generate the pseudorandom numbers used in the cipher algorithm.

3.1 Cipher Data

The cipher algorithm used in this project:

3.2 Cipher Record Format

Each cipher record must be of the form:

Action lcg_m , lcg_c , Data \n
1 char 1-20 char1 char1-20 char1 charany number of char1 char

Action:
Must be either ‘e’ or ‘d’, specifying encryption or decryption respectively.
lcg_m:
Specifies a 64-bit positive integer used for m of a Linear Congruential Generator. Must be decimal digits.
lcg_c:
Specifies a 64-bit positive integer used for c of a Linear Congruential Generator. Must be decimal digits.
Data:
Printable ASCII character data to be encrypted or decrypted. Can be empty or arbitrarily long. Note: with the given algorithm there will be no need to keep the full line of data in memory.

3.3 Algorithm Summary

  1. Determine the Linear Congruential Generator specified by the given key. This is done only once per line of input.
  2. Read 1 byte of data b
  3. Generate random value x
  4. Compute encrypted byte as b XOR (x mod 128)
  5. Deal with any non-printable ASCII characters.
  6. Print the resulting character(s) to the standard output stream.
  7. Return to step 2 and continue until the end of the line

Note: (A XOR B) XOR B = A, so we are able to decrypt our message reapplying the same XOR operation. (When decrypting, you will deal with special characters first, then XOR to decrypt back to the original plaintext character.)

3.4 Initialization

Given a 128-bit symmetric key consisting of:

Define a Linear Congruential Generator as described in section 2.1.

3.5 Reading Data Bytes

3.6 Non-printable ASCII characters

This cipher algorithm can generate target bytes that are outside the range of printable ASCII.

3.7 Output Format

4 Testing your program

You will be given the following mechanisms to test the output of your program.
  • a makefile. This has two usages: compiling your cipher program and compiling the test program given to you. The output of this test program is lcgtestout.txt. You should test lcg.c and verify that your output is correct before moving on to write cipher.c.
  • a test file. Like others, running your code on cipherdata.in should generate the output cipherdata.out. You're *highly* encouraged to write a simple script to automate checking your output against the given output using diff.

    Grading Rubric (total of 60 points)

    -5 point
    : The programs do not start with a comment stating the students first and last name and/or the source files are not named correctly.
    -5 points
    : Programs compile with warnings on moons.cs.unm.edu using /usr/bin/gcc with the -Wall -ansi -pedantic options (and options for any standard libraries you may want to use such as -lm for math.h). If you do use a standard library that requires a linking option, please include this as a note when you submit in Learn.
    10 points
    : Output of running lcgtest matches lcgtestout.txt.
    30 Points:
    The given test file: cipherdata.in contains 30 tests. For each failed test, one point is lost. Every line reported by diff your.output cipherdata.out is a failed test.
    5 Points:
    Must decrypt novel.crypt, a file containing an encrypted novel in html format. Success is easily checked by opening the output in an html viewer. If it looks good to the eye at the start, somewhere in the middle and end, it passes.
    15 Points:
    Follows CS 241 Coding Standard. Points will be taken off for code that is less efficient than optimal, code that isn’t modular, missing comments, dead code, etc.