diff --git a/src/commonMain/kotlin/com/infendro/hash/sha1/SHA1.kt b/src/commonMain/kotlin/com/infendro/hash/sha1/SHA1.kt index fe01ad3..c0f4c16 100644 --- a/src/commonMain/kotlin/com/infendro/hash/sha1/SHA1.kt +++ b/src/commonMain/kotlin/com/infendro/hash/sha1/SHA1.kt @@ -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] diff --git a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-224.kt b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-224.kt index 1b982d8..f051958 100644 --- a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-224.kt +++ b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-224.kt @@ -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()) - } - - // process - val blocks = paddedValue - .chunked(64) { it.toUByteArray() } - for (block in blocks) { - val w = buildList { - addAll(block.toUIntArray()) - for (i in 16..<64) { - 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() + }.toUByteArray() } private fun process( h: UIntArray, - w: UIntArray, + block: UByteArray, ) { + val w = buildList { + 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() 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]) diff --git a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-256.kt b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-256.kt index c41c83e..e97b49d 100644 --- a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-256.kt +++ b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-256.kt @@ -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()) - } - - // process - val chunks = paddedValue - .chunked(64) { it.toUByteArray() } - for (chunk in chunks) { - val w = buildList { - addAll(chunk.toUIntArray()) - for (i in 16..<64) { - 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() + }.toUByteArray() } private fun process( h: UIntArray, - w: UIntArray, + block: UByteArray, ) { + val w = buildList { + 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() 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]) diff --git a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-384.kt b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-384.kt index 20c9d49..b2c6fa6 100644 --- a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-384.kt +++ b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-384.kt @@ -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()) - } - - // process - val blocks = paddedValue - .chunked(128) { it.toUByteArray() } - for (block in blocks) { - val w = buildList { - addAll(block.toULongArray()) - for (i in 16..<80) { - 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() + }.toUByteArray() } private fun process( h: ULongArray, - w: ULongArray, + block: UByteArray, ) { + val w = buildList { + addAll(block.toULongArray()) + 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() 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]) diff --git a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-512.kt b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-512.kt index f7137fd..3df9481 100644 --- a/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-512.kt +++ b/src/commonMain/kotlin/com/infendro/hash/sha2/SHA-512.kt @@ -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()) - } - - // process - val blocks = paddedValue - .chunked(128) { it.toUByteArray() } - for (block in blocks) { - val w = buildList { - addAll(block.toULongArray()) - for (i in 16..<80) { - 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() + }.toUByteArray() } private fun process( h: ULongArray, - w: ULongArray, + block: UByteArray, ) { + val w = buildList { + addAll(block.toULongArray()) + 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() 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])