import binascii
import functools
import hmac
import hashlib
import random
import test.support.hashlib_helper as hashlib_helper
import types
import unittest
import unittest.mock as mock
import warnings
from _operator import _compare_digest as operator_compare_digest
from test.support import check_disallow_instantiation
from test.support.import_helper import import_fresh_module, import_module

try:
    import _hashlib
    from _hashlib import compare_digest as openssl_compare_digest
except ImportError:
    _hashlib = None
    openssl_compare_digest = None

try:
    import _sha2 as sha2
except ImportError:
    sha2 = None


def requires_builtin_sha2():
    return unittest.skipIf(sha2 is None, "requires _sha2")


class ModuleMixin:
    """Mixin with a HMAC module implementation."""

    hmac = None


class PyModuleMixin(ModuleMixin):
    """Pure Python implementation of HMAC.

    The underlying hash functions may be OpenSSL-based or HACL* based,
    depending on whether OpenSSL is present or not.
    """

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.hmac = import_fresh_module('hmac', blocked=['_hashlib', '_hmac'])


@hashlib_helper.requires_builtin_hmac()
class BuiltinModuleMixin(ModuleMixin):
    """Built-in HACL* implementation of HMAC."""

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.hmac = import_fresh_module('_hmac')


# Sentinel object used to detect whether a digestmod is given or not.
DIGESTMOD_SENTINEL = object()


