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 cryptographic 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 cryptographic primitive you are allowed to use; any other cryptographic code you use must be built (by you) on top of this file. Specifically, you may not use any other cryptographic 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.
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:
.next
method in java.util.Random
is not forward-secure.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.)
PRF.java
class to deterministically generate pseudo-random values. See the comments in PRF.java
for examples.Submit your files to Gradescope:
PRGen.java
- Source code file containing your implementation of the PRGen
class.StreamCipher.java
- Source code file containing your implementation of the StreamCipher
class.