test_hashlib.py 37.9 KB
Newer Older
1 2 3 4
# Test hashlib module
#
# $Id$
#
5
#  Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org)
6 7 8
#  Licensed to PSF under a Contributor Agreement.
#

9
import array
10
from binascii import unhexlify
11
import hashlib
12
import importlib
13
import itertools
14
import os
15
import sys
16
import threading
17
import unittest
18
import warnings
19
from test import support
20
from test.support import _4G, bigmemtest, import_fresh_module
21
from http.client import HTTPException
22

23 24 25
# Were we compiled --with-pydebug or with #define Py_DEBUG?
COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount')

26 27
c_hashlib = import_fresh_module('hashlib', fresh=['_hashlib'])
py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])
28

29 30 31 32 33 34 35
try:
    import _blake2
except ImportError:
    _blake2 = None

requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2')

36 37 38 39 40 41 42
try:
    import _sha3
except ImportError:
    _sha3 = None

requires_sha3 = unittest.skipUnless(_sha3, 'requires _sha3')

43

44
def hexstr(s):
45
    assert isinstance(s, bytes), repr(s)
46 47
    h = "0123456789abcdef"
    r = ''
48
    for i in s:
49
        r += h[(i >> 4) & 0xF] + h[i & 0xF]
50 51 52
    return r


53
URL = "http://www.pythontest.net/hashlib/{}.txt"
54 55

def read_vectors(hash_name):
56 57 58 59 60 61 62
    url = URL.format(hash_name)
    try:
        testdata = support.open_urlresource(url)
    except (OSError, HTTPException):
        raise unittest.SkipTest("Could not retrieve {}".format(url))
    with testdata:
        for line in testdata:
63 64 65 66 67 68 69 70
            line = line.strip()
            if line.startswith('#') or not line:
                continue
            parts = line.split(',')
            parts[0] = bytes.fromhex(parts[0])
            yield parts


71 72 73
class HashLibTestCase(unittest.TestCase):
    supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1',
                             'sha224', 'SHA224', 'sha256', 'SHA256',
74
                             'sha384', 'SHA384', 'sha512', 'SHA512',
75 76 77 78 79
                             'blake2b', 'blake2s',
                             'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
                             'shake_128', 'shake_256')

    shakes = {'shake_128', 'shake_256'}
80

81 82
    # Issue #14693: fallback modules are always compiled under POSIX
    _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG
83 84 85 86

    def _conditional_import_module(self, module_name):
        """Import a module and return a reference to it or None on failure."""
        try:
87 88
            return importlib.import_module(module_name)
        except ModuleNotFoundError as error:
89 90
            if self._warn_on_extension_import:
                warnings.warn('Did a C extension fail to compile? %s' % error)
91
        return None
92 93 94 95 96

    def __init__(self, *args, **kwargs):
        algorithms = set()
        for algorithm in self.supported_hash_names:
            algorithms.add(algorithm.lower())
97 98 99 100 101

        _blake2 = self._conditional_import_module('_blake2')
        if _blake2:
            algorithms.update({'blake2b', 'blake2s'})

102 103 104 105 106 107 108 109
        self.constructors_to_test = {}
        for algorithm in algorithms:
            self.constructors_to_test[algorithm] = set()

        # For each algorithm, test the direct constructor and the use
        # of hashlib.new given the algorithm name.
        for algorithm, constructors in self.constructors_to_test.items():
            constructors.add(getattr(hashlib, algorithm))
110
            def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm, **kwargs):
111
                if data is None:
112 113
                    return hashlib.new(_alg, **kwargs)
                return hashlib.new(_alg, data, **kwargs)
114 115 116 117 118 119
            constructors.add(_test_algorithm_via_hashlib_new)

        _hashlib = self._conditional_import_module('_hashlib')
        if _hashlib:
            # These two algorithms should always be present when this module
            # is compiled.  If not, something was compiled wrong.
120 121
            self.assertTrue(hasattr(_hashlib, 'openssl_md5'))
            self.assertTrue(hasattr(_hashlib, 'openssl_sha1'))
122 123 124 125 126
            for algorithm, constructors in self.constructors_to_test.items():
                constructor = getattr(_hashlib, 'openssl_'+algorithm, None)
                if constructor:
                    constructors.add(constructor)

127 128 129 130
        def add_builtin_constructor(name):
            constructor = getattr(hashlib, "__get_builtin_constructor")(name)
            self.constructors_to_test[name].add(constructor)

131 132
        _md5 = self._conditional_import_module('_md5')
        if _md5:
133
            add_builtin_constructor('md5')
134 135
        _sha1 = self._conditional_import_module('_sha1')
        if _sha1:
