Migrate everything to UByteArray

This commit is contained in:
Ugljesa Jovanovic 2020-05-21 12:34:14 +02:00 committed by Ugljesa Jovanovic
parent 4ea04eb90d
commit 34a86cd9c7
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
22 changed files with 306 additions and 246 deletions

View File

@ -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
}

View File

@ -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 }
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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) {

View File

@ -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))

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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())
}

View File

@ -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,

View File

@ -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)

View File

@ -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())
}
}
}

View File

@ -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())
}
}
}

View File

@ -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())
}
}
}

View File

@ -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())
}
}
}

View File

@ -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())
}
}
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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
}
}

View File

@ -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 &&