hmac.HMAC's flexibility comes with a cost. To create the MAC of a message, it has to create between three and four hash instances (inner, outer, key for long keys, result), multiple bound method objects and other temporary objects. For short messages, memory allocation, object handling and GIL release/acquire operations dominate the performance.
I propose to provide a fast one-shot HMAC function: hmac.digest(key, msg, digstmod) -> bytes function. A PoC implementation based on OpenSSL's HMAC() function and a pure Python implementation as inlined HMAC showed promising performance improvements. The C implementation is 3 times faster.
$ ./python -m timeit -n200000 -s "import hmac" -- "hmac.HMAC(b'key', b'message', 'sha256').digest()"
200000 loops, best of 5: 5.38 usec per loop
Optimized Python code:
$ ./python -m timeit -n 200000 -s "import hmac; hmac._hashopenssl = None" -- "hmac.digest(b'key', b'message', 'sha256')"
200000 loops, best of 5: 3.87 usec per loop
$ ./python -m timeit -n 200000 -s "import hmac" -- "hmac.digest(b'key', b'message', 'sha256')"
200000 loops, best of 5: 1.82 usec per loop
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
The text was updated successfully, but these errors were encountered: