Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c4ab110

Browse files
committed
Issue #18775: Add name and block_size attribute to HMAC object. They now
provide the same API elements as non-keyed cryptographic hash functions.
1 parent 634919a commit c4ab110

4 files changed

Lines changed: 59 additions & 6 deletions

File tree

Doc/library/hmac.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,25 @@ An HMAC object has the following methods:
7979
compute the digests of strings that share a common initial substring.
8080

8181

82+
A hash object has the following attributes:
83+
84+
.. attribute:: HMAC.digest_size
85+
86+
The size of the resulting HMAC digest in bytes.
87+
88+
.. attribute:: HMAC.block_size
89+
90+
The internal block size of the hash algorithm in bytes.
91+
92+
.. versionadded:: 3.4
93+
94+
.. attribute:: HMAC.name
95+
96+
The canonical name of this HMAC, always lowercase, e.g. ``hmac-md5``.
97+
98+
.. versionadded:: 3.4
99+
100+
82101
This module also provides the following helper function:
83102

84103
.. function:: compare_digest(a, b)

Lib/hmac.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ def __init__(self, key, msg = None, digestmod = None):
7070
RuntimeWarning, 2)
7171
blocksize = self.blocksize
7272

73+
# self.blocksize is the default blocksize. self.block_size is
74+
# effective block size as well as the public API attribute.
75+
self.block_size = blocksize
76+
7377
if len(key) > blocksize:
7478
key = self.digest_cons(key).digest()
7579

@@ -79,6 +83,10 @@ def __init__(self, key, msg = None, digestmod = None):
7983
if msg is not None:
8084
self.update(msg)
8185

86+
@property
87+
def name(self):
88+
return "hmac-" + self.inner.name
89+
8290
def update(self, msg):
8391
"""Update this hashing object with the string msg.
8492
"""

Lib/test/test_hmac.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ def test_md5_vectors(self):
1212
def md5test(key, data, digest):
1313
h = hmac.HMAC(key, data, digestmod=hashlib.md5)
1414
self.assertEqual(h.hexdigest().upper(), digest.upper())
15+
self.assertEqual(h.name, "hmac-md5")
16+
self.assertEqual(h.digest_size, 16)
17+
self.assertEqual(h.block_size, 64)
18+
1519
h = hmac.HMAC(key, data, digestmod='md5')
1620
self.assertEqual(h.hexdigest().upper(), digest.upper())
21+
self.assertEqual(h.name, "hmac-md5")
22+
self.assertEqual(h.digest_size, 16)
23+
self.assertEqual(h.block_size, 64)
24+
1725

1826
md5test(b"\x0b" * 16,
1927
b"Hi There",
@@ -48,8 +56,15 @@ def test_sha_vectors(self):
4856
def shatest(key, data, digest):
4957
h = hmac.HMAC(key, data, digestmod=hashlib.sha1)
5058
self.assertEqual(h.hexdigest().upper(), digest.upper())
59+
self.assertEqual(h.name, "hmac-sha1")
60+
self.assertEqual(h.digest_size, 20)
61+
self.assertEqual(h.block_size, 64)
62+
5163
h = hmac.HMAC(key, data, digestmod='sha1')
5264
self.assertEqual(h.hexdigest().upper(), digest.upper())
65+
self.assertEqual(h.name, "hmac-sha1")
66+
self.assertEqual(h.digest_size, 20)
67+
self.assertEqual(h.block_size, 64)
5368

5469

5570
shatest(b"\x0b" * 20,
@@ -81,12 +96,20 @@ def shatest(key, data, digest):
8196
b"and Larger Than One Block-Size Data"),
8297
"e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
8398

84-
def _rfc4231_test_cases(self, hashfunc, hashname):
99+
def _rfc4231_test_cases(self, hashfunc, hash_name, digest_size, block_size):
85100
def hmactest(key, data, hexdigests):
101+
hmac_name = "hmac-" + hash_name
86102
h = hmac.HMAC(key, data, digestmod=hashfunc)
87103
self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
88-
h = hmac.HMAC(key, data, digestmod=hashname)
104+
self.assertEqual(h.name, hmac_name)
105+
self.assertEqual(h.digest_size, digest_size)
106+
self.assertEqual(h.block_size, block_size)
107+
108+
h = hmac.HMAC(key, data, digestmod=hash_name)
89109
self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
110+
self.assertEqual(h.name, hmac_name)
111+
self.assertEqual(h.digest_size, digest_size)
112+
self.assertEqual(h.block_size, block_size)
90113

91114

92115
# 4.2. Test Case 1
@@ -197,16 +220,16 @@ def hmactest(key, data, hexdigests):
197220
})
198221

199222
def test_sha224_rfc4231(self):
200-
self._rfc4231_test_cases(hashlib.sha224, 'sha224')
223+
self._rfc4231_test_cases(hashlib.sha224, 'sha224', 28, 64)
201224

202225
def test_sha256_rfc4231(self):
203-
self._rfc4231_test_cases(hashlib.sha256, 'sha256')
226+
self._rfc4231_test_cases(hashlib.sha256, 'sha256', 32, 64)
204227

205228
def test_sha384_rfc4231(self):
206-
self._rfc4231_test_cases(hashlib.sha384, 'sha384')
229+
self._rfc4231_test_cases(hashlib.sha384, 'sha384', 48, 128)
207230

208231
def test_sha512_rfc4231(self):
209-
self._rfc4231_test_cases(hashlib.sha512, 'sha512')
232+
self._rfc4231_test_cases(hashlib.sha512, 'sha512', 64, 128)
210233

211234
def test_legacy_block_size_warnings(self):
212235
class MockCrazyHash(object):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ Core and Builtins
5959
Library
6060
-------
6161

62+
- Issue #18775: Add name and block_size attribute to HMAC object. They now
63+
provide the same API elements as non-keyed cryptographic hash functions.
64+
6265
- Issue #17276: MD5 as default digestmod for HMAC is deprecated. The HMAC
6366
module supports digestmod names, e.g. hmac.HMAC('sha1').
6467

0 commit comments

Comments
 (0)