Skip to content

Commit

Permalink
Fix typo, make code more concise
Browse files Browse the repository at this point in the history
  • Loading branch information
ligi committed Apr 11, 2020
1 parent f3c6c9e commit 9c97e88
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 190 deletions.
14 changes: 3 additions & 11 deletions sha512/src/main/kotlin/org/komputing/khash/sha512/Sha384.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,9 @@ package org.komputing.khash.sha512

object Sha384 {
private val H0 = longArrayOf(
-0x344462a23efa6128L,
0x629a292a367cd507L,
-0x6ea6fea5cf8f22e9L,
0x152fecd8f70e5939L,
0x67332667ffc00b31L,
-0x714bb57897a7eaefL,
-0x24f3d1f29b067059L,
0x47b5481dbefa4fa4L
-0x344462a23efa6128L, 0x629a292a367cd507L, -0x6ea6fea5cf8f22e9L, 0x152fecd8f70e5939L,
0x67332667ffc00b31L, -0x714bb57897a7eaefL, -0x24f3d1f29b067059L, 0x47b5481dbefa4fa4L
)

fun digest(message: ByteArray): ByteArray {
return Sha512.digest(message, H0).sliceArray(0 until 48)
}
fun digest(message: ByteArray) = Sha512.digest(message, H0).sliceArray(0 until 48)
}
218 changes: 64 additions & 154 deletions sha512/src/main/kotlin/org/komputing/khash/sha512/Sha512.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,111 +2,48 @@ package org.komputing.khash.sha512

