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, ) } }