90 lines
3.1 KiB
Kotlin
90 lines
3.1 KiB
Kotlin
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,
|
|
)
|
|
}
|
|
}
|