#!/usr/bin/env python3

# ========================================================
#    This code is for study only.
#    This code is not optimized.
#    This code is over simplified.
#    This code doesn't respect rules of good coding.
#    This code has duplicate codes:
#        to understanding without complexity.
#    Some values -useless on code- will not be converted.
# ========================================================

import sys
import hmac
import hashlib

key  = bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16')
data = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')


# ------- HMAC library ---------
hash = hmac.new(
    key=key,
    msg=data,
    digestmod=hashlib.sha1
).digest()
print("REFERNC = %s" % hash.hex())

# ------- HMAC home-made --------
i_pad = bytearray(b'\x36' * 64)  # todo: unique byte
o_pad = bytearray(b'\x5C' * 64)  # todo: unique byte
i_key = bytearray(b'\x00' * 64)
o_key = bytearray(b'\x00' * 64)

# duplicate unique key (16B) into i_key & o_key (64B)
for i in range(0, 16):
    i_key[i] = o_key[i] = key[i]

# create i_key_pad & o_key_pad
for i in range(0, 64):
    i_key[i] ^= i_pad[i]
    o_key[i] ^= o_pad[i]

print("i_key   = %s" % i_key.hex())
print("o_key   = %s" % o_key.hex())

# 1st pass (SHA1)
hash_1 = hashlib.new(
    name='sha1',
    data=i_key + data
).digest()
print("HASH(1) = %s" % hash_1.hex())

# 2st pass (SHA1)
hash_2 = hashlib.new(
    name='sha1',
    data=o_key + hash_1
).digest()

print("HASH(2) = %s" % hash_2.hex())
