import sys
sys.path.insert(0, '../../')
from toolkit import textToBinary, binaryToTextKidRSA¶
This section will cover one type of public key system, KidRSA named by Neal Koblitz in Cryptologia, Vol. 21, No. 4 after the full-blown RSA system to be covered in a future section. It shares many of the same features and mathematics as RSA, but is a bit easier to understand as a stepping-stone into public key cryptography. It’s important to note that KidRSA is not secure! However, it is much more secure than any of the systems that have been previously covered, and has all the benefits of not having to worry about key exchange.
The keys in KidRSA are pairs of integers, where the public key is (typically for encryption) and the private key is (typically for decryption). The “one way” function in KidRSA is determining multiplicative inverses in a particular modulo. You should recall from the section on Affine Ciphers, that the only way we were able to determine the multiplicative inverse in modulo 26 was to try all the possible inverses between 0 and 25, and multiply them with the key value to determine if it was actually an inverse. It didn’t take too long in modulo 26, but imagine if it was in modulo 104659, or 3267000013. That would take a lot longer to determine an inverse for a particular value. However, we’ll see that it’s not too difficult to quickly generate two integers that we know to be inverses in a modulo of our choosing. If we generate two numbers that are multiplicative inverses of each other, then one number will be part of the public key and the other part of the private key. This is the perfect set up for a public key cryptography system!
It’s easy to generate two numbers that are multiplicative inverses of each other in a given modulo
It’s difficult to determine one of the two numbers if you know the other
The Algorithm¶
Let’s walk through how to generate a pair of keys, and .
Choose 4 integers, , and keep these secret!
Compute:
.
.
Keep and secret, while and are public.
The public key is
The private key is
Let your message be an integer ( must be less than and share no factors with )
The encrypted message is
To decrypt, multiply the encrypted message by and reduce by modulo
Example #1 (Small Numbers)¶
Let’s start by working through an example where you’ll encrypt and decrypt a message using this system. This example uses relatively small numbers that can be computed using either mental math or a simple calculator.
Let . Next, you can compute that
You now know that the public key is and the private key is .
A friend wants to encrypt a very simple message, the single character a. They would start by converting it to binary using ASCII to obtain, 01100001 and then to decimal 97. Next, compute , which gives 325. Your friend could send this encrypted message, 325 as an integer or convert to binary 00000001 01000101 or as the base64 characters AUU= (all these representations are equivalent).
Upon receiving the message, you would use the integer value, 325 and compute which returns 93, the original value of the plaintext message. This value can be converted back to text using ASCII to retrieve the plaintext message a.
Example #2 (Large Numbers)¶
This example will use larger numbers which may require Python or other specialized mathematics software to compute values. Such software will also be needed to display all the digits of your computation, as most hand held calculators can only display between 10-12 digits..
Let and .
We take our plaintext message NCSSM and convert to binary 01001110 01000011 01010011 01010011 01001101 which as the decimal representation of . Since this message, , is less than and is relatively prime to , we can proceed.
To encrypt the message, multiply and , and reduce modulo . Here we’ll use Python to do this quickly.
print( (336136983373 * 6198089817) % 8509980525203 )2376855076134
This is our encrypted message. As binary it would be represented as 00000010 00101001 01100111 10011010 00111101 00100110 or in base64 as Ailnmj0m.
To confirm decryption works as well, take the encrypted message as a decimal, 2376855076134 and multiply by and reduce modulo .
print( (2376855076134 * 6924310717) % 8509980525203 )336136983373
Which returns the plaintext message in decimal format.
Why Does This Work?¶
While the example above illustrates that we were able to successfully encrypt and decrypt a message with this system, it doesn’t explain why this system works. Let’s dig into the mathematics.
After choosing and at random (although choosing prime numbers here will be helpful down the road), we first compute and by way of the number (notice all three of the values that are part of the keys are based on this value of ). To compute we start with:
Since is the product of and we now know that:
must be divisible by
must also be divisible by ,
Since , the equation can be rearranged to determine that .
Since , we can deduce that
Therefore, is also divisible by .
Since is divisible by , we know that . Therefore we also know that , which confirms that and are guaranteed to be multiplicative inverses in modulus .
This list of results is incredibly powerful and important. It explains why this algorithm will generate and such that they are multiplicative inverses of each other in modulus , and why is guaranteed to be an integer. Now that we know and are guaranteed to be inverses, it should make sense that when we take an encrypted message, and then multiply by , which results in , the expression simplifies to , since . Thus, multiplying by will decrypt the message and reveal the original value.
Notice that it would be very difficult to determine using only the public information and . You would need to multiply by all possible values of and reduce by modulus to check if and were inverses, which is extremely inefficient (for now).
Weakness of KidRSA¶
The math behind KidRSA ensures that correctly generated values of and can be used to encrypt and decrypt messages without both parties having the full information about the public and private key pair. It also makes it incredibly difficult for an eavesdropper to determine when they only have and . However, there’s some even more advanced mathematics that benefits the eavesdropper! The Euclidean Algorithm can be used to quickly and easily calculate multiplicative inverses in any modulus, and thus explains why KidRSA is an insecure system.
We’ll see that KidRSA is improved upon in real RSA, where it’s not about finding multiplicative inverses such that but rather exponential inverses such that , where is very hard for a computer to calculate if is large.
Exercise for the Reader¶
Write a function that takes in a list of 4 numbers that represent and and returns a list containing and .
Why Does This Work? The Little Details¶
Now that you understand how the key generation works, the last bit of mathematics you need to understand relates to the actual encryption and decryption processes. This next part will further explain how we know that and are inverses of each other.
To encrypt a message , you would multiply by and reduce modulo . Reducing the encrypted message, by modulo , put another way, is equivalent to finding another integer that is smaller than by some factor of . We can write that reduction as for some value of that ensures the result is between 0 and . For example, if and , then reducing is equivalent to subtracting off multiples of 29 until is between 0 and 29. In this example, , so by setting we know that , and 4 will be the encrypted message. The expression is a general representation for an encrypted message that we will transmit using KidRSA.
To decrypt the message , you multiply by and reduce modulo . Multiplying yields the following result:
Which implies that is equal to plus some integer multiple of . Since we know that is already less than by the rules of the system, then we know that is equivalent reducing by modulo is equivalent to subtracting off multiplies of until the value is less than , we know that , confirming that the decryption process will always yield the original message, .