Files
hash.kt/src/commonMain/kotlin/com/infendro/hash/sha1/SHA1.kt
2026-03-11 18:53:00 +01:00

78 lines
1.9 KiB
Kotlin

package com.infendro.hash.sha1
import com.infendro.bytes.bytearray.copyInto
import com.infendro.bytes.intarray.copyInto
import com.infendro.hash.HashFunction
class SHA1 : HashFunction(20, 64) {
private val h = initial.copyOf()
private val w = IntArray(80)
private val v = IntArray(5)
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.reset()
}
buffer.jumpTo(56)
buffer.append(length * 8)
process()
}
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..<80) {
w[i] = (w[i - 3] xor w[i - 8] xor w[i - 14] xor w[i - 16]).rotateLeft(1)
}
h.copyInto(v)
repeat(80) { i ->
val f = when (i) {
in 0..<20 -> (v[1] and v[2]) or (v[1].inv() and v[3])
in 20..<40 -> v[1] xor v[2] xor v[3]
in 40..<60 -> (v[1] and v[2]) or (v[1] and v[3]) or (v[2] and v[3])
else -> v[1] xor v[2] xor v[3]
}
val temp = v[0].rotateLeft(5) + f + v[4] + k[i / 20] + w[i]
v[4] = v[3]
v[3] = v[2]
v[2] = v[1].rotateLeft(30)
v[1] = v[0]
v[0] = temp
}
for (i in 0..<5) {
h[i] += v[i]
}
}
companion object {
private val initial = intArrayOf(
+0x67452301, -0x10325477,
-0x67452302, +0x10325476,
-0x3c2d1e10,
)
private val k = intArrayOf(
+0x5a827999, +0x6ed9eba1,
-0x70e44324, -0x359d3e2a,
)
}
}