refactor hash functions

This commit is contained in:
2025-12-01 19:13:58 +01:00
parent 10ba03dedc
commit 8a2848e6e3
7 changed files with 341 additions and 392 deletions

View File

@@ -11,76 +11,74 @@ object SHA1 : HashFunction() {
override val block: Int
get() = 64
private val initial = uintArrayOf(
0x67452301U, 0xefcdaB89U,
0x98badcfeU, 0x10325476U,
0xc3d2e1f0U,
)
override fun hash(
value: UByteArray,
): UByteArray {
var h0 = 0x67452301U
var h1 = 0xefcdaB89U
var h2 = 0x98badcfeU
var h3 = 0x10325476U
var h4 = 0xc3d2e1f0U
val ml = value.size.toULong() * 8UL
val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
addAll(value)
add(0x80U)
while (size % 64 != 56) {
add(0x00U)
}
addAll(ml.toUByteArray())
addAll(l.toUByteArray())
}
val chunks = paddedValue
// process
val blocks = paddedValue
.chunked(64) { it.toUByteArray() }
for (chunk in chunks) {
for (block in blocks) {
val w = buildList {
addAll(chunk.toUIntArray())
addAll(block.toUIntArray())
for (i in 16..<80) {
val word = (get(i - 3) xor get(i - 8) xor get(i - 14) xor get(i - 16)).rotateLeft(1)
add(word)
}
}
var a = h0
var b = h1
var c = h2
var d = h3
var e = h4
for (i in 0..<80) {
val f = when (i) {
in 0..<20 -> (b and c) or (b.inv() and d)
in 20..<40 -> b xor c xor d
in 40..<60 -> (b and c) or (b and d) or (c and d)
else -> b xor c xor d
}
val k = when (i) {
in 0..<20 -> 0x5a827999U
in 20..<40 -> 0x6ed9eba1U
in 40..<60 -> 0x8f1bbcdcU
else -> 0xca62c1d6U
}
val temp = a.rotateLeft(5) + f + e + k + w[i]
e = d
d = c
c = b.rotateLeft(30)
b = a
a = temp
}
h0 += a
h1 += b
h2 += c
h3 += d
h4 += e
}.toUIntArray()
process(h, w)
}
return ubyteArrayOf(
*h0.toUByteArray(),
*h1.toUByteArray(),
*h2.toUByteArray(),
*h3.toUByteArray(),
*h4.toUByteArray(),
)
return h.toUByteArray()
}
private fun process(
h: UIntArray,
w: UIntArray,
) {
val v = h.copyOf()
for (i in 0..<80) {
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 k = when (i) {
in 0..<20 -> 0x5a827999U
in 20..<40 -> 0x6ed9eba1U
in 40..<60 -> 0x8f1bbcdcU
else -> 0xca62c1d6U
}
val temp = v[0].rotateLeft(5) + f + v[4] + k + 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..4) {
h[i] += v[i]
}
}
}