package com.infendro.mac import com.infendro.bytes.bytearray.xorInto import com.infendro.hash.HashFunction class HMAC( val function: HashFunction, ) : MAC { override val bytes: Int get() = function.bytes override fun hashInto(key: ByteArray, value: ByteArray, destination: ByteArray, destinationOffset: Int) { val paddedKey = pad(key) val inner = ByteArray(function.block + value.size).also { paddedKey.xorInto(0x36, it) value.copyInto(it, function.block) } val outer = ByteArray(function.block + function.bytes).also { paddedKey.xorInto(0x5C, it) function.hashInto(inner, it, function.block) } function.hashInto(outer, destination, destinationOffset) } private fun pad(key: ByteArray): ByteArray = ByteArray(function.block).also { when { key.size > function.block -> function.hashInto(key, it) else -> key.copyInto(it) } } }