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

Issue:
__hash__() missing on EllipticCurvePublicNumbers and EllipticCurvePrivateNumbers
RSAPublicNumbers implements __hash__:

```
def __hash__(self):
    return hash((self.e, self.n))
```

Why doesn't EllipticCurvePublicNumbers and EllipticCurvePrivateNumbers similarly implement __hash__?



Discussion:
That's an oversight. If you'd like to contribute a PR we'll be happy to review!


Resolving patch:
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -302,6 +302,9 @@ def __eq__(self, other):
     def __ne__(self, other):
         return not self == other
 
+    def __hash__(self):
+        return hash((self.x, self.y, self.curve.name, self.curve.key_size))
+
     def __repr__(self):
         return (
             "<EllipticCurvePublicNumbers(curve={0.curve.name}, x={0.x}, "
@@ -341,6 +344,9 @@ def __eq__(self, other):
     def __ne__(self, other):
         return not self == other
 
+    def __hash__(self):
+        return hash((self.private_value, self.public_numbers))
+
 
 class ECDH(object):
     pass


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
@@ -223,6 +223,30 @@ def test_ec_public_numbers_repr():
     assert repr(pn) == "<EllipticCurvePublicNumbers(curve=secp256r1, x=2, y=3>"
 
 
+def test_ec_public_numbers_hash():
+    pn1 = ec.EllipticCurvePublicNumbers(2, 3, ec.SECP256R1())
+    pn2 = ec.EllipticCurvePublicNumbers(2, 3, ec.SECP256R1())
+    pn3 = ec.EllipticCurvePublicNumbers(1, 3, ec.SECP256R1())
+
+    assert hash(pn1) == hash(pn2)
+    assert hash(pn1) != hash(pn3)
+
+
+def test_ec_private_numbers_hash():
+    numbers1 = ec.EllipticCurvePrivateNumbers(
+        1, ec.EllipticCurvePublicNumbers(2, 3, DummyCurve())
+    )
+    numbers2 = ec.EllipticCurvePrivateNumbers(
+        1, ec.EllipticCurvePublicNumbers(2, 3, DummyCurve())
+    )
+    numbers3 = ec.EllipticCurvePrivateNumbers(
+        2, ec.EllipticCurvePublicNumbers(2, 3, DummyCurve())
+    )
+
+    assert hash(numbers1) == hash(numbers2)
+    assert hash(numbers1) != hash(numbers3)
+
+
 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
 class TestECWithNumbers(object):
     @pytest.mark.parametrize(
Repository: pyca/cryptography

Issue:
rsa.rsa_recover_prime_factors() should return p > q
The documentation for `rsa_recover_prime_factors()` warns that it returns `p` and `q` such that `p < q`. However, things like OpenSSL and BoringSSL seem to require that `p > q`. Given this, would it be feasible to change the order around in cryptography so that it lines up with OpenSSL?

See also: http://crypto.stackexchange.com/questions/18084/in-rsa-why-does-p-have-to-be-bigger-than-q-where-n-p-times-q. @briansmith can provide more commentary if needed.



Discussion:
I think OpenSSL and BoringSSL do accept the keys with `p` < `q`, but some software doesn't work (as well) with them currently. As noted in the linked-to documentation above, retyurning a key with `p` < `q` is more consistent with OpenSSL and so things are more likely to interoperate better. And, it's an easy thing to do.

I have no objection to swapping them. I don't think I'd even consider this to be a change that would require a deprecation/new function. If you'd like to submit a PR to swap them (and update the docs) I'll be happy to review.

To play devil's advocate, the documentation is very explicit about `p < q`. What if someone read this and choose to fix it up by swapping `p` and `q`?


Resolving patch:
diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
--- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
@@ -257,7 +257,7 @@ def rsa_recover_prime_factors(n, e, d):
     # Found !
     q, r = divmod(n, p)
     assert r == 0
-
+    p, q = sorted((p, q), reverse=True)
     return (p, q)
 
 


Test patch:
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -1985,10 +1985,11 @@ def test_recover_prime_factors(self, vector):
             private["private_exponent"]
         )
         # Unfortunately there is no convention on which prime should be p
-        # and which one q. The function we use always makes p < q, but the
+        # and which one q. The function we use always makes p > q, but the
         # NIST vectors are not so consistent. Accordingly, we verify we've
         # recovered the proper (p, q) by sorting them and asserting on that.
         assert sorted([p, q]) == sorted([private["p"], private["q"]])
+        assert p > q
 
     def test_invalid_recover_prime_factors(self):
         with pytest.raises(ValueError):
Repository: pyca/cryptography

Issue:
1.4 Test failure TestRSACertificate.test_cert_serial_warning
While testing an upgrade of the GNU Guix python-cryptography package from 1.3.2 to 1.4, I encountered the following failure of `TestRSACertificate.test_cert_serial_warning[backend0]`.

```
=================================== FAILURES ===================================
____________ TestRSACertificate.test_cert_serial_warning[backend0] _____________

self = <tests.test_x509.TestRSACertificate object at 0x7fffe0fa7978>
backend = <cryptography.hazmat.backends.openssl.backend.Backend object at 0x7ffff3020278>

    def test_cert_serial_warning(self, backend):
        cert = _load_cert(
            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
            x509.load_der_x509_certificate,
            backend
        )

        with warnings.catch_warnings():
            warnings.simplefilter("always", utils.DeprecatedIn10)
>           with pytest.deprecated_call():
E           TypeError: deprecated_call() missing 1 required positional argument: 'func'

tests/test_x509.py:516: TypeError
============ 1 failed, 83123 passed, 3222 skipped in 164.91 seconds ============
```

The dependency graph is using Python 3.4.3 and Hypothesis 3.1.0. Please let me know what other information I can provide to help debug this failure.



Discussion:
What version of py.test are you using

I'm using 2.7.3.

Try a newer pytest

On Fri, Jul 1, 2016 at 8:29 PM, lfam notifications@github.com wrote:

> I'm using 2.7.3.
> 
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> https://github.com/pyca/cryptography/issues/3034#issuecomment-230073052,
> or mute the thread
> https://github.com/notifications/unsubscribe/AAADBKqGx-sq76w8Qu8CmG0MJbYeO3W9ks5qRbEDgaJpZM4JDjvP
> .

## 

"I disapprove of what you say, but I will defend to the death your right to
say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
"The people's good is the highest law." -- Cicero
GPG Key fingerprint: D1B3 ADC0 E023 8CA6


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -58,7 +58,7 @@
     setup_requirements.append("cffi>=1.4.1")
 
 test_requirements = [
-    "pytest",
+    "pytest>=2.9.0",
     "pretend",
     "iso8601",
     "pyasn1_modules",


Test patch:
Repository: pyca/cryptography

Issue:
scrypt bounds checking
```
[11:23:58]  <Alex_Gaynor>   reaperhulk: what happens if you pass a non-even n?
[11:24:10]  <Alex_Gaynor>   Or a negative value for any of the params?
```

Presumably it will fail with an assertion error on return from the call to `EVP_PBE_scrypt`, but we shouldn't allow those types of errors.

cc @Ayrx.



Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/primitives/kdf/scrypt.py b/src/cryptography/hazmat/primitives/kdf/scrypt.py
--- a/src/cryptography/hazmat/primitives/kdf/scrypt.py
+++ b/src/cryptography/hazmat/primitives/kdf/scrypt.py
@@ -25,6 +25,16 @@ def __init__(self, salt, length, n, r, p, backend):
         self._length = length
         if not isinstance(salt, bytes):
             raise TypeError("salt must be bytes.")
+
+        if n < 2 or (n & (n - 1)) != 0:
+            raise ValueError("n must be greater than 1 and be a power of 2.")
+
+        if r < 1:
+            raise ValueError("r must be greater than or equal to 1.")
+
+        if p < 1:
+            raise ValueError("p must be greater than or equal to 1.")
+
         self._used = False
         self._salt = salt
         self._n = n


Test patch:
diff --git a/tests/hazmat/primitives/test_scrypt.py b/tests/hazmat/primitives/test_scrypt.py
--- a/tests/hazmat/primitives/test_scrypt.py
+++ b/tests/hazmat/primitives/test_scrypt.py
@@ -117,3 +117,20 @@ def test_already_finalized(self, backend):
         scrypt.derive(password)
         with pytest.raises(AlreadyFinalized):
             scrypt.derive(password)
+
+    def test_invalid_n(self, backend):
+        # n is less than 2
+        with pytest.raises(ValueError):
+            Scrypt(b"NaCl", 64, 1, 8, 16, backend)
+
+        # n is not a power of 2
+        with pytest.raises(ValueError):
+            Scrypt(b"NaCl", 64, 3, 8, 16, backend)
+
+    def test_invalid_r(self, backend):
+        with pytest.raises(ValueError):
+            Scrypt(b"NaCl", 64, 2, 0, 16, backend)
+
+    def test_invalid_p(self, backend):
+        with pytest.raises(ValueError):
+            Scrypt(b"NaCl", 64, 2, 8, 0, backend)
Repository: pyca/cryptography

Issue:
Add function to set random serial number to X509 certificate
Good way -- is to use `random.randint(1, (159<<1) -1)` to set serial number. One question is bother me -- is it good to use undefined Python random implementation comparing to cryptographically strong random?

See https://en.wikipedia.org/wiki/Predictable_serial_number_attack
and http://www.win.tue.nl/hashclash/rogue-ca/



Discussion:
It would not be safe to use random.randint because underneath the covers this uses a single shared instance of Mersenne Twister, which can be attacked to predict all future output values.

`int.from_bytes(os.urandom(16))` would be a reasonable way to generate it (serials are allowed to be up to 20 octets by RFC 5280, but the number must be positive and ASN.1 integer positive encoding requires a leading zero byte if the high bit is set, so the max bytes you can safely encode is 19).

maybe `int.from_bytes(os.urandom(20)) >> 1` ? + ensure serial number is not zero


Resolving patch:
diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py
--- a/src/cryptography/x509/__init__.py
+++ b/src/cryptography/x509/__init__.py
@@ -11,6 +11,7 @@
     InvalidVersion, RevokedCertificate, RevokedCertificateBuilder,
     Version, load_der_x509_certificate, load_der_x509_crl, load_der_x509_csr,
     load_pem_x509_certificate, load_pem_x509_crl, load_pem_x509_csr,
+    random_serial_number,
 )
 from cryptography.x509.extensions import (
     AccessDescription, AuthorityInformationAccess,
@@ -113,6 +114,7 @@
     "load_der_x509_csr",
     "load_pem_x509_crl",
     "load_der_x509_crl",
+    "random_serial_number",
     "InvalidVersion",
     "DuplicateExtension",
     "UnsupportedExtension",
diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py
--- a/src/cryptography/x509/base.py
+++ b/src/cryptography/x509/base.py
@@ -6,6 +6,7 @@
 
 import abc
 import datetime
+import os
 from enum import Enum
 
 import six
@@ -723,3 +724,7 @@ def build(self, backend):
             )
 
         return backend.create_x509_revoked_certificate(self)
+
+
+def random_serial_number():
+    return utils.int_from_bytes(os.urandom(20), "big") >> 1


Test patch:
diff --git a/tests/test_x509.py b/tests/test_x509.py
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -3724,3 +3724,20 @@ def test_repr(self):
     def test_not_nameattribute(self):
         with pytest.raises(TypeError):
             x509.Name(["not-a-NameAttribute"])
+
+
+def test_random_serial_number(monkeypatch):
+    sample_data = os.urandom(20)
+
+    def notrandom(size):
+        assert size == len(sample_data)
+        return sample_data
+
+    monkeypatch.setattr(os, "urandom", notrandom)
+
+    serial_number = x509.random_serial_number()
+
+    assert (
+        serial_number == utils.int_from_bytes(sample_data, "big") >> 1
+    )
+    assert utils.bit_length(serial_number) < 160
Repository: pyca/cryptography

Issue:
Memory leak in _encode_name
```
#!/usr/bin/python3

import cryptography.hazmat.backends.openssl.backend as backend
from cryptography.hazmat.backends.openssl.encode_asn1 import _encode_name_gc
from cryptography.x509.oid import NameOID
from cryptography import x509
import gc

n = [x509.NameAttribute(NameOID.COMMON_NAME, 'Hello')]

while True:
    _encode_name_gc(backend, n)
    gc.collect()
```

The result from _encode_name_entry is not garbage collected. _encode_name calls X509_NAME_add_entry which creates a copy of it. The original is never freed.



Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
--- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
@@ -85,6 +85,10 @@ def _encode_name(backend, attributes):
     subject = backend._lib.X509_NAME_new()
     for attribute in attributes:
         name_entry = _encode_name_entry(backend, attribute)
+        # X509_NAME_add_entry dups the object so we need to gc this copy
+        name_entry = backend._ffi.gc(
+            name_entry, backend._lib.X509_NAME_ENTRY_free
+        )
         res = backend._lib.X509_NAME_add_entry(subject, name_entry, -1, 0)
         backend.openssl_assert(res == 1)
     return subject


Test patch:
Repository: pyca/cryptography

Issue:
HKDF key-length inconsistency
For too small key sizes, `HKDF.derive()` outputs an empty array instead of a small key:

Program:
```python
#!/usr/bin/env python3.5
import cryptography
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.backends import default_backend

print("cryptography.io:{}".format(cryptography.__version__))

hkdf = HKDF(algorithm=hashes.SHA256(), length=4, salt=b"salt",
            info=b"some-test", backend=default_backend())

key = hkdf.derive(b"my secret passphrase")
print("Derived key: {}".format(key))
```

Output:
```
cryptography.io:1.5.2
Derived key: b''
```

Suggested fix:

I am not quite sure why the division by 8 in the snippet below was added. The cumulative size of the output array is always `self._algorithm.digest_size * len(output)` and thus we can stop after `self._algorithm.digest_size * len(output) >= self._length`. At first I thought this might be a clever trick taken from the paper, but I didn't find it there. I guess there was a mixup between bits and bytes at some point.

```python
# class HKDFExpand
def _expand(self, key_material):
        output = [b""]
        counter = 1

        while (self._algorithm.digest_size // 8) * len(output) < self._length:
            h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)
            h.update(output[-1])
            h.update(self._info)
            h.update(six.int2byte(counter))
            output.append(h.finalize())
            counter += 1

        return b"".join(output)[:self._length]
```


Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/primitives/kdf/hkdf.py b/src/cryptography/hazmat/primitives/kdf/hkdf.py
--- a/src/cryptography/hazmat/primitives/kdf/hkdf.py
+++ b/src/cryptography/hazmat/primitives/kdf/hkdf.py
@@ -91,7 +91,7 @@ def _expand(self, key_material):
         output = [b""]
         counter = 1
 
-        while (self._algorithm.digest_size // 8) * len(output) < self._length:
+        while self._algorithm.digest_size * (len(output) - 1) < self._length:
             h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)
             h.update(output[-1])
             h.update(self._info)


Test patch:
diff --git a/tests/hazmat/primitives/test_hkdf.py b/tests/hazmat/primitives/test_hkdf.py
--- a/tests/hazmat/primitives/test_hkdf.py
+++ b/tests/hazmat/primitives/test_hkdf.py
@@ -142,6 +142,17 @@ def test_unicode_typeerror(self, backend):
 
             hkdf.verify(b"foo", u"bar")
 
+    def test_derive_short_output(self, backend):
+        hkdf = HKDF(
+            hashes.SHA256(),
+            4,
+            salt=None,
+            info=None,
+            backend=backend
+        )
+
+        assert hkdf.derive(b"\x01" * 16) == b"gJ\xfb{"
+
 
 @pytest.mark.requires_backend_interface(interface=HMACBackend)
 class TestHKDFExpand(object):
Repository: pyca/cryptography

Issue:
Add tests for ec.derive_private_key with negative secret value



Discussion:

Resolving patch:
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -257,6 +257,9 @@ def derive_private_key(private_value, curve, backend):
     if not isinstance(private_value, six.integer_types):
         raise TypeError("private_value must be an integer type.")
 
+    if private_value <= 0:
+        raise ValueError("private_value must be a positive integer.")
+
     if not isinstance(curve, EllipticCurve):
         raise TypeError("curve must provide the EllipticCurve interface.")
 


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
@@ -125,6 +125,9 @@ def test_derive_private_key_errors(backend):
     with pytest.raises(TypeError):
         ec.derive_private_key(10, 'five', backend)
 
+    with pytest.raises(ValueError):
+        ec.derive_private_key(-7, curve, backend)
+
 
 def test_ec_numbers():
     numbers = ec.EllipticCurvePrivateNumbers(
Repository: pyca/cryptography

Issue:
Document openssl_version_number
https://cryptography.io/en/latest/hazmat/backends/openssl/


Discussion:
Hi Alex, small thing and I could be wrong, but I think the function name is openssl_version_text. cryptography.hazmat.backends.openssl.backend.openssl_version_text() seems to work and returns "OpenSSL 1.0.2j  26 Sep 2016" for me. I have just downloaded cryptography V1.7 and run the command.
Thanks for the heads-up on this one. :-)
Uhhh, yeah, you're correct about the name. (This is what I get for filing issues before tea)

Resolving patch:
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -206,6 +206,9 @@ def openssl_version_text(self):
             self._lib.OpenSSL_version(self._lib.OPENSSL_VERSION)
         ).decode("ascii")
 
