enable passing hash function to HMAC PRNG
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user