diff --git a/lab9/zad1.py b/lab9/zad1.py new file mode 100644 index 0000000..a6a2b4d --- /dev/null +++ b/lab9/zad1.py @@ -0,0 +1,35 @@ +# Aleksander Kluczka + +from Crypto.Hash import SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256 + + +def zad1(): + def print_results(text, func, name): + print(f"Function: {name}") + h = func.new() + h.update(text.encode("utf-8")) + print(f"'{text}' -> {h.hexdigest()}") + print() + + def print_results2(text, func, arg: int, name): + print(f"Function: {name}") + h = func.new() + h.update(text.encode("utf-8")) + print(f"'{text}' -> {h.read(arg).hex()}") + print() + + print_results("", SHA3_224, "sha-3-224") + print_results("", SHA3_256, "sha-3-256") + print_results("", SHA3_384, "sha-3-384") + print_results("", SHA3_512, "sha-3-512") + print_results2("", SHAKE128, 256 // 8, "shake-128(256)") + print_results2("", SHAKE128, 512 // 8, "shake-128(512)") + print_results2("", SHAKE256, 512 // 8, "shake-256(512)") + + +def main(): + zad1() + + +if __name__ == "__main__": + main() diff --git a/lab9/zad2.py b/lab9/zad2.py new file mode 100644 index 0000000..8409dc0 --- /dev/null +++ b/lab9/zad2.py @@ -0,0 +1,23 @@ +# Aleksander Kluczka + +from Crypto.Hash import SHAKE128 + + +def zad2(): + def print_results(text): + print(f"SHAKE-128({text}):") + h = SHAKE128.new() + h.update(text.encode("utf-8")) + print(f"{h.read(256 // 8).hex()}") + print() + + print_results("The quick brown fox jumps over the lazy dog") + print_results("The quick brown fox jumps over the lazy dof") + + +def main(): + zad2() + + +if __name__ == "__main__": + main() diff --git a/lab9/zad3.py b/lab9/zad3.py new file mode 100644 index 0000000..edc85db --- /dev/null +++ b/lab9/zad3.py @@ -0,0 +1,55 @@ +# Aleksander Kluczka + +from Crypto.Hash import HMAC, SHA3_256, SHA3_512, SHA256, SHA512 + + +def zad3(): + def encrypt(text, key, func): + h = HMAC.new(key.encode("utf-8"), digestmod=func) + h.update(text.encode("utf-8")) + return f"{h.hexdigest()}" + + def print_results(text, key, func, name): + print(f'HMAC_{name}("{key}", "{text}")') + print(f"{encrypt(text, key, func)}") + print() + + text = "The quick brown fox jumps over the lazy dog" + key = "key" + print_results(text, key, SHA256, "SHA256") + print_results(text, key, SHA3_256, "SHA3-256") + print_results(text, key, SHA512, "SHA512") + print_results(text, key, SHA3_512, "SHA3-512") + + print("====\n") + + msg_encoder = SHA256.new() + msg_encoder.update(text.encode("utf-8")) + msg = msg_encoder.hexdigest() + print(f'Encoding message "{text}" with SHA256: ') + print(f'"{msg}"') + + mac_encoder = HMAC.new(key.encode("utf-8"), digestmod=SHA256) + mac_encoder.update(text.encode("utf-8")) + mac_enc: str = mac_encoder.hexdigest() + + # msg is decoded back to text + + mac_decoder = HMAC.new(key.encode("utf-8"), digestmod=SHA256) + mac_decoder.update(text.encode("utf-8")) + + print(f'Validating message "{msg}" with key "{key}" and mac "{mac_enc}":') + + try: + mac_decoder.hexverify(mac_enc) + print(f"The message '{msg}' is authentic") + except ValueError: + print("The message or the key is wrong") + + +def main(): + zad3() + + +if __name__ == "__main__": + main() diff --git a/lab9/zad4.py b/lab9/zad4.py new file mode 100644 index 0000000..9fc343d --- /dev/null +++ b/lab9/zad4.py @@ -0,0 +1,114 @@ +# Aleksander Kluczka + +from Crypto.Hash import SHA3_224 + + +def zad4(): + def ROL64(a, n): + return ((a >> (64 - (n % 64))) + (a << (n % 64))) % (1 << 64) + + def KeccakF1600onLanes(lanes): + R = 1 + for round in range(24): + # θ + C = [ + lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4] + for x in range(5) + ] + D = [C[(x + 4) % 5] ^ ROL64(C[(x + 1) % 5], 1) for x in range(5)] + lanes = [[lanes[x][y] ^ D[x] for y in range(5)] for x in range(5)] + # ρ and π + (x, y) = (1, 0) + current = lanes[x][y] + for t in range(24): + (x, y) = (y, (2 * x + 3 * y) % 5) + (current, lanes[x][y]) = ( + lanes[x][y], + ROL64(current, (t + 1) * (t + 2) // 2), + ) + # χ + for y in range(5): + T = [lanes[x][y] for x in range(5)] + for x in range(5): + lanes[x][y] = T[x] ^ ((~T[(x + 1) % 5]) & T[(x + 2) % 5]) + # ι + for j in range(7): + R = ((R << 1) ^ ((R >> 7) * 0x71)) % 256 + if R & 2: + lanes[0][0] = lanes[0][0] ^ (1 << ((1 << j) - 1)) + return lanes + + def load64(b): + return sum((b[i] << (8 * i)) for i in range(8)) + + def store64(a): + return list((a >> (8 * i)) % 256 for i in range(8)) + + def KeccakF1600(state): + lanes = [ + [load64(state[8 * (x + 5 * y) : 8 * (x + 5 * y) + 8]) for y in range(5)] + for x in range(5) + ] + lanes = KeccakF1600onLanes(lanes) + state = bytearray(200) + for x in range(5): + for y in range(5): + state[8 * (x + 5 * y) : 8 * (x + 5 * y) + 8] = store64(lanes[x][y]) + return state + + def Keccak(rate, capacity, inputBytes, delimitedSuffix, outputByteLen): + outputBytes = bytearray() + state = bytearray([0 for i in range(200)]) + rateInBytes = rate // 8 + blockSize = 0 + if ((rate + capacity) != 1600) or ((rate % 8) != 0): + return + inputOffset = 0 + # === Absorb all the input blocks === + while inputOffset < len(inputBytes): + blockSize = min(len(inputBytes) - inputOffset, rateInBytes) + for i in range(blockSize): + state[i] = state[i] ^ inputBytes[i + inputOffset] + inputOffset = inputOffset + blockSize + if blockSize == rateInBytes: + state = KeccakF1600(state) + blockSize = 0 + # === Do the padding and switch to the squeezing phase === + state[blockSize] = state[blockSize] ^ delimitedSuffix + if ((delimitedSuffix & 0x80) != 0) and (blockSize == (rateInBytes - 1)): + state = KeccakF1600(state) + state[rateInBytes - 1] = state[rateInBytes - 1] ^ 0x80 + state = KeccakF1600(state) + # === Squeeze out all the output blocks === + while outputByteLen > 0: + blockSize = min(outputByteLen, rateInBytes) + outputBytes = outputBytes + state[0:blockSize] + outputByteLen = outputByteLen - blockSize + if outputByteLen > 0: + state = KeccakF1600(state) + return outputBytes + + def SHA_3_224(inputBytes): + return Keccak(1152, 448, inputBytes, 0x06, 224 // 8) + + def zad1(text, func, name): + print(f'Function from Crypto.Hash: {name}, text: "{text}"') + h = func.new() + h.update(text.encode("utf-8")) + print(f"{h.hexdigest()}") + print() + + msg: str = "" + print(f'SHA3-224("{msg}")') + encoded = SHA_3_224(msg.encode("utf-8")) + print(f"{encoded.hex()}\n") + + zad1(msg, SHA3_224, "SHA3_224") + + +def main(): + zad4() + + +if __name__ == "__main__": + main()