Programming Assignment #1

GCD (Greatest Common Divisor) with Big Integers

1. Introduction

Cryptography is a key element in preserving confidentiality; it is used to scramble data such that it
cannot be easily read by anyone except the intended receiver.

There are many protocols that use cryptography, SSH and SSL are just the two best known. PGP is a popular
application that uses publick-key cryptography.

These protocols and the algorithms they use are largely based on the power of having large keys that
are used to perform forward calculations in a reasonable amount of time, but difficult to calculate the
inverse (read very time consuming).

One way of doing this is by using prime numbers. It is very easy to multiply two very large numbers,
say 1000 digits each, and get the 2000 digit result; multiplying two n-digit numbers requires O(n2)
operations. But it is extremely difficult to factor a large integer.

For very large number there is no known efficient integer factorization algorithm. An effort that took
almost 2000 2.2GHz-Opteron-CPU years -- according to the submitters -- just short of 3 years of calendar time,
has lead to the factorization of a 232-digit number (RSA-768).

Not all numbers of a given length are equally hard to factor. The hardest instances of these problems
are those where the factors are two randomly-chosen prime numbers of about the same size.

The supposed difficulty of factoring large numbers is at the heart of RSA.

In this programming assignment, you will implement one of the key building blocks required to implement
the RSA algorithm. GCD will come in handy when you try to determine if two numbers are relatively prime.

2. Details

Since you will have to compute large exponents as part of the RSA algorithm, the standard integer types
(int - 16 or 32 bits, long int - 32 bits and and even long long int - 64 bits) of most computer
languages will not suffice.

Here are your choices:

Java has a built-in bigint class that behaves exactly like an int, except that it is not bound by a
finite value

C++ you'll have to use a library such as NTL (Library for doing Number Theory)
or GMP (the GNU Multiple Precision Arithmetic Library)

In Ruby you don't have to worry about the size of numbers at all, Ruby automatically takes care of any conversion
between numbers of fixed size (Fixnum - 16, 32, 64 bits) and Bignum (numbers with an arbitrary number of digits)

3. What You Have to Do

The assignment is broken down into four main parts. Each part will be graded separately, but each
part will also be reused for other parts of the assignment. This will allow you to test each part
conclusively before moving on.

3.1 GCD Algorithm (30%)

Develop your own algorithm or find an existing one for finding the GCD of two arbitrarily large integers.
If you're using somebody else's algorithm, then don't forget to include your sources in the memo.

Please write your algorithm in the space provided below (edit this html file and drop your name and the
algorithm in the appropriate table rows):

Student name:

Type your content in this table row.

3.2 GCD Implementation (30%)

Now, implement your algorithm using your choice of language. Make sure that your program allows
the use of arbitrarily large integers.

You may NOT use the gcd() library function, regardless of the language you're using for your
implementation and the particular name of the function in the library. Instead, you have to develop your own function(s)
for finding the GCD of two arbitrarily large integers.

Your program will be named gcd and runs from the command line. It takes two arguments, two integer numbers
of arbitrary size, and prints out their GCD.

Example (the $ sign is the command line prompt):

$ gcd 4323874085395 586898689868986900219865
$ 85

In the table below you'll find some test cases for testing your GCD function. Fill in the empty locations using your
program. For those cases where you have to select your own numbers, make sure you select numbers that are at least
20 digits long.

First number

Second number

GCD

2345

72

1

1406700

164115

23445

1368

339

3

55534

434334

2

243532

0

243532

30315475

24440870

31415

37279462087332

366983722766

564958

3823485236523624

43882834845621

233961810342958422635

3927915395316175446

34823484334858234892934

438923489238932492

Student name:

3.3 Time Complexity (20%)

Measure the time complexity of your algorithm and include it in your memo. You'll be required to attach
the experimental evidence to your submission.

3.4 Required Document (10%)

In addition to your source code and your output you are required to submit a memo to your instructor
that is flawlessly written. No spelling errors. No grammatical errors, etc. If the document is deemed
unprofessional, e.g. with grammatical or spelling errors, then it will be assigned a grade
of zero.

If you're not sure about the format for a memo, then just search for "memo format" on Google.

Your memo should state clearly the status of the assignment. Is it done or not? Does it meet all
of the requirements? If anything is missing then state clearly what is missing from your work.

Failure to give a status for the assignment will result in a grade of zero for the entire assignment.
Providing a status that's false or significantly misleading will also result in a zero for the entire assignment.

The other things that you should include in the memo are: (i) the number of hours you needed to get
the code working, (ii) the number of hours you spent preparing your submission, and (iii) a list of challenges
you faced while working on this assignment. Not required, however very nice to have, is a list of recommendations
for how to make the assignment better, to the possible benefit of future generations.

Make sure your document is well-written, succinct, and easy to read. If you encountered problems with
the assignment, then provide a detailed description of those problems and the solution(s) you found.