CSE 207B, Fall 2023
Homework 2: The C rand() stream cipher

The GNU C Library's implementation of the C rand() function uses a linear congruential generator if the state is initialized with sufficiently small parameters. (It is no longer the default.) You can find the relevant code here.

The LaTeX source for your next homework assignment has been encrypted using C rand() as a stream cipher. The encrypted file is available here. Your task is to recover the plaintext so you can do the rest of the problems.

You may use Python or C to solve this challenge. Gradescope will expect either a file named hw2-sol.py or hw2-sol.c. Your code should accept a filename that contains the ciphertext as a command-line argument and write the decrypted tex code to a file named hw2.tex for the autograder to recognize it.

Please submit your code and a short description of how you solved the problem along with a PDF of your LaTeXed solutions to the other problems named hw2-solutions.pdf to Gradescope before class on October 11. You may discuss this assignment in small groups with classmates, but please code and write up your solutions yourself. Please credit any collaborators you discussed with and any references you used.

For reference, the homework was generated using the following C program running on a little-endian Arch Linux system. If you try to run it on a Mac, you will discover that the BSD C library implements rand using a different function, which remains equally insecure for our purposes.

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

//Return a byte at a time of the rand() keystream
char randchar() {
  static int key;
  static int i = 0;
  i = i % 4;
  if (i == 0) key = rand();
  return ((char *)(&key))[i++];
}

int main(int argc, const char* argv[]) {
  static char randstate[64];
  initstate(time(NULL),randstate,31);

  FILE *input, *output;
  input = fopen("hw2.tex", "r");
  output = fopen("hw2.tex.enc", "w");

  int c;
  while ((c = fgetc(input)) != EOF)
    fputc(c^randchar(),output);

  fclose(input);
  fclose(output);
}