diff --git a/.flake8 b/.flake8 index e107c2c..96ca3bc 100644 --- a/.flake8 +++ b/.flake8 @@ -5,3 +5,4 @@ select = B,C,E,F,W,B001,B003,B006,B007,B301,B305,B306,B902,Q000,Q001,Q002,Q003 ignore = E203,E722,W503 exclude = .tox,build max-line-length = 120 +per-file-ignores = coincurve/__init__.py:F401 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b32e236..d4e4e14 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,7 @@ on: - master env: + PYTHON_VERSION_BUILD_EXTRA: '3.9' COINCURVE_UPSTREAM_REF: f2d9aeae6d5a7c7fbbba8bbb38b1849b784beef7 LD_LIBRARY_PATH: ./libsecp256k1_ext/.libs DYLD_FALLBACK_LIBRARY_PATH: ./libsecp256k1_ext/.libs @@ -61,9 +62,9 @@ jobs: - name: Run tests run: tox -e ${PYTHON_VERSION},bench - # - name: Lint - # if: startsWith(matrix.os, 'ubuntu-') && matrix.python-version == '3.9' && always() - # run: tox -e lint + - name: Lint + if: startsWith(matrix.os, 'ubuntu-') && matrix.python-version == env.PYTHON_VERSION_BUILD_EXTRA && always() + run: tox -e lint - name: Upload coverage run: codecov -X gcov @@ -84,7 +85,6 @@ jobs: env: PYTHON_VERSION: ${{ matrix.python-version }} OS_NAME: ${{ matrix.os }} - PYTHON_VERSION_BUILD_EXTRA: '3.9' steps: - uses: actions/checkout@v2 diff --git a/_cffi_build/build.py b/_cffi_build/build.py index ea5c66c..29c9836 100644 --- a/_cffi_build/build.py +++ b/_cffi_build/build.py @@ -3,7 +3,6 @@ from collections import namedtuple from cffi import FFI - here = os.path.dirname(os.path.abspath(__file__)) Source = namedtuple('Source', ('h', 'include')) @@ -23,6 +22,7 @@ def _mk_ffi(sources, name='_libsecp256k1', **kwargs): return _ffi + modules = [ Source('secp256k1.h', '#include '), Source('secp256k1_ecdh.h', '#include '), diff --git a/coincurve/context.py b/coincurve/context.py index d986c28..b01bd80 100644 --- a/coincurve/context.py +++ b/coincurve/context.py @@ -2,6 +2,7 @@ from os import urandom from threading import Lock from coincurve.flags import CONTEXT_ALL, CONTEXT_FLAGS + from ._libsecp256k1 import ffi, lib diff --git a/coincurve/ecdsa.py b/coincurve/ecdsa.py index 1a18a6c..8d14bd0 100644 --- a/coincurve/ecdsa.py +++ b/coincurve/ecdsa.py @@ -1,5 +1,6 @@ from coincurve.context import GLOBAL_CONTEXT from coincurve.utils import bytes_to_int, int_to_bytes, sha256 + from ._libsecp256k1 import ffi, lib MAX_SIG_LENGTH = 72 @@ -48,12 +49,12 @@ def serialize_recoverable(recover_sig, context=GLOBAL_CONTEXT): def deserialize_recoverable(serialized, context=GLOBAL_CONTEXT): if len(serialized) != 65: - raise ValueError("Serialized signature must be 65 bytes long.") + raise ValueError('Serialized signature must be 65 bytes long.') ser_sig, rec_id = serialized[:64], bytes_to_int(serialized[64:]) if not 0 <= rec_id <= 3: - raise ValueError("Invalid recovery id.") + raise ValueError('Invalid recovery id.') recover_sig = ffi.new('secp256k1_ecdsa_recoverable_signature *') @@ -81,7 +82,7 @@ def serialize_compact(raw_sig, context=GLOBAL_CONTEXT): # no cov def deserialize_compact(ser_sig, context=GLOBAL_CONTEXT): # no cov if len(ser_sig) != 64: - raise Exception("invalid signature length") + raise Exception('invalid signature length') raw_sig = ffi.new('secp256k1_ecdsa_signature *') res = lib.secp256k1_ecdsa_signature_parse_compact(context.ctx, raw_sig, ser_sig) diff --git a/coincurve/keys.py b/coincurve/keys.py index a42d24b..38ddc6a 100644 --- a/coincurve/keys.py +++ b/coincurve/keys.py @@ -14,6 +14,7 @@ from coincurve.utils import ( sha256, validate_secret, ) + from ._libsecp256k1 import ffi, lib DEFAULT_NONCE = (ffi.NULL, ffi.NULL) diff --git a/coincurve/utils.py b/coincurve/utils.py index 0478f95..d803048 100644 --- a/coincurve/utils.py +++ b/coincurve/utils.py @@ -3,6 +3,7 @@ from hashlib import sha256 as _sha256 from os import urandom from coincurve.context import GLOBAL_CONTEXT + from ._libsecp256k1 import ffi, lib GROUP_ORDER = ( diff --git a/pyproject.toml b/pyproject.toml index 0b6b160..50e14bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,3 +23,13 @@ exclude = ''' | _libsecp256k1\.py$ ) ''' + +[tool.isort] +default_section = 'THIRDPARTY' +force_grid_wrap = 0 +include_trailing_comma = true +known_first_party = 'coincurve' +line_length = 120 +multi_line_output = 3 +skip_glob = 'setup.py' +use_parentheses = true diff --git a/setup.py b/setup.py index 1caede0..64bb09a 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ except ImportError: sys.path.append(os.path.abspath(os.path.dirname(__file__))) -from setup_support import absolute, build_flags, detect_dll, has_system_lib +from setup_support import absolute, build_flags, detect_dll, has_system_lib # noqa: E402 BUILDING_FOR_WINDOWS = detect_dll() diff --git a/setup_support.py b/setup_support.py index e5fc1fb..fcd1d9d 100644 --- a/setup_support.py +++ b/setup_support.py @@ -1,11 +1,10 @@ import glob import os import shutil +import subprocess from contextlib import contextmanager from tempfile import mkdtemp -import subprocess - @contextmanager def workdir(): @@ -42,20 +41,20 @@ def build_flags(library, type_, path): """Return separated build flags from pkg-config output""" pkg_config_path = [path] - if "PKG_CONFIG_PATH" in os.environ: + if 'PKG_CONFIG_PATH' in os.environ: pkg_config_path.append(os.environ['PKG_CONFIG_PATH']) - if "LIB_DIR" in os.environ: + if 'LIB_DIR' in os.environ: pkg_config_path.append(os.environ['LIB_DIR']) - pkg_config_path.append(os.path.join(os.environ['LIB_DIR'], "pkgconfig")) + pkg_config_path.append(os.path.join(os.environ['LIB_DIR'], 'pkgconfig')) - options = ["--static", {'I': "--cflags-only-I", 'L': "--libs-only-L", 'l': "--libs-only-l"}[type_]] + options = ['--static', {'I': '--cflags-only-I', 'L': '--libs-only-L', 'l': '--libs-only-l'}[type_]] return [ - flag.strip("-{}".format(type_)) + flag.strip('-{}'.format(type_)) for flag in subprocess.check_output( - ["pkg-config"] + options + [library], env=dict(os.environ, PKG_CONFIG_PATH=":".join(pkg_config_path)) + ['pkg-config'] + options + [library], env=dict(os.environ, PKG_CONFIG_PATH=':'.join(pkg_config_path)) ) - .decode("UTF-8") + .decode('UTF-8') .split() ] @@ -68,7 +67,7 @@ def _find_lib(): ffi = FFI() try: - ffi.dlopen("secp256k1") + ffi.dlopen('secp256k1') if os.path.exists('/usr/include/secp256k1_ecdh.h'): return True else: @@ -76,7 +75,7 @@ def _find_lib(): return False except OSError: if 'LIB_DIR' in os.environ: - for path in glob.glob(os.path.join(os.environ['LIB_DIR'], "*secp256k1*")): + for path in glob.glob(os.path.join(os.environ['LIB_DIR'], '*secp256k1*')): try: FFI().dlopen(path) return True diff --git a/tests/samples.py b/tests/samples.py index d71cdb2..20faf0b 100644 --- a/tests/samples.py +++ b/tests/samples.py @@ -1,12 +1,12 @@ PRIVATE_KEY_BYTES = b'\xc2\x8a\x9f\x80s\x8fw\rRx\x03\xa5f\xcfo\xc3\xed\xf6\xce\xa5\x86\xc4\xfcJR#\xa5\xady~\x1a\xc3' PRIVATE_KEY_DER = ( - b"0\x81\x84\x02\x01\x000\x10\x06\x07*\x86H\xce=\x02\x01\x06" - b"\x05+\x81\x04\x00\n\x04m0k\x02\x01\x01\x04 \xc2\x8a\x9f" - b"\x80s\x8fw\rRx\x03\xa5f\xcfo\xc3\xed\xf6\xce\xa5\x86\xc4" - b"\xfcJR#\xa5\xady~\x1a\xc3\xa1D\x03B\x00\x04=\\(u\xc9\xbd" + b'0\x81\x84\x02\x01\x000\x10\x06\x07*\x86H\xce=\x02\x01\x06' + b'\x05+\x81\x04\x00\n\x04m0k\x02\x01\x01\x04 \xc2\x8a\x9f' + b'\x80s\x8fw\rRx\x03\xa5f\xcfo\xc3\xed\xf6\xce\xa5\x86\xc4' + b'\xfcJR#\xa5\xady~\x1a\xc3\xa1D\x03B\x00\x04=\\(u\xc9\xbd' b"\x11hu\xa7\x1a]\xb6L\xff\xcb\x139k\x16=\x03\x9b\x1d\x93'" - b"\x82H\x91\x80C4v\xa45**\xdd\x00\xeb\xb0\xd5\xc9LQ[r\xeb" - b"\x10\xf1\xfd\x8f?\x03\xb4/J+%[\xfc\x9a\xa9\xe3" + b'\x82H\x91\x80C4v\xa45**\xdd\x00\xeb\xb0\xd5\xc9LQ[r\xeb' + b'\x10\xf1\xfd\x8f?\x03\xb4/J+%[\xfc\x9a\xa9\xe3' ) PRIVATE_KEY_HEX = 'c28a9f80738f770d527803a566cf6fc3edf6cea586c4fc4a5223a5ad797e1ac3' PRIVATE_KEY_NUM = 87993618360805341115891506172036624893404292644470266399436498750715784469187 @@ -19,9 +19,9 @@ PRIVATE_KEY_PEM = ( ) PUBLIC_KEY_COMPRESSED = b"\x03=\\(u\xc9\xbd\x11hu\xa7\x1a]\xb6L\xff\xcb\x139k\x16=\x03\x9b\x1d\x93'\x82H\x91\x80C4" PUBLIC_KEY_UNCOMPRESSED = ( - b"\x04=\\(u\xc9\xbd\x11hu\xa7\x1a]\xb6L\xff\xcb\x139k\x16=\x03" + b'\x04=\\(u\xc9\xbd\x11hu\xa7\x1a]\xb6L\xff\xcb\x139k\x16=\x03' b"\x9b\x1d\x93'\x82H\x91\x80C4v\xa45**\xdd\x00\xeb\xb0\xd5\xc9" - b"LQ[r\xeb\x10\xf1\xfd\x8f?\x03\xb4/J+%[\xfc\x9a\xa9\xe3" + b'LQ[r\xeb\x10\xf1\xfd\x8f?\x03\xb4/J+%[\xfc\x9a\xa9\xe3' ) PUBLIC_KEY_X = 27753912938952041417634381842191885283234814940840273460372041880794577257268 PUBLIC_KEY_Y = 53663045980837260634637807506183816949039230809110041985901491152185762425315 @@ -30,7 +30,7 @@ MESSAGE = ( b'\xdfw\xeb)\t2R8\xda5\x02\xadE\xdd\xce\xd2\xe0\xb4\xf1\x81\xe7\xdf' b':\xce\x82m\xcf\x99\xf3o\x9d\xe6\xfb\xe4\x98O\x88\xcfh\xbe\xfd\xc2' b'{\xafm\xb3\xff\xb4QR\xffPu$\xfc>A\'\x03t\xc5\xf9\xd8\xf3I,\xaa"*' - b'\xd7q\xfe\xb7]\x11\xa9uB\'d\x89\x03\'3\xb8/\x80\xa2#\x00\xa2\xfe' + b"\xd7q\xfe\xb7]\x11\xa9uB'd\x89\x03\'3\xb8/\x80\xa2#\x00\xa2\xfe" b'\xff\xae\xb0\x86\xc1/ o\xc8]?\xa05L\xff8\x8az\x92\xc9\xab\x9fg0|' b'\\5\x98\xfaG\x9b#\xec\x1a\xc5\x10\xd6\x08\x9c:\x01"\x0c\x812O/i' b'\xc4WI\x0c\r\xd8\x81-m1_\x14]$\xf8\x16\xef\x1e\x1d\xb0"Q\x1a\xcf' @@ -38,13 +38,13 @@ MESSAGE = ( b'\x84\x1a?No\x10T\xf8\xb8\xd3\x18\xa4\xaf' ) SIGNATURE = ( - b"0E\x02!\x00\xee$\x1b\x0e@fa\xd4<\x17)\xa7\n\xd0\xd7\xef\x90\xcd\x13" + b'0E\x02!\x00\xee$\x1b\x0e@fa\xd4<\x17)\xa7\n\xd0\xd7\xef\x90\xcd\x13' b"\xad`\xc1\x06[\xe0\x821\x96\xe29\x80'\x02 \r\x02\x13\xd2\xaf?\x92G" - b"\x80&8\x1cVz%2\xb0\x8a\xd0l\x0b4\x9c~\x93\x18\xad\xe4J\x9c-\n" + b'\x80&8\x1cVz%2\xb0\x8a\xd0l\x0b4\x9c~\x93\x18\xad\xe4J\x9c-\n' ) RECOVERABLE_SIGNATURE = ( - b"\xee$\x1b\x0e@fa\xd4<\x17)\xa7\n\xd0\xd7\xef\x90\xcd\x13" + b'\xee$\x1b\x0e@fa\xd4<\x17)\xa7\n\xd0\xd7\xef\x90\xcd\x13' b"\xad`\xc1\x06[\xe0\x821\x96\xe29\x80'\r\x02\x13\xd2\xaf?" - b"\x92G\x80&8\x1cVz%2\xb0\x8a\xd0l\x0b4\x9c~\x93\x18\xad" - b"\xe4J\x9c-\n\x00" + b'\x92G\x80&8\x1cVz%2\xb0\x8a\xd0l\x0b4\x9c~\x93\x18\xad' + b'\xe4J\x9c-\n\x00' ) diff --git a/tests/test_bench.py b/tests/test_bench.py index 05c9db2..1a1095d 100644 --- a/tests/test_bench.py +++ b/tests/test_bench.py @@ -1,5 +1,6 @@ from coincurve import PrivateKey, PublicKey, verify_signature -from .samples import PRIVATE_KEY_BYTES, PUBLIC_KEY_COMPRESSED, MESSAGE, SIGNATURE + +from .samples import MESSAGE, PRIVATE_KEY_BYTES, PUBLIC_KEY_COMPRESSED, SIGNATURE def test_verify_signature_util(benchmark): diff --git a/tests/test_ecdsa.py b/tests/test_ecdsa.py index aea05c7..c90a6e5 100644 --- a/tests/test_ecdsa.py +++ b/tests/test_ecdsa.py @@ -1,4 +1,5 @@ from coincurve.ecdsa import cdata_to_der, der_to_cdata + from .samples import SIGNATURE diff --git a/tests/test_keys.py b/tests/test_keys.py index 06a7473..e2a2b76 100644 --- a/tests/test_keys.py +++ b/tests/test_keys.py @@ -6,7 +6,9 @@ import pytest from coincurve.ecdsa import deserialize_recoverable, recover from coincurve.keys import PrivateKey, PublicKey from coincurve.utils import bytes_to_int, int_to_bytes_padded, verify_signature + from .samples import ( + MESSAGE, PRIVATE_KEY_BYTES, PRIVATE_KEY_DER, PRIVATE_KEY_HEX, @@ -16,12 +18,10 @@ from .samples import ( PUBLIC_KEY_UNCOMPRESSED, PUBLIC_KEY_X, PUBLIC_KEY_Y, - MESSAGE, - SIGNATURE, RECOVERABLE_SIGNATURE, + SIGNATURE, ) - G = PublicKey( b'\x04y\xbef~\xf9\xdc\xbb\xacU\xa0b\x95\xce\x87\x0b\x07\x02\x9b' b'\xfc\xdb-\xce(\xd9Y\xf2\x81[\x16\xf8\x17\x98H:\xdaw&\xa3\xc4e' diff --git a/tests/test_utils.py b/tests/test_utils.py index c05d6ef..39ba688 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -16,6 +16,7 @@ from coincurve.utils import ( validate_secret, verify_signature, ) + from .samples import MESSAGE, PRIVATE_KEY_DER, PUBLIC_KEY_COMPRESSED, PUBLIC_KEY_UNCOMPRESSED, SIGNATURE