/**
* Digest Class for SHA-512.
* Original Java version at hhttps://github.com/trittimo/SHA512
* Original Java version at https://github.com/trittimo/SHA512
*/
object Sha512 {

private var K = longArrayOf(
0x428A2F98D728AE22L,
0x7137449123EF65CDL,
-0x4a3f043013b2c4d1L,
-0x164a245a7e762444L,
0x3956C25BF348B538L,
0x59F111F1B605D019L,
-0x6dc07d5b50e6b065L,
-0x54e3a12a25927ee8L,
-0x27f855675cfcfdbeL,
0x12835B0145706FBEL,
0x243185BE4EE4B28CL,
0x550C7DC3D5FFB4E2L,
0x72BE5D74F27B896FL,
-0x7f214e01c4e9694fL,
-0x6423f958da38edcbL,
-0x3e640e8b3096d96cL,
-0x1b64963e610eb52eL,
-0x1041b879c7b0da1dL,
0x0FC19DC68B8CD5B5L,
0x240CA1CC77AC9C65L,
0x2DE92C6F592B0275L,
0x4A7484AA6EA6E483L,
0x5CB0A9DCBD41FBD4L,
0x76F988DA831153B5L,
-0x67c1aead11992055L,
-0x57ce3992d24bcdf0L,
-0x4ffcd8376704dec1L,
-0x40a680384110f11cL,
-0x391ff40cc257703eL,
-0x2a586eb86cf558dbL,
0x06CA6351E003826FL,
0x142929670A0E6E70L,
0x27B70A8546D22FFCL,
0x2E1B21385C26C926L,
0x4D2C6DFC5AC42AEDL,
0x53380D139D95B3DFL,
0x650A73548BAF63DEL,
0x766A0ABB3C77B2A8L,
-0x7e3d36d1b812511aL,
-0x6d8dd37aeb7dcac5L,
-0x5d40175eb30efc9cL,
-0x57e599b443bdcfffL,
-0x3db4748f2f07686fL,
-0x3893ae5cf9ab41d0L,
-0x2e6d17e62910ade8L,
-0x2966f9dbaa9a56f0L,
-0xbf1ca7aa88edfd6L,
0x106AA07032BBD1B8L,
0x19A4C116B8D2D0C8L,
0x1E376C085141AB53L,
0x2748774CDF8EEB99L,
0x34B0BCB5E19B48A8L,
0x391C0CB3C5C95A63L,
0x4ED8AA4AE3418ACBL,
0x5B9CCA4F7763E373L,
0x682E6FF3D6B2B8A3L,
0x748F82EE5DEFB2FCL,
0x78A5636F43172F60L,
-0x7b3787eb5e0f548eL,
-0x7338fdf7e59bc614L,
-0x6f410005dc9ce1d8L,
-0x5baf9314217d4217L,
-0x41065c084d3986ebL,
-0x398e870d1c8dacd5L,
-0x35d8c13115d99e64L,
-0x2e794738de3f3df9L,
-0x15258229321f14e2L,
-0xa82b08011912e88L,
0x06F067AA72176FBAL,
0x0A637DC5A2C898A6L,
0x113F9804BEF90DAEL,
0x1B710B35131C471BL,
0x28DB77F523047D84L,
0x32CAAB7B40C72493L,
0x3C9EBE0A15C9BEBCL,
0x431D67C49C100D4CL,
0x4CC5D4BECB3E42B6L,
0x597F299CFC657E2AL,
0x5FCB6FAB3AD6FAECL,
0x6C44198C4A475817L
private val K = longArrayOf(
0x428A2F98D728AE22L, 0x7137449123EF65CDL, -0x4a3f043013b2c4d1L, -0x164a245a7e762444L,
0x3956C25BF348B538L, 0x59F111F1B605D019L, -0x6dc07d5b50e6b065L, -0x54e3a12a25927ee8L,
-0x27f855675cfcfdbeL, 0x12835B0145706FBEL, 0x243185BE4EE4B28CL, 0x550C7DC3D5FFB4E2L,
0x72BE5D74F27B896FL, -0x7f214e01c4e9694fL, -0x6423f958da38edcbL, -0x3e640e8b3096d96cL,
-0x1b64963e610eb52eL, -0x1041b879c7b0da1dL, 0x0FC19DC68B8CD5B5L, 0x240CA1CC77AC9C65L,
0x2DE92C6F592B0275L, 0x4A7484AA6EA6E483L, 0x5CB0A9DCBD41FBD4L, 0x76F988DA831153B5L,
-0x67c1aead11992055L, -0x57ce3992d24bcdf0L, -0x4ffcd8376704dec1L, -0x40a680384110f11cL,
-0x391ff40cc257703eL, -0x2a586eb86cf558dbL, 0x06CA6351E003826FL, 0x142929670A0E6E70L,
0x27B70A8546D22FFCL, 0x2E1B21385C26C926L, 0x4D2C6DFC5AC42AEDL, 0x53380D139D95B3DFL,
0x650A73548BAF63DEL, 0x766A0ABB3C77B2A8L, -0x7e3d36d1b812511aL, -0x6d8dd37aeb7dcac5L,
-0x5d40175eb30efc9cL, -0x57e599b443bdcfffL, -0x3db4748f2f07686fL, -0x3893ae5cf9ab41d0L,
-0x2e6d17e62910ade8L, -0x2966f9dbaa9a56f0L, -0xbf1ca7aa88edfd6L, 0x106AA07032BBD1B8L,
0x19A4C116B8D2D0C8L, 0x1E376C085141AB53L, 0x2748774CDF8EEB99L, 0x34B0BCB5E19B48A8L,
0x391C0CB3C5C95A63L, 0x4ED8AA4AE3418ACBL, 0x5B9CCA4F7763E373L, 0x682E6FF3D6B2B8A3L,
0x748F82EE5DEFB2FCL, 0x78A5636F43172F60L, -0x7b3787eb5e0f548eL, -0x7338fdf7e59bc614L,
-0x6f410005dc9ce1d8L, -0x5baf9314217d4217L, -0x41065c084d3986ebL, -0x398e870d1c8dacd5L,
-0x35d8c13115d99e64L, -0x2e794738de3f3df9L, -0x15258229321f14e2L, -0xa82b08011912e88L,
0x06F067AA72176FBAL, 0x0A637DC5A2C898A6L, 0x113F9804BEF90DAEL, 0x1B710B35131C471BL,
0x28DB77F523047D84L, 0x32CAAB7B40C72493L, 0x3C9EBE0A15C9BEBCL, 0x431D67C49C100D4CL,
0x4CC5D4BECB3E42B6L, 0x597F299CFC657E2AL, 0x5FCB6FAB3AD6FAECL, 0x6C44198C4A475817L
)

private var H0 = longArrayOf(
private val H0 = longArrayOf(
0x6A09E667F3BCC908L, -0x4498517a7b3558c5L, 0x3C6EF372FE94F82BL, -0x5ab00ac5a0e2c90fL,
0x510E527FADE682D1L, -0x64fa9773d4c193e1L, 0x1F83D9ABFB41BD6BL, 0x5BE0CD19137E2179L
)

fun digest(input: ByteArray): ByteArray {
return digest(input, H0)
}
fun digest(input: ByteArray) = digest(input, H0)

// Does the actual hash
internal fun digest(input: ByteArray, h0: LongArray): ByteArray {
// First pad the input to the correct length, adding the bits specified in the SHA algorithm
var input = input
input = padMessage(input)
val paddedInput = padMessage(input)
// Break the padded input up into blocks
val blocks: Array<LongArray> = toBlocks(input)
val blocks: Array<LongArray> = toBlocks(paddedInput)
// And get the expanded message blocks
val W: Array<LongArray> = calculateMessageBlocks(blocks)
val expandedMessageBlocks: Array<LongArray> = calculateMessageBlocks(blocks)
// Set up the buffer which will eventually contain the final hash
// Initially, it's set to the constants provided as part of the algorithm
val buffer: LongArray = h0.clone()
Expand All @@ -122,8 +59,7 @@ object Sha512 {
var h = buffer[7]
// Run 80 rounds of the SHA-512 compression function on a-h
for (j in 0..79) {
val t1: Long =
h + bigSig1(e) + ch(e, f, g) + K[j] + W[i][j]
val t1: Long = h + bigSig1(e) + ch(e, f, g) + K[j] + expandedMessageBlocks[i][j]
val t2: Long = bigSig0(a) + maj(a, b, c)
h = g
g = f
Expand All @@ -135,14 +71,14 @@ object Sha512 {
a = t1 + t2
}
// After finishing the compression, save the state to the buffer
buffer[0] = a + buffer[0]
buffer[1] = b + buffer[1]
buffer[2] = c + buffer[2]
buffer[3] = d + buffer[3]
buffer[4] = e + buffer[4]
buffer[5] = f + buffer[5]
buffer[6] = g + buffer[6]
buffer[7] = h + buffer[7]
buffer[0] += a
buffer[1] += b
buffer[2] += c
buffer[3] += d
buffer[4] += e
buffer[5] += f
buffer[6] += g
buffer[7] += h
}
return buffer.foldIndexed(ByteArray(64)) { index, acc, value ->
val indexBytes = index * 8
Expand All @@ -159,19 +95,13 @@ object Sha512 {
}

// Used in the compression function
private fun ch(x: Long, y: Long, z: Long): Long {
return x and y xor (x.inv() and z)
}
private fun ch(x: Long, y: Long, z: Long) = x and y xor (x.inv() and z)

// Used in the compression function
private fun maj(x: Long, y: Long, z: Long): Long {
return x and y xor (x and z) xor (y and z)
}
private fun maj(x: Long, y: Long, z: Long) = x and y xor (x and z) xor (y and z)

// Used in the compression function
private fun rotate(x: Long, l: Int): Long {
return x ushr l or (x shl java.lang.Long.SIZE - l)
}
private fun rotate(x: Long, l: Int) = x ushr l or (x shl java.lang.Long.SIZE - l)

// Used in the compression function
// Sn = right rotate by n bits
Expand Down Expand Up @@ -199,65 +129,45 @@ object Sha512 {
private fun padMessage(input: ByteArray): ByteArray {
// Need to append at least 17 bytes (16 for length of the message, and 1 for the '1' bit)
// then fill with 0s until multiple of 128 bytes
var size = input.size + 17

val remainder = size % 128
if (remainder != 0) {
size += 128 - remainder
val size = (input.size + 17).let {
if (it % 128 == 0) it else it + 128 - it % 128
}

val len = input.size * 8L
// The padded byte array
val out = ByteArray(size)
// Copy over the old stuff
for (i in input.indices) {
out[i] = input[i]
return ByteArray(size) { i ->
when {
i < input.size -> input[i]
i == input.size -> 0x80.toByte()
i == size - 1 -> len.toByte()
i == size - 2 -> (len ushr 8).toByte()
i == size - 3 -> (len ushr 16).toByte()
i == size - 4 -> (len ushr 24).toByte()
else -> 0
}
}
// Add the '1' bit
out[input.size] = 0x80.toByte()
// And put original length of input at the end of our padded input
val len = input.size * 8L
out[size - 1] = len.toByte()
out[size - 2] = (len ushr 8).toByte()
out[size - 3] = (len ushr 16).toByte()
out[size - 4] = (len ushr 24).toByte()
return out

}

// Converts the byte array input starting at index j into a long
private fun arrToLong(input: ByteArray, j: Int): Long {
var v: Long = 0
for (i in 0..7) {
v = (v shl 8) + input[i + j].toUByte().toLong()
}
return v
private fun arrToLong(input: ByteArray, j: Int) = (0..7).fold(0L) { acc, i ->
(acc shl 8) + input[i + j].toUByte().toLong()
}

// Converts the byte array input into blocks of longs
private fun toBlocks(input: ByteArray): Array<LongArray> { // a block has: 1024 bits = 128 bytes = 16 longs
val blocks = Array(input.size / 128) {
val block = LongArray(16)
for (j in 0..15) { // Set the block value to the correct one
block[j] = arrToLong(input, it * 128 + j * 8)
}
block
}
return blocks
// a block has: 1024 bits = 128 bytes = 16 longs
private fun toBlocks(input: ByteArray) = Array(input.size / 128) {
LongArray(16) { j -> arrToLong(input, it * 128 + j * 8) }
}

// Calculates the expanded message blocks W0-W79
private fun calculateMessageBlocks(M: Array<LongArray>): Array<LongArray> {
val W = Array(M.size) { LongArray(80) }
// For each block in the input
private fun calculateMessageBlocks(M: Array<LongArray>) = Array(M.size) { i ->
LongArray(80) { j -> if (j < 16) M[i][j] else 0 }
}.apply {
for (i in M.indices) {
// For each long in the block
for (j in 0..15) { // Set the initial values of W to be the value of the input directly
W[i][j] = M[i][j]
}
// For the rest of the values
for (j in 16..79) { // Do some math from the SHA512 algorithm
W[i][j] =
smallSig1(W[i][j - 2]) + W[i][j - 7] + smallSig0(W[i][j - 15]) + W[i][j - 16]
(16..79).forEach { j ->
get(i)[j] = smallSig1(get(i)[j - 2]) + get(i)[j - 7] + smallSig0(get(i)[j - 15]) + get(i)[j - 16]
}
}
return W
}
}
15 changes: 3 additions & 12 deletions sha512/src/main/kotlin/org/komputing/khash/sha512/Sha512_224.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,9 @@ package org.komputing.khash.sha512

object Sha512_224 {
private val H0 = longArrayOf(
-0x73c2c837e6abb25eL,
0x73E1996689DCD4D6L,
0x1DFAB7AE32FF9C82L,
0x679DD514582F9FCFL,
0x0F6D2B697BD44DA8L,
0x77E36F7304C48942L,
0x3F9D85A86A1D36C8L,
0x1112E6AD91D692A1L
-0x73c2c837e6abb25eL, 0x73E1996689DCD4D6L, 0x1DFAB7AE32FF9C82L, 0x679DD514582F9FCFL,
0x0F6D2B697BD44DA8L, 0x77E36F7304C48942L, 0x3F9D85A86A1D36C8L, 0x1112E6AD91D692A1L
)


fun digest(message: ByteArray): ByteArray {
return Sha512.digest(message, H0).sliceArray(0 until 28)
}
fun digest(message: ByteArray) = Sha512.digest(message, H0).sliceArray(0 until 28)
}
15 changes: 3 additions & 12 deletions sha512/src/main/kotlin/org/komputing/khash/sha512/Sha512_256.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,9 @@ package org.komputing.khash.sha512

object Sha512_256 {
private val H0 = longArrayOf(
0x22312194fc2bf72cL,
-0x60aaa05c37b39b3eL,
0x2393b86b6f53b151L,
-0x69c788e6a6bf1543L,
-0x69d7c11d5771001dL,
-0x41a1e1daac79c66eL,
0x2b0199fc2c85b8aaL,
0x0eb72ddc81c52ca2L
0x22312194fc2bf72cL, -0x60aaa05c37b39b3eL, 0x2393b86b6f53b151L, -0x69c788e6a6bf1543L,
-0x69d7c11d5771001dL, -0x41a1e1daac79c66eL, 0x2b0199fc2c85b8aaL, 0x0eb72ddc81c52ca2L
)


fun digest(message: ByteArray): ByteArray {
return Sha512.digest(message, H0).sliceArray(0 until 32)
}
fun digest(message: ByteArray) = Sha512.digest(message, H0).sliceArray(0 until 32)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ fun ByteArray.sha512() = Sha512.digest(this)
/**
* Returns the SHA512 digest of this string.
*/
fun String.sha512() = this.toByteArray(Charsets.UTF_8).sha512()
fun String.sha512() = toByteArray(Charsets.UTF_8).sha512()

0 comments on commit 9c97e88

Please sign in to comment.