mirror of
https://github.com/20kaushik02/CSE539_Applied_Cryptography_Midterm.git
synced 2025-12-06 07:04:06 +00:00
Completed RSA part, wrapping up
This commit is contained in:
parent
c6ecfa305b
commit
b8d034b52c
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Setup and requirements
|
## Setup and requirements
|
||||||
|
|
||||||
- Recommended Python version: 3.10.5 or later
|
- Minimum required Python version: 3.6
|
||||||
- Install packages from requirements.txt
|
- Install packages from requirements.txt
|
||||||
|
|
||||||
## Run program
|
## Run program
|
||||||
|
|||||||
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# CSE539_Applied_Cryptography_Midterm
|
||||||
|
|
||||||
|
Programming assignments/midterm for Fall 2023 CSE539 - Applied Cryptography at ASU, check README files in both folders!
|
||||||
30
RSA/README.md
Normal file
30
RSA/README.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# RSA encryption
|
||||||
|
|
||||||
|
## Setup and requirements
|
||||||
|
|
||||||
|
- Minimum required Python version: 3.3
|
||||||
|
- No additional dependencies
|
||||||
|
|
||||||
|
## Run program
|
||||||
|
|
||||||
|
The specified example's inputs:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
python3 rsa.py 254 1223 251 1339 17 65535 66536047120374145538916787981868004206438539248910734713495276883724693574434582104900978079701174539167102706725422582788481727619546235440508214694579 1756026041
|
||||||
|
```
|
||||||
|
|
||||||
|
This gives the attached outputs:
|
||||||
|

|
||||||
|
|
||||||
|
For a more verbose output, include the `--verbose` flag:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
python3 rsa.py 254 1223 251 1339 17 65535 66536047120374145538916787981868004206438539248910734713495276883724693574434582104900978079701174539167102706725422582788481727619546235440508214694579 1756026041 --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Notes and inferences
|
||||||
|
|
||||||
|
- Recent versions (2.2+) of Python automatically handle large numbers
|
||||||
|
- In this implementation, Euler totient function is used, and not Carmichael totient function
|
||||||
BIN
RSA/RSA-Project.pdf
Normal file
BIN
RSA/RSA-Project.pdf
Normal file
Binary file not shown.
101
RSA/rsa.py
Normal file
101
RSA/rsa.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import os
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
def buildExpNum(exponent: int, constant: int, base: int = 2) -> int:
|
||||||
|
return pow(base, exponent) - constant
|
||||||
|
|
||||||
|
|
||||||
|
def gcdExtendedEuclidean(a: int, b: int) -> (int, int, int):
|
||||||
|
if a == 0:
|
||||||
|
return (b, 0, 1)
|
||||||
|
gcd, x, y = gcdExtendedEuclidean(b % a, a)
|
||||||
|
return (gcd, y - (b // a) * x, x)
|
||||||
|
|
||||||
|
|
||||||
|
def modularInverse(a: int, b: int) -> int:
|
||||||
|
"""Find modular inverse of `a` under modulo `b`"""
|
||||||
|
g, x, y = gcdExtendedEuclidean(a, b)
|
||||||
|
if g != 1:
|
||||||
|
raise ValueError("non-coprime arguments provided")
|
||||||
|
return x % b
|
||||||
|
|
||||||
|
|
||||||
|
def generatePrivateKey(e: int, p: int, q: int) -> (int, int):
|
||||||
|
n = p * q
|
||||||
|
lambda_n = (p - 1) * (q - 1) # Euler totient function
|
||||||
|
d = modularInverse(e, lambda_n)
|
||||||
|
|
||||||
|
# verify
|
||||||
|
if (e * d) % lambda_n != 1:
|
||||||
|
raise Exception("error computing d")
|
||||||
|
return n, d
|
||||||
|
|
||||||
|
|
||||||
|
def decrypt(ciphertext: str, key: int, N: int) -> str:
|
||||||
|
"""RSA decryption with private key"""
|
||||||
|
return str(pow(int(ciphertext), key, N))
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt(plaintext: str, key: int, N: int) -> str:
|
||||||
|
"""RSA encryption with public key"""
|
||||||
|
return str(pow(int(plaintext), key, N))
|
||||||
|
|
||||||
|
|
||||||
|
def main(args: argparse.Namespace) -> None:
|
||||||
|
# pre-processing inputs
|
||||||
|
p_e = int(args.p_e)
|
||||||
|
p_c = int(args.p_c)
|
||||||
|
q_e = int(args.q_e)
|
||||||
|
q_c = int(args.q_c)
|
||||||
|
e_e = int(args.e_e)
|
||||||
|
e_c = int(args.e_c)
|
||||||
|
ciphertext = str(args.ciphertext)
|
||||||
|
plaintext = int(args.plaintext)
|
||||||
|
verbose = args.verbose
|
||||||
|
|
||||||
|
p = buildExpNum(p_e, p_c)
|
||||||
|
q = buildExpNum(q_e, q_c)
|
||||||
|
pub_key = e = buildExpNum(e_e, e_c)
|
||||||
|
if verbose:
|
||||||
|
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||||
|
print("Given public key (e)\t\t", pub_key)
|
||||||
|
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||||
|
|
||||||
|
N, priv_key = generatePrivateKey(e, p, q)
|
||||||
|
if verbose:
|
||||||
|
print("Calculated private key (d)\t", priv_key)
|
||||||
|
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||||
|
|
||||||
|
new_pt = decrypt(ciphertext, priv_key, N)
|
||||||
|
if verbose:
|
||||||
|
print("Given ciphertext\t\t", ciphertext)
|
||||||
|
print("Decrypted plaintext\t\t", new_pt)
|
||||||
|
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||||
|
|
||||||
|
new_ct = encrypt(plaintext, pub_key, N)
|
||||||
|
if verbose:
|
||||||
|
print("Given plaintext\t\t\t", plaintext)
|
||||||
|
print("Encrypted ciphertext\t\t", new_ct)
|
||||||
|
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||||
|
|
||||||
|
if not verbose:
|
||||||
|
print(new_pt, new_ct)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Extended Euclidean algorithm and RSA encryption/decryption"
|
||||||
|
)
|
||||||
|
parser.add_argument("p_e", help="Exponent (base 2), for p")
|
||||||
|
parser.add_argument("p_c", help="Constant to be subtracted, for p")
|
||||||
|
parser.add_argument("q_e", help="Exponent (base 2), for q")
|
||||||
|
parser.add_argument("q_c", help="Constant to be subtracted, for q")
|
||||||
|
parser.add_argument("e_e", help="Exponent (base 2), for e")
|
||||||
|
parser.add_argument("e_c", help="Constant to be subtracted, for e")
|
||||||
|
parser.add_argument("ciphertext", help="Ciphertext to be decrypted")
|
||||||
|
parser.add_argument("plaintext", help="Plaintext to be encrypted")
|
||||||
|
parser.add_argument("-v", "--verbose", action="store_true")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
main(args)
|
||||||
BIN
RSA/rsa_output.png
Normal file
BIN
RSA/rsa_output.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
RSA/rsa_verbose_output.png
Normal file
BIN
RSA/rsa_verbose_output.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
Loading…
x
Reference in New Issue
Block a user