by Neal R. Wagner
Copyright © 2001 by Neal R. Wagner. All rights reserved.
NOTE: This site is obsolete. See book draft (in PDF):
The history of RSA is still fascinating to me because I watched it unfold. In 1976, as discussed in the previous section, Diffie and Hellman introduced the idea of a public key cryptosystem. (Actually, the concept had been discovered earlier in classified work by British and American military researchers, but no one knew this at the time.) Then a 1977 Scientific American article by Martin Gardener talked about a new public key implementation by MIT researchers Rivest, Shamir, and Adelman. This article caught my attention (along with many others), but did not contain the details needed to fully understand the system. A year later the details were finally published and the revolution in cryptography was in full motion. After more than twenty years of research, RSA remains secure and has become the most popular public key cryptosystem.
The RSA system is a symmetric public key cryptosystem in the terms of the previous section. Recall that this means that there are any number of pairs of algorithms (E, D) both defined on the same set of values. E is the public encryption algorithm and D is the private decryption algorithm These satisfy:
Users A, B, ... can create their own pairs (EA, DA), (EB, DB), ... of RSA key pairs. The encryption algorithms are ``published'' or made available on a secure public key server, while the decryption algorithms are kept secret from everyone except the originator. The previous section has gone over how these can be used.
In RSA, the plaintexts and ciphertexts are just large positive integers, up to a certain size depending on the specific key pair. The underlying algoriths are not secret but only certain information used in them. The RSA system itself is constructed as follows:
Some people are surprised that RSA just deals with large integers. So how does it represent data? Suppose the value of n is at least 1024 bits long. This is the same as 128 bytes. In principle then, one can just run 128 bytes of Ascii text together and regard the whole as a single RSA plaintext (a single large integer) to be encrypted or signed. In practice, the protocols will demand additional data besides just the raw message, such as a timestamp, but there is room for a lot of data in a single RSA encryption.
To show that RSA decryption reverses what RSA encryption does, one only needs to show that:
But recall that
The last line follows from the chapter on favorite algorithms which shows that the exponent can be reduced modulo phi(n) = phi(p*q) = (p - 1)*(q - 1).
RSA uses arithmetic on integers at least 200 digits long. RSA has been implemented many times in hardware, but if it is only used for key exchange, a software implementation is fast enough. Any such implementation must start with routines to do extended precision arithmetic on the large integers. Writing such routines is perhaps a reasonable project for an undergraduate CS major as part of one course, with division causing the most grief. (Twenty years ago, I laid out one weekend for such a project, but I ended up devoting more than a week to it.) Many implementations are available, including the Java BigInteger class, and implementations in symbolic algebra packages such as Maple or Mathematica.
This Java implementation of the RSA cryptosystem uses the Java BigInteger library class. This arbitrary precision integer arithmetic classt has all the methods one needs to implement RSA without difficulty. In fact, it seems as if a number of specialized methods were included just to make RSA implementation easy. Additional comments about the particular implementation presented here:
Here is the implementation code and the simple test: RSA implementation and test.
Here is an altered implementation of the RSA cryptosystem, using the the Chinese Remainder Theorem (CRT) to speed up decryption. Please refer first to the comments in the earlier subsection and to other material about the RSA cryptosystem.
Suppose one calculates
instead. The Chinese Remainder Theorem (and associated algorithm) allows one to deduce x mod (p q) from a knowledge of x mod p and x mod q.
Arithmetic mod p should be done mod (p-1) in an exponent, because
Thus we can use the simpler calculation:
Finally, following the algorithm 14.71 referred to above, calculate
The final answer is:
(In calculating u in my implementation, I had to check for a result less than 0, and I had to add q to the result in that case.)
One does have to be careful with exponent 3 in two ways: if the message is less than the cube root of m, then the encrypted message will be the same as the message, and if someone obtains ciphertext for a message encrypted under several different public keys, it may be possible to calculate the message.
Here is the implementation code: Faster RSA.
Exercise: Write a ``toy'' implementation of RSA in the Java language, using the long type (64-bit integers) for the calculations. This should be a working implementation in every respect except that the integers cannot be very large.