CS255: Cryptography and Computer Security Winter 1998

Assignment #2

Due: Feb. 13, 1998.

Written Assignment

Problem 1 In this problem, we see why it is a really bad idea to choose p = 2^{k} + 1 for discrete-log based protocols: the discrete logarithm can be efficiently computed for such p.

A. Show how one can compute the least significant bit of the discrete log. That is, given y = g^{x} (with x unknown), show how to determine whether x is even or odd by computing y^{(p−1)/2}. [Hint: what does the lsb of x say about y?]

B. If x is even, show how to compute the 2nd least significant bit of x. [Hint: generalize

the computation in Part A.] C. By generalizing part B., show how to compute x.

Problem 2 Let’s explore why in the RSA public key system each person has to be assigned a different modulus N = pq. Suppose we try to use the same modulus N = pq for everyone. Each person is assigned a public exponent e_{i} and a private exponent d_{i} such that e_{i}d_{i} ≡ 1 mod φ(N). At first this appears to work fine: to encrypt a message to Bob, Alice computes C = M^{e_{Bob}} mod N and sends C to Bob. An eavesdropper Eve, not knowing d_{Bob}, seems to not be able to decrypt C. Let’s show that using e_{Eve}, d_{Eve} Eve can very easily decrypt.

A. Show that given e_{Eve}, d_{Eve} Eve can obtain an integer multiple of φ(N). B. Show that given an integer multiple of φ(N) one can easily factor N.

Hint: Let E = kφ(N) for some integer k. Write E = 2^{r}z where z is odd. Consider the values g^{E/2}, g^{E/4}, …, g^{E/2^{r}} mod N for some random g. Use the fact that g^{E} = 1 mod N and that 1 has four roots modulo N.

C. Deduce that Eve can decrypt any message encrypted using the modulus N.

Problem 3 Suppose one uses a modulus p and a generator g of ℤ_{p}^{∗} as parameters for the ElGamal public key system. Show that the system leaks one bit of information about the plaintext. Namely, given the public key and a ciphertext, an eavesdropper can learn the Legendre symbol of the plaintext.

Programming Assignment

In this assignment, your goal is to implement a secure network spellchecker. The spellchecker is composed of two parts — the client and the server. The basic idea is that the client will send words to the server which will spellcheck them and reply to the client with the result. Your goal is to enable the client and server to communicate over a secure line.

To help you get started and to free you from dealing with the networking code (for the most part) we are providing you skeleton client and server programs. The skeleton client and server perform the entire spellchecking function but they currently have no provisions for security. Your job is to modify them to add the security functionality.

You are strongly encouraged to work in pairs for this assignment. There will be no difference in the grading standard if you choose to work individually.

Getting Started

You will need an account on the Leland machines. If you do not have one, you can get one by

sending mail to action@leland.stanford.edu.

The directory /afs/ir/class/cs255/p1 on the Leland machines contains all the files you will need. They are:

1. spellc.c which implements the client spellc,

2. spelld.c which implements the server spelld,

3. spell.h a simple header file used by spellc and spelld, and

  4. Makefile

Copy these files to your directory and run make to create spellc and spelld. After you create spellc and spelld, you can test them in the following manner. First, start the server spelld without arguments like this:

   % spelld

spelld will display the UDP port on which it is waiting for requests and you will see something like this:

   % spelld
On port 12345

Now startup the client spellc like this:

   % spellc 12345@machine-name

where machine-name is the name of the computer on which you are running spelld (e.g.,

epic10.stanford.edu).

Now you can type words into stdin for spellc and mispelled words will be copied to stdout. Thus, if you execute a command like this

   % spellcheck 12345@epic10 < foo.txt > foo.msp

you will get a copy of all the mispelled words in foo.txt in foo.msp.

To quit either program use CTRL-C.

What You Need To Do

You will maintain the current interface for spellc and spelld, but you will add provisions for security.

Look at the implementations of spellc and spelld. Their main() functions set up the networking facility and then call two functions: init security() and process(). You need not and should not change any of the code in the main() functions, but you will have to change the

init security() and process() functions.

Currently, the function init security() is a dummy function. You need to change the implementation of this function in spellc so that it initiates key exchange with spelld. Similarly, you need to change the implementation of this function in spelld so that it performs key exchange once the key exchange is initiated by spelld. Your key exchange mechanism cannot assume the existence of a shared secret between the client and server. In addition, your key exchange mechanism need not include authentication and need not protect against active adversaries.