136
            add_builtin_constructor('sha1')
137 138
        _sha256 = self._conditional_import_module('_sha256')
        if _sha256:
139 140
            add_builtin_constructor('sha224')
            add_builtin_constructor('sha256')
141 142
        _sha512 = self._conditional_import_module('_sha512')
        if _sha512:
143 144
            add_builtin_constructor('sha384')
            add_builtin_constructor('sha512')
145 146 147
        if _blake2:
            add_builtin_constructor('blake2s')
            add_builtin_constructor('blake2b')
148

149 150 151 152 153 154 155 156 157
        _sha3 = self._conditional_import_module('_sha3')
        if _sha3:
            add_builtin_constructor('sha3_224')
            add_builtin_constructor('sha3_256')
            add_builtin_constructor('sha3_384')
            add_builtin_constructor('sha3_512')
            add_builtin_constructor('shake_128')
            add_builtin_constructor('shake_256')

158 159
        super(HashLibTestCase, self).__init__(*args, **kwargs)

160 161 162 163 164
    @property
    def hash_constructors(self):
        constructors = self.constructors_to_test.values()
        return itertools.chain.from_iterable(constructors)

165
    @support.refcount_test
166
    @unittest.skipIf(c_hashlib is None, 'Require _hashlib module')
167 168 169 170 171 172 173 174
    def test_refleaks_in_hash___init__(self):
        gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount')
        sha1_hash = c_hashlib.new('sha1')
        refs_before = gettotalrefcount()
        for i in range(100):
            sha1_hash.__init__('sha1')
        self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)

175 176
    def test_hash_array(self):
        a = array.array("b", range(10))
177
        for cons in self.hash_constructors:
178
            c = cons(a)
179 180 181 182
            if c.name in self.shakes:
                c.hexdigest(16)
            else:
                c.hexdigest()
183

184 185
    def test_algorithms_guaranteed(self):
        self.assertEqual(hashlib.algorithms_guaranteed,
186
            set(_algo for _algo in self.supported_hash_names
187 188
                  if _algo.islower()))

189 190 191 192
    def test_algorithms_available(self):
        self.assertTrue(set(hashlib.algorithms_guaranteed).
                            issubset(hashlib.algorithms_available))

193
    def test_unknown_hash(self):
194 195
        self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam')
        self.assertRaises(TypeError, hashlib.new, 1)
196

197
    def test_get_builtin_constructor(self):
198 199 200 201
        get_builtin_constructor = getattr(hashlib,
                                          '__get_builtin_constructor')
        builtin_constructor_cache = getattr(hashlib,
                                            '__builtin_constructor_cache')
202 203 204 205
        self.assertRaises(ValueError, get_builtin_constructor, 'test')
        try:
            import _md5
        except ImportError:
206
            self.skipTest("_md5 module not available")
207 208
        # This forces an ImportError for "import _md5" statements
        sys.modules['_md5'] = None
209 210
        # clear the cache
        builtin_constructor_cache.clear()
211 212 213 214 215 216 217
        try:
            self.assertRaises(ValueError, get_builtin_constructor, 'md5')
        finally:
            if '_md5' in locals():
                sys.modules['_md5'] = _md5
            else:
                del sys.modules['_md5']
218
        self.assertRaises(TypeError, get_builtin_constructor, 3)
219 220 221
        constructor = get_builtin_constructor('md5')
        self.assertIs(constructor, _md5.md5)
        self.assertEqual(sorted(builtin_constructor_cache), ['MD5', 'md5'])
222

223
    def test_hexdigest(self):
224 225
        for cons in self.hash_constructors:
            h = cons()
226 227 228 229 230 231
            if h.name in self.shakes:
                self.assertIsInstance(h.digest(16), bytes)
                self.assertEqual(hexstr(h.digest(16)), h.hexdigest(16))
            else:
                self.assertIsInstance(h.digest(), bytes)
                self.assertEqual(hexstr(h.digest()), h.hexdigest())
232

233 234 235
    def test_name_attribute(self):
        for cons in self.hash_constructors:
            h = cons()
236
            self.assertIsInstance(h.name, str)
237 238 239 240
            if h.name in self.supported_hash_names:
                self.assertIn(h.name, self.supported_hash_names)
            else:
                self.assertNotIn(h.name, self.supported_hash_names)
241
            self.assertEqual(h.name, hashlib.new(h.name).name)
242 243

    def test_large_update(self):
244 245 246
        aas = b'a' * 128
        bees = b'b' * 127
        cees = b'c' * 126
247
        dees = b'd' * 2048 #  HASHLIB_GIL_MINSIZE
248

249 250
        for cons in self.hash_constructors:
            m1 = cons()
