refactor SHA1 and SHA2

This commit is contained in:
2025-12-04 19:20:35 +01:00
parent b41debf948
commit 17b765b13c
5 changed files with 124 additions and 114 deletions

View File

@@ -21,42 +21,44 @@ object SHA1 : HashFunction() {
value: UByteArray, value: UByteArray,
): UByteArray { ): UByteArray {
val h = initial.copyOf() val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding val blocks = pad(value)
val paddedValue = buildList { .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) addAll(value)
add(0x80U) add(0x80U)
while (size % 64 != 56) { while (size % 64 != 56) {
add(0x00U) add(0x00U)
} }
addAll(l.toUByteArray()) addAll(l.toUByteArray())
} }.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()
} }
private fun process( private fun process(
h: UIntArray, 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() val v = h.copyOf()
for (i in 0..<80) { repeat(80) { i ->
val f = when (i) { val f = when (i) {
in 0..<20 -> (v[1] and v[2]) or (v[1].inv() and v[3]) 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 20..<40 -> v[1] xor v[2] xor v[3]

View File

@@ -33,43 +33,45 @@ object `SHA-224` : HashFunction() {
value: UByteArray, value: UByteArray,
): UByteArray { ): UByteArray {
val h = initial.copyOf() val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding val blocks = pad(value)
val paddedValue = buildList { .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) addAll(value)
add(0x80U) add(0x80U)
while (size % 64 != 56) { while (size % 64 != 56) {
add(0x00U) add(0x00U)
} }
addAll(l.toUByteArray()) addAll(l.toUByteArray())
}.toUByteArray()
} }
// process private fun process(
val blocks = paddedValue h: UIntArray,
.chunked(64) { it.toUByteArray() } block: UByteArray,
for (block in blocks) { ) {
val w = buildList { val w = buildList {
addAll(block.toUIntArray()) 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 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) 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) add(get(i - 16) + s0 + get(i - 7) + s1)
} }
}.toUIntArray() }.toUIntArray()
process(h, w)
}
return h.sliceArray(0..6).toUByteArray()
}
private fun process(
h: UIntArray,
w: UIntArray,
) {
val v = h.copyOf() 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 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 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]) 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, value: UByteArray,
): UByteArray { ): UByteArray {
val h = initial.copyOf() val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding val blocks = pad(value)
val paddedValue = buildList { .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) addAll(value)
add(0x80U) add(0x80U)
while (size % 64 != 56) { while (size % 64 != 56) {
add(0x00U) add(0x00U)
} }
addAll(l.toUByteArray()) addAll(l.toUByteArray())
}.toUByteArray()
} }
// process private fun process(
val chunks = paddedValue h: UIntArray,
.chunked(64) { it.toUByteArray() } block: UByteArray,
for (chunk in chunks) { ) {
val w = buildList { val w = buildList {
addAll(chunk.toUIntArray()) 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 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) 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) add(get(i - 16) + s0 + get(i - 7) + s1)
} }
}.toUIntArray() }.toUIntArray()
process(h, w)
}
return h.toUByteArray()
}
private fun process(
h: UIntArray,
w: UIntArray,
) {
val v = h.copyOf() 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 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 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]) 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, value: UByteArray,
): UByteArray { ): UByteArray {
val h = initial.copyOf() val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding val blocks = pad(value)
val paddedValue = buildList { .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) addAll(value)
add(0x80U) add(0x80U)
while (size % 128 != 120) { while (size % 128 != 120) {
add(0x00U) add(0x00U)
} }
addAll(l.toUByteArray()) addAll(l.toUByteArray())
}.toUByteArray()
} }
// process private fun process(
val blocks = paddedValue h: ULongArray,
.chunked(128) { it.toUByteArray() } block: UByteArray,
for (block in blocks) { ) {
val w = buildList { val w = buildList {
addAll(block.toULongArray()) 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 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) 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) add(get(i - 16) + s0 + get(i - 7) + s1)
} }
}.toULongArray() }.toULongArray()
process(h, w)
}
return h.sliceArray(0..5).toUByteArray()
}
private fun process(
h: ULongArray,
w: ULongArray,
) {
val v = h.copyOf() 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 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 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]) 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, value: UByteArray,
): UByteArray { ): UByteArray {
val h = initial.copyOf() val h = initial.copyOf()
val l = value.size.toULong() * 8UL
// padding val blocks = pad(value)
val paddedValue = buildList { .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) addAll(value)
add(0x80U) add(0x80U)
while (size % 128 != 120) { while (size % 128 != 120) {
add(0x00U) add(0x00U)
} }
addAll(l.toUByteArray()) addAll(l.toUByteArray())
}.toUByteArray()
} }
// process private fun process(
val blocks = paddedValue h: ULongArray,
.chunked(128) { it.toUByteArray() } block: UByteArray,
for (block in blocks) { ) {
val w = buildList { val w = buildList {
addAll(block.toULongArray()) 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 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) 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) add(get(i - 16) + s0 + get(i - 7) + s1)
} }
}.toULongArray() }.toULongArray()
process(h, w)
}
return h.toUByteArray()
}
private fun process(
h: ULongArray,
w: ULongArray,
) {
val v = h.copyOf() 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 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 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]) val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])