Implement streaming API

This commit is contained in:
2026-03-11 18:53:00 +01:00
parent cb3ff7ec6c
commit 328d4b957e
34 changed files with 936 additions and 593 deletions

View File

@@ -2,57 +2,45 @@ package com.infendro.hash.sha1
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 SHA1 : HashFunction {
override val bytes: Int
get() = 20
class SHA1 : HashFunction(20, 64) {
private val h = initial.copyOf()
override val block: Int
get() = 64
private val w = IntArray(80)
private val v = IntArray(5)
private val initial = intArrayOf(
+0x67452301, -0x10325477,
-0x67452302, +0x10325476,
-0x3c2d1e10,
)
override fun reset() {
super.reset()
initial.copyInto(h)
}
private val k = intArrayOf(
+0x5a827999, +0x6ed9eba1,
-0x70e44324, -0x359d3e2a,
)
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.reset()
}
buffer.jumpTo(56)
buffer.append(length * 8)
process()
}
override fun digestInto(destination: ByteArray, destinationOffset: Int) {
finalize()
h.copyInto(destination, destinationOffset)
reset()
}
private 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)
}
}
private fun process(h: IntArray, block: ByteArray) {
val w = IntArray(80)
private fun process(block: ByteArray) {
block.copyInto(w)
for (i in 16..<80) {
w[i] = (w[i - 3] xor w[i - 8] xor w[i - 14] xor w[i - 16]).rotateLeft(1)
}
val v = h.copyOf()
h.copyInto(v)
repeat(80) { i ->
val f = when (i) {
@@ -73,4 +61,17 @@ object SHA1 : HashFunction {
h[i] += v[i]
}
}
companion object {
private val initial = intArrayOf(
+0x67452301, -0x10325477,
-0x67452302, +0x10325476,
-0x3c2d1e10,
)
private val k = intArrayOf(
+0x5a827999, +0x6ed9eba1,
-0x70e44324, -0x359d3e2a,
)
}
}