-
Notifications
You must be signed in to change notification settings - Fork 5
Home
Welcome to the RSA-Encryption-Decryption wiki!
IMPLEMENTATION: This program was implemented in 3 separate parts:
-
Key Setup:
-
Generate a random integer with at least 100 digits
-
Use Fermat’s Little Theorem to test for primality
-
If prime, this will be p
-
Do a-c to find q
-
n = p*q
-
Use Euclid’s Extended function to calculate private key d
-
e is always 65537 here
-
Write n and e to public_key.txt
-
Write d to private_key.txt
-
Encryption:
-
Read n and e from public_key.txt
-
Read the message to encrypt from message.txt
-
Divide the message up into blocks of <= 82 characters
-
Convert each block from ascii into a large integer base 256
-
Encrypt each block using C = M^e mod n (Mod_expon function)
-
Write the each block of ciphertext to ciphertext.txt
-
Decryption:
-
Read the ciphertext from ciphertext.txt, split up each block again
-
Read the private key d from private_key.txt
-
Read the public key from public_key.txt
-
Decrypt each block of ciphertext using M = C^d mod n (mod_expon function)
-
Convert the the message M to ascii so it can be reported as a string
-
ALGORITHMS:
-
In addition to the modules listed above, some sub-modules were needed to perform some operations.
-
mod_expon(x,a,n)
-
This algorithm calculates x^a (mod n) using the right to left binary method
-
Follows this pseudocode (Source: Wiki): function modular_pow(base, exponent, modulus) if modulus = 1 then return 0 Assert :: (modulus - 1) * (modulus - 1) does not overflow base result := 1 base := base mod modulus while exponent > 0 if (exponent mod 2 == 1): result := (result * base) mod modulus exponent := exponent >> 1 base := (base * base) mod modulus return result
-
is_prime(x)
-
This algorithm determines if x is prime by using Fermat’s Primality Test
-
Follows this pseudocode: If x is odd: return false else: result = compute 2^(x-1) if result = 1, #Do more testing if necessary return true else, return false
-
euclid_extended(e, n)
-
This algorithm calculates the modular inverse of a number e mod n
-
Follows this pseudocode (Source: Wiki): function extended_gcd(a, b) s := 0; old_s := 1 t := 1; old_t := 0 r := b; old_r := a while r ≠ 0 quotient := old_r div r (old_r, r) := (r, old_r - quotient * r) (old_s, s) := (s, old_s - quotient * s) (old_t, t) := (t, old_t - quotient * t) output "Bézout coefficients:", (old_s, old_t) output "greatest common divisor:", old_r output "quotients by the gcd:", (t, s)
-
TESTING:
-
Testing was done manually with test cases. Along the way I had modules which would compare the outputs of things such as the numerical version of the message before encryption and the numerical version of the message after decryption. I wrote driver functions during development to try some random inputs as well. * Some example test cases: * -A long message ~328 characters * -A short message < 82 characters * -A blank message
-
DIFFICULTIES:
-
Throughout development of this program, I encountered several difficulties. The most memorable of then was early into development when I was writing the ciphertext to a file all as one huge number, then trying to divide it back up again once I read that file in my decrypt() function. Whenever I was reading the file and dividing up the pieces into their 200 digit forms, I would get lots of inconsistency since sometimes the ciphertexts were 199 digits or something of the sort. This would make it so that the message would only be correctly deciphered 1 out of 3 times or so. I solved the problem by instead just writing the numbers to the file with a ‘,’ as a delimiter so I could split the file easily.
-
Also, I had a problem early on where whenever I used my mod_expon function, the program would take lots of time to execute, 30 minutes +. I was using the memory efficient version of modular exponentiation instead of time efficient, thus it ran at a snail's pace. I eventually reworked this function using the right to left binary method and that ran much faster.
-
The most recent problem I faced was with the last character from 82 character blocks getting cut off when decrypting. Turns out I was going from 0-82 in a loop somewhere instead of 0-81, thus I was actually getting 83 character blocks.
-
KNOWN ERRORS:
-
none as of yet
-
COMPILATION AND EXECUTION INSTRUCTIONS:
- Compilation: My program is in Python so it is not compiled.
- Execution: I have been executing my program without any flags, so: python RSA.py