Compare commits

..

4 Commits

Author SHA1 Message Date
17b765b13c refactor SHA1 and SHA2 2025-12-04 19:20:35 +01:00
b41debf948 refactor MD5 2025-12-04 19:13:43 +01:00
6dc3cf3b87 refactor Keccak 2025-12-04 19:13:39 +01:00
16390b0308 refactor Blake and Blake2 2025-12-04 19:05:54 +01:00
13 changed files with 296 additions and 296 deletions

View File

@@ -43,12 +43,25 @@ object `Blake-224` : HashFunction() {
)
override fun hash(value: UByteArray): UByteArray {
val l = value.size.toULong() * 8UL
val h = initial.copyOf()
var t = 0U
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 512UL).toUInt()
compress(h, block, t)
}
return h.sliceArray(0..6).toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 64 != 56) {
@@ -56,56 +69,39 @@ object `Blake-224` : HashFunction() {
}
addAll(l.toUByteArray())
}.toUByteArray()
// compress
val blocks = paddedValue
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 512UL).toUInt()
val m = block.toUIntArray()
compress(h, m, t)
}
return h.sliceArray(0..6).toUByteArray()
}
private fun compress(
h: UIntArray,
m: UIntArray,
block: UByteArray,
t: UInt,
) {
// initialization
val m = block.toUIntArray()
val v = UIntArray(16)
for (i in 0..<8) v[i] = h[i]
for (i in 0..<4) v[i + 8] = c[i]
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
for (i in 0..<2) v[i + 14] = c[i + 6]
// rounds
for (r in 0..<14) {
repeat(14) { r ->
val s = sigma[r % 10]
// column
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
// diagonal
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
}
// finalization
for (i in 0..7) {
h[i] = h[i] xor v[i] xor v[i + 8]
}
}
// round function
private fun g(
v: UIntArray,
a: Int,

View File

@@ -43,12 +43,25 @@ object `Blake-256` : HashFunction() {
)
override fun hash(value: UByteArray): UByteArray {
val l = value.size.toULong() * 8UL
val h = initial.copyOf()
var t = 0U
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 512UL).toUInt()
compress(h, block, t)
}
return h.toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 64 != 55) {
@@ -57,56 +70,39 @@ object `Blake-256` : HashFunction() {
add(0x01U)
addAll(l.toUByteArray())
}.toUByteArray()
// compress
val blocks = paddedValue
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 512UL).toUInt()
val m = block.toUIntArray()
compress(h, m, t)
}
return h.toUByteArray()
}
private fun compress(
h: UIntArray,
m: UIntArray,
block: UByteArray,
t: UInt,
) {
// initialization
val m = block.toUIntArray()
val v = UIntArray(16)
for (i in 0..<8) v[i] = h[i]
for (i in 0..<4) v[i + 8] = c[i]
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
for (i in 0..<2) v[i + 14] = c[i + 6]
// rounds
for (r in 0..<14) {
repeat(14) { r ->
val s = sigma[r % 10]
// column
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
// diagonal
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
}
// finalization
for (i in 0..7) {
h[i] = h[i] xor v[i] xor v[i + 8]
}
}
// round function
private fun g(
v: UIntArray,
a: Int,

View File

@@ -43,12 +43,25 @@ object `Blake-384` : HashFunction() {
)
override fun hash(value: UByteArray): UByteArray {
val l = value.size.toULong() * 8UL
val h = initial.copyOf()
var t = 0UL
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 1024UL)
compress(h, block, t)
}
return h.sliceArray(0..5).toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 128 != 120) {
@@ -56,56 +69,39 @@ object `Blake-384` : HashFunction() {
}
addAll(l.toUByteArray())
}.toUByteArray()
// compress
val blocks = paddedValue
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 1024UL)
val m = block.toULongArray()
compress(h, m, t)
}
return h.sliceArray(0..5).toUByteArray()
}
private fun compress(
h: ULongArray,
m: ULongArray,
block: UByteArray,
t: ULong,
) {
// initialization
val m = block.toULongArray()
val v = ULongArray(16)
for (i in 0..<8) v[i] = h[i]
for (i in 0..<4) v[i + 8] = c[i]
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
for (i in 0..<2) v[i + 14] = c[i + 6]
// rounds
for (r in 0..<16) {
repeat(16) { r ->
val s = sigma[r % 10]
// column
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
// diagonal
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
}
// finalization
for (i in 0..7) {
h[i] = h[i] xor v[i] xor v[i + 8]
}
}
// round function
private fun g(
v: ULongArray,
a: Int,

View File

@@ -43,12 +43,25 @@ object `Blake-512` : HashFunction() {
)
override fun hash(value: UByteArray): UByteArray {
val l = value.size.toULong() * 8UL
val h = initial.copyOf()
var t = 0UL
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 1024UL)
compress(h, block, t)
}
return h.toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 128 != 111) {
@@ -58,56 +71,39 @@ object `Blake-512` : HashFunction() {
repeat(8) { add(0x00U) }
addAll(l.toUByteArray())
}.toUByteArray()
// compress
val blocks = paddedValue
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
t += minOf(l - t, 1024UL)
val m = block.toULongArray()
compress(h, m, t)
}
return h.toUByteArray()
}
private fun compress(
h: ULongArray,
m: ULongArray,
block: UByteArray,
t: ULong,
) {
// initialization
val m = block.toULongArray()
val v = ULongArray(16)
for (i in 0..<8) v[i] = h[i]
for (i in 0..<4) v[i + 8] = c[i]
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
for (i in 0..<2) v[i + 14] = c[i + 6]
// rounds
for (r in 0..<16) {
repeat(16) { r ->
val s = sigma[r % 10]
// column
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
// diagonal
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
}
// finalization
for (i in 0..7) {
h[i] = h[i] xor v[i] xor v[i + 8]
}
}
// round function
private fun g(
v: ULongArray,
a: Int,

View File

@@ -36,65 +36,60 @@ class Blake2b(
)
override fun hash(value: UByteArray): UByteArray {
val l = value.size.toULong()
val h = initial.copyOf()
h[0] = h[0] xor (0x01010000UL or bytes.toULong())
var t = 0UL
val l = value.size.toULong()
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(128) { it.toUByteArray() }
for ((i, block) in blocks.withIndex()) {
t += minOf(l - t, 128UL)
compress(h, block, t, i == blocks.lastIndex)
}
return h.toUByteArray(ByteOrder.LITTLE_ENDIAN).sliceArray(0..<bytes)
}
private fun pad(
value: UByteArray,
): UByteArray {
return buildList {
addAll(value)
if (isEmpty()) add(0x00U)
while (size % 128 != 0) {
add(0x00U)
}
}.toUByteArray()
// compress
val blocks = paddedValue
.chunked(128) { it.toUByteArray() }
for ((i, block) in blocks.withIndex()) {
t += minOf(l - t, 128UL)
val m = block.toULongArray()
compress(h, m, t, i == blocks.lastIndex)
}
return h.toUByteArray(ByteOrder.LITTLE_ENDIAN).sliceArray(0..<bytes)
}
private fun compress(
h: ULongArray,
m: ULongArray,
block: UByteArray,
t: ULong,
last: Boolean,
) {
// initialization
val m = block.toULongArray()
val v = ULongArray(16)
for (i in 0..<8) v[i] = h[i]
for (i in 0..<8) v[i + 8] = initial[i]
v[12] = v[12] xor t
if (last) v[14] = v[14].inv()
// rounds
for (r in 0..<12) {
repeat(12) { r ->
val s = sigma[r % 10]
// column
mix(v, 0, 4, 8, 12, m[s[0]], m[s[1]])
mix(v, 1, 5, 9, 13, m[s[2]], m[s[3]])
mix(v, 2, 6, 10, 14, m[s[4]], m[s[5]])
mix(v, 3, 7, 11, 15, m[s[6]], m[s[7]])
// diagonal
mix(v, 0, 5, 10, 15, m[s[8]], m[s[9]])
mix(v, 1, 6, 11, 12, m[s[10]], m[s[11]])
mix(v, 2, 7, 8, 13, m[s[12]], m[s[13]])
mix(v, 3, 4, 9, 14, m[s[14]], m[s[15]])
}
// finalization
for (i in 0..7) {
h[i] = h[i] xor v[i] xor v[i + 8]
}

View File

@@ -36,40 +36,40 @@ class Blake2s(
)
override fun hash(value: UByteArray): UByteArray {
val l = value.size.toULong()
val h = initial.copyOf()
h[0] = h[0] xor (0x01010000U or bytes.toUInt())
var t = 0U
val l = value.size.toULong()
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(64) { it.toUByteArray() }
for ((i, block) in blocks.withIndex()) {
t += minOf(l - t, 64UL).toUInt()
compress(h, block, t, i == blocks.lastIndex)
}
return h.toUByteArray(LITTLE_ENDIAN).sliceArray(0..<bytes)
}
private fun pad(
value: UByteArray,
): UByteArray {
return buildList {
addAll(value)
if (isEmpty()) add(0x00U)
while (size % 64 != 0) {
add(0x00U)
}
}.toUByteArray()
// compress
val blocks = paddedValue
.chunked(64) { it.toUByteArray() }
for ((i, block) in blocks.withIndex()) {
t += minOf(l - t, 64U).toUInt()
val m = block.toUIntArray()
compress(h, m, t, i == blocks.lastIndex)
}
return h.toUByteArray(LITTLE_ENDIAN).sliceArray(0..<bytes)
}
private fun compress(
h: UIntArray,
m: UIntArray,
block: UByteArray,
t: UInt,
last: Boolean,
) {
// initialization
val m = block.toUIntArray()
val v = UIntArray(16)
for (i in 0..<8) v[i] = h[i]
for (i in 0..<8) v[i + 8] = initial[i]
@@ -77,24 +77,20 @@ class Blake2s(
v[12] = v[12] xor t
if (last) v[14] = v[14].inv()
// rounds
for (r in 0..<10) {
repeat(10) { r ->
val s = sigma[r]
// column
mix(v, 0, 4, 8, 12, m[s[0]], m[s[1]])
mix(v, 1, 5, 9, 13, m[s[2]], m[s[3]])
mix(v, 2, 6, 10, 14, m[s[4]], m[s[5]])
mix(v, 3, 7, 11, 15, m[s[6]], m[s[7]])
// diagonal
mix(v, 0, 5, 10, 15, m[s[8]], m[s[9]])
mix(v, 1, 6, 11, 12, m[s[10]], m[s[11]])
mix(v, 2, 7, 8, 13, m[s[12]], m[s[13]])
mix(v, 3, 4, 9, 14, m[s[14]], m[s[15]])
}
// finalization
for (i in 0..7) {
h[i] = h[i] xor v[i] xor v[i + 8]
}

View File

@@ -41,20 +41,32 @@ open class Keccak(
): UByteArray {
val state = ULongArray(25)
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(rate) { it.toUByteArray() }
for (block in blocks) {
absorb(state, block)
}
return squeeze(state)
}
private fun pad(
value: UByteArray,
): UByteArray {
return buildList {
addAll(value)
add(domain)
while ((size % rate) != (rate - 1)) {
add(0x00U)
}
add(0x80U)
}.toUByteArray()
}
// absorb
val blocks = paddedValue
.chunked(rate) { it.toUByteArray() }
for (block in blocks) {
private fun absorb(
state: ULongArray,
block: UByteArray,
) {
val numbers = block.toULongArray(LITTLE_ENDIAN)
for ((i, number) in numbers.withIndex()) {
state[i] = state[i] xor number
@@ -62,23 +74,6 @@ open class Keccak(
permute(state)
}
// squeeze
return buildList {
var i = 0
while (size < bytes) {
if (i == rate / 8) {
permute(state)
i = 0
}
addAll(
state[i++].toUByteArray(LITTLE_ENDIAN)
.sliceArray(0..<min(bytes - size, 8))
)
}
}.toUByteArray()
}
private fun permute(
a: ULongArray,
) {
@@ -112,4 +107,22 @@ open class Keccak(
a[0] = a[0] xor rc[round]
}
}
fun squeeze(
state: ULongArray,
): UByteArray {
return buildList {
var i = 0
while (size < bytes) {
if (i == rate / 8) {
permute(state)
i = 0
}
addAll(
state[i++].toUByteArray(LITTLE_ENDIAN)
.sliceArray(0..<min(bytes - size, 8))
)
}
}.toUByteArray()
}
}

View File

@@ -51,36 +51,38 @@ object MD5 : HashFunction() {
value: UByteArray,
): UByteArray {
val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
process(h, block)
}
return h.toUByteArray(LITTLE_ENDIAN)
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 64 != 56) {
add(0x00U)
}
addAll(l.toUByteArray(LITTLE_ENDIAN))
}
// process
val blocks = paddedValue
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
val w = block.toUIntArray(LITTLE_ENDIAN)
process(h, w)
}
return h.toUByteArray(LITTLE_ENDIAN)
}.toUByteArray()
}
private fun process(
h: UIntArray,
w: UIntArray,
block: UByteArray,
) {
val w = block.toUIntArray(LITTLE_ENDIAN)
val v = h.copyOf()
for (i in 0..<64) {
repeat(64) { i ->
var f = when (i) {
in 0..15 -> (v[1] and v[2]) or (v[1].inv() and v[3])
in 16..31 -> (v[3] and v[1]) or (v[3].inv() and v[2])

View File

@@ -21,42 +21,44 @@ object SHA1 : HashFunction() {
value: UByteArray,
): UByteArray {
val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
process(h, block)
}
return h.toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 64 != 56) {
add(0x00U)
}
addAll(l.toUByteArray())
}
// process
val blocks = paddedValue
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
val w = buildList {
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)
}
}.toUIntArray()
process(h, w)
}
return h.toUByteArray()
}.toUByteArray()
}
private fun process(
h: UIntArray,
w: UIntArray,
block: UByteArray,
) {
val w = buildList {
addAll(block.toUIntArray())
for (i in 16..79) {
val word = (get(i - 3) xor get(i - 8) xor get(i - 14) xor get(i - 16)).rotateLeft(1)
add(word)
}
}.toUIntArray()
val v = h.copyOf()
for (i in 0..<80) {
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]

View File

@@ -33,43 +33,45 @@ object `SHA-224` : HashFunction() {
value: UByteArray,
): UByteArray {
val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
process(h, block)
}
return h.sliceArray(0..6).toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 64 != 56) {
add(0x00U)
}
addAll(l.toUByteArray())
}.toUByteArray()
}
// process
val blocks = paddedValue
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
private fun process(
h: UIntArray,
block: UByteArray,
) {
val w = buildList {
addAll(block.toUIntArray())
for (i in 16..<64) {
for (i in 16..63) {
val s0 = get(i - 15).rotateRight(7) xor get(i - 15).rotateRight(18) xor (get(i - 15) shr 3)
val s1 = get(i - 2).rotateRight(17) xor get(i - 2).rotateRight(19) xor (get(i - 2) shr 10)
add(get(i - 16) + s0 + get(i - 7) + s1)
}
}.toUIntArray()
process(h, w)
}
return h.sliceArray(0..6).toUByteArray()
}
private fun process(
h: UIntArray,
w: UIntArray,
) {
val v = h.copyOf()
for (i in 0..<64) {
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])

