enable passing hash function to HMAC PRNG

This commit is contained in:
2025-08-03 00:12:34 +02:00
parent a606a62eb4
commit f6f9625cf2
2 changed files with 47 additions and 19 deletions

View File

@@ -1,26 +1,26 @@
package com.infendro.random package com.infendro.random
import com.infendro.bytearray.toInt import com.infendro.bytearray.addAll
import com.infendro.hash.SHA256 import com.infendro.hash.HashFunction
import com.infendro.mac.HMAC
import kotlin.random.Random
class HMAC internal constructor() : Random() { class HMAC internal constructor(
function: HashFunction,
) : PRNG() {
private val random = Default private val random = Default
private val hmac = HMAC(SHA256) private val hmac = com.infendro.mac.HMAC(function)
private var K: ByteArray private var K: ByteArray
private var V: ByteArray private var V: ByteArray
init { init {
K = ByteArray(32).also { K = ByteArray(function.bytes).also {
random.nextBytes(it) random.nextBytes(it)
} }
V = ByteArray(32).also { V = ByteArray(function.bytes).also {
random.nextBytes(it) random.nextBytes(it)
} }
} }
fun reseed( override fun reseed(
entropy: ByteArray, entropy: ByteArray,
) { ) {
K = hmac.hash(K, V + byteArrayOf(0x00) + entropy) K = hmac.hash(K, V + byteArrayOf(0x00) + entropy)
@@ -29,18 +29,19 @@ class HMAC internal constructor() : Random() {
V = hmac.hash(K, V) V = hmac.hash(K, V)
} }
override fun nextBits( override fun generate(
count: Int, count: Int,
): Int { ): ByteArray {
if (count !in 0..32) throw Exception() val bytes = buildList {
if (count == 0) return 0 while (size < count) {
V = hmac.hash(K, V)
val bytes = hmac.hash(K, V) addAll(V)
val bits = bytes.take(4).toInt() ushr (32 - count) }
}.take(count).toByteArray()
K = hmac.hash(K, V + byteArrayOf(0x00)) K = hmac.hash(K, V + byteArrayOf(0x00))
V = hmac.hash(K, V) V = hmac.hash(K, V)
return bits return bytes
} }
} }

View File

@@ -1,5 +1,32 @@
package com.infendro.random package com.infendro.random
object PRNG { import com.infendro.bytearray.toInt
val HMAC = HMAC() import com.infendro.hash.HashFunction
import kotlin.random.Random
abstract class PRNG : Random() {
abstract fun reseed(
entropy: ByteArray,
)
abstract fun generate(
count: Int,
): ByteArray
override fun nextBits(
count: Int,
): Int {
if (count !in 0..32) throw Exception()
if (count == 0) return 0
return generate(4).toInt() ushr (32 - count)
}
companion object {
fun HMAC(
function: HashFunction,
): HMAC {
return com.infendro.random.HMAC(function)
}
}
} }