Implement streaming API
This commit is contained in:
@@ -2,72 +2,53 @@ package com.infendro.hash.sha2
|
||||
|
||||
import com.infendro.bytes.bytearray.copyInto
|
||||
import com.infendro.bytes.intarray.copyInto
|
||||
import com.infendro.bytes.long.copyInto
|
||||
import com.infendro.hash.HashFunction
|
||||
import com.infendro.hash.util.align
|
||||
|
||||
object `SHA-256` : HashFunction {
|
||||
override val bytes: Int
|
||||
get() = 32
|
||||
class `SHA-256` : HashFunction(32, 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(
|
||||
+0x6a09e667, -0x4498517b,
|
||||
+0x3c6ef372, -0x5ab00ac6,
|
||||
+0x510e527f, -0x64fa9774,
|
||||
+0x1f83d9ab, +0x5be0cd19,
|
||||
)
|
||||
override fun reset() {
|
||||
super.reset()
|
||||
initial.copyInto(h)
|
||||
}
|
||||
|
||||
private 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,
|
||||
)
|
||||
override fun process() = process(buffer.value)
|
||||
|
||||
override fun hashInto(value: ByteArray, destination: ByteArray, destinationOffset: Int) {
|
||||
val input = pad(value)
|
||||
val h = initial.copyOf()
|
||||
|
||||
for (i in input.indices step block) {
|
||||
val block = input.sliceArray(i..<(i + block))
|
||||
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)
|
||||
reset()
|
||||
}
|
||||
|
||||
internal fun pad(value: ByteArray): ByteArray {
|
||||
val length = value.size * 8L
|
||||
|
||||
val size = (value.size + 9).align(block)
|
||||
return ByteArray(size).also {
|
||||
value.copyInto(it)
|
||||
it[value.size] = -0x80
|
||||
length.copyInto(it, size - 8)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun process(h: IntArray, block: ByteArray) {
|
||||
val w = IntArray(64)
|
||||
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)
|
||||
}
|
||||
val v = h.copyOf()
|
||||
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 + this.c[i] + w[i]
|
||||
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
|
||||
|
||||
@@ -85,4 +66,24 @@ object `SHA-256` : HashFunction {
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user