HMAC algorithm implementation

I wanted to understand the HMAC algorithm. So, I implemented it as a Jupyter Notebook with all intermediate steps being output to console. My objective now is to improve it so it may serve as a reference to anyone trying to implement or understand it.

The Jupyter Notebook on github is easier to read and I would like feedback on the notebook rather than the code below.

Jupiter notebook on GitHub

import hashlib
import hmac

### Define key, message, Block size, hashing algorithm
hash_algo = "sha1"
B = 64
message = b'hello!'
key = b'key'

### hash () for an easy to read code
def hash(M):
H = hashlib.new(hash_algo)
H.update(M)
b_hash = H.digest()
return b_hash

### XOR Translation table
trans_5C = bytes((x ^ 0x5C) for x in range(256))
trans_36 = bytes((x ^ 0x36) for x in range(256))

### Zero pad key to block length B
# Xor with ipad and opad sequence

### concatinate message
print("key XOR ipad || message:\n"+part1.hex())

### hash (key xor ipad || message )
hash1=hash(part1)
print("hash( key XOR ipad || message):\n"+hash1.hex())

### hash (key xor opad || hash ( (key xor ipad)||message ) )
part2 = K_opad + hash1
print("hash (key xor opad || hash ( (key XOR ipad)||message ) ):\n"+part2.hex())
hash_final = hash(part2)
print("\n\nFinal Hash:\n"+hash_final.hex())

# Compare with Python's HMAC Implementation
pyH=hmac.new(key,message,digestmod=hash_algo)
pyH.hexdigest()

My objective now is to improve it so it may serve as a reference to anyone trying to implement or understand it.

In light of that goal I would have thought it made more sense to use the documented test vectors of RFC 2202 rather than make up your own one.

### hash (key xor opad || hash ( (key xor ipad)||message ) )
part2 = K_opad + hash1
print("hash (key xor opad || hash ( (key XOR ipad)||message ) ):\n"+part2.hex())
hash_final = hash(part2)
print("\n\nFinal Hash:\n"+hash_final.hex())

The comment and the first print describe hash_final, not part2. IMO this is a bug, albeit a minor one.

• hash_final = hash(part2) what is wrong? The comment and print are expanding the part1 in part2 as hash ( (key xor ipad)||message – Lord Loh. Aug 20 '18 at 14:22
• @LordLoh., what's wrong is print("hash ( – Peter Taylor Aug 20 '18 at 14:23
• I see. Thank you. I was unaware of RFC 2202. That is a good idea! – Lord Loh. Aug 20 '18 at 14:26