Tests cleanup
This commit is contained in:
		
							parent
							
								
									187282232e
								
							
						
					
					
						commit
						995cb23176
					
				@ -30,6 +30,8 @@ import com.ionspin.kotlin.crypto.rotateRight
 | 
			
		||||
class Sha512 : Hash {
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val BLOCK_SIZE = 1024
 | 
			
		||||
        const val BLOCK_SIZE_IN_BYTES = 128
 | 
			
		||||
        const val CHUNK_SIZE = 80
 | 
			
		||||
        const val ULONG_MASK = 0xFFFFFFFFFFFFFFFFUL
 | 
			
		||||
 | 
			
		||||
        val k = arrayOf(
 | 
			
		||||
@ -133,102 +135,29 @@ class Sha512 : Hash {
 | 
			
		||||
 | 
			
		||||
        fun digest(message: Array<UByte>): Array<UByte> {
 | 
			
		||||
 | 
			
		||||
            var h0 = 0x6a09e667f3bcc908UL
 | 
			
		||||
            var h1 = 0xbb67ae8584caa73bUL
 | 
			
		||||
            var h2 = 0x3c6ef372fe94f82bUL
 | 
			
		||||
            var h3 = 0xa54ff53a5f1d36f1UL
 | 
			
		||||
            var h4 = 0x510e527fade682d1UL
 | 
			
		||||
            var h5 = 0x9b05688c2b3e6c1fUL
 | 
			
		||||
            var h6 = 0x1f83d9abfb41bd6bUL
 | 
			
		||||
            var h7 = 0x5be0cd19137e2179UL
 | 
			
		||||
            var h = iv.copyOf()
 | 
			
		||||
 | 
			
		||||
            val originalMessageSizeInBits = message.size * 8
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            //K such that L + 1 + K + 64 is a multiple of 512
 | 
			
		||||
            val expandedRemainderOf1024 = (originalMessageSizeInBits + 130) % BLOCK_SIZE
 | 
			
		||||
            val zeroAddAmount = when (expandedRemainderOf1024) {
 | 
			
		||||
                0 -> 0
 | 
			
		||||
                else -> (BLOCK_SIZE - expandedRemainderOf1024) / 8
 | 
			
		||||
            }
 | 
			
		||||
            val expansionArray = Array<UByte>(zeroAddAmount + 1) {
 | 
			
		||||
                when (it) {
 | 
			
		||||
                    0 -> 0b10000000U
 | 
			
		||||
                    else -> 0U
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            val expansionArray = createExpansionArray(message.size)
 | 
			
		||||
 | 
			
		||||
            val chunks =
 | 
			
		||||
                (message + expansionArray + originalMessageSizeInBits.toULong().toPadded128BitByteArray()).chunked(128)
 | 
			
		||||
                (message + expansionArray + (message.size * 8).toULong().toPadded128BitByteArray()).chunked(
 | 
			
		||||
                    BLOCK_SIZE_IN_BYTES)
 | 
			
		||||
 | 
			
		||||
            chunks.forEach { chunk ->
 | 
			
		||||
                val w = Array<ULong>(80) {
 | 
			
		||||
                    when (it) {
 | 
			
		||||
                        in 0 until 16 -> {
 | 
			
		||||
                            var collected = (chunk[(it * 8)].toULong() shl 56) +
 | 
			
		||||
                                    (chunk[(it * 8) + 1].toULong() shl 48) +
 | 
			
		||||
                                    (chunk[(it * 8) + 2].toULong() shl 40) +
 | 
			
		||||
                                    (chunk[(it * 8) + 3].toULong() shl 32) +
 | 
			
		||||
                                    (chunk[(it * 8) + 4].toULong() shl 24) +
 | 
			
		||||
                                    (chunk[(it * 8) + 5].toULong() shl 16) +
 | 
			
		||||
                                    (chunk[(it * 8) + 6].toULong() shl 8) +
 | 
			
		||||
                                    (chunk[(it * 8) + 7].toULong())
 | 
			
		||||
                            collected
 | 
			
		||||
                        }
 | 
			
		||||
                        else -> 0UL
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                for (i in 16 until 80) {
 | 
			
		||||
                    val s0 = scheduleSigma0(w[i - 15])
 | 
			
		||||
                    val s1 = scheduleSigma1(w[i - 2])
 | 
			
		||||
                    w[i] = w[i - 16] + s0 + w[i - 7] + s1
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var a = h0
 | 
			
		||||
                var b = h1
 | 
			
		||||
                var c = h2
 | 
			
		||||
                var d = h3
 | 
			
		||||
                var e = h4
 | 
			
		||||
                var f = h5
 | 
			
		||||
                var g = h6
 | 
			
		||||
                var h = h7
 | 
			
		||||
 | 
			
		||||
                for (i in 0 until 80) {
 | 
			
		||||
                    val s1 = compressionSigma1(e)
 | 
			
		||||
                    val ch = ch(e, f, g)
 | 
			
		||||
                    val temp1 = h + s1 + ch + k[i] + w[i]
 | 
			
		||||
                    val s0 = compressionSigma0(a)
 | 
			
		||||
                    val maj = maj(a, b, c)
 | 
			
		||||
                    val temp2 = s0 + maj
 | 
			
		||||
                    h = g
 | 
			
		||||
                    g = f
 | 
			
		||||
                    f = e
 | 
			
		||||
                    e = d + temp1
 | 
			
		||||
                    d = c
 | 
			
		||||
                    c = b
 | 
			
		||||
                    b = a
 | 
			
		||||
                    a = temp1 + temp2
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                h0 += a
 | 
			
		||||
                h1 += b
 | 
			
		||||
                h2 += c
 | 
			
		||||
                h3 += d
 | 
			
		||||
                h4 += e
 | 
			
		||||
                h5 += f
 | 
			
		||||
                h6 += g
 | 
			
		||||
                h7 += h
 | 
			
		||||
                val w = expandChunk(chunk)
 | 
			
		||||
                mix(h, w)
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val digest = h0.toPaddedByteArray() +
 | 
			
		||||
                    h1.toPaddedByteArray() +
 | 
			
		||||
                    h2.toPaddedByteArray() +
 | 
			
		||||
                    h3.toPaddedByteArray() +
 | 
			
		||||
                    h4.toPaddedByteArray() +
 | 
			
		||||
                    h5.toPaddedByteArray() +
 | 
			
		||||
                    h6.toPaddedByteArray() +
 | 
			
		||||
                    h7.toPaddedByteArray()
 | 
			
		||||
            val digest =
 | 
			
		||||
                    h[0].toPaddedByteArray() +
 | 
			
		||||
                    h[1].toPaddedByteArray() +
 | 
			
		||||
                    h[2].toPaddedByteArray() +
 | 
			
		||||
                    h[3].toPaddedByteArray() +
 | 
			
		||||
                    h[4].toPaddedByteArray() +
 | 
			
		||||
                    h[5].toPaddedByteArray() +
 | 
			
		||||
                    h[6].toPaddedByteArray() +
 | 
			
		||||
                    h[7].toPaddedByteArray()
 | 
			
		||||
            return digest
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -256,6 +185,86 @@ class Sha512 : Hash {
 | 
			
		||||
            return ((x and y) xor (x and z) xor (y and z))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private fun expandChunk(chunk: Array<UByte>): Array<ULong> {
 | 
			
		||||
            val w = Array<ULong>(CHUNK_SIZE) {
 | 
			
		||||
                when (it) {
 | 
			
		||||
                    in 0 until 16 -> {
 | 
			
		||||
                        var collected = (chunk[(it * 8)].toULong() shl 56) +
 | 
			
		||||
                                (chunk[(it * 8) + 1].toULong() shl 48) +
 | 
			
		||||
                                (chunk[(it * 8) + 2].toULong() shl 40) +
 | 
			
		||||
                                (chunk[(it * 8) + 3].toULong() shl 32) +
 | 
			
		||||
                                (chunk[(it * 8) + 4].toULong() shl 24) +
 | 
			
		||||
                                (chunk[(it * 8) + 5].toULong() shl 16) +
 | 
			
		||||
                                (chunk[(it * 8) + 6].toULong() shl 8) +
 | 
			
		||||
                                (chunk[(it * 8) + 7].toULong())
 | 
			
		||||
                        collected
 | 
			
		||||
                    }
 | 
			
		||||
                    else -> 0UL
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (i in 16 until CHUNK_SIZE) {
 | 
			
		||||
                val s0 = scheduleSigma0(w[i - 15])
 | 
			
		||||
                val s1 = scheduleSigma1(w[i - 2])
 | 
			
		||||
                w[i] = w[i - 16] + s0 + w[i - 7] + s1
 | 
			
		||||
            }
 | 
			
		||||
            return w
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private fun mix(h: Array<ULong>, w: Array<ULong>): Array<ULong> {
 | 
			
		||||
            var paramA = h[0]
 | 
			
		||||
            var paramB = h[1]
 | 
			
		||||
            var paramC = h[2]
 | 
			
		||||
            var paramD = h[3]
 | 
			
		||||
            var paramE = h[4]
 | 
			
		||||
            var paramF = h[5]
 | 
			
		||||
            var paramG = h[6]
 | 
			
		||||
            var paramH = h[7]
 | 
			
		||||
 | 
			
		||||
            for (i in 0 until CHUNK_SIZE) {
 | 
			
		||||
                val s1 = compressionSigma1(paramE)
 | 
			
		||||
                val ch = ch(paramE, paramF, paramG)
 | 
			
		||||
                val temp1 = paramH + s1 + ch + k[i] + w[i]
 | 
			
		||||
                val s0 = compressionSigma0(paramA)
 | 
			
		||||
                val maj = maj(paramA, paramB, paramC)
 | 
			
		||||
                val temp2 = s0 + maj
 | 
			
		||||
                paramH = paramG
 | 
			
		||||
                paramG = paramF
 | 
			
		||||
                paramF = paramE
 | 
			
		||||
                paramE = paramD + temp1
 | 
			
		||||
                paramD = paramC
 | 
			
		||||
                paramC = paramB
 | 
			
		||||
                paramB = paramA
 | 
			
		||||
                paramA = temp1 + temp2
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            h[0] += paramA
 | 
			
		||||
            h[1] += paramB
 | 
			
		||||
            h[2] += paramC
 | 
			
		||||
            h[3] += paramD
 | 
			
		||||
            h[4] += paramE
 | 
			
		||||
            h[5] += paramF
 | 
			
		||||
            h[6] += paramG
 | 
			
		||||
            h[7] += paramH
 | 
			
		||||
            return h
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun createExpansionArray(originalSizeInBytes : Int) : Array<UByte> {
 | 
			
		||||
            val originalMessageSizeInBits = originalSizeInBytes * 8
 | 
			
		||||
 | 
			
		||||
            val expandedRemainderOf1024 = (originalMessageSizeInBits + 129) % BLOCK_SIZE
 | 
			
		||||
            val zeroAddAmount = when (expandedRemainderOf1024) {
 | 
			
		||||
                0 -> 0
 | 
			
		||||
                else -> (BLOCK_SIZE - expandedRemainderOf1024) / 8
 | 
			
		||||
            }
 | 
			
		||||
            val expansionArray = Array<UByte>(zeroAddAmount + 1) {
 | 
			
		||||
                when (it) {
 | 
			
		||||
                    0 -> 0b10000000U
 | 
			
		||||
                    else -> 0U
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return expansionArray
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private fun ULong.toPaddedByteArray(): Array<UByte> {
 | 
			
		||||
            val byteMask = 0xFFUL
 | 
			
		||||
@ -294,5 +303,85 @@ class Sha512 : Hash {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var h = iv.copyOf()
 | 
			
		||||
    var counter = 0
 | 
			
		||||
    var bufferCounter = 0
 | 
			
		||||
    var buffer = Array<UByte>(BLOCK_SIZE_IN_BYTES) { 0U }
 | 
			
		||||
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    fun update(message: String) {
 | 
			
		||||
        return update(message.encodeToByteArray().map { it.toUByte() }.toTypedArray())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun update(array: Array<UByte>) {
 | 
			
		||||
        if (array.isEmpty()) {
 | 
			
		||||
            throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        when {
 | 
			
		||||
            bufferCounter + array.size < BLOCK_SIZE_IN_BYTES -> appendToBuffer(array, bufferCounter)
 | 
			
		||||
            bufferCounter + array.size >= BLOCK_SIZE_IN_BYTES -> {
 | 
			
		||||
                val chunked = array.chunked(BLOCK_SIZE_IN_BYTES)
 | 
			
		||||
                chunked.forEach { chunk ->
 | 
			
		||||
                    if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) {
 | 
			
		||||
                        appendToBuffer(chunk, bufferCounter)
 | 
			
		||||
                    } else {
 | 
			
		||||
                        chunk.copyInto(
 | 
			
		||||
                            destination = buffer,
 | 
			
		||||
                            destinationOffset = bufferCounter,
 | 
			
		||||
                            startIndex = 0,
 | 
			
		||||
                            endIndex = BLOCK_SIZE_IN_BYTES - bufferCounter
 | 
			
		||||
                        )
 | 
			
		||||
                        counter += BLOCK_SIZE_IN_BYTES
 | 
			
		||||
                        consumeBlock(buffer)
 | 
			
		||||
                        buffer = Array<UByte>(BLOCK_SIZE_IN_BYTES) {
 | 
			
		||||
                            when (it) {
 | 
			
		||||
                                in (0 until (chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter))) -> {
 | 
			
		||||
                                    chunk[it + (BLOCK_SIZE_IN_BYTES - bufferCounter)]
 | 
			
		||||
                                }
 | 
			
		||||
                                else -> {
 | 
			
		||||
                                    0U
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                        bufferCounter = chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun consumeBlock(block: Array<UByte>) {
 | 
			
		||||
        val w = expandChunk(block)
 | 
			
		||||
        mix(h, w).copyInto(h)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun digest() : Array<UByte> {
 | 
			
		||||
        val length = counter + bufferCounter
 | 
			
		||||
        val expansionArray = createExpansionArray(length)
 | 
			
		||||
        val finalBlock = buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPadded128BitByteArray()
 | 
			
		||||
        finalBlock.chunked(BLOCK_SIZE_IN_BYTES).forEach {
 | 
			
		||||
            consumeBlock(it)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        val digest = h[0].toPaddedByteArray() +
 | 
			
		||||
                h[1].toPaddedByteArray() +
 | 
			
		||||
                h[2].toPaddedByteArray() +
 | 
			
		||||
                h[3].toPaddedByteArray() +
 | 
			
		||||
                h[4].toPaddedByteArray() +
 | 
			
		||||
                h[5].toPaddedByteArray() +
 | 
			
		||||
                h[6].toPaddedByteArray() +
 | 
			
		||||
                h[7].toPaddedByteArray()
 | 
			
		||||
        return digest
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun appendToBuffer(array: Array<UByte>, start: Int) {
 | 
			
		||||
        array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size)
 | 
			
		||||
        bufferCounter += array.size
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -50,4 +50,31 @@ class Sha256Test {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnown3() { //It's good that I'm consistent with names.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        val resultDoubleBlock = Sha256.digest(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
 | 
			
		||||
        println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = ""))
 | 
			
		||||
        val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownLong() {
 | 
			
		||||
        val inputBuilder = StringBuilder()
 | 
			
		||||
        for (i in 0 until 1000000) {
 | 
			
		||||
            inputBuilder.append("a")
 | 
			
		||||
        }
 | 
			
		||||
        val resultDoubleBlock = Sha256.digest(message = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toTypedArray())
 | 
			
		||||
        val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -17,6 +17,7 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.sha
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.chunked
 | 
			
		||||
import kotlin.test.Ignore
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
import kotlin.test.assertTrue
 | 
			
		||||
 | 
			
		||||
@ -54,4 +55,50 @@ class Sha256UpdateableTest {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnown3() { //It's good that I'm consistent with names.
 | 
			
		||||
        val sha256 = Sha256()
 | 
			
		||||
        sha256.update(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
 | 
			
		||||
        val resultDoubleBlock = sha256.digest()
 | 
			
		||||
        println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = ""))
 | 
			
		||||
        val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownLong() {
 | 
			
		||||
        val sha256 = Sha256()
 | 
			
		||||
        for (i in 0 until 10000) {
 | 
			
		||||
            sha256.update("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
 | 
			
		||||
        }
 | 
			
		||||
        val resultDoubleBlock = sha256.digest()
 | 
			
		||||
        val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Ignore()
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownLonger() {
 | 
			
		||||
        val sha256 = Sha256()
 | 
			
		||||
        for (i in 0 until 16_777_216) {
 | 
			
		||||
            if (i % 10000 == 0) {
 | 
			
		||||
                println("$i/16777216")
 | 
			
		||||
            }
 | 
			
		||||
            sha256.update("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno")
 | 
			
		||||
        }
 | 
			
		||||
        val resultDoubleBlock = sha256.digest()
 | 
			
		||||
        val expectedResultForDoubleBlock = "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    //50e72a0e 26442fe2 552dc393 8ac58658 228c0cbf b1d2ca87 2ae43526 6fcd055e
 | 
			
		||||
}
 | 
			
		||||
@ -44,12 +44,12 @@ class Sha512Test {
 | 
			
		||||
    @ExperimentalUnsignedTypes
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownDoubleBlock() {
 | 
			
		||||
 | 
			
		||||
        val resultDoubleBlock = Sha512.digest(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
 | 
			
		||||
            "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
 | 
			
		||||
    fun testWellKnown3() {
 | 
			
		||||
        val sha512 = Sha512()
 | 
			
		||||
        sha512.update(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
 | 
			
		||||
        val resultDoubleBlock = sha512.digest()
 | 
			
		||||
        val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" +
 | 
			
		||||
            "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
 | 
			
		||||
                "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,89 @@
 | 
			
		||||
/*
 | 
			
		||||
 *    Copyright 2019 Ugljesa Jovanovic
 | 
			
		||||
 *
 | 
			
		||||
 *    Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 *    you may not use this file except in compliance with the License.
 | 
			
		||||
 *    You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *        http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 *    Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 *    distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 *    See the License for the specific language governing permissions and
 | 
			
		||||
 *    limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.ionspin.kotlin.crypto.sha
 | 
			
		||||
 | 
			
		||||
import kotlin.test.Ignore
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
import kotlin.test.assertTrue
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
 * ugljesa.jovanovic@ionspin.com
 | 
			
		||||
 * on 21-Jul-2019
 | 
			
		||||
 */
 | 
			
		||||
class Sha512UpdateableTest {
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownValue() {
 | 
			
		||||
        val sha512 = Sha512()
 | 
			
		||||
        sha512.update("abc")
 | 
			
		||||
        val result = sha512.digest()
 | 
			
		||||
        val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
 | 
			
		||||
                "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownDoubleBlock() {
 | 
			
		||||
        val sha512 = Sha512()
 | 
			
		||||
        sha512.update(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
 | 
			
		||||
        val resultDoubleBlock = sha512.digest()
 | 
			
		||||
        println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = ""))
 | 
			
		||||
        val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" +
 | 
			
		||||
                "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownLong() {
 | 
			
		||||
        val sha512 = Sha512()
 | 
			
		||||
        for (i in 0 until 10000) {
 | 
			
		||||
            sha512.update("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
 | 
			
		||||
        }
 | 
			
		||||
        val resultDoubleBlock = sha512.digest()
 | 
			
		||||
        val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Ignore() //Interestingly enough I'm not the only one having trouble with this test.
 | 
			
		||||
    @ExperimentalStdlibApi
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testWellKnownLonger() {
 | 
			
		||||
        val sha512 = Sha512()
 | 
			
		||||
        for (i in 0 until 16_777_216) {
 | 
			
		||||
            if (i % 10000 == 0) {
 | 
			
		||||
                println("$i/16777216")
 | 
			
		||||
            }
 | 
			
		||||
            sha512.update("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno")
 | 
			
		||||
        }
 | 
			
		||||
        val resultDoubleBlock = sha512.digest()
 | 
			
		||||
        val expectedResultForDoubleBlock = "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086"
 | 
			
		||||
        assertTrue {
 | 
			
		||||
            resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user