Skip to content

Commit

Permalink
perf: ⚡️ flake8 code style
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhaoQi99 committed Apr 12, 2022
1 parent 52341e6 commit 74eccec
Show file tree
Hide file tree
Showing 17 changed files with 116 additions and 100 deletions.
11 changes: 6 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ jobs:
run: |
pip install --upgrade pip
pip install setuptools==57.5.0
pip install flake8 pytest
pip install -r dev-requirement.txt
pip install .
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# Run flake8 on Python files
flake8 pyencrypt --count --show-source --max-complexity=10 --statistics
# Run flake8 on test files
flake8 tests --count --show-source --max-complexity=10 --statistics --ignore F401,E501
- name: Test with pytest
run: |
pytest
3 changes: 2 additions & 1 deletion dev-requirement.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
isort==5.10.1
yapf==0.31.0
pytest==6.2.5
ipython==7.16.3
ipython==7.16.3
flake8==4.0.1
69 changes: 39 additions & 30 deletions pyencrypt/aes.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ class AES(object):
0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d
]

def __init__(self, key):
def __init__(self, key): # noqa: C901

if len(key) not in (16, 24, 32):
raise ValueError('Invalid key size')
Expand Down Expand Up @@ -675,10 +675,14 @@ def __init__(self, key):
while t < round_key_count:

tt = tk[KC - 1]
tk[0] ^= ((self.S[(tt >> 16) & 0xFF] << 24) ^
(self.S[(tt >> 8) & 0xFF] << 16) ^
(self.S[tt & 0xFF] << 8) ^ self.S[(tt >> 24) & 0xFF] ^
(self.rcon[rconpointer] << 24))
# noqa: W504
tk[0] ^= (
(self.S[(tt >> 16) & 0xFF] << 24) ^
(self.S[(tt >> 8) & 0xFF] << 16) ^
(self.S[tt & 0xFF] << 8) ^
self.S[(tt >> 24) & 0xFF] ^
(self.rcon[rconpointer] << 24)
)
rconpointer += 1

