Merge pull request #1348 from reaperhulk/improve-naming-consistency

deprecate backend method names for elliptic curve number loading
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index dfc6d8b..eb9b4f4 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -11,6 +11,11 @@
   constructor. The ``salt_length`` should be passed to
   :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` instead.
 * Fix compilation on OS X Yosemite.
+* Deprecated ``elliptic_curve_private_key_from_numbers`` and
+  ``elliptic_curve_public_key_from_numbers`` in favor of
+  ``load_elliptic_curve_private_numbers`` and
+  ``load_elliptic_curve_public_numbers`` on
+  :class:`~cryptography.hazmat.backends.interfaces.EllipticCurveBackend`.
 
 0.5.4 - 2014-08-20
 ~~~~~~~~~~~~~~~~~~
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py
index dc720ad..f471b94 100644
--- a/cryptography/hazmat/backends/interfaces.py
+++ b/cryptography/hazmat/backends/interfaces.py
@@ -260,13 +260,13 @@
         """
 
     @abc.abstractmethod
-    def elliptic_curve_public_key_from_numbers(self, numbers):
+    def load_elliptic_curve_public_numbers(self, numbers):
         """
         Return an EllipticCurvePublicKey provider using the given numbers.
         """
 
     @abc.abstractmethod
-    def elliptic_curve_private_key_from_numbers(self, numbers):
+    def load_elliptic_curve_private_numbers(self, numbers):
         """
         Return an EllipticCurvePublicKey provider using the given numbers.
         """
diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py
index 163dd0e..ce9e6de 100644
--- a/cryptography/hazmat/backends/multibackend.py
+++ b/cryptography/hazmat/backends/multibackend.py
@@ -13,6 +13,8 @@
 
 from __future__ import absolute_import, division, print_function
 
+import warnings
+
 from cryptography import utils
 from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
 from cryptography.hazmat.backends.interfaces import (
@@ -297,6 +299,12 @@
         )
 
     def elliptic_curve_private_key_from_numbers(self, numbers):
+        warnings.warn(
+            "elliptic_curve_private_key_from_numbers is deprecated and will "
+            "be removed in a future version.",
+            utils.DeprecatedIn06,
+            stacklevel=2
+        )
         for b in self._filtered_backends(EllipticCurveBackend):
             try:
                 return b.elliptic_curve_private_key_from_numbers(numbers)
@@ -308,7 +316,25 @@
             _Reasons.UNSUPPORTED_ELLIPTIC_CURVE
         )
 
+    def load_elliptic_curve_private_numbers(self, numbers):
+        for b in self._filtered_backends(EllipticCurveBackend):
+            try:
+                return b.load_elliptic_curve_private_numbers(numbers)
+            except UnsupportedAlgorithm:
+                continue
+
+        raise UnsupportedAlgorithm(
+            "This backend does not support this elliptic curve.",
+            _Reasons.UNSUPPORTED_ELLIPTIC_CURVE
+        )
+
     def elliptic_curve_public_key_from_numbers(self, numbers):
+        warnings.warn(
+            "elliptic_curve_public_key_from_numbers is deprecated and will "
+            "be removed in a future version.",
+            utils.DeprecatedIn06,
+            stacklevel=2
+        )
         for b in self._filtered_backends(EllipticCurveBackend):
             try:
                 return b.elliptic_curve_public_key_from_numbers(numbers)
@@ -320,6 +346,18 @@
             _Reasons.UNSUPPORTED_ELLIPTIC_CURVE
         )
 
+    def load_elliptic_curve_public_numbers(self, numbers):
+        for b in self._filtered_backends(EllipticCurveBackend):
+            try:
+                return b.load_elliptic_curve_public_numbers(numbers)
+            except UnsupportedAlgorithm:
+                continue
+
+        raise UnsupportedAlgorithm(
+            "This backend does not support this elliptic curve.",
+            _Reasons.UNSUPPORTED_ELLIPTIC_CURVE
+        )
+
     def load_pem_private_key(self, data, password):
         for b in self._filtered_backends(PEMSerializationBackend):
             return b.load_pem_private_key(data, password)
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 389ef0b..d0f6937 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -1015,6 +1015,15 @@
             )
 
     def elliptic_curve_private_key_from_numbers(self, numbers):
+        warnings.warn(
+            "elliptic_curve_private_key_from_numbers is deprecated and will "
+            "be removed in a future version.",
+            utils.DeprecatedIn06,
+            stacklevel=2
+        )
+        return self.load_elliptic_curve_private_numbers(numbers)
+
+    def load_elliptic_curve_private_numbers(self, numbers):
         public = numbers.public_numbers
 
         curve_nid = self._elliptic_curve_to_nid(public.curve)
@@ -1034,6 +1043,15 @@
                                         numbers.public_numbers.curve)
 
     def elliptic_curve_public_key_from_numbers(self, numbers):
+        warnings.warn(
+            "elliptic_curve_public_key_from_numbers is deprecated and will be "
+            "removed in a future version.",
+            utils.DeprecatedIn06,
+            stacklevel=2
+        )
+        return self.load_elliptic_curve_public_numbers(numbers)
+
+    def load_elliptic_curve_public_numbers(self, numbers):
         curve_nid = self._elliptic_curve_to_nid(numbers.curve)
 
         ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid)
diff --git a/cryptography/hazmat/primitives/asymmetric/ec.py b/cryptography/hazmat/primitives/asymmetric/ec.py
index 98eca27..6dcf39c 100644
--- a/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -238,7 +238,10 @@
         self._curve = curve
 
     def public_key(self, backend):
-        return backend.elliptic_curve_public_key_from_numbers(self)
+        try:
+            return backend.load_elliptic_curve_public_numbers(self)
+        except AttributeError:
+            return backend.elliptic_curve_public_key_from_numbers(self)
 
     @property
     def curve(self):
@@ -268,7 +271,10 @@
         self._public_numbers = public_numbers
 
     def private_key(self, backend):
-        return backend.elliptic_curve_private_key_from_numbers(self)
+        try:
+            return backend.load_elliptic_curve_private_numbers(self)
+        except AttributeError:
+            return backend.elliptic_curve_private_key_from_numbers(self)
 
     @property
     def private_value(self):
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index e8e1bac..3b41433 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -558,7 +558,7 @@
             :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurve`
             provider.
 
