aboutsummaryrefslogtreecommitdiff
path: root/freezed_deps/ecdsa/test_pyecdsa.py
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2020-11-17 18:47:40 -0500
committerDeterminant <tederminant@gmail.com>2020-11-17 18:47:40 -0500
commit3bef51eec2299403467e621ae660cef3f9256ac8 (patch)
tree9b72aaa95fb6dffacd8b20164699870a32ab6825 /freezed_deps/ecdsa/test_pyecdsa.py
parent92b8b8e9628cac41d37226416107adc76b10e01b (diff)
update frozen deps
Diffstat (limited to 'freezed_deps/ecdsa/test_pyecdsa.py')
-rw-r--r--freezed_deps/ecdsa/test_pyecdsa.py1445
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_