internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: pyca/cryptography

Issue:
EC key loading fails with AssertionError on bad key
Example:

``` py
        numbers = ec.EllipticCurvePrivateNumbers(
            357646505660320080863666618182642070958081774038609089496899025506,
            ec.EllipticCurvePublicNumbers(
                -47250808410327023131573602008345894927686381772325561185532964,
                1120253292479243545483756778742719537373113335231773536789915,
                ec.SECP256R1(),
            )
        )
        with pytest.raises(ValueError):
            numbers.private_key(backend)
```

RIght now it fails with a syntax error because of #1415, once that's fixed we can debug the actual `AssertoinError`



Discussion:

Resolving patch:
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -984,6 +984,11 @@ def _ec_key_set_public_key_affine_coordinates(self, ctx, x, y):
         values.
         """
 
+        if x < 0 or y < 0:
+            raise ValueError(
+                "Invalid EC key. Both x and y must be non-negative."
+            )
+
         bn_x = self._int_to_bn(x)
         bn_y = self._int_to_bn(y)
 


Test patch:
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -274,6 +274,28 @@ def test_load_invalid_ec_key_from_numbers(self, backend):
         with pytest.raises(ValueError):
             numbers.private_key(backend)
 
+        numbers = ec.EllipticCurvePrivateNumbers(
+            357646505660320080863666618182642070958081774038609089496899025506,
+            ec.EllipticCurvePublicNumbers(
+                -4725080841032702313157360200834589492768638177232556118553296,
+                1120253292479243545483756778742719537373113335231773536789915,
+                ec.SECP256R1(),
+            )
+        )
+        with pytest.raises(ValueError):
+            numbers.private_key(backend)
+
+        numbers = ec.EllipticCurvePrivateNumbers(
+            357646505660320080863666618182642070958081774038609089496899025506,
+            ec.EllipticCurvePublicNumbers(
+                47250808410327023131573602008345894927686381772325561185532964,
+                -1120253292479243545483756778742719537373113335231773536789915,
+                ec.SECP256R1(),
+            )
+        )
+        with pytest.raises(ValueError):
+            numbers.private_key(backend)
+
     @pytest.mark.parametrize(
         "vector",
         load_vectors_from_file(
Repository: pyca/cryptography

Issue:
OpenSSL's HMAC Context isn't marked as implementing MACContext
It ought to be.



Discussion:
CommonCrypto's as well


Resolving patch:
diff --git a/cryptography/hazmat/backends/commoncrypto/hmac.py b/cryptography/hazmat/backends/commoncrypto/hmac.py
--- a/cryptography/hazmat/backends/commoncrypto/hmac.py
+++ b/cryptography/hazmat/backends/commoncrypto/hmac.py
@@ -18,6 +18,7 @@
 from cryptography.hazmat.primitives import interfaces
 
 
+@utils.register_interface(interfaces.MACContext)
 @utils.register_interface(interfaces.HashContext)
 class _HMACContext(object):
     def __init__(self, backend, key, algorithm, ctx=None):
diff --git a/cryptography/hazmat/backends/openssl/hmac.py b/cryptography/hazmat/backends/openssl/hmac.py
--- a/cryptography/hazmat/backends/openssl/hmac.py
+++ b/cryptography/hazmat/backends/openssl/hmac.py
@@ -19,6 +19,7 @@
 from cryptography.hazmat.primitives import interfaces
 
 
+@utils.register_interface(interfaces.MACContext)
 @utils.register_interface(interfaces.HashContext)
 class _HMACContext(object):
     def __init__(self, backend, key, algorithm, ctx=None):


Test patch:
Repository: pyca/cryptography

Issue:
Remove pragma nocovers from Windows specific code
See #502 



Discussion:

Resolving patch:
diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py
--- a/cryptography/hazmat/bindings/openssl/binding.py
+++ b/cryptography/hazmat/bindings/openssl/binding.py
@@ -95,15 +95,7 @@ def _ensure_ffi_initialized(cls):
 
         # OpenSSL goes by a different library name on different operating
         # systems.
-        if sys.platform != "win32":
-            # In some circumstances, the order in which these libs are
-            # specified on the linker command-line is significant;
-            # libssl must come before libcrypto
-            # (http://marc.info/?l=openssl-users&m=135361825921871)
-            libraries = ["ssl", "crypto"]
-        else:  # pragma: no cover
-            link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
-            libraries = _get_windows_libraries(link_type)
+        libraries = _get_libraries(sys.platform)
 
         cls.ffi, cls.lib = build_ffi_for_binding(
             module_prefix=cls._module_prefix,
@@ -156,6 +148,18 @@ def _lock_cb(cls, mode, n, file, line):
             )
 
 
+def _get_libraries(platform):
+    if platform != "win32":
+        # In some circumstances, the order in which these libs are
+        # specified on the linker command-line is significant;
+        # libssl must come before libcrypto
+        # (http://marc.info/?l=openssl-users&m=135361825921871)
+        return ["ssl", "crypto"]
+    else:
+        link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
+        return _get_windows_libraries(link_type)
+
+
 def _get_windows_libraries(link_type):
     if link_type == "dynamic":
         return ["libeay32", "ssleay32", "advapi32"]


Test patch:
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
--- a/tests/hazmat/bindings/test_openssl.py
+++ b/tests/hazmat/bindings/test_openssl.py
@@ -16,7 +16,7 @@
 import pytest
 
 from cryptography.hazmat.bindings.openssl.binding import (
-    Binding, _get_windows_libraries
+    Binding, _get_libraries, _get_windows_libraries
 )
 
 
@@ -143,6 +143,10 @@ def test_ssl_mode(self):
         assert resp == expected_options
         assert b.lib.SSL_get_mode(ssl) == expected_options
 
+    def test_libraries(self):
+        assert _get_libraries("darwin") == ["ssl", "crypto"]
+        assert "ssleay32mt" in _get_libraries("win32")
+
     def test_windows_static_dynamic_libraries(self):
         assert "ssleay32mt" in _get_windows_libraries("static")
Repository: pyca/cryptography

Issue:
Monitor what debian's doing with SSLv3
http://bugs.python.org/issue22935 suggests that they might change the define they're using. /cc @mithrandi



Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/cryptography/hazmat/bindings/openssl/ssl.py
@@ -15,7 +15,7 @@
  * Internally invented symbols to tell which versions of SSL/TLS are supported.
 */
 static const long Cryptography_HAS_SSL2;
-static const long Cryptography_HAS_SSL3_METHOD;
+static const long Cryptography_HAS_SSL3;
 static const long Cryptography_HAS_TLSv1_1;
 static const long Cryptography_HAS_TLSv1_2;
 static const long Cryptography_HAS_SECURE_RENEGOTIATION;
@@ -385,13 +385,13 @@
 static const long Cryptography_HAS_SSL2 = 1;
 #endif
 
-#ifdef OPENSSL_NO_SSL3_METHOD
-static const long Cryptography_HAS_SSL3_METHOD = 0;
+#ifdef OPENSSL_NO_SSL3
+static const long Cryptography_HAS_SSL3 = 0;
 SSL_METHOD* (*SSLv3_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_client_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_server_method)(void) = NULL;
 #else
-static const long Cryptography_HAS_SSL3_METHOD = 1;
+static const long Cryptography_HAS_SSL3 = 1;
 #endif
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -564,7 +564,7 @@
         "SSLv2_server_method",
     ],
 
-    "Cryptography_HAS_SSL3_METHOD": [
+    "Cryptography_HAS_SSL3": [
         "SSLv3_method",
         "SSLv3_client_method",
         "SSLv3_server_method",


Test patch:
Repository: pyca/cryptography

Issue:
Bind SSL_CTX_check_private_key
pyOpenSSL 0.14 needed this (oops).  pyOpenSSL 0.15 will definitely need it.



Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/cryptography/hazmat/bindings/openssl/ssl.py
@@ -211,6 +211,8 @@
 int SSL_CTX_use_certificate_chain_file(SSL_CTX *, const char *);
 int SSL_CTX_use_PrivateKey(SSL_CTX *, EVP_PKEY *);
 int SSL_CTX_use_PrivateKey_file(SSL_CTX *, const char *, int);
+int SSL_CTX_check_private_key(const SSL_CTX *);
+
 void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
 X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
 int SSL_CTX_add_client_CA(SSL_CTX *, X509 *);


Test patch:
Repository: pyca/cryptography

Issue:
Release Automation Fixes for Seventh Release
The release script is not properly waiting for the wheel job it starts to finish before downloading. This causes it to download previous releases and attempt to upload them.



Discussion:
I'm guessing the bug is that `wait_for_build_completed` is called so quickly that it actually checks the status of the previous build? Does that sound right to you?

That'd be my guess, yes.

I think the right thing to do is get the `id` out of the `POST /build` and use that in the endpoint to poll, instead of `/lastBuild/`.

@reaperhulk you hit an issue doing 0.6.1 right? Can taht get recorded here?

Both the `/lastBuild` issue as well as failing to upload the sdist of `cryptography_vectors` occurred for the 0.6.1 release.

The fix for our sdist upload issue is in pypa/twine master.

There's a new twine release fixing that.

If we can't get a fix for triggering the build in there, can we just put a sleep(3) so it at least works correctly?

sleep(3) (or whatever number) is probably a useful bandaid for the moment.

On Mon, Dec 15, 2014 at 3:38 PM, Alex Gaynor notifications@github.com
wrote:

> There's a new twine release fixing that.
> 
> If we can't get a fix for triggering the build in there, can we just put a
> sleep(3) so it at least works correctly?
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/pyca/cryptography/issues/1372#issuecomment-67070687.


Resolving patch:
diff --git a/tasks.py b/tasks.py
--- a/tasks.py
+++ b/tasks.py
@@ -17,6 +17,9 @@
 
 
 def wait_for_build_completed(session):
+    # Wait 3 seconds before actually checking if the build is complete, to
+    # ensure that it had time to really start.
+    time.sleep(3)
     while True:
         response = session.get(
             "{0}/lastBuild/api/json/".format(JENKINS_URL),


Test patch:
Repository: pyca/cryptography

Issue:
Don't install enum34 on Python3.4+



Discussion:
@dstufft is there going to be anything to this besides besides a branch in `setup.py` on `sys.version_info`?

The wheel file too.

https://github.com/pypa/twine/blob/master/setup.cfg#L9-L13

Can we use `python_version < '3.4'`?

On Wed Dec 17 2014 at 11:11:15 PM Donald Stufft notifications@github.com
wrote:

> https://github.com/pypa/twine/blob/master/setup.cfg#L9-L13
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/pyca/cryptography/issues/1547#issuecomment-67448952.

It's going to use string sorting as of right now, though maybe we should change that in pip 6.


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -36,12 +36,14 @@
 
 requirements = [
     CFFI_DEPENDENCY,
-    "enum34",
     "pyasn1",
     SIX_DEPENDENCY,
     SETUPTOOLS_DEPENDENCY
 ]
 
+if sys.version_info < (3, 4):
+    requirements.append("enum34")
+
 # If you add a new dep here you probably need to add it in the tox.ini as well
 test_requirements = [
     "pytest",


Test patch:
Repository: pyca/cryptography

Issue:
raises_unsupported_algorithm gives very unhelpful errors
When the error tag is wrong you get errors along the lines of `assert <object object at 0xf0000000> is not <object object as 0xb0000000>`. This is not very helpful, it's not even particularly obvious that the error tag is actually what's wrong until you go and read the code.

Should probably generate a useful error message or somehow give the tag objects a more useful `repr` output.



Discussion:

Resolving patch:
diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py
--- a/src/cryptography/exceptions.py
+++ b/src/cryptography/exceptions.py
@@ -4,17 +4,19 @@
 
 from __future__ import absolute_import, division, print_function
 
-
-class _Reasons(object):
-    BACKEND_MISSING_INTERFACE = object()
-    UNSUPPORTED_HASH = object()
-    UNSUPPORTED_CIPHER = object()
-    UNSUPPORTED_PADDING = object()
-    UNSUPPORTED_MGF = object()
-    UNSUPPORTED_PUBLIC_KEY_ALGORITHM = object()
-    UNSUPPORTED_ELLIPTIC_CURVE = object()
-    UNSUPPORTED_SERIALIZATION = object()
-    UNSUPPORTED_X509 = object()
+from enum import Enum
+
+
+class _Reasons(Enum):
+    BACKEND_MISSING_INTERFACE = 0
+    UNSUPPORTED_HASH = 1
+    UNSUPPORTED_CIPHER = 2
+    UNSUPPORTED_PADDING = 3
+    UNSUPPORTED_MGF = 4
+    UNSUPPORTED_PUBLIC_KEY_ALGORITHM = 5
+    UNSUPPORTED_ELLIPTIC_CURVE = 6
+    UNSUPPORTED_SERIALIZATION = 7
+    UNSUPPORTED_X509 = 8
 
 
 class UnsupportedAlgorithm(Exception):


Test patch:
Repository: pyca/cryptography

Issue:
Build automation fixes for 8th release
When triggering the wheel build the release automation does not appropriately wait for the build to complete but instead grabs the previous build. The previous attempted fix of adding a `sleep(3)` did not work around this issue.



Discussion:

Resolving patch:
diff --git a/tasks.py b/tasks.py
--- a/tasks.py
+++ b/tasks.py
@@ -17,9 +17,9 @@
 
 
 def wait_for_build_completed(session):
-    # Wait 3 seconds before actually checking if the build is complete, to
+    # Wait 20 seconds before actually checking if the build is complete, to
     # ensure that it had time to really start.
-    time.sleep(3)
+    time.sleep(20)
     while True:
         response = session.get(
             "{0}/lastBuild/api/json/".format(JENKINS_URL),


Test patch:
Repository: pyca/cryptography

Issue:
Monitor what debian's doing with SSLv3
http://bugs.python.org/issue22935 suggests that they might change the define they're using. /cc @mithrandi

Possibly revert #1512
Upstream OpenSSL does not remove the SSLv3 functions if `OPENSSL_NO_SSL3` is defined. There is some discussion (http://bugs.python.org/issue22935) about whether or not this will change, but as of now our current code causes an installation failure if `OPENSSL_NO_SSL3` is defined.



Discussion:

Right now we do have the same code as CPython, I think maybe we should just follow their lead, since hte relevant debian folks are directly engaged there.

I think a difference though is that CPython can just not define something if `OPENSSL_NO_SSL3` is defined but we can't, we have to define it as `NULL` which causes an error if someone compiles OpenSSL without patching OpenSSL to make `OPENSSL_NO_SSL3` remove the methods.

I ran into this problem in debian jessie, when trying to install the pyopenssl package (that depends on cryptography, when trying to compile it simply says:

error: ‘SSLv3_method’ redeclared as different kind of symbol

As explained above, OpenSSL still defines SSLv3_method and your redefinition breaks it (maybe undef if OPENSSL_NO_SSL3 is defined?)

For now I am explicitly installing cryptography 0.6.1 before installing pyopenssl, I'll be waiting for a fix, but I can help if needed

+1 to @bwgpro comment

We've had several more people come into the IRC channel with this problem.


Resolving patch:
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/cryptography/hazmat/bindings/openssl/ssl.py
@@ -15,7 +15,7 @@
  * Internally invented symbols to tell which versions of SSL/TLS are supported.
 */
 static const long Cryptography_HAS_SSL2;
-static const long Cryptography_HAS_SSL3;
+static const long Cryptography_HAS_SSL3_METHOD;
 static const long Cryptography_HAS_TLSv1_1;
 static const long Cryptography_HAS_TLSv1_2;
 static const long Cryptography_HAS_SECURE_RENEGOTIATION;
@@ -387,13 +387,13 @@
 static const long Cryptography_HAS_SSL2 = 1;
 #endif
 
-#ifdef OPENSSL_NO_SSL3
-static const long Cryptography_HAS_SSL3 = 0;
+#ifdef OPENSSL_NO_SSL3_METHOD
+static const long Cryptography_HAS_SSL3_METHOD = 0;
 SSL_METHOD* (*SSLv3_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_client_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_server_method)(void) = NULL;
 #else
-static const long Cryptography_HAS_SSL3 = 1;
+static const long Cryptography_HAS_SSL3_METHOD = 1;
 #endif
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -566,7 +566,7 @@
         "SSLv2_server_method",
     ],
 
-    "Cryptography_HAS_SSL3": [
+    "Cryptography_HAS_SSL3_METHOD": [
         "SSLv3_method",
         "SSLv3_client_method",
         "SSLv3_server_method",


Test patch:
Repository: pyca/cryptography

Issue:
Monitor what debian's doing with SSLv3
http://bugs.python.org/issue22935 suggests that they might change the define they're using. /cc @mithrandi



Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/cryptography/hazmat/bindings/openssl/ssl.py
@@ -15,7 +15,7 @@
  * Internally invented symbols to tell which versions of SSL/TLS are supported.
 */
 static const long Cryptography_HAS_SSL2;
-static const long Cryptography_HAS_SSL3;
+static const long Cryptography_HAS_SSL3_METHOD;
 static const long Cryptography_HAS_TLSv1_1;
 static const long Cryptography_HAS_TLSv1_2;
 static const long Cryptography_HAS_SECURE_RENEGOTIATION;
@@ -387,13 +387,13 @@
 static const long Cryptography_HAS_SSL2 = 1;
 #endif
 
-#ifdef OPENSSL_NO_SSL3
-static const long Cryptography_HAS_SSL3 = 0;
+#ifdef OPENSSL_NO_SSL3_METHOD
+static const long Cryptography_HAS_SSL3_METHOD = 0;
 SSL_METHOD* (*SSLv3_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_client_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_server_method)(void) = NULL;
 #else
-static const long Cryptography_HAS_SSL3 = 1;
+static const long Cryptography_HAS_SSL3_METHOD = 1;
 #endif
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -566,7 +566,7 @@
         "SSLv2_server_method",
     ],
 
-    "Cryptography_HAS_SSL3": [
+    "Cryptography_HAS_SSL3_METHOD": [
         "SSLv3_method",
         "SSLv3_client_method",
         "SSLv3_server_method",


Test patch:
Repository: pyca/cryptography

Issue:
Update year in copyright notice for vectors
Refs #1597 



Discussion:

Resolving patch:
diff --git a/vectors/cryptography_vectors/__about__.py b/vectors/cryptography_vectors/__about__.py
--- a/vectors/cryptography_vectors/__about__.py
+++ b/vectors/cryptography_vectors/__about__.py
@@ -20,4 +20,4 @@
 __email__ = "cryptography-dev@python.org"
 
 __license__ = "BSD or Apache License, Version 2.0"
-__copyright__ = "Copyright 2013-2014 %s" % __author__
+__copyright__ = "Copyright 2013-2015 %s" % __author__


Test patch:
Repository: pyca/cryptography

Issue:
Backend loading code produces a warning with the latest setuptools
The use `load(require=False)` (specifically the `require` kwarg) is deprecated. /cc @dstufft 



Discussion:
Change `ep.load(require=False)` to `getattr(ep, "resolve", lambda: ep.load(require=False))()`.

@dstufft I suppose it's not even remotely realistic for us to emit a warning on old versions of setuptools, or to require a newer version of setuptools in our `install_requires`?

You can emit a warning yes, that's pretty trivial but it would be a cryptography warning. There's no `PendingDeprecation` warning or anything in older setuptools for this. You can also require a newer version of setuptools in install_requires. It probably won't get installed when `setup.py` gets called but that's OK because this is a runtime use of setuptools we're concerned about.

The biggest problem really is that you make it annoying or hard to use/install cryptography on systems where setuptools is shipped by the system (like most *nix) and it's not a rolling release like Arch. Most likely they are going to have an older setuptools (how much older depending on the release cycle of that OS) and the ability to upgrade it isn't very good (a lot of things in the system are going to depend on it, so you're forced to either make your own OS package or use pip to upgrade it and have pip and the OS package manager fighting over who owns some files).

I should note that I'm hoping to fix the second paragraph by making PPA/copr etc for the popular distributions.

Ok, that all sounds frightening, let's go with the wacky `getattr` thing.


Resolving patch:
diff --git a/src/cryptography/hazmat/backends/__init__.py b/src/cryptography/hazmat/backends/__init__.py
--- a/src/cryptography/hazmat/backends/__init__.py
+++ b/src/cryptography/hazmat/backends/__init__.py
@@ -17,8 +17,13 @@ def _available_backends():
 
     if _available_backends_list is None:
         _available_backends_list = [
-            backend.load(require=False)
-            for backend in pkg_resources.iter_entry_points(
+            # setuptools 11.3 deprecated support for the require parameter to
+            # load(), and introduced the new resolve() method instead.
+            # This can be removed if/when we can assume setuptools>=11.3. At
+            # some point we may wish to add a warning, to push people along,
+            # but at present this would result in too many warnings.
+            ep.resolve() if hasattr(ep, "resolve") else ep.load(require=False)
+            for ep in pkg_resources.iter_entry_points(
                 "cryptography.backends"
             )
         ]


Test patch:
Repository: pyca/cryptography

Issue:
Move C code for padding into it's own .c and .h files
See `constant_time` for the same idea.



Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py
--- a/src/cryptography/hazmat/primitives/padding.py
+++ b/src/cryptography/hazmat/primitives/padding.py
@@ -6,6 +6,8 @@
 
 import abc
 
+import os
+
 import six
 
 from cryptography import utils
@@ -13,47 +15,11 @@
 from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi
 
 
-TYPES = """
-uint8_t Cryptography_check_pkcs7_padding(const uint8_t *, uint8_t);
-"""
-
-FUNCTIONS = """
-/* Returns the value of the input with the most-significant-bit copied to all
-   of the bits. */
-static uint8_t Cryptography_DUPLICATE_MSB_TO_ALL(uint8_t a) {
-    return (1 - (a >> (sizeof(uint8_t) * 8 - 1))) - 1;
-}
-
-/* This returns 0xFF if a < b else 0x00, but does so in a constant time
-   fashion */
-static uint8_t Cryptography_constant_time_lt(uint8_t a, uint8_t b) {
-    a -= b;
-    return Cryptography_DUPLICATE_MSB_TO_ALL(a);
-}
-
-uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data,
-                                         uint8_t block_len) {
-    uint8_t i;
-    uint8_t pad_size = data[block_len - 1];
-    uint8_t mismatch = 0;
-    for (i = 0; i < block_len; i++) {
-        unsigned int mask = Cryptography_constant_time_lt(i, pad_size);
-        uint8_t b = data[block_len - 1 - i];
-        mismatch |= (mask & (pad_size ^ b));
-    }
-
-    /* Check to make sure the pad_size was within the valid range. */
-    mismatch |= ~Cryptography_constant_time_lt(0, pad_size);
-    mismatch |= Cryptography_constant_time_lt(block_len, pad_size);
-
-    /* Make sure any bits set are copied to the lowest bit */
-    mismatch |= mismatch >> 4;
-    mismatch |= mismatch >> 2;
-    mismatch |= mismatch >> 1;
-    /* Now check the low bit to see if it's set */
-    return (mismatch & 1) == 0;
-}
-"""
+with open(os.path.join(os.path.dirname(__file__), "src/padding.h")) as f:
+    TYPES = f.read()
+
+with open(os.path.join(os.path.dirname(__file__), "src/padding.c")) as f:
+    FUNCTIONS = f.read()
 
 
 _ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS)


Test patch: