Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

KidRSA

import sys
sys.path.insert(0, '../../')

from toolkit import textToBinary, binaryToText

KidRSA

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 (e,n)\left( e, n\right) (typically for encryption) and the private key is (d,n)\left( d, n \right) (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, (e,n)\left( e, n\right) and (d,n)\left( d, n\right).

  1. Choose 4 integers, a,b,a,ba, b, a', b', and keep these secret!

  2. Compute:

    • M=ab1M = ab - 1

    • e=aM+ae = a'M + a

    • d=bM+bd = b'M + b.

    • n=(ed1)/Mn = \left(ed -1 \right) / M.

    • Keep MM and dd secret, while ee and nn are public.

  3. The public key is (e,n)\left( e, n\right)

  4. The private key is (d,n)\left( d, n\right)

  5. Let your message be an integer mm (mm must be less than nn and share no factors with nn)

  6. The encrypted message is em(modn)e \cdot m \pmod{n}

  7. To decrypt, multiply the encrypted message by dd and reduce by modulo nn

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 a=5,b=3,a=7,b=5a = 5, b = 3, a' = 7, b' = 5. Next, you can compute that

  • M=531=14M = 5 \cdot 3 - 1 = 14

  • e=714+5=103e = 7 \cdot 14 + 5 = 103

  • d=514+3=73d = 5 \cdot 14 + 3 = 73

  • n=(103731)/14=537n = \left( 103 \cdot 73 -1 \right) / 14 = 537

You now know that the public key is (103,537)\left( 103, 537 \right) and the private key is (73,537)\left( 73, 537 \right).

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 97103(mod537)97 \cdot 103 \pmod{537}, 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 32573(mod537) 325 \cdot 73 \pmod{537} 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 a=1933,b=2609,a=1229,a = 1933, b = 2609, a' = 1229, and b=1373b' = 1373.

  • M=(1933)(2609)1=5,043,196M = \left(1933\right) \left(2609\right) - 1 = 5,043,196

  • e=(1229)(5043196)+1933=6,198,089,817e = \left(1229\right) \left(5043196\right) + 1933 = 6,198,089,817

  • d=(1373)(5043196)+2609=6,924,310,717d = \left(1373\right) \left(5043196\right) + 2609 = 6,924,310,717

  • n=(619808981769243107171)/5043196=8,509,980,525,203n = \left(6198089817 \cdot 6924310717 - 1 \right) / 5043196 = 8,509,980,525,203

We take our plaintext message NCSSM and convert to binary 01001110 01000011 01010011 01010011 01001101 which as the decimal representation of m=336,136,983,373m = 336,136,983,373. Since this message, mm, is less than nn and is relatively prime to nn, we can proceed.

To encrypt the message, multiply mm and ee, and reduce modulo nn. 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 dd and reduce modulo nn.

print( (2376855076134 * 6924310717) % 8509980525203 )
336136983373

Which returns the plaintext message mm 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 a,b,a,a, b, a', and bb' at random (although choosing prime numbers here will be helpful down the road), we first compute e,d,e, d, and nn by way of the number MM (notice all three of the values that are part of the keys are based on this value of MM). To compute nn we start with:

ed1=(aM+a)(bM+b)multiply1=abM2+abM+abMfactor out M+ab1=abM2+(ab+ab)M+ab1substitute M=ab1=abM2+(ab+ab)M+Mfactor out M=M(abM+ab+ab+1)\begin{align} ed - 1 & = \underbrace{ \left( a'M + a \right) \left(b'M + b \right) }_{\text{multiply}} - 1 \\ & = a'b'M^2 + \underbrace{ ab'M + a'bM }_{\text{factor out } M}+ ab - 1 \\ & = a'b'M^2 + \left( ab' + a'b \right)M + \underbrace{ ab - 1 }_{\text{substitute } M = ab - 1} \\ & = \underbrace{ a'b'M^2 + \left( ab' + a'b \right)M + M }_{\text{factor out } M} \\ & = M \left( a'b'M + ab' + a'b + 1 \right) \\ \end{align}

Since ed1ed - 1 is the product of MM and (abM+ab+ab+1)\left( a'b'M + ab' + a'b + 1 \right) we now know that:

  • ed1ed - 1 must be divisible by MM

  • ed1ed - 1 must also be divisible by (abM+ab+ab+1)\left( a'b'M + ab' + a'b + 1 \right),

  • Since n=(ed1)/Mn = \left(ed - 1\right) / M, the equation can be rearranged to determine that nM=(ed1)nM = \left(ed - 1\right).

    • Since (ed1)=nM=(abM+ab+ab+1)M\left( ed - 1 \right) = nM = \left( a'b'M + ab' + a'b + 1 \right) M, we can deduce that n=(abM+ab+ab+1)n = \left( a'b'M + ab' + a'b + 1 \right)

    • Therefore, ed1ed - 1 is also divisible by nn.

  • Since ed1ed - 1 is divisible by nn, we know that 0ed1(modn)0 \equiv ed - 1 \pmod{n}. Therefore we also know that 1ed(modn)1 \equiv ed \pmod{n}, which confirms that ee and dd are guaranteed to be multiplicative inverses in modulus nn.

This list of results is incredibly powerful and important. It explains why this algorithm will generate ee and dd such that they are multiplicative inverses of each other in modulus nn, and why nn is guaranteed to be an integer. Now that we know ee and dd are guaranteed to be inverses, it should make sense that when we take an encrypted message, em(modn)e \cdot m \pmod{n} and then multiply by dd, which results in dem(modn)d \cdot e \cdot m \pmod{n}, the expression simplifies to m(modn)m \pmod{n}, since de=1d \cdot e = 1. Thus, multiplying by dd will decrypt the message and reveal the original value.

Notice that it would be very difficult to determine ee using only the public information dd and nn. You would need to multiply dd by all possible values of ee and reduce by modulus nn to check if dd and ee were inverses, which is extremely inefficient (for now).

Weakness of KidRSA

The math behind KidRSA ensures that correctly generated values of e,d,e, d, and nn 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 dd when they only have ee and nn. 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 1ed(modn)1 \equiv e \cdot d \pmod{n} but rather exponential inverses such that 1ed(modφ(n))1 \equiv e^d \pmod{ \varphi(n)}, where φ(n)\varphi(n) is very hard for a computer to calculate if nn is large.

Exercise for the Reader

  • Write a function that takes in a list of 4 numbers that represent a,b,a,a, b, a', and bb' and returns a list containing e,d,e, d, and nn.

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 ee and dd are inverses of each other.

To encrypt a message mm, you would multiply by ee and reduce modulo nn. Reducing the encrypted message, mem \cdot e by modulo nn, put another way, is equivalent to finding another integer that is smaller than mem \cdot e by some factor of nn. We can write that reduction as meknm \cdot e - k \cdot n for some value of kk that ensures the result is between 0 and nn. For example, if m=13,e=7m = 13, e = 7 and n=29n=29, then reducing 137(mod29)13 \cdot 7 \pmod{29} is equivalent to subtracting off multiples of 29 until 7137 \cdot 13 is between 0 and 29. In this example, 91(3)29=491 - \left( 3 \right) 29 = 4, so by setting k=4k=4 we know that 491(mod29)4 \equiv 91 \pmod{29}, and 4 will be the encrypted message. The expression meknm \cdot e - k \cdot n is a general representation for an encrypted message that we will transmit using KidRSA.

To decrypt the message meknm \cdot e - k \cdot n, you multiply by dd and reduce modulo nn. Multiplying yields the following result:

d(mekn)=medkdndistribute d=m(nM+1)kdnsubstitute for ed=mnM+mkdndistribute m=m+mnMkdnrearrange terms=m+(mMkd)nfactor out n\begin{align} d \left(m \cdot e - k \cdot n\right) & = med - kdn & \text{distribute } d\\ & = m \cdot \left(nM + 1\right) - kdn & \text{substitute for } ed \\ & = mnM + m - kdn & \text{distribute } m \\ & = m + mnM - kdn & \text{rearrange terms} \\ & = m + \left( mM - kd \right)n & \text{factor out } n\\ \end{align}

Which implies that d(mekn)d \left(m \cdot e - k \cdot n\right) is equal to mm plus some integer multiple of nn. Since we know that mm is already less than nn by the rules of the system, then we know that mm is equivalent reducing by modulo nn is equivalent to subtracting off multiplies of nn until the value is less than nn, we know that mm+(Mkd)n(modn) m \equiv m + \left( M - kd \right)n \pmod{n} , confirming that the decryption process will always yield the original message, mm.