Assignment 1: Pseudo-Random Generator
Introduction

In this project, you will implement your own pseudo-random number generator (PRG) in Java. We will give you some of the code you need, and we will ask you to provide certain functions missing from the code we provide.

PRF.java: This is a fully implemented code file which we are giving you. You should use it as a building block for all of the crypto functionality you need to do this assignment. The file gives you access to a pseudo-random function, as described in lecture. This is the only crypto primitive you are allowed to use any other crypto you use must be built (by you) on top of this file. Specifically, you may not use any other crypto libraries, not even the ones that are part of the standard Java libraries.

Your task is to implement two cryptographic algorithms, by modifying two Java code files as described below.

PRGen.java is a partially implemented file for a pseudo-random generator class. Some parts are stubbed out. You will replace the stubbed out pieces with code that actually works and provides the required security guarantee. We have put a comment indicating IMPLEMENT THIS everywhere that you have to supply code.

StreamCipher.java is a partially implemented file for a stream cipher. Some parts are stubbed out. You will replace the stubbed out pieces with code that actually works and provides the required security guarantee. We have put a comment indicating IMPLEMENT THIS everywhere that you have to supply code.

Objectives of this assignment
PRGen.java

Your PRGen class should implement the following API:

public class PRGen extends Random {
   public PRGen(byte[] key)     // creates a new PRGen
   protected int next(int bits) // generates the next pseudorandom number      

Your PRGen class will extend the java.util.Random class, but you should only implement the constructor and "next" method specified above. Your "next" method should follow the same behavior as the java.util.Random.next method. The Java documentation says, "The general contract of next is that it returns an int value and if the argument bits is between 1 and 32 (inclusive), then that many low-order bits of the returned value will be (approximately) independently chosen bit values, each of which is (approximately) equally likely to be 0 or 1." For example, if you call next(4), it will return a pseudo-random int between 0 and 15 (the range of 4-bit unsigned number). If you call next(31), it will return a pseudo-random int between 0 and 2,147,483,647 (the range of an unsigned 31-bit number). If you call next(32), it will return a pseudo-random int between -2,147,483,648 and 2,147,483,647 (the range of a signed 32-bit number).

Your PRGen class must also obey the following three properties:

StreamCipher.java

Your StreamCipher class should implement the following API:

public class StreamCipher {
   public StreamCipher(byte[] key, byte[] nonceArr, int nonceOffset)   // constructor 
   public StreamCipher(byte[] key, byte[] nonce)                       // constructor 
   public byte cryptByte(byte in)                                      // encrypts the next byte
   public void cryptBytes(byte[] inBuf, int inOffset,                  // encrypts next numBytes
                          byte[] outBuf, int outOffset,                // in the inBuf, writing
                          int numBytes)                                // results to the outBuf
}      

This class encrypts or decrypts a stream of bytes, using a stream cipher. (Recall that for a stream cipher, encryption and decryption are the same operation.)

Getting Started
Submission Checklist

Submit your files to Gradescope: