aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-10-27 16:47:55 +0900
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-10-27 20:35:13 +0900
commit13d4e74b13832b495ddfdff043376144d8ada66a (patch)
tree8100b54337d32b0442c9ff1315e24e1f64b0a58c
parente4150bcc07fb2c68e3c860c31766b4282bba8740 (diff)
downloadcryptography-13d4e74b13832b495ddfdff043376144d8ada66a.tar.gz
cryptography-13d4e74b13832b495ddfdff043376144d8ada66a.tar.bz2
cryptography-13d4e74b13832b495ddfdff043376144d8ada66a.zip
modify approach to use EllipticCurvePublicNumbers methods
-rw-r--r--docs/hazmat/primitives/asymmetric/ec.rst32
-rw-r--r--docs/hazmat/primitives/asymmetric/utils.rst45
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/ec.py28
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/utils.py34
-rw-r--r--tests/hazmat/primitives/test_asym_utils.py75
-rw-r--r--tests/hazmat/primitives/test_ec.py74
6 files changed, 136 insertions, 152 deletions
diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst
index 90e73711..c1619dd0 100644
--- a/docs/hazmat/primitives/asymmetric/ec.rst
+++ b/docs/hazmat/primitives/asymmetric/ec.rst
@@ -122,6 +122,37 @@ Elliptic Curve Signature Algorithms
:returns: A new instance of a :class:`EllipticCurvePublicKey`
provider.
+ .. method:: encode_point()
+
+ .. versionadded:: 1.1
+
+ Encodes an elliptic curve point to a byte string as described in
+ `SEC 1 v2.0`_ section 2.3.3. This method only supports uncompressed
+ points.
+
+ :return bytes: The encoded point.
+
+ .. classmethod:: from_encoded_point(curve, data)
+
+ .. versionadded:: 1.1
+
+ Decodes a byte string as described in `SEC 1 v2.0`_ section 2.3.3 and
+ returns an :class:`EllipticCurvePublicNumbers`. This method only
+ supports uncompressed points.
+
+ :param curve: An
+ :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`
+ instance.
+
+ :param bytes data: The serialized point byte string.
+
+ :returns: An :class:`EllipticCurvePublicNumbers` instance.
+
+ :raises ValueError: Raised on invalid point type or data length.
+
+ :raises TypeError: Raised when curve is not an
+ :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`.
+
Elliptic Curve Key Exchange algorithm
-------------------------------------
@@ -478,3 +509,4 @@ Key Interfaces
.. _`ECDSA`: https://en.wikipedia.org/wiki/ECDSA
.. _`EdDSA`: https://en.wikipedia.org/wiki/EdDSA
.. _`forward secrecy`: https://en.wikipedia.org/wiki/Forward_secrecy
+.. _`SEC 1 v2.0`: http://www.secg.org/sec1-v2.pdf
diff --git a/docs/hazmat/primitives/asymmetric/utils.rst b/docs/hazmat/primitives/asymmetric/utils.rst
index 79d14dae..07883598 100644
--- a/docs/hazmat/primitives/asymmetric/utils.rst
+++ b/docs/hazmat/primitives/asymmetric/utils.rst
@@ -28,48 +28,3 @@ Asymmetric Utilities
:param int s: The raw signature value ``s``.
:return bytes: The encoded signature.
-
-.. function:: encode_ec_point(curve, x, y)
-
- .. versionadded:: 1.1
-
- Encodes an elliptic curve point to a byte string as described in
- `SEC 1 v2.0`_ section 2.3.3. This function only supports uncompressed
- points.
-
- :param curve: An
- :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`
- instance.
-
- :param int x: The x value of the point.
-
- :param int y: The y value of the point.
-
- :return bytes: The encoded point.
-
- :raises TypeError: Raised when curve is not an
- :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`.
-
-.. function:: decode_ec_point(key_length, data)
-
- .. versionadded:: 1.1
-
- Decodes a byte string as described in `SEC 1 v2.0`_ section 2.3.3 to the
- ``x`` and ``y`` integer values. This function only supports uncompressed
- points.
-
- :param curve: An
- :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`
- instance.
-
- :param bytes data: The serialized point byte string.
-
- :returns: The decoded tuple ``(x, y)``.
-
- :raises ValueError: Raised on invalid point type or data length.
-
- :raises TypeError: Raised when curve is not an
- :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`.
-
-
-.. _`SEC 1 v2.0`: http://www.secg.org/sec1-v2.pdf
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
index c6f83667..f25ea6de 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -259,6 +259,34 @@ class EllipticCurvePublicNumbers(object):
def public_key(self, backend):
return backend.load_elliptic_curve_public_numbers(self)
+ def encode_point(self):
+ # key_size is in bits. Convert to bytes and round up
+ byte_length = (self.curve.key_size + 7) // 8
+ return (
+ b'\x04' + utils.int_to_bytes(self.x, byte_length) +
+ utils.int_to_bytes(self.y, byte_length)
+ )
+
+ @classmethod
+ def from_encoded_point(cls, curve, data):
+ if not isinstance(curve, EllipticCurve):
+ raise TypeError("curve must be an EllipticCurve instance")
+
+ if data == b'\x00':
+ raise ValueError("null points are not supported")
+ elif data.startswith(b'\x04'):
+ # key_size is in bits. Convert to bytes and round up
+ byte_length = (curve.key_size + 7) // 8
+ if len(data) == 2 * byte_length + 1:
+ x = utils.int_from_bytes(data[1:byte_length + 1], 'big')
+ y = utils.int_from_bytes(data[byte_length + 1:], 'big')
+ else:
+ raise ValueError('Invalid elliptic curve point data length')
+ else:
+ raise ValueError('Unsupported elliptic curve point type')
+
+ return cls(x, y, curve)
+
curve = utils.read_only_property("_curve")
x = utils.read_only_property("_x")
y = utils.read_only_property("_y")
diff --git a/src/cryptography/hazmat/primitives/asymmetric/utils.py b/src/cryptography/hazmat/primitives/asymmetric/utils.py
index 57dea41a..bad9ab73 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/utils.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/utils.py
@@ -13,7 +13,6 @@ from pyasn1.type import namedtype, univ
import six
from cryptography import utils
-from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
class _DSSSigValue(univ.Sequence):
@@ -72,36 +71,3 @@ def encode_dss_signature(r, s):
sig.setComponentByName('r', r)
sig.setComponentByName('s', s)
return encoder.encode(sig)
-
-
-def encode_ec_point(curve, x, y):
- if not isinstance(curve, EllipticCurve):
- raise TypeError("curve must be an EllipticCurve instance")
-
- if x is None:
- raise ValueError("null points are not supported")
- else:
- # key_size is in bits. Convert to bytes and round up
- byte_length = (curve.key_size + 7) // 8
- return (
- b'\x04' + utils.int_to_bytes(x, byte_length) +
- utils.int_to_bytes(y, byte_length)
- )
-
-
-def decode_ec_point(curve, data):
- if not isinstance(curve, EllipticCurve):
- raise TypeError("curve must be an EllipticCurve instance")
-
- if data == b'\x00':
- raise ValueError("null points are not supported")
- elif data.startswith(b'\x04'):
- # key_size is in bits. Convert to bytes and round up
- byte_length = (curve.key_size + 7) // 8
- if len(data) == 2 * byte_length + 1:
- return (utils.int_from_bytes(data[1:byte_length + 1], 'big'),
- utils.int_from_bytes(data[byte_length + 1:], 'big'))
- else:
- raise ValueError('Invalid elliptic curve point data length')
- else:
- raise ValueError('Unsupported elliptic curve point type')
diff --git a/tests/hazmat/primitives/test_asym_utils.py b/tests/hazmat/primitives/test_asym_utils.py
index 22551bc4..b9971137 100644
--- a/tests/hazmat/primitives/test_asym_utils.py
+++ b/tests/hazmat/primitives/test_asym_utils.py
@@ -4,14 +4,11 @@
from __future__ import absolute_import, division, print_function
-import binascii
-
import pytest
-from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.utils import (
- decode_dss_signature, decode_ec_point, decode_rfc6979_signature,
- encode_dss_signature, encode_ec_point, encode_rfc6979_signature
+ decode_dss_signature, decode_rfc6979_signature,
+ encode_dss_signature, encode_rfc6979_signature
)
@@ -79,71 +76,3 @@ def test_decode_dss_invalid_asn1():
# This is the BER "end-of-contents octets," which older versions of
# pyasn1 are wrongly willing to return from top-level DER decoding.
decode_dss_signature(b"\x00\x00")
-
-
-def test_encode_ec_point_none():
- with pytest.raises(ValueError):
- encode_ec_point(ec.SECP384R1(), None, 100)
-
-
-def test_encode_wrong_curve_type():
- with pytest.raises(TypeError):
- encode_ec_point("notacurve", 3, 4)
-
-
-def test_encode_ec_point():
- # secp256r1 point
- x = int(
- '233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec', 16
- )
- y = int(
- '3ea2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e', 16
- )
- data = encode_ec_point(ec.SECP256R1(), x, y)
- assert data == binascii.unhexlify(
- "04233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec3ea"
- "2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e"
- )
-
-
-def test_decode_ec_point_none():
- with pytest.raises(ValueError):
- decode_ec_point(ec.SECP384R1(), b"\x00")
-
-
-def test_decode_ec_point():
- # secp256r1 point
- data = binascii.unhexlify(
- "04233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec3ea"
- "2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e"
- )
- x, y = decode_ec_point(ec.SECP256R1(), data)
- assert x == int(
- '233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec', 16
- )
- assert y == int(
- '3ea2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e', 16
- )
-
-
-def test_decode_ec_point_invalid_length():
- bad_data = binascii.unhexlify(
- "04233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec3ea"
- "2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460"
- )
- with pytest.raises(ValueError):
- decode_ec_point(ec.SECP384R1(), bad_data)
-
-
-def test_decode_ec_point_unsupported_point_type():
- # set to point type 2.
- unsupported_type = binascii.unhexlify(
- "02233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec3e"
- )
- with pytest.raises(ValueError):
- decode_ec_point(ec.SECP256R1(), unsupported_type)
-
-
-def test_decode_wrong_curve_type():
- with pytest.raises(TypeError):
- decode_ec_point("notacurve", b"\x02data")
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 4c4d5b90..ac1ba27a 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -4,6 +4,7 @@
from __future__ import absolute_import, division, print_function
+import binascii
import itertools
import os
@@ -148,6 +149,79 @@ def test_ec_numbers():
)
+def test_encode_point():
+ # secp256r1 point
+ x = int(
+ '233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec',
+ 16
+ )
+ y = int(
+ '3ea2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e',
+ 16
+ )
+ pn = ec.EllipticCurvePublicNumbers(x, y, ec.SECP256R1())
+ data = pn.encode_point()
+ assert data == binascii.unhexlify(
+ "04233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22ae"
+ "c3ea2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e"
+ )
+
+
+def test_from_encoded_point_null():
+ with pytest.raises(ValueError):
+ ec.EllipticCurvePublicNumbers.from_encoded_point(
+ ec.SECP384R1(), b"\x00"
+ )
+
+
+def test_from_encoded_point():
+ # secp256r1 point
+ data = binascii.unhexlify(
+ "04233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22ae"
+ "c3ea2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e"
+ )
+ pn = ec.EllipticCurvePublicNumbers.from_encoded_point(
+ ec.SECP256R1(), data
+ )
+ assert pn.x == int(
+ '233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22aec',
+ 16
+ )
+ assert pn.y == int(
+ '3ea2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460b35f442e',
+ 16
+ )
+
+
+def test_from_encoded_point_invalid_length():
+ bad_data = binascii.unhexlify(
+ "04233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22ae"
+ "c3ea2c10a84153862be4ec82940f0543f9ba866af9751a6ee79d38460"
+ )
+ with pytest.raises(ValueError):
+ ec.EllipticCurvePublicNumbers.from_encoded_point(
+ ec.SECP384R1(), bad_data
+ )
+
+
+def test_from_encoded_point_unsupported_point_type():
+ # set to point type 2.
+ unsupported_type = binascii.unhexlify(
+ "02233ea3b0027127084cd2cd336a13aeef69c598d8af61369a36454a17c6c22a"
+ )
+ with pytest.raises(ValueError):
+ ec.EllipticCurvePublicNumbers.from_encoded_point(
+ ec.SECP256R1(), unsupported_type
+ )
+
+
+def test_from_encoded_point_not_a_curve():
+ with pytest.raises(TypeError):
+ ec.EllipticCurvePublicNumbers.from_encoded_point(
+ "notacurve", b"\x04data"
+ )
+
+
@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
class TestECWithNumbers(object):
@pytest.mark.parametrize(