251 252 253
            m1.update(aas)
            m1.update(bees)
            m1.update(cees)
254
            m1.update(dees)
255 256 257 258
            if m1.name in self.shakes:
                args = (16,)
            else:
                args = ()
259

260 261
            m2 = cons()
            m2.update(aas + bees + cees + dees)
262
            self.assertEqual(m1.digest(*args), m2.digest(*args))
263

264
            m3 = cons(aas + bees + cees + dees)
265
            self.assertEqual(m1.digest(*args), m3.digest(*args))
266 267 268

            # verify copy() doesn't touch original
            m4 = cons(aas + bees + cees)
269
            m4_digest = m4.digest(*args)
270 271
            m4_copy = m4.copy()
            m4_copy.update(dees)
272 273
            self.assertEqual(m1.digest(*args), m4_copy.digest(*args))
            self.assertEqual(m4.digest(*args), m4_digest)
274

275 276
    def check(self, name, data, hexdigest, shake=False, **kwargs):
        length = len(hexdigest)//2
277
        hexdigest = hexdigest.lower()
278 279 280 281
        constructors = self.constructors_to_test[name]
        # 2 is for hashlib.name(...) and hashlib.new(name, ...)
        self.assertGreaterEqual(len(constructors), 2)
        for hash_object_constructor in constructors:
282
            m = hash_object_constructor(data, **kwargs)
283
            computed = m.hexdigest() if not shake else m.hexdigest(length)
284
            self.assertEqual(
285
                    computed, hexdigest,
286 287 288
                    "Hash algorithm %s constructed using %s returned hexdigest"
                    " %r for %d byte input data that should have hashed to %r."
                    % (name, hash_object_constructor,
289
                       computed, len(data), hexdigest))
290
            computed = m.digest() if not shake else m.digest(length)
291 292
            digest = bytes.fromhex(hexdigest)
            self.assertEqual(computed, digest)
293 294
            if not shake:
                self.assertEqual(len(digest), m.digest_size)
295

296 297
    def check_no_unicode(self, algorithm_name):
        # Unicode objects are not allowed as input.
298 299 300
        constructors = self.constructors_to_test[algorithm_name]
        for hash_object_constructor in constructors:
            self.assertRaises(TypeError, hash_object_constructor, 'spam')
301 302 303 304 305 306 307 308

    def test_no_unicode(self):
        self.check_no_unicode('md5')
        self.check_no_unicode('sha1')
        self.check_no_unicode('sha224')
        self.check_no_unicode('sha256')
        self.check_no_unicode('sha384')
        self.check_no_unicode('sha512')
309

310 311 312 313 314
    @requires_blake2
    def test_no_unicode_blake2(self):
        self.check_no_unicode('blake2b')
        self.check_no_unicode('blake2s')

315 316 317 318 319 320 321 322 323 324 325
    @requires_sha3
    def test_no_unicode_sha3(self):
        self.check_no_unicode('sha3_224')
        self.check_no_unicode('sha3_256')
        self.check_no_unicode('sha3_384')
        self.check_no_unicode('sha3_512')
        self.check_no_unicode('shake_128')
        self.check_no_unicode('shake_256')

    def check_blocksize_name(self, name, block_size=0, digest_size=0,
                             digest_length=None):
326 327 328 329 330
        constructors = self.constructors_to_test[name]
        for hash_object_constructor in constructors:
            m = hash_object_constructor()
            self.assertEqual(m.block_size, block_size)
            self.assertEqual(m.digest_size, digest_size)
331 332 333 334 335 336 337 338
            if digest_length:
                self.assertEqual(len(m.digest(digest_length)),
                                 digest_length)
                self.assertEqual(len(m.hexdigest(digest_length)),
                                 2*digest_length)
            else:
                self.assertEqual(len(m.digest()), digest_size)
                self.assertEqual(len(m.hexdigest()), 2*digest_size)
339
            self.assertEqual(m.name, name)
340
            # split for sha3_512 / _sha3.sha3 object
341
            self.assertIn(name.split("_")[0], repr(m))
342 343 344 345 346 347 348 349

    def test_blocksize_name(self):
        self.check_blocksize_name('md5', 64, 16)
        self.check_blocksize_name('sha1', 64, 20)
        self.check_blocksize_name('sha224', 64, 28)
        self.check_blocksize_name('sha256', 64, 32)
        self.check_blocksize_name('sha384', 128, 48)
        self.check_blocksize_name('sha512', 128, 64)
350 351 352

    @requires_sha3
    def test_blocksize_name_sha3(self):
