diff --git a/src/commonMain/kotlin/com/infendro/random/HMAC.kt b/src/commonMain/kotlin/com/infendro/random/HMAC.kt new file mode 100644 index 0000000..6d4209a --- /dev/null +++ b/src/commonMain/kotlin/com/infendro/random/HMAC.kt @@ -0,0 +1,46 @@ +package com.infendro.random + +import com.infendro.bytearray.toInt +import com.infendro.hash.SHA256 +import com.infendro.mac.HMAC +import kotlin.random.Random + +class HMAC internal constructor() : Random() { + private val random = Default + private val hmac = HMAC(SHA256) + private var K: ByteArray + private var V: ByteArray + + init { + K = ByteArray(32).also { + random.nextBytes(it) + } + V = ByteArray(32).also { + random.nextBytes(it) + } + } + + fun reseed( + entropy: ByteArray, + ) { + K = hmac.hash(K, V + byteArrayOf(0x00) + entropy) + V = hmac.hash(K, V) + K = hmac.hash(K, V + byteArrayOf(0x01) + entropy) + V = hmac.hash(K, V) + } + + override fun nextBits( + count: Int, + ): Int { + if (count !in 0..32) throw Exception() + if (count == 0) return 0 + + val bytes = hmac.hash(K, V) + val bits = bytes.take(4).toInt() ushr (32 - count) + + K = hmac.hash(K, V + byteArrayOf(0x00)) + V = hmac.hash(K, V) + + return bits + } +} diff --git a/src/commonMain/kotlin/com/infendro/random/PRNG.kt b/src/commonMain/kotlin/com/infendro/random/PRNG.kt new file mode 100644 index 0000000..8df79d7 --- /dev/null +++ b/src/commonMain/kotlin/com/infendro/random/PRNG.kt @@ -0,0 +1,5 @@ +package com.infendro.random + +object PRNG { + val HMAC = HMAC() +}