+    def openssl_version_number(self):
+        return self._lib.OpenSSL_version_num()
+
     def create_hmac_ctx(self, key, algorithm):
         return _HMACContext(self, key, algorithm)
 


Test patch:
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -71,6 +71,9 @@ def test_openssl_version_text(self):
             backend.openssl_version_text().startswith("LibreSSL")
         )
 
+    def test_openssl_version_number(self):
+        assert backend.openssl_version_number() > 0
+
     def test_supports_cipher(self):
         assert backend.cipher_supported(None, None) is False
Repository: pyca/cryptography

Issue:
Add Python 3.6 support



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -297,6 +297,7 @@ def run_tests(self):
         "Programming Language :: Python :: 3.3",
         "Programming Language :: Python :: 3.4",
         "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
         "Topic :: Security :: Cryptography",


Test patch:
Repository: pyca/cryptography

Issue:
Please can you add X509_STORE_CTX_get0_cert() to the OpenSSL ffi?
This method is needed in order to get the cert that is being validated, given an X509_STORE_CTX*. Prior to 1.1.0 , this information was obtained by directly getting the "cert" member of the struct this pointed to, but in 1.1.0 this struct has been made internal/opaque and its layout changed. The X509_STORE_CTX_get0_cert() accessor was added at this time. Without it, SSL_CTX_set_cert_verify_callback(), which is in the ffi, is useless because you can't get the cert in your callback implementation.