class CreatorMixin:
    """Mixin exposing a method creating a HMAC object."""

    def hmac_new(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        """Create a new HMAC object.

        Implementations should accept arbitrary 'digestmod' as this
        method can be used to test which exceptions are being raised.
        """
        raise NotImplementedError

    def bind_hmac_new(self, digestmod):
        """Return a specialization of hmac_new() with a bound digestmod."""
        return functools.partial(self.hmac_new, digestmod=digestmod)


class DigestMixin:
    """Mixin exposing a method computing a HMAC digest."""

    def hmac_digest(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        """Compute a HMAC digest.

        Implementations should accept arbitrary 'digestmod' as this
        method can be used to test which exceptions are being raised.
        """
        raise NotImplementedError

    def bind_hmac_digest(self, digestmod):
        """Return a specialization of hmac_digest() with a bound digestmod."""
        return functools.partial(self.hmac_digest, digestmod=digestmod)


def _call_newobj_func(new_func, key, msg, digestmod):
    if digestmod is DIGESTMOD_SENTINEL:  # to test when digestmod is missing
        return new_func(key, msg)  # expected to raise
    # functions creating HMAC objects take a 'digestmod' keyword argument
    return new_func(key, msg, digestmod=digestmod)


def _call_digest_func(digest_func, key, msg, digestmod):
    if digestmod is DIGESTMOD_SENTINEL:  # to test when digestmod is missing
        return digest_func(key, msg)  # expected to raise
    # functions directly computing digests take a 'digest' keyword argument
    return digest_func(key, msg, digest=digestmod)


class ThroughObjectMixin(ModuleMixin, CreatorMixin, DigestMixin):
    """Mixin delegating to <module>.HMAC() and <module>.HMAC(...).digest().

    Both the C implementation and the Python implementation of HMAC should
    expose a HMAC class with the same functionalities.
    """

    def hmac_new(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        """Create a HMAC object via a module-level class constructor."""
        return _call_newobj_func(self.hmac.HMAC, key, msg, digestmod)

    def hmac_digest(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        """Call the digest() method on a HMAC object obtained by hmac_new()."""
        return _call_newobj_func(self.hmac_new, key, msg, digestmod).digest()


class ThroughModuleAPIMixin(ModuleMixin, CreatorMixin, DigestMixin):
    """Mixin delegating to <module>.new() and <module>.digest()."""

    def hmac_new(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        """Create a HMAC object via a module-level function."""
        return _call_newobj_func(self.hmac.new, key, msg, digestmod)

    def hmac_digest(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        """One-shot HMAC digest computation."""
        return _call_digest_func(self.hmac.digest, key, msg, digestmod)


@hashlib_helper.requires_hashlib()
class ThroughOpenSSLAPIMixin(CreatorMixin, DigestMixin):
    """Mixin delegating to _hashlib.hmac_new() and _hashlib.hmac_digest()."""

    def hmac_new(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        return _call_newobj_func(_hashlib.hmac_new, key, msg, digestmod)

    def hmac_digest(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        return _call_digest_func(_hashlib.hmac_digest, key, msg, digestmod)


class ThroughBuiltinAPIMixin(BuiltinModuleMixin, CreatorMixin, DigestMixin):
    """Mixin delegating to _hmac.new() and _hmac.compute_digest()."""

    def hmac_new(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        return _call_newobj_func(self.hmac.new, key, msg, digestmod)

    def hmac_digest(self, key, msg=None, digestmod=DIGESTMOD_SENTINEL):
        return _call_digest_func(self.hmac.compute_digest, key, msg, digestmod)


class ObjectCheckerMixin:
    """Mixin for checking HMAC objects (pure Python, OpenSSL or built-in)."""

    def check_object(self, h, hexdigest, hashname, digest_size, block_size):
        """Check a HMAC object 'h' against the given values."""
        self.check_internals(h, hashname, digest_size, block_size)
        self.check_hexdigest(h, hexdigest, digest_size)

    def check_internals(self, h, hashname, digest_size, block_size):
        """Check the constant attributes of a HMAC object."""
        self.assertEqual(h.name, f"hmac-{hashname}")
        self.assertEqual(h.digest_size, digest_size)
        self.assertEqual(h.block_size, block_size)

    def check_hexdigest(self, h, hexdigest, digest_size):
        """Check the HMAC digest of 'h' and its size."""
        self.assertEqual(len(h.digest()), digest_size)
        self.assertEqual(h.digest(), binascii.unhexlify(hexdigest))
        self.assertEqual(h.hexdigest().upper(), hexdigest.upper())


class AssertersMixin(CreatorMixin, DigestMixin, ObjectCheckerMixin):
    """Mixin class for common tests."""

    def hmac_new_by_name(self, key, msg=None, *, hashname):
        """Alternative implementation of hmac_new().

        This is typically useful when one needs to test against an HMAC
        implementation which only recognizes underlying hash functions
        by their name (all HMAC implementations must at least recognize
        hash functions by their names but some may use aliases such as
        `hashlib.sha1` instead of "sha1").

        Unlike hmac_new(), this method may assert the type of 'hashname'
        as it should only be used in tests that are expected to create
        a HMAC object.
        """
        self.assertIsInstance(hashname, str)
        return self.hmac_new(key, msg, digestmod=hashname)

    def hmac_digest_by_name(self, key, msg=None, *, hashname):
        """Alternative implementation of hmac_digest().

        Unlike hmac_digest(), this method may assert the type of 'hashname'
        as it should only be used in tests that are expected to compute a
        HMAC digest.
        """
        self.assertIsInstance(hashname, str)
        return self.hmac_digest(key, msg, digestmod=hashname)

    def assert_hmac(
        self, key, msg, hexdigest, hashfunc, hashname, digest_size, block_size
    ):
        """Check that HMAC(key, msg) == digest.

        The 'hashfunc' and 'hashname' are used as 'digestmod' values,
        thereby allowing to test the underlying dispatching mechanism.

        Note that 'hashfunc' may be a string, a callable, or a PEP-257
        module. Note that not all HMAC implementations may recognize the
        same set of types for 'hashfunc', but they should always accept
        a hash function by its name.
        """
        if hashfunc == hashname:
            choices = [hashname]
        else:
            choices = [hashfunc, hashname]

        for digestmod in choices:
            with self.subTest(digestmod=digestmod):
                self.assert_hmac_new(
                    key, msg, hexdigest, digestmod,
                    hashname, digest_size, block_size
                )
                self.assert_hmac_hexdigest(
                    key, msg, hexdigest, digestmod, digest_size
                )
                self.assert_hmac_common_cases(
                    key, msg, hexdigest, digestmod,
                    hashname, digest_size, block_size
                )
                self.assert_hmac_extra_cases(
                    key, msg, hexdigest, digestmod,
                    hashname, digest_size, block_size
                )

        self.assert_hmac_new_by_name(
            key, msg, hexdigest, hashname, digest_size, block_size
        )
        self.assert_hmac_hexdigest_by_name(
            key, msg, hexdigest, hashname, digest_size
        )

    def assert_hmac_new(
        self, key, msg, hexdigest, digestmod, hashname, digest_size, block_size
    ):
        """Check that HMAC(key, msg) == digest.

        This test uses the `hmac_new()` method to create HMAC objects.
        """
        self.check_hmac_new(
            key, msg, hexdigest, hashname, digest_size, block_size,
            hmac_new_func=self.hmac_new,
            hmac_new_kwds={'digestmod': digestmod},
        )

    def assert_hmac_new_by_name(
        self, key, msg, hexdigest, hashname, digest_size, block_size
    ):
        """Check that HMAC(key, msg) == digest.

        This test uses the `hmac_new_by_name()` method to create HMAC objects.
        """
        self.check_hmac_new(
            key, msg, hexdigest, hashname, digest_size, block_size,
            hmac_new_func=self.hmac_new_by_name,
            hmac_new_kwds={'hashname': hashname},
        )

    def check_hmac_new(
        self, key, msg, hexdigest, hashname, digest_size, block_size,
        hmac_new_func, hmac_new_kwds=types.MappingProxyType({}),
    ):
        """Check that HMAC(key, msg) == digest.

        This also tests that using an empty/None initial message and
        then calling `h.update(msg)` produces the same result, namely
        that HMAC(key, msg) is equivalent to HMAC(key).update(msg).
        """
        h = hmac_new_func(key, msg, **hmac_new_kwds)
        self.check_object(h, hexdigest, hashname, digest_size, block_size)

        def hmac_new_feed(*args):
            h = hmac_new_func(key, *args, **hmac_new_kwds)
            h.update(msg)
            self.check_hexdigest(h, hexdigest, digest_size)

        with self.subTest('no initial message'):
            hmac_new_feed()
        with self.subTest('initial message is empty'):
            hmac_new_feed(b'')
        with self.subTest('initial message is None'):
            hmac_new_feed(None)

    def assert_hmac_hexdigest(
        self, key, msg, hexdigest, digestmod, digest_size,
    ):
        """Check a HMAC digest computed by hmac_digest()."""
        self.check_hmac_hexdigest(
            key, msg, hexdigest, digest_size,
            hmac_digest_func=self.hmac_digest,
            hmac_digest_kwds={'digestmod': digestmod},
        )

    def assert_hmac_hexdigest_by_name(
        self, key, msg, hexdigest, hashname, digest_size
    ):
        """Check a HMAC digest computed by hmac_digest_by_name()."""
        self.assertIsInstance(hashname, str)
        self.check_hmac_hexdigest(
            key, msg, hexdigest, digest_size,
            hmac_digest_func=self.hmac_digest_by_name,
            hmac_digest_kwds={'hashname': hashname},
        )

    def check_hmac_hexdigest(
        self, key, msg, hexdigest, digest_size,
        hmac_digest_func, hmac_digest_kwds=types.MappingProxyType({}),
    ):
        """Check and return a HMAC digest computed by hmac_digest_func().

        This HMAC digest is computed by:

            hmac_digest_func(key, msg, **hmac_digest_kwds)

        This is typically useful for checking one-shot HMAC functions.
        """
        d = hmac_digest_func(key, msg, **hmac_digest_kwds)
        self.assertEqual(len(d), digest_size)
        self.assertEqual(d, binascii.unhexlify(hexdigest))
        return d

    def assert_hmac_common_cases(
        self, key, msg, hexdigest, digestmod, hashname, digest_size, block_size
    ):
        """Common tests executed by all subclasses."""
        h1 = self.hmac_new_by_name(key, hashname=hashname)
        h2 = h1.copy()
        h2.update(b"test update should not affect original")
        h1.update(msg)
        self.check_object(h1, hexdigest, hashname, digest_size, block_size)

    def assert_hmac_extra_cases(
        self, key, msg, hexdigest, digestmod, hashname, digest_size, block_size
    ):
        """Extra tests that can be added in subclasses."""


class PyAssertersMixin(PyModuleMixin, AssertersMixin):

    def assert_hmac_extra_cases(
        self, key, msg, hexdigest, digestmod, hashname, digest_size, block_size
    ):
        h = self.hmac.HMAC.__new__(self.hmac.HMAC)
        h._init_old(key, msg, digestmod=digestmod)
        self.check_object(h, hexdigest, hashname, digest_size, block_size)


class OpenSSLAssertersMixin(ThroughOpenSSLAPIMixin, AssertersMixin):

    def hmac_new_by_name(self, key, msg=None, *, hashname):
        self.assertIsInstance(hashname, str)
        openssl_func = getattr(_hashlib, f"openssl_{hashname}")
        return self.hmac_new(key, msg, digestmod=openssl_func)

    def hmac_digest_by_name(self, key, msg=None, *, hashname):
        self.assertIsInstance(hashname, str)
        openssl_func = getattr(_hashlib, f"openssl_{hashname}")
        return self.hmac_digest(key, msg, digestmod=openssl_func)


class BuiltinAssertersMixin(ThroughBuiltinAPIMixin, AssertersMixin):
    pass


class HashFunctionsTrait:
    """Trait class for 'hashfunc' in hmac_new() and hmac_digest()."""

    ALGORITHMS = [
        'md5', 'sha1',
        'sha224', 'sha256', 'sha384', 'sha512',
        'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
    ]

    # By default, a missing algorithm skips the test that uses it.
    _ = property(lambda self: self.skipTest("missing hash function"))
    md5 = sha1 = _
    sha224 = sha256 = sha384 = sha512 = _
    sha3_224 = sha3_256 = sha3_384 = sha3_512 = _
    del _


class WithOpenSSLHashFunctions(HashFunctionsTrait):
    """Test a HMAC implementation with an OpenSSL-based callable 'hashfunc'."""

    @classmethod
    def setUpClass(cls):
        super().setUpClass()

        for name in cls.ALGORITHMS:
            @property
            @hashlib_helper.requires_openssl_hashdigest(name)
            def func(self, *, __name=name):  # __name needed to bind 'name'
                return getattr(_hashlib, f'openssl_{__name}')
            setattr(cls, name, func)


class WithNamedHashFunctions(HashFunctionsTrait):
    """Test a HMAC implementation with a named 'hashfunc'."""

    @classmethod
    def setUpClass(cls):
        super().setUpClass()

        for name in cls.ALGORITHMS:
            setattr(cls, name, name)


class RFCTestCaseMixin(AssertersMixin, HashFunctionsTrait):
    """Test HMAC implementations against RFC 2202/4231 and NIST test vectors.

    - Test vectors for MD5 and SHA-1 are taken from RFC 2202.
    - Test vectors for SHA-2 are taken from RFC 4231.
    - Test vectors for SHA-3 are NIST's test vectors [1].

    [1] https://csrc.nist.gov/projects/message-authentication-codes
    """

    def test_md5_rfc2202(self):
        def md5test(key, msg, hexdigest):
            self.assert_hmac(key, msg, hexdigest, self.md5, "md5", 16, 64)

        md5test(b"\x0b" * 16,
                b"Hi There",
                "9294727a3638bb1c13f48ef8158bfc9d")

        md5test(b"Jefe",
                b"what do ya want for nothing?",
                "750c783e6ab0b503eaa86e310a5db738")

        md5test(b"\xaa" * 16,
                b"\xdd" * 50,
                "56be34521d144c88dbb8c733f0e8b3f6")

        md5test(bytes(range(1, 26)),
                b"\xcd" * 50,
                "697eaf0aca3a3aea3a75164746ffaa79")

        md5test(b"\x0C" * 16,
                b"Test With Truncation",
                "56461ef2342edc00f9bab995690efd4c")

        md5test(b"\xaa" * 80,
                b"Test Using Larger Than Block-Size Key - Hash Key First",
                "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd")

        md5test(b"\xaa" * 80,
                (b"Test Using Larger Than Block-Size Key "
                 b"and Larger Than One Block-Size Data"),
                "6f630fad67cda0ee1fb1f562db3aa53e")

    def test_sha1_rfc2202(self):
        def shatest(key, msg, hexdigest):
            self.assert_hmac(key, msg, hexdigest, self.sha1, "sha1", 20, 64)

        shatest(b"\x0b" * 20,
                b"Hi There",
                "b617318655057264e28bc0b6fb378c8ef146be00")

        shatest(b"Jefe",
                b"what do ya want for nothing?",
                "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79")

        shatest(b"\xAA" * 20,
                b"\xDD" * 50,
                "125d7342b9ac11cd91a39af48aa17b4f63f175d3")

        shatest(bytes(range(1, 26)),
                b"\xCD" * 50,
                "4c9007f4026250c6bc8414f9bf50c86c2d7235da")

        shatest(b"\x0C" * 20,
                b"Test With Truncation",
                "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04")

        shatest(b"\xAA" * 80,
                b"Test Using Larger Than Block-Size Key - Hash Key First",
                "aa4ae5e15272d00e95705637ce8a3b55ed402112")

        shatest(b"\xAA" * 80,
                (b"Test Using Larger Than Block-Size Key "
                 b"and Larger Than One Block-Size Data"),
                "e8e99d0f45237d786d6bbaa7965c7808bbff1a91")

    def test_sha2_224_rfc4231(self):
        self._test_sha2_rfc4231(self.sha224, 'sha224', 28, 64)

    def test_sha2_256_rfc4231(self):
        self._test_sha2_rfc4231(self.sha256, 'sha256', 32, 64)

    def test_sha2_384_rfc4231(self):
        self._test_sha2_rfc4231(self.sha384, 'sha384', 48, 128)

    def test_sha2_512_rfc4231(self):
        self._test_sha2_rfc4231(self.sha512, 'sha512', 64, 128)

    def _test_sha2_rfc4231(self, hashfunc, hashname, digest_size, block_size):
        def hmactest(key, msg, hexdigests):
            hexdigest = hexdigests[hashname]

            self.assert_hmac(
                key, msg, hexdigest,
                hashfunc=hashfunc,
                hashname=hashname,
                digest_size=digest_size,
                block_size=block_size
            )

        # 4.2.  Test Case 1
        hmactest(key=b'\x0b' * 20,
                 msg=b'Hi There',
                 hexdigests={
                     'sha224': '896fb1128abbdf196832107cd49df33f'
                               '47b4b1169912ba4f53684b22',
                     'sha256': 'b0344c61d8db38535ca8afceaf0bf12b'
                               '881dc200c9833da726e9376c2e32cff7',
                     'sha384': 'afd03944d84895626b0825f4ab46907f'
                               '15f9dadbe4101ec682aa034c7cebc59c'
                               'faea9ea9076ede7f4af152e8b2fa9cb6',
                     'sha512': '87aa7cdea5ef619d4ff0b4241a1d6cb0'
                               '2379f4e2ce4ec2787ad0b30545e17cde'
                               'daa833b7d6b8a702038b274eaea3f4e4'
                               'be9d914eeb61f1702e696c203a126854',
                 })

        # 4.3.  Test Case 2
        hmactest(key=b'Jefe',
                 msg=b'what do ya want for nothing?',
                 hexdigests={
                     'sha224': 'a30e01098bc6dbbf45690f3a7e9e6d0f'
                               '8bbea2a39e6148008fd05e44',
                     'sha256': '5bdcc146bf60754e6a042426089575c7'
                               '5a003f089d2739839dec58b964ec3843',
                     'sha384': 'af45d2e376484031617f78d2b58a6b1b'
                               '9c7ef464f5a01b47e42ec3736322445e'
                               '8e2240ca5e69e2c78b3239ecfab21649',
                     'sha512': '164b7a7bfcf819e2e395fbe73b56e0a3'
                               '87bd64222e831fd610270cd7ea250554'
                               '9758bf75c05a994a6d034f65f8f0e6fd'
                               'caeab1a34d4a6b4b636e070a38bce737',
                 })

        # 4.4.  Test Case 3
        hmactest(key=b'\xaa' * 20,
                 msg=b'\xdd' * 50,
                 hexdigests={
                     'sha224': '7fb3cb3588c6c1f6ffa9694d7d6ad264'
                               '9365b0c1f65d69d1ec8333ea',
                     'sha256': '773ea91e36800e46854db8ebd09181a7'
                               '2959098b3ef8c122d9635514ced565fe',
                     'sha384': '88062608d3e6ad8a0aa2ace014c8a86f'
                               '0aa635d947ac9febe83ef4e55966144b'
                               '2a5ab39dc13814b94e3ab6e101a34f27',
                     'sha512': 'fa73b0089d56a284efb0f0756c890be9'
                               'b1b5dbdd8ee81a3655f83e33b2279d39'
                               'bf3e848279a722c806b485a47e67c807'
                               'b946a337bee8942674278859e13292fb',
                 })

        # 4.5.  Test Case 4
        hmactest(key=bytes(x for x in range(0x01, 0x19 + 1)),
                 msg=b'\xcd' * 50,
                 hexdigests={
                     'sha224': '6c11506874013cac6a2abc1bb382627c'
                               'ec6a90d86efc012de7afec5a',
                     'sha256': '82558a389a443c0ea4cc819899f2083a'
                               '85f0faa3e578f8077a2e3ff46729665b',
                     'sha384': '3e8a69b7783c25851933ab6290af6ca7'
                               '7a9981480850009cc5577c6e1f573b4e'
                               '6801dd23c4a7d679ccf8a386c674cffb',
                     'sha512': 'b0ba465637458c6990e5a8c5f61d4af7'
                               'e576d97ff94b872de76f8050361ee3db'
                               'a91ca5c11aa25eb4d679275cc5788063'
                               'a5f19741120c4f2de2adebeb10a298dd',
                 })

        # 4.7.  Test Case 6
        hmactest(key=b'\xaa' * 131,
                 msg=b'Test Using Larger Than Block-Siz'
                     b'e Key - Hash Key First',
                 hexdigests={
                     'sha224': '95e9a0db962095adaebe9b2d6f0dbce2'
                               'd499f112f2d2b7273fa6870e',
                     'sha256': '60e431591ee0b67f0d8a26aacbf5b77f'
                               '8e0bc6213728c5140546040f0ee37f54',
                     'sha384': '4ece084485813e9088d2c63a041bc5b4'
                               '4f9ef1012a2b588f3cd11f05033ac4c6'
                               '0c2ef6ab4030fe8296248df163f44952',
                     'sha512': '80b24263c7c1a3ebb71493c1dd7be8b4'
                               '9b46d1f41b4aeec1121b013783f8f352'
                               '6b56d037e05f2598bd0fd2215d6a1e52'
                               '95e64f73f63f0aec8b915a985d786598',
                 })

        # 4.8.  Test Case 7
        hmactest(key=b'\xaa' * 131,
                 msg=b'This is a test using a larger th'
                     b'an block-size key and a larger t'
                     b'han block-size data. The key nee'
                     b'ds to be hashed before being use'
                     b'd by the HMAC algorithm.',
                 hexdigests={
                     'sha224': '3a854166ac5d9f023f54d517d0b39dbd'
                               '946770db9c2b95c9f6f565d1',
                     'sha256': '9b09ffa71b942fcb27635fbcd5b0e944'
                               'bfdc63644f0713938a7f51535c3a35e2',
                     'sha384': '6617178e941f020d351e2f254e8fd32c'
                               '602420feb0b8fb9adccebb82461e99c5'
                               'a678cc31e799176d3860e6110c46523e',
                     'sha512': 'e37b6a775dc87dbaa4dfa9f96e5e3ffd'
                               'debd71f8867289865df5a32d20cdc944'
                               'b6022cac3c4982b10d5eeb55c3e4de15'
                               '134676fb6de0446065c97440fa8c6a58',
                 })

    def test_sha3_224_nist(self):
        for key, msg, hexdigest in [
            (
                bytes(range(28)),
                b'Sample message for keylen<blocklen',
                '332cfd59347fdb8e576e77260be4aba2d6dc53117b3bfb52c6d18c04'
            ), (
                bytes(range(144)),
                b'Sample message for keylen=blocklen',
                'd8b733bcf66c644a12323d564e24dcf3fc75f231f3b67968359100c7'
            ), (
                bytes(range(172)),
                b'Sample message for keylen>blocklen',
                '078695eecc227c636ad31d063a15dd05a7e819a66ec6d8de1e193e59'
            )
        ]:
            self.assert_hmac(
                key, msg, hexdigest,
                hashfunc=self.sha3_224, hashname='sha3_224',
                digest_size=28, block_size=144
            )

    def test_sha3_256_nist(self):
        for key, msg, hexdigest in [
            (
                bytes(range(32)),
                b'Sample message for keylen<blocklen',
                '4fe8e202c4f058e8dddc23d8c34e4673'
                '43e23555e24fc2f025d598f558f67205'
            ), (
                bytes(range(136)),
                b'Sample message for keylen=blocklen',
                '68b94e2e538a9be4103bebb5aa016d47'
                '961d4d1aa906061313b557f8af2c3faa'
            ), (
                bytes(range(168)),
                b'Sample message for keylen>blocklen',
                '9bcf2c238e235c3ce88404e813bd2f3a'
                '97185ac6f238c63d6229a00b07974258'
            )
        ]:
            self.assert_hmac(
                key, msg, hexdigest,
                hashfunc=self.sha3_256, hashname='sha3_256',
                digest_size=32, block_size=136
            )

    def test_sha3_384_nist(self):
        for key, msg, hexdigest in [
            (
                bytes(range(48)),
                b'Sample message for keylen<blocklen',
                'd588a3c51f3f2d906e8298c1199aa8ff'
                '6296218127f6b38a90b6afe2c5617725'
                'bc99987f79b22a557b6520db710b7f42'
            ), (
                bytes(range(104)),
                b'Sample message for keylen=blocklen',
                'a27d24b592e8c8cbf6d4ce6fc5bf62d8'
                'fc98bf2d486640d9eb8099e24047837f'
                '5f3bffbe92dcce90b4ed5b1e7e44fa90'
            ), (
                bytes(range(152)),
                b'Sample message for keylen>blocklen',
                'e5ae4c739f455279368ebf36d4f5354c'
                '95aa184c899d3870e460ebc288ef1f94'
                '70053f73f7c6da2a71bcaec38ce7d6ac'
            )
        ]:
            self.assert_hmac(
                key, msg, hexdigest,
                hashfunc=self.sha3_384, hashname='sha3_384',
                digest_size=48, block_size=104
            )

    def test_sha3_512_nist(self):
        for key, msg, hexdigest in [
            (
                bytes(range(64)),
                b'Sample message for keylen<blocklen',
                '4efd629d6c71bf86162658f29943b1c3'
                '08ce27cdfa6db0d9c3ce81763f9cbce5'
                'f7ebe9868031db1a8f8eb7b6b95e5c5e'
                '3f657a8996c86a2f6527e307f0213196'
            ), (
                bytes(range(72)),
                b'Sample message for keylen=blocklen',
                '544e257ea2a3e5ea19a590e6a24b724c'
                'e6327757723fe2751b75bf007d80f6b3'
                '60744bf1b7a88ea585f9765b47911976'
                'd3191cf83c039f5ffab0d29cc9d9b6da'
            ), (
                bytes(range(136)),
                b'Sample message for keylen>blocklen',
                '5f464f5e5b7848e3885e49b2c385f069'
                '4985d0e38966242dc4a5fe3fea4b37d4'
                '6b65ceced5dcf59438dd840bab22269f'
                '0ba7febdb9fcf74602a35666b2a32915'
            )
        ]:
            self.assert_hmac(
                key, msg, hexdigest,
                hashfunc=self.sha3_512, hashname='sha3_512',
                digest_size=64, block_size=72
            )


class PyRFCTestCase(ThroughObjectMixin, PyAssertersMixin,
                    WithOpenSSLHashFunctions, RFCTestCaseMixin,
                    unittest.TestCase):
    """Python implementation of HMAC using hmac.HMAC().

    The underlying hash functions are OpenSSL-based.
    """


class PyDotNewRFCTestCase(ThroughModuleAPIMixin, PyAssertersMixin,
                          WithOpenSSLHashFunctions, RFCTestCaseMixin,
                          unittest.TestCase):
    """Python implementation of HMAC using hmac.new().

    The underlying hash functions are OpenSSL-based.
    """


class OpenSSLRFCTestCase(OpenSSLAssertersMixin,
                         WithOpenSSLHashFunctions, RFCTestCaseMixin,
                         unittest.TestCase):
    """OpenSSL implementation of HMAC.

    The underlying hash functions are also OpenSSL-based.
    """


class BuiltinRFCTestCase(BuiltinAssertersMixin,
                         WithNamedHashFunctions, RFCTestCaseMixin,
                         unittest.TestCase):
    """Built-in HACL* implementation of HMAC.

    The underlying hash functions are also HACL*-based.
    """

    def assert_hmac_extra_cases(
        self, key, msg, hexdigest, digestmod, hashname, digest_size, block_size
    ):
        # assert one-shot HMAC at the same time
        with self.subTest(key=key, msg=msg, hashname=hashname):
            func = getattr(self.hmac, f'compute_{hashname}')
            self.assertTrue(callable(func))
            self.check_hmac_hexdigest(key, msg, hexdigest, digest_size, func)


# TODO(picnixz): once we have a HACL* HMAC, we should also test the Python
# implementation of HMAC with a HACL*-based hash function. For now, we only
# test it partially via the '_sha2' module, but for completeness we could
# also test the RFC test vectors against all possible implementations.


class DigestModTestCaseMixin(CreatorMixin, DigestMixin):
    """Tests for the 'digestmod' parameter for hmac_new() and hmac_digest()."""

    def assert_raises_missing_digestmod(self):
        """A context manager catching errors when a digestmod is missing."""
        return self.assertRaisesRegex(TypeError,
                                      "[M|m]issing.*required.*digestmod")

    def assert_raises_unknown_digestmod(self):
        """A context manager catching errors when a digestmod is unknown."""
        return self.assertRaisesRegex(ValueError, "[Uu]nsupported.*")

    def test_constructor_missing_digestmod(self):
        catcher = self.assert_raises_missing_digestmod
        self.do_test_constructor_missing_digestmod(catcher)

    def test_constructor_unknown_digestmod(self):
        catcher = self.assert_raises_unknown_digestmod
        self.do_test_constructor_unknown_digestmod(catcher)

    def do_test_constructor_missing_digestmod(self, catcher):
        for func, args, kwds in self.cases_missing_digestmod_in_constructor():
            with self.subTest(args=args, kwds=kwds), catcher():
                func(*args, **kwds)

    def do_test_constructor_unknown_digestmod(self, catcher):
        for func, args, kwds in self.cases_unknown_digestmod_in_constructor():
            with self.subTest(args=args, kwds=kwds), catcher():
                func(*args, **kwds)

    def cases_missing_digestmod_in_constructor(self):
        raise NotImplementedError

    def make_missing_digestmod_cases(self, func, missing_like=()):
        """Generate cases for missing digestmod tests.

        Only the Python implementation should consider "falsey" 'digestmod'
        values as being equivalent to a missing one.
        """
        key, msg = b'unused key', b'unused msg'
        choices = [DIGESTMOD_SENTINEL, *missing_like]
        return self._invalid_digestmod_cases(func, key, msg, choices)

    def cases_unknown_digestmod_in_constructor(self):
        raise NotImplementedError

    def make_unknown_digestmod_cases(self, func, bad_digestmods):
        """Generate cases for unknown digestmod tests."""
        key, msg = b'unused key', b'unused msg'
        return self._invalid_digestmod_cases(func, key, msg, bad_digestmods)

    def _invalid_digestmod_cases(self, func, key, msg, choices):
        cases = []
        for digestmod in choices:
            kwargs = {'digestmod': digestmod}
            cases.append((func, (key,), kwargs))
            cases.append((func, (key, msg), kwargs))
            cases.append((func, (key,), kwargs | {'msg': msg}))
        return cases


class ConstructorTestCaseMixin(CreatorMixin, DigestMixin, ObjectCheckerMixin):
    """HMAC constructor tests based on HMAC-SHA-2/256."""

    key = b"key"
    msg = b"hash this!"
    res = "6c845b47f52b3b47f6590c502db7825aad757bf4fadc8fa972f7cd2e76a5bdeb"

    def do_test_constructor(self, hmac_on_key_and_msg):
        self.do_test_constructor_invalid_types(hmac_on_key_and_msg)
        self.do_test_constructor_supported_types(hmac_on_key_and_msg)

    def do_test_constructor_invalid_types(self, hmac_on_key_and_msg):
        self.assertRaises(TypeError, hmac_on_key_and_msg, 1)
        self.assertRaises(TypeError, hmac_on_key_and_msg, "key")

        self.assertRaises(TypeError, hmac_on_key_and_msg, b"key", 1)
        self.assertRaises(TypeError, hmac_on_key_and_msg, b"key", "msg")

    def do_test_constructor_supported_types(self, hmac_on_key_and_msg):
        for tp_key in [bytes, bytearray]:
            for tp_msg in [bytes, bytearray, memoryview]:
                with self.subTest(tp_key=tp_key, tp_msg=tp_msg):
                    h = hmac_on_key_and_msg(tp_key(self.key), tp_msg(self.msg))
                    self.assertEqual(h.name, "hmac-sha256")
                    self.assertEqual(h.hexdigest(), self.res)

    @hashlib_helper.requires_hashdigest("sha256")
    def test_constructor(self):
        self.do_test_constructor(self.bind_hmac_new("sha256"))

    @hashlib_helper.requires_hashdigest("sha256")
    def test_digest(self):
        digest = self.hmac_digest(self.key, self.msg, "sha256")
        self.assertEqual(digest, binascii.unhexlify(self.res))


class PyConstructorBaseMixin(PyModuleMixin,
                             DigestModTestCaseMixin,
                             ConstructorTestCaseMixin):

    def cases_missing_digestmod_in_constructor(self):
        func, choices = self.hmac_new, ['', None, False]
        return self.make_missing_digestmod_cases(func, choices)

    def cases_unknown_digestmod_in_constructor(self):
        func, choices = self.hmac_new, ['unknown']
        return self.make_unknown_digestmod_cases(func, choices)

    @requires_builtin_sha2()
    def test_constructor_with_module(self):
        self.do_test_constructor(self.bind_hmac_new(sha2.sha256))

    @requires_builtin_sha2()
    def test_digest_with_module(self):
        digest = self.hmac_digest(self.key, self.msg, sha2.sha256)
        self.assertEqual(digest, binascii.unhexlify(self.res))


class PyConstructorTestCase(ThroughObjectMixin, PyConstructorBaseMixin,
                            unittest.TestCase):
    """Test the hmac.HMAC() pure Python constructor."""


class PyModuleConstructorTestCase(ThroughModuleAPIMixin, PyConstructorBaseMixin,
                                  unittest.TestCase):
    """Test the hmac.new() and hmac.digest() functions."""

    def test_hmac_digest_digestmod_parameter(self):
        func = self.hmac_digest

        def raiser():
            raise RuntimeError("custom exception")

        with self.assertRaisesRegex(RuntimeError, "custom exception"):
            func(b'key', b'msg', raiser)

        with self.assertRaisesRegex(ValueError, 'hash type'):
            func(b'key', b'msg', 'unknown')

        with self.assertRaisesRegex(AttributeError, 'new'):
            func(b'key', b'msg', 1234)
        with self.assertRaisesRegex(AttributeError, 'new'):
            func(b'key', b'msg', None)


class ExtensionConstructorTestCaseMixin(DigestModTestCaseMixin,
                                        ConstructorTestCaseMixin):

    @property
    def obj_type(self):
        """The underlying (non-instantiable) C class."""
        raise NotImplementedError

    @property
    def exc_type(self):
        """The exact exception class raised upon invalid 'digestmod' values."""
        raise NotImplementedError

    def test_internal_types(self):
        # internal C types are immutable and cannot be instantiated
        check_disallow_instantiation(self, self.obj_type)
        with self.assertRaisesRegex(TypeError, "immutable type"):
            self.obj_type.value = None

    def assert_raises_unknown_digestmod(self):
        self.assertIsSubclass(self.exc_type, ValueError)
        return self.assertRaises(self.exc_type)

    def cases_missing_digestmod_in_constructor(self):
        return self.make_missing_digestmod_cases(self.hmac_new)

    def cases_unknown_digestmod_in_constructor(self):
        func, choices = self.hmac_new, ['unknown', 1234]
        return self.make_unknown_digestmod_cases(func, choices)


class OpenSSLConstructorTestCase(ThroughOpenSSLAPIMixin,
                                 ExtensionConstructorTestCaseMixin,
                                 unittest.TestCase):

    @property
    def obj_type(self):
        return _hashlib.HMAC

    @property
    def exc_type(self):
        return _hashlib.UnsupportedDigestmodError

    def test_hmac_digest_digestmod_parameter(self):
        # TODO(picnixz): remove default arguments in _hashlib.hmac_digest()
        # since the return value is not a HMAC object but a bytes object.
        for value in [object, 'unknown', 1234, None]:
            with (
                self.subTest(value=value),
                self.assert_raises_unknown_digestmod(),
            ):
                self.hmac_digest(b'key', b'msg', value)


class BuiltinConstructorTestCase(ThroughBuiltinAPIMixin,
                                 ExtensionConstructorTestCaseMixin,
                                 unittest.TestCase):

    @property
    def obj_type(self):
        return self.hmac.HMAC

    @property
    def exc_type(self):
        return self.hmac.UnknownHashError

    def test_hmac_digest_digestmod_parameter(self):
        for value in [object, 'unknown', 1234, None]:
            with (
                self.subTest(value=value),
                self.assert_raises_unknown_digestmod(),
            ):
                self.hmac_digest(b'key', b'msg', value)


class SanityTestCaseMixin(CreatorMixin):
    """Sanity checks for HMAC objects and their object interface.

    The tests here use a common digestname and do not check all supported
    hash functions.
    """

    # The underlying HMAC class to test. May be in C or in Python.
    hmac_class: type
    # The underlying hash function name (should be accepted by the HMAC class).
    digestname: str
    # The expected digest and block sizes (must be hardcoded).
    digest_size: int
    block_size: int

    def test_methods(self):
        h = self.hmac_new(b"my secret key", digestmod=self.digestname)
        self.assertIsInstance(h, self.hmac_class)
        self.assertIsNone(h.update(b"compute the hash of this text!"))
        self.assertIsInstance(h.digest(), bytes)
        self.assertIsInstance(h.hexdigest(), str)
        self.assertIsInstance(h.copy(), self.hmac_class)

    def test_properties(self):
        h = self.hmac_new(b"my secret key", digestmod=self.digestname)
        self.assertEqual(h.name, f"hmac-{self.digestname}")
        self.assertEqual(h.digest_size, self.digest_size)
        self.assertEqual(h.block_size, self.block_size)

    def test_repr(self):
        # HMAC object representation may differ across implementations
        raise NotImplementedError


@hashlib_helper.requires_hashdigest('sha256')
class PySanityTestCase(ThroughObjectMixin, PyModuleMixin, SanityTestCaseMixin,
                       unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.hmac_class = cls.hmac.HMAC
        cls.digestname = 'sha256'
        cls.digest_size = 32
        cls.block_size = 64

    def test_repr(self):
        h = self.hmac_new(b"my secret key", digestmod=self.digestname)
        self.assertStartsWith(repr(h), "<hmac.HMAC object at")


@hashlib_helper.requires_openssl_hashdigest('sha256')
class OpenSSLSanityTestCase(ThroughOpenSSLAPIMixin, SanityTestCaseMixin,
                            unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.hmac_class = _hashlib.HMAC
        cls.digestname = 'sha256'
        cls.digest_size = 32
        cls.block_size = 64

    def test_repr(self):
        h = self.hmac_new(b"my secret key", digestmod=self.digestname)
        self.assertStartsWith(repr(h), f"<{self.digestname} HMAC object @")


class BuiltinSanityTestCase(ThroughBuiltinAPIMixin, SanityTestCaseMixin,
                            unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.hmac_class = cls.hmac.HMAC
        cls.digestname = 'sha256'
        cls.digest_size = 32
        cls.block_size = 64

    def test_repr(self):
        h = self.hmac_new(b"my secret key", digestmod=self.digestname)
        self.assertStartsWith(repr(h), f"<{self.digestname} HMAC object @")


class UpdateTestCaseMixin:
    """Tests for the update() method (streaming HMAC)."""

    def HMAC(self, key, msg=None):
        """Create a HMAC object."""
        raise NotImplementedError

    def check_update(self, key, chunks):
        chunks = list(chunks)
        msg = b''.join(chunks)
        h1 = self.HMAC(key, msg)

        h2 = self.HMAC(key)
        for chunk in chunks:
            h2.update(chunk)

        self.assertEqual(h1.digest(), h2.digest())
        self.assertEqual(h1.hexdigest(), h2.hexdigest())

    def test_update(self):
        key, msg = random.randbytes(16), random.randbytes(16)
        with self.subTest(key=key, msg=msg):
            self.check_update(key, [msg])

    def test_update_large(self):
        HASHLIB_GIL_MINSIZE = 2048

        key = random.randbytes(16)
        top = random.randbytes(HASHLIB_GIL_MINSIZE + 1)
        bot = random.randbytes(HASHLIB_GIL_MINSIZE + 1)
        self.check_update(key, [top, bot])

    def test_update_exceptions(self):
        h = self.HMAC(b"key")
        for msg in ['invalid msg', 123, (), []]:
            with self.subTest(msg=msg):
                self.assertRaises(TypeError, h.update, msg)


@hashlib_helper.requires_hashdigest('sha256')
class PyUpdateTestCase(PyModuleMixin, UpdateTestCaseMixin, unittest.TestCase):

    def HMAC(self, key, msg=None):
        return self.hmac.HMAC(key, msg, digestmod='sha256')


@hashlib_helper.requires_openssl_hashdigest('sha256')
class OpenSSLUpdateTestCase(UpdateTestCaseMixin, unittest.TestCase):

    def HMAC(self, key, msg=None):
        return _hashlib.hmac_new(key, msg, digestmod='sha256')


class BuiltinUpdateTestCase(BuiltinModuleMixin,
                            UpdateTestCaseMixin, unittest.TestCase):

    def HMAC(self, key, msg=None):
        # Even if Python does not build '_sha2', the HACL* sources
        # are still built, making it possible to use SHA-2 hashes.
        return self.hmac.new(key, msg, digestmod='sha256')


class CopyBaseTestCase:

    def test_attributes(self):
        raise NotImplementedError

    def test_realcopy(self):
        raise NotImplementedError


@hashlib_helper.requires_hashdigest('sha256')
class PythonCopyTestCase(CopyBaseTestCase, unittest.TestCase):

    def test_attributes(self):
        # Testing if attributes are of same type.
        h1 = hmac.HMAC.__new__(hmac.HMAC)
        h1._init_old(b"key", b"msg", digestmod="sha256")
        self.assertIsNone(h1._hmac)
        self.assertIsNotNone(h1._inner)
        self.assertIsNotNone(h1._outer)

        h2 = h1.copy()
        self.assertIsNone(h2._hmac)
        self.assertIsNotNone(h2._inner)
        self.assertIsNotNone(h2._outer)
        self.assertEqual(type(h1._inner), type(h2._inner))
        self.assertEqual(type(h1._outer), type(h2._outer))

    def test_realcopy(self):
        # Testing if the copy method created a real copy.
        h1 = hmac.HMAC.__new__(hmac.HMAC)
        h1._init_old(b"key", b"msg", digestmod="sha256")
        h2 = h1.copy()
        # Using id() in case somebody has overridden __eq__/__ne__.
        self.assertNotEqual(id(h1), id(h2))
        self.assertNotEqual(id(h1._inner), id(h2._inner))
        self.assertNotEqual(id(h1._outer), id(h2._outer))

    def test_equality(self):
        # Testing if the copy has the same digests.
        h1 = hmac.HMAC(b"key", digestmod="sha256")
        h1.update(b"some random text")
        h2 = h1.copy()
        self.assertEqual(h1.digest(), h2.digest())
        self.assertEqual(h1.hexdigest(), h2.hexdigest())

    def test_equality_new(self):
        # Testing if the copy has the same digests with hmac.new().
        h1 = hmac.new(b"key", digestmod="sha256")
        h1.update(b"some random text")
        h2 = h1.copy()
        # Using id() in case somebody has overridden __eq__/__ne__.
        self.assertNotEqual(id(h1), id(h2))
        self.assertEqual(h1.digest(), h2.digest())
        self.assertEqual(h1.hexdigest(), h2.hexdigest())


class ExtensionCopyTestCase(CopyBaseTestCase):

    def init(self, h):
        """Call the dedicate init() method to test."""
        raise NotImplementedError

    def test_attributes(self):
        # Testing if attributes are of same type.
        h1 = hmac.HMAC.__new__(hmac.HMAC)

        self.init(h1)
        self.assertIsNotNone(h1._hmac)
        self.assertIsNone(h1._inner)
        self.assertIsNone(h1._outer)

        h2 = h1.copy()
        self.assertIsNotNone(h2._hmac)
        self.assertIsNone(h2._inner)
        self.assertIsNone(h2._outer)

    def test_realcopy(self):
        h1 = hmac.HMAC.__new__(hmac.HMAC)
        self.init(h1)
        h2 = h1.copy()
        # Using id() in case somebody has overridden __eq__/__ne__.
        self.assertNotEqual(id(h1._hmac), id(h2._hmac))


@hashlib_helper.requires_openssl_hashdigest('sha256')
class OpenSSLCopyTestCase(ExtensionCopyTestCase, unittest.TestCase):

    def init(self, h):
        h._init_openssl_hmac(b"key", b"msg", digestmod="sha256")


@hashlib_helper.requires_builtin_hmac()
class BuiltinCopyTestCase(ExtensionCopyTestCase, unittest.TestCase):

    def init(self, h):
        # Even if Python does not build '_sha2', the HACL* sources
        # are still built, making it possible to use SHA-2 hashes.
        h._init_builtin_hmac(b"key", b"msg", digestmod="sha256")


class CompareDigestMixin:

    @staticmethod
    def compare_digest(a, b):
        """Implementation of 'a == b' to test."""
        raise NotImplementedError

    def assert_digest_equal(self, a, b):
        with self.subTest(a=a, b=b):
            self.assertTrue(self.compare_digest(a, b))
        with self.subTest(a=b, b=a):
            self.assertTrue(self.compare_digest(b, a))

    def assert_digest_not_equal(self, a, b):
        with self.subTest(a=a, b=b):
            self.assertFalse(self.compare_digest(a, b))
        with self.subTest(a=b, b=a):
            self.assertFalse(self.compare_digest(b, a))

    def test_exceptions(self):
        for a, b in [
            # Testing input type exception handling
            (100, 200), (100, b"foobar"), ("foobar", b"foobar"),
            # non-ASCII strings
            ("fooä", "fooä")
        ]:
            self.assertRaises(TypeError, self.compare_digest, a, b)
            self.assertRaises(TypeError, self.compare_digest, b, a)

    def test_bytes(self):
        # Testing bytes of different lengths
        a, b = b"foobar", b"foo"
        self.assert_digest_not_equal(a, b)
        a, b = b"\xde\xad\xbe\xef", b"\xde\xad"
        self.assert_digest_not_equal(a, b)

        # Testing bytes of same lengths, different values
        a, b = b"foobar", b"foobaz"
        self.assert_digest_not_equal(a, b)
        a, b = b"\xde\xad\xbe\xef", b"\xab\xad\x1d\xea"
        self.assert_digest_not_equal(a, b)

        # Testing bytes of same lengths, same values
        a, b = b"foobar", b"foobar"
        self.assert_digest_equal(a, b)
        a, b = b"\xde\xad\xbe\xef", b"\xde\xad\xbe\xef"
        self.assert_digest_equal(a, b)

    def test_bytearray(self):
        # Testing bytearrays of same lengths, same values
        a, b = bytearray(b"foobar"), bytearray(b"foobar")
        self.assert_digest_equal(a, b)

        # Testing bytearrays of different lengths
        a, b = bytearray(b"foobar"), bytearray(b"foo")
        self.assert_digest_not_equal(a, b)

        # Testing bytearrays of same lengths, different values
        a, b = bytearray(b"foobar"), bytearray(b"foobaz")
        self.assert_digest_not_equal(a, b)

    def test_mixed_types(self):
        # Testing byte and bytearray of same lengths, same values
        a, b = bytearray(b"foobar"), b"foobar"
        self.assert_digest_equal(a, b)

        # Testing byte bytearray of different lengths
        a, b = bytearray(b"foobar"), b"foo"
        self.assert_digest_not_equal(a, b)

        # Testing byte and bytearray of same lengths, different values
        a, b = bytearray(b"foobar"), b"foobaz"
        self.assert_digest_not_equal(a, b)

    def test_string(self):
        # Testing str of same lengths
        a, b = "foobar", "foobar"
        self.assert_digest_equal(a, b)

        # Testing str of different lengths
        a, b = "foo", "foobar"
        self.assert_digest_not_equal(a, b)

        # Testing str of same lengths, different values
        a, b = "foobar", "foobaz"
        self.assert_digest_not_equal(a, b)

    def test_string_subclass(self):
        class S(str):
            def __eq__(self, other):
                raise ValueError("should not be called")

        a, b = S("foobar"), S("foobar")
        self.assert_digest_equal(a, b)
        a, b = S("foobar"), "foobar"
        self.assert_digest_equal(a, b)
        a, b = S("foobar"), S("foobaz")
        self.assert_digest_not_equal(a, b)

    def test_bytes_subclass(self):
        class B(bytes):
            def __eq__(self, other):
                raise ValueError("should not be called")

        a, b = B(b"foobar"), B(b"foobar")
        self.assert_digest_equal(a, b)
        a, b = B(b"foobar"), b"foobar"
        self.assert_digest_equal(a, b)
        a, b = B(b"foobar"), B(b"foobaz")
        self.assert_digest_not_equal(a, b)


class HMACCompareDigestTestCase(CompareDigestMixin, unittest.TestCase):
    compare_digest = hmac.compare_digest

    def test_compare_digest_func(self):
        if openssl_compare_digest is not None:
            self.assertIs(self.compare_digest, openssl_compare_digest)
        else:
            self.assertIs(self.compare_digest, operator_compare_digest)


@hashlib_helper.requires_hashlib()
class OpenSSLCompareDigestTestCase(CompareDigestMixin, unittest.TestCase):
    compare_digest = openssl_compare_digest


class OperatorCompareDigestTestCase(CompareDigestMixin, unittest.TestCase):
    compare_digest = operator_compare_digest


class PyMiscellaneousTests(unittest.TestCase):
    """Miscellaneous tests for the pure Python HMAC module."""

    @hashlib_helper.requires_builtin_hmac()
    def test_hmac_constructor_uses_builtin(self):
        # Block the OpenSSL implementation and check that
        # HMAC() uses the built-in implementation instead.
        hmac = import_fresh_module("hmac", blocked=["_hashlib"])

        def watch_method(cls, name):
            return mock.patch.object(
                cls, name, autospec=True, wraps=getattr(cls, name)
            )

        with (
            watch_method(hmac.HMAC, '_init_openssl_hmac') as f,
            watch_method(hmac.HMAC, '_init_builtin_hmac') as g,
        ):
            _ = hmac.HMAC(b'key', b'msg', digestmod="sha256")
            f.assert_not_called()
            g.assert_called_once()

    @hashlib_helper.requires_hashdigest('sha256')
    def test_hmac_delegated_properties(self):
        h = hmac.HMAC(b'key', b'msg', digestmod="sha256")
        self.assertEqual(h.name, "hmac-sha256")
        self.assertEqual(h.digest_size, 32)
        self.assertEqual(h.block_size, 64)

    @hashlib_helper.requires_hashdigest('sha256')
    def test_legacy_block_size_warnings(self):
        class MockCrazyHash(object):
            """Ain't no block_size attribute here."""
            def __init__(self, *args):
                self._x = hashlib.sha256(*args)
                self.digest_size = self._x.digest_size
            def update(self, v):
                self._x.update(v)
            def digest(self):
                return self._x.digest()

        with warnings.catch_warnings():
            warnings.simplefilter('error', RuntimeWarning)
            with self.assertRaises(RuntimeWarning):
                hmac.HMAC(b'a', b'b', digestmod=MockCrazyHash)
                self.fail('Expected warning about missing block_size')

            MockCrazyHash.block_size = 1
            with self.assertRaises(RuntimeWarning):
                hmac.HMAC(b'a', b'b', digestmod=MockCrazyHash)
                self.fail('Expected warning about small block_size')

    @hashlib_helper.requires_hashdigest('sha256')
    def test_with_fallback(self):
        cache = getattr(hashlib, '__builtin_constructor_cache')
        try:
            cache['foo'] = hashlib.sha256
            hexdigest = hmac.digest(b'key', b'message', 'foo').hex()
            expected = ('6e9ef29b75fffc5b7abae527d58fdadb'
                        '2fe42e7219011976917343065f58ed4a')
            self.assertEqual(hexdigest, expected)
        finally:
            cache.pop('foo')


class BuiltinMiscellaneousTests(BuiltinModuleMixin, unittest.TestCase):
    """HMAC-BLAKE2 is not standardized as BLAKE2 is a keyed hash function.

    In particular, there is no official test vectors for HMAC-BLAKE2.
    However, we can test that the HACL* interface is correctly used by
    checking against the pure Python implementation output.
    """

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.blake2 = import_module("_blake2")
        cls.blake2b = cls.blake2.blake2b
        cls.blake2s = cls.blake2.blake2s

    def assert_hmac_blake_correctness(self, digest, key, msg, hashfunc):
        self.assertIsInstance(digest, bytes)
        expect = hmac._compute_digest_fallback(key, msg, hashfunc)
        self.assertEqual(digest, expect)

    def test_compute_blake2b_32(self):
        key, msg = random.randbytes(8), random.randbytes(16)
        digest = self.hmac.compute_blake2b_32(key, msg)
        self.assert_hmac_blake_correctness(digest, key, msg, self.blake2b)

    def test_compute_blake2s_32(self):
        key, msg = random.randbytes(8), random.randbytes(16)
        digest = self.hmac.compute_blake2s_32(key, msg)
        self.assert_hmac_blake_correctness(digest, key, msg, self.blake2s)


if __name__ == "__main__":
    unittest.main()
