From 6d8024cf7f6c29f8785c66c46b33bbefb915cb93 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 21 Jul 2019 12:26:41 +0200 Subject: [PATCH] Extracted interfaces for hashes --- .../ionspin/kotlin/crypto/{ => hash}/Hash.kt | 29 +++++++- .../crypto/{ => hash}/blake2b/Blake2b.kt | 59 +++++++-------- .../kotlin/crypto/{ => hash}/sha/Sha256.kt | 61 +++++++++------- .../kotlin/crypto/{ => hash}/sha/Sha512.kt | 72 +++++++++++-------- .../com/ionspin/kotlin/crypto/ReadmeTest.kt | 10 +-- .../crypto/{ => hash}/blake2b/Blake2BTest.kt | 2 +- .../{ => hash}/blake2b/Blake2bInstanceTest.kt | 5 +- .../blake2b/Blake2bKnowAnswerTests.kt | 7 +- .../crypto/{ => hash}/sha/Sha256Test.kt | 10 +-- .../{ => hash}/sha/Sha256UpdateableTest.kt | 7 +- .../crypto/{ => hash}/sha/Sha512Test.kt | 8 +-- .../{ => hash}/sha/Sha512UpdateableTest.kt | 4 +- 12 files changed, 162 insertions(+), 112 deletions(-) rename multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/{ => hash}/Hash.kt (53%) rename multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/{ => hash}/blake2b/Blake2b.kt (87%) rename multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/{ => hash}/sha/Sha256.kt (84%) rename multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/{ => hash}/sha/Sha512.kt (84%) rename multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/{ => hash}/blake2b/Blake2BTest.kt (99%) rename multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/{ => hash}/blake2b/Blake2bInstanceTest.kt (94%) rename multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/{ => hash}/blake2b/Blake2bKnowAnswerTests.kt (99%) rename multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/{ => hash}/sha/Sha256Test.kt (81%) rename multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/{ => hash}/sha/Sha256UpdateableTest.kt (91%) rename multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/{ => hash}/sha/Sha512Test.kt (83%) rename multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/{ => hash}/sha/Sha512UpdateableTest.kt (94%) diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Hash.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt similarity index 53% rename from multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Hash.kt rename to multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt index 0a89f27..21add43 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Hash.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -14,14 +14,37 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto +package com.ionspin.kotlin.crypto.hash + /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 20-Jul-2019 */ -interface Hash +interface Hash { + val MAX_HASH_BYTES : Int +} -interface UpdateableHash : Hash +@ExperimentalUnsignedTypes +interface UpdateableHash : Hash { + fun update(data : Array) + + fun update(data : String) + + fun digest() : Array + + fun digestString() : String +} + +@ExperimentalUnsignedTypes +interface StatelessHash : Hash { + fun digest(inputString: String, key: String? = null, hashLength: Int = MAX_HASH_BYTES): Array + + fun digest( + inputMessage: Array = emptyArray(), + key: Array = emptyArray(), + hashLength: Int = MAX_HASH_BYTES + ): Array +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2b.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt similarity index 87% rename from multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2b.kt rename to multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt index 937ea57..5c435f7 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2b.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt @@ -14,14 +14,13 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.blake2b +package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.bignum.integer.BigInteger import com.ionspin.kotlin.bignum.integer.toBigInteger import com.ionspin.kotlin.crypto.* -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job +import com.ionspin.kotlin.crypto.hash.StatelessHash +import com.ionspin.kotlin.crypto.hash.UpdateableHash /** * Created by Ugljesa Jovanovic @@ -31,12 +30,13 @@ import kotlinx.coroutines.Job @ExperimentalUnsignedTypes class Blake2b(val key: Array? = null, val hashLength: Int = 64) : UpdateableHash { - companion object : Hash { + + companion object : StatelessHash { const val BITS_IN_WORD = 64 const val ROUNDS_IN_COMPRESS = 12 const val BLOCK_BYTES = 128 - const val MAX_HASH_BYTES = 64 + override val MAX_HASH_BYTES = 64 const val MIN_HASH_BYTES = 1 const val MAX_KEY_BYTES = 64 const val MIN_KEY_BYTES = 0 @@ -143,38 +143,39 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatea } @ExperimentalStdlibApi - fun digest(inputString: String, key: String? = null): Array { - val chunked = inputString.encodeToByteArray().map { it.toUByte() }.toList().chunked(BLOCK_BYTES) - .map { it.toTypedArray() }.toTypedArray() + override fun digest(inputString: String, key: String?, hashLength: Int): Array { + val array = inputString.encodeToByteArray().map { it.toUByte() }.toList().toTypedArray() val keyBytes = key?.run { encodeToByteArray().map { it.toUByte() }.toTypedArray() } ?: emptyArray() - return digest(inputMessage = chunked, secretKey = keyBytes) + return digest(inputMessage = array, key = keyBytes) } - fun digest( - inputMessage: Array> = emptyArray(), - secretKey: Array = emptyArray(), - hashLength: Int = MAX_HASH_BYTES + override fun digest( + inputMessage: Array, + key: Array, + hashLength: Int ): Array { + val chunkedMessage = inputMessage.chunked(BLOCK_BYTES) + val h = iv.copyOf() - h[0] = h[0] xor 0x01010000UL xor (secretKey.size.toULong() shl 8) xor hashLength.toULong() + h[0] = h[0] xor 0x01010000UL xor (key.size.toULong() shl 8) xor hashLength.toULong() - val message = if (secretKey.isEmpty()) { - if (inputMessage.isEmpty()) { + val message = if (key.isEmpty()) { + if (chunkedMessage.isEmpty()) { Array(1) { Array(128) { 0U } } } else { - inputMessage + chunkedMessage } } else { - arrayOf(padToBlock(secretKey), *inputMessage) + arrayOf(padToBlock(key), *chunkedMessage) } if (message.size > 1) { @@ -246,6 +247,8 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatea requestedHashLenght ) + override val MAX_HASH_BYTES: Int = Blake2b.MAX_HASH_BYTES + var h = iv.copyOf() var counter = BigInteger.ZERO var bufferCounter = 0 @@ -260,15 +263,15 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatea } } - fun update(array: Array) { - if (array.isEmpty()) { + override fun update(data: Array) { + if (data.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_BYTES -> appendToBuffer(array, bufferCounter) - bufferCounter + array.size >= BLOCK_BYTES -> { - val chunked = array.chunked(BLOCK_BYTES) + bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) + bufferCounter + data.size >= BLOCK_BYTES -> { + val chunked = data.chunked(BLOCK_BYTES) chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_BYTES) { appendToBuffer(chunk, bufferCounter) @@ -301,8 +304,8 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatea } @ExperimentalStdlibApi - fun update(input: String) { - update(input.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + override fun update(data: String) { + update(data.encodeToByteArray().map { it.toUByte() }.toTypedArray()) } private fun appendToBuffer(array: Array, start: Int) { @@ -314,7 +317,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatea h = compress(h, block, counter, false) } - fun digest(): Array { + override fun digest(): Array { val lastBlockPadded = padToBlock(buffer) counter += bufferCounter compress(h, lastBlockPadded, counter, true) @@ -325,7 +328,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatea } - fun digestString(): String { + override fun digestString(): String { return digest().map { it.toString(16) }.joinToString(separator = "") } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sha/Sha256.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt similarity index 84% rename from multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sha/Sha256.kt rename to multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt index d8e49f6..58e47c2 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sha/Sha256.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt @@ -14,10 +14,11 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.sha +package com.ionspin.kotlin.crypto.hash.sha -import com.ionspin.kotlin.crypto.Hash import com.ionspin.kotlin.crypto.chunked +import com.ionspin.kotlin.crypto.hash.StatelessHash +import com.ionspin.kotlin.crypto.hash.UpdateableHash import com.ionspin.kotlin.crypto.rotateRight @@ -29,15 +30,20 @@ import com.ionspin.kotlin.crypto.rotateRight @ExperimentalUnsignedTypes -class Sha256 : Hash { +class Sha256 : UpdateableHash { - companion object { + override val MAX_HASH_BYTES: Int = 32 + + + companion object : StatelessHash { const val BLOCK_SIZE = 512 const val BLOCK_SIZE_IN_BYTES = 64 const val UINT_MASK = 0xFFFFFFFFU const val BYTE_MASK_FROM_ULONG = 0xFFUL const val BYTE_MASK_FROM_UINT = 0xFFU + override val MAX_HASH_BYTES: Int = 32 + val iv = arrayOf( 0x6a09e667U, 0xbb67ae85U, @@ -61,22 +67,25 @@ class Sha256 : Hash { ) @ExperimentalStdlibApi - fun digest(message: String): Array { - return digest(message.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + override fun digest(inputString: String, key: String?, hashLength: Int): Array { + return digest( + inputString.encodeToByteArray().map { it.toUByte() }.toTypedArray(), + key?.run { encodeToByteArray().map { it.toUByte() }.toTypedArray() } ?: emptyArray(), + hashLength) } - fun digest(message: Array): Array { + override fun digest(inputMessage: Array, key: Array, hashLength: Int): Array { var h = iv.copyOf() - val expansionArray = createExpansionArray(message.size) + val expansionArray = createExpansionArray(inputMessage.size) val chunks = ( - message + - expansionArray + - (message.size * 8).toULong().toPaddedByteArray() - ) - .chunked(BLOCK_SIZE_IN_BYTES) + inputMessage + + expansionArray + + (inputMessage.size * 8).toULong().toPaddedByteArray() + ) + .chunked(BLOCK_SIZE_IN_BYTES) chunks.forEach { chunk -> val w = expandChunk(chunk) @@ -179,7 +188,7 @@ class Sha256 : Hash { } - fun createExpansionArray(originalSizeInBytes : Int) : Array { + fun createExpansionArray(originalSizeInBytes: Int): Array { val originalMessageSizeInBits = originalSizeInBytes * 8 @@ -236,19 +245,19 @@ class Sha256 : Hash { var buffer = Array(BLOCK_SIZE_IN_BYTES) { 0U } @ExperimentalStdlibApi - fun update(message: String) { - return update(message.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + override fun update(data: String) { + return update(data.encodeToByteArray().map { it.toUByte() }.toTypedArray()) } - fun update(array: Array) { - if (array.isEmpty()) { + override fun update(data: Array) { + if (data.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) + bufferCounter + data.size < BLOCK_SIZE_IN_BYTES -> appendToBuffer(data, bufferCounter) + bufferCounter + data.size >= BLOCK_SIZE_IN_BYTES -> { + val chunked = data.chunked(BLOCK_SIZE_IN_BYTES) chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) { appendToBuffer(chunk, bufferCounter) @@ -285,10 +294,11 @@ class Sha256 : Hash { mix(h, w).copyInto(h) } - fun digest() : Array { + override fun digest(): Array { val length = counter + bufferCounter val expansionArray = createExpansionArray(length) - val finalBlock = buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPaddedByteArray() + val finalBlock = + buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPaddedByteArray() finalBlock.chunked(BLOCK_SIZE_IN_BYTES).forEach { consumeBlock(it) } @@ -305,11 +315,14 @@ class Sha256 : Hash { return digest } + override fun digestString(): String { + return digest().map { it.toString(16) }.joinToString(separator = "") + } + private fun appendToBuffer(array: Array, start: Int) { array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) bufferCounter += array.size } - } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sha/Sha512.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt similarity index 84% rename from multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sha/Sha512.kt rename to multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt index 9b5fffc..95a934c 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sha/Sha512.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt @@ -14,10 +14,11 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.sha +package com.ionspin.kotlin.crypto.hash.sha -import com.ionspin.kotlin.crypto.Hash import com.ionspin.kotlin.crypto.chunked +import com.ionspin.kotlin.crypto.hash.StatelessHash +import com.ionspin.kotlin.crypto.hash.UpdateableHash import com.ionspin.kotlin.crypto.rotateRight /** @@ -27,13 +28,18 @@ import com.ionspin.kotlin.crypto.rotateRight */ @ExperimentalUnsignedTypes -class Sha512 : Hash { - companion object { +class Sha512 : UpdateableHash { + + override val MAX_HASH_BYTES: Int = 32 + + companion object : StatelessHash { const val BLOCK_SIZE = 1024 const val BLOCK_SIZE_IN_BYTES = 128 const val CHUNK_SIZE = 80 const val ULONG_MASK = 0xFFFFFFFFFFFFFFFFUL + override val MAX_HASH_BYTES: Int = 32 + val k = arrayOf( 0x428a2f98d728ae22UL, 0x7137449123ef65cdUL, @@ -129,19 +135,24 @@ class Sha512 : Hash { ) @ExperimentalStdlibApi - fun digest(message: String): Array { - return digest(message.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + override fun digest(inputString: String, key: String?, hashLength: Int): Array { + return digest( + inputString.encodeToByteArray().map { it.toUByte() }.toTypedArray(), + key?.run { encodeToByteArray().map { it.toUByte() }.toTypedArray() } ?: emptyArray(), + hashLength = hashLength + ) } - fun digest(message: Array): Array { + override fun digest(inputMessage: Array, key: Array, hashLength: Int): Array { var h = iv.copyOf() - val expansionArray = createExpansionArray(message.size) + val expansionArray = createExpansionArray(inputMessage.size) val chunks = - (message + expansionArray + (message.size * 8).toULong().toPadded128BitByteArray()).chunked( - BLOCK_SIZE_IN_BYTES) + (inputMessage + expansionArray + (inputMessage.size * 8).toULong().toPadded128BitByteArray()).chunked( + BLOCK_SIZE_IN_BYTES + ) chunks.forEach { chunk -> val w = expandChunk(chunk) @@ -150,14 +161,14 @@ class Sha512 : Hash { } 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() + 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 } @@ -248,7 +259,7 @@ class Sha512 : Hash { return h } - fun createExpansionArray(originalSizeInBytes : Int) : Array { + fun createExpansionArray(originalSizeInBytes: Int): Array { val originalMessageSizeInBits = originalSizeInBytes * 8 val expandedRemainderOf1024 = (originalMessageSizeInBits + 129) % BLOCK_SIZE @@ -309,19 +320,19 @@ class Sha512 : Hash { var buffer = Array(BLOCK_SIZE_IN_BYTES) { 0U } @ExperimentalStdlibApi - fun update(message: String) { - return update(message.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + override fun update(data: String) { + return update(data.encodeToByteArray().map { it.toUByte() }.toTypedArray()) } - fun update(array: Array) { - if (array.isEmpty()) { + override fun update(data: Array) { + if (data.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) + bufferCounter + data.size < BLOCK_SIZE_IN_BYTES -> appendToBuffer(data, bufferCounter) + bufferCounter + data.size >= BLOCK_SIZE_IN_BYTES -> { + val chunked = data.chunked(BLOCK_SIZE_IN_BYTES) chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) { appendToBuffer(chunk, bufferCounter) @@ -358,10 +369,11 @@ class Sha512 : Hash { mix(h, w).copyInto(h) } - fun digest() : Array { + override fun digest(): Array { val length = counter + bufferCounter val expansionArray = createExpansionArray(length) - val finalBlock = buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPadded128BitByteArray() + val finalBlock = + buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPadded128BitByteArray() finalBlock.chunked(BLOCK_SIZE_IN_BYTES).forEach { consumeBlock(it) } @@ -378,6 +390,10 @@ class Sha512 : Hash { return digest } + override fun digestString(): String { + return digest().map { it.toString(16) }.joinToString(separator = "") + } + private fun appendToBuffer(array: Array, start: Int) { array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) bufferCounter += array.size diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt index 4f39cf1..2a1d703 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt @@ -16,9 +16,9 @@ package com.ionspin.kotlin.crypto -import com.ionspin.kotlin.crypto.blake2b.Blake2b -import com.ionspin.kotlin.crypto.sha.Sha256 -import com.ionspin.kotlin.crypto.sha.Sha512 +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b +import com.ionspin.kotlin.crypto.hash.sha.Sha256 +import com.ionspin.kotlin.crypto.hash.sha.Sha512 import kotlin.test.Test import kotlin.test.assertTrue @@ -74,7 +74,7 @@ class ReadmeTest { @Test fun sha256Example() { val input ="abc" - val result = Sha256.digest(message = input) + val result = Sha256.digest(inputString = input) val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) @@ -87,7 +87,7 @@ class ReadmeTest { @Test fun sha512Example() { val input ="abc" - val result = Sha512.digest(message = input.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val result = Sha512.digest(inputMessage = input.encodeToByteArray().map { it.toUByte() }.toTypedArray()) println(result.map {it.toString(16)}) val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2BTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt similarity index 99% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2BTest.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt index 5916900..d4bdd51 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2BTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.blake2b +package com.ionspin.kotlin.crypto.hash.blake2b import kotlin.test.Test import kotlin.test.assertTrue diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2bInstanceTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt similarity index 94% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2bInstanceTest.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt index 020232e..24f1181 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2bInstanceTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt @@ -14,11 +14,8 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.blake2b +package com.ionspin.kotlin.crypto.hash.blake2b -import com.ionspin.kotlin.crypto.util.testBlocking -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import kotlin.test.Test import kotlin.test.assertTrue diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2bKnowAnswerTests.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt similarity index 99% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2bKnowAnswerTests.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt index ddfb35c..c1c4bab 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/blake2b/Blake2bKnowAnswerTests.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.blake2b +package com.ionspin.kotlin.crypto.hash.blake2b import kotlin.test.Test import kotlin.test.assertTrue @@ -37,10 +37,9 @@ class Blake2bKnowAnswerTests { fun knownAnswerTest() { kat.forEach { val parsedInput = it.input.chunked(2).map { it.toUByte(16) }.toTypedArray() - val chunkedInput = parsedInput.toList().chunked(128).map { it.toTypedArray() }.toTypedArray() val result = Blake2b.digest( - inputMessage = chunkedInput, - secretKey = it.key.chunked(2).map { it.toUByte(16) }.toTypedArray() + inputMessage = parsedInput, + key = it.key.chunked(2).map { it.toUByte(16) }.toTypedArray() ) assertTrue { result.contentEquals(it.hash.chunked(2).map { it.toUByte(16) }.toTypedArray()) diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha256Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt similarity index 81% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha256Test.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt index 505d05f..7aec043 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha256Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.sha +package com.ionspin.kotlin.crypto.hash.sha import kotlin.test.Test import kotlin.test.assertTrue @@ -31,7 +31,7 @@ class Sha256Test { @Test fun testWellKnownValue() { - val result = Sha256.digest(message = "abc") + val result = Sha256.digest(inputString = "abc") val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) @@ -44,7 +44,7 @@ class Sha256Test { @Test fun testWellKnownDoubleBlock() { - val resultDoubleBlock = Sha256.digest(message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") + val resultDoubleBlock = Sha256.digest(inputString = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" assertTrue { resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) @@ -56,7 +56,7 @@ class Sha256Test { fun testWellKnown3() { //It's good that I'm consistent with names. - val resultDoubleBlock = Sha256.digest(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") + val resultDoubleBlock = Sha256.digest(inputString = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" assertTrue { @@ -71,7 +71,7 @@ class Sha256Test { for (i in 0 until 1000000) { inputBuilder.append("a") } - val resultDoubleBlock = Sha256.digest(message = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val resultDoubleBlock = Sha256.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toTypedArray()) val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" assertTrue { resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha256UpdateableTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt similarity index 91% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha256UpdateableTest.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt index 9ba98cb..8790573 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha256UpdateableTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.sha +package com.ionspin.kotlin.crypto.hash.sha -import com.ionspin.kotlin.crypto.chunked import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertTrue @@ -47,7 +46,7 @@ class Sha256UpdateableTest { @Test fun testWellKnownDoubleBlock() { val sha256 = Sha256() - sha256.update(message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") + sha256.update(data = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") val resultDoubleBlock = sha256.digest() println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" @@ -60,7 +59,7 @@ class Sha256UpdateableTest { @Test fun testWellKnown3() { //It's good that I'm consistent with names. val sha256 = Sha256() - sha256.update(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") + sha256.update(data = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") val resultDoubleBlock = sha256.digest() println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha512Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt similarity index 83% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha512Test.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt index 37d5c07..353c79d 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha512Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.sha +package com.ionspin.kotlin.crypto.hash.sha import kotlin.test.Test import kotlin.test.assertTrue @@ -30,7 +30,7 @@ class Sha512Test { @Test fun testWellKnownValue() { - val result = Sha512.digest(message = "abc".encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val result = Sha512.digest(inputMessage = "abc".encodeToByteArray().map { it.toUByte() }.toTypedArray()) println(result.map {it.toString(16)}) val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" @@ -46,7 +46,7 @@ class Sha512Test { @Test fun testWellKnown3() { val sha512 = Sha512() - sha512.update(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") + sha512.update(data = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") val resultDoubleBlock = sha512.digest() val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" + "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" @@ -62,7 +62,7 @@ class Sha512Test { for (i in 0 until 1000000) { inputBuilder.append("a") } - val resultDoubleBlock = Sha512.digest(message = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val resultDoubleBlock = Sha512.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toTypedArray()) val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" assertTrue { resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha512UpdateableTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt similarity index 94% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha512UpdateableTest.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt index bdcf195..19ecd40 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/sha/Sha512UpdateableTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.sha +package com.ionspin.kotlin.crypto.hash.sha import kotlin.test.Ignore import kotlin.test.Test @@ -45,7 +45,7 @@ class Sha512UpdateableTest { @Test fun testWellKnownDoubleBlock() { val sha512 = Sha512() - sha512.update(message = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") + sha512.update(data = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") val resultDoubleBlock = sha512.digest() println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" +