Discussion:

Resolving patch:
diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py
--- a/src/_cffi_src/openssl/x509_vfy.py
+++ b/src/_cffi_src/openssl/x509_vfy.py
@@ -206,6 +206,9 @@
 Cryptography_STACK_OF_X509_OBJECT *X509_STORE_get0_objects(X509_STORE *);
 X509 *X509_OBJECT_get0_X509(X509_OBJECT *);
 int X509_OBJECT_get_type(const X509_OBJECT *);
+
+/* added in 1.1.0 */
+X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *);
 """
 
 CUSTOMIZATIONS = """
@@ -278,6 +281,12 @@
 #endif
 
 #if CRYPTOGRAPHY_OPENSSL_LESS_THAN_110PRE5 || defined(LIBRESSL_VERSION_NUMBER)
+/* from x509/x509_vfy.c */
+X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
+{
+    return ctx->cert;
+}
+
 X509 *X509_OBJECT_get0_X509(X509_OBJECT *x) {
     return x->data.x509;
 }


Test patch:
Repository: pyca/cryptography

Issue:
Very slow performance of ec.generate_private_key
On Windows with Python 3.6.0:
```bash
$ python -m timeit -s "from cryptography.hazmat.backends import default_backend;from cryptography.hazmat.primitives.asymmetric.ec import SECP256K1, derive_private_key;DEFAULT_BACKEND = default_backend();SECP256K1 = SECP256K1();import os" "derive_private_key(int.from_bytes(os.urandom(32), 'big'), SECP256K1, DEFAULT_BACKEND)"
1000 loops, best of 3: 772 usec per loop
$ python -m timeit -s "from cryptography.hazmat.backends import default_backend;from cryptography.hazmat.primitives.asymmetric.ec import SECP256K1, generate_private_key;DEFAULT_BACKEND = default_backend();SECP256K1 = SECP256K1()" "generate_private_key(SECP256K1, DEFAULT_BACKEND)"
1000 loops, best of 3: 1.91 msec per loop
```