In implementing key exchange, you will most likely use public-key techniques. Some of these techniques require long-term security information to be generated (e.g., the RSA modulus) and this information can typically be reused between different runs of the spelld. To save yourself from generating this information each time you start the spelld, you can save this information in a file (with a hardcoded name). Thus, if the file exists, the spelld should simply read the security information from the file. Otherwise, the spelld should generate the information and store it in the file. Important Note: only the spelld is allowed to store long term security information in a file. The spellc should be self contained and not use any auxilary files. Most likely you will want to send any long term security information stored on the spelld to the spellc as part of the SERVER HELLO message.

In both spellc and spelld, the function process() is an infinite loop. In spellc, this loop reads a string (i.e., word) from stdin, sends it to spelld, waits for the reply, and outputs the string to stdout if it is mispelled according to spelld (i.e., the return code rc is nonzero). Similarly, in spelld, this loop waits for requests from the client, spellchecks them using the function spellcheck(), and replies to the client. You need to change the process() functions so that they use the keying material generated in init security() to encrypt the data that is exchanged between spellc and spelld. NOTE: As with key exchange, you need not worry about active adversaries. That is, you need not worry about ensuring the integrity of the message in transit.

How You Should Do It

There are three steps to making the source code changes you need to make.

The first step is to decide (at a high level) what cryptographic algorithms and what security protocols you will use. You have considerable freedom in this matter. The only restriction is that your algorithms/protocols must not require a third-party. For example, the use of an key distribution center (as in Kerberos) is not permitted.

Having decided what schemes you will use, the next step will be to fix the details of the protocols. You will also need to design the message formats and the protocol flows to support your schemes.

Finally, you will need to implement your schemes and your implementation is subject to certain constraints:

1. spellc and spelld were designed for use on the Leland epic and elaine machines. You should ensure that your submissions work on those machines as we will test submissions on those machines.

2. You must use ANSI C (not C++ and not Java) for coding.^{1}

3. You need to modify the process() and init security() functions, but you should not change any other code. Of course, you are free to add other, supporting functions. You should also not change the Makefile.

To help you with the implementation you will have access to the CryptoLib library which includes most commonly used cryptographic primitives. (For more information on Cryptolib, see the file

/afs/ir/class/cs255/cryptolib 1.2/cryptolib/man/cryptoman.ps.) Do not use other crypto

toolkits available on the Web.

In addition to coding, you will also need to submit a writeup. The writeup should consist of three parts corresponding to the three design phases described above. It should describe the algorithms and protocols that you used and provide a justification for your choices. In addition, it should provide a description the message formats and flows that you actually implemented. This description needs to be detailed enough to allow someone to independently implement spelld and have it work with your spellc (or vice versa). Note that your writeup must be in plain ascii text format.

Submission

Put your source code (spell.h, spellc.c, spelld.c) and your writeup (writeup.txt) in a directory called ∼/cs255 handin/p1. Make sure that this directory is readable by the course staff. If you are on AFS, give the group “cs255-admins” access using the following commands:

     % fs sa ∼ cs255-admins lr
     % fs sa ∼/cs255 handin cs255-admins all
     % fs sa ∼/cs255 handin/p1 cs255-admins all

When you have done this, send email to suvo@webclass.stanford.edu providing us with your (and your partner’s) names, leland logins, and Stanford ID numbers. (Only one partner needs to send email.)

A A Note on Networking

For the most part you need not worry about the networking portion of the spellchecker. However, you will necessarily have to deal with sending and receiving. The spellchecker is a client-server application that uses an unreliable datagram communications model (i.e., UDP) to communicate. This fact has two implications for you.

First, it means that the networking code makes no guarantees regarding delivery of data and data packets may be dropped in transit. You are unlikely to experience this problem on a LAN, but in any case, you can make this problem a non-issue by running spellc and spelld on the same machine.

Second, it means that spellc and spelld uses discrete messages called datagrams (as opposed to a stream) to exchange data. Normally, you would use the send(), receive(), sendto() and recvfrom() functions to exchange data. To save you from using these function directly we have provided two macros: sp send() and sp recv(). See the file spell.h for their definitions and for details concerning their use.

1It would nice to support other languages but the large enrollment and the small staff size precludes this.