diff options
Diffstat (limited to 'freezed_deps/ecdsa/test_pyecdsa.py')
-rw-r--r-- | freezed_deps/ecdsa/test_pyecdsa.py | 1445 |
1 files changed, 0 insertions, 1445 deletions
diff --git a/freezed_deps/ecdsa/test_pyecdsa.py b/freezed_deps/ecdsa/test_pyecdsa.py deleted file mode 100644 index d83eb01..0000000 --- a/freezed_deps/ecdsa/test_pyecdsa.py +++ /dev/null @@ -1,1445 +0,0 @@ -from __future__ import with_statement, division - -try: - import unittest2 as unittest -except ImportError: - import unittest -import os -import time -import shutil -import subprocess -import pytest -from binascii import hexlify, unhexlify -from hashlib import sha1, sha256, sha384, sha512 -import hashlib -from functools import partial - -from hypothesis import given -import hypothesis.strategies as st - -from six import b, print_, binary_type -from .keys import SigningKey, VerifyingKey -from .keys import BadSignatureError, MalformedPointError, BadDigestError -from . import util -from .util import sigencode_der, sigencode_strings -from .util import sigdecode_der, sigdecode_strings -from .util import number_to_string, encoded_oid_ecPublicKey, \ - MalformedSignature -from .curves import Curve, UnknownCurveError -from .curves import NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, \ - SECP256k1, BRAINPOOLP160r1, BRAINPOOLP192r1, BRAINPOOLP224r1, \ - BRAINPOOLP256r1, BRAINPOOLP320r1, BRAINPOOLP384r1, BRAINPOOLP512r1, \ - curves -from .ecdsa import curve_brainpoolp224r1, curve_brainpoolp256r1, \ - curve_brainpoolp384r1, curve_brainpoolp512r1 -from .ellipticcurve import Point -from . import der -from . import rfc6979 -from . import ecdsa - - -class SubprocessError(Exception): - pass - - -def run_openssl(cmd): - OPENSSL = "openssl" - p = subprocess.Popen([OPENSSL] + cmd.split(), - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - stdout, ignored = p.communicate() - if p.returncode != 0: - raise SubprocessError("cmd '%s %s' failed: rc=%s, stdout/err was %s" % - (OPENSSL, cmd, p.returncode, stdout)) - return stdout.decode() - - -class ECDSA(unittest.TestCase): - def test_basic(self): - priv = SigningKey.generate() - pub = priv.get_verifying_key() - - data = b("blahblah") - sig = priv.sign(data) - - self.assertTrue(pub.verify(sig, data)) - self.assertRaises(BadSignatureError, pub.verify, sig, data + b("bad")) - - pub2 = VerifyingKey.from_string(pub.to_string()) - self.assertTrue(pub2.verify(sig, data)) - - def test_deterministic(self): - data = b("blahblah") - secexp = int("9d0219792467d7d37b4d43298a7d0c05", 16) - - priv = SigningKey.from_secret_exponent(secexp, SECP256k1, sha256) - pub = priv.get_verifying_key() - - k = rfc6979.generate_k( - SECP256k1.generator.order(), secexp, sha256, sha256(data).digest()) - - sig1 = priv.sign(data, k=k) - self.assertTrue(pub.verify(sig1, data)) - - sig2 = priv.sign(data, k=k) - self.assertTrue(pub.verify(sig2, data)) - - sig3 = priv.sign_deterministic(data, sha256) - self.assertTrue(pub.verify(sig3, data)) - - self.assertEqual(sig1, sig2) - self.assertEqual(sig1, sig3) - - def test_bad_usage(self): - # sk=SigningKey() is wrong - self.assertRaises(TypeError, SigningKey) - self.assertRaises(TypeError, VerifyingKey) - - def test_lengths(self): - default = NIST192p - priv = SigningKey.generate() - pub = priv.get_verifying_key() - self.assertEqual(len(pub.to_string()), default.verifying_key_length) - sig = priv.sign(b("data")) - self.assertEqual(len(sig), default.signature_length) - for curve in (NIST192p, NIST224p, NIST256p, NIST384p, NIST521p, - BRAINPOOLP160r1, BRAINPOOLP192r1, BRAINPOOLP224r1, - BRAINPOOLP256r1, BRAINPOOLP320r1, BRAINPOOLP384r1, - BRAINPOOLP512r1): - start = time.time() - priv = SigningKey.generate(curve=curve) - pub1 = priv.get_verifying_key() - keygen_time = time.time() - start - pub2 = VerifyingKey.from_string(pub1.to_string(), curve) - self.assertEqual(pub1.to_string(), pub2.to_string()) - self.assertEqual(len(pub1.to_string()), - curve.verifying_key_length) - start = time.time() - sig = priv.sign(b("data")) - sign_time = time.time() - start - self.assertEqual(len(sig), curve.signature_length) - - def test_serialize(self): - seed = b("secret") - curve = NIST192p - secexp1 = util.randrange_from_seed__trytryagain(seed, curve.order) - secexp2 = util.randrange_from_seed__trytryagain(seed, curve.order) - self.assertEqual(secexp1, secexp2) - priv1 = SigningKey.from_secret_exponent(secexp1, curve) - priv2 = SigningKey.from_secret_exponent(secexp2, curve) - self.assertEqual(hexlify(priv1.to_string()), - hexlify(priv2.to_string())) - self.assertEqual(priv1.to_pem(), priv2.to_pem()) - pub1 = priv1.get_verifying_key() - pub2 = priv2.get_verifying_key() - data = b("data") - sig1 = priv1.sign(data) - sig2 = priv2.sign(data) - self.assertTrue(pub1.verify(sig1, data)) - self.assertTrue(pub2.verify(sig1, data)) - self.assertTrue(pub1.verify(sig2, data)) - self.assertTrue(pub2.verify(sig2, data)) - self.assertEqual(hexlify(pub1.to_string()), - hexlify(pub2.to_string())) - - def test_nonrandom(self): - s = b("all the entropy in the entire world, compressed into one line") - - def not_much_entropy(numbytes): - return s[:numbytes] - - # we control the entropy source, these two keys should be identical: - priv1 = SigningKey.generate(entropy=not_much_entropy) - priv2 = SigningKey.generate(entropy=not_much_entropy) - self.assertEqual(hexlify(priv1.get_verifying_key().to_string()), - hexlify(priv2.get_verifying_key().to_string())) - # likewise, signatures should be identical. Obviously you'd never - # want to do this with keys you care about, because the secrecy of - # the private key depends upon using different random numbers for - # each signature - sig1 = priv1.sign(b("data"), entropy=not_much_entropy) - sig2 = priv2.sign(b("data"), entropy=not_much_entropy) - self.assertEqual(hexlify(sig1), hexlify(sig2)) - - def assertTruePrivkeysEqual(self, priv1, priv2): - self.assertEqual(priv1.privkey.secret_multiplier, - priv2.privkey.secret_multiplier) - self.assertEqual(priv1.privkey.public_key.generator, - priv2.privkey.public_key.generator) - - def test_privkey_creation(self): - s = b("all the entropy in the entire world, compressed into one line") - - def not_much_entropy(numbytes): - return s[:numbytes] - - priv1 = SigningKey.generate() - self.assertEqual(priv1.baselen, NIST192p.baselen) - - priv1 = SigningKey.generate(curve=NIST224p) - self.assertEqual(priv1.baselen, NIST224p.baselen) - - priv1 = SigningKey.generate(entropy=not_much_entropy) - self.assertEqual(priv1.baselen, NIST192p.baselen) - priv2 = SigningKey.generate(entropy=not_much_entropy) - self.assertEqual(priv2.baselen, NIST192p.baselen) - self.assertTruePrivkeysEqual(priv1, priv2) - - priv1 = SigningKey.from_secret_exponent(secexp=3) - self.assertEqual(priv1.baselen, NIST192p.baselen) - priv2 = SigningKey.from_secret_exponent(secexp=3) - self.assertTruePrivkeysEqual(priv1, priv2) - - priv1 = SigningKey.from_secret_exponent(secexp=4, curve=NIST224p) - self.assertEqual(priv1.baselen, NIST224p.baselen) - - def test_privkey_strings(self): - priv1 = SigningKey.generate() - s1 = priv1.to_string() - self.assertEqual(type(s1), binary_type) - self.assertEqual(len(s1), NIST192p.baselen) - priv2 = SigningKey.from_string(s1) - self.assertTruePrivkeysEqual(priv1, priv2) - - s1 = priv1.to_pem() - self.assertEqual(type(s1), binary_type) - self.assertTrue(s1.startswith(b("-----BEGIN EC PRIVATE KEY-----"))) - self.assertTrue(s1.strip().endswith(b("-----END EC PRIVATE KEY-----"))) - priv2 = SigningKey.from_pem(s1) - self.assertTruePrivkeysEqual(priv1, priv2) - - s1 = priv1.to_der() - self.assertEqual(type(s1), binary_type) - priv2 = SigningKey.from_der(s1) - self.assertTruePrivkeysEqual(priv1, priv2) - - priv1 = SigningKey.generate(curve=NIST256p) - s1 = priv1.to_pem() - self.assertEqual(type(s1), binary_type) - self.assertTrue(s1.startswith(b("-----BEGIN EC PRIVATE KEY-----"))) - self.assertTrue(s1.strip().endswith(b("-----END EC PRIVATE KEY-----"))) - priv2 = SigningKey.from_pem(s1) - self.assertTruePrivkeysEqual(priv1, priv2) - - s1 = priv1.to_der() - self.assertEqual(type(s1), binary_type) - priv2 = SigningKey.from_der(s1) - self.assertTruePrivkeysEqual(priv1, priv2) - - def test_privkey_strings_brainpool(self): - priv1 = SigningKey.generate(curve=BRAINPOOLP512r1) - s1 = priv1.to_pem() - self.assertEqual(type(s1), binary_type) - self.assertTrue(s1.startswith(b("-----BEGIN EC PRIVATE KEY-----"))) - self.assertTrue(s1.strip().endswith(b("-----END EC PRIVATE KEY-----"))) - priv2 = SigningKey.from_pem(s1) - self.assertTruePrivkeysEqual(priv1, priv2) - - s1 = priv1.to_der() - self.assertEqual(type(s1), binary_type) - priv2 = SigningKey.from_der(s1) - self.assertTruePrivkeysEqual(priv1, priv2) - - def assertTruePubkeysEqual(self, pub1, pub2): - self.assertEqual(pub1.pubkey.point, pub2.pubkey.point) - self.assertEqual(pub1.pubkey.generator, pub2.pubkey.generator) - self.assertEqual(pub1.curve, pub2.curve) - - def test_pubkey_strings(self): - priv1 = SigningKey.generate() - pub1 = priv1.get_verifying_key() - s1 = pub1.to_string() - self.assertEqual(type(s1), binary_type) - self.assertEqual(len(s1), NIST192p.verifying_key_length) - pub2 = VerifyingKey.from_string(s1) - self.assertTruePubkeysEqual(pub1, pub2) - - priv1 = SigningKey.generate(curve=NIST256p) - pub1 = priv1.get_verifying_key() - s1 = pub1.to_string() - self.assertEqual(type(s1), binary_type) - self.assertEqual(len(s1), NIST256p.verifying_key_length) - pub2 = VerifyingKey.from_string(s1, curve=NIST256p) - self.assertTruePubkeysEqual(pub1, pub2) - - pub1_der = pub1.to_der() - self.assertEqual(type(pub1_der), binary_type) - pub2 = VerifyingKey.from_der(pub1_der) - self.assertTruePubkeysEqual(pub1, pub2) - - self.assertRaises(der.UnexpectedDER, - VerifyingKey.from_der, pub1_der + b("junk")) - badpub = VerifyingKey.from_der(pub1_der) - - class FakeGenerator: - def order(self): - return 123456789 - - badcurve = Curve("unknown", None, FakeGenerator(), (1, 2, 3, 4, 5, 6), None) - badpub.curve = badcurve - badder = badpub.to_der() - self.assertRaises(UnknownCurveError, VerifyingKey.from_der, badder) - - pem = pub1.to_pem() - self.assertEqual(type(pem), binary_type) - self.assertTrue(pem.startswith(b("-----BEGIN PUBLIC KEY-----")), pem) - self.assertTrue(pem.strip().endswith(b("-----END PUBLIC KEY-----")), pem) - pub2 = VerifyingKey.from_pem(pem) - self.assertTruePubkeysEqual(pub1, pub2) - - def test_pubkey_strings_brainpool(self): - priv1 = SigningKey.generate(curve=BRAINPOOLP512r1) - pub1 = priv1.get_verifying_key() - s1 = pub1.to_string() - self.assertEqual(type(s1), binary_type) - self.assertEqual(len(s1), BRAINPOOLP512r1.verifying_key_length) - pub2 = VerifyingKey.from_string(s1, curve=BRAINPOOLP512r1) - self.assertTruePubkeysEqual(pub1, pub2) - - pub1_der = pub1.to_der() - self.assertEqual(type(pub1_der), binary_type) - pub2 = VerifyingKey.from_der(pub1_der) - self.assertTruePubkeysEqual(pub1, pub2) - - def test_vk_to_der_with_invalid_point_encoding(self): - sk = SigningKey.generate() - vk = sk.verifying_key - - with self.assertRaises(ValueError): - vk.to_der("raw") - - def test_sk_to_der_with_invalid_point_encoding(self): - sk = SigningKey.generate() - - with self.assertRaises(ValueError): - sk.to_der("raw") - - def test_vk_from_der_garbage_after_curve_oid(self): - type_oid_der = encoded_oid_ecPublicKey - curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) + \ - b('garbage') - enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der) - point_der = der.encode_bitstring(b'\x00\xff', None) - to_decode = der.encode_sequence(enc_type_der, point_der) - - with self.assertRaises(der.UnexpectedDER): - VerifyingKey.from_der(to_decode) - - def test_vk_from_der_invalid_key_type(self): - type_oid_der = der.encode_oid(*(1, 2, 3)) - curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) - enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der) - point_der = der.encode_bitstring(b'\x00\xff', None) - to_decode = der.encode_sequence(enc_type_der, point_der) - - with self.assertRaises(der.UnexpectedDER): - VerifyingKey.from_der(to_decode) - - def test_vk_from_der_garbage_after_point_string(self): - type_oid_der = encoded_oid_ecPublicKey - curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) - enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der) - point_der = der.encode_bitstring(b'\x00\xff', None) + b('garbage') - to_decode = der.encode_sequence(enc_type_der, point_der) - - with self.assertRaises(der.UnexpectedDER): - VerifyingKey.from_der(to_decode) - - def test_vk_from_der_invalid_bitstring(self): - type_oid_der = encoded_oid_ecPublicKey - curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) - enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der) - point_der = der.encode_bitstring(b'\x08\xff', None) - to_decode = der.encode_sequence(enc_type_der, point_der) - - with self.assertRaises(der.UnexpectedDER): - VerifyingKey.from_der(to_decode) - - def test_vk_from_der_with_invalid_length_of_encoding(self): - type_oid_der = encoded_oid_ecPublicKey - curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) - enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der) - point_der = der.encode_bitstring(b'\xff'*64, 0) - to_decode = der.encode_sequence(enc_type_der, point_der) - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_der(to_decode) - - def test_vk_from_der_with_raw_encoding(self): - type_oid_der = encoded_oid_ecPublicKey - curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) - enc_type_der = der.encode_sequence(type_oid_der, curve_oid_der) - point_der = der.encode_bitstring(b'\xff'*48, 0) - to_decode = der.encode_sequence(enc_type_der, point_der) - - with self.assertRaises(der.UnexpectedDER): - VerifyingKey.from_der(to_decode) - - def test_signature_strings(self): - priv1 = SigningKey.generate() - pub1 = priv1.get_verifying_key() - data = b("data") - - sig = priv1.sign(data) - self.assertEqual(type(sig), binary_type) - self.assertEqual(len(sig), NIST192p.signature_length) - self.assertTrue(pub1.verify(sig, data)) - - sig = priv1.sign(data, sigencode=sigencode_strings) - self.assertEqual(type(sig), tuple) - self.assertEqual(len(sig), 2) - self.assertEqual(type(sig[0]), binary_type) - self.assertEqual(type(sig[1]), binary_type) - self.assertEqual(len(sig[0]), NIST192p.baselen) - self.assertEqual(len(sig[1]), NIST192p.baselen) - self.assertTrue(pub1.verify(sig, data, sigdecode=sigdecode_strings)) - - sig_der = priv1.sign(data, sigencode=sigencode_der) - self.assertEqual(type(sig_der), binary_type) - self.assertTrue(pub1.verify(sig_der, data, sigdecode=sigdecode_der)) - - def test_sig_decode_strings_with_invalid_count(self): - with self.assertRaises(MalformedSignature): - sigdecode_strings([b('one'), b('two'), b('three')], 0xff) - - def test_sig_decode_strings_with_wrong_r_len(self): - with self.assertRaises(MalformedSignature): - sigdecode_strings([b('one'), b('two')], 0xff) - - def test_sig_decode_strings_with_wrong_s_len(self): - with self.assertRaises(MalformedSignature): - sigdecode_strings([b('\xa0'), b('\xb0\xff')], 0xff) - - def test_verify_with_too_long_input(self): - sk = SigningKey.generate() - vk = sk.verifying_key - - with self.assertRaises(BadDigestError): - vk.verify_digest(None, b('\x00') * 128) - - def test_sk_from_secret_exponent_with_wrong_sec_exponent(self): - with self.assertRaises(MalformedPointError): - SigningKey.from_secret_exponent(0) - - def test_sk_from_string_with_wrong_len_string(self): - with self.assertRaises(MalformedPointError): - SigningKey.from_string(b('\x01')) - - def test_sk_from_der_with_junk_after_sequence(self): - ver_der = der.encode_integer(1) - to_decode = der.encode_sequence(ver_der) + b('garbage') - - with self.assertRaises(der.UnexpectedDER): - SigningKey.from_der(to_decode) - - def test_sk_from_der_with_wrong_version(self): - ver_der = der.encode_integer(0) - to_decode = der.encode_sequence(ver_der) - - with self.assertRaises(der.UnexpectedDER): - SigningKey.from_der(to_decode) - - def test_sk_from_der_invalid_const_tag(self): - ver_der = der.encode_integer(1) - privkey_der = der.encode_octet_string(b('\x00\xff')) - curve_oid_der = der.encode_oid(*(1, 2, 3)) - const_der = der.encode_constructed(1, curve_oid_der) - to_decode = der.encode_sequence(ver_der, privkey_der, const_der, - curve_oid_der) - - with self.assertRaises(der.UnexpectedDER): - SigningKey.from_der(to_decode) - - def test_sk_from_der_garbage_after_privkey_oid(self): - ver_der = der.encode_integer(1) - privkey_der = der.encode_octet_string(b('\x00\xff')) - curve_oid_der = der.encode_oid(*(1, 2, 3)) + b('garbage') - const_der = der.encode_constructed(0, curve_oid_der) - to_decode = der.encode_sequence(ver_der, privkey_der, const_der, - curve_oid_der) - - with self.assertRaises(der.UnexpectedDER): - SigningKey.from_der(to_decode) - - def test_sk_from_der_with_short_privkey(self): - ver_der = der.encode_integer(1) - privkey_der = der.encode_octet_string(b('\x00\xff')) - curve_oid_der = der.encode_oid(*(1, 2, 840, 10045, 3, 1, 1)) - const_der = der.encode_constructed(0, curve_oid_der) - to_decode = der.encode_sequence(ver_der, privkey_der, const_der, - curve_oid_der) - - sk = SigningKey.from_der(to_decode) - self.assertEqual(sk.privkey.secret_multiplier, 255) - - def test_sign_with_too_long_hash(self): - sk = SigningKey.from_secret_exponent(12) - - with self.assertRaises(BadDigestError): - sk.sign_digest(b('\xff') * 64) - - def test_hashfunc(self): - sk = SigningKey.generate(curve=NIST256p, hashfunc=sha256) - data = b("security level is 128 bits") - sig = sk.sign(data) - vk = VerifyingKey.from_string(sk.get_verifying_key().to_string(), - curve=NIST256p, hashfunc=sha256) - self.assertTrue(vk.verify(sig, data)) - - sk2 = SigningKey.generate(curve=NIST256p) - sig2 = sk2.sign(data, hashfunc=sha256) - vk2 = VerifyingKey.from_string(sk2.get_verifying_key().to_string(), - curve=NIST256p, hashfunc=sha256) - self.assertTrue(vk2.verify(sig2, data)) - - vk3 = VerifyingKey.from_string(sk.get_verifying_key().to_string(), - curve=NIST256p) - self.assertTrue(vk3.verify(sig, data, hashfunc=sha256)) - - def test_public_key_recovery(self): - # Create keys - curve = NIST256p - - sk = SigningKey.generate(curve=curve) - vk = sk.get_verifying_key() - - # Sign a message - data = b("blahblah") - signature = sk.sign(data) - - # Recover verifying keys - recovered_vks = VerifyingKey.from_public_key_recovery(signature, data, curve) - - # Test if each pk is valid - for recovered_vk in recovered_vks: - # Test if recovered vk is valid for the data - self.assertTrue(recovered_vk.verify(signature, data)) - - # Test if properties are equal - self.assertEqual(vk.curve, recovered_vk.curve) - self.assertEqual(vk.default_hashfunc, recovered_vk.default_hashfunc) - - # Test if original vk is the list of recovered keys - self.assertTrue( - vk.pubkey.point in [recovered_vk.pubkey.point for recovered_vk in recovered_vks]) - - def test_public_key_recovery_with_custom_hash(self): - # Create keys - curve = NIST256p - - sk = SigningKey.generate(curve=curve, hashfunc=sha256) - vk = sk.get_verifying_key() - - # Sign a message - data = b("blahblah") - signature = sk.sign(data) - - # Recover verifying keys - recovered_vks = VerifyingKey.\ - from_public_key_recovery(signature, data, curve, - hashfunc=sha256) - - # Test if each pk is valid - for recovered_vk in recovered_vks: - # Test if recovered vk is valid for the data - self.assertTrue(recovered_vk.verify(signature, data)) - - # Test if properties are equal - self.assertEqual(vk.curve, recovered_vk.curve) - self.assertEqual(sha256, recovered_vk.default_hashfunc) - - # Test if original vk is the list of recovered keys - self.assertTrue(vk.pubkey.point in - [recovered_vk.pubkey.point for recovered_vk in recovered_vks]) - - def test_encoding(self): - sk = SigningKey.from_secret_exponent(123456789) - vk = sk.verifying_key - - exp = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3' - '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4' - 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*') - self.assertEqual(vk.to_string(), exp) - self.assertEqual(vk.to_string('raw'), exp) - self.assertEqual(vk.to_string('uncompressed'), b('\x04') + exp) - self.assertEqual(vk.to_string('compressed'), b('\x02') + exp[:24]) - self.assertEqual(vk.to_string('hybrid'), b('\x06') + exp) - - def test_decoding(self): - sk = SigningKey.from_secret_exponent(123456789) - vk = sk.verifying_key - - enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3' - '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4' - 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*') - - from_raw = VerifyingKey.from_string(enc) - self.assertEqual(from_raw.pubkey.point, vk.pubkey.point) - - from_uncompressed = VerifyingKey.from_string(b('\x04') + enc) - self.assertEqual(from_uncompressed.pubkey.point, vk.pubkey.point) - - from_compressed = VerifyingKey.from_string(b('\x02') + enc[:24]) - self.assertEqual(from_compressed.pubkey.point, vk.pubkey.point) - - from_uncompressed = VerifyingKey.from_string(b('\x06') + enc) - self.assertEqual(from_uncompressed.pubkey.point, vk.pubkey.point) - - def test_decoding_with_malformed_uncompressed(self): - enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3' - '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4' - 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*') - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(b('\x02') + enc) - - def test_decoding_with_malformed_compressed(self): - enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3' - '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4' - 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*') - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(b('\x01') + enc[:24]) - - def test_decoding_with_inconsistent_hybrid(self): - enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3' - '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4' - 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*') - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(b('\x07') + enc) - - def test_decoding_with_point_not_on_curve(self): - enc = b('\x0c\xe0\x1d\xe0d\x1c\x8eS\x8a\xc0\x9eK\xa8x !\xd5\xc2\xc3' - '\xfd\xc8\xa0c\xff\xfb\x02\xb9\xc4\x84)\x1a\x0f\x8b\x87\xa4' - 'z\x8a#\xb5\x97\xecO\xb6\xa0HQ\x89*') - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(enc[:47] + b('\x00')) - - def test_decoding_with_point_at_infinity(self): - # decoding it is unsupported, as it's not necessary to encode it - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(b('\x00')) - - def test_not_lying_on_curve(self): - enc = number_to_string(NIST192p.curve.p(), NIST192p.curve.p()+1) - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(b('\x02') + enc) - - def test_from_string_with_invalid_curve_too_short_ver_key_len(self): - # both verifying_key_length and baselen are calculated internally - # by the Curve constructor, but since we depend on them verify - # that inconsistent values are detected - curve = Curve("test", ecdsa.curve_192, ecdsa.generator_192, (1, 2)) - curve.verifying_key_length = 16 - curve.baselen = 32 - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(b('\x00')*16, curve) - - def test_from_string_with_invalid_curve_too_long_ver_key_len(self): - # both verifying_key_length and baselen are calculated internally - # by the Curve constructor, but since we depend on them verify - # that inconsistent values are detected - curve = Curve("test", ecdsa.curve_192, ecdsa.generator_192, (1, 2)) - curve.verifying_key_length = 16 - curve.baselen = 16 - - with self.assertRaises(MalformedPointError): - VerifyingKey.from_string(b('\x00')*16, curve) - - -@pytest.mark.parametrize("val,even", - [(i, j) for i in range(256) for j in [True, False]]) -def test_VerifyingKey_decode_with_small_values(val, even): - enc = number_to_string(val, NIST192p.order) - - if even: - enc = b('\x02') + enc - else: - enc = b('\x03') + enc - - # small values can both be actual valid public keys and not, verify that - # only expected exceptions are raised if they are not - try: - vk = VerifyingKey.from_string(enc) - assert isinstance(vk, VerifyingKey) - except MalformedPointError: - assert True - - -params = [] -for curve in curves: - for enc in ["raw", "uncompressed", "compressed", "hybrid"]: - params.append(pytest.param(curve, enc, id="{0}-{1}".format( - curve.name, enc))) - - -@pytest.mark.parametrize("curve,encoding", params) -def test_VerifyingKey_encode_decode(curve, encoding): - sk = SigningKey.generate(curve=curve) - vk = sk.verifying_key - - encoded = vk.to_string(encoding) - - from_enc = VerifyingKey.from_string(encoded, curve=curve) - - assert vk.pubkey.point == from_enc.pubkey.point - - -class OpenSSL(unittest.TestCase): - # test interoperability with OpenSSL tools. Note that openssl's ECDSA - # sign/verify arguments changed between 0.9.8 and 1.0.0: the early - # versions require "-ecdsa-with-SHA1", the later versions want just - # "-SHA1" (or to leave out that argument entirely, which means the - # signature will use some default digest algorithm, probably determined - # by the key, probably always SHA1). - # - # openssl ecparam -name secp224r1 -genkey -out privkey.pem - # openssl ec -in privkey.pem -text -noout # get the priv/pub keys - # openssl dgst -ecdsa-with-SHA1 -sign privkey.pem -out data.sig data.txt - # openssl asn1parse -in data.sig -inform DER - # data.sig is 64 bytes, probably 56b plus ASN1 overhead - # openssl dgst -ecdsa-with-SHA1 -prverify privkey.pem -signature data.sig data.txt ; echo $? - # openssl ec -in privkey.pem -pubout -out pubkey.pem - # openssl ec -in privkey.pem -pubout -outform DER -out pubkey.der - - OPENSSL_SUPPORTED_CURVES = set(c.split(':')[0].strip() for c in - run_openssl("ecparam -list_curves") - .split('\n')) - - def get_openssl_messagedigest_arg(self, hash_name): - v = run_openssl("version") - # e.g. "OpenSSL 1.0.0 29 Mar 2010", or "OpenSSL 1.0.0a 1 Jun 2010", - # or "OpenSSL 0.9.8o 01 Jun 2010" - vs = v.split()[1].split(".") - if vs >= ["1", "0", "0"]: # pragma: no cover - return "-{0}".format(hash_name) - else: # pragma: no cover - return "-ecdsa-with-{0}".format(hash_name) - - # sk: 1:OpenSSL->python 2:python->OpenSSL - # vk: 3:OpenSSL->python 4:python->OpenSSL - # sig: 5:OpenSSL->python 6:python->OpenSSL - - @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime192v1") - def test_from_openssl_nist192p(self): - return self.do_test_from_openssl(NIST192p) - - @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime192v1") - def test_from_openssl_nist192p_sha256(self): - return self.do_test_from_openssl(NIST192p, "SHA256") - - @pytest.mark.skipif("secp224r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support secp224r1") - def test_from_openssl_nist224p(self): - return self.do_test_from_openssl(NIST224p) - - @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime256v1") - def test_from_openssl_nist256p(self): - return self.do_test_from_openssl(NIST256p) - - @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime256v1") - def test_from_openssl_nist256p_sha384(self): - return self.do_test_from_openssl(NIST256p, "SHA384") - - @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime256v1") - def test_from_openssl_nist256p_sha512(self): - return self.do_test_from_openssl(NIST256p, "SHA512") - - @pytest.mark.skipif("secp384r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support secp384r1") - def test_from_openssl_nist384p(self): - return self.do_test_from_openssl(NIST384p) - - @pytest.mark.skipif("secp521r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support secp521r1") - def test_from_openssl_nist521p(self): - return self.do_test_from_openssl(NIST521p) - - @pytest.mark.skipif("secp256k1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support secp256k1") - def test_from_openssl_secp256k1(self): - return self.do_test_from_openssl(SECP256k1) - - @pytest.mark.skipif("brainpoolP160r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support brainpoolP160r1") - def test_from_openssl_brainpoolp160r1(self): - return self.do_test_from_openssl(BRAINPOOLP160r1) - - @pytest.mark.skipif("brainpoolP192r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support brainpoolP192r1") - def test_from_openssl_brainpoolp192r1(self): - return self.do_test_from_openssl(BRAINPOOLP192r1) - - @pytest.mark.skipif("brainpoolP224r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support brainpoolP224r1") - def test_from_openssl_brainpoolp224r1(self): - return self.do_test_from_openssl(BRAINPOOLP224r1) - - @pytest.mark.skipif("brainpoolP256r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support brainpoolP256r1") - def test_from_openssl_brainpoolp256r1(self): - return self.do_test_from_openssl(BRAINPOOLP256r1) - - @pytest.mark.skipif("brainpoolP320r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support brainpoolP320r1") - def test_from_openssl_brainpoolp320r1(self): - return self.do_test_from_openssl(BRAINPOOLP320r1) - - @pytest.mark.skipif("brainpoolP384r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support brainpoolP384r1") - def test_from_openssl_brainpoolp384r1(self): - return self.do_test_from_openssl(BRAINPOOLP384r1) - - @pytest.mark.skipif("brainpoolP512r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support brainpoolP512r1") - def test_from_openssl_brainpoolp512r1(self): - return self.do_test_from_openssl(BRAINPOOLP512r1) - - def do_test_from_openssl(self, curve, hash_name="SHA1"): - curvename = curve.openssl_name - assert curvename - # OpenSSL: create sk, vk, sign. - # Python: read vk(3), checksig(5), read sk(1), sign, check - mdarg = self.get_openssl_messagedigest_arg(hash_name) - if os.path.isdir("t"): # pragma: no cover - shutil.rmtree("t") - os.mkdir("t") - run_openssl("ecparam -name %s -genkey -out t/privkey.pem" % curvename) - run_openssl("ec -in t/privkey.pem -pubout -out t/pubkey.pem") - data = b("data") - with open("t/data.txt", "wb") as e: - e.write(data) - run_openssl("dgst %s -sign t/privkey.pem -out t/data.sig t/data.txt" % mdarg) - run_openssl("dgst %s -verify t/pubkey.pem -signature t/data.sig t/data.txt" % mdarg) - with open("t/pubkey.pem", "rb") as e: - pubkey_pem = e.read() - vk = VerifyingKey.from_pem(pubkey_pem) # 3 - with open("t/data.sig", "rb") as e: - sig_der = e.read() - self.assertTrue(vk.verify(sig_der, data, # 5 - hashfunc=partial(hashlib.new, hash_name), - sigdecode=sigdecode_der)) - - with open("t/privkey.pem") as e: - fp = e.read() - sk = SigningKey.from_pem(fp) # 1 - sig = sk.sign( - data, - hashfunc=partial(hashlib.new, hash_name), - ) - self.assertTrue(vk.verify(sig, - data, - hashfunc=partial(hashlib.new, hash_name))) - - @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime192v1") - def test_to_openssl_nist192p(self): - self.do_test_to_openssl(NIST192p) - - @pytest.mark.skipif("prime192v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime192v1") - def test_to_openssl_nist192p_sha256(self): - self.do_test_to_openssl(NIST192p, "SHA256") - - @pytest.mark.skipif("secp224r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support secp224r1") - def test_to_openssl_nist224p(self): - self.do_test_to_openssl(NIST224p) - - @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime256v1") - def test_to_openssl_nist256p(self): - self.do_test_to_openssl(NIST256p) - - @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime256v1") - def test_to_openssl_nist256p_sha384(self): - self.do_test_to_openssl(NIST256p, "SHA384") - - @pytest.mark.skipif("prime256v1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support prime256v1") - def test_to_openssl_nist256p_sha512(self): - self.do_test_to_openssl(NIST256p, "SHA512") - - @pytest.mark.skipif("secp384r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support secp384r1") - def test_to_openssl_nist384p(self): - self.do_test_to_openssl(NIST384p) - - @pytest.mark.skipif("secp521r1" not in OPENSSL_SUPPORTED_CURVES, - reason="system openssl does not support secp521r1") - def test_to_openssl_nist521p(self): - self.do_test_to_openssl(NIST521p) |