Note: This page requires a MathML-capable browser to display properly. If the symbol in brackets () isn't an arrow, please use the HTML version instead.
In this article, I discuss methods for encrypting messages, with particular emphasis on the code known as RSA. The background material on congruences, Euclid's algorithm, etc. is also discussed. The material presented should by accessible to a mathematics or theoretically-oriented science undergraduate, or to a bright A-level student. Terms which may seem technical appear in italics.
The RSA code is an 'unbreakable' cipher - a means of scrambling a message so that it will be indecipherable to prying eyes. In mathematical terms, a cipher is a special kind of mapping from an set A, called the alphabet (not necessarily a natural alphabet!), to itself. The mapping must be a bijection, i.e. it must be invertible, because we would like to be able to recover the original message given the encoded message.
One of the oldest ciphers was used by Julius Caesar and involves permuting the letters of the alphabet, often simply shifting each letter a fixed number of places. For instance, if we agreed to shift every letter 3 places down, then the letter 'B' would become 'E', 'G' would become 'J' and so on. The phrase 'fifth legion advance' would become 'iliwk ohjlrq dgydqfh'. To get back the original message, all we have to do is to transpose each letter 3 places up in the alphabet. In a code such as the Caesarian, which is really a collection of similar codes that depend on a parameter (in this case the number of places by which each letter is shifted), the parameter is called the encryption key
There are a number of problems with Caesar's method. Because we are using the ordinary Roman alphabet, there are only different possible codes (the total number of permutations on a set of size 26), this might seem like a big number, but modern computers can search through all the possiblities in a relatively small amount of time. (moreover, if we insist on using simple shifts, then there are only 26 different possibilities, one of which is clearly useless!) Another problem, of a more practical nature, is how Caesar is going to let his generals know of the encryption key.
The RSA code addresses both problems. On the one hand, it allows the use of alphabets of arbitrary length, but, more fundamentally, the main advantage of the RSA code is that even if the encryption method should fall into enemy hands, it is still very difficult to invert the cipher. For this reason, the RSA code is sometimes known as public-key encryption, because the encryption key can be divulged to everyone without posing a security risk.
Before explaining how to encode a natural message, I will discuss how the RSA code works on a special alphabet of numbers. But we'll need to define a few mathematical terms along the way.
Definitions (see below for examples!)
Examples
The following Java applet calculates the hcf of any two whole numbers and expresses the hcf as a linear combination of the numbers:
Choose any (largish!) positive whole number n. The set of elements which we will encode in the RSA scheme is simply R(n). This takes the place of the Roman alphabet in Caesar's code.
Look back at Caesar's code. What is really going on is that there is a bijection f : A A (where A is the Roman alphabet ) which tells us to shift each letter a certain number of places. We are going to find a bijection f : R(n) R(n) which is relatively easy to carry out, but very hard to invert. This will be our code.
First we need a little theorem about congruences. If you've never heard of these objects, follow the link in the previous sentence.
Lemma
Let n be a positive whole number and t a whole number such that t 1 mod (10) = 4. (n). If x is coprime to n, then . The proof is left as an easy exercise (easy iff you know the Fermat-Euler theorem).
Corollary
If e is positive integer such that e is coprime to (10) = 4. (n) then the map f : R(n) R(n) defined by is a bijection (i.e. is invertible).
Proof
We'll use the above lemma to find an inverse. The idea is to find a whole number d such that if t = ed then t 1 mod (10) = 4. (n). Then for any x in R(n), . That is, the mapping g : R(n) R(n) defined by , is the required inverse for f. But such a d does exist, because e is coprime to (10) = 4. (n) ( see the section on congruences ). QED.
So now we have our bijection ( namely the function f introduced in the corollary ). Why is it difficult to invert? If we are to use the method of the corollary to find an inverse function, we first need to calculate (10) = 4. (n). The best method known for evaluating (10) = 4. (n) requires factorising n ( i.e. writing n as a product of its factors ). In general, for large n ( say 100 digits or more ), this is a tough problem, particularly if n has only a small number of factors. Often n is chosen to be the product of two large prime numbers. Of course, there may be an alternative method for finding the inverse function ( without needing to calculate (10) = 4. (n) or to factorise n ); no-one knows of such a method, or if they do, they're keeping very quiet about it!
If you would like to calculate (10) = 4. (n) for yourself, the following fact is handy (no proof supplied!):
Fact
Let a, b be coprime positive whole numbers, then (a b) = (a) (b).
Note: we must have that a and b are coprime because, for instance, (4) = Size of {1,3} = 2. Whereas (2) = Size of {1} = 1, and hence (4) doesn't equal (2) (2).
Example: (21) = (3 * 7) = (3) * (7) = 2 * 6 = 12.
If you can't be bothered to calculate phi by hand, I've written a phi calculator which will do it for you.
Warning! Calculating (n) involves factorising n, which generally takes a long time for large n. (which is why the RSA code is so effective!), so if you enter a large number ( say >= 20 digits ), my programme may appear to stall. Really, it's just thinking very hard. :-(
Another related programme, which you may find useful later on is my factoriser:
The following program multiplies any two integers together (more useful than you might think!)
It's all very well messing about with numbers, but what about encrypting an actual message?!
One rather silly approach would be to assign each letter of the alphabet to one of the elements of R(n). The drawback, as with Caesar's method is that it effectively limits the number of codes to only 26! (that's an exclamation point, and not the factorial symbol.) So in order to increase the size of our alphabet, we convert blocks of characters into integers. The way we do this is first to assign an integer between 0 and N-1 to each character (where there are a total of N characters in our character set, e.g. N = 26 if we use the Roman alphabet as our character set) then, having already chosen n, we define r to the the unique positive integer such that . Each block of r characters then corresponds to a base N number which is between 0 and n-1 inclusive. When I get round to it, this will be a link to a page about numbers in other bases. This number is encoded using the map . Now is between 0 and n-1 (mod n), but not necessarily less than , so it converts to a block of r+1 characters (not a block of r characters). To decode, we simply invert the entire process. Note that we can only invert if x is coprime to n; often, we will take n to be the product of two primes, say n = p q, with p and q prime. Then the number of choices for x which are coprime to n is (n) = (p)(q) = (p-1)(q-1), which is close enough to n, for large p,q. If that's all Greek to you, don't worry, because I have slaved away at my keyboard and produced a Java applet which does the job for you:
I have spent the last two weeks learning the Java programming language just so that I could produce the following applet. I've written it so that you need to understand at least some of the maths in order to be able to use it.
Just punch in your number n, and a number e if you wish to encode and/or d if you wish to decode. Type your message in the appropriate window (I'll let you figure out which one is the appropriate window) and hit the encode or decode button. That's it.
As far as I know, there aren't any bugs in the program, but sometimes it will produce error messages. This is because you did something wrong ;-)
Error Message | Explanation |
---|---|
java.lang.NumberFormatException: Zero length BigInteger | You need to type in a number for n and for e or d |
java.lang.NumberFormatException: Choose n>95 | Do as it tells you! I have chosen N = 95. If n <= N, then the program won't be able to calculate r>0 such that . |
java.lang.NumberFormatException: 'x' isn't coprime to 'n' | This means that when one of the block of characters was converted to an integer x, x wasn't coprime to n. You can sometimes remedy this by simply adding a few extra characters at the beginning of your message. Otherwise, choose a decent n which has few factors! |
If you're not sure how to get the software running, here's a step-by-step list of what you have to do:
Worked Example
N.B..: Often you will need the output from one of the programmes above in order to calculate n, e and d. Note that with most windows operating systems, you can copy and paste from the text boxes. e.g. with Microsoft Windows, just select the text to be copied with your mouse, then hit Ctrl-C to copy and Ctrl-V to paste.
If you want to use my programme to receive messages from other people, you will typically tell them the numbers n and e, but keep the number d a secret. They can then encode messages and send them to you, but cannot decode anything!!. (Note that you can copy the output of CodeIt and paste it into your mail programme)
This section is for those who have not come across congruences or Euclid's algorithm. If this applies to you, read on, else feel free to skip it.
Congruences are a bit like equations, but different! We need congruences to describe the RSA code, so I guess I'll have to explain what they are ;-)
Definition
Let a, b, m be whole numbers. We say a is congruent b modulo m and write 'a b mod m' if m divides a-b.
For instance, 10 4 mod 2, as 2 divides 6 = 10-4. Also 24 -1 mod 5, as 5 divides 25 = 24-(-1).
Sometimes, the idea of congruence arithmetic is introduced by looking at the arithmetic of clocks. Note that on a (twelve-hour) clock, if you add 3 to 10, you get 1 ( because 3:00 + 10:00 = 13:00 = 1pm ). More generally, whenever you add on a multiple of 12 hours, you get back the same position of the hour hand. What is really happening is that clock arithmetic is congruence arithmetic modulo 12; we make precise the statement that 3 + 10 '=' 1 by observing that 3 + 10 = 13 1 mod 12.
The reason we introduce congruences is that they behave in many ways like ordinary equations. First, they have some nice properties which enable you to combine congruences in simple ways e.g. if a, b, c, m are whole numbers then:
Also, like ordinary equations, one can add and multiply congruences:
All these statements require proof, of course, but I'll leave them as exercises!
Next, we need something called Euclid's Algorithm in order to be able to find congruence inverses. Suppose we have whole numbers a and m such that a is coprime to m. We'd like to be able to find a whole number b such that a b 1 mod m. If this were an ordinary equation then we'd just put b = 1/a, but of course, it isn't, and usually, 1/a won't even be a whole number. Instead we use a nifty result which shows the existence of whole numbers s and t, such that 1 = sa + tm. Then we just take b = s and we're done.
Lemma (Euclid's Algorithm)
Let a, b be whole numbers and let d = hcf(a,b) ( follow this link for a definition ) then there exist whole numbers s and t such that d = s a + t b.
Proof
It is a basic property of whole numbers that given a and b, there exist whole numbers q and r such that a = bq + r and, moreover, that 0<= r < |b|. One can check that hcf(a,b) = hcf(b,r). Then, by induction on r, we have that there exist s' and t' such that d = s' b + t' r. Consequently, d = s' b + t' (a - bq) = t' a + (s' - t'q)b. So put s = t' and t = s' - t'q, then d = sa + tb. QED.
Even if you don't get the proof, there's no need to worry as I've written a Java applet which will do the calculations for you. Click here for Gihan's hcf Calculator.
I am rather inexperienced with Java (at the date of writing, I've only been at it two weeks), so my software may seem a little rough round the edges. If you have any feedback on how to improve the programmes, please email me.
Java is meant to be platform and country independent, but I have sidestepped the latter feature by using the Unicode values of the characters in 'CodeIt'. This will cause problems if your operating system / web browser does not use the ASCII or ISO8859-1 (Latin-1) document encoding method.
All the software on this page uses the java.math package. (this package is new to Java 1.1, if you're browser doesn't support Java 1.1, get one that does! See the JavaSoft home page for more details) The package java.math defines a class BigInteger which supports arbitrary sized integers. This means that you can choose 'n' to be as large as you like in CodeIt.
RSA Data Security, Inc. | This company was set up by the guys who invented the RSA code. Unsurprisingly, they specialise in cryptography methods. |
This document was written in XHTML and MathML. To view it properly, you need an up-to-date browser, such as mozilla, and the required fonts.
On a modern Debian system, you should install the latex-xft-font debian package, then copy the Mathematica 4.1 fonts to /usr/local/share/fonts/math-fonts. You may also need to install the adobe symbol font as described in this document on installing MathML on linux. Restart mozilla and you're up!
If you're running mozilla on Windows, follow the instructions on the mozilla MathML webpage. You may need to save the file before running it if installation throws up errors.
This document is XHTML 1.1 compliant!