diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt index 23f9cfd..327556a 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -28,23 +28,23 @@ interface Hash { @ExperimentalUnsignedTypes interface UpdatableHash : Hash { - fun update(data : Array) + fun update(data : UByteArray) fun update(data : String) - fun digest() : Array + fun digest() : UByteArray fun digestString() : String } @ExperimentalUnsignedTypes interface StatelessHash : Hash { - fun digest(inputString: String, key: String? = null, hashLength: Int = MAX_HASH_BYTES): Array + fun digest(inputString: String, key: String? = null, hashLength: Int = MAX_HASH_BYTES): UByteArray fun digest( - inputMessage: Array = emptyArray(), - key: Array = emptyArray(), + inputMessage: UByteArray = ubyteArrayOf(), + key: UByteArray = ubyteArrayOf(), hashLength: Int = MAX_HASH_BYTES - ): Array + ): UByteArray } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt index afcc519..214172e 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt @@ -31,10 +31,14 @@ import com.ionspin.kotlin.crypto.util.rotateRight */ @ExperimentalUnsignedTypes -class Blake2b(val key: Array? = null, val hashLength: Int = 64) : UpdatableHash { +class Blake2b(val key: UByteArray? = null, val hashLength: Int = 64) : UpdatableHash { companion object : StatelessHash { - + //Hack start + //If this line is not included konanc 1.4-M1 fails to link because it cant find ByteArray which is + //a backing class for UByteArray + val byteArray: ByteArray = byteArrayOf(0, 1) + //Hack end const val BITS_IN_WORD = 64 const val ROUNDS_IN_COMPRESS = 12 const val BLOCK_BYTES = 128 @@ -103,7 +107,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab fun compress( h: Array, - input: Array, + input: UByteArray, offsetCounter: BigInteger, finalBlock: Boolean ): Array { @@ -145,24 +149,24 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab } @ExperimentalStdlibApi - override fun digest(inputString: String, key: String?, hashLength: Int): Array { - val array = inputString.encodeToByteArray().map { it.toUByte() }.toList().toTypedArray() + override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray { + val array = inputString.encodeToByteArray().toUByteArray() val keyBytes = key?.run { - encodeToByteArray().map { it.toUByte() }.toTypedArray() - } ?: emptyArray() + encodeToByteArray().toUByteArray() + } ?: ubyteArrayOf() return digest(inputMessage = array, key = keyBytes, hashLength = hashLength) } override fun digest( - inputMessage: Array, - key: Array, + inputMessage: UByteArray, + key: UByteArray, hashLength: Int - ): Array { + ): UByteArray { if (hashLength > MAX_HASH_BYTES) { throw RuntimeException("Invalid hash length. Requested length more than maximum length. Requested length $hashLength") } - val chunkedMessage = inputMessage.chunked(BLOCK_BYTES) + val chunkedMessage = inputMessage.chunked(BLOCK_BYTES).map { it.toUByteArray() }.toTypedArray() val h = iv.copyOf() @@ -172,7 +176,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab val message = if (key.isEmpty()) { if (chunkedMessage.isEmpty()) { Array(1) { - Array(128) { + UByteArray(128) { 0U } } @@ -199,7 +203,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab val lastBlockPadded = if (message.isNotEmpty()) { padToBlock(message[message.size - 1]) } else { - Array(16) { 0U } + UByteArray(16) { 0U } } compress(h, lastBlockPadded, lastSize.toBigInteger(), true).copyInto(h) @@ -208,7 +212,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab return formatResult(h).copyOfRange(0, hashLength) } - private fun formatResult(h: Array): Array { + private fun formatResult(h: Array): UByteArray { return h.map { arrayOf( (it and 0xFFUL).toUByte(), @@ -222,10 +226,10 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab ) }.flatMap { it.toList() - }.toTypedArray() + }.toUByteArray() } - private fun padToBlock(unpadded: Array): Array { + private fun padToBlock(unpadded: UByteArray): UByteArray { if (unpadded.size == BLOCK_BYTES) { return unpadded } @@ -234,7 +238,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab throw IllegalStateException("Block larger than 128 bytes") } - return Array(BLOCK_BYTES) { + return UByteArray(BLOCK_BYTES) { when (it) { in 0 until unpadded.size -> unpadded[it] else -> 0U @@ -248,7 +252,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab key: String?, requestedHashLenght: Int = 64 ) : this( - (key?.encodeToByteArray()?.map { it.toUByte() }?.toTypedArray() ?: emptyArray()), + (key?.encodeToByteArray()?.toUByteArray() ?: ubyteArrayOf()), requestedHashLenght ) @@ -257,7 +261,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab var h = iv.copyOf() var counter = BigInteger.ZERO var bufferCounter = 0 - var buffer = Array(BLOCK_BYTES) { 0U } + var buffer = UByteArray(BLOCK_BYTES) { 0U } init { @@ -268,7 +272,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab } } - override fun update(data: Array) { + override fun update(data: UByteArray) { if (data.isEmpty()) { throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating") } @@ -276,7 +280,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab when { bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) bufferCounter + data.size >= BLOCK_BYTES -> { - val chunked = data.chunked(BLOCK_BYTES) + val chunked = data.chunked(BLOCK_BYTES).map { it.toUByteArray() } chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_BYTES) { appendToBuffer(chunk, bufferCounter) @@ -289,7 +293,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab ) counter += BLOCK_BYTES consumeBlock(buffer) - buffer = Array(BLOCK_BYTES) { + buffer = UByteArray(BLOCK_BYTES) { when (it) { in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { chunk[it + (BLOCK_BYTES - bufferCounter)] @@ -310,19 +314,19 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab } @ExperimentalStdlibApi override fun update(data: String) { - update(data.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + update(data.encodeToByteArray().toUByteArray()) } - private fun appendToBuffer(array: Array, start: Int) { + private fun appendToBuffer(array: UByteArray, start: Int) { array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) bufferCounter += array.size } - private fun consumeBlock(block: Array) { + private fun consumeBlock(block: UByteArray) { h = compress(h, block, counter, false) } - override fun digest(): Array { + override fun digest(): UByteArray { val lastBlockPadded = padToBlock(buffer) counter += bufferCounter compress(h, lastBlockPadded, counter, true) @@ -341,7 +345,7 @@ class Blake2b(val key: Array? = null, val hashLength: Int = 64) : Updatab h = iv.copyOf() counter = BigInteger.ZERO bufferCounter = 0 - buffer = Array(BLOCK_BYTES) { 0U } + buffer = UByteArray(BLOCK_BYTES) { 0U } } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt index 1a222ff..ca2143f 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt @@ -67,14 +67,14 @@ class Sha256 : UpdatableHash { ) @ExperimentalStdlibApi - override fun digest(inputString: String, key: String?, hashLength: Int): Array { + override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray { return digest( - inputString.encodeToByteArray().map { it.toUByte() }.toTypedArray(), - key?.run { encodeToByteArray().map { it.toUByte() }.toTypedArray() } ?: emptyArray(), + inputString.encodeToByteArray().toUByteArray(), + key?.run { encodeToByteArray().toUByteArray()} ?: ubyteArrayOf(), hashLength) } - override fun digest(inputMessage: Array, key: Array, hashLength: Int): Array { + override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { var h = iv.copyOf() @@ -88,7 +88,7 @@ class Sha256 : UpdatableHash { .chunked(BLOCK_SIZE_IN_BYTES) chunks.forEach { chunk -> - val w = expandChunk(chunk) + val w = expandChunk(chunk.toUByteArray()) mix(h, w).copyInto(h) } @@ -128,7 +128,7 @@ class Sha256 : UpdatableHash { return (((x and y) xor (x and z) xor (y and z))) } - private fun expandChunk(chunk: Array): Array { + private fun expandChunk(chunk: UByteArray): Array { val w = Array(BLOCK_SIZE_IN_BYTES) { when (it) { in 0 until 16 -> { @@ -188,7 +188,7 @@ class Sha256 : UpdatableHash { } - fun createExpansionArray(originalSizeInBytes: Int): Array { + fun createExpansionArray(originalSizeInBytes: Int): UByteArray { val originalMessageSizeInBits = originalSizeInBytes * 8 @@ -198,7 +198,7 @@ class Sha256 : UpdatableHash { 0 -> 0 else -> (BLOCK_SIZE - expandedRemainderOf512) / 8 } - val expansionArray = Array(zeroAddAmount + 1) { + val expansionArray = UByteArray(zeroAddAmount + 1) { when (it) { 0 -> 0b10000000U else -> 0U @@ -207,9 +207,9 @@ class Sha256 : UpdatableHash { return expansionArray } - private fun ULong.toPaddedByteArray(): Array { + private fun ULong.toPaddedByteArray(): UByteArray { val byteMask = BYTE_MASK_FROM_ULONG - return Array(8) { + return UByteArray(8) { when (it) { 7 -> (this and byteMask).toUByte() 6 -> ((this shr 8) and byteMask).toUByte() @@ -224,9 +224,9 @@ class Sha256 : UpdatableHash { } } - private fun UInt.toPaddedByteArray(): Array { + private fun UInt.toPaddedByteArray(): UByteArray { val byteMask = BYTE_MASK_FROM_UINT - return Array(4) { + return UByteArray(4) { when (it) { 3 -> (this and byteMask).toUByte() 2 -> ((this shr 8) and byteMask).toUByte() @@ -242,14 +242,14 @@ class Sha256 : UpdatableHash { var h = iv.copyOf() var counter = 0 var bufferCounter = 0 - var buffer = Array(BLOCK_SIZE_IN_BYTES) { 0U } + var buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { 0U } @ExperimentalStdlibApi override fun update(data: String) { - return update(data.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + return update(data.encodeToByteArray().toUByteArray()) } - override fun update(data: Array) { + override fun update(data: UByteArray) { if (data.isEmpty()) { throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating") } @@ -260,9 +260,9 @@ class Sha256 : UpdatableHash { val chunked = data.chunked(BLOCK_SIZE_IN_BYTES) chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) { - appendToBuffer(chunk, bufferCounter) + appendToBuffer(chunk.toUByteArray(), bufferCounter) } else { - chunk.copyInto( + chunk.toUByteArray().copyInto( destination = buffer, destinationOffset = bufferCounter, startIndex = 0, @@ -270,7 +270,7 @@ class Sha256 : UpdatableHash { ) counter += BLOCK_SIZE_IN_BYTES consumeBlock(buffer) - buffer = Array(BLOCK_SIZE_IN_BYTES) { + buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { when (it) { in (0 until (chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter))) -> { chunk[it + (BLOCK_SIZE_IN_BYTES - bufferCounter)] @@ -289,18 +289,18 @@ class Sha256 : UpdatableHash { } } - private fun consumeBlock(block: Array) { + private fun consumeBlock(block: UByteArray) { val w = expandChunk(block) mix(h, w).copyInto(h) } - override fun digest(): Array { + override fun digest(): UByteArray { val length = counter + bufferCounter val expansionArray = createExpansionArray(length) val finalBlock = buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPaddedByteArray() finalBlock.chunked(BLOCK_SIZE_IN_BYTES).forEach { - consumeBlock(it) + consumeBlock(it.toUByteArray()) } @@ -319,7 +319,7 @@ class Sha256 : UpdatableHash { return digest().map { it.toString(16) }.joinToString(separator = "") } - private fun appendToBuffer(array: Array, start: Int) { + private fun appendToBuffer(array: UByteArray, start: Int) { array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) bufferCounter += array.size } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt index 69618cf..c58e562 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt @@ -135,15 +135,15 @@ class Sha512 : UpdatableHash { ) @ExperimentalStdlibApi - override fun digest(inputString: String, key: String?, hashLength: Int): Array { + override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray { return digest( - inputString.encodeToByteArray().map { it.toUByte() }.toTypedArray(), - key?.run { encodeToByteArray().map { it.toUByte() }.toTypedArray() } ?: emptyArray(), + inputString.encodeToByteArray().toUByteArray(), + key?.run { encodeToByteArray().toUByteArray() } ?: ubyteArrayOf(), hashLength = hashLength ) } - override fun digest(inputMessage: Array, key: Array, hashLength: Int): Array { + override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { var h = iv.copyOf() @@ -155,7 +155,7 @@ class Sha512 : UpdatableHash { ) chunks.forEach { chunk -> - val w = expandChunk(chunk) + val w = expandChunk(chunk.toUByteArray()) mix(h, w) } @@ -196,7 +196,7 @@ class Sha512 : UpdatableHash { return ((x and y) xor (x and z) xor (y and z)) } - private fun expandChunk(chunk: Array): Array { + private fun expandChunk(chunk: UByteArray): Array { val w = Array(CHUNK_SIZE) { when (it) { in 0 until 16 -> { @@ -259,7 +259,7 @@ class Sha512 : UpdatableHash { return h } - fun createExpansionArray(originalSizeInBytes: Int): Array { + fun createExpansionArray(originalSizeInBytes: Int): UByteArray { val originalMessageSizeInBits = originalSizeInBytes * 8 val expandedRemainderOf1024 = (originalMessageSizeInBits + 129) % BLOCK_SIZE @@ -267,7 +267,7 @@ class Sha512 : UpdatableHash { 0 -> 0 else -> (BLOCK_SIZE - expandedRemainderOf1024) / 8 } - val expansionArray = Array(zeroAddAmount + 1) { + val expansionArray = UByteArray(zeroAddAmount + 1) { when (it) { 0 -> 0b10000000U else -> 0U @@ -277,10 +277,10 @@ class Sha512 : UpdatableHash { } - private fun ULong.toPaddedByteArray(): Array { + private fun ULong.toPaddedByteArray(): UByteArray { val byteMask = 0xFFUL //Ignore messages longer than 64 bits for now - return Array(8) { + return UByteArray(8) { when (it) { 7 -> (this and byteMask).toUByte() 6 -> ((this shr 8) and byteMask).toUByte() @@ -295,10 +295,10 @@ class Sha512 : UpdatableHash { } } - private fun ULong.toPadded128BitByteArray(): Array { + private fun ULong.toPadded128BitByteArray(): UByteArray { val byteMask = 0xFFUL //Ignore messages longer than 64 bits for now - return Array(16) { + return UByteArray(16) { when (it) { 15 -> (this and byteMask).toUByte() 14 -> ((this shr 8) and byteMask).toUByte() @@ -317,14 +317,14 @@ class Sha512 : UpdatableHash { var h = iv.copyOf() var counter = 0 var bufferCounter = 0 - var buffer = Array(BLOCK_SIZE_IN_BYTES) { 0U } + var buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { 0U } @ExperimentalStdlibApi override fun update(data: String) { - return update(data.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + return update(data.encodeToByteArray().toUByteArray()) } - override fun update(data: Array) { + override fun update(data: UByteArray) { if (data.isEmpty()) { throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating") } @@ -335,9 +335,9 @@ class Sha512 : UpdatableHash { val chunked = data.chunked(BLOCK_SIZE_IN_BYTES) chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) { - appendToBuffer(chunk, bufferCounter) + appendToBuffer(chunk.toUByteArray(), bufferCounter) } else { - chunk.copyInto( + chunk.toUByteArray().copyInto( destination = buffer, destinationOffset = bufferCounter, startIndex = 0, @@ -345,7 +345,7 @@ class Sha512 : UpdatableHash { ) counter += BLOCK_SIZE_IN_BYTES consumeBlock(buffer) - buffer = Array(BLOCK_SIZE_IN_BYTES) { + buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { when (it) { in (0 until (chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter))) -> { chunk[it + (BLOCK_SIZE_IN_BYTES - bufferCounter)] @@ -364,18 +364,18 @@ class Sha512 : UpdatableHash { } } - private fun consumeBlock(block: Array) { + private fun consumeBlock(block: UByteArray) { val w = expandChunk(block) mix(h, w).copyInto(h) } - override fun digest(): Array { + override fun digest(): UByteArray { 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) + consumeBlock(it.toUByteArray()) } @@ -394,7 +394,7 @@ class Sha512 : UpdatableHash { return digest().map { it.toString(16) }.joinToString(separator = "") } - private fun appendToBuffer(array: Array, start: Int) { + private fun appendToBuffer(array: UByteArray, start: Int) { array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) bufferCounter += array.size } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2.kt index 1632516..2381308 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2.kt @@ -310,8 +310,8 @@ class Argon2( key.size.toUInt().toLittleEndianUByteArray() + key + associatedData.size.toUInt().toLittleEndianUByteArray() + associatedData val h0 = Blake2b.digest( - blakeInput.toTypedArray() - ).toUByteArray() + blakeInput + ) //Compute B[i][0] for (i in 0 until parallelism) { diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Utils.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Utils.kt index bfc000d..9763978 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Utils.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Utils.kt @@ -127,17 +127,17 @@ object Argon2Utils { internal fun argonBlake2bArbitraryLenghtHash(input: UByteArray, length: UInt): UByteArray { if (length <= 64U) { - return Blake2b.digest(inputMessage = length + input.toTypedArray(), hashLength = length.toInt()).toUByteArray() + return Blake2b.digest(inputMessage = length + input, hashLength = length.toInt()) } //We can cast to int because UInt even if MAX_VALUE divided by 32 is guaranteed not to overflow val numberOf64ByteBlocks = (1U + ((length - 1U) / 32U) - 2U).toInt() // equivalent to ceil(length/32) - 2 val v = Array(numberOf64ByteBlocks) { ubyteArrayOf() } - v[0] = Blake2b.digest(length + input.toTypedArray()).toUByteArray() + v[0] = Blake2b.digest(length + input) for (i in 1 until numberOf64ByteBlocks) { - v[i] = Blake2b.digest(v[i - 1].toTypedArray()).toUByteArray() + v[i] = Blake2b.digest(v[i - 1]) } val remainingPartOfInput = length.toInt() - numberOf64ByteBlocks * 32 - val vLast = Blake2b.digest(v[numberOf64ByteBlocks - 1].toTypedArray(), hashLength = remainingPartOfInput).toUByteArray() + val vLast = Blake2b.digest(v[numberOf64ByteBlocks - 1], hashLength = remainingPartOfInput) val concat = (v.map { it.copyOfRange(0, 32) }) .plus(listOf(vLast)) diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt index 69e2a00..371e872 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt @@ -1,10 +1,12 @@ package com.ionspin.kotlin.crypto.symmetric +import com.ionspin.kotlin.crypto.util.flattenToUByteArray + /** * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 07/Sep/2019 */ @ExperimentalUnsignedTypes -internal class Aes internal constructor(val aesKey: AesKey, val input: Array) { +internal class Aes internal constructor(val aesKey: AesKey, val input: UByteArray) { companion object { private val debug = false @@ -54,18 +56,18 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array): Array { + fun encrypt(aesKey: AesKey, input: UByteArray): UByteArray { return Aes(aesKey, input).encrypt() } - fun decrypt(aesKey: AesKey, input: Array): Array { + fun decrypt(aesKey: AesKey, input: UByteArray): UByteArray { return Aes(aesKey, input).decrypt() } } - val state: Array> = (0 until 4).map { outerCounter -> - Array(4) { innerCounter -> input[innerCounter * 4 + outerCounter] } + val state: Array = (0 until 4).map { outerCounter -> + UByteArray(4) { innerCounter -> input[innerCounter * 4 + outerCounter] } }.toTypedArray() val numberOfRounds = when (aesKey) { @@ -74,7 +76,7 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array 14 } - val expandedKey: Array> = expandKey() + val expandedKey: Array = expandKey() var round = 0 @@ -110,22 +112,22 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array> = (0 until 4).map { - Array(4) { 0U } + val stateMixed: Array = (0 until 4).map { + UByteArray(4) { 0U } }.toTypedArray() for (c in 0..3) { @@ -138,8 +140,8 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array> = (0 until 4).map { - Array(4) { 0U } + val stateMixed: Array = (0 until 4).map { + UByteArray(4) { 0U } }.toTypedArray() for (c in 0..3) { stateMixed[0][c] = @@ -203,9 +205,9 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array> { + fun expandKey(): Array { val expandedKey = (0 until 4 * (numberOfRounds + 1)).map { - Array(4) { 0U } + UByteArray(4) { 0U } }.toTypedArray() // First round for (i in 0 until aesKey.numberOf32BitWords) { @@ -241,13 +243,13 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array it xor temp[index] - }.toTypedArray() + }.toUByteArray() clearArray(temp) } return expandedKey } - fun encrypt(): Array { + fun encrypt(): UByteArray { if (completed) { throw RuntimeException("Encrypt can only be called once per Aes instance, since the state is cleared at the " + "end of the operation") @@ -273,8 +275,8 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array - Array(4) { 0U } - }.toTypedArray() + UByteArray(4) { 0U } + } for (i in 0 until 4) { for (j in 0 until 4) { transposedMatrix[i][j] = state[j][i] @@ -282,10 +284,10 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array { + fun decrypt(): UByteArray { if (completed) { throw RuntimeException("Decrypt can only be called once per Aes instance, since the state is cleared at the " + "end of the operation") @@ -313,20 +315,19 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array - Array(4) { 0U } - }.toTypedArray() + UByteArray(4) { 0U } + } for (i in 0 until 4) { for (j in 0 until 4) { transposedMatrix[i][j] = state[j][i] } } - printState(transposedMatrix) state.forEach { clearArray(it) } completed = true - return transposedMatrix.flatten().toTypedArray() + return transposedMatrix.flattenToUByteArray() } - private fun clearArray(array : Array) { + private fun clearArray(array : UByteArray) { array.indices.forEach { array[it] = 0U } } @@ -342,7 +343,7 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array>) { + private fun printState(specific : List) { if (!debug) { return } @@ -356,7 +357,7 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array = key.chunked(2).map { it.toUByte(16) }.toTypedArray() + val keyArray: UByteArray = key.chunked(2).map { it.toUByte(16) }.toUByteArray() val numberOf32BitWords = keyLength / 32 class Aes128Key(key: String) : AesKey(key, 128) diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt index 6a5fd2f..b2e492a 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt @@ -32,7 +32,7 @@ import com.ionspin.kotlin.crypto.util.xor * on 21-Sep-2019 */ @ExperimentalUnsignedTypes -class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializationVector: Array? = null) { +class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializationVector: UByteArray? = null) { companion object { const val BLOCK_BYTES = 16 @@ -54,7 +54,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa /** * Bulk encryption, returns encrypted data and a random initialization vector */ - fun encrypt(aesKey: AesKey, data: Array): EncryptedDataAndInitializationVector { + fun encrypt(aesKey: AesKey, data: UByteArray): EncryptedDataAndInitializationVector { val aesCbc = AesCbc(aesKey, Mode.ENCRYPT) aesCbc.addData(data) return aesCbc.encrypt() @@ -63,20 +63,20 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa /** * Bulk decryption, returns decrypted data */ - fun decrypt(aesKey: AesKey, data: Array, initialCounter: Array? = null): Array { + fun decrypt(aesKey: AesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { val aesCbc = AesCbc(aesKey, Mode.DECRYPT, initialCounter) aesCbc.addData(data) return aesCbc.decrypt() } - private fun padToBlock(unpadded: Array): Array { + private fun padToBlock(unpadded: UByteArray): UByteArray { val paddingSize = 16 - unpadded.size if (unpadded.size == BLOCK_BYTES) { return unpadded } if (unpadded.size == BLOCK_BYTES) { - return Array(BLOCK_BYTES) { + return UByteArray(BLOCK_BYTES) { BLOCK_BYTES.toUByte() } } @@ -85,7 +85,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa throw IllegalStateException("Block larger than 128 bytes") } - return Array(BLOCK_BYTES) { + return UByteArray(BLOCK_BYTES) { when (it) { in unpadded.indices -> unpadded[it] else -> paddingSize.toUByte() @@ -95,20 +95,20 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa } } - var currentOutput: Array = arrayOf() - var previousEncrypted: Array = arrayOf() + var currentOutput: UByteArray = ubyteArrayOf() + var previousEncrypted: UByteArray = ubyteArrayOf() val initVector = if (initializationVector.isNullOrEmpty()) { - SRNG.getRandomBytes(16).toTypedArray() + SRNG.getRandomBytes(16) } else { initializationVector } - val output = MutableList>(0) { arrayOf() } + val output = MutableList(0) { ubyteArrayOf() } - var buffer: Array = UByteArray(16) { 0U }.toTypedArray() + var buffer: UByteArray = UByteArray(16) { 0U } var bufferCounter = 0 - fun addData(data: Array) { + fun addData(data: UByteArray) { //Padding when { bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) @@ -116,16 +116,16 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa val chunked = data.chunked(BLOCK_BYTES) chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_BYTES) { - appendToBuffer(chunk, bufferCounter) + appendToBuffer(chunk.toUByteArray(), bufferCounter) } else { - chunk.copyInto( + chunk.toUByteArray().copyInto( destination = buffer, destinationOffset = bufferCounter, startIndex = 0, endIndex = BLOCK_BYTES - bufferCounter ) output += consumeBlock(buffer) - buffer = Array(BLOCK_BYTES) { + buffer = UByteArray(BLOCK_BYTES) { when (it) { in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { chunk[it + (BLOCK_BYTES - bufferCounter)] @@ -153,7 +153,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa if (bufferCounter > 0) { val lastBlockPadded = padToBlock(buffer) if (lastBlockPadded.size > BLOCK_BYTES) { - val chunks = lastBlockPadded.chunked(BLOCK_BYTES) + val chunks = lastBlockPadded.chunked(BLOCK_BYTES).map { it.toUByteArray() } output += consumeBlock(chunks[0]) output += consumeBlock(chunks[1]) } else { @@ -161,7 +161,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa } } return EncryptedDataAndInitializationVector( - output.reversed().foldRight(Array(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, + output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, initVector ) } @@ -170,7 +170,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa * Decrypt data * @return Decrypted data */ - fun decrypt(): Array { + fun decrypt(): UByteArray { val removePaddingCount = output.last().last() @@ -178,22 +178,23 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa output.last().dropLast(removePaddingCount.toInt() and 0x7F) } else { output.last().toList() - } - val preparedOutput = output.dropLast(1).toTypedArray() + removedPadding.toTypedArray() + }.toUByteArray() + val preparedOutput = (output.dropLast(1) + listOf(removedPadding)) //JS compiler freaks out here if we don't supply exact type - val reversed : List> = preparedOutput.reversed() as List> - val folded : Array = reversed.foldRight(Array(0) { 0U }) { arrayOfUBytes, acc -> - acc + arrayOfUBytes } + val reversed : List = preparedOutput.reversed() as List + val folded : UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { uByteArray, acc -> + acc + uByteArray + } return folded } - private fun appendToBuffer(array: Array, start: Int) { + private fun appendToBuffer(array: UByteArray, start: Int) { array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) bufferCounter += array.size } - private fun consumeBlock(data: Array): Array { + private fun consumeBlock(data: UByteArray): UByteArray { return when (mode) { Mode.ENCRYPT -> { currentOutput = if (currentOutput.isEmpty()) { @@ -220,7 +221,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa } @ExperimentalUnsignedTypes -data class EncryptedDataAndInitializationVector(val encryptedData : Array, val initilizationVector : Array) { +data class EncryptedDataAndInitializationVector(val encryptedData : UByteArray, val initilizationVector : UByteArray) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt index c96508c..2410fae 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt @@ -37,7 +37,7 @@ import com.ionspin.kotlin.crypto.util.xor * on 22-Sep-2019 */ @ExperimentalUnsignedTypes -class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCounter: Array? = null) { +class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCounter: UByteArray? = null) { companion object { const val BLOCK_BYTES = 16 @@ -60,7 +60,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou /** * Bulk encryption, returns encrypted data and a random initial counter */ - fun encrypt(aesKey: AesKey, data: Array): EncryptedDataAndInitialCounter { + fun encrypt(aesKey: AesKey, data: UByteArray): EncryptedDataAndInitialCounter { val aesCtr = AesCtr(aesKey, Mode.ENCRYPT) aesCtr.addData(data) return aesCtr.encrypt() @@ -68,7 +68,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou /** * Bulk decryption, returns decrypted data */ - fun decrypt(aesKey: AesKey, data: Array, initialCounter: Array? = null): Array { + fun decrypt(aesKey: AesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { val aesCtr = AesCtr(aesKey, Mode.DECRYPT, initialCounter) aesCtr.addData(data) return aesCtr.decrypt() @@ -76,21 +76,21 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou } - var currentOutput: Array = arrayOf() - var previousEncrypted: Array = arrayOf() + var currentOutput: UByteArray = ubyteArrayOf() + var previousEncrypted: UByteArray = ubyteArrayOf() val counterStart = if (initialCounter.isNullOrEmpty()) { - SRNG.getRandomBytes(16).toTypedArray() + SRNG.getRandomBytes(16) } else { initialCounter } - var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart, Endianness.BIG)) + var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart.toTypedArray(), Endianness.BIG)) - val output = MutableList>(0) { arrayOf() } + val output = MutableList(0) { ubyteArrayOf() } - var buffer: Array = UByteArray(16) { 0U }.toTypedArray() + var buffer: UByteArray = UByteArray(16) { 0U } var bufferCounter = 0 - fun addData(data: Array) { + fun addData(data: UByteArray) { //Padding when { bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) @@ -98,9 +98,9 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou val chunked = data.chunked(BLOCK_BYTES) chunked.forEach { chunk -> if (bufferCounter + chunk.size < BLOCK_BYTES) { - appendToBuffer(chunk, bufferCounter) + appendToBuffer(chunk.toUByteArray(), bufferCounter) } else { - chunk.copyInto( + chunk.toUByteArray().copyInto( destination = buffer, destinationOffset = bufferCounter, startIndex = 0, @@ -108,7 +108,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou ) output += consumeBlock(buffer, blockCounter) blockCounter += 1 - buffer = Array(BLOCK_BYTES) { + buffer = UByteArray(BLOCK_BYTES) { when (it) { in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { chunk[it + (BLOCK_BYTES - bufferCounter)] @@ -136,7 +136,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou output += consumeBlock(buffer, blockCounter) } return EncryptedDataAndInitialCounter( - output.reversed().foldRight(Array(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, + output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, counterStart ) } @@ -144,25 +144,25 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou * Decrypt data * @return Decrypted data */ - fun decrypt(): Array { + fun decrypt(): UByteArray { if (bufferCounter > 0) { output += consumeBlock(buffer, blockCounter) } //JS compiler freaks out here if we don't supply exact type - val reversed: List> = output.reversed() as List> - val folded: Array = reversed.foldRight(Array(0) { 0U }) { arrayOfUBytes, acc -> + val reversed: List = output.reversed() as List + val folded: UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes } return folded } - private fun appendToBuffer(array: Array, start: Int) { + private fun appendToBuffer(array: UByteArray, start: Int) { array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) bufferCounter += array.size } - private fun consumeBlock(data: Array, blockCount: ModularBigInteger): Array { - val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).expandCounterTo16Bytes() + private fun consumeBlock(data: UByteArray, blockCount: ModularBigInteger): UByteArray { + val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).toUByteArray().expandCounterTo16Bytes() return when (mode) { Mode.ENCRYPT -> { Aes.encrypt(aesKey, blockCountAsByteArray) xor data @@ -174,11 +174,11 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou } - private fun Array.expandCounterTo16Bytes() : Array { + private fun UByteArray.expandCounterTo16Bytes() : UByteArray { return if (this.size < 16) { println("Expanding") val diff = 16 - this.size - val pad = Array(diff) { 0U } + val pad = UByteArray(diff) { 0U } pad + this } else { this @@ -188,7 +188,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou } @ExperimentalUnsignedTypes -data class EncryptedDataAndInitialCounter(val encryptedData : Array, val initialCounter : Array) { +data class EncryptedDataAndInitialCounter(val encryptedData : UByteArray, val initialCounter : UByteArray) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt index b6d6c73..abb6010 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt @@ -89,10 +89,15 @@ infix fun UByteArray.xor(other : UByteArray) : UByteArray { } @ExperimentalUnsignedTypes -fun String.hexStringToUByteArray() : Array { +fun String.hexStringToTypedUByteArray() : Array { return this.chunked(2).map { it.toUByte(16) }.toTypedArray() } +@ExperimentalUnsignedTypes +fun String.hexStringToUByteArray() : UByteArray { + return this.chunked(2).map { it.toUByte(16) }.toUByteArray() +} + @ExperimentalUnsignedTypes fun Array.toHexString() : String { return this.joinToString(separator = "") { @@ -104,6 +109,17 @@ fun Array.toHexString() : String { } } +@ExperimentalUnsignedTypes +fun UByteArray.toHexString() : String { + return this.joinToString(separator = "") { + if (it <= 0x0FU) { + "0${it.toString(16)}" + } else { + it.toString(16) + } + } +} + // UInt / Array utils @ExperimentalUnsignedTypes fun UInt.toBigEndianUByteArray() : Array { @@ -228,6 +244,19 @@ fun Array.fromBigEndianArrayToUInt() : UInt { } @ExperimentalUnsignedTypes -operator fun UInt.plus(other : Array) : Array { - return this.toLittleEndianTypedUByteArray() + other +operator fun UInt.plus(other : UByteArray) : UByteArray { + return this.toLittleEndianUByteArray() + other +} + +//AES Flatten +fun Collection.flattenToUByteArray(): UByteArray { + val result = UByteArray(sumBy { it.size }) + var position = 0 + for (element in this) { + element.forEach { uByte -> + result[position] = uByte + position++ + } + } + return result } \ No newline at end of file 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 3eedf3a..704d853 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 @@ -39,7 +39,7 @@ class ReadmeTest { val input = "abc" val result = Blake2b.digest(input) //@formatter:off - val expectedResult = arrayOf( + val expectedResult = ubyteArrayOf( 0xBAU,0x80U,0xA5U,0x3FU,0x98U,0x1CU,0x4DU,0x0DU,0x6AU,0x27U,0x97U,0xB6U,0x9FU,0x12U,0xF6U,0xE9U, 0x4CU,0x21U,0x2FU,0x14U,0x68U,0x5AU,0xC4U,0xB7U,0x4BU,0x12U,0xBBU,0x6FU,0xDBU,0xFFU,0xA2U,0xD1U, 0x7DU,0x87U,0xC5U,0x39U,0x2AU,0xABU,0x79U,0x2DU,0xC2U,0x52U,0xD5U,0xDEU,0x45U,0x33U,0xCCU,0x95U, @@ -65,7 +65,7 @@ class ReadmeTest { } val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" + "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") - .chunked(2).map { it.toUByte(16) }.toTypedArray() + .chunked(2).map { it.toUByte(16) }.toUByteArray() assertTrue { result.contentEquals(expectedResult) @@ -79,7 +79,7 @@ class ReadmeTest { val result = Sha256.digest(inputString = input) val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } @@ -89,12 +89,12 @@ class ReadmeTest { @Test fun sha512Example() { val input = "abc" - val result = Sha512.digest(inputMessage = input.encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val result = Sha512.digest(inputMessage = input.encodeToByteArray().map { it.toUByte() }.toUByteArray()) println(result.map { it.toString(16) }) val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } @@ -108,7 +108,7 @@ class ReadmeTest { val result = sha256.digest() val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -121,7 +121,7 @@ class ReadmeTest { val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt index 852e7dc..3c2f57d 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt @@ -48,7 +48,7 @@ class Blake2BTest { val result = Blake2b.digest(test) //Generated with b2sum 8.31 - val expectedResult = arrayOf( + val expectedResult = ubyteArrayOf( //@formatter:off 0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU, @@ -81,7 +81,7 @@ class Blake2BTest { val expectedResultString = "800bb78cd4da18995c8074713bb674" + "3cd94b2b6490a693fe4000ed00833b88b7b474d94af9cfed246b1b" + "4ce1935a76154d7ea7c410493557741d18ec3a08da75" - val expectedResult = expectedResultString.chunked(2).map { it.toUByte(16) }.toTypedArray() + val expectedResult = expectedResultString.chunked(2).map { it.toUByte(16) }.toUByteArray() assertTrue { result.contentEquals(expectedResult) @@ -95,7 +95,7 @@ class Blake2BTest { val result = Blake2b.digest(test) //Generated with b2sum 8.31 - val expectedResult = arrayOf( + val expectedResult = ubyteArrayOf( //@formatter:off 0xe0U, 0xabU, 0xb7U, 0x5dU, 0xb2U, 0xc8U, 0xe1U, 0x3cU, 0x5fU, 0x1dU, 0x9fU, 0x55U, 0xc8U, 0x4eU, 0xacU, 0xd7U, 0xa8U, 0x44U, 0x57U, 0x9bU, 0xc6U, 0x9cU, 0x47U, 0x26U, 0xebU, 0xeaU, 0x2bU, 0xafU, 0x9eU, 0x44U, 0x16U, 0xebU, @@ -122,7 +122,7 @@ class Blake2BTest { } val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" + "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") - .chunked(2).map { it.toUByte(16) }.toTypedArray() + .chunked(2).map { it.toUByte(16) }.toUByteArray() assertTrue { result.contentEquals(expectedResult) @@ -136,7 +136,7 @@ class Blake2BTest { val result = Blake2b.digest(test) //@formatter:off - val expectedResult = arrayOf( + val expectedResult = ubyteArrayOf( 0xBAU,0x80U,0xA5U,0x3FU,0x98U,0x1CU,0x4DU,0x0DU,0x6AU,0x27U,0x97U,0xB6U,0x9FU,0x12U,0xF6U,0xE9U, 0x4CU,0x21U,0x2FU,0x14U,0x68U,0x5AU,0xC4U,0xB7U,0x4BU,0x12U,0xBBU,0x6FU,0xDBU,0xFFU,0xA2U,0xD1U, diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt index 44eaaa0..91ddf8f 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt @@ -32,7 +32,7 @@ class Blake2bInstanceTest { fun testUpdatableBlake2b() { val updates = 14 val input = "1234567890" - val expectedResult = arrayOf( + val expectedResult = ubyteArrayOf( //@formatter:off 0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU, @@ -83,7 +83,7 @@ class Blake2bInstanceTest { } val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" + "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") - .chunked(2).map { it.toUByte(16) }.toTypedArray() + .chunked(2).map { it.toUByte(16) }.toUByteArray() assertTrue { result.contentEquals(expectedResult) diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt index c1c4bab..eae5b08 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt @@ -36,13 +36,13 @@ class Blake2bKnowAnswerTests { @Test fun knownAnswerTest() { kat.forEach { - val parsedInput = it.input.chunked(2).map { it.toUByte(16) }.toTypedArray() + val parsedInput = it.input.chunked(2).map { it.toUByte(16) }.toUByteArray() val result = Blake2b.digest( inputMessage = parsedInput, - key = it.key.chunked(2).map { it.toUByte(16) }.toTypedArray() + key = it.key.chunked(2).map { it.toUByte(16) }.toUByteArray() ) assertTrue { - result.contentEquals(it.hash.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(it.hash.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } } @@ -51,13 +51,13 @@ class Blake2bKnowAnswerTests { fun knownAnswerTestInstance() { kat.forEach { kat -> - val parsedInput = kat.input.chunked(2).map { it.toUByte(16) }.toTypedArray() - val chunkedInput = parsedInput.toList().chunked(128).map { it.toTypedArray() }.toTypedArray() - val blake2b = Blake2b(key = kat.key.chunked(2).map { it.toUByte(16) }.toTypedArray()) + val parsedInput = kat.input.chunked(2).map { it.toUByte(16) }.toUByteArray() + val chunkedInput = parsedInput.toList().chunked(128).map { it.toUByteArray() } + val blake2b = Blake2b(key = kat.key.chunked(2).map { it.toUByte(16) }.toUByteArray()) chunkedInput.forEach { blake2b.update(it) } val result = blake2b.digest() assertTrue("KAT ${kat.input} \nkey: ${kat.key} \nexpected: {${kat.hash}") { - result.contentEquals(kat.hash.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(kat.hash.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } } diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt index 7aec043..39b6c24 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt @@ -34,7 +34,7 @@ class Sha256Test { val result = Sha256.digest(inputString = "abc") val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } @@ -47,7 +47,7 @@ class Sha256Test { val resultDoubleBlock = Sha256.digest(inputString = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -60,7 +60,7 @@ class Sha256Test { println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -71,10 +71,10 @@ class Sha256Test { for (i in 0 until 1000000) { inputBuilder.append("a") } - val resultDoubleBlock = Sha256.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val resultDoubleBlock = Sha256.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toUByteArray()) val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt index 620d2fd..bdb0db4 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt @@ -36,7 +36,7 @@ class Sha256UpdatableTest { val result = sha256.digest() val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -49,7 +49,7 @@ class Sha256UpdatableTest { println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -62,7 +62,7 @@ class Sha256UpdatableTest { println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -76,7 +76,7 @@ class Sha256UpdatableTest { val resultDoubleBlock = sha256.digest() val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -94,7 +94,7 @@ class Sha256UpdatableTest { val resultDoubleBlock = sha256.digest() val expectedResultForDoubleBlock = "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt index 353c79d..c83c85d 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt @@ -30,12 +30,12 @@ class Sha512Test { @Test fun testWellKnownValue() { - val result = Sha512.digest(inputMessage = "abc".encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val result = Sha512.digest(inputMessage = "abc".encodeToByteArray().map { it.toUByte() }.toUByteArray()) println(result.map {it.toString(16)}) val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } @@ -51,7 +51,7 @@ class Sha512Test { val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" + "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -62,10 +62,10 @@ class Sha512Test { for (i in 0 until 1000000) { inputBuilder.append("a") } - val resultDoubleBlock = Sha512.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toTypedArray()) + val resultDoubleBlock = Sha512.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toUByteArray()) val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt index 9facd3b..e2471d9 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt @@ -35,7 +35,7 @@ class Sha512UpdatableTest { val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) } @@ -51,7 +51,7 @@ class Sha512UpdatableTest { val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" + "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -65,7 +65,7 @@ class Sha512UpdatableTest { val resultDoubleBlock = sha512.digest() val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } @@ -83,7 +83,7 @@ class Sha512UpdatableTest { val resultDoubleBlock = sha512.digest() val expectedResultForDoubleBlock = "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toTypedArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } } } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt index f0bada0..dc34234 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt @@ -16,6 +16,7 @@ package com.ionspin.kotlin.crypto.symmetric +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import com.ionspin.kotlin.crypto.util.toHexString import kotlin.test.Test diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt index 1ac2f90..ca3ef4f 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt @@ -10,15 +10,15 @@ import kotlin.test.assertTrue class AesTest { val irrelevantKey = "01234567890123345678901234567890" - val irrelevantInput = UByteArray(16) { 0U }.toTypedArray() + val irrelevantInput = UByteArray(16) { 0U } @Test fun testSubBytes() { val fakeState = arrayOf( - ubyteArrayOf(0x53U, 0U, 0U, 0U).toTypedArray(), - ubyteArrayOf(0U, 0U, 0U, 0U).toTypedArray(), - ubyteArrayOf(0U, 0U, 0U, 0U).toTypedArray(), - ubyteArrayOf(0U, 0U, 0U, 0U).toTypedArray() + ubyteArrayOf(0x53U, 0U, 0U, 0U), + ubyteArrayOf(0U, 0U, 0U, 0U), + ubyteArrayOf(0U, 0U, 0U, 0U), + ubyteArrayOf(0U, 0U, 0U, 0U) ) val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput) fakeState.copyInto(aes.state) @@ -31,16 +31,16 @@ class AesTest { @Test fun testShiftRows() { val fakeState = arrayOf( - ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), - ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), - ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), - ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray() + ubyteArrayOf(0U, 1U, 2U, 3U), + ubyteArrayOf(0U, 1U, 2U, 3U), + ubyteArrayOf(0U, 1U, 2U, 3U), + ubyteArrayOf(0U, 1U, 2U, 3U) ) val expectedState = arrayOf( - ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), - ubyteArrayOf(1U, 2U, 3U, 0U).toTypedArray(), - ubyteArrayOf(2U, 3U, 0U, 1U).toTypedArray(), - ubyteArrayOf(3U, 0U, 1U, 2U).toTypedArray() + ubyteArrayOf(0U, 1U, 2U, 3U), + ubyteArrayOf(1U, 2U, 3U, 0U), + ubyteArrayOf(2U, 3U, 0U, 1U), + ubyteArrayOf(3U, 0U, 1U, 2U) ) val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput) fakeState.copyInto(aes.state) @@ -76,17 +76,17 @@ class AesTest { fun testMixColumns() { //Test vectors from wikipedia val fakeState = arrayOf( - ubyteArrayOf(0xdbU, 0xf2U, 0x01U, 0xc6U).toTypedArray(), - ubyteArrayOf(0x13U, 0x0aU, 0x01U, 0xc6U).toTypedArray(), - ubyteArrayOf(0x53U, 0x22U, 0x01U, 0xc6U).toTypedArray(), - ubyteArrayOf(0x45U, 0x5cU, 0x01U, 0xc6U).toTypedArray() + ubyteArrayOf(0xdbU, 0xf2U, 0x01U, 0xc6U), + ubyteArrayOf(0x13U, 0x0aU, 0x01U, 0xc6U), + ubyteArrayOf(0x53U, 0x22U, 0x01U, 0xc6U), + ubyteArrayOf(0x45U, 0x5cU, 0x01U, 0xc6U) ) val expectedState = arrayOf( - ubyteArrayOf(0x8eU, 0x9fU, 0x01U, 0xc6U).toTypedArray(), - ubyteArrayOf(0x4dU, 0xdcU, 0x01U, 0xc6U).toTypedArray(), - ubyteArrayOf(0xa1U, 0x58U, 0x01U, 0xc6U).toTypedArray(), - ubyteArrayOf(0xbcU, 0x9dU, 0x01U, 0xc6U).toTypedArray() + ubyteArrayOf(0x8eU, 0x9fU, 0x01U, 0xc6U), + ubyteArrayOf(0x4dU, 0xdcU, 0x01U, 0xc6U), + ubyteArrayOf(0xa1U, 0x58U, 0x01U, 0xc6U), + ubyteArrayOf(0xbcU, 0x9dU, 0x01U, 0xc6U) ) val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput) @@ -183,10 +183,10 @@ class AesTest { val key = "2b7e151628aed2a6abf7158809cf4f3c" val expectedResult = "3925841d02dc09fbdc118597196a0b32" - val aes = Aes(AesKey.Aes128Key(key), input.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray()) + val aes = Aes(AesKey.Aes128Key(key), input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) val result = aes.encrypt() assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray()) + result.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) } } @@ -196,11 +196,11 @@ class AesTest { val input = "3243f6a8885a308d313198a2e0370734" val key = "2b7e151628aed2a6abf7158809cf4f3c" val expectedResult = "3925841d02dc09fbdc118597196a0b32" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray() + val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() val aes = Aes(AesKey.Aes128Key(key), original) val encrypted = aes.encrypt() assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray()) + encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) } val decrypted = Aes.decrypt(AesKey.Aes128Key(key), encrypted) @@ -210,57 +210,57 @@ class AesTest { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f" val expectedResult = "69c4e0d86a7b0430d8cdb78070b4c55a" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray() + val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() val aes = Aes(AesKey.Aes128Key(key), original) val encrypted = aes.encrypt() assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray()) + encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) } val aesDec = Aes(AesKey.Aes128Key(key), encrypted) val decrypted = aesDec.decrypt() assertTrue { aesDec.expandedKey.contentDeepEquals(aes.expandedKey) } - decrypted.contentDeepEquals(original) + decrypted.contentEquals(original) } assertTrue { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f" val expectedResult = "69c4e0d86a7b0430d8cdb78070b4c55a" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray() + val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() val encrypted = Aes.encrypt(AesKey.Aes128Key(key), original) assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray()) + encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) } val decrypted = Aes.decrypt(AesKey.Aes128Key(key), encrypted) - decrypted.contentDeepEquals(original) + decrypted.contentEquals(original) } assertTrue { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f1011121314151617" val expectedResult = "dda97ca4864cdfe06eaf70a0ec0d7191" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray() + val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() val encrypted = Aes.encrypt(AesKey.Aes192Key(key), original) assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray()) + encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) } val decrypted = Aes.decrypt(AesKey.Aes192Key(key), encrypted) - decrypted.contentDeepEquals(original) + decrypted.contentEquals(original) } assertTrue { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" val expectedResult = "8ea2b7ca516745bfeafc49904b496089" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray() + val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() val encrypted = Aes.encrypt(AesKey.Aes256Key(key), original) assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toTypedArray()) + encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) } val decrypted = Aes.decrypt(AesKey.Aes256Key(key), encrypted) - decrypted.contentDeepEquals(original) + decrypted.contentEquals(original) } } diff --git a/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt b/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt index 7bc4879..56849d5 100644 --- a/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt +++ b/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt @@ -29,8 +29,10 @@ actual object SRNG { actual fun getRandomBytes(amount: Int): UByteArray { val runningOnNode = jsTypeOf(window) == "undefined" val randomBytes = if (runningOnNode) { + println("Running on node") js("require('crypto')").randomBytes(amount).toJSON().data } else { + println("Running in browser") js( """ var randomArray = new Uint8Array(amount); @@ -41,7 +43,21 @@ actual object SRNG { var randomArrayResult = js("Array.prototype.slice.call(randomArray);") randomArrayResult } + println("Random bytes: $randomBytes") + print("Byte at ${randomBytes[0]}") + val randomBytesUByteArray = UByteArray(amount) { + 0U + } + for (i in 0 until amount) { + println("Setting ${randomBytes[i]}") + js(""" + randomBytesUByteArray[i] = randomBytes[i] + """) + println("Set value ${randomBytesUByteArray[i]}") + } - return randomBytes as UByteArray + return randomBytesUByteArray } + + } \ No newline at end of file diff --git a/multiplatform-crypto/src/jsTest/kotlin/com/ionspin/kotlin/crypto/SRNGJsTest.kt b/multiplatform-crypto/src/jsTest/kotlin/com/ionspin/kotlin/crypto/SRNGJsTest.kt index 55981de..95d5291 100644 --- a/multiplatform-crypto/src/jsTest/kotlin/com/ionspin/kotlin/crypto/SRNGJsTest.kt +++ b/multiplatform-crypto/src/jsTest/kotlin/com/ionspin/kotlin/crypto/SRNGJsTest.kt @@ -31,6 +31,14 @@ class SRNGJsTest { fun testJsSrng() { val bytes1 = SRNG.getRandomBytes(10) val bytes2 = SRNG.getRandomBytes(10) + println("BYTES1") + bytes1.forEach { + print(it.toString(16).padStart(2, '0')) + } + println("BYTES2") + bytes2.forEach { + print(it.toString(16).padStart(2, '0')) + } assertTrue { !bytes1.contentEquals(bytes2) && bytes1.size == 10 &&