We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
_truncate_digest_for_ecdsa in the OpenSSL document should be commented
Right now there are no comments explaining why it exists, or what it's attempting to do.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cryptography/hazmat/backends/openssl/ec.py`
Content:
```
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 #    http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10 # implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13 
14 from __future__ import absolute_import, division, print_function
15 
16 import six
17 
18 from cryptography import utils
19 from cryptography.exceptions import (
20     InvalidSignature, UnsupportedAlgorithm, _Reasons
21 )
22 from cryptography.hazmat.primitives import hashes, interfaces
23 from cryptography.hazmat.primitives.asymmetric import ec
24 
25 
26 def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):
27     _lib = backend._lib
28     _ffi = backend._ffi
29 
30     digest_len = len(digest)
31 
32     group = _lib.EC_KEY_get0_group(ec_key_cdata)
33 
34     bn_ctx = _lib.BN_CTX_new()
35     assert bn_ctx != _ffi.NULL
36     bn_ctx = _ffi.gc(bn_ctx, _lib.BN_CTX_free)
37 
38     order = _lib.BN_CTX_get(bn_ctx)
39     assert order != _ffi.NULL
40 
41     res = _lib.EC_GROUP_get_order(group, order, bn_ctx)
42     assert res == 1
43 
44     order_bits = _lib.BN_num_bits(order)
45 
46     if 8 * digest_len > order_bits:
47         digest_len = (order_bits + 7) // 8
48         digest = digest[:digest_len]
49 
50     if 8 * digest_len > order_bits:
51         rshift = 8 - (order_bits & 0x7)
52         assert rshift > 0 and rshift < 8
53 
54         mask = 0xFF >> rshift << rshift
55 
56         # Set the bottom rshift bits to 0
57         digest = digest[:-1] + six.int2byte(six.indexbytes(digest, -1) & mask)
58 
59     return digest
60 
61 
62 @utils.register_interface(interfaces.AsymmetricSignatureContext)
63 class _ECDSASignatureContext(object):
64     def __init__(self, backend, private_key, algorithm):
65         self._backend = backend
66         self._private_key = private_key
67         self._digest = hashes.Hash(algorithm, backend)
68 
69     def update(self, data):
70         self._digest.update(data)
71 
72     def finalize(self):
73         ec_key = self._private_key._ec_key
74 
75         digest = self._digest.finalize()
76 
77         digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)
78 
79         max_size = self._backend._lib.ECDSA_size(ec_key)
80         assert max_size > 0
81 
82         sigbuf = self._backend._ffi.new("char[]", max_size)
83         siglen_ptr = self._backend._ffi.new("unsigned int[]", 1)
84         res = self._backend._lib.ECDSA_sign(
85             0,
86             digest,
87             len(digest),
88             sigbuf,
89             siglen_ptr,
90             ec_key
91         )
92         assert res == 1
93         return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]]
94 
95 
96 @utils.register_interface(interfaces.AsymmetricVerificationContext)
97 class _ECDSAVerificationContext(object):
98     def __init__(self, backend, public_key, signature, algorithm):
99         self._backend = backend
100         self._public_key = public_key
101         self._signature = signature
102         self._digest = hashes.Hash(algorithm, backend)
103 
104     def update(self, data):
105         self._digest.update(data)
106 
107     def verify(self):
108         ec_key = self._public_key._ec_key
109 
110         digest = self._digest.finalize()
111 
112         digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)
113 
114         res = self._backend._lib.ECDSA_verify(
115             0,
116             digest,
117             len(digest),
118             self._signature,
119             len(self._signature),
120             ec_key
121         )
122         if res != 1:
123             self._backend._consume_errors()
124             raise InvalidSignature
125         return True
126 
127 
128 @utils.register_interface(interfaces.EllipticCurvePrivateKey)
129 class _EllipticCurvePrivateKey(object):
130     def __init__(self, backend, ec_key_cdata, curve):
131         self._backend = backend
132         self._ec_key = ec_key_cdata
133         self._curve = curve
134 
135     @property
136     def curve(self):
137         return self._curve
138 
139     def signer(self, signature_algorithm):
140         if isinstance(signature_algorithm, ec.ECDSA):
141             return _ECDSASignatureContext(
142                 self._backend, self, signature_algorithm.algorithm
143             )
144         else:
145             raise UnsupportedAlgorithm(
146                 "Unsupported elliptic curve signature algorithm.",
147                 _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
148 
149     def public_key(self):
150         group = self._backend._lib.EC_KEY_get0_group(self._ec_key)
151         assert group != self._backend._ffi.NULL
152 
153         curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group)
154 
155         public_ec_key = self._backend._lib.EC_KEY_new_by_curve_name(curve_nid)
156         assert public_ec_key != self._backend._ffi.NULL
157         public_ec_key = self._backend._ffi.gc(
158             public_ec_key, self._backend._lib.EC_KEY_free
159         )
160 
161         point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key)
162         assert point != self._backend._ffi.NULL
163 
164         res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point)
165         assert res == 1
166 
167         return _EllipticCurvePublicKey(
168             self._backend, public_ec_key, self._curve
169         )
170 
171 
172 @utils.register_interface(interfaces.EllipticCurvePublicKey)
173 class _EllipticCurvePublicKey(object):
174     def __init__(self, backend, ec_key_cdata, curve):
175         self._backend = backend
176         self._ec_key = ec_key_cdata
177         self._curve = curve
178 
179     @property
180     def curve(self):
181         return self._curve
182 
183     def verifier(self, signature, signature_algorithm):
184         if isinstance(signature_algorithm, ec.ECDSA):
185             return _ECDSAVerificationContext(
186                 self._backend, self, signature, signature_algorithm.algorithm
187             )
188         else:
189             raise UnsupportedAlgorithm(
190                 "Unsupported elliptic curve signature algorithm.",
191                 _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
192
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cryptography/hazmat/backends/openssl/ec.py b/cryptography/hazmat/backends/openssl/ec.py
--- a/cryptography/hazmat/backends/openssl/ec.py
+++ b/cryptography/hazmat/backends/openssl/ec.py
@@ -24,6 +24,13 @@
 
 
 def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):
+    """
+    This function truncates digests that are longer than a given elliptic
+    curve key's length so they can be signed. Since elliptic curve keys are
+    much shorter than RSA keys many digests (e.g. SHA-512) may require
+    truncation.
+    """
+
     _lib = backend._lib
     _ffi = backend._ffi
 
@@ -31,17 +38,14 @@
 
     group = _lib.EC_KEY_get0_group(ec_key_cdata)
 
-    bn_ctx = _lib.BN_CTX_new()
-    assert bn_ctx != _ffi.NULL
-    bn_ctx = _ffi.gc(bn_ctx, _lib.BN_CTX_free)
-
-    order = _lib.BN_CTX_get(bn_ctx)
-    assert order != _ffi.NULL
+    with backend._bn_ctx_manager() as bn_ctx:
+        order = _lib.BN_CTX_get(bn_ctx)
+        assert order != _ffi.NULL
 
-    res = _lib.EC_GROUP_get_order(group, order, bn_ctx)
-    assert res == 1
+        res = _lib.EC_GROUP_get_order(group, order, bn_ctx)
+        assert res == 1
 
-    order_bits = _lib.BN_num_bits(order)
+        order_bits = _lib.BN_num_bits(order)
 
     if 8 * digest_len > order_bits:
         digest_len = (order_bits + 7) // 8

{"golden_diff": "diff --git a/cryptography/hazmat/backends/openssl/ec.py b/cryptography/hazmat/backends/openssl/ec.py\n--- a/cryptography/hazmat/backends/openssl/ec.py\n+++ b/cryptography/hazmat/backends/openssl/ec.py\n@@ -24,6 +24,13 @@\n \n \n def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):\n+    \"\"\"\n+    This function truncates digests that are longer than a given elliptic\n+    curve key's length so they can be signed. Since elliptic curve keys are\n+    much shorter than RSA keys many digests (e.g. SHA-512) may require\n+    truncation.\n+    \"\"\"\n+\n     _lib = backend._lib\n     _ffi = backend._ffi\n \n@@ -31,17 +38,14 @@\n \n     group = _lib.EC_KEY_get0_group(ec_key_cdata)\n \n-    bn_ctx = _lib.BN_CTX_new()\n-    assert bn_ctx != _ffi.NULL\n-    bn_ctx = _ffi.gc(bn_ctx, _lib.BN_CTX_free)\n-\n-    order = _lib.BN_CTX_get(bn_ctx)\n-    assert order != _ffi.NULL\n+    with backend._bn_ctx_manager() as bn_ctx:\n+        order = _lib.BN_CTX_get(bn_ctx)\n+        assert order != _ffi.NULL\n \n-    res = _lib.EC_GROUP_get_order(group, order, bn_ctx)\n-    assert res == 1\n+        res = _lib.EC_GROUP_get_order(group, order, bn_ctx)\n+        assert res == 1\n \n-    order_bits = _lib.BN_num_bits(order)\n+        order_bits = _lib.BN_num_bits(order)\n \n     if 8 * digest_len > order_bits:\n         digest_len = (order_bits + 7) // 8\n", "issue": "_truncate_digest_for_ecdsa in the OpenSSL document should be commented\nRight now there are no comments explaining why it exists, or what it's attempting to do.\n\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport six\n\nfrom cryptography import utils\nfrom cryptography.exceptions import (\n    InvalidSignature, UnsupportedAlgorithm, _Reasons\n)\nfrom cryptography.hazmat.primitives import hashes, interfaces\nfrom cryptography.hazmat.primitives.asymmetric import ec\n\n\ndef _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):\n    _lib = backend._lib\n    _ffi = backend._ffi\n\n    digest_len = len(digest)\n\n    group = _lib.EC_KEY_get0_group(ec_key_cdata)\n\n    bn_ctx = _lib.BN_CTX_new()\n    assert bn_ctx != _ffi.NULL\n    bn_ctx = _ffi.gc(bn_ctx, _lib.BN_CTX_free)\n\n    order = _lib.BN_CTX_get(bn_ctx)\n    assert order != _ffi.NULL\n\n    res = _lib.EC_GROUP_get_order(group, order, bn_ctx)\n    assert res == 1\n\n    order_bits = _lib.BN_num_bits(order)\n\n    if 8 * digest_len > order_bits:\n        digest_len = (order_bits + 7) // 8\n        digest = digest[:digest_len]\n\n    if 8 * digest_len > order_bits:\n        rshift = 8 - (order_bits & 0x7)\n        assert rshift > 0 and rshift < 8\n\n        mask = 0xFF >> rshift << rshift\n\n        # Set the bottom rshift bits to 0\n        digest = digest[:-1] + six.int2byte(six.indexbytes(digest, -1) & mask)\n\n    return digest\n\n\n@utils.register_interface(interfaces.AsymmetricSignatureContext)\nclass _ECDSASignatureContext(object):\n    def __init__(self, backend, private_key, algorithm):\n        self._backend = backend\n        self._private_key = private_key\n        self._digest = hashes.Hash(algorithm, backend)\n\n    def update(self, data):\n        self._digest.update(data)\n\n    def finalize(self):\n        ec_key = self._private_key._ec_key\n\n        digest = self._digest.finalize()\n\n        digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)\n\n        max_size = self._backend._lib.ECDSA_size(ec_key)\n        assert max_size > 0\n\n        sigbuf = self._backend._ffi.new(\"char[]\", max_size)\n        siglen_ptr = self._backend._ffi.new(\"unsigned int[]\", 1)\n        res = self._backend._lib.ECDSA_sign(\n            0,\n            digest,\n            len(digest),\n            sigbuf,\n            siglen_ptr,\n            ec_key\n        )\n        assert res == 1\n        return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]]\n\n\n@utils.register_interface(interfaces.AsymmetricVerificationContext)\nclass _ECDSAVerificationContext(object):\n    def __init__(self, backend, public_key, signature, algorithm):\n        self._backend = backend\n        self._public_key = public_key\n        self._signature = signature\n        self._digest = hashes.Hash(algorithm, backend)\n\n    def update(self, data):\n        self._digest.update(data)\n\n    def verify(self):\n        ec_key = self._public_key._ec_key\n\n        digest = self._digest.finalize()\n\n        digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)\n\n        res = self._backend._lib.ECDSA_verify(\n            0,\n            digest,\n            len(digest),\n            self._signature,\n            len(self._signature),\n            ec_key\n        )\n        if res != 1:\n            self._backend._consume_errors()\n            raise InvalidSignature\n        return True\n\n\n@utils.register_interface(interfaces.EllipticCurvePrivateKey)\nclass _EllipticCurvePrivateKey(object):\n    def __init__(self, backend, ec_key_cdata, curve):\n        self._backend = backend\n        self._ec_key = ec_key_cdata\n        self._curve = curve\n\n    @property\n    def curve(self):\n        return self._curve\n\n    def signer(self, signature_algorithm):\n        if isinstance(signature_algorithm, ec.ECDSA):\n            return _ECDSASignatureContext(\n                self._backend, self, signature_algorithm.algorithm\n            )\n        else:\n            raise UnsupportedAlgorithm(\n                \"Unsupported elliptic curve signature algorithm.\",\n                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)\n\n    def public_key(self):\n        group = self._backend._lib.EC_KEY_get0_group(self._ec_key)\n        assert group != self._backend._ffi.NULL\n\n        curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group)\n\n        public_ec_key = self._backend._lib.EC_KEY_new_by_curve_name(curve_nid)\n        assert public_ec_key != self._backend._ffi.NULL\n        public_ec_key = self._backend._ffi.gc(\n            public_ec_key, self._backend._lib.EC_KEY_free\n        )\n\n        point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key)\n        assert point != self._backend._ffi.NULL\n\n        res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point)\n        assert res == 1\n\n        return _EllipticCurvePublicKey(\n            self._backend, public_ec_key, self._curve\n        )\n\n\n@utils.register_interface(interfaces.EllipticCurvePublicKey)\nclass _EllipticCurvePublicKey(object):\n    def __init__(self, backend, ec_key_cdata, curve):\n        self._backend = backend\n        self._ec_key = ec_key_cdata\n        self._curve = curve\n\n    @property\n    def curve(self):\n        return self._curve\n\n    def verifier(self, signature, signature_algorithm):\n        if isinstance(signature_algorithm, ec.ECDSA):\n            return _ECDSAVerificationContext(\n                self._backend, self, signature, signature_algorithm.algorithm\n            )\n        else:\n            raise UnsupportedAlgorithm(\n                \"Unsupported elliptic curve signature algorithm.\",\n                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)\n", "path": "cryptography/hazmat/backends/openssl/ec.py"}], "after_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport six\n\nfrom cryptography import utils\nfrom cryptography.exceptions import (\n    InvalidSignature, UnsupportedAlgorithm, _Reasons\n)\nfrom cryptography.hazmat.primitives import hashes, interfaces\nfrom cryptography.hazmat.primitives.asymmetric import ec\n\n\ndef _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):\n    \"\"\"\n    This function truncates digests that are longer than a given elliptic\n    curve key's length so they can be signed. Since elliptic curve keys are\n    much shorter than RSA keys many digests (e.g. SHA-512) may require\n    truncation.\n    \"\"\"\n\n    _lib = backend._lib\n    _ffi = backend._ffi\n\n    digest_len = len(digest)\n\n    group = _lib.EC_KEY_get0_group(ec_key_cdata)\n\n    with backend._bn_ctx_manager() as bn_ctx:\n        order = _lib.BN_CTX_get(bn_ctx)\n        assert order != _ffi.NULL\n\n        res = _lib.EC_GROUP_get_order(group, order, bn_ctx)\n        assert res == 1\n\n        order_bits = _lib.BN_num_bits(order)\n\n    if 8 * digest_len > order_bits:\n        digest_len = (order_bits + 7) // 8\n        digest = digest[:digest_len]\n\n    if 8 * digest_len > order_bits:\n        rshift = 8 - (order_bits & 0x7)\n        assert rshift > 0 and rshift < 8\n\n        mask = 0xFF >> rshift << rshift\n\n        # Set the bottom rshift bits to 0\n        digest = digest[:-1] + six.int2byte(six.indexbytes(digest, -1) & mask)\n\n    return digest\n\n\n@utils.register_interface(interfaces.AsymmetricSignatureContext)\nclass _ECDSASignatureContext(object):\n    def __init__(self, backend, private_key, algorithm):\n        self._backend = backend\n        self._private_key = private_key\n        self._digest = hashes.Hash(algorithm, backend)\n\n    def update(self, data):\n        self._digest.update(data)\n\n    def finalize(self):\n        ec_key = self._private_key._ec_key\n\n        digest = self._digest.finalize()\n\n        digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)\n\n        max_size = self._backend._lib.ECDSA_size(ec_key)\n        assert max_size > 0\n\n        sigbuf = self._backend._ffi.new(\"char[]\", max_size)\n        siglen_ptr = self._backend._ffi.new(\"unsigned int[]\", 1)\n        res = self._backend._lib.ECDSA_sign(\n            0,\n            digest,\n            len(digest),\n            sigbuf,\n            siglen_ptr,\n            ec_key\n        )\n        assert res == 1\n        return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]]\n\n\n@utils.register_interface(interfaces.AsymmetricVerificationContext)\nclass _ECDSAVerificationContext(object):\n    def __init__(self, backend, public_key, signature, algorithm):\n        self._backend = backend\n        self._public_key = public_key\n        self._signature = signature\n        self._digest = hashes.Hash(algorithm, backend)\n\n    def update(self, data):\n        self._digest.update(data)\n\n    def verify(self):\n        ec_key = self._public_key._ec_key\n\n        digest = self._digest.finalize()\n\n        digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)\n\n        res = self._backend._lib.ECDSA_verify(\n            0,\n            digest,\n            len(digest),\n            self._signature,\n            len(self._signature),\n            ec_key\n        )\n        if res != 1:\n            self._backend._consume_errors()\n            raise InvalidSignature\n        return True\n\n\n@utils.register_interface(interfaces.EllipticCurvePrivateKey)\nclass _EllipticCurvePrivateKey(object):\n    def __init__(self, backend, ec_key_cdata, curve):\n        self._backend = backend\n        self._ec_key = ec_key_cdata\n        self._curve = curve\n\n    @property\n    def curve(self):\n        return self._curve\n\n    def signer(self, signature_algorithm):\n        if isinstance(signature_algorithm, ec.ECDSA):\n            return _ECDSASignatureContext(\n                self._backend, self, signature_algorithm.algorithm\n            )\n        else:\n            raise UnsupportedAlgorithm(\n                \"Unsupported elliptic curve signature algorithm.\",\n                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)\n\n    def public_key(self):\n        group = self._backend._lib.EC_KEY_get0_group(self._ec_key)\n        assert group != self._backend._ffi.NULL\n\n        curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group)\n\n        public_ec_key = self._backend._lib.EC_KEY_new_by_curve_name(curve_nid)\n        assert public_ec_key != self._backend._ffi.NULL\n        public_ec_key = self._backend._ffi.gc(\n            public_ec_key, self._backend._lib.EC_KEY_free\n        )\n\n        point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key)\n        assert point != self._backend._ffi.NULL\n\n        res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point)\n        assert res == 1\n\n        return _EllipticCurvePublicKey(\n            self._backend, public_ec_key, self._curve\n        )\n\n\n@utils.register_interface(interfaces.EllipticCurvePublicKey)\nclass _EllipticCurvePublicKey(object):\n    def __init__(self, backend, ec_key_cdata, curve):\n        self._backend = backend\n        self._ec_key = ec_key_cdata\n        self._curve = curve\n\n    @property\n    def curve(self):\n        return self._curve\n\n    def verifier(self, signature, signature_algorithm):\n        if isinstance(signature_algorithm, ec.ECDSA):\n            return _ECDSAVerificationContext(\n                self._backend, self, signature, signature_algorithm.algorithm\n            )\n        else:\n            raise UnsupportedAlgorithm(\n                \"Unsupported elliptic curve signature algorithm.\",\n                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)\n", "path": "cryptography/hazmat/backends/openssl/ec.py"}]}