From e3b5eb1a8d7f36c7bde4cead66c94a950d658b0d Mon Sep 17 00:00:00 2001 From: Gabriel Lindeblad Date: Sat, 23 Jul 2022 21:33:21 +0200 Subject: [PATCH 01/12] Update __main__.py --- src/AES_Python/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AES_Python/__main__.py b/src/AES_Python/__main__.py index 949e8a1..9ff81f0 100644 --- a/src/AES_Python/__main__.py +++ b/src/AES_Python/__main__.py @@ -14,7 +14,7 @@ def main(): __/ | |___/ """) print("-"*66) - print(f"Version: {AES_Python.__version__} {AES_Python.__copyright__}") + print(f"Version: {AES_Python.__version__} {AES_Python.__copyright__}") print("-"*66) print("""This is a simple AES (Advanced Encryption Standard) implementation in Python-3. It is a pure Python implementation of AES that is From 80fd0ae43acbdabec6f879a432de5ccf8454441d Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Sun, 24 Jul 2022 15:39:39 +0200 Subject: [PATCH 02/12] structural changes --- README.md | 2 +- dist/AES-Python-1.0.0.tar.gz | Bin 10939 -> 0 bytes dist/AES-Python-1.0.2.tar.gz | Bin 0 -> 10501 bytes dist/AES_Python-1.0.0-py3-none-any.whl | Bin 11091 -> 0 bytes dist/AES_Python-1.0.2-py3-none-any.whl | Bin 0 -> 10611 bytes pyproject.toml | 16 ++++++--- setup.cfg | 3 ++ src/AES_Python.egg-info/PKG-INFO | 44 +++++++++++------------- src/AES_Python/AES.py | 2 +- src/AES_Python/__main__.py | 45 +++++++++++++++++++++++-- src/AES_Python/decrypt.py | 2 +- src/AES_Python/encrypt.py | 2 +- 12 files changed, 80 insertions(+), 36 deletions(-) delete mode 100644 dist/AES-Python-1.0.0.tar.gz create mode 100644 dist/AES-Python-1.0.2.tar.gz delete mode 100644 dist/AES_Python-1.0.0-py3-none-any.whl create mode 100644 dist/AES_Python-1.0.2-py3-none-any.whl diff --git a/README.md b/README.md index 3614696..77a7999 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AES-Python -![Tests](https://github.com/Circut-labs/AES-Python/actions/workflows/test.yml/badge.svg) [![Build & Upload Python Package](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml) +![Tests](https://github.com/Circut-labs/AES-Python/actions/workflows/test.yml/badge.svg) [![CodeQL](https://github.com/Circut-labs/AES-Python/actions/workflows/codeql-analysis.yml/badge.svg?branch=core)](https://github.com/Circut-labs/AES-Python/actions/workflows/codeql-analysis.yml) [![Build & Upload Python Package](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml) - [AES-Python](#aes-python) - [About](#about) diff --git a/dist/AES-Python-1.0.0.tar.gz b/dist/AES-Python-1.0.0.tar.gz deleted file mode 100644 index 5be24a3d7ef404c7c07650beb09b228c8d6a335f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10939 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 diff --git a/dist/AES-Python-1.0.2.tar.gz b/dist/AES-Python-1.0.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..81c49e5c210dff536e46302e9d403930cf9b6882 GIT binary patch literal 10501 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 YLi5**|6h6p9KJ!Zh*nZyBw=Cx4;t<1J^%m! literal 0 HcmV?d00001 diff --git a/dist/AES_Python-1.0.0-py3-none-any.whl b/dist/AES_Python-1.0.0-py3-none-any.whl deleted file mode 100644 index 55dd44411847ace179859315cb4a5dcb3a837940..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11091 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 E1O5L38UO$Q diff --git a/dist/AES_Python-1.0.2-py3-none-any.whl b/dist/AES_Python-1.0.2-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..a1390026527738122536edc8372b650cacb6586e GIT binary patch literal 10611 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.0", "wheel"] +requires = ["setuptools>=63.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "AES-Python" -version = "1.0.2" +dynamic = ["version"] description = "AES (Advanced Encryption Standard) implementation in Python-3" readme = "README.md" -authors = [{ name = "Gabriel Lindeblad", email = "Gabriel.Lindeblad@icloud.com" }] -license = { file = "LICENSE" } +authors = [{name = "Gabriel Lindeblad "}] +license = {text = "MIT License (MIT)"} classifiers = [ + "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", + "Environment :: Console", + "Topic :: Education", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.9", @@ -19,11 +22,16 @@ classifiers = [ keywords = ["AES", "AES_Python", "AES-Python", "Advanced Encryption Standard", "encryption", "cryptography"] requires-python = ">=3.7" +[tools.setuptools.dynamic] +version = {attr = "AES_Python.__version__"} + [project.optional-dependencies] dev = ["pytest", "pytest-cov", "mypy", "flake8", "tox"] [project.urls] Homepage = "https://github.com/Circut-labs/AES-Python" +Repository = "https://github.com/Circut-labs/AES-Python" +Documentation = "https://github.com/Circut-labs/AES-Python" [project.scripts] AES_Python = "AES_Python.__main__:main" diff --git a/setup.cfg b/setup.cfg index a560196..8198daf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,6 @@ +[metadata] +version = attr: AES_Python.__version__ + [options.package_data] AES_Python = py.typed diff --git a/src/AES_Python.egg-info/PKG-INFO b/src/AES_Python.egg-info/PKG-INFO index 5f2b405..8b5e5ee 100644 --- a/src/AES_Python.egg-info/PKG-INFO +++ b/src/AES_Python.egg-info/PKG-INFO @@ -1,33 +1,17 @@ Metadata-Version: 2.1 Name: AES-Python -Version: 1.0.0 +Version: 1.0.2 Summary: AES (Advanced Encryption Standard) implementation in Python-3 -Author-email: Gabriel Lindeblad -License: MIT License - - Copyright (c) 2022 Circut Labs - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - +Author: Gabriel Lindeblad +License: MIT License (MIT) Project-URL: Homepage, https://github.com/Circut-labs/AES-Python +Project-URL: Repository, https://github.com/Circut-labs/AES-Python +Project-URL: Documentation, https://github.com/Circut-labs/AES-Python Keywords: AES,AES_Python,AES-Python,Advanced Encryption Standard,encryption,cryptography +Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent +Classifier: Environment :: Console +Classifier: Topic :: Education Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3.9 @@ -39,12 +23,14 @@ License-File: LICENSE # AES-Python -![Tests](https://github.com/Circut-labs/AES-Python/actions/workflows/test.yml/badge.svg) +![Tests](https://github.com/Circut-labs/AES-Python/actions/workflows/test.yml/badge.svg) [![Build & Upload Python Package](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml) - [AES-Python](#aes-python) - [About](#about) - [Implemented running modes](#implemented-running-modes) - [More information](#more-information) + - [Installation](#installation) + - [How to use](#how-to-use) About --- @@ -64,3 +50,11 @@ Implemented running modes More information --- ... + +Installation +--- +... + +How to use +--- +... diff --git a/src/AES_Python/AES.py b/src/AES_Python/AES.py index 1c7f5f5..89643ca 100644 --- a/src/AES_Python/AES.py +++ b/src/AES_Python/AES.py @@ -220,7 +220,7 @@ def decryption_rounds(data, key): # --------------- -# Key expantion setup +# Key expansion setup # --------------- # Key expansion function (returns a list of round keys) def keyExpansion(key): diff --git a/src/AES_Python/__main__.py b/src/AES_Python/__main__.py index 9ff81f0..f73fbbe 100644 --- a/src/AES_Python/__main__.py +++ b/src/AES_Python/__main__.py @@ -54,7 +54,7 @@ def run(): confirmation = input("Are you sure you want to encrypt this file? (y/n): ") if confirmation == "y": - decrypt(key, file_path, running_mode, iv) + encrypt(key, file_path, running_mode, iv) print("Encryption complete!") elif confirmation == "n": @@ -70,14 +70,53 @@ def run(): run() elif action == "d": - pass + running_mode = input("Please select cipher running mode (ECB/CBC/CFB/OFB/CTR/GCM): ") + + if running_mode == "ECB": + key = input("Please enter your key: ") + file_path = input("Please enter path to file: ") + confirmation = input("Are you sure you want to decrypt this file? (y/n): ") + + if confirmation == "y": + encrypt(key, file_path, running_mode) + print("Decryption complete!") + + elif confirmation == "n": + print("Decryption aborted!") + exit() + + else: + print("Invalid input!") + exit() + + elif running_mode in ["CBC", "CFB", "OFB", "CTR", "GCM"]: + key = input("Please enter your key: ") + iv = input("Please enter your iv: ") + file_path = input("Please enter path to file: ") + confirmation = input("Are you sure you want to decrypt this file? (y/n): ") + + if confirmation == "y": + decrypt(key, file_path, running_mode, iv) + print("Decryption complete!") + + elif confirmation == "n": + print("Decryption aborted!") + exit() + + else: + print("Invalid input!") + exit() + + else: + print("Invalid cipher running mode") + run() elif action == "q": print("Exiting...") exit() else: - print("Invalid action (to cancel enter 'q')") + print("Invalid action (to quit enter 'q')") run() diff --git a/src/AES_Python/decrypt.py b/src/AES_Python/decrypt.py index 64c0751..6caf7c2 100644 --- a/src/AES_Python/decrypt.py +++ b/src/AES_Python/decrypt.py @@ -27,4 +27,4 @@ def decrypt(key, file_path, running_mode, iv=None): if __name__ == "__main__": - decrypt(key=argv[0], file_path=argv[1], running_mode=argv[2], iv=argv[3]) + decrypt(key=argv[1], file_path=argv[2], running_mode=argv[3], iv=argv[4]) diff --git a/src/AES_Python/encrypt.py b/src/AES_Python/encrypt.py index 062281b..2dbe23f 100644 --- a/src/AES_Python/encrypt.py +++ b/src/AES_Python/encrypt.py @@ -24,4 +24,4 @@ def encrypt(key, file_path, running_mode, iv=None): if __name__ == "__main__": - encrypt(key=argv[0], file_path=argv[1], running_mode=argv[2], iv=argv[3]) + encrypt(key=argv[1], file_path=argv[2], running_mode=argv[3], iv=argv[4]) From a12cec343054db4cdd4d6d18d8c2db3011ddc52a Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Sun, 24 Jul 2022 16:25:49 +0200 Subject: [PATCH 03/12] almost implemented PCBC --- README.md | 1 + index.md | 19 +++++++++ pyproject.toml | 2 +- src/AES_Python/AES.py | 77 +++++++++++++++++++++++++++++++++++++ src/AES_Python/__init__.py | 2 +- src/AES_Python/__main__.py | 8 ++-- src/AES_Python/decrypt.py | 5 ++- src/AES_Python/encrypt.py | 4 +- tests/Analyze.py | 13 ++++--- tmp/test_files/data.txt | 1 - tmp/test_files/data.txt.enc | 1 + 11 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 index.md create mode 100644 tmp/test_files/data.txt.enc diff --git a/README.md b/README.md index 77a7999..64a2306 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Implemented running modes --- - [x] **ECB** - Electronic Code Book mode (For more information see ...) - [x] **CBC** - Cipher Block Chaining mode (For more information see ...) +- [x] **PCBC** - Propagating Cipher Block Chaining mode (For more information see ...) - [ ] **CFB** - Cipher Feedback mode (For more information see ...) - [ ] **OFB** - Output FeedBack mode (For more information see ...) - [ ] **CTR** - Counter mode (For more information see ...) diff --git a/index.md b/index.md new file mode 100644 index 0000000..7c64b3b --- /dev/null +++ b/index.md @@ -0,0 +1,19 @@ +# AES-Python + +![Tests](https://github.com/Circut-labs/AES-Python/actions/workflows/test.yml/badge.svg) [![CodeQL](https://github.com/Circut-labs/AES-Python/actions/workflows/codeql-analysis.yml/badge.svg?branch=core)](https://github.com/Circut-labs/AES-Python/actions/workflows/codeql-analysis.yml) [![Build & Upload Python Package](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml) + +- [AES-Python](#aes-python) + - [Installation](#installation) + - [Usage](#usage) + +Installation +--- +``` +pip install aes-python +``` + +Usage +--- +``` +AES_Python +``` diff --git a/pyproject.toml b/pyproject.toml index 1c4583e..d4388b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "AES-Python" dynamic = ["version"] description = "AES (Advanced Encryption Standard) implementation in Python-3" -readme = "README.md" +readme = "index.md" authors = [{name = "Gabriel Lindeblad "}] license = {text = "MIT License (MIT)"} classifiers = [ diff --git a/src/AES_Python/AES.py b/src/AES_Python/AES.py index 89643ca..dcf322b 100644 --- a/src/AES_Python/AES.py +++ b/src/AES_Python/AES.py @@ -462,3 +462,80 @@ def cbc_dec(key, file_path, iv): output.write(result) remove(file_path) + + +# PCBC encryption function +def pcbc_enc(key, file_path, iv): + file_size = getsize(file_path) + vector = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] + + with open(f"{file_path}.enc", 'wb') as output, open(file_path, 'rb') as data: + for i in range(int(file_size/16)): + raw = [i for i in data.read(16)] + tmp = xor(raw, vector) + vector = encryption_rounds(tmp, key) + output.write(bytes(vector)) + vector = xor(vector, tmp) + + if file_size % 16 != 0: + raw = [i for i in data.read()] + raw, length = add_padding(raw) + + tmp = xor(raw, vector) + vector1 = encryption_rounds(tmp, key) + vector = xor(vector1, tmp) + + identifier = xor(([0 for i in range(15)] + [length]), vector1) + identifier = encryption_rounds(identifier, key) + + output.write(bytes(vector + identifier)) + else: + identifier = xor([0 for i in range(16)], vector) + identifier = bytes(encryption_rounds(identifier, key)) + output.write(identifier) + remove(file_path) + + +# PCBC decryption function +def pcbc_dec(key, file_path, iv): + iv = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] + file_size = getsize(file_path) + file_name = file_path[:-4] + + with open(f"{file_name}", 'wb') as output, open(file_path, 'rb') as data: + if int(file_size/16) - 3 >= 0: + vector = [i for i in data.read(16)] + raw = decryption_rounds(vector, key) + result = xor(raw, iv) + vector = xor(vector, result) + output.write(bytes(result)) + + for i in range(int(file_size/16) - 3): + raw = [i for i in data.read(16)] + result = decryption_rounds(raw, key) + result = xor(result, vector) + vector = xor(raw, result) + output.write(bytes(result)) + else: + vector = iv + + data_pice = [i for i in data.read(16)] + vector_1, identifier = data_pice, [i for i in data.read()] + + print(identifier) + print(data_pice) + + result = decryption_rounds(data_pice, key) + data_pice = xor(result, vector) + + vector_1 = xor(vector_1, data_pice) + identifier = decryption_rounds(identifier, key) + identifier = xor(identifier, vector_1) + + print(data_pice) + print(identifier) + + result = bytes(remove_padding(data_pice, identifier)) + + output.write(result) + remove(file_path) \ No newline at end of file diff --git a/src/AES_Python/__init__.py b/src/AES_Python/__init__.py index cfbfdfd..0065c30 100644 --- a/src/AES_Python/__init__.py +++ b/src/AES_Python/__init__.py @@ -19,7 +19,7 @@ __copyright__ = 'Copyright 2022, Circut Labs' __credits__ = [""] __license__ = 'MIT' -__version__ = '1.0.2' +__version__ = '1.1.0' __maintainer__ = 'Gabriel Lindeblad' __email__ = 'Gabriel.lindeblad@icloud.com' __status__ = 'Development' diff --git a/src/AES_Python/__main__.py b/src/AES_Python/__main__.py index f73fbbe..0588c58 100644 --- a/src/AES_Python/__main__.py +++ b/src/AES_Python/__main__.py @@ -28,7 +28,7 @@ def main(): def run(): action = input("Do you want to encrypt, decrypt or quit? (e/d/q): ") if action == "e": - running_mode = input("Please select cipher running mode (ECB/CBC/CFB/OFB/CTR/GCM): ") + running_mode = input("Please select cipher running mode (ECB/CBC/PCBC/CFB/OFB/CTR/GCM): ") if running_mode == "ECB": key = input("Please enter your key: ") @@ -47,7 +47,7 @@ def run(): print("Invalid input!") exit() - elif running_mode in ["CBC", "CFB", "OFB", "CTR", "GCM"]: + elif running_mode in ["CBC", "PCBC", "CFB", "OFB", "CTR", "GCM"]: key = input("Please enter your key: ") iv = input("Please enter your iv: ") file_path = input("Please enter path to file: ") @@ -70,7 +70,7 @@ def run(): run() elif action == "d": - running_mode = input("Please select cipher running mode (ECB/CBC/CFB/OFB/CTR/GCM): ") + running_mode = input("Please select cipher running mode (ECB/CBC/PCBC/CFB/OFB/CTR/GCM): ") if running_mode == "ECB": key = input("Please enter your key: ") @@ -89,7 +89,7 @@ def run(): print("Invalid input!") exit() - elif running_mode in ["CBC", "CFB", "OFB", "CTR", "GCM"]: + elif running_mode in ["CBC", "PCBC", "CFB", "OFB", "CTR", "GCM"]: key = input("Please enter your key: ") iv = input("Please enter your iv: ") file_path = input("Please enter path to file: ") diff --git a/src/AES_Python/decrypt.py b/src/AES_Python/decrypt.py index 6caf7c2..82c7cd0 100644 --- a/src/AES_Python/decrypt.py +++ b/src/AES_Python/decrypt.py @@ -1,5 +1,4 @@ from AES_Python import AES - from sys import argv @@ -13,7 +12,7 @@ def decrypt(key, file_path, running_mode, iv=None): raise Exception('File is not encrypted in known format') if (len(key) / 2) not in [16, 24, 32]: raise Exception('Key length is not valid') - elif running_mode in ["CBC", "CFB", "OFB", "CTR", "GCM"]: + elif running_mode in ["CBC", "PCBC", "CFB", "OFB", "CTR", "GCM"]: if (len(iv) / 2) != 16 or iv is None: raise Exception('IV length is not valid') @@ -22,6 +21,8 @@ def decrypt(key, file_path, running_mode, iv=None): AES.ecb_dec(key, file_path) elif running_mode == "CBC" and iv is not None: AES.cbc_dec(key, file_path, iv) + elif running_mode == "PCBC" and iv is not None: + AES.pcbc_dec(key, file_path, iv) else: raise Exception("Running mode not supported") diff --git a/src/AES_Python/encrypt.py b/src/AES_Python/encrypt.py index 2dbe23f..10b0cdf 100644 --- a/src/AES_Python/encrypt.py +++ b/src/AES_Python/encrypt.py @@ -10,7 +10,7 @@ def encrypt(key, file_path, running_mode, iv=None): # Input validation if (len(key) / 2) not in [16, 24, 32]: raise Exception('Key length is not valid') - elif running_mode in ["CBC", "CFB", "OFB", "CTR", "GCM"]: + elif running_mode in ["CBC", "PCBC", "CFB", "OFB", "CTR", "GCM"]: if (len(iv) / 2) != 16 or iv is None: raise Exception('IV length is not valid') @@ -19,6 +19,8 @@ def encrypt(key, file_path, running_mode, iv=None): AES.ecb_enc(key, file_path) elif running_mode == "CBC" and iv is not None: AES.cbc_enc(key, file_path, iv) + elif running_mode == "PCBC" and iv is not None: + AES.pcbc_enc(key, file_path, iv) else: raise Exception("Running mode not supported") diff --git a/tests/Analyze.py b/tests/Analyze.py index 80bfe20..d40d297 100644 --- a/tests/Analyze.py +++ b/tests/Analyze.py @@ -1,18 +1,19 @@ -import AES_Python.AES as AES +from AES_Python.encrypt import encrypt +from AES_Python.decrypt import decrypt def main(i): key = "2b7e151628aed2a6abf7158809cf4f3c" iv = "000102030405060708090a0b0c0d0e0f" - running_mode = "CBC" - file_path = r"/Users/gabriellindeblad/Documents/GitHub/AES-Python/tmp/test_files/data.txt" + running_mode = "PCBC" + file_path = r"C:\Users\Gabriel\Documents\GitHub\AES-Python\tmp\test_files\data.txt" if i == "enc": - AES.encrypt(key, file_path, running_mode, iv) + encrypt(key, file_path, running_mode, iv) else: file_path += ".enc" - AES.decrypt(key, file_path, running_mode, iv) + decrypt(key, file_path, running_mode, iv) if __name__ == '__main__': - main("enc") + main("dec") diff --git a/tmp/test_files/data.txt b/tmp/test_files/data.txt index 6f785a9..e69de29 100644 --- a/tmp/test_files/data.txt +++ b/tmp/test_files/data.txt @@ -1 +0,0 @@ -1234567890123456789012345678901234567890 \ No newline at end of file diff --git a/tmp/test_files/data.txt.enc b/tmp/test_files/data.txt.enc new file mode 100644 index 0000000..fe6b2f4 --- /dev/null +++ b/tmp/test_files/data.txt.enc @@ -0,0 +1 @@ +Õ”?еÉÄçQ«s£g‰FesoÅ~_|éGÙ*\ \ No newline at end of file From 4a596e4a3fcaf0d9ed1848e403caa5732ee8610f Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Sun, 24 Jul 2022 16:26:53 +0200 Subject: [PATCH 04/12] update --- dist/AES-Python-1.0.2.tar.gz | Bin 10501 -> 0 bytes dist/AES-Python-1.1.0.tar.gz | Bin 0 -> 10375 bytes dist/AES_Python-1.0.2-py3-none-any.whl | Bin 10611 -> 0 bytes dist/AES_Python-1.1.0-py3-none-any.whl | Bin 0 -> 10070 bytes src/AES_Python.egg-info/PKG-INFO | 38 +++++++------------------ 5 files changed, 10 insertions(+), 28 deletions(-) delete mode 100644 dist/AES-Python-1.0.2.tar.gz create mode 100644 dist/AES-Python-1.1.0.tar.gz delete mode 100644 dist/AES_Python-1.0.2-py3-none-any.whl create mode 100644 dist/AES_Python-1.1.0-py3-none-any.whl diff --git a/dist/AES-Python-1.0.2.tar.gz b/dist/AES-Python-1.0.2.tar.gz deleted file mode 100644 index 81c49e5c210dff536e46302e9d403930cf9b6882..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10501 zcmbWdRZtvU6RwK~cXv&2cXxLS?(PsE_}~fd7Thhk>);j~f&?Gj-G`a|{rl9ZI@hP_ zz37XzRi;@FLLo&Gy=mP{eeV4ee|Me#?#P$^O}yqZb>?k55&-Sx z5_Q^z6a|JtavScQ++vh0)D99?E?s`f>72puiWscb+w<-S-7Zhu1rl_6eBN z3Qe$USg7ao`U8FZ2i-6I7<|7UJYIpib@V7hbB$!I-*+4YjMbI_b$`QO8dA=oL_qaK z_K_xA#qq4%sF|UDk^I1wM>T3?c|%?@3(6<9xokv`0oAJkDB|IB=CyG>9jp1KqDJBo z=-*PlE;M;#ldqO}9-sgDE^rH)a!*fE|t z*s@gS9QMWp4+w1nj7}qXt4F=I1#%FMBsbW2d= zV=-GjU!0Kpd-?eWz`4p6NN4DT!x8LY5u@K3mvtk??%t2zOCe~Hqx&Yot_kT^=tq|q zfBi=EYaCiA3SBaahqj4A04XoP4sVEkZA*sp(^nEG;APL1Ky>T$&nPtCttTr7y6}&J zEeUE)56KF1I}0=Wz_HRm-h3-DT;fN&evG+@GZ5rQ(-MzCiG*pHlzl$ZRZRDt5!vFR z7A6;r7AVwa494Utt`4*_G)Svv+vlXDRb=pDL(aDIIDQ;84n8nkj2`@HJ(W_I3u<7l zCS>^NuwA>F{!Maq5Qv;2xOf#eLM)%YTZ~?cKQ~&``F4BJ$+6vqC-j%g0f-V_z0o?Z>cYb9PZW2~Cdp=ob`|!0lP8{uF_TSEv&)Vw0~!%qbaY z(da4u3@@}d1wwvvX5Je|Sv>qSn}67a*$f+ZH7q&U#>2^BVPa`LOv_55!FM6N$#DFvo(Cbro+qr`zhy z-~(`|D%;VFej7og1l+=i3Zp%z^kp#mcseBnPPn;inA!K8zLvZD>Cc-98r) zRyzjDVcP4>z(G6`&E2uS1|&BE$|@gO5#DB_(NkD*Xv^SG4u$FF`8QbNQCV6Ti5ok4 zP8}WI2|?H`;hebh*O7%_XZ{$co&Dd*jaDrhJg_HUtYqlD-~T-pm3}_K%r4)8cB98s#rwu4;)fN#Uid`s^~rwgN{7YV1jzWoj>IBrGxYCx6nCpf&5r6 zrq9p+Ls zQdknjkbPh}!3GYauvCe|wMZpD7++aRgyB;TEWNEDXJdIA4?-bWcyYK6EsSXwd&?Aa zOl<9B{(aoc>llaidH90}$c%{tQrmg!HuPeVc1HVL6TH~ji*|c+@nmKGjX(wTwVjRQ zsj9{S>O1&;GzXRb^Z_A7*($W zNW}pMkG08~|vpxp@fW*rhShgS$#?nkX0Q_(-?|_0@vjzZP-; z4(W!2Y_gNk?^7(rxu+GPUng$P$w-d&fkEJ`0O*eMe^G-!SRlVvvVyP^?_F*TP^S)h zPa-@6)aC%8fShx$$cW||jRyAyezbxBE+*d*+l8z_7t+r9O8{`m^)KmYETc3s$0cq0 zLF`FCO=}b=W|41-Ox>o4XyKbFb4s{TB4$K11!`f&rWDFI%t`Db>RAyp`%vQP7u%|u zyLTc|{3gfl$%#@SOvS&BAFyrDJ2akirg55Jj4C}eKrsY(YsxlcXppT5c5ShcZHPl* z!W@fa6u-O-Y$}PBfPlo9yTSQ^>3uKVVp9P_e=d&GG0dAKD%D-z4a?h*2!G6W>ZyEI zER*!m^xBWYJFEWXXGEu;O@-BV!_@V&BwLe|4>r_P2EAwNC)KMH?Z%$!dmc%`_X>{ zgYllVo6{;p*$!97if&=zD%mHP1EQ@+{#s(LTJZ87xJgZSI}X9enm5Hx?}RBoM#8ue zHZJO7xuwd(ECn$P()e9)`;AD*uxexyGQ!As(Isrqpo<;pIAW>^$!mrQMC^q*z6ysR zaW3b--WUllw!{mrcKcc&bC+d6W*@QRE6x!;+xM+-vw2vEqr(Yp-vnUv0t(JCFi212 zNgl#Rv3aFBJpa+E0$0WCPn5nPbsr$e$UNg!>DqBdNC=juC>IJ@G$oKxD1dX&iQ#iX zcSwv^|C~OR1r;$BbMhoTKt}#6wvT5j0f=!oq-S+%6#yvTm+%VXvkv;Ox`vX@xQVnt zda8Zyp8*^^klZT7-D(H?2rVPmUV8lUd09DO%XD5{Y;D+8Z?n?*NM?_bn6P+=W*eJ= zzU!%pj$o+|nXasv3@a$!lo9`ARfbeXnqOisNKjOB(!?1$3Vzuj!l1u27#f4+>mSjyK5lO2zpKO$Wa8H+kk2;{pt&X0vpC5$L~Oh3Mt|8U*3!fI44DY=+#~?7qDM34fXh z@IY7HyaQjsJ1QnSu}*J8GggUya@gDK2aA!#aqf`tT#xn}Bc%RE4iekw(}KLt@2LVs zhT%u^0m&7eOJZoNFE1?0`AM6fZiy^~UXZjG_w5D?6P`S_{ze&5=z`WK#$-D5!gdOz zfMRbHd)J*YK-2E)#M{-AUH95BAV$Jsbx_(L6)+!@TxGgh2QDp_x9S>g@)*DEFWs0$ zk@Uri8f&-)o%;2Pz?yPAlnvPm^;5Cvm7mG+#4vhW75aQVvRqKyP_7IvWYxGqom%>j z#A-dUH@=Q4^eyLnWTgmZl1&e3tN8}`(GC>7h)`FZ4N_fgI-`y%*VHS9rYfZ_I^|P_ zWNexCP7K*v`2pT543PH^ZEv`B8W^@IzL-dyRR+P->*^2VOJt=VscKFZ5lnO|e5WC* z4hrcTmaUQVMejH%^PrH@2mXv}Y@&G2$Pt@?NaMgM#uyFbTm_A2q7b`bn-c}x@kQ*#4OC zEh8!IDx{a-_@&83hLEummLkX4m^Du~CVLTaucFwbRns3JW$;$d2$y^3G|3+EpJUY? z_{K-(3@FP!n>yVQI`e<$U#P_U$Ig?MoP?51U(&7HJU%pg86y%RJ1Hi;SQf6vT+)$S=HoCX8w0p)6GHM=1GtSgMy3q&tx3DMO*TRE=s|Id%f*wHiET|g!!Uulm@uW z0J_$RqDC?r$D(Dj;&Asr26E}CPwA#H0n?gx?sTnM7yj9f7RUn9Y@b$KBNJiPdT>Z8 ze18x9R*CK7!gUjWnM!EXFeo)RleFiT{sbEU#9?O2o=niRH{ir6k7euuiy?8d&tC*W0ANDRdq3 zZ?m9Tj_@ZCWG0;Zx`-PB1D8{N3%M+=o2pphoTC^VB+UDU?QbF1k)Pv|>9*6ltmCmK zsFf<=e?uQiOh5$4_S%cAP}7rRD7sDRUv#ghH)Gi*EuYw#7^Q_WAs*Z)ezhEvulj;< zhPUFEzqmfqIJ1i#YdV=(A6|!zvSHiUNLI|?@Fh<=Yb4V&qAar!O2RYb>4GAdXGJ!F zT5!WpUU#yL%m3rTe$DrM`HRbVdli+S7fIT3lbU_R)KUAY)={)fI(7`|c_%{vxp@>lZ6 zg4?sU`;C4Khxt?L#pi)nxeL@!pU5nir!AAc{;>|35>&WHvNx(o4``udsipHQfo^K; zKljdbfTr_>I-|m6?3rB%MT01#=ajDT)U%u37_M^9#1rrEa*S{LRwnRWK2x{jJsYow z|1-;5KO1}A`cNH=K7Kvg}IR(r~85~4r_CCgT%%%1;IFOz7eTv@*CJl zHPc7adtt%TV$SfsT?L}nu|lLS8Hd-JZ$11B2v-awx6P}%Y-wD<4jLI4)f?YE@kw_n z8C$L4Dcxy52kaVRb&|-w7teHZeIxFanPuKPTSKSFGKl16uj_v_eXmg^lQ4LhDXA1$ zZANfuE+6(`DKYIgl9ol~(~0oNL7tW6MkbQ5o4B#Z%h1Bf`l==JT}>x>GsajbDSOt! zXNkO7Rhly8E6&0Li1OU6|eoo zz0y9%SG1E-3+vZUz%QC;n}1ehj6`qNN?!Lod@6Apau!*wtV?aGx@*f=i^F{kLI1jK z5jDKt&UNmm{E!x>1Pm9?Mgy;w16Zu zh7(o4VbbLnl@Ho*6^&2~>X4OKQkvTDloP3{U--xsp!)Vtn?NaJ;N19M#E}VUiRqG)+OqLx+nMCs z3g2a%x7`OQySsItS!%5xiMX_}e9x4p8!b0#m9-xCi#(?<%z;F@wHb`btnPfKo+4;Y z-+{e0nV!eExa~LG=U5VwC4_H8YhAMw`)$241LC^-U@Y-BVaQu&!|a_?54AeBVpzH9!D~x z$7eK2iWYCQj)+ZbiNGJ_q3D|VnWB(?5RY!74^hVHBksv}srv#9I#K$o^e78*X4Fc6 z2bKpNH!B@kum2Js?SoNHko(1g8l?D6(wAj;>(BIq^GtbP2gUkyWZqicGD?KD?jQW8ELh3hMl_Si&&~aK3k%TCbRJiu zAH*4r;Ycwwf{Tks-1kob-j$BGuFlo-(u$_xPhTy0GcrtysL5g~wy!gY;_N}mQE)5| zFQ=~UsjlL!9%u+tYPXk6x(($oj;)*pfNG`d_@<|lk%U=W^j-aR*~6KBg8XePVZ_v>$wsb~h581inr3vRwVXQl z@=MqS+{DU%(oU{BN|SVhotTB2P^affp{Mz}(~~%Tw{&YoiIjF)V|CfN3SU4o1#i1CsXv-t|(NB{IyAnya0T z1(GCV13hO9`{9}gs$tlWyh+TpEC{Edb+qirO50gVX^E0XS0jDC@qIvZ8}7~T-Gp1F z7(OO#ooX~7^AvDQ=sfZ^b``}(KsQw_lD~f7F_!tsF*H3Y#&CUFUEZm_KMQ+@lU@UU4wAfjCtN2_VV{D}%=5Ie4Scp?PiguF-Lh7aY zCkC$!;$PK%HT5pSA&CO%v^1Im8tA=c%&D z5?N?}n8;B^KF_)?%SWUC63JN)L-hJ7hQvB1R#&XFoQK*WgCuYANdX1~Y_zd!4PAxb zMf`D#SHzOv1^Xdak{Tg_%NOyKsR+dHlD%v?+r(iaNGsbE!2J>^#j{rti9MAy1JOge z!xbN=BP#0Yi@#`GM0DkDo7bF%u%BodS1O&K z+*Koh8~>-5H#{D}(OIQY3Jv?kw{S_% zN~Cymrt_;-c5Av6?byPm;mn=d`9D-;+s&NE*CjZRwa zsVc|PUJ-wTK0vwT%ND8_rc6u*YY+=YgjimxDskw1nAW3@46x;a3*9+7#E)0TYL?@p zU4^ui#>T4`g)6^oMxb=HBwG@%S7Z^TFq$PcBe5y~+n&uy9KfH5I-Vz>_LuC++LK-+E$64S}D}` z-_o3Or^q>jesRtW5C~{B2p}BBryBv4#PEpG!Fv z`KfDqB!Fppz1&Ns0mD`ZhDWIG0zz}Qqm=g*lge_}lT)sL3OKtwkS16#X(dB-DNkD3 zf)j`&Z;}E_?@%9@G~?)hFD0w^n68`pzS@#X16!>XpT}~$3(sY89 zW;fjZo`1BfajD?>vuEUcy9X+3Z2(H?3%PUii5l@dw+hZ{sv<^MQW9#D7a7_eB$B!~ zqb+N$BPXeIlYrl|sclM&T`w2^9TsGDWz_y#>lnGl=b1?gHG;$`LzNz9oD48DVLO=4 zfcArpnZtf+kv-5!Gu>g@J|^xi829eO{6F=Ff0!F3*o8pM`=Khm&_5myLi(KKAyc0@ zlP;i}F1)25g~k{dQ;zu+|1&83V`>dpqrWih$1&o6!jKrRAlvkWbN`iJPi#1NC)2I6 zN9t)gU)_(*{#!UYN!)Wz810;UstuZ<5-7IMUNM`Q&|Y%H&c?_VU6pup}I z;D*zqus^tP92)adIQRY%eha8va;*LU7$+30l)eBLX7-_3oen8lpdtYR+h`HN8ilqN z>yo@!iD9p^6lp+EqRQO{&UVs}m-3$X%kuF0omJaQ#Rl7#G|`^|cuV6l-OD>RMt(`q z<==K6_Ajp)_kg;4s;MI0+m`N1Xs5EN1+yq^uelt`9=E(Qi?y26b4|R3)kw1E3eNEy zI#o!>*k+*&j6r+-&ECB;J?sRo#J!lb1vA&-s^!nTChl_8&4ybJEkpIz5==pa63p90 z_x!GV79N;pX3%OOR~n4vLU*@$-l=(rmT`f>%W8Ib6k2x&_$P9FoP?LbHWAb;1ZmHm zMXQp9J{kik7E8z&_i0FcbOE#uD{w_bB)7@ui9cdJ<$;|SGjF*YW#Ay{uu$p$XFR(a zmWgtO-ekPs2ctgboyRpf@%}=%mQjiOZYNQr5L0L?rx;~|G!J-0Gd(&sM~ksSHexW`_vX zNVnPg4Q<&ZqA_zOhmC-(Wc>_`-eU-tF`*?c)#icg%`=#>jg)ibD`v!adOmv(e1H5H z?t5bbZvX{rfm;$<209#KOM;s!xx=G3oPR|b89 zyyDtUCoVjSC}GzS*Jat4nCBTTjzZ*q4jlV$89FpLeIpfa^*1xQyVHR+^}{PTSWE3l zQ%=NXMwW5bER*avqK_8;XFxq}C_hVU5{y8p`l}&Ur79V#6UHBBYsh&H;pFE08|VqI zSQ}oO8zCUb5Mhr+Ul!*83z~OFl`IX04>#z2L&udr$JWAv}7To@mHOzuS!1VtBUVRq?nFSP&SJdExW> z>ug>gCCszZIPt_Un&@zau0GOcs}JubUcnk65Cw5)ixWh_e@sId{vhR*s%~Sd0J^d8 z>lHjl#Ra7Uy^?vmf>Hj73eU?t*I%y$1^P6)Jf5ef#%$SBVs!a>SVzC;C~rO@4iQLg z8zpq6IrliKIk#;AhuXH}jL?CNe9OCo$+EVmk2K3DKjv=d39T-T$NRn`0RIM2U@@sI zxDoh(WwRBwK-%Z}2yQ0ZPG)t((Z)1Yhal81d~}gel5j|}EV5qC(AU;d;`+E=nY@YV zD8y?L=A;l4Ih$4;buZm%_#+zyQU0eP)AGpM7|Jlvyf(1ZxGf+8lC#4a0B#sOU)bNfK> z+b~Gt5Fh9OUcGWeyEU)P9|r)u!Oznt?z^I5Z-G>o ztk`K>tLMt3>AP2;DCE!op0VBsp7uun8J^Mj3+1~t4}t^+LEI~I0nppWH30Gx(FK5~ z1Il3q?a)341a8&o*R}n1^l2CABAU1asF|66y*)2@`*H?oSPk5S2y7U&Y|*~&z<*pH zy#3d#{GmV#@Z8gXJ?z^%&;lv}zG)A5fZROXkN;nc-UQ7zE6o^(a(L!XNRCHs{dJfO zZmDo3+&;%!Cu;I=AuI{PO`92db>Uv<^EVG#6sXRPGJSjM;2;!lA^>1W)QFkgX0^?su^E2l(u8unG{5KDC)j+;-!#*fX%}8m_`-ycoZrZtW^; zEakr1S?;U^7xI5PQy{;19zA_cS<6=!d&Y!$(m_{W70L(U5D9(>{C|)*+;_^ck6?xZ z^E_4wk1N(WpJWUJ?;W3@)!BhwkIKxju85oaNbml)qo8nuB%k8|B(b>Bzi8;4&SE`q z3zuv6_FsRyN&sV5)>!jybI|+G`ukr(D)r7?2{Az&{j~%6FvNO&MZ=PCuh`2{`)+E_ z1#;)J+^_??G&c|ZoQI}mIDch~9D;*dCHw&5n&W>N4jfx<&hDh&!T@>!&G;++mcPx% zgUQC)1Fu&-|3v%?vRYN>_Gfd3Z21_P^mlLO8n!b*XvNiCiCPWXz!7ena2(f;b%G5wcQxrm`r@8q zIh$Ir|1SvNeI;tAAZ)=+vP}7YCB~jx_&V_J?!Ni%w5z`tW~9(6Lw8$89{iTR#wShm zEPP$Tm4ZBg)tiGe5BnogsptDH(n(rZXMqO!R)<|$)ze492;qobVSD9-%M^|~HLmL% zPCns)u>%aUIA_EYBYe2%WCKl#)5LHB`y#KklqN~|&vfR-R`X~T_xKxlMliY4q&nT6 z9T`$Hl`uk5ZE*s#`bmHG_E&gIFGn3aATXAHMbbsG7ArQk(7*0=+sX4e30X1KKG85q zqNn*p6+WNzu=YbmJFy)}Tw&ghMbXqL3s1Gv_wQf^ow$ev=q)UHzsc5M&7P#vbyg9* zX!w*KFD7?;$@lhugga>H6Z@~0@|XhONK<;Z2azhoi}Hqb)f(~CAdfeMIo1KnCp^VH zSkXH7gwR*X4g&Bsl(UI3j6aThlJY7*dLzw*wOs^U=H{r|Og3dI#1xK#y_d-x01~BL zB28kTc-}4V$SNceP~^D^O+X)DldR@uW(`4>M)$gnfD?7dz+@yFN(t5Lq(}8Q74!#brdC^3NUP-pm-)v z`v-#Y7UuuPU-6W?&qf>gt;NEHuvy>4$7BtNqLM!wbLqn^RtTLO2mEgwe0bhV99L4! zJ$*WE+ogHgyax1`vhhHdTxGPyq4#iEr1XTdNIjpvMEo0JRXyI5_X-nfLh}w+pCLA{ z?K$mDHlz)8?jh8{BU2#Mzh=@gco+9A34!lD*p%Q1%7MWjjf)MuyQbXv@iLVzFio04qc)j}ryuA)&rWZ%r z#HrrG_g~%~m*|R`_yGLhtLEl$P>oq#28`uMLHwaL`aaLXB9?p~gm6Q1cq7-q&O0 YLi5**|6h6p9KJ!Zh*nZyBw=Cx4;t<1J^%m! diff --git a/dist/AES-Python-1.1.0.tar.gz b/dist/AES-Python-1.1.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3a22a7846a5b1293714773b0488ffa404c9db36b GIT binary patch literal 10375 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 ZpnULi+W$vASoJ`u+nzj@V5DGS{s$HQW!?Y) literal 0 HcmV?d00001 diff --git a/dist/AES_Python-1.0.2-py3-none-any.whl b/dist/AES_Python-1.0.2-py3-none-any.whl deleted file mode 100644 index a1390026527738122536edc8372b650cacb6586e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10611 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%0Ak`*NC4Vhgq^>4va-%LLWi0 zVLlec*Cjc_ENwhk1X!(T_AEB#m2h?c@G!%w*FTS-U{YQ2M_|{h>`ER?yD&DbNEpyM zaq7`p?VWJ@aBbO$)yE0pYGJ&<{`*ik@l|*?d|y6 ztt>}RMu4ZInJGBPFB8ePyI;~`i0b}tHo|Z7nDlQZ3@nT+jLeLtRxSVrD|>SXCOK(Q zaRpUzJrx6o6=r0A$!)$&59^}RjK^lKq%>oONV37?OG{Ky{!r|G^U@7J_rS(ua`N4_ zr`F-gfMT|tX-Z^)v@OI5Hw2iAC(G}fVPx2rN>=atrk6+*FTy=I3i=N* z?-&8F^&gw>K1K8k^;><0 zrFhtvglUvCk=mMiM8BKeU>7@^te^8RP|Y1_0G3p1cm-|LgtV0bZb;W~=cs+k^9H*v5rhzzCB`^tS@L;lj1$n-GpT2Iw zbZ~LJ8ivGt#UHi?Q>57_xh(s=X8cRO#{)Il`)`3N;Z43||14j5aW!EvVKw2bBzc!v z=C?)4PYiDxJ`+Af9*`iw5IGcUArTsMRSc;en({HYv|E9H+(|tRAvWulVO;&w3EiRI zA+EsQ-0TUS4plwr1uYRJml|oHw6eK-k3)mZyJe&IV@yePsfjC7B#!U55Y-WQ(4&?O zeIW9#)tsy!AYrU%lS}zeQAK+6+3+Zmc;C?nDgx{vHENKfc3SiC*9AkbL=S=uQ>r{C z>f2>7gYul6q8EV}{PLUp3XF+-<^IIL<;A_AZVQI#Da7KMn{{qhY}=5Hg<}mfW{lMN z_vHsGh<<$5iiVLAd|M5OuM8}+74Pw1(NmbP2^;pRTzFzP?tDpojb{9{bGAuR-M~9) z=WIn;D@$Fr^$qKPF7u0QHfHvH!!FM#mGoM_m9a-$@xX2fWaW-?Hh>2%Q3qd^_#iQ< zkyU6^LNf5oj~td&H_u4aaB5$qyS~4fnVx8Np;@KCQnNc+noeE!p86J{}mH+O?44QH&*iD*fi{;_B01|bmRSjQX?FtzD*pTU z{HT_GAD!>X;@-o!Jq4Dvz*N-DrFMFDvlma9{t zrlFPJgOiqPQlTzoUl<>ql%1C!E8pD)`y>9wNbW~4yemj3e~aG#~ez0f--wO6iA(CRJY@W4qR?F?jeGX_WR?eo_x&a zX&g6PqpRg^5|8w{s@F_AGB>l`EjLxVZOT*dec~!rZuOl+pKKje<`7QVi`l9p4>5v^mccNtQ=du5`$*%)Z~}*09J7ht;`yVD zxq5@UyWwkwmkkPIC+qrYyUwPcgeuThd}T#F)6}9YNdS%~EFMC<%b6vjwI!5kr2I_@T7Kb2kc$qc(5DLy_iaLFp4WL`%@=0Ml- z(t-uT=V&R@TjFMzTd=%)I0K_{?sJm#MQLE=2)=*)L&>Vz?n9w9qWHFUpY5rQ>9dFN zl96X7HlE?PGBHhW3xLaAE%VnGF`M?jGwtvfwyzXPutze*E{K=dO!geEruEYpVuqVa zl%jh=^;}eZAxL;7f-9ZhfJbPUPCBI8B2cl~^Iq<^L!i21{fu?(0`g<1EH^b6-<;=` zB&&0@l=|%7tx#4Qbp@gMP}1w=j6@P^=3+hYW*zl!P!hB?OBXs)zBEI{K*cSk#YDHi z%=yFCSOufTSm^Z(Z1`d?!Zkj6lYw|2yD=D)SO zerNo*2F5Q&je!$N3xLS1JEH;=dJ= zzYwFie?$CVS@}EQzm=8006+f*`2UK`KY4%V`Cq&ag5NLbKY0I__5TF^nGt>gcZvQH z_^}f5 Y+e)&KP=A>qyuG~Nf_?vAl^4kW08YUV%K!iX literal 0 HcmV?d00001 diff --git a/src/AES_Python.egg-info/PKG-INFO b/src/AES_Python.egg-info/PKG-INFO index 8b5e5ee..d74a3d6 100644 --- a/src/AES_Python.egg-info/PKG-INFO +++ b/src/AES_Python.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: AES-Python -Version: 1.0.2 +Version: 1.1.0 Summary: AES (Advanced Encryption Standard) implementation in Python-3 Author: Gabriel Lindeblad License: MIT License (MIT) @@ -23,38 +23,20 @@ License-File: LICENSE # AES-Python -![Tests](https://github.com/Circut-labs/AES-Python/actions/workflows/test.yml/badge.svg) [![Build & Upload Python Package](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml) +![Tests](https://github.com/Circut-labs/AES-Python/actions/workflows/test.yml/badge.svg) [![CodeQL](https://github.com/Circut-labs/AES-Python/actions/workflows/codeql-analysis.yml/badge.svg?branch=core)](https://github.com/Circut-labs/AES-Python/actions/workflows/codeql-analysis.yml) [![Build & Upload Python Package](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Circut-labs/AES-Python/actions/workflows/python-publish.yml) - [AES-Python](#aes-python) - - [About](#about) - - [Implemented running modes](#implemented-running-modes) - - [More information](#more-information) - [Installation](#installation) - - [How to use](#how-to-use) - -About ---- -This project is a way for me to structure and work on my gymnasium project where i implement the AES encryption algorithm in python to the evaluate it and write a report about it. This project is written in pure python and do not use any external libraries for the core module "AES_Module". The project and the code is not intended for any use outside of educational and no security can be guaranteed for any encryption and/or decryption that uses this implementation. Do also not that this is not going to be the most efficient implementation due to my limited coding skills and knowledge, but i have tried to do my best to make it as efficient as possible so it´s not to slow to work with. - -This implementation of AES (Advanced Encryption Algorithm) algorithm is implemented with a number of different running modes such as ECB and CBC with more coming soon (see list below for updated information)... - -Implemented running modes ---- -- [x] **ECB** - Electronic Code Book mode (For more information see ...) -- [x] **CBC** - Cipher Block Chaining mode (For more information see ...) -- [ ] **CFB** - Cipher Feedback mode (For more information see ...) -- [ ] **OFB** - Output FeedBack mode (For more information see ...) -- [ ] **CTR** - Counter mode (For more information see ...) -- [ ] **GCM** - Galois/Counter mode (For more information see ...) - -More information ---- -... + - [Usage](#usage) Installation --- -... +``` +pip install aes-python +``` -How to use +Usage --- -... +``` +AES_Python +``` From 49ec65ee92d9d5f96623d296d5f0e8095de72d49 Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Sun, 24 Jul 2022 16:29:44 +0200 Subject: [PATCH 05/12] fixed missing line --- src/AES_Python/AES.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AES_Python/AES.py b/src/AES_Python/AES.py index dcf322b..1bed5cc 100644 --- a/src/AES_Python/AES.py +++ b/src/AES_Python/AES.py @@ -538,4 +538,4 @@ def pcbc_dec(key, file_path, iv): result = bytes(remove_padding(data_pice, identifier)) output.write(result) - remove(file_path) \ No newline at end of file + remove(file_path) From 0287909c2479700fe745b09b40caa65a094cfbee Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Sun, 24 Jul 2022 16:33:00 +0200 Subject: [PATCH 06/12] changed python build name --- .github/workflows/python-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 9d03d17..d5dadb7 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -6,7 +6,7 @@ # separate terms of service, privacy policy, and support # documentation. -name: Build & Upload Python Package +name: Build on: release: From 7c1e2947892ada980e48cd03fe10c80f9bef10dc Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Tue, 26 Jul 2022 13:04:59 +0200 Subject: [PATCH 07/12] new actions setup --- .github/workflows/core.yml | 90 +++++++++++++++++++++++++ .github/workflows/python-publish.yml | 62 ----------------- .github/workflows/test.yml | 11 ++- dist/AES-Python-1.1.0.tar.gz | Bin 10375 -> 10362 bytes dist/AES_Python-1.1.0-py3-none-any.whl | Bin 10070 -> 10071 bytes 5 files changed, 98 insertions(+), 65 deletions(-) create mode 100644 .github/workflows/core.yml delete mode 100644 .github/workflows/python-publish.yml diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml new file mode 100644 index 0000000..b2d7c16 --- /dev/null +++ b/.github/workflows/core.yml @@ -0,0 +1,90 @@ +# This workflow will upload a Python Package using Twine when a push or pull-request pushed thru to the core branch. + +name: Core Build & Publish + +on: + merge: + branches: [core] + push: + branches: [core] + +permissions: + contents: read + +jobs: + validate: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ['3.9', '3.10'] + + steps: + - uses: actions/checkout@v3 + - name: Set up python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: + python -m pip install --upgrade pip + pip install tox tox-gh-actions + - name: Test + run: tox + + build: + needs: + - validate + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + - name: Building package + run: python -m build + + release: + needs: + - build + - validate + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.x' + - name: Create release + uses: 'marvinpinto/action-automatic-releases@latest' + with: + repo_token: ${{ secrets.RELEASE_TOKEN }} + automatic_release_tag: $(python setup.py --version) + prerelease: false + title: $(python setup.py --version) + files: | + dist/* + + deploy: + needs: + - release + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.x' + - name: Publish package + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml deleted file mode 100644 index d5dadb7..0000000 --- a/.github/workflows/python-publish.yml +++ /dev/null @@ -1,62 +0,0 @@ -# This workflow will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -name: Build - -on: - release: - branches: [core] - types: [published] - -permissions: - contents: read - -jobs: - validate: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - python-version: ['3.9', '3.10'] - - steps: - - uses: actions/checkout@v2 - - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: - python -m pip install --upgrade pip - pip install tox tox-gh-actions - - name: Test with tox - run: tox - - deploy: - needs: - - validate - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build - - name: Build package - run: python -m build - - name: Publish package - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e1c5101..661eb36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,8 +1,13 @@ -name: Tests +name: Test on: - - push - - pull_request + push: + branches: [dev] + pull_request: + branches: [core] + +permissions: + contents: read jobs: test: diff --git a/dist/AES-Python-1.1.0.tar.gz b/dist/AES-Python-1.1.0.tar.gz index 3a22a7846a5b1293714773b0488ffa404c9db36b..d8d16ee7bf618bc62e42e2bf6b2d62906a99663c 100644 GIT binary patch delta 9162 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 delta 9168 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 delta 770 zcmccacg;^az?+#xgn@y9gF(9ZM@ZH7l`h`|7#Na07#IX6e^eIPsQ*!bv3#?l;B!u9 z_u?O$xuy3off=V{RltnNALXZm1SWSYl!9qy#Q;tqKVaCnKFHj-KHt17yS&A|An)1PluB!Zv>B#f%}?K6UFP;n zCnord{$sDNmk;dxx-MpS;05l(u0iX{w(OHvkv;l#<_yo;OVR#40&^B}{OSJd&FUEU z+<+s_=KQYXfu@dApY}Z5q|%be)m`r;nzSkO(!_;*nq|6gxTKc#JdoH~`FxeZ`ui3K zwr-wXl`W{Z&*P%eDzDuKSA&J9h1C)xWhy+(|7Y zmGkcb@x(xhYRmK!J8LZ?|#gAHR<7@ z7xfzNZRAs~bxNCkS6kP5+Q#~O--C&7t*@Qaw%D#v7xX0U{OsI=9@f?_%%ry&}F1rs+ zdO2-c`sY*6FSR~f{(13C|2;>GcWrf_u>O94HzSh>1C}(p`Mz=^BRI_^tNMcJ&8mK2 ennleUOb4ljf$7z1!ANP6UEPcAs4_6kGXMY~HD Date: Tue, 26 Jul 2022 14:15:53 +0200 Subject: [PATCH 08/12] PCBC setup and ready --- src/AES_Python/AES.py | 21 +++++++++++---------- tests/Analyze.py | 2 +- tests/test_decryption.py | 28 +++++++++++++++++++++++++++- tests/test_encryption.py | 24 ++++++++++++++++++++++++ tmp/test_3.py | 2 +- tmp/test_files/data.txt | 1 + tmp/test_files/data.txt.enc | 1 - 7 files changed, 65 insertions(+), 14 deletions(-) delete mode 100644 tmp/test_files/data.txt.enc diff --git a/src/AES_Python/AES.py b/src/AES_Python/AES.py index 1bed5cc..d469d9d 100644 --- a/src/AES_Python/AES.py +++ b/src/AES_Python/AES.py @@ -59,6 +59,13 @@ # --------------- # Main action functions # --------------- +# Progress bar display and update +def progress_bar(progress, total_progress): + percent = 100 * (float(progress) / float(total_progress)) + bar = '#' * int(percent) + '-' * (100 - int(percent)) + print(f"\r[{bar}] {percent:.2f}%", end="\r") + return progress + 16 + # Xtime def xtime(a): return (((a << 1) ^ 0x1B) & 0xFF) if (a & 0x80) else (a << 1) @@ -475,7 +482,7 @@ def pcbc_enc(key, file_path, iv): tmp = xor(raw, vector) vector = encryption_rounds(tmp, key) output.write(bytes(vector)) - vector = xor(vector, tmp) + vector = xor(vector, raw) if file_size % 16 != 0: raw = [i for i in data.read()] @@ -483,12 +490,12 @@ def pcbc_enc(key, file_path, iv): tmp = xor(raw, vector) vector1 = encryption_rounds(tmp, key) - vector = xor(vector1, tmp) + vector = xor(vector1, raw) - identifier = xor(([0 for i in range(15)] + [length]), vector1) + identifier = xor(([0 for i in range(15)] + [length]), vector) identifier = encryption_rounds(identifier, key) - output.write(bytes(vector + identifier)) + output.write(bytes(vector1 + identifier)) else: identifier = xor([0 for i in range(16)], vector) identifier = bytes(encryption_rounds(identifier, key)) @@ -522,9 +529,6 @@ def pcbc_dec(key, file_path, iv): data_pice = [i for i in data.read(16)] vector_1, identifier = data_pice, [i for i in data.read()] - print(identifier) - print(data_pice) - result = decryption_rounds(data_pice, key) data_pice = xor(result, vector) @@ -532,9 +536,6 @@ def pcbc_dec(key, file_path, iv): identifier = decryption_rounds(identifier, key) identifier = xor(identifier, vector_1) - print(data_pice) - print(identifier) - result = bytes(remove_padding(data_pice, identifier)) output.write(result) diff --git a/tests/Analyze.py b/tests/Analyze.py index d40d297..489713f 100644 --- a/tests/Analyze.py +++ b/tests/Analyze.py @@ -16,4 +16,4 @@ def main(i): if __name__ == '__main__': - main("dec") + main("enc") diff --git a/tests/test_decryption.py b/tests/test_decryption.py index 600a64c..f24307d 100644 --- a/tests/test_decryption.py +++ b/tests/test_decryption.py @@ -51,4 +51,30 @@ def test_aes_decryption_CBC(data, key, file_name, iv, expected): os.remove(file_name) - assert result == expected \ No newline at end of file + assert result == expected + +@pytest.mark.parametrize("data,key,file_name,iv,expected", [ + # 128 bit + (b'\xe4\xa7\x0e\xbd\x84\xfa\xf5\xd8`\xb8\xa1\x10\x0b~\xadhJ\xa98\x9f\xceZ\xd4\x9f"\xde\x00\xf6w\xa9\x1b\x05', "2b7e151628aed2a6abf7158809cf4f3c", "tmp1.txt", "000102030405060708090a0b0c0d0e0f", b'1234567890'), + (b'\x1b\x16\x86:\xb9*w\xc5)"\xe4\xe9D\\\xf1\xeeD\xc2\x1d\x19\x93\xd4\x7f\xed\xc8\xb8\xa1\xb60ow\xdd', "2b7e151628aed2a6abf7158809cf4f3c", "tmp2.txt", "000102030405060708090a0b0c0d0e0f", b'1234567890123456'), + (b'\x1b\x16\x86:\xb9*w\xc5)"\xe4\xe9D\\\xf1\xee\x0e\xcez\xe5\xcde\x91Q7\xc3|\x8bB\xe6\x96\xc0\x0e%0).\x8006\xf7V\xa1P\xf4\xec\xc0\x05', "2b7e151628aed2a6abf7158809cf4f3c", "tmp7.txt", "000102030405060708090a0b0c0d0e0f", b'12345678901234567890'), + (b'\x1b\x16\x86:\xb9*w\xc5)"\xe4\xe9D\\\xf1\xeeg\x19\xcc\xa3\x86K\xfax\xae\n\xee!k\xcc\xcb\xf2:\xfe\xa7,9jJo\xf6/q\xce\xec\x8b\xfd\xee\xc6\xee]\x9f\xbf\xcb~\x84\x8b\xd6\xe6\xed\xba\xbe\xbb.', "2b7e151628aed2a6abf7158809cf4f3c", "tmp8.txt", "000102030405060708090a0b0c0d0e0f", b'1234567890123456789012345678901234567890'), + # 192 bit + (b"\x89\x8fwWh\xaf\xfb@\xc9\xc3\xc0w\x81\xf7\x0e\xd3s\xee\xdf\xa7\xaf\x9f\xddV\x92\x18\x11\r'\xc1\x8d\xfa", "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "tmp3.txt", "000102030405060708090a0b0c0d0e0f", b'1234567890'), + (b'5\xb9\x19\x1dd\xf3e\xd7EP\x01^8\xb0\xf6\xfb\xe6\xc0\x12\xd1\xfa\x0fr\xde\xc5\xc4\xb9\x9a\xcc\xcd\x9d\xea', "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "tmp4.txt", "000102030405060708090a0b0c0d0e0f", b'1234567890123456'), + # 256 bit + (b'\x9dT\xb7B\x19e\xb8q\xc95\xfa\x80L\x88.9\x97]D\xd8L\xf7\x7f\xc4D\xb3\xbe\xb7\xe1\x81\xe5/', "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "tmp5.txt", "000102030405060708090a0b0c0d0e0f", b'1234567890'), + (b'a\xfdIRQ\xf8\xf1D\xcc\xbf\x89\xc8\xd6\xec\x01;\xe3\xba\xba{-\xbdz\xa0r\x9c\xd6\xed\x86\xa0\xe2\xee', "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "tmp6.txt", "000102030405060708090a0b0c0d0e0f", b'1234567890123456') +]) +def test_aes_decryption_PCBC(data, key, file_name, iv, expected): + with open(f"{file_name}.enc", "wb") as file: + file.write(data) + + decrypt(key, f"{file_name}.enc", "PCBC", iv) + + with open(file_name, "rb") as file: + result = file.read() + + os.remove(file_name) + + assert result == expected diff --git a/tests/test_encryption.py b/tests/test_encryption.py index 6917fba..c63b607 100644 --- a/tests/test_encryption.py +++ b/tests/test_encryption.py @@ -48,4 +48,28 @@ def test_aes_encrypt_CBC(data, key, file_name, iv, expected): os.remove(f"{file_name}.enc") + assert result == expected + +@pytest.mark.parametrize("data,key,file_name,iv,expected", [ + # 128 bit + (b'1234567890', "2b7e151628aed2a6abf7158809cf4f3c", "tmp.txt", "000102030405060708090a0b0c0d0e0f", b'\xe4\xa7\x0e\xbd\x84\xfa\xf5\xd8`\xb8\xa1\x10\x0b~\xadhJ\xa98\x9f\xceZ\xd4\x9f"\xde\x00\xf6w\xa9\x1b\x05'), + (b'1234567890123456', "2b7e151628aed2a6abf7158809cf4f3c", "tmp1.txt", "000102030405060708090a0b0c0d0e0f", b'\x1b\x16\x86:\xb9*w\xc5)"\xe4\xe9D\\\xf1\xeeD\xc2\x1d\x19\x93\xd4\x7f\xed\xc8\xb8\xa1\xb60ow\xdd'), + # 192 bit + (b'1234567890', "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "tmp2.txt", "000102030405060708090a0b0c0d0e0f", b"\x89\x8fwWh\xaf\xfb@\xc9\xc3\xc0w\x81\xf7\x0e\xd3s\xee\xdf\xa7\xaf\x9f\xddV\x92\x18\x11\r'\xc1\x8d\xfa"), + (b'1234567890123456', "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "tmp3.txt", "000102030405060708090a0b0c0d0e0f", b'5\xb9\x19\x1dd\xf3e\xd7EP\x01^8\xb0\xf6\xfb\xe6\xc0\x12\xd1\xfa\x0fr\xde\xc5\xc4\xb9\x9a\xcc\xcd\x9d\xea'), + # 256 bit + (b'1234567890', "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "tmp4.txt", "000102030405060708090a0b0c0d0e0f", b'\x9dT\xb7B\x19e\xb8q\xc95\xfa\x80L\x88.9\x97]D\xd8L\xf7\x7f\xc4D\xb3\xbe\xb7\xe1\x81\xe5/'), + (b'1234567890123456', "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "tmp5.txt", "000102030405060708090a0b0c0d0e0f", b'a\xfdIRQ\xf8\xf1D\xcc\xbf\x89\xc8\xd6\xec\x01;\xe3\xba\xba{-\xbdz\xa0r\x9c\xd6\xed\x86\xa0\xe2\xee') +]) +def test_aes_encrypt_PCBC(data, key, file_name, iv, expected): + with open(file_name, "wb") as file: + file.write(data) + + encrypt(key, file_name, "PCBC", iv) + + with open(f"{file_name}.enc", "rb") as file: + result = file.read() + + os.remove(f"{file_name}.enc") + assert result == expected \ No newline at end of file diff --git a/tmp/test_3.py b/tmp/test_3.py index 18c6fbb..86a587a 100644 --- a/tmp/test_3.py +++ b/tmp/test_3.py @@ -1,4 +1,4 @@ -with open(r"/Users/gabriellindeblad/Documents/GitHub/AES-Python/tmp/test_files/data.txt.enc", "rb") as p: +with open(r".\tmp\test_files\data.txt.enc", "rb") as p: t = p.read() print(t) diff --git a/tmp/test_files/data.txt b/tmp/test_files/data.txt index e69de29..6a537b5 100644 --- a/tmp/test_files/data.txt +++ b/tmp/test_files/data.txt @@ -0,0 +1 @@ +1234567890 \ No newline at end of file diff --git a/tmp/test_files/data.txt.enc b/tmp/test_files/data.txt.enc deleted file mode 100644 index fe6b2f4..0000000 --- a/tmp/test_files/data.txt.enc +++ /dev/null @@ -1 +0,0 @@ -Õ”?еÉÄçQ«s£g‰FesoÅ~_|éGÙ*\ \ No newline at end of file From 33b3635d6806abeb5a52c9b313027884791493ea Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Tue, 26 Jul 2022 14:43:01 +0200 Subject: [PATCH 09/12] implemented secure key and iv entry m.m --- src/AES_Python/AES.py | 37 ++++++++ src/AES_Python/__main__.py | 21 ++--- tmp/test.py | 171 +++---------------------------------- 3 files changed, 60 insertions(+), 169 deletions(-) diff --git a/src/AES_Python/AES.py b/src/AES_Python/AES.py index d469d9d..75353a9 100644 --- a/src/AES_Python/AES.py +++ b/src/AES_Python/AES.py @@ -62,6 +62,8 @@ # Progress bar display and update def progress_bar(progress, total_progress): percent = 100 * (float(progress) / float(total_progress)) + if percent > 100: + percent = 100 bar = '#' * int(percent) + '-' * (100 - int(percent)) print(f"\r[{bar}] {percent:.2f}%", end="\r") return progress + 16 @@ -360,12 +362,15 @@ def SubWord(word): # ECB encryption function def ecb_enc(key, file_path): file_size = getsize(file_path) + progress = 0 + progress = progress_bar(progress, file_size) with open(f"{file_path}.enc", 'wb') as output, open(file_path, 'rb') as data: for i in range(int(file_size/16)): raw = [i for i in data.read(16)] result = bytes(encryption_rounds(raw, key)) output.write(result) + progress = progress_bar(progress, file_size) if file_size % 16 != 0: raw = [i for i in data.read()] @@ -375,15 +380,20 @@ def ecb_enc(key, file_path): identifier = bytes(encryption_rounds([0 for i in range(15)] + [length], key)) output.write(result + identifier) + progress = progress_bar(progress, file_size) else: identifier = bytes(encryption_rounds([0 for i in range(16)], key)) output.write(identifier) + progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size) remove(file_path) # ECB decryption function def ecb_dec(key, file_path): file_size = getsize(file_path) + progress = 0 + progress = progress_bar(progress, file_size) file_name = file_path[:-4] with open(f"{file_name}", 'wb') as output, open(file_path, 'rb') as data: @@ -391,6 +401,7 @@ def ecb_dec(key, file_path): raw = [i for i in data.read(16)] result = bytes(decryption_rounds(raw, key)) output.write(result) + progress = progress_bar(progress, file_size) data_pice = [i for i in data.read(16)] identifier = [i for i in data.read()] @@ -401,12 +412,16 @@ def ecb_dec(key, file_path): result = bytes(remove_padding(result, identifier)) output.write(result) + progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size) remove(file_path) # CBC encryption function def cbc_enc(key, file_path, iv): file_size = getsize(file_path) + progress = 0 + progress = progress_bar(progress, file_size) vector = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] with open(f"{file_path}.enc", 'wb') as output, open(file_path, 'rb') as data: @@ -415,6 +430,7 @@ def cbc_enc(key, file_path, iv): raw = xor(raw, vector) vector = encryption_rounds(raw, key) output.write(bytes(vector)) + progress = progress_bar(progress, file_size) if file_size % 16 != 0: raw = [i for i in data.read()] @@ -427,10 +443,13 @@ def cbc_enc(key, file_path, iv): identifier = encryption_rounds(identifier, key) output.write(bytes(vector + identifier)) + progress = progress_bar(progress, file_size) else: identifier = xor([0 for i in range(16)], vector) identifier = bytes(encryption_rounds(identifier, key)) output.write(identifier) + progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size) remove(file_path) @@ -438,6 +457,8 @@ def cbc_enc(key, file_path, iv): def cbc_dec(key, file_path, iv): iv = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] file_size = getsize(file_path) + progress = 0 + progress = progress_bar(progress, file_size) file_name = file_path[:-4] with open(f"{file_name}", 'wb') as output, open(file_path, 'rb') as data: @@ -446,6 +467,7 @@ def cbc_dec(key, file_path, iv): raw = decryption_rounds(vector, key) result = xor(raw, iv) output.write(bytes(result)) + progress = progress_bar(progress, file_size) for i in range(int(file_size/16) - 3): raw = [i for i in data.read(16)] @@ -453,6 +475,7 @@ def cbc_dec(key, file_path, iv): result = xor(result, vector) vector = raw output.write(bytes(result)) + progress = progress_bar(progress, file_size) else: vector = iv @@ -468,12 +491,16 @@ def cbc_dec(key, file_path, iv): result = bytes(remove_padding(data_pice, identifier)) output.write(result) + progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size) remove(file_path) # PCBC encryption function def pcbc_enc(key, file_path, iv): file_size = getsize(file_path) + progress = 0 + progress = progress_bar(progress, file_size) vector = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] with open(f"{file_path}.enc", 'wb') as output, open(file_path, 'rb') as data: @@ -483,6 +510,7 @@ def pcbc_enc(key, file_path, iv): vector = encryption_rounds(tmp, key) output.write(bytes(vector)) vector = xor(vector, raw) + progress = progress_bar(progress, file_size) if file_size % 16 != 0: raw = [i for i in data.read()] @@ -496,10 +524,13 @@ def pcbc_enc(key, file_path, iv): identifier = encryption_rounds(identifier, key) output.write(bytes(vector1 + identifier)) + progress = progress_bar(progress, file_size) else: identifier = xor([0 for i in range(16)], vector) identifier = bytes(encryption_rounds(identifier, key)) output.write(identifier) + progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size) remove(file_path) @@ -507,6 +538,8 @@ def pcbc_enc(key, file_path, iv): def pcbc_dec(key, file_path, iv): iv = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] file_size = getsize(file_path) + progress = 0 + progress = progress_bar(progress, file_size) file_name = file_path[:-4] with open(f"{file_name}", 'wb') as output, open(file_path, 'rb') as data: @@ -516,6 +549,7 @@ def pcbc_dec(key, file_path, iv): result = xor(raw, iv) vector = xor(vector, result) output.write(bytes(result)) + progress = progress_bar(progress, file_size) for i in range(int(file_size/16) - 3): raw = [i for i in data.read(16)] @@ -523,6 +557,7 @@ def pcbc_dec(key, file_path, iv): result = xor(result, vector) vector = xor(raw, result) output.write(bytes(result)) + progress = progress_bar(progress, file_size) else: vector = iv @@ -539,4 +574,6 @@ def pcbc_dec(key, file_path, iv): result = bytes(remove_padding(data_pice, identifier)) output.write(result) + progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size) remove(file_path) diff --git a/src/AES_Python/__main__.py b/src/AES_Python/__main__.py index 0588c58..59b9c3c 100644 --- a/src/AES_Python/__main__.py +++ b/src/AES_Python/__main__.py @@ -1,5 +1,6 @@ from AES_Python.encrypt import encrypt from AES_Python.decrypt import decrypt +from getpass import getpass import AES_Python @@ -31,13 +32,13 @@ def run(): running_mode = input("Please select cipher running mode (ECB/CBC/PCBC/CFB/OFB/CTR/GCM): ") if running_mode == "ECB": - key = input("Please enter your key: ") + key = getpass(prompt="Please enter your key: ") file_path = input("Please enter path to file: ") confirmation = input("Are you sure you want to encrypt this file? (y/n): ") if confirmation == "y": encrypt(key, file_path, running_mode) - print("Encryption complete!") + print("\nEncryption complete!") elif confirmation == "n": print("Encryption aborted!") @@ -48,14 +49,14 @@ def run(): exit() elif running_mode in ["CBC", "PCBC", "CFB", "OFB", "CTR", "GCM"]: - key = input("Please enter your key: ") - iv = input("Please enter your iv: ") + key = getpass(prompt="Please enter your key: ") + iv = getpass(prompt="Please enter your iv: ") file_path = input("Please enter path to file: ") confirmation = input("Are you sure you want to encrypt this file? (y/n): ") if confirmation == "y": encrypt(key, file_path, running_mode, iv) - print("Encryption complete!") + print("\nEncryption complete!") elif confirmation == "n": print("Encryption aborted!") @@ -73,13 +74,13 @@ def run(): running_mode = input("Please select cipher running mode (ECB/CBC/PCBC/CFB/OFB/CTR/GCM): ") if running_mode == "ECB": - key = input("Please enter your key: ") + key = getpass(prompt="Please enter your key: ") file_path = input("Please enter path to file: ") confirmation = input("Are you sure you want to decrypt this file? (y/n): ") if confirmation == "y": encrypt(key, file_path, running_mode) - print("Decryption complete!") + print("\nDecryption complete!") elif confirmation == "n": print("Decryption aborted!") @@ -90,14 +91,14 @@ def run(): exit() elif running_mode in ["CBC", "PCBC", "CFB", "OFB", "CTR", "GCM"]: - key = input("Please enter your key: ") - iv = input("Please enter your iv: ") + key = getpass(prompt="Please enter your key: ") + iv = getpass(prompt="Please enter your iv: ") file_path = input("Please enter path to file: ") confirmation = input("Are you sure you want to decrypt this file? (y/n): ") if confirmation == "y": decrypt(key, file_path, running_mode, iv) - print("Decryption complete!") + print("\nDecryption complete!") elif confirmation == "n": print("Decryption aborted!") diff --git a/tmp/test.py b/tmp/test.py index 383649c..e9da35c 100644 --- a/tmp/test.py +++ b/tmp/test.py @@ -1,162 +1,15 @@ -sbox = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16] -Rcon = [0x00000000, 0x01000000, 0x02000000, - 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000, 0x80000000, - 0x1b000000, 0x36000000] +def progress_bar(progress, total_progress): + percent = 100 * (float(progress) / float(total_progress)) + if percent > 100: + percent = 100 + bar = '#' * int(percent) + '-' * (100 - int(percent)) + print(f"\r[{bar}] {percent:.2f}%", end="\r") + return progress + 16 -# --------------- -# Key expantion setup -# --------------- -# Key expansion function -def keyExpansion(key): - # Key expansion setup - if len(key) == 16: - words = key_schedule(key, 4, 11) - nr = 11 - if len(key) == 24: - words = key_schedule(key, 6, 13) - nr = 13 - if len(key) == 32: - words = key_schedule(key, 8, 15) - nr = 15 - - round_keys = [None for i in range(nr)] - - #words = [[t for t in range(4)] for i in range(nr * 4)] - tmp = [None for i in range(4)] - for i in range(nr * 4): - for t in range(4): - tmp[t] = int(words[i][t], 16) - words[i] = tuple(tmp) - - for i in range(nr): - round_keys[i] = (words[i * 4] + words[i * 4 + 1] + words[i * 4 + 2] + words[i * 4 + 3]) - - return round_keys - - -# Key schedule (nk = number of colums, nr = number of rounds) -def key_schedule(key, nk, nr): - # Create list and populates first nk words with key - words = [(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]) for i in range(nk)] - - # fill out the rest based on previews words, rotword, subword and rcon values - limit = False - for i in range(nk, (nr * nk)): - # get required previous keywords - temp, word = words[i-1], words[i-nk] - - # if multiple of nk use rot, sub, rcon etc - if i % nk == 0: - x = SubWord(RotWord(temp)) - rcon = Rcon[int(i/nk)] - temp = hexor(x, hex(rcon)[2:]) - limit = False - elif i % 4 == 0: - limit = True - - if i % 4 == 0 and limit and nk >= 8: - temp = SubWord(temp) - - # xor the two hex values - xord = hexor(''.join(word), ''.join(temp)) - words.append((xord[:2], xord[2:4], xord[4:6], xord[6:8])) - return words - - -# takes two hex values and calculates hex1 xor hex2 -def hexor(hex1, hex2): - # convert to binary - bin1 = hex2binary(hex1) - bin2 = hex2binary(hex2) - - # calculate - xord = int(bin1, 2) ^ int(bin2, 2) - - # cut prefix - hexed = hex(xord)[2:] - - # leading 0s get cut above, if not length 8 add a leading 0 - if len(hexed) != 8: - hexed = '0' + hexed - - return hexed - - -# takes a hex value and returns binary -def hex2binary(hex): - return bin(int(str(hex), 16)) - - -# takes from 1 to the end, adds on from the start to 1 -def RotWord(word): - return word[1:] + word[:1] - - -# selects correct value from sbox based on the current word -def SubWord(word): - sWord = [] - - # loop throug the current word - for i in range(4): - - # check first char, if its a letter(a-f) get corresponding decimal - # otherwise just take the value and add 1 - if word[i][0].isdigit() is False: - row = ord(word[i][0]) - 86 - else: - row = int(word[i][0])+1 - - # repeat above for the seoncd char - if word[i][1].isdigit() is False: - col = ord(word[i][1]) - 86 - else: - col = int(word[i][1])+1 - - # get the index base on row and col (16x16 grid) - sBoxIndex = (row*16) - (17-col) - - # get the value from sbox without prefix - piece = hex(sbox[sBoxIndex])[2:] - - # check length to ensure leading 0s are not forgotton - if len(piece) != 2: - piece = '0' + piece - - sWord.append(piece) - - # return string - return ''.join(sWord) - - -def main(): - # hardcoding input key for demonstration purposes, could be read in from user/program via cmd/gui etc. - key = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f"] - - # expand key - w = keyExpansion(key) - - # display nicely - print("Key provided: " + "".join(key)) - print(w) - - -if __name__ == '__main__': - main() +if __name__ == "__main__": + progress = 0 + for i in range(100): + progress = progress_bar(progress, 100) + print() \ No newline at end of file From b0aa635ce51e4ba5b8d64e9f8d5938a870fb92aa Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Tue, 26 Jul 2022 14:53:15 +0200 Subject: [PATCH 10/12] new adaptive progress bar --- src/AES_Python/AES.py | 14 +++++++++++--- tmp/test.py | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/AES_Python/AES.py b/src/AES_Python/AES.py index 75353a9..d04440f 100644 --- a/src/AES_Python/AES.py +++ b/src/AES_Python/AES.py @@ -2,7 +2,7 @@ # Imports # --------------- from os.path import getsize -from os import remove +from os import remove, get_terminal_size # --------------- # Fixed variables @@ -62,9 +62,17 @@ # Progress bar display and update def progress_bar(progress, total_progress): percent = 100 * (float(progress) / float(total_progress)) - if percent > 100: + + terminal_width = get_terminal_size()[0] + bar_width = terminal_width - 10 + bar_progress = int(bar_width * (float(progress) / float(total_progress))) + + if bar_progress > bar_width or percent > 100: + bar_progress = bar_width percent = 100 - bar = '#' * int(percent) + '-' * (100 - int(percent)) + + bar_remaining = bar_width - bar_progress + bar = '#' * bar_progress + '-' * bar_remaining print(f"\r[{bar}] {percent:.2f}%", end="\r") return progress + 16 diff --git a/tmp/test.py b/tmp/test.py index e9da35c..f1ee994 100644 --- a/tmp/test.py +++ b/tmp/test.py @@ -1,10 +1,18 @@ - +from os import get_terminal_size def progress_bar(progress, total_progress): percent = 100 * (float(progress) / float(total_progress)) - if percent > 100: + + terminal_width = get_terminal_size()[0] + bar_width = terminal_width - 10 + bar_progress = int(bar_width * (float(progress) / float(total_progress))) + + if bar_progress > bar_width or percent > 100: + bar_progress = bar_width percent = 100 - bar = '#' * int(percent) + '-' * (100 - int(percent)) + + bar_remaining = bar_width - bar_progress + bar = '#' * bar_progress + '-' * bar_remaining print(f"\r[{bar}] {percent:.2f}%", end="\r") return progress + 16 @@ -12,4 +20,4 @@ def progress_bar(progress, total_progress): progress = 0 for i in range(100): progress = progress_bar(progress, 100) - print() \ No newline at end of file + print() From 514d7861277589c71f102869356dc5112c0c74eb Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Tue, 26 Jul 2022 15:30:36 +0200 Subject: [PATCH 11/12] fixed error in progrss bar implmentation --- src/AES_Python/AES.py | 76 +++++++++++++++++++------------------- src/AES_Python/__main__.py | 9 +++-- src/AES_Python/decrypt.py | 8 ++-- src/AES_Python/encrypt.py | 8 ++-- 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/AES_Python/AES.py b/src/AES_Python/AES.py index d04440f..92aaf66 100644 --- a/src/AES_Python/AES.py +++ b/src/AES_Python/AES.py @@ -2,7 +2,7 @@ # Imports # --------------- from os.path import getsize -from os import remove, get_terminal_size +from os import remove # --------------- # Fixed variables @@ -60,10 +60,9 @@ # Main action functions # --------------- # Progress bar display and update -def progress_bar(progress, total_progress): +def progress_bar(progress, total_progress, terminal_width): percent = 100 * (float(progress) / float(total_progress)) - terminal_width = get_terminal_size()[0] bar_width = terminal_width - 10 bar_progress = int(bar_width * (float(progress) / float(total_progress))) @@ -76,6 +75,7 @@ def progress_bar(progress, total_progress): print(f"\r[{bar}] {percent:.2f}%", end="\r") return progress + 16 + # Xtime def xtime(a): return (((a << 1) ^ 0x1B) & 0xFF) if (a & 0x80) else (a << 1) @@ -368,17 +368,17 @@ def SubWord(word): # Running modes setup # --------------- # ECB encryption function -def ecb_enc(key, file_path): +def ecb_enc(key, file_path, terminal_width=110): file_size = getsize(file_path) progress = 0 - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) with open(f"{file_path}.enc", 'wb') as output, open(file_path, 'rb') as data: for i in range(int(file_size/16)): raw = [i for i in data.read(16)] result = bytes(encryption_rounds(raw, key)) output.write(result) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) if file_size % 16 != 0: raw = [i for i in data.read()] @@ -388,20 +388,20 @@ def ecb_enc(key, file_path): identifier = bytes(encryption_rounds([0 for i in range(15)] + [length], key)) output.write(result + identifier) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) else: identifier = bytes(encryption_rounds([0 for i in range(16)], key)) output.write(identifier) - progress = progress_bar(progress, file_size) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) + progress = progress_bar(progress, file_size, terminal_width) remove(file_path) # ECB decryption function -def ecb_dec(key, file_path): +def ecb_dec(key, file_path, terminal_width=110): file_size = getsize(file_path) progress = 0 - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) file_name = file_path[:-4] with open(f"{file_name}", 'wb') as output, open(file_path, 'rb') as data: @@ -409,7 +409,7 @@ def ecb_dec(key, file_path): raw = [i for i in data.read(16)] result = bytes(decryption_rounds(raw, key)) output.write(result) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) data_pice = [i for i in data.read(16)] identifier = [i for i in data.read()] @@ -420,16 +420,16 @@ def ecb_dec(key, file_path): result = bytes(remove_padding(result, identifier)) output.write(result) - progress = progress_bar(progress, file_size) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) + progress = progress_bar(progress, file_size, terminal_width) remove(file_path) # CBC encryption function -def cbc_enc(key, file_path, iv): +def cbc_enc(key, file_path, iv, terminal_width=110): file_size = getsize(file_path) progress = 0 - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) vector = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] with open(f"{file_path}.enc", 'wb') as output, open(file_path, 'rb') as data: @@ -438,7 +438,7 @@ def cbc_enc(key, file_path, iv): raw = xor(raw, vector) vector = encryption_rounds(raw, key) output.write(bytes(vector)) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) if file_size % 16 != 0: raw = [i for i in data.read()] @@ -451,22 +451,22 @@ def cbc_enc(key, file_path, iv): identifier = encryption_rounds(identifier, key) output.write(bytes(vector + identifier)) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) else: identifier = xor([0 for i in range(16)], vector) identifier = bytes(encryption_rounds(identifier, key)) output.write(identifier) - progress = progress_bar(progress, file_size) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) + progress = progress_bar(progress, file_size, terminal_width) remove(file_path) # CBC decryption function -def cbc_dec(key, file_path, iv): +def cbc_dec(key, file_path, iv, terminal_width=110): iv = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] file_size = getsize(file_path) progress = 0 - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) file_name = file_path[:-4] with open(f"{file_name}", 'wb') as output, open(file_path, 'rb') as data: @@ -475,7 +475,7 @@ def cbc_dec(key, file_path, iv): raw = decryption_rounds(vector, key) result = xor(raw, iv) output.write(bytes(result)) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) for i in range(int(file_size/16) - 3): raw = [i for i in data.read(16)] @@ -483,7 +483,7 @@ def cbc_dec(key, file_path, iv): result = xor(result, vector) vector = raw output.write(bytes(result)) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) else: vector = iv @@ -499,16 +499,16 @@ def cbc_dec(key, file_path, iv): result = bytes(remove_padding(data_pice, identifier)) output.write(result) - progress = progress_bar(progress, file_size) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) + progress = progress_bar(progress, file_size, terminal_width) remove(file_path) # PCBC encryption function -def pcbc_enc(key, file_path, iv): +def pcbc_enc(key, file_path, iv, terminal_width=110): file_size = getsize(file_path) progress = 0 - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) vector = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] with open(f"{file_path}.enc", 'wb') as output, open(file_path, 'rb') as data: @@ -518,7 +518,7 @@ def pcbc_enc(key, file_path, iv): vector = encryption_rounds(tmp, key) output.write(bytes(vector)) vector = xor(vector, raw) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) if file_size % 16 != 0: raw = [i for i in data.read()] @@ -532,22 +532,22 @@ def pcbc_enc(key, file_path, iv): identifier = encryption_rounds(identifier, key) output.write(bytes(vector1 + identifier)) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) else: identifier = xor([0 for i in range(16)], vector) identifier = bytes(encryption_rounds(identifier, key)) output.write(identifier) - progress = progress_bar(progress, file_size) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) + progress = progress_bar(progress, file_size, terminal_width) remove(file_path) # PCBC decryption function -def pcbc_dec(key, file_path, iv): +def pcbc_dec(key, file_path, iv, terminal_width=110): iv = [int(iv[i:i+2], 16) for i in range(0, len(iv), 2)] file_size = getsize(file_path) progress = 0 - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) file_name = file_path[:-4] with open(f"{file_name}", 'wb') as output, open(file_path, 'rb') as data: @@ -557,7 +557,7 @@ def pcbc_dec(key, file_path, iv): result = xor(raw, iv) vector = xor(vector, result) output.write(bytes(result)) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) for i in range(int(file_size/16) - 3): raw = [i for i in data.read(16)] @@ -565,7 +565,7 @@ def pcbc_dec(key, file_path, iv): result = xor(result, vector) vector = xor(raw, result) output.write(bytes(result)) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) else: vector = iv @@ -582,6 +582,6 @@ def pcbc_dec(key, file_path, iv): result = bytes(remove_padding(data_pice, identifier)) output.write(result) - progress = progress_bar(progress, file_size) - progress = progress_bar(progress, file_size) + progress = progress_bar(progress, file_size, terminal_width) + progress = progress_bar(progress, file_size, terminal_width) remove(file_path) diff --git a/src/AES_Python/__main__.py b/src/AES_Python/__main__.py index 59b9c3c..50f6976 100644 --- a/src/AES_Python/__main__.py +++ b/src/AES_Python/__main__.py @@ -1,6 +1,7 @@ from AES_Python.encrypt import encrypt from AES_Python.decrypt import decrypt from getpass import getpass +from os import get_terminal_size import AES_Python @@ -37,7 +38,7 @@ def run(): confirmation = input("Are you sure you want to encrypt this file? (y/n): ") if confirmation == "y": - encrypt(key, file_path, running_mode) + encrypt(key, file_path, running_mode, terminal_size=get_terminal_size()[0]) print("\nEncryption complete!") elif confirmation == "n": @@ -55,7 +56,7 @@ def run(): confirmation = input("Are you sure you want to encrypt this file? (y/n): ") if confirmation == "y": - encrypt(key, file_path, running_mode, iv) + encrypt(key, file_path, running_mode, iv, get_terminal_size()[0]) print("\nEncryption complete!") elif confirmation == "n": @@ -79,7 +80,7 @@ def run(): confirmation = input("Are you sure you want to decrypt this file? (y/n): ") if confirmation == "y": - encrypt(key, file_path, running_mode) + decrypt(key, file_path, running_mode, terminal_size=get_terminal_size()[0]) print("\nDecryption complete!") elif confirmation == "n": @@ -97,7 +98,7 @@ def run(): confirmation = input("Are you sure you want to decrypt this file? (y/n): ") if confirmation == "y": - decrypt(key, file_path, running_mode, iv) + decrypt(key, file_path, running_mode, iv, get_terminal_size()[0]) print("\nDecryption complete!") elif confirmation == "n": diff --git a/src/AES_Python/decrypt.py b/src/AES_Python/decrypt.py index 82c7cd0..a793dd2 100644 --- a/src/AES_Python/decrypt.py +++ b/src/AES_Python/decrypt.py @@ -5,7 +5,7 @@ # --------------- # Decryption function # --------------- -def decrypt(key, file_path, running_mode, iv=None): +def decrypt(key, file_path, running_mode, iv=None, terminal_size=110): # Input validation if file_path[-4:] != ".enc": @@ -18,11 +18,11 @@ def decrypt(key, file_path, running_mode, iv=None): # Running mode selection if running_mode == "ECB": - AES.ecb_dec(key, file_path) + AES.ecb_dec(key, file_path, terminal_size) elif running_mode == "CBC" and iv is not None: - AES.cbc_dec(key, file_path, iv) + AES.cbc_dec(key, file_path, iv, terminal_size) elif running_mode == "PCBC" and iv is not None: - AES.pcbc_dec(key, file_path, iv) + AES.pcbc_dec(key, file_path, iv, terminal_size) else: raise Exception("Running mode not supported") diff --git a/src/AES_Python/encrypt.py b/src/AES_Python/encrypt.py index 10b0cdf..7a9dc84 100644 --- a/src/AES_Python/encrypt.py +++ b/src/AES_Python/encrypt.py @@ -5,7 +5,7 @@ # --------------- # Encryption function # --------------- -def encrypt(key, file_path, running_mode, iv=None): +def encrypt(key, file_path, running_mode, iv=None, terminal_size=110): # Input validation if (len(key) / 2) not in [16, 24, 32]: @@ -16,11 +16,11 @@ def encrypt(key, file_path, running_mode, iv=None): # Running mode selection if running_mode == "ECB": - AES.ecb_enc(key, file_path) + AES.ecb_enc(key, file_path, terminal_size) elif running_mode == "CBC" and iv is not None: - AES.cbc_enc(key, file_path, iv) + AES.cbc_enc(key, file_path, iv, terminal_size) elif running_mode == "PCBC" and iv is not None: - AES.pcbc_enc(key, file_path, iv) + AES.pcbc_enc(key, file_path, iv, terminal_size) else: raise Exception("Running mode not supported") From ddd7d538a68ad6d1eb07d6833235d69b5cfbba9d Mon Sep 17 00:00:00 2001 From: Below-Zero <78178279+Glindeb@users.noreply.github.com> Date: Tue, 26 Jul 2022 15:36:21 +0200 Subject: [PATCH 12/12] new build --- dist/AES-Python-1.1.0.tar.gz | Bin 10362 -> 10712 bytes dist/AES_Python-1.1.0-py3-none-any.whl | Bin 10071 -> 10409 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/dist/AES-Python-1.1.0.tar.gz b/dist/AES-Python-1.1.0.tar.gz index d8d16ee7bf618bc62e42e2bf6b2d62906a99663c..33ec0399fb0a8e458f05c28d4a53a01bb5b97695 100644 GIT binary patch literal 10712 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 literal 10362 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 NfDPJIC~;`0{|C+;gaZHo diff --git a/dist/AES_Python-1.1.0-py3-none-any.whl b/dist/AES_Python-1.1.0-py3-none-any.whl index 7d991077342386514c80a67ef97c8af68c326cc4..b9ca89e8d57b2a25d082563326cd95c6a9b2f0e8 100644 GIT binary patch delta 7566 zcmZu$1yCH#wnl;n2(Y+2BFSNGlf zSG}p3`lh?T`Kr55pEF&37L+U0NL3XOUjg9Y;85XG?e8?ZC`^oCIB;-pG~nQHpl7rI z@R5Oo%Zha8Q#HaPb`zSu!pBcBDJ)|{oqY^WA?6Lc06RBt_!!$Q2k{0PXv!A zyE(fXkT0>8WpWL6Btej9u9MH#E3dbs_v@c-ADW`~yAG6+cQT1vwRP;=YmyH~8AePh zQA76Ccl9os*a(jTE9;=7na7eBszQm*V6SrLFm7}Lho4Hv1$SmitCj3pfVDmD8Q+J8 zCdV${JBEd&MC&qsjmPgI8h?m?Di2HC3LF2vCtAZe@BTA!4cLTz3uI3mzxK84k)hau zKfyE3K6%3hZ=Fykp7_lFnLm{6SPpEkM##pSDBg!#kk4iwWiXoU~ zF(Q(kBALKJF5ZX37rq}Dr$g1%2j0gS4O_?EMA9Xian8ttdqUOMt(B*t#tHX^>%)Je zC>n?mW)Wwjx*XvR_Zw#}tXrm!3pokTJX5G+++twZ=H5*&!!jh(3wA1B}9hM};N! zHJVP?SBU!cR;DO2<^{&MuPEiT)TvOR0gF6MR%h||A98l$_T)@K?r6UiM57>led8%H zNZE{Wlu=u9QW5f|Z_ETEN4TUx@t98tkR0_)svZO&W@%}NU}=*^?zdA6Mau9G*rJqF z6f>`AL*W&q;DN6&hMVzI1i=LwP_Z~0F}bab{lWw>OLR*-DpE1lcSAy^rK)2@5Scia zC@#~q3vLExqY8|fcMLcr$;1Q(5;Smkc&9-KY(nGXqLPT#a$htEQ(Do7i02T#a*>b* zvgE%~s>ry48F6z^1$By05i0VVT8c@R7ISixD4>7G?yAJ(O5JM9RRS{=XlT)CTsumq zg&gV4)0GE+`cypeX`~>)6CJEca|XLQ8xO!c>{N!2^)^L@nhQ;lqO&XS@bGemK9-1g z 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