package com.infendro.hash.blake import com.infendro.bytes.longarray.copyInto import com.infendro.bytes.ulong.copyInto import com.infendro.hash.HashFunction import com.infendro.hash.util.align object `Blake-384` : HashFunction { override val bytes: Int get() = 48 override val block: Int get() = 128 private val initial = ulongArrayOf( 0xcbbb9d5dc1059ed8U, 0x629a292a367cd507U, 0x9159015a3070dd17U, 0x152fecd8f70e5939U, 0x67332667ffc00b31U, 0x8eb44a8768581511U, 0xdb0c2e0d64f98fa7U, 0x47b5481dbefa4fa4U, ).asLongArray() override fun hashInto(value: ByteArray, destination: ByteArray, destinationOffset: Int) { val length = value.size.toULong() * 8UL val input = pad(value) val h = initial.copyOf() val m = LongArray(16) val v = LongArray(16) var t = 0UL for (i in input.indices step block) { t += minOf(length - t, 1024UL) `Blake-512`.compress(h, input, i, m, v, t) } h.copyInto(destination, destinationOffset, endIndex = 6) } private fun pad(value: ByteArray): ByteArray { val length = value.size.toULong() * 8UL val size = (value.size + 17).align(block) val result = ByteArray(size) value.copyInto(result) result[value.size] = 0x80U.toByte() length.copyInto(result, result.size - 8) return result } }