• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Test hashlib module
2#
3# $Id$
4#
5#  Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org)
6#  Licensed to PSF under a Contributor Agreement.
7#
8
9import array
10from binascii import unhexlify
11import functools
12import hashlib
13import importlib
14import itertools
15import os
16import sys
17import threading
18import unittest
19import warnings
20from test import support
21from test.support import _4G, bigmemtest, import_fresh_module
22from test.support import requires_hashdigest
23from http.client import HTTPException
24
25# Were we compiled --with-pydebug or with #define Py_DEBUG?
26COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount')
27
28c_hashlib = import_fresh_module('hashlib', fresh=['_hashlib'])
29py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])
30
31try:
32    from _hashlib import HASH
33except ImportError:
34    HASH = None
35
36try:
37    import _blake2
38except ImportError:
39    _blake2 = None
40
41requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2')
42
43try:
44    import _sha3
45except ImportError:
46    _sha3 = None
47
48requires_sha3 = unittest.skipUnless(_sha3, 'requires _sha3')
49
50
51def hexstr(s):
52    assert isinstance(s, bytes), repr(s)
53    h = "0123456789abcdef"
54    r = ''
55    for i in s:
56        r += h[(i >> 4) & 0xF] + h[i & 0xF]
57    return r
58
59
60URL = "http://www.pythontest.net/hashlib/{}.txt"
61
62def read_vectors(hash_name):
63    url = URL.format(hash_name)
64    try:
65        testdata = support.open_urlresource(url)
66    except (OSError, HTTPException):
67        raise unittest.SkipTest("Could not retrieve {}".format(url))
68    with testdata:
69        for line in testdata:
70            line = line.strip()
71            if line.startswith('#') or not line:
72                continue
73            parts = line.split(',')
74            parts[0] = bytes.fromhex(parts[0])
75            yield parts
76
77
78class HashLibTestCase(unittest.TestCase):
79    supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1',
80                             'sha224', 'SHA224', 'sha256', 'SHA256',
81                             'sha384', 'SHA384', 'sha512', 'SHA512',
82                             'blake2b', 'blake2s',
83                             'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
84                             'shake_128', 'shake_256')
85
86    shakes = {'shake_128', 'shake_256'}
87
88    # Issue #14693: fallback modules are always compiled under POSIX
89    _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG
90
91    def _conditional_import_module(self, module_name):
92        """Import a module and return a reference to it or None on failure."""
93        try:
94            return importlib.import_module(module_name)
95        except ModuleNotFoundError as error:
96            if self._warn_on_extension_import:
97                warnings.warn('Did a C extension fail to compile? %s' % error)
98        return None
99
100    def __init__(self, *args, **kwargs):
101        algorithms = set()
102        for algorithm in self.supported_hash_names:
103            algorithms.add(algorithm.lower())
104
105        _blake2 = self._conditional_import_module('_blake2')
106        if _blake2:
107            algorithms.update({'blake2b', 'blake2s'})
108
109        self.constructors_to_test = {}
110        for algorithm in algorithms:
111            self.constructors_to_test[algorithm] = set()
112
113        # For each algorithm, test the direct constructor and the use
114        # of hashlib.new given the algorithm name.
115        for algorithm, constructors in self.constructors_to_test.items():
116            constructors.add(getattr(hashlib, algorithm))
117            def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm, **kwargs):
118                if data is None:
119                    return hashlib.new(_alg, **kwargs)
120                return hashlib.new(_alg, data, **kwargs)
121            constructors.add(_test_algorithm_via_hashlib_new)
122
123        _hashlib = self._conditional_import_module('_hashlib')
124        self._hashlib = _hashlib
125        if _hashlib:
126            # These two algorithms should always be present when this module
127            # is compiled.  If not, something was compiled wrong.
128            self.assertTrue(hasattr(_hashlib, 'openssl_md5'))
129            self.assertTrue(hasattr(_hashlib, 'openssl_sha1'))
130            for algorithm, constructors in self.constructors_to_test.items():
131                constructor = getattr(_hashlib, 'openssl_'+algorithm, None)
132                if constructor:
133                    try:
134                        constructor()
135                    except ValueError:
136                        # default constructor blocked by crypto policy
137                        pass
138                    else:
139                        constructors.add(constructor)
140
141        def add_builtin_constructor(name):
142            constructor = getattr(hashlib, "__get_builtin_constructor")(name)
143            self.constructors_to_test[name].add(constructor)
144
145        _md5 = self._conditional_import_module('_md5')
146        if _md5:
147            add_builtin_constructor('md5')
148        _sha1 = self._conditional_import_module('_sha1')
149        if _sha1:
150            add_builtin_constructor('sha1')
151        _sha256 = self._conditional_import_module('_sha256')
152        if _sha256:
153            add_builtin_constructor('sha224')
154            add_builtin_constructor('sha256')
155        _sha512 = self._conditional_import_module('_sha512')
156        if _sha512:
157            add_builtin_constructor('sha384')
158            add_builtin_constructor('sha512')
159        if _blake2:
160            add_builtin_constructor('blake2s')
161            add_builtin_constructor('blake2b')
162
163        _sha3 = self._conditional_import_module('_sha3')
164        if _sha3:
165            add_builtin_constructor('sha3_224')
166            add_builtin_constructor('sha3_256')
167            add_builtin_constructor('sha3_384')
168            add_builtin_constructor('sha3_512')
169            add_builtin_constructor('shake_128')
170            add_builtin_constructor('shake_256')
171
172        super(HashLibTestCase, self).__init__(*args, **kwargs)
173
174    @property
175    def hash_constructors(self):
176        constructors = self.constructors_to_test.values()
177        return itertools.chain.from_iterable(constructors)
178
179    @support.refcount_test
180    @unittest.skipIf(c_hashlib is None, 'Require _hashlib module')
181    def test_refleaks_in_hash___init__(self):
182        gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount')
183        sha1_hash = c_hashlib.new('sha1')
184        refs_before = gettotalrefcount()
185        for i in range(100):
186            sha1_hash.__init__('sha1')
187        self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
188
189    def test_hash_array(self):
190        a = array.array("b", range(10))
191        for cons in self.hash_constructors:
192            c = cons(a)
193            if c.name in self.shakes:
194                c.hexdigest(16)
195            else:
196                c.hexdigest()
197
198    def test_algorithms_guaranteed(self):
199        self.assertEqual(hashlib.algorithms_guaranteed,
200            set(_algo for _algo in self.supported_hash_names
201                  if _algo.islower()))
202
203    def test_algorithms_available(self):
204        self.assertTrue(set(hashlib.algorithms_guaranteed).
205                            issubset(hashlib.algorithms_available))
206
207    def test_unknown_hash(self):
208        self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam')
209        self.assertRaises(TypeError, hashlib.new, 1)
210
211    def test_new_upper_to_lower(self):
212        self.assertEqual(hashlib.new("SHA256").name, "sha256")
213
214    def test_get_builtin_constructor(self):
215        get_builtin_constructor = getattr(hashlib,
216                                          '__get_builtin_constructor')
217        builtin_constructor_cache = getattr(hashlib,
218                                            '__builtin_constructor_cache')
219        self.assertRaises(ValueError, get_builtin_constructor, 'test')
220        try:
221            import _md5
222        except ImportError:
223            self.skipTest("_md5 module not available")
224        # This forces an ImportError for "import _md5" statements
225        sys.modules['_md5'] = None
226        # clear the cache
227        builtin_constructor_cache.clear()
228        try:
229            self.assertRaises(ValueError, get_builtin_constructor, 'md5')
230        finally:
231            if '_md5' in locals():
232                sys.modules['_md5'] = _md5
233            else:
234                del sys.modules['_md5']
235        self.assertRaises(TypeError, get_builtin_constructor, 3)
236        constructor = get_builtin_constructor('md5')
237        self.assertIs(constructor, _md5.md5)
238        self.assertEqual(sorted(builtin_constructor_cache), ['MD5', 'md5'])
239
240    def test_hexdigest(self):
241        for cons in self.hash_constructors:
242            h = cons()
243            if h.name in self.shakes:
244                self.assertIsInstance(h.digest(16), bytes)
245                self.assertEqual(hexstr(h.digest(16)), h.hexdigest(16))
246            else:
247                self.assertIsInstance(h.digest(), bytes)
248                self.assertEqual(hexstr(h.digest()), h.hexdigest())
249
250    def test_digest_length_overflow(self):
251        # See issue #34922
252        large_sizes = (2**29, 2**32-10, 2**32+10, 2**61, 2**64-10, 2**64+10)
253        for cons in self.hash_constructors:
254            h = cons()
255            if h.name not in self.shakes:
256                continue
257            for digest in h.digest, h.hexdigest:
258                self.assertRaises(ValueError, digest, -10)
259                for length in large_sizes:
260                    with self.assertRaises((ValueError, OverflowError)):
261                        digest(length)
262
263    def test_name_attribute(self):
264        for cons in self.hash_constructors:
265            h = cons()
266            self.assertIsInstance(h.name, str)
267            if h.name in self.supported_hash_names:
268                self.assertIn(h.name, self.supported_hash_names)
269            else:
270                self.assertNotIn(h.name, self.supported_hash_names)
271            self.assertEqual(h.name, hashlib.new(h.name).name)
272
273    def test_large_update(self):
274        aas = b'a' * 128
275        bees = b'b' * 127
276        cees = b'c' * 126
277        dees = b'd' * 2048 #  HASHLIB_GIL_MINSIZE
278
279        for cons in self.hash_constructors:
280            m1 = cons()
281            m1.update(aas)
282            m1.update(bees)
283            m1.update(cees)
284            m1.update(dees)
285            if m1.name in self.shakes:
286                args = (16,)
287            else:
288                args = ()
289
290            m2 = cons()
291            m2.update(aas + bees + cees + dees)
292            self.assertEqual(m1.digest(*args), m2.digest(*args))
293
294            m3 = cons(aas + bees + cees + dees)
295            self.assertEqual(m1.digest(*args), m3.digest(*args))
296
297            # verify copy() doesn't touch original
298            m4 = cons(aas + bees + cees)
299            m4_digest = m4.digest(*args)
300            m4_copy = m4.copy()
301            m4_copy.update(dees)
302            self.assertEqual(m1.digest(*args), m4_copy.digest(*args))
303            self.assertEqual(m4.digest(*args), m4_digest)
304
305    def check(self, name, data, hexdigest, shake=False, **kwargs):
306        length = len(hexdigest)//2
307        hexdigest = hexdigest.lower()
308        constructors = self.constructors_to_test[name]
309        # 2 is for hashlib.name(...) and hashlib.new(name, ...)
310        self.assertGreaterEqual(len(constructors), 2)
311        for hash_object_constructor in constructors:
312            m = hash_object_constructor(data, **kwargs)
313            computed = m.hexdigest() if not shake else m.hexdigest(length)
314            self.assertEqual(
315                    computed, hexdigest,
316                    "Hash algorithm %s constructed using %s returned hexdigest"
317                    " %r for %d byte input data that should have hashed to %r."
318                    % (name, hash_object_constructor,
319                       computed, len(data), hexdigest))
320            computed = m.digest() if not shake else m.digest(length)
321            digest = bytes.fromhex(hexdigest)
322            self.assertEqual(computed, digest)
323            if not shake:
324                self.assertEqual(len(digest), m.digest_size)
325
326    def check_no_unicode(self, algorithm_name):
327        # Unicode objects are not allowed as input.
328        constructors = self.constructors_to_test[algorithm_name]
329        for hash_object_constructor in constructors:
330            self.assertRaises(TypeError, hash_object_constructor, 'spam')
331
332    def test_no_unicode(self):
333        self.check_no_unicode('md5')
334        self.check_no_unicode('sha1')
335        self.check_no_unicode('sha224')
336        self.check_no_unicode('sha256')
337        self.check_no_unicode('sha384')
338        self.check_no_unicode('sha512')
339
340    @requires_blake2
341    def test_no_unicode_blake2(self):
342        self.check_no_unicode('blake2b')
343        self.check_no_unicode('blake2s')
344
345    @requires_sha3
346    def test_no_unicode_sha3(self):
347        self.check_no_unicode('sha3_224')
348        self.check_no_unicode('sha3_256')
349        self.check_no_unicode('sha3_384')
350        self.check_no_unicode('sha3_512')
351        self.check_no_unicode('shake_128')
352        self.check_no_unicode('shake_256')
353
354    def check_blocksize_name(self, name, block_size=0, digest_size=0,
355                             digest_length=None):
356        constructors = self.constructors_to_test[name]
357        for hash_object_constructor in constructors:
358            m = hash_object_constructor()
359            self.assertEqual(m.block_size, block_size)
360            self.assertEqual(m.digest_size, digest_size)
361            if digest_length:
362                self.assertEqual(len(m.digest(digest_length)),
363                                 digest_length)
364                self.assertEqual(len(m.hexdigest(digest_length)),
365                                 2*digest_length)
366            else:
367                self.assertEqual(len(m.digest()), digest_size)
368                self.assertEqual(len(m.hexdigest()), 2*digest_size)
369            self.assertEqual(m.name, name)
370            # split for sha3_512 / _sha3.sha3 object
371            self.assertIn(name.split("_")[0], repr(m))
372
373    def test_blocksize_name(self):
374        self.check_blocksize_name('md5', 64, 16)
375        self.check_blocksize_name('sha1', 64, 20)
376        self.check_blocksize_name('sha224', 64, 28)
377        self.check_blocksize_name('sha256', 64, 32)
378        self.check_blocksize_name('sha384', 128, 48)
379        self.check_blocksize_name('sha512', 128, 64)
380
381    @requires_sha3
382    def test_blocksize_name_sha3(self):
383        self.check_blocksize_name('sha3_224', 144, 28)
384        self.check_blocksize_name('sha3_256', 136, 32)
385        self.check_blocksize_name('sha3_384', 104, 48)
386        self.check_blocksize_name('sha3_512', 72, 64)
387        self.check_blocksize_name('shake_128', 168, 0, 32)
388        self.check_blocksize_name('shake_256', 136, 0, 64)
389
390    def check_sha3(self, name, capacity, rate, suffix):
391        constructors = self.constructors_to_test[name]
392        for hash_object_constructor in constructors:
393            m = hash_object_constructor()
394            if HASH is not None and isinstance(m, HASH):
395                # _hashopenssl's variant does not have extra SHA3 attributes
396                continue
397            self.assertEqual(capacity + rate, 1600)
398            self.assertEqual(m._capacity_bits, capacity)
399            self.assertEqual(m._rate_bits, rate)
400            self.assertEqual(m._suffix, suffix)
401
402    @requires_sha3
403    def test_extra_sha3(self):
404        self.check_sha3('sha3_224', 448, 1152, b'\x06')
405        self.check_sha3('sha3_256', 512, 1088, b'\x06')
406        self.check_sha3('sha3_384', 768, 832, b'\x06')
407        self.check_sha3('sha3_512', 1024, 576, b'\x06')
408        self.check_sha3('shake_128', 256, 1344, b'\x1f')
409        self.check_sha3('shake_256', 512, 1088, b'\x1f')
410
411    @requires_blake2
412    def test_blocksize_name_blake2(self):
413        self.check_blocksize_name('blake2b', 128, 64)
414        self.check_blocksize_name('blake2s', 64, 32)
415
416    def test_case_md5_0(self):
417        self.check('md5', b'', 'd41d8cd98f00b204e9800998ecf8427e')
418
419    def test_case_md5_1(self):
420        self.check('md5', b'abc', '900150983cd24fb0d6963f7d28e17f72')
421
422    def test_case_md5_2(self):
423        self.check('md5',
424                   b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
425                   'd174ab98d277d9f5a5611c2c9f419d9f')
426
427    @unittest.skipIf(sys.maxsize < _4G + 5, 'test cannot run on 32-bit systems')
428    @bigmemtest(size=_4G + 5, memuse=1, dry_run=False)
429    def test_case_md5_huge(self, size):
430        self.check('md5', b'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
431
432    @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems')
433    @bigmemtest(size=_4G - 1, memuse=1, dry_run=False)
434    def test_case_md5_uintmax(self, size):
435        self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3')
436
437    # use the three examples from Federal Information Processing Standards
438    # Publication 180-1, Secure Hash Standard,  1995 April 17
439    # http://www.itl.nist.gov/div897/pubs/fip180-1.htm
440
441    def test_case_sha1_0(self):
442        self.check('sha1', b"",
443                   "da39a3ee5e6b4b0d3255bfef95601890afd80709")
444
445    def test_case_sha1_1(self):
446        self.check('sha1', b"abc",
447                   "a9993e364706816aba3e25717850c26c9cd0d89d")
448
449    def test_case_sha1_2(self):
450        self.check('sha1',
451                   b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
452                   "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
453
454    def test_case_sha1_3(self):
455        self.check('sha1', b"a" * 1000000,
456                   "34aa973cd4c4daa4f61eeb2bdbad27316534016f")
457
458
459    # use the examples from Federal Information Processing Standards
460    # Publication 180-2, Secure Hash Standard,  2002 August 1
461    # http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
462
463    def test_case_sha224_0(self):
464        self.check('sha224', b"",
465          "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
466
467    def test_case_sha224_1(self):
468        self.check('sha224', b"abc",
469          "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7")
470
471    def test_case_sha224_2(self):
472        self.check('sha224',
473          b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
474          "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525")
475
476    def test_case_sha224_3(self):
477        self.check('sha224', b"a" * 1000000,
478          "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67")
479
480
481    def test_case_sha256_0(self):
482        self.check('sha256', b"",
483          "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
484
485    def test_case_sha256_1(self):
486        self.check('sha256', b"abc",
487          "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
488
489    def test_case_sha256_2(self):
490        self.check('sha256',
491          b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
492          "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1")
493
494    def test_case_sha256_3(self):
495        self.check('sha256', b"a" * 1000000,
496          "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0")
497
498
499    def test_case_sha384_0(self):
500        self.check('sha384', b"",
501          "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da"+
502          "274edebfe76f65fbd51ad2f14898b95b")
503
504    def test_case_sha384_1(self):
505        self.check('sha384', b"abc",
506          "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"+
507          "8086072ba1e7cc2358baeca134c825a7")
508
509    def test_case_sha384_2(self):
510        self.check('sha384',
511                   b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
512                   b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
513          "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"+
514          "fcc7c71a557e2db966c3e9fa91746039")
515
516    def test_case_sha384_3(self):
517        self.check('sha384', b"a" * 1000000,
518          "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"+
519          "07b8b3dc38ecc4ebae97ddd87f3d8985")
520
521
522    def test_case_sha512_0(self):
523        self.check('sha512', b"",
524          "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"+
525          "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
526
527    def test_case_sha512_1(self):
528        self.check('sha512', b"abc",
529          "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"+
530          "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")
531
532    def test_case_sha512_2(self):
533        self.check('sha512',
534                   b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
535                   b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
536          "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"+
537          "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909")
538
539    def test_case_sha512_3(self):
540        self.check('sha512', b"a" * 1000000,
541          "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"+
542          "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b")
543
544    def check_blake2(self, constructor, salt_size, person_size, key_size,
545                     digest_size, max_offset):
546        self.assertEqual(constructor.SALT_SIZE, salt_size)
547        for i in range(salt_size + 1):
548            constructor(salt=b'a' * i)
549        salt = b'a' * (salt_size + 1)
550        self.assertRaises(ValueError, constructor, salt=salt)
551
552        self.assertEqual(constructor.PERSON_SIZE, person_size)
553        for i in range(person_size+1):
554            constructor(person=b'a' * i)
555        person = b'a' * (person_size + 1)
556        self.assertRaises(ValueError, constructor, person=person)
557
558        self.assertEqual(constructor.MAX_DIGEST_SIZE, digest_size)
559        for i in range(1, digest_size + 1):
560            constructor(digest_size=i)
561        self.assertRaises(ValueError, constructor, digest_size=-1)
562        self.assertRaises(ValueError, constructor, digest_size=0)
563        self.assertRaises(ValueError, constructor, digest_size=digest_size+1)
564
565        self.assertEqual(constructor.MAX_KEY_SIZE, key_size)
566        for i in range(key_size+1):
567            constructor(key=b'a' * i)
568        key = b'a' * (key_size + 1)
569        self.assertRaises(ValueError, constructor, key=key)
570        self.assertEqual(constructor().hexdigest(),
571                         constructor(key=b'').hexdigest())
572
573        for i in range(0, 256):
574            constructor(fanout=i)
575        self.assertRaises(ValueError, constructor, fanout=-1)
576        self.assertRaises(ValueError, constructor, fanout=256)
577
578        for i in range(1, 256):
579            constructor(depth=i)
580        self.assertRaises(ValueError, constructor, depth=-1)
581        self.assertRaises(ValueError, constructor, depth=0)
582        self.assertRaises(ValueError, constructor, depth=256)
583
584        for i in range(0, 256):
585            constructor(node_depth=i)
586        self.assertRaises(ValueError, constructor, node_depth=-1)
587        self.assertRaises(ValueError, constructor, node_depth=256)
588
589        for i in range(0, digest_size + 1):
590            constructor(inner_size=i)
591        self.assertRaises(ValueError, constructor, inner_size=-1)
592        self.assertRaises(ValueError, constructor, inner_size=digest_size+1)
593
594        constructor(leaf_size=0)
595        constructor(leaf_size=(1<<32)-1)
596        self.assertRaises(ValueError, constructor, leaf_size=-1)
597        self.assertRaises(OverflowError, constructor, leaf_size=1<<32)
598
599        constructor(node_offset=0)
600        constructor(node_offset=max_offset)
601        self.assertRaises(ValueError, constructor, node_offset=-1)
602        self.assertRaises(OverflowError, constructor, node_offset=max_offset+1)
603
604        self.assertRaises(TypeError, constructor, data=b'')
605        self.assertRaises(TypeError, constructor, string=b'')
606        self.assertRaises(TypeError, constructor, '')
607
608        constructor(
609            b'',
610            key=b'',
611            salt=b'',
612            person=b'',
613            digest_size=17,
614            fanout=1,
615            depth=1,
616            leaf_size=256,
617            node_offset=512,
618            node_depth=1,
619            inner_size=7,
620            last_node=True
621        )
622
623    def blake2_rfc7693(self, constructor, md_len, in_len):
624        def selftest_seq(length, seed):
625            mask = (1<<32)-1
626            a = (0xDEAD4BAD * seed) & mask
627            b = 1
628            out = bytearray(length)
629            for i in range(length):
630                t = (a + b) & mask
631                a, b = b, t
632                out[i] = (t >> 24) & 0xFF
633            return out
634        outer = constructor(digest_size=32)
635        for outlen in md_len:
636            for inlen in in_len:
637                indata = selftest_seq(inlen, inlen)
638                key = selftest_seq(outlen, outlen)
639                unkeyed = constructor(indata, digest_size=outlen)
640                outer.update(unkeyed.digest())
641                keyed = constructor(indata, key=key, digest_size=outlen)
642                outer.update(keyed.digest())
643        return outer.hexdigest()
644
645    @requires_blake2
646    def test_blake2b(self):
647        self.check_blake2(hashlib.blake2b, 16, 16, 64, 64, (1<<64)-1)
648        b2b_md_len = [20, 32, 48, 64]
649        b2b_in_len = [0, 3, 128, 129, 255, 1024]
650        self.assertEqual(
651            self.blake2_rfc7693(hashlib.blake2b, b2b_md_len, b2b_in_len),
652            "c23a7800d98123bd10f506c61e29da5603d763b8bbad2e737f5e765a7bccd475")
653
654    @requires_blake2
655    def test_case_blake2b_0(self):
656        self.check('blake2b', b"",
657          "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419"+
658          "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce")
659
660    @requires_blake2
661    def test_case_blake2b_1(self):
662        self.check('blake2b', b"abc",
663          "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1"+
664          "7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923")
665
666    @requires_blake2
667    def test_case_blake2b_all_parameters(self):
668        # This checks that all the parameters work in general, and also that
669        # parameter byte order doesn't get confused on big endian platforms.
670        self.check('blake2b', b"foo",
671          "920568b0c5873b2f0ab67bedb6cf1b2b",
672          digest_size=16,
673          key=b"bar",
674          salt=b"baz",
675          person=b"bing",
676          fanout=2,
677          depth=3,
678          leaf_size=4,
679          node_offset=5,
680          node_depth=6,
681          inner_size=7,
682          last_node=True)
683
684    @requires_blake2
685    def test_blake2b_vectors(self):
686        for msg, key, md in read_vectors('blake2b'):
687            key = bytes.fromhex(key)
688            self.check('blake2b', msg, md, key=key)
689
690    @requires_blake2
691    def test_blake2s(self):
692        self.check_blake2(hashlib.blake2s, 8, 8, 32, 32, (1<<48)-1)
693        b2s_md_len = [16, 20, 28, 32]
694        b2s_in_len = [0, 3, 64, 65, 255, 1024]
695        self.assertEqual(
696            self.blake2_rfc7693(hashlib.blake2s, b2s_md_len, b2s_in_len),
697            "6a411f08ce25adcdfb02aba641451cec53c598b24f4fc787fbdc88797f4c1dfe")
698
699    @requires_blake2
700    def test_case_blake2s_0(self):
701        self.check('blake2s', b"",
702          "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9")
703
704    @requires_blake2
705    def test_case_blake2s_1(self):
706        self.check('blake2s', b"abc",
707          "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982")
708
709    @requires_blake2
710    def test_case_blake2s_all_parameters(self):
711        # This checks that all the parameters work in general, and also that
712        # parameter byte order doesn't get confused on big endian platforms.
713        self.check('blake2s', b"foo",
714          "bf2a8f7fe3c555012a6f8046e646bc75",
715          digest_size=16,
716          key=b"bar",
717          salt=b"baz",
718          person=b"bing",
719          fanout=2,
720          depth=3,
721          leaf_size=4,
722          node_offset=5,
723          node_depth=6,
724          inner_size=7,
725          last_node=True)
726
727    @requires_blake2
728    def test_blake2s_vectors(self):
729        for msg, key, md in read_vectors('blake2s'):
730            key = bytes.fromhex(key)
731            self.check('blake2s', msg, md, key=key)
732
733    @requires_sha3
734    def test_case_sha3_224_0(self):
735        self.check('sha3_224', b"",
736          "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7")
737
738    @requires_sha3
739    def test_case_sha3_224_vector(self):
740        for msg, md in read_vectors('sha3_224'):
741            self.check('sha3_224', msg, md)
742
743    @requires_sha3
744    def test_case_sha3_256_0(self):
745        self.check('sha3_256', b"",
746          "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a")
747
748    @requires_sha3
749    def test_case_sha3_256_vector(self):
750        for msg, md in read_vectors('sha3_256'):
751            self.check('sha3_256', msg, md)
752
753    @requires_sha3
754    def test_case_sha3_384_0(self):
755        self.check('sha3_384', b"",
756          "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"+
757          "c3713831264adb47fb6bd1e058d5f004")
758
759    @requires_sha3
760    def test_case_sha3_384_vector(self):
761        for msg, md in read_vectors('sha3_384'):
762            self.check('sha3_384', msg, md)
763
764    @requires_sha3
765    def test_case_sha3_512_0(self):
766        self.check('sha3_512', b"",
767          "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"+
768          "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26")
769
770    @requires_sha3
771    def test_case_sha3_512_vector(self):
772        for msg, md in read_vectors('sha3_512'):
773            self.check('sha3_512', msg, md)
774
775    @requires_sha3
776    def test_case_shake_128_0(self):
777        self.check('shake_128', b"",
778          "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26",
779          True)
780        self.check('shake_128', b"", "7f9c", True)
781
782    @requires_sha3
783    def test_case_shake128_vector(self):
784        for msg, md in read_vectors('shake_128'):
785            self.check('shake_128', msg, md, True)
786
787    @requires_sha3
788    def test_case_shake_256_0(self):
789        self.check('shake_256', b"",
790          "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f",
791          True)
792        self.check('shake_256', b"", "46b9", True)
793
794    @requires_sha3
795    def test_case_shake256_vector(self):
796        for msg, md in read_vectors('shake_256'):
797            self.check('shake_256', msg, md, True)
798
799    def test_gil(self):
800        # Check things work fine with an input larger than the size required
801        # for multithreaded operation (which is hardwired to 2048).
802        gil_minsize = 2048
803
804        for cons in self.hash_constructors:
805            m = cons()
806            m.update(b'1')
807            m.update(b'#' * gil_minsize)
808            m.update(b'1')
809
810            m = cons(b'x' * gil_minsize)
811            m.update(b'1')
812
813        m = hashlib.md5()
814        m.update(b'1')
815        m.update(b'#' * gil_minsize)
816        m.update(b'1')
817        self.assertEqual(m.hexdigest(), 'cb1e1a2cbc80be75e19935d621fb9b21')
818
819        m = hashlib.md5(b'x' * gil_minsize)
820        self.assertEqual(m.hexdigest(), 'cfb767f225d58469c5de3632a8803958')
821
822    @support.reap_threads
823    def test_threaded_hashing(self):
824        # Updating the same hash object from several threads at once
825        # using data chunk sizes containing the same byte sequences.
826        #
827        # If the internal locks are working to prevent multiple
828        # updates on the same object from running at once, the resulting
829        # hash will be the same as doing it single threaded upfront.
830        hasher = hashlib.sha1()
831        num_threads = 5
832        smallest_data = b'swineflu'
833        data = smallest_data * 200000
834        expected_hash = hashlib.sha1(data*num_threads).hexdigest()
835
836        def hash_in_chunks(chunk_size):
837            index = 0
838            while index < len(data):
839                hasher.update(data[index:index + chunk_size])
840                index += chunk_size
841
842        threads = []
843        for threadnum in range(num_threads):
844            chunk_size = len(data) // (10 ** threadnum)
845            self.assertGreater(chunk_size, 0)
846            self.assertEqual(chunk_size % len(smallest_data), 0)
847            thread = threading.Thread(target=hash_in_chunks,
848                                      args=(chunk_size,))
849            threads.append(thread)
850
851        for thread in threads:
852            thread.start()
853        for thread in threads:
854            thread.join()
855
856        self.assertEqual(expected_hash, hasher.hexdigest())
857
858
859class KDFTests(unittest.TestCase):
860
861    pbkdf2_test_vectors = [
862        (b'password', b'salt', 1, None),
863        (b'password', b'salt', 2, None),
864        (b'password', b'salt', 4096, None),
865        # too slow, it takes over a minute on a fast CPU.
866        #(b'password', b'salt', 16777216, None),
867        (b'passwordPASSWORDpassword', b'saltSALTsaltSALTsaltSALTsaltSALTsalt',
868         4096, -1),
869        (b'pass\0word', b'sa\0lt', 4096, 16),
870    ]
871
872    scrypt_test_vectors = [
873        (b'', b'', 16, 1, 1, unhexlify('77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906')),
874        (b'password', b'NaCl', 1024, 8, 16, unhexlify('fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640')),
875        (b'pleaseletmein', b'SodiumChloride', 16384, 8, 1, unhexlify('7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887')),
876   ]
877
878    pbkdf2_results = {
879        "sha1": [
880            # official test vectors from RFC 6070
881            (bytes.fromhex('0c60c80f961f0e71f3a9b524af6012062fe037a6'), None),
882            (bytes.fromhex('ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'), None),
883            (bytes.fromhex('4b007901b765489abead49d926f721d065a429c1'), None),
884            #(bytes.fromhex('eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'), None),
885            (bytes.fromhex('3d2eec4fe41c849b80c8d83662c0e44a8b291a964c'
886                           'f2f07038'), 25),
887            (bytes.fromhex('56fa6aa75548099dcc37d7f03425e0c3'), None),],
888        "sha256": [
889            (bytes.fromhex('120fb6cffcf8b32c43e7225256c4f837'
890                           'a86548c92ccc35480805987cb70be17b'), None),
891            (bytes.fromhex('ae4d0c95af6b46d32d0adff928f06dd0'
892                           '2a303f8ef3c251dfd6e2d85a95474c43'), None),
893            (bytes.fromhex('c5e478d59288c841aa530db6845c4c8d'
894                           '962893a001ce4e11a4963873aa98134a'), None),
895            #(bytes.fromhex('cf81c66fe8cfc04d1f31ecb65dab4089'
896            #               'f7f179e89b3b0bcb17ad10e3ac6eba46'), None),
897            (bytes.fromhex('348c89dbcbd32b2f32d814b8116e84cf2b17'
898                           '347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9'), 40),
899            (bytes.fromhex('89b69d0516f829893c696226650a8687'), None),],
900        "sha512": [
901            (bytes.fromhex('867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5'
902                           'd513554e1c8cf252c02d470a285a0501bad999bfe943c08f'
903                           '050235d7d68b1da55e63f73b60a57fce'), None),
904            (bytes.fromhex('e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f004071'
905                           '3f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82'
906                           'be67335c77a6068e04112754f27ccf4e'), None),
907            (bytes.fromhex('d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f8'
908                           '7f6902e072f457b5143f30602641b3d55cd335988cb36b84'
909                           '376060ecd532e039b742a239434af2d5'), None),
910            (bytes.fromhex('8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b8'
911                           '68c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30'
912                           '225c583a186cd82bd4daea9724a3d3b8'), 64),
913            (bytes.fromhex('9d9e9c4cd21fe4be24d5b8244c759665'), None),],
914    }
915
916    def _test_pbkdf2_hmac(self, pbkdf2):
917        for digest_name, results in self.pbkdf2_results.items():
918            for i, vector in enumerate(self.pbkdf2_test_vectors):
919                password, salt, rounds, dklen = vector
920                expected, overwrite_dklen = results[i]
921                if overwrite_dklen:
922                    dklen = overwrite_dklen
923                out = pbkdf2(digest_name, password, salt, rounds, dklen)
924                self.assertEqual(out, expected,
925                                 (digest_name, password, salt, rounds, dklen))
926                out = pbkdf2(digest_name, memoryview(password),
927                             memoryview(salt), rounds, dklen)
928                out = pbkdf2(digest_name, bytearray(password),
929                             bytearray(salt), rounds, dklen)
930                self.assertEqual(out, expected)
931                if dklen is None:
932                    out = pbkdf2(digest_name, password, salt, rounds)
933                    self.assertEqual(out, expected,
934                                     (digest_name, password, salt, rounds))
935
936        self.assertRaises(TypeError, pbkdf2, b'sha1', b'pass', b'salt', 1)
937        self.assertRaises(TypeError, pbkdf2, 'sha1', 'pass', 'salt', 1)
938        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', 0)
939        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', -1)
940        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', 1, 0)
941        self.assertRaises(ValueError, pbkdf2, 'sha1', b'pass', b'salt', 1, -1)
942        with self.assertRaisesRegex(ValueError, 'unsupported hash type'):
943            pbkdf2('unknown', b'pass', b'salt', 1)
944        out = pbkdf2(hash_name='sha1', password=b'password', salt=b'salt',
945            iterations=1, dklen=None)
946        self.assertEqual(out, self.pbkdf2_results['sha1'][0][0])
947
948    def test_pbkdf2_hmac_py(self):
949        self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac)
950
951    @unittest.skipUnless(hasattr(c_hashlib, 'pbkdf2_hmac'),
952                     '   test requires OpenSSL > 1.0')
953    def test_pbkdf2_hmac_c(self):
954        self._test_pbkdf2_hmac(c_hashlib.pbkdf2_hmac)
955
956
957    @unittest.skipUnless(hasattr(c_hashlib, 'scrypt'),
958                     '   test requires OpenSSL > 1.1')
959    def test_scrypt(self):
960        for password, salt, n, r, p, expected in self.scrypt_test_vectors:
961            result = hashlib.scrypt(password, salt=salt, n=n, r=r, p=p)
962            self.assertEqual(result, expected)
963
964        # this values should work
965        hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1)
966        # password and salt must be bytes-like
967        with self.assertRaises(TypeError):
968            hashlib.scrypt('password', salt=b'salt', n=2, r=8, p=1)
969        with self.assertRaises(TypeError):
970            hashlib.scrypt(b'password', salt='salt', n=2, r=8, p=1)
971        # require keyword args
972        with self.assertRaises(TypeError):
973            hashlib.scrypt(b'password')
974        with self.assertRaises(TypeError):
975            hashlib.scrypt(b'password', b'salt')
976        with self.assertRaises(TypeError):
977            hashlib.scrypt(b'password', 2, 8, 1, salt=b'salt')
978        for n in [-1, 0, 1, None]:
979            with self.assertRaises((ValueError, OverflowError, TypeError)):
980                hashlib.scrypt(b'password', salt=b'salt', n=n, r=8, p=1)
981        for r in [-1, 0, None]:
982            with self.assertRaises((ValueError, OverflowError, TypeError)):
983                hashlib.scrypt(b'password', salt=b'salt', n=2, r=r, p=1)
984        for p in [-1, 0, None]:
985            with self.assertRaises((ValueError, OverflowError, TypeError)):
986                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=p)
987        for maxmem in [-1, None]:
988            with self.assertRaises((ValueError, OverflowError, TypeError)):
989                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1,
990                               maxmem=maxmem)
991        for dklen in [-1, None]:
992            with self.assertRaises((ValueError, OverflowError, TypeError)):
993                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1,
994                               dklen=dklen)
995
996    def test_normalized_name(self):
997        self.assertNotIn("blake2b512", hashlib.algorithms_available)
998        self.assertNotIn("sha3-512", hashlib.algorithms_available)
999
1000
1001if __name__ == "__main__":
1002    unittest.main()
1003