From 79d7e385b0f4014be864fdaa7ad662bdcfc756f7 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Sun, 26 Jan 2020 11:53:30 +0100 Subject: [PATCH 1/3] Enable explicit ECC curve parameters export --- AUTHORS.rst | 1 + Changelog.rst | 1 + lib/Crypto/PublicKey/ECC.py | 43 ++++++++++++++++-- .../SelfTest/PublicKey/test_import_ECC.py | 7 +++ .../ECC/ecc_p256_private_explicit_params.der | Bin 0 -> 341 bytes 5 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 lib/Crypto/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_explicit_params.der diff --git a/AUTHORS.rst b/AUTHORS.rst index bdafc8224..58f8d803b 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -29,6 +29,7 @@ Mark Moraes Lim Chee Siang Bryan Olson Wallace Owen +Sylvain Pelissier Colin Plumb Robey Pointer Lorenz Quack diff --git a/Changelog.rst b/Changelog.rst index a0e1f6874..645c39856 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -7,6 +7,7 @@ Changelog New features ------------ * Updated Wycheproof test vectors to version 0.8r12. +* Export explicitly ECC curve parameters in key file. Resolved issues --------------- diff --git a/lib/Crypto/PublicKey/ECC.py b/lib/Crypto/PublicKey/ECC.py index 5bce31f73..6c953b35a 100644 --- a/lib/Crypto/PublicKey/ECC.py +++ b/lib/Crypto/PublicKey/ECC.py @@ -89,7 +89,7 @@ int ec_ws_is_pai(EcPoint *ecp); """) -_Curve = namedtuple("_Curve", "p b order Gx Gy G modulus_bits oid context desc openssh") +_Curve = namedtuple("_Curve", "p a b order Gx Gy G modulus_bits oid context desc openssh") _curves = {} @@ -99,6 +99,7 @@ def init_p256(): p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff + a = p - 3 b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b order = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 @@ -121,6 +122,7 @@ def init_p256(): context = SmartPointer(ec_p256_context.get(), _ec_lib.ec_free_context) p256 = _Curve(Integer(p), + Integer(a), Integer(b), Integer(order), Integer(Gx), @@ -145,6 +147,7 @@ def init_p256(): def init_p384(): p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff + a = p - 3 b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef order = 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760aB7 @@ -167,6 +170,7 @@ def init_p384(): context = SmartPointer(ec_p384_context.get(), _ec_lib.ec_free_context) p384 = _Curve(Integer(p), + Integer(a), Integer(b), Integer(order), Integer(Gx), @@ -191,6 +195,7 @@ def init_p384(): def init_p521(): p = 0x000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + a = p - 3 b = 0x00000051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 order = 0x000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409 Gx = 0x000000c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66 @@ -213,6 +218,7 @@ def init_p521(): context = SmartPointer(ec_p521_context.get(), _ec_lib.ec_free_context) p521 = _Curve(Integer(p), + Integer(a), Integer(b), Integer(order), Integer(Gx), @@ -560,7 +566,7 @@ def _export_subjectPublicKeyInfo(self, compress): public_key, DerObjectId(self._curve.oid)) - def _export_private_der(self, include_ec_params=True): + def _export_private_der(self, **kwargs): assert self.has_private() @@ -572,12 +578,35 @@ def _export_private_der(self, include_ec_params=True): # } # Public key - uncompressed form + args = kwargs.copy() + include_ec_params = args.pop("include_ec_params", True) + params_enc_explicit = args.pop("params_enc_explicit", False) modulus_bytes = self.pointQ.size_in_bytes() public_key = (b'\x04' + self.pointQ.x.to_bytes(modulus_bytes) + self.pointQ.y.to_bytes(modulus_bytes)) - seq = [1, + if params_enc_explicit: + order = int(self._curve.order) + p = int(self._curve.p) + generator = (b'\x04' + + self._curve.G.x.to_bytes(modulus_bytes) + + self._curve.G.y.to_bytes(modulus_bytes)) + field_parameters = DerSequence([DerObjectId("1.2.840.10045.1.1"), p]) + parameters = [DerSequence([1, field_parameters, + DerSequence([ + DerOctetString(self._curve.a.to_bytes(modulus_bytes)), + DerOctetString(self._curve.b.to_bytes(modulus_bytes))]), + DerOctetString(generator), + order, + 1 + ])] + seq = [1, + DerOctetString(self.d.to_bytes(modulus_bytes)), + DerSequence(parameters, implicit=0), + DerBitString(public_key, explicit=1)] + else: + seq = [1, DerOctetString(self.d.to_bytes(modulus_bytes)), DerObjectId(self._curve.oid, explicit=0), DerBitString(public_key, explicit=1)] @@ -610,7 +639,7 @@ def _export_public_pem(self, compress): def _export_private_pem(self, passphrase, **kwargs): from Crypto.IO import PEM - encoded_der = self._export_private_der() + encoded_der = self._export_private_der(**kwargs) return PEM.encode(encoded_der, "EC PRIVATE KEY", passphrase, **kwargs) def _export_private_clear_pkcs8_in_clear_pem(self): @@ -650,6 +679,7 @@ def _export_openssh(self, compress): return desc + " " + tostr(binascii.b2a_base64(blob)) def export_key(self, **kwargs): + """Export this ECC key. Args: @@ -689,6 +719,9 @@ def export_key(self, **kwargs): If ``False`` (default), the full public key will be exported. + params_enc_explicit (boolean): + If ``True``, stores the curve parameters with the keys. + .. warning:: If you don't provide a passphrase, the private key will be exported in the clear! @@ -738,7 +771,7 @@ def export_key(self, **kwargs): if use_pkcs8: return self._export_pkcs8(passphrase=passphrase, **args) else: - return self._export_private_der() + return self._export_private_der(**args) else: raise ValueError("Private keys cannot be exported in OpenSSH format") else: # Public key diff --git a/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py b/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py index 19ef4b40c..a06f12d7d 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py +++ b/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py @@ -506,6 +506,13 @@ def test_export_private_der(self): encoded = self.ref_private.export_key(format="DER", use_pkcs8=False) self.assertEqual(key_file, encoded) + + def test_export_private_explicit_params_der(self): + key_file = load_file("ecc_p256_private_explicit_params.der") + key = ECC.construct(curve='P-256', d=0x5c4e4320ef260f91ed9fc597aee98c8236b60e0ced692cc7a057d5e45798a052) + + encoded = key._export_private_der(params_enc_explicit = True) + self.assertEqual(key_file, encoded) def test_export_private_pkcs8_clear(self): key_file = load_file("ecc_p256_private_p8_clear.der") diff --git a/lib/Crypto/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_explicit_params.der b/lib/Crypto/SelfTest/PublicKey/test_vectors/ECC/ecc_p256_private_explicit_params.der new file mode 100644 index 0000000000000000000000000000000000000000..47203ece16c5e7fb0dd4065cff26fc42bb5be026 GIT binary patch literal 341 zcmXqLVhm(rWMol@@pD#quf{*|?fj$D*S+j%GTX+-^EOlG_=51OPr_#`2wKqi*r4$N zP^p0q8@pDU$2nU@MkYmu|3JXNz`zK^Z~zj60RtBn1rQr3iA&8N7KNx|rZ-kuO@6-l z_1@638Etz~W!W~I3EuF{`kalO`lSSK7DtwB@r$1x>NvUo*z@dZ@)Czn<;=B>y048F zd|7DedSk|+Y5tF$9{rQ5pWXNTwO0-QJTdKa#^Kq9apz8NbI35?ANUpFRGyF|aJ*x;jfC;Pp$D%DwR$vo}47PDy=jvuWe|e@^zR rpPepIx!olBo_lq}nos%HS*LE3e^SP4{O$(t1zY_K_cvAdJdXhYH07nJ literal 0 HcmV?d00001 From 38b06db0e815b060367d30a562a863bb08eca856 Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Mon, 10 Feb 2020 22:18:20 +0100 Subject: [PATCH 2/3] Add Experimental module --- lib/Crypto/Experimental/ECC.py | 154 ++++++++++++++++++ lib/Crypto/Experimental/__init__.py | 0 lib/Crypto/PublicKey/ECC.py | 32 +--- lib/Crypto/SelfTest/Experimental/__init__.py | 39 +++++ lib/Crypto/SelfTest/Experimental/test_ECC.py | 68 ++++++++ .../SelfTest/PublicKey/test_import_ECC.py | 7 - lib/Crypto/SelfTest/__init__.py | 1 + lib/Crypto/__init__.py | 2 +- setup.py | 2 + 9 files changed, 269 insertions(+), 36 deletions(-) create mode 100644 lib/Crypto/Experimental/ECC.py create mode 100644 lib/Crypto/Experimental/__init__.py create mode 100644 lib/Crypto/SelfTest/Experimental/__init__.py create mode 100644 lib/Crypto/SelfTest/Experimental/test_ECC.py diff --git a/lib/Crypto/Experimental/ECC.py b/lib/Crypto/Experimental/ECC.py new file mode 100644 index 000000000..d92103385 --- /dev/null +++ b/lib/Crypto/Experimental/ECC.py @@ -0,0 +1,154 @@ +# =================================================================== +# +# Copyright (c) 2019, Sylvain Pelissier +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== +from Crypto.Math.Numbers import Integer +from Crypto.PublicKey.ECC import (EccKey, _curves, EccPoint) +from Crypto.Util.asn1 import (DerObjectId, DerOctetString, DerSequence, + DerBitString) + +from Crypto.Random import get_random_bytes + + +class EccKeyExplicit(EccKey): + r"""Class defining an ECC key supporting the explicit curve parameters export. + """ + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + def _export_private_der(self, **kwargs): + + assert self.has_private() + + # ECPrivateKey ::= SEQUENCE { + # version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + # privateKey OCTET STRING, + # parameters [0] ECParameters, + # publicKey [1] BIT STRING OPTIONAL + # } + + # Public key - uncompressed form + args = kwargs.copy() + include_ec_params = args.pop("include_ec_params", True) + modulus_bytes = self.pointQ.size_in_bytes() + public_key = (b'\x04' + + self.pointQ.x.to_bytes(modulus_bytes) + + self.pointQ.y.to_bytes(modulus_bytes)) + + order = int(self._curve.order) + p = int(self._curve.p) + generator = (b'\x04' + + self._curve.G.x.to_bytes(modulus_bytes) + + self._curve.G.y.to_bytes(modulus_bytes)) + field_parameters = DerSequence([DerObjectId("1.2.840.10045.1.1"), p]) + parameters = [DerSequence([1, field_parameters, + DerSequence([ + DerOctetString(self._curve.a.to_bytes(modulus_bytes)), + DerOctetString(self._curve.b.to_bytes(modulus_bytes))]), + DerOctetString(generator), + order, + 1 + ])] + seq = [1, + DerOctetString(self.d.to_bytes(modulus_bytes)), + DerSequence(parameters, implicit=0), + DerBitString(public_key, explicit=1)] + + if not include_ec_params: + del seq[2] + + return DerSequence(seq).encode() + +def generate(**kwargs): + """Generate a new private key on the given curve. + + Args: + + curve (string): + Mandatory. It must be a curve name defined in :numref:`curve_names`. + + randfunc (callable): + Optional. The RNG to read randomness from. + If ``None``, :func:`Crypto.Random.get_random_bytes` is used. + """ + + curve_name = kwargs.pop("curve") + curve = _curves[curve_name] + randfunc = kwargs.pop("randfunc", get_random_bytes) + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + d = Integer.random_range(min_inclusive=1, + max_exclusive=curve.order, + randfunc=randfunc) + + return EccKeyExplicit(curve=curve_name, d=d) + +def construct(**kwargs): + """Build a new ECC key (private or public) starting + from some base components. + + Args: + + curve (string): + Mandatory. It must be a curve name defined in :numref:`curve_names`. + + d (integer): + Only for a private key. It must be in the range ``[1..order-1]``. + + point_x (integer): + Mandatory for a public key. X coordinate (affine) of the ECC point. + + point_y (integer): + Mandatory for a public key. Y coordinate (affine) of the ECC point. + + Returns: + :class:`EccKey` : a new ECC key object + """ + + curve_name = kwargs["curve"] + curve = _curves[curve_name] + point_x = kwargs.pop("point_x", None) + point_y = kwargs.pop("point_y", None) + + if "point" in kwargs: + raise TypeError("Unknown keyword: point") + + if None not in (point_x, point_y): + # ValueError is raised if the point is not on the curve + kwargs["point"] = EccPoint(point_x, point_y, curve_name) + + # Validate that the private key matches the public one + d = kwargs.get("d", None) + if d is not None and "point" in kwargs: + pub_key = curve.G * d + if pub_key.xy != (point_x, point_y): + raise ValueError("Private and public ECC keys do not match") + + return EccKeyExplicit(**kwargs) \ No newline at end of file diff --git a/lib/Crypto/Experimental/__init__.py b/lib/Crypto/Experimental/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/lib/Crypto/PublicKey/ECC.py b/lib/Crypto/PublicKey/ECC.py index 6c953b35a..86db10020 100644 --- a/lib/Crypto/PublicKey/ECC.py +++ b/lib/Crypto/PublicKey/ECC.py @@ -580,36 +580,15 @@ def _export_private_der(self, **kwargs): # Public key - uncompressed form args = kwargs.copy() include_ec_params = args.pop("include_ec_params", True) - params_enc_explicit = args.pop("params_enc_explicit", False) modulus_bytes = self.pointQ.size_in_bytes() public_key = (b'\x04' + self.pointQ.x.to_bytes(modulus_bytes) + self.pointQ.y.to_bytes(modulus_bytes)) - if params_enc_explicit: - order = int(self._curve.order) - p = int(self._curve.p) - generator = (b'\x04' + - self._curve.G.x.to_bytes(modulus_bytes) + - self._curve.G.y.to_bytes(modulus_bytes)) - field_parameters = DerSequence([DerObjectId("1.2.840.10045.1.1"), p]) - parameters = [DerSequence([1, field_parameters, - DerSequence([ - DerOctetString(self._curve.a.to_bytes(modulus_bytes)), - DerOctetString(self._curve.b.to_bytes(modulus_bytes))]), - DerOctetString(generator), - order, - 1 - ])] - seq = [1, - DerOctetString(self.d.to_bytes(modulus_bytes)), - DerSequence(parameters, implicit=0), - DerBitString(public_key, explicit=1)] - else: - seq = [1, - DerOctetString(self.d.to_bytes(modulus_bytes)), - DerObjectId(self._curve.oid, explicit=0), - DerBitString(public_key, explicit=1)] + seq = [1, + DerOctetString(self.d.to_bytes(modulus_bytes)), + DerObjectId(self._curve.oid, explicit=0), + DerBitString(public_key, explicit=1)] if not include_ec_params: del seq[2] @@ -719,9 +698,6 @@ def export_key(self, **kwargs): If ``False`` (default), the full public key will be exported. - params_enc_explicit (boolean): - If ``True``, stores the curve parameters with the keys. - .. warning:: If you don't provide a passphrase, the private key will be exported in the clear! diff --git a/lib/Crypto/SelfTest/Experimental/__init__.py b/lib/Crypto/SelfTest/Experimental/__init__.py new file mode 100644 index 000000000..ecf5fbfdd --- /dev/null +++ b/lib/Crypto/SelfTest/Experimental/__init__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# +# SelfTest/PublicKey/__init__.py: Self-test for public key crypto +# +# Written in 2008 by Dwayne C. Litzenberger +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""Self-test for experimental crypto""" + +__revision__ = "$Id$" + +def get_tests(config={}): + tests = [] + from Crypto.SelfTest.Experimental import test_ECC; tests += test_ECC.get_tests(config=config) + return tests + +if __name__ == '__main__': + import unittest + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/lib/Crypto/SelfTest/Experimental/test_ECC.py b/lib/Crypto/SelfTest/Experimental/test_ECC.py new file mode 100644 index 000000000..c782608d1 --- /dev/null +++ b/lib/Crypto/SelfTest/Experimental/test_ECC.py @@ -0,0 +1,68 @@ +# =================================================================== +# +# Copyright (c) 2015, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import sys +import unittest +from binascii import unhexlify + +from Crypto.SelfTest.st_common import list_test_cases +from Crypto.Util._file_system import pycryptodome_filename +from Crypto.Util.py3compat import bord, tostr +from Crypto.Util.number import bytes_to_long + +from Crypto.Experimental import ECC + +def load_file(filename, mode="rb"): + comps = [ "Crypto", "SelfTest", "PublicKey", "test_vectors", "ECC" ] + with open(pycryptodome_filename(comps, filename), mode) as fd: + return fd.read() + + +def compact(lines): + ext = b"".join(lines) + return unhexlify(tostr(ext).replace(" ", "").replace(":", "")) + +class TestExportExplicit_P256(unittest.TestCase): + + def test_export_private_explicit_params_der(self): + key_file = load_file("ecc_p256_private_explicit_params.der") + key = ECC.construct(curve='P-256', d=0x5c4e4320ef260f91ed9fc597aee98c8236b60e0ced692cc7a057d5e45798a052) + + encoded = key._export_private_der() + self.assertEqual(key_file, encoded) + +def get_tests(config={}): + tests = [] + tests += list_test_cases(TestExportExplicit_P256) + return tests + +if __name__ == '__main__': + suite = lambda: unittest.TestSuite(get_tests()) + unittest.main(defaultTest='suite') \ No newline at end of file diff --git a/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py b/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py index a06f12d7d..19ef4b40c 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py +++ b/lib/Crypto/SelfTest/PublicKey/test_import_ECC.py @@ -506,13 +506,6 @@ def test_export_private_der(self): encoded = self.ref_private.export_key(format="DER", use_pkcs8=False) self.assertEqual(key_file, encoded) - - def test_export_private_explicit_params_der(self): - key_file = load_file("ecc_p256_private_explicit_params.der") - key = ECC.construct(curve='P-256', d=0x5c4e4320ef260f91ed9fc597aee98c8236b60e0ced692cc7a057d5e45798a052) - - encoded = key._export_private_der(params_enc_explicit = True) - self.assertEqual(key_file, encoded) def test_export_private_pkcs8_clear(self): key_file = load_file("ecc_p256_private_p8_clear.der") diff --git a/lib/Crypto/SelfTest/__init__.py b/lib/Crypto/SelfTest/__init__.py index bc34f4a8c..41252e487 100644 --- a/lib/Crypto/SelfTest/__init__.py +++ b/lib/Crypto/SelfTest/__init__.py @@ -88,6 +88,7 @@ def get_tests(config={}): from Crypto.SelfTest import Signature; tests += Signature.get_tests(config=config) from Crypto.SelfTest import IO; tests += IO.get_tests(config=config) from Crypto.SelfTest import Math; tests += Math.get_tests(config=config) + from Crypto.SelfTest import Experimental; tests += Experimental.get_tests(config=config) return tests if __name__ == '__main__': diff --git a/lib/Crypto/__init__.py b/lib/Crypto/__init__.py index 043b4892b..261329b9b 100644 --- a/lib/Crypto/__init__.py +++ b/lib/Crypto/__init__.py @@ -1,5 +1,5 @@ __all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature', - 'IO', 'Math'] + 'IO', 'Math', 'Experimental'] version_info = (3, 9, '5a0') diff --git a/setup.py b/setup.py index 74ea6e114..721af5cde 100644 --- a/setup.py +++ b/setup.py @@ -249,6 +249,7 @@ def create_cryptodome_lib(): "Crypto.Signature", "Crypto.Util", "Crypto.Math", + "Crypto.Experimental", "Crypto.SelfTest", "Crypto.SelfTest.Cipher", "Crypto.SelfTest.Hash", @@ -259,6 +260,7 @@ def create_cryptodome_lib(): "Crypto.SelfTest.Signature", "Crypto.SelfTest.Util", "Crypto.SelfTest.Math", + "Crypto.SelfTest.Experimental", ] package_data = { "Crypto" : [ "py.typed", "*.pyi" ], From 7636a8b42c4a36fdd6db345b1f6f9098943fdd6b Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 11 Feb 2020 14:54:53 +0100 Subject: [PATCH 3/3] Python2 compatibility --- lib/Crypto/Experimental/ECC.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Crypto/Experimental/ECC.py b/lib/Crypto/Experimental/ECC.py index d92103385..baa791303 100644 --- a/lib/Crypto/Experimental/ECC.py +++ b/lib/Crypto/Experimental/ECC.py @@ -40,7 +40,7 @@ class EccKeyExplicit(EccKey): """ def __init__(self, **kwargs): - super().__init__(**kwargs) + EccKey.__init__(self, **kwargs) def _export_private_der(self, **kwargs):