Discussion:
On fresh Ubuntu 16.04.2 LTS with Python 3.5.2:
```bash
$ python3 -m timeit -s "from cryptography.hazmat.backends import default_backend;from cryptography.hazmat.primitives.asymmetric.ec import SECP256K1, derive_private_key;DEFAULT_BACKEND = default_backend();SECP256K1 = SECP256K1();import os" "derive_private_key(int.from_bytes(os.urandom(32), 'big'), SECP256K1, DEFAULT_BACKEND)"
1000 loops, best of 3: 610 usec per loop
$ python3 -m timeit -s "from cryptography.hazmat.backends import default_backend;from cryptography.hazmat.primitives.asymmetric.ec import SECP256K1, generate_private_key;DEFAULT_BACKEND = default_backend();SECP256K1 = SECP256K1()" "generate_private_key(SECP256K1, DEFAULT_BACKEND)"
1000 loops, best of 3: 1.43 msec per loop
```
For some reason it takes ~2.5 times longer than deriving a private key from a random 256 bit value.

Resolving patch:
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -1271,9 +1271,6 @@ def generate_elliptic_curve_private_key(self, curve):
             res = self._lib.EC_KEY_generate_key(ec_cdata)
             self.openssl_assert(res == 1)
 
-            res = self._lib.EC_KEY_check_key(ec_cdata)
-            self.openssl_assert(res == 1)
-
             evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata)
 
             return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey)


Test patch: