package com.infendro.hash.sha2 import com.infendro.bytes.bytearray.copyInto import com.infendro.bytes.intarray.copyInto import com.infendro.hash.HashFunction class `SHA-256` : HashFunction(32, 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) 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( +0x6a09e667, -0x4498517b, +0x3c6ef372, -0x5ab00ac6, +0x510e527f, -0x64fa9774, +0x1f83d9ab, +0x5be0cd19, ) internal val c = intArrayOf( +0x428a2f98, +0x71374491, -0x4a3f0431, -0x164a245b, +0x3956c25b, +0x59f111f1, -0x6dc07d5c, -0x54e3a12b, -0x27f85568, +0x12835b01, +0x243185be, +0x550c7dc3, +0x72be5d74, -0x7f214e02, -0x6423f959, -0x3e640e8c, -0x1b64963f, -0x1041b87a, +0x0fc19dc6, +0x240ca1cc, +0x2de92c6f, +0x4a7484aa, +0x5cb0a9dc, +0x76f988da, -0x67c1aeae, -0x57ce3993, -0x4ffcd838, -0x40a68039, -0x391ff40d, -0x2a586eb9, +0x06ca6351, +0x14292967, +0x27b70a85, +0x2e1b2138, +0x4d2c6dfc, +0x53380d13, +0x650a7354, +0x766a0abb, -0x7e3d36d2, -0x6d8dd37b, -0x5d40175f, -0x57e599b5, -0x3db47490, -0x3893ae5d, -0x2e6d17e7, -0x2966f9dc, -0x0bf1ca7b, +0x106aa070, +0x19a4c116, +0x1e376c08, +0x2748774c, +0x34b0bcb5, +0x391c0cb3, +0x4ed8aa4a, +0x5b9cca4f, +0x682e6ff3, +0x748f82ee, +0x78a5636f, -0x7b3787ec, -0x7338fdf8, -0x6f410006, -0x5baf9315, -0x41065c09, -0x398e870e, ) } }