From c047b04d95ddee3874582310864205f635d07079 Mon Sep 17 00:00:00 2001 From: Infendro Date: Sun, 20 Jul 2025 10:43:05 +0200 Subject: [PATCH] implement PBKDF2 --- gradle/libs.versions.toml | 2 +- .../kotlin/com/infendro/kdf/PBKDF2.kt | 45 +++++++++++++++++++ .../kotlin/com/infendro/kdf/util/ByteArray.kt | 26 +++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/commonMain/kotlin/com/infendro/kdf/PBKDF2.kt create mode 100644 src/commonMain/kotlin/com/infendro/kdf/util/ByteArray.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ed7967b..aa2fdd9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] kotlin = "2.1.20" mac = "1.1.0" -hash = "1.1.0" +hash = "1.2.0" [plugins] multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } diff --git a/src/commonMain/kotlin/com/infendro/kdf/PBKDF2.kt b/src/commonMain/kotlin/com/infendro/kdf/PBKDF2.kt new file mode 100644 index 0000000..95f4625 --- /dev/null +++ b/src/commonMain/kotlin/com/infendro/kdf/PBKDF2.kt @@ -0,0 +1,45 @@ +package com.infendro.kdf + +import com.infendro.hash.HashFunction +import com.infendro.kdf.util.addAll +import com.infendro.kdf.util.toByteArray +import com.infendro.kdf.util.xor +import com.infendro.mac.HMAC + +class PBKDF2( + function: HashFunction, +) { + private val size = function.bytes + private val hmac = HMAC(function) + + fun hash( + value: ByteArray, + salt: ByteArray, + iterations: Int, + length: Int, + ): ByteArray { + val key = mutableListOf() + + for (i in 1..(length + size - 1) / size) { + val input = salt + i.toUInt().toByteArray() + + var u = hmac.hash(value, input) + var result = u + repeat(iterations - 1) { + u = hmac.hash(value, u) + result = result xor u + } + + key.addAll(result) + + if (key.size >= length) { + println(key.size) + break + } + } + + return key + .take(length) + .toByteArray() + } +} diff --git a/src/commonMain/kotlin/com/infendro/kdf/util/ByteArray.kt b/src/commonMain/kotlin/com/infendro/kdf/util/ByteArray.kt new file mode 100644 index 0000000..09aaaeb --- /dev/null +++ b/src/commonMain/kotlin/com/infendro/kdf/util/ByteArray.kt @@ -0,0 +1,26 @@ +package com.infendro.kdf.util + +import kotlin.experimental.xor + +internal infix fun ByteArray.xor( + that: ByteArray, +): ByteArray { + if (this.size != that.size) throw Exception() + + return ByteArray(size) { i -> + this[i] xor that[i] + } +} + +internal fun MutableCollection.addAll( + bytes: ByteArray, +): Boolean { + return addAll(bytes.toList()) +} + +internal fun UInt.toByteArray(): ByteArray { + return ByteArray(4) { i -> + val offset = (3 - i) * 8 + (this shr offset).toByte() + } +}