Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(27716)

Delta Between Two Patch Sets: Lib/test/test_hashlib.py

Issue 16113: Add SHA-3 (Keccak) support
Left Patch Set: Created 3 years, 4 months ago
Right Patch Set: Created 3 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/hashlib.py ('k') | Modules/hashlib.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Test hashlib module 1 # Test hashlib module
2 # 2 #
3 # $Id$ 3 # $Id$
4 # 4 #
5 # Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org) 5 # Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org)
6 # Licensed to PSF under a Contributor Agreement. 6 # Licensed to PSF under a Contributor Agreement.
7 # 7 #
8 8
9 import array 9 import array
10 import hashlib 10 import hashlib
(...skipping 25 matching lines...) Expand all
36 36
37 def hexstr(s): 37 def hexstr(s):
38 assert isinstance(s, bytes), repr(s) 38 assert isinstance(s, bytes), repr(s)
39 h = "0123456789abcdef" 39 h = "0123456789abcdef"
40 r = '' 40 r = ''
41 for i in s: 41 for i in s:
42 r += h[(i >> 4) & 0xF] + h[i & 0xF] 42 r += h[(i >> 4) & 0xF] + h[i & 0xF]
43 return r 43 return r
44 44
45 45
46 URL = "https://raw.githubusercontent.com/tiran/python_vectors/master/{}.txt"
47
46 def read_vectors(hash_name): 48 def read_vectors(hash_name):
47 vector = os.path.join(support.TEST_HOME_DIR, 'vectors', 49 with support.open_urlresource(URL.format(hash_name)) as f:
48 hash_name + '.txt')
49 with open(vector) as f:
50 for line in f: 50 for line in f:
51 line = line.strip() 51 line = line.strip()
52 if line.startswith('#') or not line: 52 if line.startswith('#') or not line:
53 continue 53 continue
54 msg, md = line.split(',') 54 msg, md = line.split(',')
55 yield bytes.fromhex(msg), md 55 yield bytes.fromhex(msg), md
56 56
57 57
58 class HashLibTestCase(unittest.TestCase): 58 class HashLibTestCase(unittest.TestCase):
59 supported_hash_names = {'md5', 'MD5', 'sha1', 'SHA1', 59 supported_hash_names = {'md5', 'MD5', 'sha1', 'SHA1',
60 'sha224', 'SHA224', 'sha256', 'SHA256', 60 'sha224', 'SHA224', 'sha256', 'SHA256',
61 'sha384', 'SHA384', 'sha512', 'SHA512'} 61 'sha384', 'SHA384', 'sha512', 'SHA512',
62 62 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
63 sha3_hash_names = {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 63 'shake_128', 'shake_256'}
64 'shake_128', 'shake_256'}
65 64
66 shakes = {'shake_128', 'shake_256'} 65 shakes = {'shake_128', 'shake_256'}
67 66
68 # Issue #14693: fallback modules are always compiled under POSIX 67 # Issue #14693: fallback modules are always compiled under POSIX
69 _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG 68 _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG
70 69
71 def _conditional_import_module(self, module_name): 70 def _conditional_import_module(self, module_name):
72 """Import a module and return a reference to it or None on failure.""" 71 """Import a module and return a reference to it or None on failure."""
73 try: 72 try:
74 exec('import '+module_name) 73 exec('import '+module_name)
75 except ImportError as error: 74 except ImportError as error:
76 if self._warn_on_extension_import: 75 if self._warn_on_extension_import:
77 warnings.warn('Did a C extension fail to compile? %s' % error) 76 warnings.warn('Did a C extension fail to compile? %s' % error)
78 return locals().get(module_name) 77 return locals().get(module_name)
79 78
80 def __init__(self, *args, **kwargs): 79 def __init__(self, *args, **kwargs):
81 algorithms = set() 80 algorithms = set()
82 for algorithm in self.supported_hash_names: 81 for algorithm in self.supported_hash_names:
83 algorithms.add(algorithm.lower()) 82 algorithms.add(algorithm.lower())
84
85 _sha3 = self._conditional_import_module('_sha3')
86 if _sha3:
87 for algorithm in self.sha3_hash_names:
88 algorithms.add(algorithm.lower())
89 83
90 self.constructors_to_test = {} 84 self.constructors_to_test = {}
91 for algorithm in algorithms: 85 for algorithm in algorithms:
92 self.constructors_to_test[algorithm] = set() 86 self.constructors_to_test[algorithm] = set()
93 87
94 # For each algorithm, test the direct constructor and the use 88 # For each algorithm, test the direct constructor and the use
95 # of hashlib.new given the algorithm name. 89 # of hashlib.new given the algorithm name.
96 for algorithm, constructors in self.constructors_to_test.items(): 90 for algorithm, constructors in self.constructors_to_test.items():
97 constructors.add(getattr(hashlib, algorithm)) 91 constructors.add(getattr(hashlib, algorithm))
98 def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm): 92 def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm):
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 287
294 def check_blocksize_name(self, name, block_size=0, digest_size=0, 288 def check_blocksize_name(self, name, block_size=0, digest_size=0,
295 digest_length=None): 289 digest_length=None):
296 constructors = self.constructors_to_test[name] 290 constructors = self.constructors_to_test[name]
297 for hash_object_constructor in constructors: 291 for hash_object_constructor in constructors:
298 m = hash_object_constructor() 292 m = hash_object_constructor()
299 self.assertEqual(m.block_size, block_size) 293 self.assertEqual(m.block_size, block_size)
300 self.assertEqual(m.digest_size, digest_size) 294 self.assertEqual(m.digest_size, digest_size)
301 if digest_length: 295 if digest_length:
302 self.assertEqual(len(m.digest(digest_length)), 296 self.assertEqual(len(m.digest(digest_length)),
303 digest_size) 297 digest_length)
304 self.assertEqual(len(m.hexdigest(digest_length)), 298 self.assertEqual(len(m.hexdigest(digest_length)),
305 2*digest_size) 299 2*digest_length)
306 else: 300 else:
307 self.assertEqual(len(m.digest()), digest_size) 301 self.assertEqual(len(m.digest()), digest_size)
308 self.assertEqual(len(m.hexdigest()), 2*digest_size) 302 self.assertEqual(len(m.hexdigest()), 2*digest_size)
309 self.assertEqual(m.name, name) 303 self.assertEqual(m.name, name)
310 # split for sha3_512 / _sha3.sha3 object 304 # split for sha3_512 / _sha3.sha3 object
311 self.assertIn(name.split("_")[0], repr(m)) 305 self.assertIn(name.split("_")[0], repr(m))
312 306
313 def test_blocksize_name(self): 307 def test_blocksize_name(self):
314 self.check_blocksize_name('md5', 64, 16) 308 self.check_blocksize_name('md5', 64, 16)
315 self.check_blocksize_name('sha1', 64, 20) 309 self.check_blocksize_name('sha1', 64, 20)
316 self.check_blocksize_name('sha224', 64, 28) 310 self.check_blocksize_name('sha224', 64, 28)
317 self.check_blocksize_name('sha256', 64, 32) 311 self.check_blocksize_name('sha256', 64, 32)
318 self.check_blocksize_name('sha384', 128, 48) 312 self.check_blocksize_name('sha384', 128, 48)
319 self.check_blocksize_name('sha512', 128, 64) 313 self.check_blocksize_name('sha512', 128, 64)
320 #self.check_blocksize_name('sha3_224', 128, 64) 314 self.check_blocksize_name('sha3_224', 144, 28)
321 #self.check_blocksize_name('sha3_256', 128, 64) 315 self.check_blocksize_name('sha3_256', 136, 32)
322 #self.check_blocksize_name('sha3_384', 128, 64) 316 self.check_blocksize_name('sha3_384', 104, 48)
323 #self.check_blocksize_name('sha3_512', 128, 64) 317 self.check_blocksize_name('sha3_512', 72, 64)
318 self.check_blocksize_name('shake_128', 168, 0, 32)
319 self.check_blocksize_name('shake_256', 136, 0, 64)
324 320
325 def test_case_md5_0(self): 321 def test_case_md5_0(self):
326 self.check('md5', b'', 'd41d8cd98f00b204e9800998ecf8427e') 322 self.check('md5', b'', 'd41d8cd98f00b204e9800998ecf8427e')
327 323
328 def test_case_md5_1(self): 324 def test_case_md5_1(self):
329 self.check('md5', b'abc', '900150983cd24fb0d6963f7d28e17f72') 325 self.check('md5', b'abc', '900150983cd24fb0d6963f7d28e17f72')
330 326
331 def test_case_md5_2(self): 327 def test_case_md5_2(self):
332 self.check('md5', 328 self.check('md5',
333 b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456 789', 329 b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456 789',
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 502
507 @requires_sha3 503 @requires_sha3
508 def test_case_shake_256_0(self): 504 def test_case_shake_256_0(self):
509 self.check('shake_256', b"", 505 self.check('shake_256', b"",
510 "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f", 506 "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f",
511 True) 507 True)
512 self.check('shake_256', b"", "46b9", True) 508 self.check('shake_256', b"", "46b9", True)
513 509
514 @requires_sha3 510 @requires_sha3
515 def test_case_shake128_vector(self): 511 def test_case_shake128_vector(self):
516 for msg, md in read_vectors('shake_256'): 512 for msg, md in read_vectors('shake_128'):
517 self.check('shake_256', msg, md, True) 513 self.check('shake_128', msg, md, True)
518 514
519 def test_gil(self): 515 def test_gil(self):
520 # Check things work fine with an input larger than the size required 516 # Check things work fine with an input larger than the size required
521 # for multithreaded operation (which is hardwired to 2048). 517 # for multithreaded operation (which is hardwired to 2048).
522 gil_minsize = 2048 518 gil_minsize = 2048
523 519
524 for cons in self.hash_constructors: 520 for cons in self.hash_constructors:
525 m = cons() 521 m = cons()
526 m.update(b'1') 522 m.update(b'1')
527 m.update(b'#' * gil_minsize) 523 m.update(b'#' * gil_minsize)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 (b'password', b'salt', 4096, None), 581 (b'password', b'salt', 4096, None),
586 # too slow, it takes over a minute on a fast CPU. 582 # too slow, it takes over a minute on a fast CPU.
587 #(b'password', b'salt', 16777216, None), 583 #(b'password', b'salt', 16777216, None),
588 (b'passwordPASSWORDpassword', b'saltSALTsaltSALTsaltSALTsaltSALTsalt', 584 (b'passwordPASSWORDpassword', b'saltSALTsaltSALTsaltSALTsaltSALTsalt',
589 4096, -1), 585 4096, -1),
590 (b'pass\0word', b'sa\0lt', 4096, 16), 586 (b'pass\0word', b'sa\0lt', 4096, 16),
591 ] 587 ]
592 588
593 pbkdf2_results = { 589 pbkdf2_results = {
594 "sha1": [ 590 "sha1": [
595 # offical test vectors from RFC 6070 591 # official test vectors from RFC 6070
596 (bytes.fromhex('0c60c80f961f0e71f3a9b524af6012062fe037a6'), None), 592 (bytes.fromhex('0c60c80f961f0e71f3a9b524af6012062fe037a6'), None),
597 (bytes.fromhex('ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'), None), 593 (bytes.fromhex('ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'), None),
598 (bytes.fromhex('4b007901b765489abead49d926f721d065a429c1'), None), 594 (bytes.fromhex('4b007901b765489abead49d926f721d065a429c1'), None),
599 #(bytes.fromhex('eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'), None), 595 #(bytes.fromhex('eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'), None),
600 (bytes.fromhex('3d2eec4fe41c849b80c8d83662c0e44a8b291a964c' 596 (bytes.fromhex('3d2eec4fe41c849b80c8d83662c0e44a8b291a964c'
601 'f2f07038'), 25), 597 'f2f07038'), 25),
602 (bytes.fromhex('56fa6aa75548099dcc37d7f03425e0c3'), None),], 598 (bytes.fromhex('56fa6aa75548099dcc37d7f03425e0c3'), None),],
603 "sha256": [ 599 "sha256": [
604 (bytes.fromhex('120fb6cffcf8b32c43e7225256c4f837' 600 (bytes.fromhex('120fb6cffcf8b32c43e7225256c4f837'
605 'a86548c92ccc35480805987cb70be17b'), None), 601 'a86548c92ccc35480805987cb70be17b'), None),
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac) 660 self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac)
665 661
666 @unittest.skipUnless(hasattr(c_hashlib, 'pbkdf2_hmac'), 662 @unittest.skipUnless(hasattr(c_hashlib, 'pbkdf2_hmac'),
667 ' test requires OpenSSL > 1.0') 663 ' test requires OpenSSL > 1.0')
668 def test_pbkdf2_hmac_c(self): 664 def test_pbkdf2_hmac_c(self):
669 self._test_pbkdf2_hmac(c_hashlib.pbkdf2_hmac) 665 self._test_pbkdf2_hmac(c_hashlib.pbkdf2_hmac)
670 666
671 667
672 if __name__ == "__main__": 668 if __name__ == "__main__":
673 unittest.main() 669 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+