if KC != 8:
Expand All @@ -691,10 +695,12 @@ def __init__(self, key):
tk[i] ^= tk[i - 1]
tt = tk[KC // 2 - 1]

tk[KC //
2] ^= (self.S[tt & 0xFF] ^ (self.S[(tt >> 8) & 0xFF] << 8) ^
(self.S[(tt >> 16) & 0xFF] << 16) ^
(self.S[(tt >> 24) & 0xFF] << 24))
tk[KC // 2] ^= (
self.S[tt & 0xFF] ^
(self.S[(tt >> 8) & 0xFF] << 8) ^
(self.S[(tt >> 16) & 0xFF] << 16) ^
(self.S[(tt >> 24) & 0xFF] << 24)
)

for i in range(KC // 2 + 1, KC):
tk[i] ^= tk[i - 1]
Expand All @@ -711,10 +717,12 @@ def __init__(self, key):
for r in range(1, rounds):
for j in range(0, 4):
tt = self._Kd[r][j]
self._Kd[r][j] = (self.U1[(tt >> 24) & 0xFF]
^ self.U2[(tt >> 16) & 0xFF]
^ self.U3[(tt >> 8) & 0xFF]
^ self.U4[tt & 0xFF])
self._Kd[r][j] = (
self.U1[(tt >> 24) & 0xFF] ^
self.U2[(tt >> 16) & 0xFF] ^
self.U3[(tt >> 8) & 0xFF] ^
self.U4[tt & 0xFF]
)

def encrypt(self, plaintext):
'Encrypt a block of plain text using the AES block cipher.'
Expand All @@ -733,21 +741,22 @@ def encrypt(self, plaintext):
# Apply round transforms
for r in range(1, rounds):
for i in range(0, 4):
a[i] = (self.T1[(t[i] >> 24) & 0xFF]
^ self.T2[(t[(i + s1) % 4] >> 16) & 0xFF]
^ self.T3[(t[(i + s2) % 4] >> 8) & 0xFF]
^ self.T4[t[(i + s3) % 4] & 0xFF] ^ self._Ke[r][i])
a[i] = (
self.T1[(t[i] >> 24) & 0xFF] ^
self.T2[(t[(i + s1) % 4] >> 16) & 0xFF] ^
self.T3[(t[(i + s2) % 4] >> 8) & 0xFF] ^
self.T4[t[(i + s3) % 4] & 0xFF] ^
self._Ke[r][i]
)
t = copy.copy(a)

# The last round is special
result = []
for i in range(0, 4):
tt = self._Ke[rounds][i]
result.append((self.S[(t[i] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
result.append((self.S[(t[(i + s1) % 4] >> 16) & 0xFF] ^ (tt >> 16))
& 0xFF)
result.append((self.S[(t[(i + s2) % 4] >> 8) & 0xFF] ^ (tt >> 8))
& 0xFF)
result.append((self.S[(t[(i + s1) % 4] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
result.append((self.S[(t[(i + s2) % 4] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
result.append((self.S[t[(i + s3) % 4] & 0xFF] ^ tt) & 0xFF)

return result
Expand All @@ -769,28 +778,29 @@ def decrypt(self, ciphertext):
# Apply round transforms
for r in range(1, rounds):
for i in range(0, 4):
a[i] = (self.T5[(t[i] >> 24) & 0xFF]
^ self.T6[(t[(i + s1) % 4] >> 16) & 0xFF]
^ self.T7[(t[(i + s2) % 4] >> 8) & 0xFF]
^ self.T8[t[(i + s3) % 4] & 0xFF] ^ self._Kd[r][i])
a[i] = (
self.T5[(t[i] >> 24) & 0xFF] ^
self.T6[(t[(i + s1) % 4] >> 16) & 0xFF] ^
self.T7[(t[(i + s2) % 4] >> 8) & 0xFF] ^
self.T8[t[(i + s3) % 4] & 0xFF] ^ self._Kd[r][i]
)
t = copy.copy(a)

# The last round is special
result = []
for i in range(0, 4):
tt = self._Kd[rounds][i]
result.append((self.Si[(t[i] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
result.append((self.Si[(t[(i + s1) % 4] >> 16) & 0xFF]
^ (tt >> 16)) & 0xFF)
result.append((self.Si[(t[(i + s2) % 4] >> 8) & 0xFF] ^ (tt >> 8))
& 0xFF)
result.append((self.Si[(t[(i + s1) % 4] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
result.append((self.Si[(t[(i + s2) % 4] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
result.append((self.Si[t[(i + s3) % 4] & 0xFF] ^ tt) & 0xFF)

return result


class AESBlockModeOfOperation(object):
'''Super-class for AES modes of operation that require blocks.'''

def __init__(self, key):
self._aes = AES(key)

Expand Down Expand Up @@ -847,4 +857,3 @@ def aes_decrypt(data: bytes, key: str) -> bytes:
for x in [data[i:i + 16] for i in range(0, len(data), 16)]:
plain.append(AESModeOfOperationECB(key).decrypt(x))
return strip_padding(b''.join(plain))

6 changes: 3 additions & 3 deletions pyencrypt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from pyencrypt.generate import generate_aes_key
from pyencrypt.license import MAX_DATETIME, MIN_DATETIME, generate_license_file

VERSION = f"""\
VERSION = fr"""
_
_ __ _ _ ___ _ __ ___ _ __ _ _ _ __ | |_
| '_ \| | | |/ _ \ '_ \ / __| '__| | | | '_ \| __|
Expand All @@ -29,9 +29,8 @@
"""

KEY_OPTION_HELP = """
Your encryption key.If you dont specify key,
Your encryption key.If you don't specify key,
pyencrypt will generate encryption key randomly.
"""

PYTHON_MAJOR, PYTHON_MINOR = sys.version_info[:2]
Expand Down Expand Up @@ -123,6 +122,7 @@ def get_metavar(self, param):
def __repr__(self) -> str:
return "Ipv4Address"


class CustomParamType:
KEY = KeyParamType()
MAC_ADDR = MacAddressParamType()
Expand Down
3 changes: 2 additions & 1 deletion pyencrypt/encrypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def generate_so_file(cipher_key: str, d: int, n: int, base_dir: Path = None, lic
need_import_files = ['ntt.py', 'aes.py', 'decrypt.py', 'license.py']
for file in need_import_files:
file_path = path / file
decrypt_source_ls.append(REMOVE_SELF_IMPORT.sub('',file_path.read_text()))
decrypt_source_ls.append(REMOVE_SELF_IMPORT.sub('', file_path.read_text()))

loader_source_path = path / 'loader.py'
loader_source = REMOVE_SELF_IMPORT.sub('', loader_source_path.read_text()).replace(
Expand Down Expand Up @@ -104,6 +104,7 @@ def generate_so_file(cipher_key: str, d: int, n: int, base_dir: Path = None, lic
)
return list(temp_dir.glob('loader.cpython-*-*.so'))[0].absolute()


def encrypt_file(path: Path, key: str, delete_origin: bool = False, new_path: Path = None):
if not can_encrypt(path):
raise Exception(f"{path.name} can't be encrypted.")
Expand Down
2 changes: 1 addition & 1 deletion pyencrypt/license.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@ def check_license(license_path: Path, aes_key: str):
raise Exception("Machine mac address is invalid.")
if ipv4 and ipv4 != get_host_ipv4():
raise Exception("Machine ipv4 address is invalid.")
return True
return True
2 changes: 1 addition & 1 deletion pyencrypt/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ def find_spec(self, fullname: str, path: Sequence[_Path], target: types.ModuleTy


# TODO: generate randomly AES Class
sys.meta_path.insert(0,EncryptFileFinder())
sys.meta_path.insert(0, EncryptFileFinder())
5 changes: 2 additions & 3 deletions pyencrypt/ntt.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ def bitreverse(x: list, length: int):
for i in range(0, length):
if i > j:
x[i], x[j] = x[j], x[i]
l = length >> 1
l = length >> 1 # noqa: E741
while True:
j = j ^ l
if j >= l:
break
l >>= 1
l >>= 1 # noqa: E741


def _ntt(arr: list, inverse=False):
Expand Down Expand Up @@ -51,4 +51,3 @@ def ntt(arr: list):

def intt(arr: list):
return _ntt(arr, True)

6 changes: 5 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,8 @@ based_on_style = pep8
COLUMN_LIMIT = 119
indent_width = 4
coalesce_brackets = True
dedent_closing_brackets = True
dedent_closing_brackets = True

[flake8]
max_line_length = 119
ignore = E501,W504
16 changes: 6 additions & 10 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest
from pathlib import Path
from pyencrypt.encrypt import encrypt_file, encrypt_key, generate_so_file
from pyencrypt.generate import generate_aes_key
from pyencrypt.license import generate_license_file
Expand All @@ -21,19 +20,17 @@ def file_and_loader(request, tmp_path_factory):
code = file_marker.kwargs.get('code')

license_marker = request.node.get_closest_marker("license")
license, kwargs = False,{}
license, kwargs = False, {}
if license_marker is not None:
kwargs = license_marker.kwargs
license = kwargs.pop('enable', True)

file_path = tmp_path / f'{file_name}.py'
file_path.touch()
file_path.write_text(
"""\
file_path.write_text("""\
def {function_name}():
{code}
""".format(function_name=function_name, code=code)
)
""".format(function_name=function_name, code=code))
# generate loader.so
key = generate_aes_key()
new_path = file_path.with_suffix('.pye')
Expand All @@ -47,12 +44,11 @@ def {function_name}():
work_dir.joinpath('loader_origin.py').unlink()

# License
license == True and generate_license_file(key.decode(), work_dir,**kwargs)
license and generate_license_file(key.decode(), work_dir, **kwargs)
generate_license_file(key.decode(), work_dir)
return (new_path, loader_path)



@pytest.fixture(scope='function')
def package_and_loader(request, tmp_path_factory):
pkg_path = tmp_path_factory.mktemp('package')
Expand All @@ -63,7 +59,7 @@ def package_and_loader(request, tmp_path_factory):
code = file_marker.kwargs.get('code')

license_marker = request.node.get_closest_marker("license")
license, kwargs = False,{}
license, kwargs = False, {}
if license_marker is not None:
kwargs = license_marker.kwargs
license = kwargs.pop('enable', True)
Expand Down Expand Up @@ -92,5 +88,5 @@ def {function_name}():
work_dir.joinpath('loader.c').unlink()
work_dir.joinpath('loader_origin.py').unlink()
# License
license == True and generate_license_file(key.decode(), work_dir, **kwargs)
license and generate_license_file(key.decode(), work_dir, **kwargs)
return pkg_path, loader_path
2 changes: 1 addition & 1 deletion tests/test_aes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyencrypt.aes import AESModeOfOperationECB, add_padding, aes_encrypt, aes_decrypt
from pyencrypt.aes import AESModeOfOperationECB, aes_encrypt, aes_decrypt
import pytest

from constants import AES_KEY
Expand Down
22 changes: 12 additions & 10 deletions tests/test_decrypt.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from pyencrypt.decrypt import *
from pyencrypt.encrypt import encrypt_file, encrypt_key
from constants import AES_KEY
import pytest
from pathlib import Path

import pytest
from pyencrypt.decrypt import decrypt_key, decrypt_file
from pyencrypt.encrypt import encrypt_file, encrypt_key
from pyencrypt.generate import generate_aes_key

from constants import AES_KEY


@pytest.mark.parametrize('key', [
AES_KEY,
Expand Down Expand Up @@ -39,24 +41,24 @@ def test_decrypt_file_exception(path, key, exception):


def test_decrypt_file_default(encrypted_python_file_path):
assert isinstance(decrypt_file(encrypted_python_file_path, AES_KEY), bytes) == True
assert encrypted_python_file_path.exists() == True
assert isinstance(decrypt_file(encrypted_python_file_path, AES_KEY), bytes) is True
assert encrypted_python_file_path.exists() is True


def test_decrypt_file_delete_origin(encrypted_python_file_path):
decrypt_file(encrypted_python_file_path, AES_KEY, delete_origin=True)
assert encrypted_python_file_path.exists() == False
assert encrypted_python_file_path.exists() is False


def test_decrypt_file_new_path(encrypted_python_file_path):
new_path = encrypted_python_file_path.parent / 'test.py'
decrypt_file(encrypted_python_file_path, AES_KEY, new_path=new_path)
assert new_path.exists() == True
assert encrypted_python_file_path.exists() == True
assert new_path.exists() is True
assert encrypted_python_file_path.exists() is True


def test_decrypt_file_new_path_exception(encrypted_python_file_path):
new_path = encrypted_python_file_path.parent / 'test.pye'
with pytest.raises(Exception) as excinfo:
decrypt_file(encrypted_python_file_path, AES_KEY, new_path=new_path)
assert str(excinfo.value) == 'Origin file path must be py suffix.'
assert str(excinfo.value) == 'Origin file path must be py suffix.'
Loading

0 comments on commit 74eccec

Please sign in to comment.