[Python-checkins] cpython: Issue #18775: Add name and block_size attribute to HMAC object. They now

christian.heimes python-checkins at python.org
Wed Nov 20 17:35:17 CET 2013


http://hg.python.org/cpython/rev/71f4a805d262
changeset:   87297:71f4a805d262
user:        Christian Heimes <christian at cheimes.de>
date:        Wed Nov 20 17:35:06 2013 +0100
summary:
  Issue #18775: Add name and block_size attribute to HMAC object. They now
provide the same API elements as non-keyed cryptographic hash functions.

files:
  Doc/library/hmac.rst  |  19 ++++++++++++++++
  Lib/hmac.py           |   8 +++++++
  Lib/test/test_hmac.py |  35 +++++++++++++++++++++++++-----
  Misc/NEWS             |   3 ++
  4 files changed, 59 insertions(+), 6 deletions(-)


diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst
--- a/Doc/library/hmac.rst
+++ b/Doc/library/hmac.rst
@@ -79,6 +79,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 --git a/Lib/hmac.py b/Lib/hmac.py
--- a/Lib/hmac.py
+++ b/Lib/hmac.py
@@ -70,6 +70,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()
 
@@ -79,6 +83,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 --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py
--- a/Lib/test/test_hmac.py
+++ b/Lib/test/test_hmac.py
@@ -12,8 +12,16 @@
         def md5test(key, data, digest):
             h = hmac.HMAC(key, data, digestmod=hashlib.md5)
             self.assertEqual(h.hexdigest().upper(), digest.upper())
+            self.assertEqual(h.name, "hmac-md5")
+            self.assertEqual(h.digest_size, 16)
+            self.assertEqual(h.block_size, 64)
+
             h = hmac.HMAC(key, data, digestmod='md5')
             self.assertEqual(h.hexdigest().upper(), digest.upper())
+            self.assertEqual(h.name, "hmac-md5")
+            self.assertEqual(h.digest_size, 16)
+            self.assertEqual(h.block_size, 64)
+
 
         md5test(b"\x0b" * 16,
                 b"Hi There",
@@ -48,8 +56,15 @@
         def shatest(key, data, digest):
             h = hmac.HMAC(key, data, digestmod=hashlib.sha1)
             self.assertEqual(h.hexdigest().upper(), digest.upper())
+            self.assertEqual(h.name, "hmac-sha1")
+            self.assertEqual(h.digest_size, 20)
+            self.assertEqual(h.block_size, 64)
+
             h = hmac.HMAC(key, data, digestmod='sha1')
             self.assertEqual(h.hexdigest().upper(), digest.upper())
+            self.assertEqual(h.name, "hmac-sha1")
+            self.assertEqual(h.digest_size, 20)
+            self.assertEqual(h.block_size, 64)
 
 
         shatest(b"\x0b" * 20,
@@ -81,12 +96,20 @@
                  b"and Larger Than One Block-Size Data"),
                 "e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
 
-    def _rfc4231_test_cases(self, hashfunc, hashname):
+    def _rfc4231_test_cases(self, hashfunc, hash_name, digest_size, block_size):
         def hmactest(key, data, hexdigests):
+            hmac_name = "hmac-" + hash_name
             h = hmac.HMAC(key, data, digestmod=hashfunc)
             self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
-            h = hmac.HMAC(key, data, digestmod=hashname)
+            self.assertEqual(h.name, hmac_name)
+            self.assertEqual(h.digest_size, digest_size)
+            self.assertEqual(h.block_size, block_size)
+
+            h = hmac.HMAC(key, data, digestmod=hash_name)
             self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
+            self.assertEqual(h.name, hmac_name)
+            self.assertEqual(h.digest_size, digest_size)
+            self.assertEqual(h.block_size, block_size)
 
 
         # 4.2.  Test Case 1
@@ -197,16 +220,16 @@
                  })
 
     def test_sha224_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha224, 'sha224')
+        self._rfc4231_test_cases(hashlib.sha224, 'sha224', 28, 64)
 
     def test_sha256_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha256, 'sha256')
+        self._rfc4231_test_cases(hashlib.sha256, 'sha256', 32, 64)
 
     def test_sha384_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha384, 'sha384')
+        self._rfc4231_test_cases(hashlib.sha384, 'sha384', 48, 128)
 
     def test_sha512_rfc4231(self):
-        self._rfc4231_test_cases(hashlib.sha512, 'sha512')
+        self._rfc4231_test_cases(hashlib.sha512, 'sha512', 64, 128)
 
     def test_legacy_block_size_warnings(self):
         class MockCrazyHash(object):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -59,6 +59,9 @@
 Library
 -------
 
+- Issue #18775: Add name and block_size attribute to HMAC object. They now
+  provide the same API elements as non-keyed cryptographic hash functions.
+
 - Issue #17276: MD5 as default digestmod for HMAC is deprecated. The HMAC
   module supports digestmod names, e.g. hmac.HMAC('sha1').
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list