added labeval
This commit is contained in:
parent
00c58d5d17
commit
60ebd2b53c
1 changed files with 156 additions and 0 deletions
156
IS/Lab/Eval/test.py
Normal file
156
IS/Lab/Eval/test.py
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
from functools import partial
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
import string
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
from Crypto.Cipher import AES, PKCS1_OAEP
|
||||||
|
from Crypto.Util.Padding import pad, unpad
|
||||||
|
from Crypto.Random import get_random_bytes
|
||||||
|
from sympy import Matrix # only for the 2×2 Hill inverse
|
||||||
|
|
||||||
|
|
||||||
|
# 1. Hill-Cipher utilities (2×2 matrix [[3,3],[2,5]])
|
||||||
|
|
||||||
|
hillkey = np.array([[3, 3],
|
||||||
|
[2, 5]], dtype=int)
|
||||||
|
ALPH = string.ascii_uppercase
|
||||||
|
m_len = 2 # block size
|
||||||
|
|
||||||
|
def clean(txt):
|
||||||
|
return ''.join(ch.upper() for ch in txt if ch.isalpha())
|
||||||
|
|
||||||
|
def hill_encrypt(pt, key=hillkey):
|
||||||
|
pt = clean(pt)
|
||||||
|
if len(pt) % m_len: # padding
|
||||||
|
pt += 'X' * (m_len - len(pt) % m_len)
|
||||||
|
cipher = []
|
||||||
|
for i in range(0, len(pt), m_len):
|
||||||
|
block = np.array([ALPH.index(ch) for ch in pt[i:i+m_len]])
|
||||||
|
cipher.extend((key @ block) % 26)
|
||||||
|
return ''.join(ALPH[i] for i in cipher)
|
||||||
|
|
||||||
|
def hill_decrypt(ct, key=hillkey):
|
||||||
|
# modular inverse of the matrix
|
||||||
|
M = Matrix(key)
|
||||||
|
detinv = pow(int(M.det()) % 26, -1, 26)
|
||||||
|
adj = M.adjugate()
|
||||||
|
inv_key = (detinv * adj) % 26
|
||||||
|
inv_key = np.array(inv_key).astype(int)
|
||||||
|
|
||||||
|
plain = []
|
||||||
|
for i in range(0, len(ct), m_len):
|
||||||
|
block = np.array([ALPH.index(ch) for ch in ct[i:i+m_len]])
|
||||||
|
plain.extend((inv_key @ block) % 26)
|
||||||
|
return ''.join(ALPH[i] for i in plain)
|
||||||
|
|
||||||
|
# Generic timing wrapper
|
||||||
|
def timed(fn, *a, **kw):
|
||||||
|
t0 = time.perf_counter()
|
||||||
|
for _ in range(100_000): # 100 000 loops → 1 000 000 calls
|
||||||
|
fn(*a, **kw)
|
||||||
|
delta = time.perf_counter() - t0
|
||||||
|
return delta
|
||||||
|
|
||||||
|
# Menu
|
||||||
|
def menu():
|
||||||
|
while True:
|
||||||
|
print("\n===== Cryptographic Demo =====")
|
||||||
|
print("1. Hill-cipher demo")
|
||||||
|
print("2. RSA + envelope (share AES)")
|
||||||
|
print("3. AES-128 encrypt / decrypt")
|
||||||
|
print("4. Speed graph (100k it loops)")
|
||||||
|
print("0. Quit")
|
||||||
|
ch = input("Select >> ").strip()
|
||||||
|
if ch == '0': break
|
||||||
|
elif ch == '1': hill_demo()
|
||||||
|
elif ch == '2': rsa_env_demo()
|
||||||
|
elif ch == '3': aes_demo()
|
||||||
|
elif ch == '4': speed_graph()
|
||||||
|
else: print("Invalid choice")
|
||||||
|
|
||||||
|
# 1. Hill demo
|
||||||
|
def hill_demo():
|
||||||
|
msg = 'The key is hidden under the mattress'
|
||||||
|
print("\n------- 1. Hill-Cipher Demo -------")
|
||||||
|
print("Key matrix:\n", hillkey)
|
||||||
|
ct = hill_encrypt(msg)
|
||||||
|
print("Cipher :", ct)
|
||||||
|
pt = hill_decrypt(ct)
|
||||||
|
print("Plain :", pt) # uppercase / padded – expected
|
||||||
|
|
||||||
|
# 2. RSA Envelope demo
|
||||||
|
AES_KEY = b"0123456789ABCDEF" # 16-byte AES-128 key (truncated from prompt)
|
||||||
|
|
||||||
|
def rsa_env_demo():
|
||||||
|
print("\n------- 2. RSA × AES envelope Demo -------")
|
||||||
|
# generate RSA pairs
|
||||||
|
encoder_priv = RSA.generate(2048)
|
||||||
|
encoder_pub = encoder_priv.publickey()
|
||||||
|
|
||||||
|
decoder_priv = RSA.generate(2048) # strictly not needed, but shown
|
||||||
|
decoder_pub = decoder_priv.publickey()
|
||||||
|
|
||||||
|
# Use encoder_pub to encrypt the shared AES key
|
||||||
|
cipher_rsa = PKCS1_OAEP.new(encoder_pub)
|
||||||
|
enc_key = cipher_rsa.encrypt(AES_KEY)
|
||||||
|
|
||||||
|
# Show keys
|
||||||
|
print("Encoder public key (PEM):\n", encoder_pub.export_key().decode())
|
||||||
|
print("Encoder private key (PEM):\n", encoder_priv.export_key().decode())
|
||||||
|
print("Encrypted AES key (hex):", enc_key.hex())
|
||||||
|
|
||||||
|
# Decrypt back using encoder’s private key
|
||||||
|
dec_rsa = PKCS1_OAEP.new(encoder_priv)
|
||||||
|
dec_key = dec_rsa.decrypt(enc_key)
|
||||||
|
print("Decrypted AES key :", dec_key.hex(), " match=", dec_key==AES_KEY)
|
||||||
|
|
||||||
|
# 3. AES-128
|
||||||
|
def aes_demo():
|
||||||
|
msg = input("Enter AES plaintext:")
|
||||||
|
print("\n------- 3. AES-128 Demo -------")
|
||||||
|
cipher = AES.new(AES_KEY, AES.MODE_CBC) # random IV
|
||||||
|
ct = cipher.encrypt(pad(msg.encode(), AES.block_size))
|
||||||
|
print("Raw key :", AES_KEY.hex())
|
||||||
|
print("Ciphertext (incl. IV) :", cipher.iv.hex() + ct.hex())
|
||||||
|
decipher = AES.new(AES_KEY, AES.MODE_CBC, cipher.iv)
|
||||||
|
pt = unpad(decipher.decrypt(ct), AES.block_size).decode()
|
||||||
|
print("Recovered plaintext :", pt)
|
||||||
|
|
||||||
|
# 4. Speed test
|
||||||
|
def speed_graph():
|
||||||
|
print("\n------- Benchmark (100 000 loops = 1 Mio calls) -------")
|
||||||
|
# prepare one big dummy block for AES
|
||||||
|
aes_cipher = AES.new(AES_KEY, AES.MODE_ECB)
|
||||||
|
dummy_aes = b"A" * 16
|
||||||
|
|
||||||
|
# RSA encryption of AES key just once
|
||||||
|
pub_key = RSA.generate(2048).publickey()
|
||||||
|
rsa_cipher = PKCS1_OAEP.new(pub_key)
|
||||||
|
dummy_rsa = AES_KEY
|
||||||
|
|
||||||
|
# Hill needs string
|
||||||
|
hill_string = "HELLOWORLD"
|
||||||
|
hill_ct = hill_encrypt(hill_string) # pre-compute to keep test same
|
||||||
|
|
||||||
|
# timing
|
||||||
|
t_hill = timed(hill_encrypt, hill_string)
|
||||||
|
t_rsa = timed(rsa_cipher.encrypt, dummy_rsa)
|
||||||
|
t_aes = timed(aes_cipher.encrypt, dummy_aes)
|
||||||
|
|
||||||
|
methods = ['Hill-cipher\n(str encrypt)', 'RSA-OAEP\n(key wrap)', 'AES-128\n(block)']
|
||||||
|
timings = [t_hill, t_rsa, t_aes]
|
||||||
|
for name,val in zip(methods,timings):
|
||||||
|
print(f"{name:25s} : {val:9.4f} s (100 000 loops)")
|
||||||
|
|
||||||
|
plt.bar(methods, timings, color=['gold','coral','dodgerblue'])
|
||||||
|
plt.ylabel("Time (s) for 100 000 iterations")
|
||||||
|
plt.title("Relative speed among 3 algorithms")
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# main
|
||||||
|
##############################################################
|
||||||
|
if __name__ == "__main__":
|
||||||
|
menu()
|
Loading…
Add table
Add a link
Reference in a new issue