implement common class, refactor HMAC

This commit is contained in:
2025-11-10 14:54:19 +01:00
parent 045af38398
commit 9db4ee21a0
4 changed files with 39 additions and 30 deletions

View File

@@ -21,8 +21,13 @@ kotlin {
sourceSets { sourceSets {
commonMain.dependencies { commonMain.dependencies {
implementation(libs.hash) implementation(libs.hash)
implementation(libs.bytearray)
} }
} }
compilerOptions {
freeCompilerArgs.add("-opt-in=kotlin.ExperimentalUnsignedTypes")
}
} }
publishing { publishing {

View File

@@ -1,9 +1,11 @@
[versions] [versions]
kotlin = "2.1.20" kotlin = "2.1.20"
hash = "1.2.2" hash = "1.3.1"
bytearray = "1.2.0"
[plugins] [plugins]
multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
[libraries] [libraries]
hash = { module = "com.infendro:hash", version.ref = "hash" } hash = { module = "com.infendro:hash", version.ref = "hash" }
bytearray = { module = "com.infendro:bytearray", version.ref = "bytearray" }

View File

@@ -1,45 +1,33 @@
package com.infendro.mac package com.infendro.mac
import com.infendro.hash.* import com.infendro.bytearray.padEnd
import kotlin.experimental.xor import com.infendro.hash.HashFunction
class HMAC( class HMAC(
val function: HashFunction, val function: HashFunction,
) { ) : MAC() {
val block: Int override val bytes: Int
get() = when (function) { get() = function.bytes
MD5, SHA1, SHA224, SHA256 -> 64
SHA384, SHA512 -> 128
}
fun hash( override fun hash(
key: ByteArray, key: UByteArray,
value: ByteArray, value: UByteArray,
): ByteArray { ): UByteArray {
val paddedKey = pad(key) val paddedKey = pad(key)
val innerKey = paddedKey.map { it xor 0x36 }.toByteArray() val innerKey = paddedKey.map { it xor 0x36U }.toUByteArray()
val outerKey = paddedKey.map { it xor 0x5C }.toByteArray() val outerKey = paddedKey.map { it xor 0x5CU }.toUByteArray()
return function.hash(outerKey + function.hash(innerKey + value)) return function.hash(outerKey + function.hash(innerKey + value))
} }
private fun pad( private fun pad(
key: ByteArray, key: UByteArray,
): ByteArray { ): UByteArray {
if (key.size > block) { return when {
return function.hash(key) key.size > function.block -> function.hash(key)
} key.size < function.block -> key.padEnd(function.block, 0x00U)
else -> key
if (key.size < block) { }
return buildList {
addAll(key.toList())
repeat(block - size) {
add(0x00)
}
}.toByteArray()
}
return key
} }
} }

View File

@@ -0,0 +1,14 @@
package com.infendro.mac
abstract class MAC {
abstract val bytes: Int
@Suppress("UNUSED")
val bits: Int
get() = bytes * 8
abstract fun hash(
key: UByteArray,
value: UByteArray,
): UByteArray
}