Migrate everything to UByteArray
This commit is contained in:
		
							parent
							
								
									4ea04eb90d
								
							
						
					
					
						commit
						34a86cd9c7
					
				| @ -28,23 +28,23 @@ interface Hash { | ||||
| 
 | ||||
| @ExperimentalUnsignedTypes | ||||
| interface UpdatableHash : Hash { | ||||
|     fun update(data : Array<UByte>) | ||||
|     fun update(data : UByteArray) | ||||
| 
 | ||||
|     fun update(data : String) | ||||
| 
 | ||||
|     fun digest() : Array<UByte> | ||||
|     fun digest() : UByteArray | ||||
| 
 | ||||
|     fun digestString() : String | ||||
| } | ||||
| 
 | ||||
| @ExperimentalUnsignedTypes | ||||
| interface StatelessHash : Hash { | ||||
|     fun digest(inputString: String, key: String? = null, hashLength: Int = MAX_HASH_BYTES): Array<UByte> | ||||
|     fun digest(inputString: String, key: String? = null, hashLength: Int = MAX_HASH_BYTES): UByteArray | ||||
| 
 | ||||
|     fun digest( | ||||
|         inputMessage: Array<UByte> = emptyArray(), | ||||
|         key: Array<UByte> = emptyArray(), | ||||
|         inputMessage: UByteArray = ubyteArrayOf(), | ||||
|         key: UByteArray = ubyteArrayOf(), | ||||
|         hashLength: Int = MAX_HASH_BYTES | ||||
|     ): Array<UByte> | ||||
|     ): UByteArray | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -31,10 +31,14 @@ import com.ionspin.kotlin.crypto.util.rotateRight | ||||
|  */ | ||||
| 
 | ||||
| @ExperimentalUnsignedTypes | ||||
| class Blake2b(val key: Array<UByte>? = 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<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
| 
 | ||||
|         fun compress( | ||||
|             h: Array<ULong>, | ||||
|             input: Array<UByte>, | ||||
|             input: UByteArray, | ||||
|             offsetCounter: BigInteger, | ||||
|             finalBlock: Boolean | ||||
|         ): Array<ULong> { | ||||
| @ -145,24 +149,24 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|         } | ||||
| 
 | ||||
|         @ExperimentalStdlibApi | ||||
|         override fun digest(inputString: String, key: String?, hashLength: Int): Array<UByte> { | ||||
|             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<UByte>, | ||||
|             key: Array<UByte>, | ||||
|             inputMessage: UByteArray, | ||||
|             key: UByteArray, | ||||
|             hashLength: Int | ||||
|         ): Array<UByte> { | ||||
|         ): 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<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|             val message = if (key.isEmpty()) { | ||||
|                 if (chunkedMessage.isEmpty()) { | ||||
|                     Array(1) { | ||||
|                         Array<UByte>(128) { | ||||
|                         UByteArray(128) { | ||||
|                             0U | ||||
|                         } | ||||
|                     } | ||||
| @ -199,7 +203,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|             val lastBlockPadded = if (message.isNotEmpty()) { | ||||
|                 padToBlock(message[message.size - 1]) | ||||
|             } else { | ||||
|                 Array<UByte>(16) { 0U } | ||||
|                 UByteArray(16) { 0U } | ||||
|             } | ||||
| 
 | ||||
|             compress(h, lastBlockPadded, lastSize.toBigInteger(), true).copyInto(h) | ||||
| @ -208,7 +212,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|             return formatResult(h).copyOfRange(0, hashLength) | ||||
|         } | ||||
| 
 | ||||
|         private fun formatResult(h: Array<ULong>): Array<UByte> { | ||||
|         private fun formatResult(h: Array<ULong>): UByteArray { | ||||
|             return h.map { | ||||
|                 arrayOf( | ||||
|                     (it and 0xFFUL).toUByte(), | ||||
| @ -222,10 +226,10 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|                 ) | ||||
|             }.flatMap { | ||||
|                 it.toList() | ||||
|             }.toTypedArray() | ||||
|             }.toUByteArray() | ||||
|         } | ||||
| 
 | ||||
|         private fun padToBlock(unpadded: Array<UByte>): Array<UByte> { | ||||
|         private fun padToBlock(unpadded: UByteArray): UByteArray { | ||||
|             if (unpadded.size == BLOCK_BYTES) { | ||||
|                 return unpadded | ||||
|             } | ||||
| @ -234,7 +238,7 @@ class Blake2b(val key: Array<UByte>? = 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<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|         key: String?, | ||||
|         requestedHashLenght: Int = 64 | ||||
|     ) : this( | ||||
|         (key?.encodeToByteArray()?.map { it.toUByte() }?.toTypedArray() ?: emptyArray<UByte>()), | ||||
|         (key?.encodeToByteArray()?.toUByteArray() ?: ubyteArrayOf()), | ||||
|         requestedHashLenght | ||||
|     ) | ||||
| 
 | ||||
| @ -257,7 +261,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|     var h = iv.copyOf() | ||||
|     var counter = BigInteger.ZERO | ||||
|     var bufferCounter = 0 | ||||
|     var buffer = Array<UByte>(BLOCK_BYTES) { 0U } | ||||
|     var buffer = UByteArray(BLOCK_BYTES) { 0U } | ||||
| 
 | ||||
| 
 | ||||
|     init { | ||||
| @ -268,7 +272,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun update(data: Array<UByte>) { | ||||
|     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<UByte>? = 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<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|                         ) | ||||
|                         counter += BLOCK_BYTES | ||||
|                         consumeBlock(buffer) | ||||
|                         buffer = Array<UByte>(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<UByte>? = 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<UByte>, 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<UByte>) { | ||||
|     private fun consumeBlock(block: UByteArray) { | ||||
|         h = compress(h, block, counter, false) | ||||
|     } | ||||
| 
 | ||||
|     override fun digest(): Array<UByte> { | ||||
|     override fun digest(): UByteArray { | ||||
|         val lastBlockPadded = padToBlock(buffer) | ||||
|         counter += bufferCounter | ||||
|         compress(h, lastBlockPadded, counter, true) | ||||
| @ -341,7 +345,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab | ||||
|         h = iv.copyOf() | ||||
|         counter = BigInteger.ZERO | ||||
|         bufferCounter = 0 | ||||
|         buffer = Array<UByte>(BLOCK_BYTES) { 0U } | ||||
|         buffer = UByteArray(BLOCK_BYTES) { 0U } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -67,14 +67,14 @@ class Sha256 : UpdatableHash { | ||||
|         ) | ||||
| 
 | ||||
|         @ExperimentalStdlibApi | ||||
|         override fun digest(inputString: String, key: String?, hashLength: Int): Array<UByte> { | ||||
|         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<UByte>(), | ||||
|                 inputString.encodeToByteArray().toUByteArray(), | ||||
|                 key?.run { encodeToByteArray().toUByteArray()} ?: ubyteArrayOf(), | ||||
|                 hashLength) | ||||
|         } | ||||
| 
 | ||||
|         override fun digest(inputMessage: Array<UByte>, key: Array<UByte>, hashLength: Int): Array<UByte> { | ||||
|         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<UByte>): Array<UInt> { | ||||
|         private fun expandChunk(chunk: UByteArray): Array<UInt> { | ||||
|             val w = Array<UInt>(BLOCK_SIZE_IN_BYTES) { | ||||
|                 when (it) { | ||||
|                     in 0 until 16 -> { | ||||
| @ -188,7 +188,7 @@ class Sha256 : UpdatableHash { | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         fun createExpansionArray(originalSizeInBytes: Int): Array<UByte> { | ||||
|         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<UByte>(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<UByte> { | ||||
|         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<UByte> { | ||||
|         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<UByte>(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<UByte>) { | ||||
|     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<UByte>(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<UByte>) { | ||||
|     private fun consumeBlock(block: UByteArray) { | ||||
|         val w = expandChunk(block) | ||||
|         mix(h, w).copyInto(h) | ||||
|     } | ||||
| 
 | ||||
|     override fun digest(): Array<UByte> { | ||||
|     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<UByte>, start: Int) { | ||||
|     private fun appendToBuffer(array: UByteArray, start: Int) { | ||||
|         array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) | ||||
|         bufferCounter += array.size | ||||
|     } | ||||
|  | ||||
| @ -135,15 +135,15 @@ class Sha512 : UpdatableHash { | ||||
|         ) | ||||
| 
 | ||||
|         @ExperimentalStdlibApi | ||||
|         override fun digest(inputString: String, key: String?, hashLength: Int): Array<UByte> { | ||||
|         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<UByte>(), | ||||
|                 inputString.encodeToByteArray().toUByteArray(), | ||||
|                 key?.run { encodeToByteArray().toUByteArray() } ?: ubyteArrayOf(), | ||||
|                 hashLength = hashLength | ||||
|             ) | ||||
|         } | ||||
| 
 | ||||
|         override fun digest(inputMessage: Array<UByte>, key: Array<UByte>, hashLength: Int): Array<UByte> { | ||||
|         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<UByte>): Array<ULong> { | ||||
|         private fun expandChunk(chunk: UByteArray): Array<ULong> { | ||||
|             val w = Array<ULong>(CHUNK_SIZE) { | ||||
|                 when (it) { | ||||
|                     in 0 until 16 -> { | ||||
| @ -259,7 +259,7 @@ class Sha512 : UpdatableHash { | ||||
|             return h | ||||
|         } | ||||
| 
 | ||||
|         fun createExpansionArray(originalSizeInBytes: Int): Array<UByte> { | ||||
|         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<UByte>(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<UByte> { | ||||
|         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<UByte> { | ||||
|         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<UByte>(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<UByte>) { | ||||
|     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<UByte>(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<UByte>) { | ||||
|     private fun consumeBlock(block: UByteArray) { | ||||
|         val w = expandChunk(block) | ||||
|         mix(h, w).copyInto(h) | ||||
|     } | ||||
| 
 | ||||
|     override fun digest(): Array<UByte> { | ||||
|     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<UByte>, start: Int) { | ||||
|     private fun appendToBuffer(array: UByteArray, start: Int) { | ||||
|         array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) | ||||
|         bufferCounter += array.size | ||||
|     } | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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<UByteArray>(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)) | ||||
|  | ||||
| @ -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<UByte>) { | ||||
| 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<UBy | ||||
| 
 | ||||
|         val rcon: UByteArray = ubyteArrayOf(0x8DU, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U, 0x1BU, 0x36U) | ||||
| 
 | ||||
|         fun encrypt(aesKey: AesKey, input: Array<UByte>): Array<UByte> { | ||||
|         fun encrypt(aesKey: AesKey, input: UByteArray): UByteArray { | ||||
|             return Aes(aesKey, input).encrypt() | ||||
|         } | ||||
| 
 | ||||
|         fun decrypt(aesKey: AesKey, input: Array<UByte>): Array<UByte> { | ||||
|         fun decrypt(aesKey: AesKey, input: UByteArray): UByteArray { | ||||
|             return Aes(aesKey, input).decrypt() | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     val state: Array<Array<UByte>> = (0 until 4).map { outerCounter -> | ||||
|         Array<UByte>(4) { innerCounter -> input[innerCounter * 4 + outerCounter] } | ||||
|     val state: Array<UByteArray> = (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<UBy | ||||
|         is AesKey.Aes256Key -> 14 | ||||
|     } | ||||
| 
 | ||||
|     val expandedKey: Array<Array<UByte>> = expandKey() | ||||
|     val expandedKey: Array<UByteArray> = expandKey() | ||||
| 
 | ||||
| 
 | ||||
|     var round = 0 | ||||
| @ -110,22 +112,22 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy | ||||
|     } | ||||
| 
 | ||||
|     fun shiftRows() { | ||||
|         state[0] = arrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) | ||||
|         state[1] = arrayOf(state[1][1], state[1][2], state[1][3], state[1][0]) | ||||
|         state[2] = arrayOf(state[2][2], state[2][3], state[2][0], state[2][1]) | ||||
|         state[3] = arrayOf(state[3][3], state[3][0], state[3][1], state[3][2]) | ||||
|         state[0] = ubyteArrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) | ||||
|         state[1] = ubyteArrayOf(state[1][1], state[1][2], state[1][3], state[1][0]) | ||||
|         state[2] = ubyteArrayOf(state[2][2], state[2][3], state[2][0], state[2][1]) | ||||
|         state[3] = ubyteArrayOf(state[3][3], state[3][0], state[3][1], state[3][2]) | ||||
|     } | ||||
| 
 | ||||
|     fun inversShiftRows() { | ||||
|         state[0] = arrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) | ||||
|         state[1] = arrayOf(state[1][3], state[1][0], state[1][1], state[1][2]) | ||||
|         state[2] = arrayOf(state[2][2], state[2][3], state[2][0], state[2][1]) | ||||
|         state[3] = arrayOf(state[3][1], state[3][2], state[3][3], state[3][0]) | ||||
|         state[0] = ubyteArrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) | ||||
|         state[1] = ubyteArrayOf(state[1][3], state[1][0], state[1][1], state[1][2]) | ||||
|         state[2] = ubyteArrayOf(state[2][2], state[2][3], state[2][0], state[2][1]) | ||||
|         state[3] = ubyteArrayOf(state[3][1], state[3][2], state[3][3], state[3][0]) | ||||
|     } | ||||
| 
 | ||||
|     fun mixColumns() { | ||||
|         val stateMixed: Array<Array<UByte>> = (0 until 4).map { | ||||
|             Array<UByte>(4) { 0U } | ||||
|         val stateMixed: Array<UByteArray> = (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<UBy | ||||
|     } | ||||
| 
 | ||||
|     fun inverseMixColumns() { | ||||
|         val stateMixed: Array<Array<UByte>> = (0 until 4).map { | ||||
|             Array<UByte>(4) { 0U } | ||||
|         val stateMixed: Array<UByteArray> = (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<UBy | ||||
|         return galoisFieldMultiply(this.toUByte(), second) | ||||
|     } | ||||
| 
 | ||||
|     fun expandKey(): Array<Array<UByte>> { | ||||
|     fun expandKey(): Array<UByteArray> { | ||||
|         val expandedKey = (0 until 4 * (numberOfRounds + 1)).map { | ||||
|             Array<UByte>(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<UBy | ||||
|             } | ||||
|             expandedKey[i] = expandedKey[i - aesKey.numberOf32BitWords].mapIndexed { index, it -> | ||||
|                 it xor temp[index] | ||||
|             }.toTypedArray() | ||||
|             }.toUByteArray() | ||||
|             clearArray(temp) | ||||
|         } | ||||
|         return expandedKey | ||||
|     } | ||||
| 
 | ||||
|     fun encrypt(): Array<UByte> { | ||||
|     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<UBy | ||||
|         addRoundKey() | ||||
|         printState() | ||||
|         val transposedMatrix = (0 until 4).map { outerCounter -> | ||||
|             Array<UByte>(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<UBy | ||||
|         } | ||||
|         state.forEach { clearArray(it) } | ||||
|         completed = true | ||||
|         return transposedMatrix.flatten().toTypedArray() | ||||
|         return transposedMatrix.flattenToUByteArray() | ||||
|     } | ||||
| 
 | ||||
|     fun decrypt(): Array<UByte> { | ||||
|     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<UBy | ||||
|         printState() | ||||
| 
 | ||||
|         val transposedMatrix =  (0 until 4).map { outerCounter -> | ||||
|             Array<UByte>(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<UByte>) { | ||||
|     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<UBy | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun printState(specific : Array<Array<UByte>>) { | ||||
|     private fun printState(specific : List<UByteArray>) { | ||||
|         if (!debug) { | ||||
|             return | ||||
|         } | ||||
| @ -356,7 +357,7 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy | ||||
| } | ||||
| 
 | ||||
| sealed class AesKey(val key: String, val keyLength: Int) { | ||||
|     val keyArray: Array<UByte> = 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) | ||||
|  | ||||
| @ -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<UByte>? = 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<UByte>): 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<UByte>, initialCounter: Array<UByte>? = null): Array<UByte> { | ||||
|         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<UByte>): Array<UByte> { | ||||
|         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<UByte> = arrayOf() | ||||
|     var previousEncrypted: Array<UByte> = 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<Array<UByte>>(0) { arrayOf() } | ||||
|     val output = MutableList<UByteArray>(0) { ubyteArrayOf() } | ||||
| 
 | ||||
|     var buffer: Array<UByte> = UByteArray(16) { 0U }.toTypedArray() | ||||
|     var buffer: UByteArray = UByteArray(16) { 0U } | ||||
|     var bufferCounter = 0 | ||||
| 
 | ||||
|     fun addData(data: Array<UByte>) { | ||||
|     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<UByte>(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<UByte>(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<UByte> { | ||||
|     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<Array<UByte>> = preparedOutput.reversed() as List<Array<UByte>> | ||||
|         val folded : Array<UByte> = reversed.foldRight(Array<UByte>(0) { 0U }) { arrayOfUBytes, acc -> | ||||
|             acc + arrayOfUBytes } | ||||
|         val reversed : List<UByteArray> = preparedOutput.reversed() as List<UByteArray> | ||||
|         val folded : UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { uByteArray, acc -> | ||||
|             acc + uByteArray | ||||
|         } | ||||
|         return folded | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private fun appendToBuffer(array: Array<UByte>, 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<UByte>): Array<UByte> { | ||||
|     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<UByte>, val initilizationVector : Array<UByte>) { | ||||
| 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 | ||||
|  | ||||
| @ -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<UByte>? = 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<UByte>): 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<UByte>, initialCounter: Array<UByte>? = null): Array<UByte> { | ||||
|         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<UByte> = arrayOf() | ||||
|     var previousEncrypted: Array<UByte> = 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<Array<UByte>>(0) { arrayOf() } | ||||
|     val output = MutableList<UByteArray>(0) { ubyteArrayOf() } | ||||
| 
 | ||||
|     var buffer: Array<UByte> = UByteArray(16) { 0U }.toTypedArray() | ||||
|     var buffer: UByteArray = UByteArray(16) { 0U } | ||||
|     var bufferCounter = 0 | ||||
| 
 | ||||
|     fun addData(data: Array<UByte>) { | ||||
|     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<UByte>(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<UByte>(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<UByte> { | ||||
|     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<Array<UByte>> = output.reversed() as List<Array<UByte>> | ||||
|         val folded: Array<UByte> = reversed.foldRight(Array<UByte>(0) { 0U }) { arrayOfUBytes, acc -> | ||||
|         val reversed: List<UByteArray> = output.reversed() as List<UByteArray> | ||||
|         val folded: UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> | ||||
|             acc + arrayOfUBytes | ||||
|         } | ||||
|         return folded | ||||
|     } | ||||
| 
 | ||||
|     private fun appendToBuffer(array: Array<UByte>, 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<UByte>, blockCount: ModularBigInteger): Array<UByte> { | ||||
|         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<UByte>.expandCounterTo16Bytes() : Array<UByte> { | ||||
|     private fun UByteArray.expandCounterTo16Bytes() : UByteArray { | ||||
|         return if (this.size < 16) { | ||||
|             println("Expanding") | ||||
|             val diff = 16 - this.size | ||||
|             val pad = Array<UByte>(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<UByte>, val initialCounter : Array<UByte>) { | ||||
| 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 | ||||
|  | ||||
| @ -89,10 +89,15 @@ infix fun UByteArray.xor(other : UByteArray) : UByteArray { | ||||
| } | ||||
| 
 | ||||
| @ExperimentalUnsignedTypes | ||||
| fun String.hexStringToUByteArray() : Array<UByte> { | ||||
| fun String.hexStringToTypedUByteArray() : Array<UByte> { | ||||
|     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<UByte>.toHexString() : String { | ||||
|     return this.joinToString(separator = "") { | ||||
| @ -104,6 +109,17 @@ fun Array<UByte>.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<UByte> { | ||||
| @ -228,6 +244,19 @@ fun Array<UByte>.fromBigEndianArrayToUInt() : UInt { | ||||
| } | ||||
| 
 | ||||
| @ExperimentalUnsignedTypes | ||||
| operator fun UInt.plus(other : Array<UByte>) : Array<UByte> { | ||||
|     return this.toLittleEndianTypedUByteArray() + other | ||||
| operator fun UInt.plus(other : UByteArray) : UByteArray { | ||||
|     return this.toLittleEndianUByteArray() + other | ||||
| } | ||||
| 
 | ||||
| //AES Flatten | ||||
| fun Collection<UByteArray>.flattenToUByteArray(): UByteArray { | ||||
|     val result = UByteArray(sumBy { it.size }) | ||||
|     var position = 0 | ||||
|     for (element in this) { | ||||
|         element.forEach { uByte -> | ||||
|             result[position] = uByte | ||||
|             position++ | ||||
|         } | ||||
|     } | ||||
|     return result | ||||
| } | ||||
| @ -39,7 +39,7 @@ class ReadmeTest { | ||||
|         val input = "abc" | ||||
|         val result = Blake2b.digest(input) | ||||
|         //@formatter:off | ||||
|         val expectedResult = arrayOf<UByte>( | ||||
|         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()) | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -48,7 +48,7 @@ class Blake2BTest { | ||||
| 
 | ||||
|         val result = Blake2b.digest(test) | ||||
|         //Generated with b2sum 8.31 | ||||
|         val expectedResult = arrayOf<UByte>( | ||||
|         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<UByte>( | ||||
|         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<UByte>( | ||||
|         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, | ||||
|  | ||||
| @ -32,7 +32,7 @@ class Blake2bInstanceTest { | ||||
|     fun testUpdatableBlake2b() { | ||||
|         val updates = 14 | ||||
|         val input = "1234567890" | ||||
|         val expectedResult = arrayOf<UByte>( | ||||
|         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) | ||||
|  | ||||
| @ -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()) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -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()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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 | ||||
|  | ||||
| @ -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) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -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 && | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user