Implement streaming API
This commit is contained in:
@@ -1,30 +1,79 @@
|
||||
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
|
||||
|
||||
object `SHA-224` : HashFunction {
|
||||
override val bytes: Int
|
||||
get() = 28
|
||||
class `SHA-224` : HashFunction(28, 64) {
|
||||
private val h = initial.copyOf()
|
||||
|
||||
override val block: Int
|
||||
get() = 64
|
||||
private val w = IntArray(64)
|
||||
private val v = IntArray(8)
|
||||
|
||||
private val initial = intArrayOf(
|
||||
-0x3efa6128, +0x367cd507,
|
||||
+0x3070dd17, -0x08f1a6c7,
|
||||
-0x003ff4cf, +0x68581511,
|
||||
+0x64f98fa7, -0x4105b05c,
|
||||
)
|
||||
override fun reset() {
|
||||
super.reset()
|
||||
initial.copyInto(h)
|
||||
}
|
||||
|
||||
override fun hashInto(value: ByteArray, destination: ByteArray, destinationOffset: Int) {
|
||||
val input = `SHA-256`.pad(value)
|
||||
val h = initial.copyOf()
|
||||
override fun process() = process(buffer.value)
|
||||
|
||||
for (i in input.indices step block) {
|
||||
val block = input.sliceArray(i..<(i + block))
|
||||
`SHA-256`.process(h, block)
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user