Files
hash.kt/src/commonMain/kotlin/com/infendro/hash/blake/Blake-224.kt
2026-03-11 18:53:00 +01:00

86 lines
2.6 KiB
Kotlin

package com.infendro.hash.blake
import com.infendro.bytes.bytearray.copyInto
import com.infendro.bytes.intarray.copyInto
import com.infendro.hash.HashFunction
import com.infendro.hash.blake.`Blake-256`.Companion.c
import com.infendro.hash.blake.`Blake-256`.Companion.sigma
class `Blake-224` : HashFunction(28, 64) {
private val h = initial.copyOf()
private val m = IntArray(16)
private val v = IntArray(16)
override fun reset() {
super.reset()
initial.copyInto(h)
}
override fun process() = compress(buffer.value, length * 8L)
private fun finalize() {
buffer.append(0x80.toByte())
if (buffer.free < 8) {
process()
buffer.reset()
}
buffer.jumpTo(56)
buffer.append(length * 8L)
process()
}
override fun digestInto(destination: ByteArray, destinationOffset: Int) {
finalize()
h.copyInto(destination, destinationOffset, endIndex = 7)
reset()
}
private fun compress(block: ByteArray, t: Long) {
block.copyInto(m)
for (i in 0..<8) v[i] = h[i]
for (i in 0..<4) v[i + 8] = c[i]
for (i in 0..<2) v[i + 12] = c[i + 4] xor t.toInt()
for (i in 0..<2) v[i + 14] = c[i + 6] xor (t ushr 32).toInt()
repeat(14) { r ->
val s = sigma[r % 10]
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
}
for (i in 0..<8) {
h[i] = h[i] xor v[i] xor v[i + 8]
}
}
private fun g(v: IntArray, a: Int, b: Int, c: Int, d: Int, x: Int, y: Int) {
v[a] += v[b] + x
v[d] = (v[d] xor v[a]).rotateRight(16)
v[c] += v[d]
v[b] = (v[b] xor v[c]).rotateRight(12)
v[a] += v[b] + y
v[d] = (v[d] xor v[a]).rotateRight(8)
v[c] += v[d]
v[b] = (v[b] xor v[c]).rotateRight(7)
}
companion object {
private val initial = intArrayOf(
-0x3efa6128, +0x367cd507,
+0x3070dd17, -0x08f1a6c7,
-0x003ff4cf, +0x68581511,
+0x64f98fa7, -0x4105b05c,
)
}
}