Decryption of a file encrypted by pseudo-random number generator (The Linear Congruence rand() How to decrypt this file:

https://drive.google.com/open?id=1gZCujDYmEL-FZ5o_xBUS-Ng5979HSsZ7

Given that the only information available about it are:


It has been created ‎on 21/3/‎2018, ‏‎9:05:15 AM
The plaintext of the file is probably starting with "\documentclass[12pt]{article}", and it's a latex file
The code used for encryption is in C, and used a pseudo-random number generator (The Linear Congruence rand()):



/* The ISO/IEC 9899:1990 edition of the C standard */
#define RAND_MAX 32767
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}
void srand(unsigned int seed)
{
    next = seed;
}

#include &lt;stdio.h&gt;
#include &lt;time.h&gt;

//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 *)(&amp;key))[i++];
}

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

  srand(time(NULL)); 
  FILE *input, *output;
  input = fopen("Homework1b.tex", "r");
  output = fopen("Homework1b.tex.enc", "w");

  int c,rc;
  while ((c = fgetc(input)) != EOF) {
    rc=randchar();
    printf("c=%d (%c) and rc=%d\n",c,c,rc);
    fputc(c^rc,output);
  }
  fclose(input);
  fclose(output);
}



I read about the weakness of C random and I know that knowing a part of the plaintext should help, but couldn't figure it out.
Short answer: Just replace the srand(time(NULL)); with srand(&lt;epoch
  seconds when encrypted&gt;); and then "encrypt" the encrypted file again
  to decrypt.


Long answer: The unserlying priciple of this programm is a stream cipher, as you already mentioned in your tags, which means the plaintext $P$ is xored with a random keystream $K$. To undo this operation, you simply need to xor the ciphertext $C$ with the same keystream again, which is proven by $C \oplus K = (P \oplus K) \oplus K = P \oplus 0 = P$.

So to reconstruct the plaintext, we need to reconstruct the keystreams to which can be achieved in two ways:


Using the time of encrytion: As you can see in the second line of the main method, the seed of the rand-function is set to the current time in secconds. Since all the following outputs of the rand-function depend on that seed only, one can reconstruct the keystream by setting the seed to the seconds since the unix epoch.
Using a known plaintext:
Let's take a look at how the keystream is generated: $K_{i+1}=(1103515245 \cdot K_i + 12345)\ /\ 65536\ (mod\ 32768)$ This may look complicated at first, but there is one simple property which can easily be exploited: The next state only relies on the previous state. This allows us to compute all the following states using only one state. To get this, we simply xor the ciphertext with the plaintext since $K_0 = C_0 \oplus P_0$ and use it as seed for $K_1$. You can then go on and use the rand-function to get the keystream.


Finally, you need to know the endianness of the encrypting source, so that your decrypting program can match and correctly decrypt.