diff -r 646c2388d8f5 Doc/library/hmac.rst --- a/Doc/library/hmac.rst Sun Aug 18 12:43:24 2013 +0200 +++ b/Doc/library/hmac.rst Sun Aug 18 18:28:27 2013 +0200 @@ -72,6 +72,25 @@ compute the digests of strings that share a common initial substring. +A hash object has the following attributes: + +.. attribute:: HMAC.digest_size + + The size of the resulting HMAC digest in bytes. + +.. attribute:: HMAC.block_size + + The internal block size of the hash algorithm in bytes. + + .. versionadded:: 3.4 + +.. attribute:: HMAC.name + + The canonical name of this HMAC, always lowercase, e.g. ``hmac-md5``. + + .. versionadded:: 3.4 + + This module also provides the following helper function: .. function:: compare_digest(a, b) diff -r 646c2388d8f5 Lib/hmac.py --- a/Lib/hmac.py Sun Aug 18 12:43:24 2013 +0200 +++ b/Lib/hmac.py Sun Aug 18 18:28:27 2013 +0200 @@ -63,6 +63,10 @@ RuntimeWarning, 2) blocksize = self.blocksize + # self.blocksize is the default blocksize. self.block_size is + # effective block size as well as the public API attribute. + self.block_size = blocksize + if len(key) > blocksize: key = self.digest_cons(key).digest() @@ -72,6 +76,10 @@ if msg is not None: self.update(msg) + @property + def name(self): + return "hmac-" + self.inner.name + def update(self, msg): """Update this hashing object with the string msg. """ diff -r 646c2388d8f5 Lib/test/test_hmac.py --- a/Lib/test/test_hmac.py Sun Aug 18 12:43:24 2013 +0200 +++ b/Lib/test/test_hmac.py Sun Aug 18 18:28:27 2013 +0200 @@ -11,6 +11,9 @@ def md5test(key, data, digest): h = hmac.HMAC(key, data) + self.assertEqual(h.name, "hmac-md5") + self.assertEqual(h.digest_size, 16) + self.assertEqual(h.block_size, 64) self.assertEqual(h.hexdigest().upper(), digest.upper()) md5test(b"\x0b" * 16, @@ -45,6 +48,9 @@ def test_sha_vectors(self): def shatest(key, data, digest): h = hmac.HMAC(key, data, digestmod=hashlib.sha1) + self.assertEqual(h.name, "hmac-sha1") + self.assertEqual(h.digest_size, 20) + self.assertEqual(h.block_size, 64) self.assertEqual(h.hexdigest().upper(), digest.upper()) shatest(b"\x0b" * 20, @@ -76,9 +82,12 @@ b"and Larger Than One Block-Size Data"), "e8e99d0f45237d786d6bbaa7965c7808bbff1a91") - def _rfc4231_test_cases(self, hashfunc): + def _rfc4231_test_cases(self, hashfunc, hmac_name, digest_size, block_size): def hmactest(key, data, hexdigests): h = hmac.HMAC(key, data, digestmod=hashfunc) + self.assertEqual(h.name, hmac_name) + self.assertEqual(h.digest_size, digest_size) + self.assertEqual(h.block_size, block_size) self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc]) # 4.2. Test Case 1 @@ -189,16 +198,16 @@ }) def test_sha224_rfc4231(self): - self._rfc4231_test_cases(hashlib.sha224) + self._rfc4231_test_cases(hashlib.sha224, "hmac-sha224", 28, 64) def test_sha256_rfc4231(self): - self._rfc4231_test_cases(hashlib.sha256) + self._rfc4231_test_cases(hashlib.sha256, "hmac-sha256", 32, 64) def test_sha384_rfc4231(self): - self._rfc4231_test_cases(hashlib.sha384) + self._rfc4231_test_cases(hashlib.sha384, "hmac-sha384", 48, 128) def test_sha512_rfc4231(self): - self._rfc4231_test_cases(hashlib.sha512) + self._rfc4231_test_cases(hashlib.sha512, "hmac-sha512", 64, 128) def test_legacy_block_size_warnings(self): class MockCrazyHash(object):