View File

@@ -33,43 +33,45 @@ object `SHA-256` : HashFunction() {
value: UByteArray,
): UByteArray {
val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(64) { it.toUByteArray() }
for (block in blocks) {
process(h, block)
}
return h.toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 64 != 56) {
add(0x00U)
}
addAll(l.toUByteArray())
}.toUByteArray()
}
// process
val chunks = paddedValue
.chunked(64) { it.toUByteArray() }
for (chunk in chunks) {
private fun process(
h: UIntArray,
block: UByteArray,
) {
val w = buildList {
addAll(chunk.toUIntArray())
for (i in 16..<64) {
addAll(block.toUIntArray())
for (i in 16..63) {
val s0 = get(i - 15).rotateRight(7) xor get(i - 15).rotateRight(18) xor (get(i - 15) shr 3)
val s1 = get(i - 2).rotateRight(17) xor get(i - 2).rotateRight(19) xor (get(i - 2) shr 10)
add(get(i - 16) + s0 + get(i - 7) + s1)
}
}.toUIntArray()
process(h, w)
}
return h.toUByteArray()
}
private fun process(
h: UIntArray,
w: UIntArray,
) {
val v = h.copyOf()
for (i in 0..<64) {
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])

View File

@@ -45,43 +45,45 @@ object `SHA-384` : HashFunction() {
value: UByteArray,
): UByteArray {
val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
process(h, block)
}
return h.sliceArray(0..5).toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 128 != 120) {
add(0x00U)
}
addAll(l.toUByteArray())
}.toUByteArray()
}
// process
val blocks = paddedValue
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
private fun process(
h: ULongArray,
block: UByteArray,
) {
val w = buildList {
addAll(block.toULongArray())
for (i in 16..<80) {
for (i in 16..79) {
val s0 = get(i - 15).rotateRight(1) xor get(i - 15).rotateRight(8) xor (get(i - 15) shr 7)
val s1 = get(i - 2).rotateRight(19) xor get(i - 2).rotateRight(61) xor (get(i - 2) shr 6)
add(get(i - 16) + s0 + get(i - 7) + s1)
}
}.toULongArray()
process(h, w)
}
return h.sliceArray(0..5).toUByteArray()
}
private fun process(
h: ULongArray,
w: ULongArray,
) {
val v = h.copyOf()
for (i in 0..<80) {
repeat(80) { i ->
val s0 = v[0].rotateRight(28) xor v[0].rotateRight(34) xor v[0].rotateRight(39)
val s1 = v[4].rotateRight(14) xor v[4].rotateRight(18) xor v[4].rotateRight(41)
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])

View File

@@ -45,43 +45,45 @@ object `SHA-512` : HashFunction() {
value: UByteArray,
): UByteArray {
val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding
val paddedValue = buildList {
val blocks = pad(value)
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
process(h, block)
}
return h.toUByteArray()
}
private fun pad(
value: UByteArray,
): UByteArray {
val l = value.size.toULong() * 8UL
return buildList {
addAll(value)
add(0x80U)
while (size % 128 != 120) {
add(0x00U)
}
addAll(l.toUByteArray())
}.toUByteArray()
}
// process
val blocks = paddedValue
.chunked(128) { it.toUByteArray() }
for (block in blocks) {
private fun process(
h: ULongArray,
block: UByteArray,
) {
val w = buildList {
addAll(block.toULongArray())
for (i in 16..<80) {
for (i in 16..79) {
val s0 = get(i - 15).rotateRight(1) xor get(i - 15).rotateRight(8) xor (get(i - 15) shr 7)
val s1 = get(i - 2).rotateRight(19) xor get(i - 2).rotateRight(61) xor (get(i - 2) shr 6)
add(get(i - 16) + s0 + get(i - 7) + s1)
}
}.toULongArray()
process(h, w)
}
return h.toUByteArray()
}
private fun process(
h: ULongArray,
w: ULongArray,
) {
val v = h.copyOf()
for (i in 0..<80) {
repeat(80) { i ->
val s0 = v[0].rotateRight(28) xor v[0].rotateRight(34) xor v[0].rotateRight(39)
val s1 = v[4].rotateRight(14) xor v[4].rotateRight(18) xor v[4].rotateRight(41)
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])