Skip to content

Commit

Permalink
Add lab10
Browse files Browse the repository at this point in the history
  • Loading branch information
vis4rd committed Dec 19, 2023
1 parent e85b1e4 commit ff75939
Show file tree
Hide file tree
Showing 6 changed files with 1,040 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"python.linting.pycodestyleEnabled": false
"[python]": {
"editor.formatOnSave": true,
}
}
1 change: 1 addition & 0 deletions lab10/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.png
785 changes: 785 additions & 0 deletions lab10/data/Tux.ppm

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions lab10/zad1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Aleksander Kluczka

import os

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.padding import PKCS7
from PIL import Image


def zad1():
mods = [
["ecb", modes.ECB()],
["cbc", modes.CBC(os.urandom(16))],
["ctr", modes.CTR(os.urandom(16))],
]

for mod_name, mod in mods:
key = os.urandom(16)
ecb_cipher = Cipher(algorithms.AES(key), mod)

ecb_encryptor = ecb_cipher.encryptor()

with Image.open("./data/Tux.ppm") as source_image:
data = source_image.tobytes()

size = source_image.size
mode = source_image.mode

padder = PKCS7(16).padder()
data = padder.update(data) + padder.finalize()

ecb_ciphertext = ecb_encryptor.update(data) + ecb_encryptor.finalize()

ecb_image = Image.frombytes(mode, size, ecb_ciphertext)
ecb_image.save(f"Tux_{mod_name}.png")


def main():
zad1()


if __name__ == "__main__":
main()
75 changes: 75 additions & 0 deletions lab10/zad2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Aleksander Kluczka

import os

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes


def zad2():
def a():
key = os.urandom(16)
input = b"00000000000000000000000000000000"
l = len(input)
print(f"k = {key.hex()}")
cipher = Cipher(algorithms.AES128(key), modes.ECB())

encryptor = cipher.encryptor()

ciphertext = encryptor.update(input) + encryptor.finalize()
print(f"enc({input.decode()}) = {ciphertext.hex()[:l]}")

decryptor = cipher.decryptor()
text = decryptor.update(ciphertext) + decryptor.finalize()
print(f"dec({ciphertext.hex()[:l]}) = {text.decode()}")
print()

def b():
key = os.urandom(16)
input = b"0000000000000000000000000000000000000000000000000000000000000000"
l = len(input)
print(f"k = {key.hex()}")
cipher = Cipher(algorithms.AES128(key), modes.ECB())

encryptor = cipher.encryptor()

ciphertext = encryptor.update(input) + encryptor.finalize()
print(
f"enc({input[:l//2].decode()} {input[:l//2].decode()})\n= {ciphertext.hex()[:l//2]} {ciphertext.hex()[l//2:l]}"
)
print()

def c():
key = os.urandom(16)
iv = os.urandom(16)
input = b"0000000000000000000000000000000000000000000000000000000000000000"
l = len(input)
print(f"k = {key.hex()}")

cipher = Cipher(algorithms.AES128(key), modes.CBC(iv))
encryptor = cipher.encryptor()
ciphertext = encryptor.update(input) + encryptor.finalize()
print(f"iv ={iv.hex()}")
print(
f"enc({input[:l//2].decode()} {input[:l//2].decode()})\n= {ciphertext.hex()[:l//2]} {ciphertext.hex()[l//2:l]}"
)

iv = os.urandom(16)
cipher = Cipher(algorithms.AES128(key), modes.CBC(iv))
encryptor = cipher.encryptor()
ciphertext = encryptor.update(input) + encryptor.finalize()
print(f"iv ={iv.hex()}")
print(
f"enc({input[:l//2].decode()} {input[:l//2].decode()})\n= {ciphertext.hex()[:l//2]} {ciphertext.hex()[l//2:l]}"
)

a()
b()
c()


def main():
zad2()


if __name__ == "__main__":
main()
133 changes: 133 additions & 0 deletions lab10/zad3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Aleksander Kluczka


def left_rotate(number: int, rotation_count: int, number_of_bits: int = 32) -> int:
def ensure_correct_1_bit_count() -> None:
assert (lft := f"{number:0{number_of_bits}b}".count("1")) == (
rgt := f"{result:0{number_of_bits}b}".count("1")
), f"Incorrect number of bits: {lft=} != {rgt=}"

result: int = (
((number << rotation_count) & 0xFFFFFFFF)
| (number >> (number_of_bits - rotation_count))
) & 0xFFFFFFFF

ensure_correct_1_bit_count()
return result


def rotword(word: int) -> int:
return left_rotate(word, 8, 32)


def subword(word: int) -> int:
def subword_byte(byte: int) -> int:
def gf_invert(byte: int, mod=0x1B) -> int:
# https://stackoverflow.com/a/45444561/14048504
def gf_degree(byte: int) -> int:
result = 0
byte >>= 1
while byte != 0:
byte >>= 1
result += 1
return result

if byte == 0:
return 0

v = mod
g1 = 1
g2 = 0
j = gf_degree(byte) - 8

while byte != 1:
if j < 0:
byte, v = v, byte
g1, g2 = g2, g1
j = -j

byte ^= v << j
g1 ^= g2 << j

byte %= 256 # Emulating 8-bit overflow
g1 %= 256 # Emulating 8-bit overflow

j = gf_degree(byte) - gf_degree(v)

return g1

c = [int(i) for i in "01100011"][::-1]
byte_rev: list[int] = [int(i) for i in f"{gf_invert(byte):08b}"][::-1]
retval = []
for i in range(8):
b_i: int = (
byte_rev[i]
+ byte_rev[(i + 4) % 8]
+ byte_rev[(i + 5) % 8]
+ byte_rev[(i + 6) % 8]
+ byte_rev[(i + 7) % 8]
+ c[i]
) % 2
retval.append(str(b_i))
retval_str = "".join(retval[::-1])
return int(retval_str, 2)

b0 = subword_byte((word >> 24) & 0xF)
b1 = subword_byte((word >> 16) & 0xF)
b2 = subword_byte((word >> 8) & 0xF)
b3 = subword_byte((word >> 0) & 0xF)
return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3


def keyexpansion(key: str) -> str:
def key_byte(index: int) -> int:
return int(key[2 * index : 2 * index + 2], 16)

rcon: list = [
0x01000000,
0x02000000,
0x04000000,
0x08000000,
0x10000000,
0x20000000,
0x40000000,
0x80000000,
0x1B000000,
0x36000000,
]
w = {}
for i in range(4):
w[i] = (
(key_byte(4 * i) << 24)
| (key_byte(4 * i + 1) << 16)
| (key_byte(4 * i + 2) << 8)
| key_byte(4 * i + 3)
)
assert w[i] < 2**32

for i in range(4, 44):
temp: int = w[i - 1]
if (i % 4) == 0:
rotated_temp = rotword(temp)
subworded_temp = subword(rotated_temp)
temp = subworded_temp ^ rcon[(i // 4) - 1]
w[i] = w[i - 4] ^ temp

w = "".join([f"{w[i]:08x}" for i in range(44)])
return w


def zad3():
cipher_key = "2b7e151628aed2a6abf7158809cf4f3c"
print(f"key = '{cipher_key}'")

expanded_key = keyexpansion(cipher_key)
print(f"expanded key = '{expanded_key}'")


def main():
zad3()


if __name__ == "__main__":
main()

0 comments on commit ff75939

Please sign in to comment.