

I learnt the theory behind RSA encryption primarily by choice as part of one of my freely chosen university projects, but I’m aware that it’s one of those things that many people seem to shy away from. Interestingly, it seems that an equivalent algorithm to RSA was created at GCHQ by James Ellis, Clifford Cocks, and Malcolm Williamson four years previously in 1973. Despite its age (having been released in 1977), RSA encryption is still one of the most widely used asymmetric encryption algorithms in use today. Our strategy will be to take a string and break it up into individualĬharacters and encrypt each character, just as we did with the CaesarĬipher.RSA (short for Rivest–Shamir–Adleman - named after its creators) is an asymmetric public-key encryption system that is very commonly used in real world applications. How to adapt the RSA encryption and decryption algorithms to

With the Caesar cipher and One-Time Pad cryptosystem.

Unsatisfying because it encrypts numbers instead of strings, like we saw The above implementation of RSA is correct, but is a little Preconditions: - private_key is a valid RSA private key (p, q, d) - 0 < ciphertext < private_key * private_key """ p, q, d = private_key, public_key, public_key n = p * q decrypted = (ciphertext ** d) % n return decrypted Encrypting and This mathematicalĭefinition translates directly into Python:ĭef rsa_decrypt(private_key: tuple ciphertext: int) -> int: """Decrypt the given ciphertext using the recipient's private key. Recall that the plaintext here is a number \(m\) between \(1\) and \(n -ġ\) inclusive, and the ciphertext is another number \(c = m^e ~\%~ n\). Next, let’s look at RSA encryption, which only uses the public key. (which, in turn, used the extended_euclidean_gcd Modular_inverse function we defined in the last chapter Once we haveĮ, we can finally calculate the last part of our private Phi_n have a greatest common divisor of 1. Generate an e, but the while loop ensures that theĮ we finally choose is valid. The algorithm makes use of both a while loop and the # Notice that we're using our modular_inverse from our work in the last chapter! d = modular_inverse(e, phi_n) return ((p, q, d), (n, e)) e = random.randint( 2, phi_n - 1) while math.gcd(e, phi_n) != 1: e = random.randint( 2, phi_n - 1) # Choose d such that e * d % phi_n = 1.

phi_n = (p - 1) * (q - 1) # Since e is chosen randomly, we repeat the random choice # until e is coprime to phi_n. Preconditions: - p and q are prime - p != q """ # Compute the product of p and q n = p * q # Choose e such that gcd(e, phi_n) = 1. The second tuple is the public key, containing (n, e). The first tuple is the private key, containing (p, q, d). The return value is a tuple containing two tuples: 1. \newcommandĭef rsa_generate_key(p: int, q: int) -> \ tuple, tuple]: """Return an RSA key pair generated using primes p and q.