353 354 355 356 357 358
        self.check_blocksize_name('sha3_224', 144, 28)
        self.check_blocksize_name('sha3_256', 136, 32)
        self.check_blocksize_name('sha3_384', 104, 48)
        self.check_blocksize_name('sha3_512', 72, 64)
        self.check_blocksize_name('shake_128', 168, 0, 32)
        self.check_blocksize_name('shake_256', 136, 0, 64)
359

360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
    def check_sha3(self, name, capacity, rate, suffix):
        constructors = self.constructors_to_test[name]
        for hash_object_constructor in constructors:
            m = hash_object_constructor()
            self.assertEqual(capacity + rate, 1600)
            self.assertEqual(m._capacity_bits, capacity)
            self.assertEqual(m._rate_bits, rate)
            self.assertEqual(m._suffix, suffix)

    @requires_sha3
    def test_extra_sha3(self):
        self.check_sha3('sha3_224', 448, 1152, b'\x06')
        self.check_sha3('sha3_256', 512, 1088, b'\x06')
        self.check_sha3('sha3_384', 768, 832, b'\x06')
        self.check_sha3('sha3_512', 1024, 576, b'\x06')
        self.check_sha3('shake_128', 256, 1344, b'\x1f')
        self.check_sha3('shake_256', 512, 1088, b'\x1f')

378 379 380 381 382
    @requires_blake2
    def test_blocksize_name_blake2(self):
        self.check_blocksize_name('blake2b', 128, 64)
        self.check_blocksize_name('blake2s', 64, 32)

383
    def test_case_md5_0(self):
384
        self.check('md5', b'', 'd41d8cd98f00b204e9800998ecf8427e')
385 386

    def test_case_md5_1(self):
387
        self.check('md5', b'abc', '900150983cd24fb0d6963f7d28e17f72')
388 389

    def test_case_md5_2(self):
390 391
        self.check('md5',
                   b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
392
                   'd174ab98d277d9f5a5611c2c9f419d9f')
393

394 395
    @unittest.skipIf(sys.maxsize < _4G + 5, 'test cannot run on 32-bit systems')
    @bigmemtest(size=_4G + 5, memuse=1, dry_run=False)
396
    def test_case_md5_huge(self, size):
