package com.infendro.hash.sha2 import com.infendro.bytes.bytearray.copyInto import com.infendro.bytes.intarray.copyInto import com.infendro.hash.HashFunction import com.infendro.hash.sha2.`SHA-256`.Companion.c class `SHA-224` : HashFunction(28, 64) { private val h = initial.copyOf() private val w = IntArray(64) private val v = IntArray(8) override fun reset() { super.reset() initial.copyInto(h) } override fun process() = process(buffer.value) private fun finalize() { buffer.append(0x80.toByte()) if (buffer.free < 8) { process(buffer.value) buffer.reset() } buffer.jumpTo(56) buffer.append(length * 8) process(buffer.value) } override fun digestInto(destination: ByteArray, destinationOffset: Int) { finalize() h.copyInto(destination, destinationOffset, endIndex = 7) reset() } private fun process(block: ByteArray) { block.copyInto(w) for (i in 16..<64) { val s0 = w[i - 15].rotateRight(7) xor w[i - 15].rotateRight(18) xor (w[i - 15] ushr 3) val s1 = w[i - 2].rotateRight(17) xor w[i - 2].rotateRight(19) xor (w[i - 2] ushr 10) w[i] = (w[i - 16] + s0 + w[i - 7] + s1) } h.copyInto(v) repeat(64) { i -> val s0 = v[0].rotateRight(2) xor v[0].rotateRight(13) xor v[0].rotateRight(22) val s1 = v[4].rotateRight(6) xor v[4].rotateRight(11) xor v[4].rotateRight(25) val ch = (v[4] and v[5]) xor (v[4].inv() and v[6]) val temp1 = v[7] + s1 + ch + c[i] + w[i] val maj = (v[0] and v[1]) xor (v[0] and v[2]) xor (v[1] and v[2]) val temp2 = s0 + maj v[7] = v[6] v[6] = v[5] v[5] = v[4] v[4] = v[3] + temp1 v[3] = v[2] v[2] = v[1] v[1] = v[0] v[0] = temp1 + temp2 } for (i in 0..<8) { h[i] += v[i] } } companion object { private val initial = intArrayOf( -0x3efa6128, +0x367cd507, +0x3070dd17, -0x08f1a6c7, -0x003ff4cf, +0x68581511, +0x64f98fa7, -0x4105b05c, ) } }