refactor HashFunction

This commit is contained in:
2025-11-10 14:26:41 +01:00
parent e3619a2df1
commit e7e43f9cca
15 changed files with 115 additions and 126 deletions

View File

@@ -1,8 +1,7 @@
package com.infendro.hash.keccak
import com.infendro.bytearray.ByteOrder.LITTLE_ENDIAN
import com.infendro.bytearray.addAll
import com.infendro.bytearray.toByteArray
import com.infendro.bytearray.toUByteArray
import com.infendro.bytearray.toULongArray
import com.infendro.hash.HashFunction
import kotlin.math.min
@@ -11,14 +10,8 @@ import kotlin.math.min
open class Keccak internal constructor(
override val bytes: Int,
private val rate: Int,
private val domain: Byte,
private val domain: UByte,
) : HashFunction() {
init {
if (rate % 8 != 0) {
throw IllegalArgumentException("rate must be divisible by 8")
}
}
private val rc = ulongArrayOf(
0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808aUL, 0x8000000080008000UL,
0x000000000000808bUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL,
@@ -37,22 +30,22 @@ open class Keccak internal constructor(
)
override fun hash(
value: ByteArray,
): ByteArray {
value: UByteArray,
): UByteArray {
val paddedValue = buildList {
addAll(value)
add(domain)
while ((size % rate) != (rate - 1)) {
add(0x00.toByte())
add(0x00U)
}
add(0x80.toByte())
add(0x80U)
}
val state = ULongArray(25)
// absorb
val chunks = paddedValue
.chunked(rate)
.chunked(rate) { it.toUByteArray() }
for (chunk in chunks) {
val numbers = chunk.toULongArray(LITTLE_ENDIAN)
for ((i, number) in numbers.withIndex()) {
@@ -62,19 +55,20 @@ open class Keccak internal constructor(
}
// squeeze
return buildList(bytes) {
return buildList {
var i = 0
while (size < bytes) {
if (i == rate / 8) {
permute(state)
i = 0
}
addAll(
state[i++].toByteArray(LITTLE_ENDIAN)
state[i++].toUByteArray(LITTLE_ENDIAN)
.take(min(bytes - size, 8))
)
}
}.toByteArray()
}.toUByteArray()
}
private fun permute(

View File

@@ -3,4 +3,4 @@ package com.infendro.hash.keccak.sha3
import com.infendro.hash.keccak.Keccak
@Suppress("UNUSED")
object `SHA3-224` : Keccak(28, 144, 0x06)
object `SHA3-224` : Keccak(28, 144, 0x06U)

View File

@@ -3,4 +3,4 @@ package com.infendro.hash.keccak.sha3
import com.infendro.hash.keccak.Keccak
@Suppress("UNUSED")
object `SHA3-256` : Keccak(32, 136, 0x06)
object `SHA3-256` : Keccak(32, 136, 0x06U)

View File

@@ -3,4 +3,4 @@ package com.infendro.hash.keccak.sha3
import com.infendro.hash.keccak.Keccak
@Suppress("UNUSED")
object `SHA3-384` : Keccak(48, 104, 0x06)
object `SHA3-384` : Keccak(48, 104, 0x06U)

View File

@@ -3,4 +3,4 @@ package com.infendro.hash.keccak.sha3
import com.infendro.hash.keccak.Keccak
@Suppress("UNUSED")
object `SHA3-512` : Keccak(64, 72, 0x06)
object `SHA3-512` : Keccak(64, 72, 0x06U)

View File

@@ -3,4 +3,4 @@ package com.infendro.hash.keccak.shake
import com.infendro.hash.keccak.Keccak
@Suppress("UNUSED")
class SHAKE128(bytes: Int) : Keccak(bytes, 168, 0x1F)
class SHAKE128(bytes: Int) : Keccak(bytes, 168, 0x1FU)

View File

@@ -3,4 +3,4 @@ package com.infendro.hash.keccak.shake
import com.infendro.hash.keccak.Keccak
@Suppress("UNUSED")
class SHAKE256(bytes: Int) : Keccak(bytes, 136, 0x1F)
class SHAKE256(bytes: Int) : Keccak(bytes, 136, 0x1FU)