86 lines
2.6 KiB
Kotlin
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,
|
|
)
|
|
}
|
|
}
|