-    .. method:: elliptic_curve_private_key_from_numbers(numbers)
+    .. method:: load_elliptic_curve_private_numbers(numbers)
 
         :param numbers: An instance of a
             :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurvePrivateNumbers`
@@ -568,7 +568,7 @@
             :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurvePrivateKey`
             provider.
 
-    .. method:: elliptic_curve_public_key_from_numbers(numbers)
+    .. method:: load_elliptic_curve_public_numbers(numbers)
 
         :param numbers: An instance of a
             :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurvePublicNumbers`
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index 45c12b3..61bda54 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -13,6 +13,8 @@
 
 from __future__ import absolute_import, division, print_function
 
+import pytest
+
 from cryptography import utils
 from cryptography.exceptions import (
     UnsupportedAlgorithm, _Reasons
@@ -191,6 +193,10 @@
         if not self.elliptic_curve_supported(curve):
             raise UnsupportedAlgorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE)
 
+    def load_elliptic_curve_private_numbers(self, numbers):
+        if not self.elliptic_curve_supported(numbers.public_numbers.curve):
+            raise UnsupportedAlgorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE)
+
     def elliptic_curve_private_key_from_numbers(self, numbers):
         if not self.elliptic_curve_supported(numbers.public_numbers.curve):
             raise UnsupportedAlgorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE)
@@ -199,6 +205,10 @@
         if not self.elliptic_curve_supported(numbers.curve):
             raise UnsupportedAlgorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE)
 
+    def load_elliptic_curve_public_numbers(self, numbers):
+        if not self.elliptic_curve_supported(numbers.curve):
+            raise UnsupportedAlgorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE)
+
 
 @utils.register_interface(PKCS8SerializationBackend)
 class DummyPKCS8SerializationBackend(object):
@@ -463,7 +473,7 @@
 
         backend.generate_elliptic_curve_private_key(ec.SECT283K1())
 
-        backend.elliptic_curve_private_key_from_numbers(
+        backend.load_elliptic_curve_private_numbers(
             ec.EllipticCurvePrivateNumbers(
                 1,
                 ec.EllipticCurvePublicNumbers(
@@ -474,7 +484,7 @@
             )
         )
 
-        backend.elliptic_curve_public_key_from_numbers(
+        backend.load_elliptic_curve_public_numbers(
             ec.EllipticCurvePublicNumbers(
                 2,
                 3,
@@ -493,6 +503,51 @@
             backend.generate_elliptic_curve_private_key(ec.SECT163K1())
 
         with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE):
+            backend.load_elliptic_curve_private_numbers(
+                ec.EllipticCurvePrivateNumbers(
+                    1,
+                    ec.EllipticCurvePublicNumbers(
+                        2,
+                        3,
+                        ec.SECT163K1()
+                    )
+                )
+            )
+
+        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE):
+            backend.load_elliptic_curve_public_numbers(
+                ec.EllipticCurvePublicNumbers(
+                    2,
+                    3,
+                    ec.SECT163K1()
+                )
+            )
+
+    def test_deprecated_elliptic_curve(self):
+        backend = MultiBackend([
+            DummyEllipticCurveBackend([
+                ec.SECT283K1
+            ])
+        ])
+
+        assert backend.elliptic_curve_signature_algorithm_supported(
+            ec.ECDSA(hashes.SHA256()),
+            ec.SECT163K1()
+        ) is False
+
+        pub_numbers = ec.EllipticCurvePublicNumbers(2, 3, ec.SECT283K1())
+        numbers = ec.EllipticCurvePrivateNumbers(1, pub_numbers)
+
+        pytest.deprecated_call(
+            backend.elliptic_curve_private_key_from_numbers,
+            numbers
+        )
+        pytest.deprecated_call(
+            backend.elliptic_curve_public_key_from_numbers,
+            pub_numbers
+        )
+
+        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE):
             backend.elliptic_curve_private_key_from_numbers(
                 ec.EllipticCurvePrivateNumbers(
                     1,
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 110bbdb..bfe6040 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -28,12 +28,13 @@
     Backend, backend
 )
 from cryptography.hazmat.primitives import hashes, interfaces
-from cryptography.hazmat.primitives.asymmetric import dsa, padding, rsa
+from cryptography.hazmat.primitives.asymmetric import dsa, ec, padding, rsa
 from cryptography.hazmat.primitives.ciphers import Cipher
 from cryptography.hazmat.primitives.ciphers.algorithms import AES
 from cryptography.hazmat.primitives.ciphers.modes import CBC, CTR
 from cryptography.hazmat.primitives.interfaces import BlockCipherAlgorithm
 
+from ..primitives.test_ec import _skip_curve_unsupported
 from ...utils import load_vectors_from_file, raises_unsupported_algorithm
 
 
@@ -569,3 +570,41 @@
             b"\x00" * 128,
             hashes.SHA1()
         )
+
+
+@pytest.mark.elliptic
+class TestDeprecatedECBackendMethods(object):
+    def test_elliptic_curve_private_key_from_numbers(self):
+        d = 5634846038258869671139984276180670841223409490498798721258
+        y = 4131560123026307384858369684985976479488628761329758810693
+        x = 3402090428547195623222463880060959356423657484435591627791
+        curve = ec.SECP192R1()
+        _skip_curve_unsupported(backend, curve)
+        pub_numbers = ec.EllipticCurvePublicNumbers(
+            x=x,
+            y=y,
+            curve=curve
+        )
+        numbers = ec.EllipticCurvePrivateNumbers(
+            private_value=d,
+            public_numbers=pub_numbers
+        )
+        pytest.deprecated_call(
+            backend.elliptic_curve_private_key_from_numbers,
+            numbers
+        )
+
+    def test_elliptic_curve_public_key_from_numbers(self):
+        y = 4131560123026307384858369684985976479488628761329758810693
+        x = 3402090428547195623222463880060959356423657484435591627791
+        curve = ec.SECP192R1()
+        _skip_curve_unsupported(backend, curve)
+        pub_numbers = ec.EllipticCurvePublicNumbers(
+            x=x,
+            y=y,
+            curve=curve
+        )
+        pytest.deprecated_call(
+            backend.elliptic_curve_public_key_from_numbers,
+            pub_numbers
+        )
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 65461f7..3550582 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -20,6 +20,7 @@
 import pytest
 
 from cryptography import exceptions, utils
+from cryptography.hazmat.backends.interfaces import EllipticCurveBackend
 from cryptography.hazmat.primitives import hashes, interfaces
 from cryptography.hazmat.primitives.asymmetric import ec
 
@@ -70,6 +71,15 @@
     pass
 
 
+@utils.register_interface(EllipticCurveBackend)
+class DeprecatedDummyECBackend(object):
+    def elliptic_curve_private_key_from_numbers(self, numbers):
+        return b"private_key"
+
+    def elliptic_curve_public_key_from_numbers(self, numbers):
+        return b"public_key"
+
+
 @pytest.mark.elliptic
 def test_skip_curve_unsupported(backend):
     with pytest.raises(pytest.skip.Exception):
@@ -282,3 +292,14 @@
                 verifier.verify()
         else:
             verifier.verify()
+
+    def test_deprecated_public_private_key_load(self):
+        b = DeprecatedDummyECBackend()
+        pub_numbers = ec.EllipticCurvePublicNumbers(
+            2,
+            3,
+            ec.SECT283K1()
+        )
+        numbers = ec.EllipticCurvePrivateNumbers(1, pub_numbers)
+        assert numbers.private_key(b) == b"private_key"
+        assert pub_numbers.public_key(b) == b"public_key"