397
        self.check('md5', b'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
398

399 400
    @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems')
    @bigmemtest(size=_4G - 1, memuse=1, dry_run=False)
401
    def test_case_md5_uintmax(self, size):
402
        self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3')
403 404 405 406 407 408

    # use the three examples from Federal Information Processing Standards
    # Publication 180-1, Secure Hash Standard,  1995 April 17
    # http://www.itl.nist.gov/div897/pubs/fip180-1.htm

    def test_case_sha1_0(self):
409
        self.check('sha1', b"",
410
                   "da39a3ee5e6b4b0d3255bfef95601890afd80709")
411 412

    def test_case_sha1_1(self):
413
        self.check('sha1', b"abc",
414
                   "a9993e364706816aba3e25717850c26c9cd0d89d")
415 416

    def test_case_sha1_2(self):
417 418
        self.check('sha1',
                   b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
419
                   "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
420 421

    def test_case_sha1_3(self):
422
        self.check('sha1', b"a" * 1000000,
423
                   "34aa973cd4c4daa4f61eeb2bdbad27316534016f")
424 425 426 427 428 429 430


    # use the examples from Federal Information Processing Standards
    # Publication 180-2, Secure Hash Standard,  2002 August 1
    # http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf

    def test_case_sha224_0(self):
431
        self.check('sha224', b"",
432 433 434
          "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")

    def test_case_sha224_1(self):
435
        self.check('sha224', b"abc",
436 437 438 439
          "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7")

    def test_case_sha224_2(self):
        self.check('sha224',
440
          b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
441 442 443
          "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525")

    def test_case_sha224_3(self):
444
        self.check('sha224', b"a" * 1000000,
445 446 447 448
          "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67")


    def test_case_sha256_0(self):
449
        self.check('sha256', b"",
450 451 452
          "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")

    def test_case_sha256_1(self):
453
        self.check('sha256', b"abc",
454 455 456 457
          "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")

    def test_case_sha256_2(self):
        self.check('sha256',
458
          b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
459 460 461
          "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1")

    def test_case_sha256_3(self):
462
        self.check('sha256', b"a" * 1000000,
463 464 465 466
          "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0")


    def test_case_sha384_0(self):
467
        self.check('sha384', b"",
468 469 470 471
          "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da"+
          "274edebfe76f65fbd51ad2f14898b95b")

    def test_case_sha384_1(self):
472
        self.check('sha384', b"abc",
473 474 475 476 477
          "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"+
          "8086072ba1e7cc2358baeca134c825a7")

    def test_case_sha384_2(self):
        self.check('sha384',
478 479
                   b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
                   b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
480 481 482 483
          "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"+
          "fcc7c71a557e2db966c3e9fa91746039")

    def test_case_sha384_3(self):
484
        self.check('sha384', b"a" * 1000000,
485 486 487 488 489
          "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"+
          "07b8b3dc38ecc4ebae97ddd87f3d8985")


    def test_case_sha512_0(self):
490
        self.check('sha512', b"",
491 492 493 494
          "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"+
          "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")

    def test_case_sha512_1(self):
495
        self.check('sha512', b"abc",
496 497 498 499 500
          "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"+
          "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")

    def test_case_sha512_2(self):
        self.check('sha512',
501 502
                   b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
                   b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
503 504 505 506
          "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"+
          "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909")

    def test_case_sha512_3(self):
507
        self.check('sha512', b"a" * 1000000,
508 509 510
          "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"+
          "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b")

511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
    def check_blake2(self, constructor, salt_size, person_size, key_size,
                     digest_size, max_offset):
        self.assertEqual(constructor.SALT_SIZE, salt_size)
        for i in range(salt_size + 1):
            constructor(salt=b'a' * i)
        salt = b'a' * (salt_size + 1)
        self.assertRaises(ValueError, constructor, salt=salt)

        self.assertEqual(constructor.PERSON_SIZE, person_size)
        for i in range(person_size+1):
            constructor(person=b'a' * i)
        person = b'a' * (person_size + 1)
        self.assertRaises(ValueError, constructor, person=person)

        self.assertEqual(constructor.MAX_DIGEST_SIZE, digest_size)
        for i in range(1, digest_size + 1):
            constructor(digest_size=i)
        self.assertRaises(ValueError, constructor, digest_size=-1)
        self.assertRaises(ValueError, constructor, digest_size=0)
        self.assertRaises(ValueError, constructor, digest_size=digest_size+1)

        self.assertEqual(constructor.MAX_KEY_SIZE, key_size)
        for i in range(key_size+1):
            constructor(key=b'a' * i)
        key = b'a' * (key_size + 1)
        self.assertRaises(ValueError, constructor, key=key)
        self.assertEqual(constructor().hexdigest(),
                         constructor(key=b'').hexdigest())

        for i in range(0, 256):
            constructor(fanout=i)
        self.assertRaises(ValueError, constructor, fanout=-1)
        self.assertRaises(ValueError, constructor, fanout=256)

        for i in range(1, 256):
            constructor(depth=i)
        self.assertRaises(ValueError, constructor, depth=-1)
        self.assertRaises(ValueError, constructor, depth=0)
        self.assertRaises(ValueError, constructor, depth=256)

        for i in range(0, 256):
            constructor(node_depth=i)
        self.assertRaises(ValueError, constructor, node_depth=-1)
        self.assertRaises(ValueError, constructor, node_depth=256)

        for i in range(0, digest_size + 1):
            constructor(inner_size=i)
        self.assertRaises(ValueError, constructor, inner_size=-1)
        self.assertRaises(ValueError, constructor, inner_size=digest_size+1)

        constructor(leaf_size=0)
        constructor(leaf_size=(1<<32)-1)
        self.assertRaises(OverflowError, constructor, leaf_size=-1)
        self.assertRaises(OverflowError, constructor, leaf_size=1<<32)

        constructor(node_offset=0)
        constructor(node_offset=max_offset)
        self.assertRaises(OverflowError, constructor, node_offset=-1)
        self.assertRaises(OverflowError, constructor, node_offset=max_offset+1)

        constructor(
            string=b'',
            key=b'',
            salt=b'',
            person=b'',
            digest_size=17,
            fanout=1,
            depth=1,
            leaf_size=256,
            node_offset=512,
            node_depth=1,
            inner_size=7,
            last_node=True
        )

    def blake2_rfc7693(self, constructor, md_len, in_len):
        def selftest_seq(length, seed):
            mask = (1<<32)-1
            a = (0xDEAD4BAD * seed) & mask
            b = 1
            out = bytearray(length)
            for i in range(length):
                t = (a + b) & mask
                a, b = b, t
                out[i] = (t >> 24) & 0xFF
            return out
        outer = constructor(digest_size=32)
        for outlen in md_len:
            for inlen in in_len:
                indata = selftest_seq(inlen, inlen)
                key = selftest_seq(outlen, outlen)
                unkeyed = constructor(indata, digest_size=outlen)
                outer.update(unkeyed.digest())
                keyed = constructor(indata, key=key, digest_size=outlen)
                outer.update(keyed.digest())
        return outer.hexdigest()

    @requires_blake2
    def test_blake2b(self):
        self.check_blake2(hashlib.blake2b, 16, 16, 64, 64, (1<<64)-1)
        b2b_md_len = [20, 32, 48, 64]
        b2b_in_len = [0, 3, 128, 129, 255, 1024]
        self.assertEqual(
            self.blake2_rfc7693(hashlib.blake2b, b2b_md_len, b2b_in_len),
            "c23a7800d98123bd10f506c61e29da5603d763b8bbad2e737f5e765a7bccd475")

    @requires_blake2
    def test_case_blake2b_0(self):
        self.check('blake2b', b"",
          "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419"+
          "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce")

    @requires_blake2
    def test_case_blake2b_1(self):
        self.check('blake2b', b"abc",
          "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1"+
          "7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923")

629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
    @requires_blake2
    def test_case_blake2b_all_parameters(self):
        # This checks that all the parameters work in general, and also that
        # parameter byte order doesn't get confused on big endian platforms.
        self.check('blake2b', b"foo",
          "920568b0c5873b2f0ab67bedb6cf1b2b",
          digest_size=16,
          key=b"bar",
          salt=b"baz",
          person=b"bing",
          fanout=2,
          depth=3,
          leaf_size=4,
          node_offset=5,
          node_depth=6,
          inner_size=7,
          last_node=True)

647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
    @requires_blake2
    def test_blake2b_vectors(self):
        for msg, key, md in read_vectors('blake2b'):
            key = bytes.fromhex(key)
            self.check('blake2b', msg, md, key=key)

    @requires_blake2
    def test_blake2s(self):
        self.check_blake2(hashlib.blake2s, 8, 8, 32, 32, (1<<48)-1)
        b2s_md_len = [16, 20, 28, 32]
        b2s_in_len = [0, 3, 64, 65, 255, 1024]
        self.assertEqual(
            self.blake2_rfc7693(hashlib.blake2s, b2s_md_len, b2s_in_len),
            "6a411f08ce25adcdfb02aba641451cec53c598b24f4fc787fbdc88797f4c1dfe")

    @requires_blake2
    def test_case_blake2s_0(self):
        self.check('blake2s', b"",
          "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9")

    @requires_blake2
    def test_case_blake2s_1(self):
        self.check('blake2s', b"abc",
          "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982")

672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
    @requires_blake2
    def test_case_blake2s_all_parameters(self):
        # This checks that all the parameters work in general, and also that
        # parameter byte order doesn't get confused on big endian platforms.
        self.check('blake2s', b"foo",
          "bf2a8f7fe3c555012a6f8046e646bc75",
          digest_size=16,
          key=b"bar",
          salt=b"baz",
          person=b"bing",
          fanout=2,
          depth=3,
          leaf_size=4,
          node_offset=5,
          node_depth=6,
          inner_size=7,
          last_node=True)

690 691 692 693 694 695
    @requires_blake2
    def test_blake2s_vectors(self):
        for msg, key, md in read_vectors('blake2s'):
            key = bytes.fromhex(key)
            self.check('blake2s', msg, md, key=key)

696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
    @requires_sha3
    def test_case_sha3_224_0(self):
        self.check('sha3_224', b"",
          "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7")

    @requires_sha3
    def test_case_sha3_224_vector(self):
        for msg, md in read_vectors('sha3_224'):
            self.check('sha3_224', msg, md)

    @requires_sha3
    def test_case_sha3_256_0(self):
        self.check('sha3_256', b"",
          "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a")

    @requires_sha3
    def test_case_sha3_256_vector(self):
        for msg, md in read_vectors('sha3_256'):
            self.check('sha3_256', msg, md)

    @requires_sha3
    def test_case_sha3_384_0(self):
        self.check('sha3_384', b"",
          "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"+
          "c3713831264adb47fb6bd1e058d5f004")

    @requires_sha3
    def test_case_sha3_384_vector(self):
        for msg, md in read_vectors('sha3_384'):
            self.check('sha3_384', msg, md)

    @requires_sha3
    def test_case_sha3_512_0(self):
        self.check('sha3_512', b"",
          "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"+
          "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26")

    @requires_sha3
    def test_case_sha3_512_vector(self):
        for msg, md in read_vectors('sha3_512'):
            self.check('sha3_512', msg, md)

    @requires_sha3
    def test_case_shake_128_0(self):
        self.check('shake_128', b"",
          "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26",
          True)
        self.check('shake_128', b"", "7f9c", True)

    @requires_sha3
    def test_case_shake128_vector(self):
        for msg, md in read_vectors('shake_128'):
            self.check('shake_128', msg, md, True)

    @requires_sha3
    def test_case_shake_256_0(self):
        self.check('shake_256', b"",
          "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f",
          True)
        self.check('shake_256', b"", "46b9", True)

    @requires_sha3
    def test_case_shake256_vector(self):
        for msg, md in read_vectors('shake_256'):
            self.check('shake_256', msg, md, True)

762 763 764 765 766
    def test_gil(self):
        # Check things work fine with an input larger than the size required
        # for multithreaded operation (which is hardwired to 2048).
        gil_minsize = 2048

767 768
        for cons in self.hash_constructors:
            m = cons()
769 770 771 772
            m.update(b'1')
            m.update(b'#' * gil_minsize)
            m.update(b'1')

773
            m = cons(b'x' * gil_minsize)
774 775
            m.update(b'1')

776 777 778 779
        m = hashlib.md5()
        m.update(b'1')
        m.update(b'#' * gil_minsize)
        m.update(b'1')
780
        self.assertEqual(m.hexdigest(), 'cb1e1a2cbc80be75e19935d621fb9b21')
781 782

        m = hashlib.md5(b'x' * gil_minsize)
783
        self.assertEqual(m.hexdigest(), 'cfb767f225d58469c5de3632a8803958')
784

785
    @support.reap_threads
786 787 788 789 790 791 792 793 794 795
    def test_threaded_hashing(self):
        # Updating the same hash object from several threads at once
        # using data chunk sizes containing the same byte sequences.
        #
        # If the internal locks are working to prevent multiple
        # updates on the same object from running at once, the resulting
        # hash will be the same as doing it single threaded upfront.
        hasher = hashlib.sha1()
        num_threads = 5
        smallest_data = b'swineflu'
796
        data = smallest_data * 200000
797 798
        expected_hash = hashlib.sha1(data*num_threads).hexdigest()

799
        def hash_in_chunks(chunk_size):
800 801
            index = 0
            while index < len(data):
802
                hasher.update(data[index:index + chunk_size])
803 804
                index += chunk_size

805
        threads = []
806
        for threadnum in range(num_threads):
807
            chunk_size = len(data) // (10 ** threadnum)
808 809
            self.assertGreater(chunk_size, 0)
            self.assertEqual(chunk_size % len(smallest_data), 0)
810 811 812 813 814 815 816 817
            thread = threading.Thread(target=hash_in_chunks,
                                      args=(chunk_size,))
            threads.append(thread)

        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()
818 819 820

        self.assertEqual(expected_hash, hasher.hexdigest())

821

822
class KDFTests(unittest.TestCase):
823

824 825 826 827 828 829 830 831 832 833 834
    pbkdf2_test_vectors = [
        (b'password', b'salt', 1, None),
        (b'password', b'salt', 2, None),
        (b'password', b'salt', 4096, None),
        # too slow, it takes over a minute on a fast CPU.
        #(b'password', b'salt', 16777216, None),
        (b'passwordPASSWORDpassword', b'saltSALTsaltSALTsaltSALTsaltSALTsalt',
         4096, -1),
        (b'pass\0word', b'sa\0lt', 4096, 16),
    ]

835 836 837 838 839 840
    scrypt_test_vectors = [
        (b'', b'', 16, 1, 1, unhexlify('77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906')),
        (b'password', b'NaCl', 1024, 8, 16, unhexlify('fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640')),
        (b'pleaseletmein', b'SodiumChloride', 16384, 8, 1, unhexlify('7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887')),
   ]

841 842
    pbkdf2_results = {
        "sha1": [
843
            # official test vectors from RFC 6070
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
            (bytes.fromhex('0c60c80f961f0e71f3a9b524af6012062fe037a6'), None),
            (bytes.fromhex('ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'), None),
            (bytes.fromhex('4b007901b765489abead49d926f721d065a429c1'), None),
            #(bytes.fromhex('eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'), None),
            (bytes.fromhex('3d2eec4fe41c849b80c8d83662c0e44a8b291a964c'
                           'f2f07038'), 25),
            (bytes.fromhex('56fa6aa75548099dcc37d7f03425e0c3'), None),],
        "sha256": [
            (bytes.fromhex('120fb6cffcf8b32c43e7225256c4f837'
                           'a86548c92ccc35480805987cb70be17b'), None),
            (bytes.fromhex('ae4d0c95af6b46d32d0adff928f06dd0'
                           '2a303f8ef3c251dfd6e2d85a95474c43'), None),
            (bytes.fromhex('c5e478d59288c841aa530db6845c4c8d'
                           '962893a001ce4e11a4963873aa98134a'), None),
            #(bytes.fromhex('cf81c66fe8cfc04d1f31ecb65dab4089'
            #               'f7f179e89b3b0bcb17ad10e3ac6eba46'), None),
            (bytes.fromhex('348c89dbcbd32b2f32d814b8116e84cf2b17'
                           '347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9'), 40),
            (bytes.fromhex('89b69d0516f829893c696226650a8687'), None),],
        "sha512": [
            (bytes.fromhex('867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5'
                           'd513554e1c8cf252c02d470a285a0501bad999bfe943c08f'
                           '050235d7d68b1da55e63f73b60a57fce'), None),
            (bytes.fromhex('e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f004071'
                           '3f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82'
                           'be67335c77a6068e04112754f27ccf4e'), None),
            (bytes.fromhex('d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f8'
                           '7f6902e072f457b5143f30602641b3d55cd335988cb36b84'
                           '376060ecd532e039b742a239434af2d5'), None),
            (bytes.fromhex('8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b8'
                           '68c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30'
                           '225c583a186cd82bd4daea9724a3d3b8'), 64),
            (bytes.fromhex('9d9e9c4cd21fe4be24d5b8244c759665'), None),],
    }

879
    def _test_pbkdf2_hmac(self, pbkdf2):
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
        for digest_name, results in self.pbkdf2_results.items():
            for i, vector in enumerate(self.pbkdf2_test_vectors):
                password, salt, rounds, dklen = vector
                expected, overwrite_dklen = results[i]
                if overwrite_dklen:
                    dklen = overwrite_dklen
                out = pbkdf2(digest_name, password, salt, rounds, dklen)
                self.assertEqual(out, expected,
                                 (digest_name, password, salt, rounds, dklen))
                out = pbkdf2(digest_name, memoryview(password),
                             memoryview(salt), rounds, dklen)
                out = pbkdf2(digest_name, bytearray(password),
                             bytearray(salt), rounds, dklen)
                self.assertEqual(out, expected)
                if dklen is None:
                    out = pbkdf2(digest_name, password, salt, rounds)
                    self.assertEqual(out, expected,
                                     (digest_name, password, salt, rounds))

        self.assertRaises(TypeError, pbkdf2, b'sha1', b'pass', b'salt', 1)
        self.assertRaises(TypeError, pbkdf2, 'sha1', 'pass', 'salt', 1)
        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', 0)
        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', -1)
        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', 1, 0)
        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', 1, -1)
        with self.assertRaisesRegex(ValueError, 'unsupported hash type'):
            pbkdf2('unknown', b'pass', b'salt', 1)
907 908 909
        out = pbkdf2(hash_name='sha1', password=b'password', salt=b'salt',
            iterations=1, dklen=None)
        self.assertEqual(out, self.pbkdf2_results['sha1'][0][0])
910

911 912
    def test_pbkdf2_hmac_py(self):
        self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac)
913

914 915 916 917
    @unittest.skipUnless(hasattr(c_hashlib, 'pbkdf2_hmac'),
                     '   test requires OpenSSL > 1.0')
    def test_pbkdf2_hmac_c(self):
        self._test_pbkdf2_hmac(c_hashlib.pbkdf2_hmac)
918 919


920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959
    @unittest.skipUnless(hasattr(c_hashlib, 'scrypt'),
                     '   test requires OpenSSL > 1.1')
    def test_scrypt(self):
        for password, salt, n, r, p, expected in self.scrypt_test_vectors:
            result = hashlib.scrypt(password, salt=salt, n=n, r=r, p=p)
            self.assertEqual(result, expected)

        # this values should work
        hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1)
        # password and salt must be bytes-like
        with self.assertRaises(TypeError):
            hashlib.scrypt('password', salt=b'salt', n=2, r=8, p=1)
        with self.assertRaises(TypeError):
            hashlib.scrypt(b'password', salt='salt', n=2, r=8, p=1)
        # require keyword args
        with self.assertRaises(TypeError):
            hashlib.scrypt(b'password')
        with self.assertRaises(TypeError):
            hashlib.scrypt(b'password', b'salt')
        with self.assertRaises(TypeError):
            hashlib.scrypt(b'password', 2, 8, 1, salt=b'salt')
        for n in [-1, 0, 1, None]:
            with self.assertRaises((ValueError, OverflowError, TypeError)):
                hashlib.scrypt(b'password', salt=b'salt', n=n, r=8, p=1)
        for r in [-1, 0, None]:
            with self.assertRaises((ValueError, OverflowError, TypeError)):
                hashlib.scrypt(b'password', salt=b'salt', n=2, r=r, p=1)
        for p in [-1, 0, None]:
            with self.assertRaises((ValueError, OverflowError, TypeError)):
                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=p)
        for maxmem in [-1, None]:
            with self.assertRaises((ValueError, OverflowError, TypeError)):
                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1,
                               maxmem=maxmem)
        for dklen in [-1, None]:
            with self.assertRaises((ValueError, OverflowError, TypeError)):
                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1,
                               dklen=dklen)


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