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 @ExperimentalUnsignedTypes
interface UpdatableHash : Hash { interface UpdatableHash : Hash {
fun update(data : Array<UByte>) fun update(data : UByteArray)
fun update(data : String) fun update(data : String)
fun digest() : Array<UByte> fun digest() : UByteArray
fun digestString() : String fun digestString() : String
} }
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
interface StatelessHash : Hash { 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( fun digest(
inputMessage: Array<UByte> = emptyArray(), inputMessage: UByteArray = ubyteArrayOf(),
key: Array<UByte> = emptyArray(), key: UByteArray = ubyteArrayOf(),
hashLength: Int = MAX_HASH_BYTES hashLength: Int = MAX_HASH_BYTES
): Array<UByte> ): UByteArray
} }

View File

@ -31,10 +31,14 @@ import com.ionspin.kotlin.crypto.util.rotateRight
*/ */
@ExperimentalUnsignedTypes @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 { 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 BITS_IN_WORD = 64
const val ROUNDS_IN_COMPRESS = 12 const val ROUNDS_IN_COMPRESS = 12
const val BLOCK_BYTES = 128 const val BLOCK_BYTES = 128
@ -103,7 +107,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
fun compress( fun compress(
h: Array<ULong>, h: Array<ULong>,
input: Array<UByte>, input: UByteArray,
offsetCounter: BigInteger, offsetCounter: BigInteger,
finalBlock: Boolean finalBlock: Boolean
): Array<ULong> { ): Array<ULong> {
@ -145,24 +149,24 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
} }
@ExperimentalStdlibApi @ExperimentalStdlibApi
override fun digest(inputString: String, key: String?, hashLength: Int): Array<UByte> { override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
val array = inputString.encodeToByteArray().map { it.toUByte() }.toList().toTypedArray() val array = inputString.encodeToByteArray().toUByteArray()
val keyBytes = key?.run { val keyBytes = key?.run {
encodeToByteArray().map { it.toUByte() }.toTypedArray() encodeToByteArray().toUByteArray()
} ?: emptyArray() } ?: ubyteArrayOf()
return digest(inputMessage = array, key = keyBytes, hashLength = hashLength) return digest(inputMessage = array, key = keyBytes, hashLength = hashLength)
} }
override fun digest( override fun digest(
inputMessage: Array<UByte>, inputMessage: UByteArray,
key: Array<UByte>, key: UByteArray,
hashLength: Int hashLength: Int
): Array<UByte> { ): UByteArray {
if (hashLength > MAX_HASH_BYTES) { if (hashLength > MAX_HASH_BYTES) {
throw RuntimeException("Invalid hash length. Requested length more than maximum length. Requested length $hashLength") 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() 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()) { val message = if (key.isEmpty()) {
if (chunkedMessage.isEmpty()) { if (chunkedMessage.isEmpty()) {
Array(1) { Array(1) {
Array<UByte>(128) { UByteArray(128) {
0U 0U
} }
} }
@ -199,7 +203,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
val lastBlockPadded = if (message.isNotEmpty()) { val lastBlockPadded = if (message.isNotEmpty()) {
padToBlock(message[message.size - 1]) padToBlock(message[message.size - 1])
} else { } else {
Array<UByte>(16) { 0U } UByteArray(16) { 0U }
} }
compress(h, lastBlockPadded, lastSize.toBigInteger(), true).copyInto(h) 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) return formatResult(h).copyOfRange(0, hashLength)
} }
private fun formatResult(h: Array<ULong>): Array<UByte> { private fun formatResult(h: Array<ULong>): UByteArray {
return h.map { return h.map {
arrayOf( arrayOf(
(it and 0xFFUL).toUByte(), (it and 0xFFUL).toUByte(),
@ -222,10 +226,10 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
) )
}.flatMap { }.flatMap {
it.toList() it.toList()
}.toTypedArray() }.toUByteArray()
} }
private fun padToBlock(unpadded: Array<UByte>): Array<UByte> { private fun padToBlock(unpadded: UByteArray): UByteArray {
if (unpadded.size == BLOCK_BYTES) { if (unpadded.size == BLOCK_BYTES) {
return unpadded 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") throw IllegalStateException("Block larger than 128 bytes")
} }
return Array(BLOCK_BYTES) { return UByteArray(BLOCK_BYTES) {
when (it) { when (it) {
in 0 until unpadded.size -> unpadded[it] in 0 until unpadded.size -> unpadded[it]
else -> 0U else -> 0U
@ -248,7 +252,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
key: String?, key: String?,
requestedHashLenght: Int = 64 requestedHashLenght: Int = 64
) : this( ) : this(
(key?.encodeToByteArray()?.map { it.toUByte() }?.toTypedArray() ?: emptyArray<UByte>()), (key?.encodeToByteArray()?.toUByteArray() ?: ubyteArrayOf()),
requestedHashLenght requestedHashLenght
) )
@ -257,7 +261,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
var h = iv.copyOf() var h = iv.copyOf()
var counter = BigInteger.ZERO var counter = BigInteger.ZERO
var bufferCounter = 0 var bufferCounter = 0
var buffer = Array<UByte>(BLOCK_BYTES) { 0U } var buffer = UByteArray(BLOCK_BYTES) { 0U }
init { 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()) { if (data.isEmpty()) {
throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating") 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 { when {
bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter)
bufferCounter + data.size >= BLOCK_BYTES -> { bufferCounter + data.size >= BLOCK_BYTES -> {
val chunked = data.chunked(BLOCK_BYTES) val chunked = data.chunked(BLOCK_BYTES).map { it.toUByteArray() }
chunked.forEach { chunk -> chunked.forEach { chunk ->
if (bufferCounter + chunk.size < BLOCK_BYTES) { if (bufferCounter + chunk.size < BLOCK_BYTES) {
appendToBuffer(chunk, bufferCounter) appendToBuffer(chunk, bufferCounter)
@ -289,7 +293,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
) )
counter += BLOCK_BYTES counter += BLOCK_BYTES
consumeBlock(buffer) consumeBlock(buffer)
buffer = Array<UByte>(BLOCK_BYTES) { buffer = UByteArray(BLOCK_BYTES) {
when (it) { when (it) {
in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> {
chunk[it + (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 @ExperimentalStdlibApi
override fun update(data: String) { 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) array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size)
bufferCounter += array.size bufferCounter += array.size
} }
private fun consumeBlock(block: Array<UByte>) { private fun consumeBlock(block: UByteArray) {
h = compress(h, block, counter, false) h = compress(h, block, counter, false)
} }
override fun digest(): Array<UByte> { override fun digest(): UByteArray {
val lastBlockPadded = padToBlock(buffer) val lastBlockPadded = padToBlock(buffer)
counter += bufferCounter counter += bufferCounter
compress(h, lastBlockPadded, counter, true) compress(h, lastBlockPadded, counter, true)
@ -341,7 +345,7 @@ class Blake2b(val key: Array<UByte>? = null, val hashLength: Int = 64) : Updatab
h = iv.copyOf() h = iv.copyOf()
counter = BigInteger.ZERO counter = BigInteger.ZERO
bufferCounter = 0 bufferCounter = 0
buffer = Array<UByte>(BLOCK_BYTES) { 0U } buffer = UByteArray(BLOCK_BYTES) { 0U }
} }

View File

@ -67,14 +67,14 @@ class Sha256 : UpdatableHash {
) )
@ExperimentalStdlibApi @ExperimentalStdlibApi
override fun digest(inputString: String, key: String?, hashLength: Int): Array<UByte> { override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
return digest( return digest(
inputString.encodeToByteArray().map { it.toUByte() }.toTypedArray(), inputString.encodeToByteArray().toUByteArray(),
key?.run { encodeToByteArray().map { it.toUByte() }.toTypedArray() } ?: emptyArray<UByte>(), 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() var h = iv.copyOf()
@ -88,7 +88,7 @@ class Sha256 : UpdatableHash {
.chunked(BLOCK_SIZE_IN_BYTES) .chunked(BLOCK_SIZE_IN_BYTES)
chunks.forEach { chunk -> chunks.forEach { chunk ->
val w = expandChunk(chunk) val w = expandChunk(chunk.toUByteArray())
mix(h, w).copyInto(h) mix(h, w).copyInto(h)
} }
@ -128,7 +128,7 @@ class Sha256 : UpdatableHash {
return (((x and y) xor (x and z) xor (y and z))) 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) { val w = Array<UInt>(BLOCK_SIZE_IN_BYTES) {
when (it) { when (it) {
in 0 until 16 -> { 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 val originalMessageSizeInBits = originalSizeInBytes * 8
@ -198,7 +198,7 @@ class Sha256 : UpdatableHash {
0 -> 0 0 -> 0
else -> (BLOCK_SIZE - expandedRemainderOf512) / 8 else -> (BLOCK_SIZE - expandedRemainderOf512) / 8
} }
val expansionArray = Array<UByte>(zeroAddAmount + 1) { val expansionArray = UByteArray(zeroAddAmount + 1) {
when (it) { when (it) {
0 -> 0b10000000U 0 -> 0b10000000U
else -> 0U else -> 0U
@ -207,9 +207,9 @@ class Sha256 : UpdatableHash {
return expansionArray return expansionArray
} }
private fun ULong.toPaddedByteArray(): Array<UByte> { private fun ULong.toPaddedByteArray(): UByteArray {
val byteMask = BYTE_MASK_FROM_ULONG val byteMask = BYTE_MASK_FROM_ULONG
return Array(8) { return UByteArray(8) {
when (it) { when (it) {
7 -> (this and byteMask).toUByte() 7 -> (this and byteMask).toUByte()
6 -> ((this shr 8) 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 val byteMask = BYTE_MASK_FROM_UINT
return Array(4) { return UByteArray(4) {
when (it) { when (it) {
3 -> (this and byteMask).toUByte() 3 -> (this and byteMask).toUByte()
2 -> ((this shr 8) and byteMask).toUByte() 2 -> ((this shr 8) and byteMask).toUByte()
@ -242,14 +242,14 @@ class Sha256 : UpdatableHash {
var h = iv.copyOf() var h = iv.copyOf()
var counter = 0 var counter = 0
var bufferCounter = 0 var bufferCounter = 0
var buffer = Array<UByte>(BLOCK_SIZE_IN_BYTES) { 0U } var buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { 0U }
@ExperimentalStdlibApi @ExperimentalStdlibApi
override fun update(data: String) { 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()) { if (data.isEmpty()) {
throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating") 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) val chunked = data.chunked(BLOCK_SIZE_IN_BYTES)
chunked.forEach { chunk -> chunked.forEach { chunk ->
if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) { if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) {
appendToBuffer(chunk, bufferCounter) appendToBuffer(chunk.toUByteArray(), bufferCounter)
} else { } else {
chunk.copyInto( chunk.toUByteArray().copyInto(
destination = buffer, destination = buffer,
destinationOffset = bufferCounter, destinationOffset = bufferCounter,
startIndex = 0, startIndex = 0,
@ -270,7 +270,7 @@ class Sha256 : UpdatableHash {
) )
counter += BLOCK_SIZE_IN_BYTES counter += BLOCK_SIZE_IN_BYTES
consumeBlock(buffer) consumeBlock(buffer)
buffer = Array<UByte>(BLOCK_SIZE_IN_BYTES) { buffer = UByteArray(BLOCK_SIZE_IN_BYTES) {
when (it) { when (it) {
in (0 until (chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter))) -> { in (0 until (chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter))) -> {
chunk[it + (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) val w = expandChunk(block)
mix(h, w).copyInto(h) mix(h, w).copyInto(h)
} }
override fun digest(): Array<UByte> { override fun digest(): UByteArray {
val length = counter + bufferCounter val length = counter + bufferCounter
val expansionArray = createExpansionArray(length) val expansionArray = createExpansionArray(length)
val finalBlock = val finalBlock =
buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPaddedByteArray() buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPaddedByteArray()
finalBlock.chunked(BLOCK_SIZE_IN_BYTES).forEach { 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 = "") 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) array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size)
bufferCounter += array.size bufferCounter += array.size
} }

View File

@ -135,15 +135,15 @@ class Sha512 : UpdatableHash {
) )
@ExperimentalStdlibApi @ExperimentalStdlibApi
override fun digest(inputString: String, key: String?, hashLength: Int): Array<UByte> { override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
return digest( return digest(
inputString.encodeToByteArray().map { it.toUByte() }.toTypedArray(), inputString.encodeToByteArray().toUByteArray(),
key?.run { encodeToByteArray().map { it.toUByte() }.toTypedArray() } ?: emptyArray<UByte>(), key?.run { encodeToByteArray().toUByteArray() } ?: ubyteArrayOf(),
hashLength = hashLength 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() var h = iv.copyOf()
@ -155,7 +155,7 @@ class Sha512 : UpdatableHash {
) )
chunks.forEach { chunk -> chunks.forEach { chunk ->
val w = expandChunk(chunk) val w = expandChunk(chunk.toUByteArray())
mix(h, w) mix(h, w)
} }
@ -196,7 +196,7 @@ class Sha512 : UpdatableHash {
return ((x and y) xor (x and z) xor (y and z)) 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) { val w = Array<ULong>(CHUNK_SIZE) {
when (it) { when (it) {
in 0 until 16 -> { in 0 until 16 -> {
@ -259,7 +259,7 @@ class Sha512 : UpdatableHash {
return h return h
} }
fun createExpansionArray(originalSizeInBytes: Int): Array<UByte> { fun createExpansionArray(originalSizeInBytes: Int): UByteArray {
val originalMessageSizeInBits = originalSizeInBytes * 8 val originalMessageSizeInBits = originalSizeInBytes * 8
val expandedRemainderOf1024 = (originalMessageSizeInBits + 129) % BLOCK_SIZE val expandedRemainderOf1024 = (originalMessageSizeInBits + 129) % BLOCK_SIZE
@ -267,7 +267,7 @@ class Sha512 : UpdatableHash {
0 -> 0 0 -> 0
else -> (BLOCK_SIZE - expandedRemainderOf1024) / 8 else -> (BLOCK_SIZE - expandedRemainderOf1024) / 8
} }
val expansionArray = Array<UByte>(zeroAddAmount + 1) { val expansionArray = UByteArray(zeroAddAmount + 1) {
when (it) { when (it) {
0 -> 0b10000000U 0 -> 0b10000000U
else -> 0U else -> 0U
@ -277,10 +277,10 @@ class Sha512 : UpdatableHash {
} }
private fun ULong.toPaddedByteArray(): Array<UByte> { private fun ULong.toPaddedByteArray(): UByteArray {
val byteMask = 0xFFUL val byteMask = 0xFFUL
//Ignore messages longer than 64 bits for now //Ignore messages longer than 64 bits for now
return Array(8) { return UByteArray(8) {
when (it) { when (it) {
7 -> (this and byteMask).toUByte() 7 -> (this and byteMask).toUByte()
6 -> ((this shr 8) 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 val byteMask = 0xFFUL
//Ignore messages longer than 64 bits for now //Ignore messages longer than 64 bits for now
return Array(16) { return UByteArray(16) {
when (it) { when (it) {
15 -> (this and byteMask).toUByte() 15 -> (this and byteMask).toUByte()
14 -> ((this shr 8) and byteMask).toUByte() 14 -> ((this shr 8) and byteMask).toUByte()
@ -317,14 +317,14 @@ class Sha512 : UpdatableHash {
var h = iv.copyOf() var h = iv.copyOf()
var counter = 0 var counter = 0
var bufferCounter = 0 var bufferCounter = 0
var buffer = Array<UByte>(BLOCK_SIZE_IN_BYTES) { 0U } var buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { 0U }
@ExperimentalStdlibApi @ExperimentalStdlibApi
override fun update(data: String) { 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()) { if (data.isEmpty()) {
throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating") 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) val chunked = data.chunked(BLOCK_SIZE_IN_BYTES)
chunked.forEach { chunk -> chunked.forEach { chunk ->
if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) { if (bufferCounter + chunk.size < BLOCK_SIZE_IN_BYTES) {
appendToBuffer(chunk, bufferCounter) appendToBuffer(chunk.toUByteArray(), bufferCounter)
} else { } else {
chunk.copyInto( chunk.toUByteArray().copyInto(
destination = buffer, destination = buffer,
destinationOffset = bufferCounter, destinationOffset = bufferCounter,
startIndex = 0, startIndex = 0,
@ -345,7 +345,7 @@ class Sha512 : UpdatableHash {
) )
counter += BLOCK_SIZE_IN_BYTES counter += BLOCK_SIZE_IN_BYTES
consumeBlock(buffer) consumeBlock(buffer)
buffer = Array<UByte>(BLOCK_SIZE_IN_BYTES) { buffer = UByteArray(BLOCK_SIZE_IN_BYTES) {
when (it) { when (it) {
in (0 until (chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter))) -> { in (0 until (chunk.size - (BLOCK_SIZE_IN_BYTES - bufferCounter))) -> {
chunk[it + (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) val w = expandChunk(block)
mix(h, w).copyInto(h) mix(h, w).copyInto(h)
} }
override fun digest(): Array<UByte> { override fun digest(): UByteArray {
val length = counter + bufferCounter val length = counter + bufferCounter
val expansionArray = createExpansionArray(length) val expansionArray = createExpansionArray(length)
val finalBlock = val finalBlock =
buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPadded128BitByteArray() buffer.copyOfRange(0, bufferCounter) + expansionArray + (length * 8).toULong().toPadded128BitByteArray()
finalBlock.chunked(BLOCK_SIZE_IN_BYTES).forEach { 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 = "") 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) array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size)
bufferCounter += array.size bufferCounter += array.size
} }

View File

@ -310,8 +310,8 @@ class Argon2(
key.size.toUInt().toLittleEndianUByteArray() + key + key.size.toUInt().toLittleEndianUByteArray() + key +
associatedData.size.toUInt().toLittleEndianUByteArray() + associatedData associatedData.size.toUInt().toLittleEndianUByteArray() + associatedData
val h0 = Blake2b.digest( val h0 = Blake2b.digest(
blakeInput.toTypedArray() blakeInput
).toUByteArray() )
//Compute B[i][0] //Compute B[i][0]
for (i in 0 until parallelism) { for (i in 0 until parallelism) {

View File

@ -127,17 +127,17 @@ object Argon2Utils {
internal fun argonBlake2bArbitraryLenghtHash(input: UByteArray, length: UInt): UByteArray { internal fun argonBlake2bArbitraryLenghtHash(input: UByteArray, length: UInt): UByteArray {
if (length <= 64U) { 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 //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 numberOf64ByteBlocks = (1U + ((length - 1U) / 32U) - 2U).toInt() // equivalent to ceil(length/32) - 2
val v = Array<UByteArray>(numberOf64ByteBlocks) { ubyteArrayOf() } 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) { 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 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 = val concat =
(v.map { it.copyOfRange(0, 32) }) (v.map { it.copyOfRange(0, 32) })
.plus(listOf(vLast)) .plus(listOf(vLast))

View File

@ -1,10 +1,12 @@
package com.ionspin.kotlin.crypto.symmetric 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 * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 07/Sep/2019
*/ */
@ExperimentalUnsignedTypes @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 { companion object {
private val debug = false 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) 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() 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() return Aes(aesKey, input).decrypt()
} }
} }
val state: Array<Array<UByte>> = (0 until 4).map { outerCounter -> val state: Array<UByteArray> = (0 until 4).map { outerCounter ->
Array<UByte>(4) { innerCounter -> input[innerCounter * 4 + outerCounter] } UByteArray(4) { innerCounter -> input[innerCounter * 4 + outerCounter] }
}.toTypedArray() }.toTypedArray()
val numberOfRounds = when (aesKey) { val numberOfRounds = when (aesKey) {
@ -74,7 +76,7 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy
is AesKey.Aes256Key -> 14 is AesKey.Aes256Key -> 14
} }
val expandedKey: Array<Array<UByte>> = expandKey() val expandedKey: Array<UByteArray> = expandKey()
var round = 0 var round = 0
@ -110,22 +112,22 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy
} }
fun shiftRows() { fun shiftRows() {
state[0] = arrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) state[0] = ubyteArrayOf(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[1] = ubyteArrayOf(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[2] = ubyteArrayOf(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[3] = ubyteArrayOf(state[3][3], state[3][0], state[3][1], state[3][2])
} }
fun inversShiftRows() { fun inversShiftRows() {
state[0] = arrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) state[0] = ubyteArrayOf(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[1] = ubyteArrayOf(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[2] = ubyteArrayOf(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[3] = ubyteArrayOf(state[3][1], state[3][2], state[3][3], state[3][0])
} }
fun mixColumns() { fun mixColumns() {
val stateMixed: Array<Array<UByte>> = (0 until 4).map { val stateMixed: Array<UByteArray> = (0 until 4).map {
Array<UByte>(4) { 0U } UByteArray(4) { 0U }
}.toTypedArray() }.toTypedArray()
for (c in 0..3) { for (c in 0..3) {
@ -138,8 +140,8 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy
} }
fun inverseMixColumns() { fun inverseMixColumns() {
val stateMixed: Array<Array<UByte>> = (0 until 4).map { val stateMixed: Array<UByteArray> = (0 until 4).map {
Array<UByte>(4) { 0U } UByteArray(4) { 0U }
}.toTypedArray() }.toTypedArray()
for (c in 0..3) { for (c in 0..3) {
stateMixed[0][c] = stateMixed[0][c] =
@ -203,9 +205,9 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy
return galoisFieldMultiply(this.toUByte(), second) return galoisFieldMultiply(this.toUByte(), second)
} }
fun expandKey(): Array<Array<UByte>> { fun expandKey(): Array<UByteArray> {
val expandedKey = (0 until 4 * (numberOfRounds + 1)).map { val expandedKey = (0 until 4 * (numberOfRounds + 1)).map {
Array<UByte>(4) { 0U } UByteArray(4) { 0U }
}.toTypedArray() }.toTypedArray()
// First round // First round
for (i in 0 until aesKey.numberOf32BitWords) { 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 -> expandedKey[i] = expandedKey[i - aesKey.numberOf32BitWords].mapIndexed { index, it ->
it xor temp[index] it xor temp[index]
}.toTypedArray() }.toUByteArray()
clearArray(temp) clearArray(temp)
} }
return expandedKey return expandedKey
} }
fun encrypt(): Array<UByte> { fun encrypt(): UByteArray {
if (completed) { if (completed) {
throw RuntimeException("Encrypt can only be called once per Aes instance, since the state is cleared at the " + throw RuntimeException("Encrypt can only be called once per Aes instance, since the state is cleared at the " +
"end of the operation") "end of the operation")
@ -273,8 +275,8 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy
addRoundKey() addRoundKey()
printState() printState()
val transposedMatrix = (0 until 4).map { outerCounter -> val transposedMatrix = (0 until 4).map { outerCounter ->
Array<UByte>(4) { 0U } UByteArray(4) { 0U }
}.toTypedArray() }
for (i in 0 until 4) { for (i in 0 until 4) {
for (j in 0 until 4) { for (j in 0 until 4) {
transposedMatrix[i][j] = state[j][i] 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) } state.forEach { clearArray(it) }
completed = true completed = true
return transposedMatrix.flatten().toTypedArray() return transposedMatrix.flattenToUByteArray()
} }
fun decrypt(): Array<UByte> { fun decrypt(): UByteArray {
if (completed) { if (completed) {
throw RuntimeException("Decrypt can only be called once per Aes instance, since the state is cleared at the " + throw RuntimeException("Decrypt can only be called once per Aes instance, since the state is cleared at the " +
"end of the operation") "end of the operation")
@ -313,20 +315,19 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy
printState() printState()
val transposedMatrix = (0 until 4).map { outerCounter -> val transposedMatrix = (0 until 4).map { outerCounter ->
Array<UByte>(4) { 0U } UByteArray(4) { 0U }
}.toTypedArray() }
for (i in 0 until 4) { for (i in 0 until 4) {
for (j in 0 until 4) { for (j in 0 until 4) {
transposedMatrix[i][j] = state[j][i] transposedMatrix[i][j] = state[j][i]
} }
} }
printState(transposedMatrix)
state.forEach { clearArray(it) } state.forEach { clearArray(it) }
completed = true 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 } 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) { if (!debug) {
return 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) { 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 val numberOf32BitWords = keyLength / 32
class Aes128Key(key: String) : AesKey(key, 128) class Aes128Key(key: String) : AesKey(key, 128)

View File

@ -32,7 +32,7 @@ import com.ionspin.kotlin.crypto.util.xor
* on 21-Sep-2019 * on 21-Sep-2019
*/ */
@ExperimentalUnsignedTypes @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 { companion object {
const val BLOCK_BYTES = 16 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 * 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) val aesCbc = AesCbc(aesKey, Mode.ENCRYPT)
aesCbc.addData(data) aesCbc.addData(data)
return aesCbc.encrypt() return aesCbc.encrypt()
@ -63,20 +63,20 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
/** /**
* Bulk decryption, returns decrypted data * 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) val aesCbc = AesCbc(aesKey, Mode.DECRYPT, initialCounter)
aesCbc.addData(data) aesCbc.addData(data)
return aesCbc.decrypt() return aesCbc.decrypt()
} }
private fun padToBlock(unpadded: Array<UByte>): Array<UByte> { private fun padToBlock(unpadded: UByteArray): UByteArray {
val paddingSize = 16 - unpadded.size val paddingSize = 16 - unpadded.size
if (unpadded.size == BLOCK_BYTES) { if (unpadded.size == BLOCK_BYTES) {
return unpadded return unpadded
} }
if (unpadded.size == BLOCK_BYTES) { if (unpadded.size == BLOCK_BYTES) {
return Array(BLOCK_BYTES) { return UByteArray(BLOCK_BYTES) {
BLOCK_BYTES.toUByte() 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") throw IllegalStateException("Block larger than 128 bytes")
} }
return Array(BLOCK_BYTES) { return UByteArray(BLOCK_BYTES) {
when (it) { when (it) {
in unpadded.indices -> unpadded[it] in unpadded.indices -> unpadded[it]
else -> paddingSize.toUByte() else -> paddingSize.toUByte()
@ -95,20 +95,20 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
} }
} }
var currentOutput: Array<UByte> = arrayOf() var currentOutput: UByteArray = ubyteArrayOf()
var previousEncrypted: Array<UByte> = arrayOf() var previousEncrypted: UByteArray = ubyteArrayOf()
val initVector = if (initializationVector.isNullOrEmpty()) { val initVector = if (initializationVector.isNullOrEmpty()) {
SRNG.getRandomBytes(16).toTypedArray() SRNG.getRandomBytes(16)
} else { } else {
initializationVector 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 var bufferCounter = 0
fun addData(data: Array<UByte>) { fun addData(data: UByteArray) {
//Padding //Padding
when { when {
bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) 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) val chunked = data.chunked(BLOCK_BYTES)
chunked.forEach { chunk -> chunked.forEach { chunk ->
if (bufferCounter + chunk.size < BLOCK_BYTES) { if (bufferCounter + chunk.size < BLOCK_BYTES) {
appendToBuffer(chunk, bufferCounter) appendToBuffer(chunk.toUByteArray(), bufferCounter)
} else { } else {
chunk.copyInto( chunk.toUByteArray().copyInto(
destination = buffer, destination = buffer,
destinationOffset = bufferCounter, destinationOffset = bufferCounter,
startIndex = 0, startIndex = 0,
endIndex = BLOCK_BYTES - bufferCounter endIndex = BLOCK_BYTES - bufferCounter
) )
output += consumeBlock(buffer) output += consumeBlock(buffer)
buffer = Array<UByte>(BLOCK_BYTES) { buffer = UByteArray(BLOCK_BYTES) {
when (it) { when (it) {
in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> {
chunk[it + (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) { if (bufferCounter > 0) {
val lastBlockPadded = padToBlock(buffer) val lastBlockPadded = padToBlock(buffer)
if (lastBlockPadded.size > BLOCK_BYTES) { 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[0])
output += consumeBlock(chunks[1]) output += consumeBlock(chunks[1])
} else { } else {
@ -161,7 +161,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
} }
} }
return EncryptedDataAndInitializationVector( return EncryptedDataAndInitializationVector(
output.reversed().foldRight(Array<UByte>(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes },
initVector initVector
) )
} }
@ -170,7 +170,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
* Decrypt data * Decrypt data
* @return Decrypted data * @return Decrypted data
*/ */
fun decrypt(): Array<UByte> { fun decrypt(): UByteArray {
val removePaddingCount = output.last().last() 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) output.last().dropLast(removePaddingCount.toInt() and 0x7F)
} else { } else {
output.last().toList() output.last().toList()
} }.toUByteArray()
val preparedOutput = output.dropLast(1).toTypedArray() + removedPadding.toTypedArray() val preparedOutput = (output.dropLast(1) + listOf(removedPadding))
//JS compiler freaks out here if we don't supply exact type //JS compiler freaks out here if we don't supply exact type
val reversed : List<Array<UByte>> = preparedOutput.reversed() as List<Array<UByte>> val reversed : List<UByteArray> = preparedOutput.reversed() as List<UByteArray>
val folded : Array<UByte> = reversed.foldRight(Array<UByte>(0) { 0U }) { arrayOfUBytes, acc -> val folded : UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { uByteArray, acc ->
acc + arrayOfUBytes } acc + uByteArray
}
return folded 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) array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size)
bufferCounter += array.size bufferCounter += array.size
} }
private fun consumeBlock(data: Array<UByte>): Array<UByte> { private fun consumeBlock(data: UByteArray): UByteArray {
return when (mode) { return when (mode) {
Mode.ENCRYPT -> { Mode.ENCRYPT -> {
currentOutput = if (currentOutput.isEmpty()) { currentOutput = if (currentOutput.isEmpty()) {
@ -220,7 +221,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
} }
@ExperimentalUnsignedTypes @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 { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (other == null || this::class != other::class) return false 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 * on 22-Sep-2019
*/ */
@ExperimentalUnsignedTypes @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 { companion object {
const val BLOCK_BYTES = 16 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 * 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) val aesCtr = AesCtr(aesKey, Mode.ENCRYPT)
aesCtr.addData(data) aesCtr.addData(data)
return aesCtr.encrypt() return aesCtr.encrypt()
@ -68,7 +68,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
/** /**
* Bulk decryption, returns decrypted data * 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) val aesCtr = AesCtr(aesKey, Mode.DECRYPT, initialCounter)
aesCtr.addData(data) aesCtr.addData(data)
return aesCtr.decrypt() return aesCtr.decrypt()
@ -76,21 +76,21 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
} }
var currentOutput: Array<UByte> = arrayOf() var currentOutput: UByteArray = ubyteArrayOf()
var previousEncrypted: Array<UByte> = arrayOf() var previousEncrypted: UByteArray = ubyteArrayOf()
val counterStart = if (initialCounter.isNullOrEmpty()) { val counterStart = if (initialCounter.isNullOrEmpty()) {
SRNG.getRandomBytes(16).toTypedArray() SRNG.getRandomBytes(16)
} else { } else {
initialCounter 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 var bufferCounter = 0
fun addData(data: Array<UByte>) { fun addData(data: UByteArray) {
//Padding //Padding
when { when {
bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) 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) val chunked = data.chunked(BLOCK_BYTES)
chunked.forEach { chunk -> chunked.forEach { chunk ->
if (bufferCounter + chunk.size < BLOCK_BYTES) { if (bufferCounter + chunk.size < BLOCK_BYTES) {
appendToBuffer(chunk, bufferCounter) appendToBuffer(chunk.toUByteArray(), bufferCounter)
} else { } else {
chunk.copyInto( chunk.toUByteArray().copyInto(
destination = buffer, destination = buffer,
destinationOffset = bufferCounter, destinationOffset = bufferCounter,
startIndex = 0, startIndex = 0,
@ -108,7 +108,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
) )
output += consumeBlock(buffer, blockCounter) output += consumeBlock(buffer, blockCounter)
blockCounter += 1 blockCounter += 1
buffer = Array<UByte>(BLOCK_BYTES) { buffer = UByteArray(BLOCK_BYTES) {
when (it) { when (it) {
in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> {
chunk[it + (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) output += consumeBlock(buffer, blockCounter)
} }
return EncryptedDataAndInitialCounter( return EncryptedDataAndInitialCounter(
output.reversed().foldRight(Array<UByte>(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes },
counterStart counterStart
) )
} }
@ -144,25 +144,25 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
* Decrypt data * Decrypt data
* @return Decrypted data * @return Decrypted data
*/ */
fun decrypt(): Array<UByte> { fun decrypt(): UByteArray {
if (bufferCounter > 0) { if (bufferCounter > 0) {
output += consumeBlock(buffer, blockCounter) output += consumeBlock(buffer, blockCounter)
} }
//JS compiler freaks out here if we don't supply exact type //JS compiler freaks out here if we don't supply exact type
val reversed: List<Array<UByte>> = output.reversed() as List<Array<UByte>> val reversed: List<UByteArray> = output.reversed() as List<UByteArray>
val folded: Array<UByte> = reversed.foldRight(Array<UByte>(0) { 0U }) { arrayOfUBytes, acc -> val folded: UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc ->
acc + arrayOfUBytes acc + arrayOfUBytes
} }
return folded 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) array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size)
bufferCounter += array.size bufferCounter += array.size
} }
private fun consumeBlock(data: Array<UByte>, blockCount: ModularBigInteger): Array<UByte> { private fun consumeBlock(data: UByteArray, blockCount: ModularBigInteger): UByteArray {
val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).expandCounterTo16Bytes() val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).toUByteArray().expandCounterTo16Bytes()
return when (mode) { return when (mode) {
Mode.ENCRYPT -> { Mode.ENCRYPT -> {
Aes.encrypt(aesKey, blockCountAsByteArray) xor data 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) { return if (this.size < 16) {
println("Expanding") println("Expanding")
val diff = 16 - this.size val diff = 16 - this.size
val pad = Array<UByte>(diff) { 0U } val pad = UByteArray(diff) { 0U }
pad + this pad + this
} else { } else {
this this
@ -188,7 +188,7 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
} }
@ExperimentalUnsignedTypes @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 { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (other == null || this::class != other::class) return false if (other == null || this::class != other::class) return false

View File

@ -89,10 +89,15 @@ infix fun UByteArray.xor(other : UByteArray) : UByteArray {
} }
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun String.hexStringToUByteArray() : Array<UByte> { fun String.hexStringToTypedUByteArray() : Array<UByte> {
return this.chunked(2).map { it.toUByte(16) }.toTypedArray() return this.chunked(2).map { it.toUByte(16) }.toTypedArray()
} }
@ExperimentalUnsignedTypes
fun String.hexStringToUByteArray() : UByteArray {
return this.chunked(2).map { it.toUByte(16) }.toUByteArray()
}
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun Array<UByte>.toHexString() : String { fun Array<UByte>.toHexString() : String {
return this.joinToString(separator = "") { 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 // UInt / Array utils
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun UInt.toBigEndianUByteArray() : Array<UByte> { fun UInt.toBigEndianUByteArray() : Array<UByte> {
@ -228,6 +244,19 @@ fun Array<UByte>.fromBigEndianArrayToUInt() : UInt {
} }
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
operator fun UInt.plus(other : Array<UByte>) : Array<UByte> { operator fun UInt.plus(other : UByteArray) : UByteArray {
return this.toLittleEndianTypedUByteArray() + other 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 input = "abc"
val result = Blake2b.digest(input) val result = Blake2b.digest(input)
//@formatter:off //@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, 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, 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, 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" + val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" +
"6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1")
.chunked(2).map { it.toUByte(16) }.toTypedArray() .chunked(2).map { it.toUByte(16) }.toUByteArray()
assertTrue { assertTrue {
result.contentEquals(expectedResult) result.contentEquals(expectedResult)
@ -79,7 +79,7 @@ class ReadmeTest {
val result = Sha256.digest(inputString = input) val result = Sha256.digest(inputString = input)
val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
assertTrue { 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 @Test
fun sha512Example() { fun sha512Example() {
val input = "abc" 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) }) println(result.map { it.toString(16) })
val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
assertTrue { 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 result = sha256.digest()
val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
assertTrue { 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" + val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
assertTrue { 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) val result = Blake2b.digest(test)
//Generated with b2sum 8.31 //Generated with b2sum 8.31
val expectedResult = arrayOf<UByte>( val expectedResult = ubyteArrayOf(
//@formatter:off //@formatter:off
0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, 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, 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU,
@ -81,7 +81,7 @@ class Blake2BTest {
val expectedResultString = "800bb78cd4da18995c8074713bb674" + val expectedResultString = "800bb78cd4da18995c8074713bb674" +
"3cd94b2b6490a693fe4000ed00833b88b7b474d94af9cfed246b1b" + "3cd94b2b6490a693fe4000ed00833b88b7b474d94af9cfed246b1b" +
"4ce1935a76154d7ea7c410493557741d18ec3a08da75" "4ce1935a76154d7ea7c410493557741d18ec3a08da75"
val expectedResult = expectedResultString.chunked(2).map { it.toUByte(16) }.toTypedArray() val expectedResult = expectedResultString.chunked(2).map { it.toUByte(16) }.toUByteArray()
assertTrue { assertTrue {
result.contentEquals(expectedResult) result.contentEquals(expectedResult)
@ -95,7 +95,7 @@ class Blake2BTest {
val result = Blake2b.digest(test) val result = Blake2b.digest(test)
//Generated with b2sum 8.31 //Generated with b2sum 8.31
val expectedResult = arrayOf<UByte>( val expectedResult = ubyteArrayOf(
//@formatter:off //@formatter:off
0xe0U, 0xabU, 0xb7U, 0x5dU, 0xb2U, 0xc8U, 0xe1U, 0x3cU, 0x5fU, 0x1dU, 0x9fU, 0x55U, 0xc8U, 0x4eU, 0xacU, 0xd7U, 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, 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" + val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" +
"6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1")
.chunked(2).map { it.toUByte(16) }.toTypedArray() .chunked(2).map { it.toUByte(16) }.toUByteArray()
assertTrue { assertTrue {
result.contentEquals(expectedResult) result.contentEquals(expectedResult)
@ -136,7 +136,7 @@ class Blake2BTest {
val result = Blake2b.digest(test) val result = Blake2b.digest(test)
//@formatter:off //@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, 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, 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() { fun testUpdatableBlake2b() {
val updates = 14 val updates = 14
val input = "1234567890" val input = "1234567890"
val expectedResult = arrayOf<UByte>( val expectedResult = ubyteArrayOf(
//@formatter:off //@formatter:off
0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, 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, 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU,
@ -83,7 +83,7 @@ class Blake2bInstanceTest {
} }
val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" + val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" +
"6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1")
.chunked(2).map { it.toUByte(16) }.toTypedArray() .chunked(2).map { it.toUByte(16) }.toUByteArray()
assertTrue { assertTrue {
result.contentEquals(expectedResult) result.contentEquals(expectedResult)

View File

@ -36,13 +36,13 @@ class Blake2bKnowAnswerTests {
@Test @Test
fun knownAnswerTest() { fun knownAnswerTest() {
kat.forEach { 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( val result = Blake2b.digest(
inputMessage = parsedInput, inputMessage = parsedInput,
key = it.key.chunked(2).map { it.toUByte(16) }.toTypedArray() key = it.key.chunked(2).map { it.toUByte(16) }.toUByteArray()
) )
assertTrue { 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() { fun knownAnswerTestInstance() {
kat.forEach { kat -> kat.forEach { kat ->
val parsedInput = kat.input.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.toTypedArray() }.toTypedArray() val chunkedInput = parsedInput.toList().chunked(128).map { it.toUByteArray() }
val blake2b = Blake2b(key = kat.key.chunked(2).map { it.toUByte(16) }.toTypedArray()) val blake2b = Blake2b(key = kat.key.chunked(2).map { it.toUByte(16) }.toUByteArray())
chunkedInput.forEach { blake2b.update(it) } chunkedInput.forEach { blake2b.update(it) }
val result = blake2b.digest() val result = blake2b.digest()
assertTrue("KAT ${kat.input} \nkey: ${kat.key} \nexpected: {${kat.hash}") { 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 result = Sha256.digest(inputString = "abc")
val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
assertTrue { 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 resultDoubleBlock = Sha256.digest(inputString = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
assertTrue { 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 = "")) println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = ""))
val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"
assertTrue { 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) { for (i in 0 until 1000000) {
inputBuilder.append("a") 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" val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
assertTrue { 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 result = sha256.digest()
val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
assertTrue { 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 = "")) println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = ""))
val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
assertTrue { 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 = "")) println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = ""))
val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1"
assertTrue { 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 resultDoubleBlock = sha256.digest()
val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
assertTrue { 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 resultDoubleBlock = sha256.digest()
val expectedResultForDoubleBlock = "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e" val expectedResultForDoubleBlock = "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e"
assertTrue { 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 @Test
fun testWellKnownValue() { 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)}) println(result.map {it.toString(16)})
val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
assertTrue { 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" + val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" +
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
assertTrue { 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) { for (i in 0 until 1000000) {
inputBuilder.append("a") 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" val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
assertTrue { 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" + val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
assertTrue { 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" + val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" +
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
assertTrue { 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 resultDoubleBlock = sha512.digest()
val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
assertTrue { 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 resultDoubleBlock = sha512.digest()
val expectedResultForDoubleBlock = "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086" val expectedResultForDoubleBlock = "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086"
assertTrue { 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 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.hexStringToUByteArray
import com.ionspin.kotlin.crypto.util.toHexString import com.ionspin.kotlin.crypto.util.toHexString
import kotlin.test.Test import kotlin.test.Test

View File

@ -10,15 +10,15 @@ import kotlin.test.assertTrue
class AesTest { class AesTest {
val irrelevantKey = "01234567890123345678901234567890" val irrelevantKey = "01234567890123345678901234567890"
val irrelevantInput = UByteArray(16) { 0U }.toTypedArray() val irrelevantInput = UByteArray(16) { 0U }
@Test @Test
fun testSubBytes() { fun testSubBytes() {
val fakeState = arrayOf( val fakeState = arrayOf(
ubyteArrayOf(0x53U, 0U, 0U, 0U).toTypedArray(), ubyteArrayOf(0x53U, 0U, 0U, 0U),
ubyteArrayOf(0U, 0U, 0U, 0U).toTypedArray(), ubyteArrayOf(0U, 0U, 0U, 0U),
ubyteArrayOf(0U, 0U, 0U, 0U).toTypedArray(), ubyteArrayOf(0U, 0U, 0U, 0U),
ubyteArrayOf(0U, 0U, 0U, 0U).toTypedArray() ubyteArrayOf(0U, 0U, 0U, 0U)
) )
val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput) val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput)
fakeState.copyInto(aes.state) fakeState.copyInto(aes.state)
@ -31,16 +31,16 @@ class AesTest {
@Test @Test
fun testShiftRows() { fun testShiftRows() {
val fakeState = arrayOf( val fakeState = arrayOf(
ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), ubyteArrayOf(0U, 1U, 2U, 3U),
ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), ubyteArrayOf(0U, 1U, 2U, 3U),
ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), ubyteArrayOf(0U, 1U, 2U, 3U),
ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray() ubyteArrayOf(0U, 1U, 2U, 3U)
) )
val expectedState = arrayOf( val expectedState = arrayOf(
ubyteArrayOf(0U, 1U, 2U, 3U).toTypedArray(), ubyteArrayOf(0U, 1U, 2U, 3U),
ubyteArrayOf(1U, 2U, 3U, 0U).toTypedArray(), ubyteArrayOf(1U, 2U, 3U, 0U),
ubyteArrayOf(2U, 3U, 0U, 1U).toTypedArray(), ubyteArrayOf(2U, 3U, 0U, 1U),
ubyteArrayOf(3U, 0U, 1U, 2U).toTypedArray() ubyteArrayOf(3U, 0U, 1U, 2U)
) )
val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput) val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput)
fakeState.copyInto(aes.state) fakeState.copyInto(aes.state)
@ -76,17 +76,17 @@ class AesTest {
fun testMixColumns() { fun testMixColumns() {
//Test vectors from wikipedia //Test vectors from wikipedia
val fakeState = arrayOf( val fakeState = arrayOf(
ubyteArrayOf(0xdbU, 0xf2U, 0x01U, 0xc6U).toTypedArray(), ubyteArrayOf(0xdbU, 0xf2U, 0x01U, 0xc6U),
ubyteArrayOf(0x13U, 0x0aU, 0x01U, 0xc6U).toTypedArray(), ubyteArrayOf(0x13U, 0x0aU, 0x01U, 0xc6U),
ubyteArrayOf(0x53U, 0x22U, 0x01U, 0xc6U).toTypedArray(), ubyteArrayOf(0x53U, 0x22U, 0x01U, 0xc6U),
ubyteArrayOf(0x45U, 0x5cU, 0x01U, 0xc6U).toTypedArray() ubyteArrayOf(0x45U, 0x5cU, 0x01U, 0xc6U)
) )
val expectedState = arrayOf( val expectedState = arrayOf(
ubyteArrayOf(0x8eU, 0x9fU, 0x01U, 0xc6U).toTypedArray(), ubyteArrayOf(0x8eU, 0x9fU, 0x01U, 0xc6U),
ubyteArrayOf(0x4dU, 0xdcU, 0x01U, 0xc6U).toTypedArray(), ubyteArrayOf(0x4dU, 0xdcU, 0x01U, 0xc6U),
ubyteArrayOf(0xa1U, 0x58U, 0x01U, 0xc6U).toTypedArray(), ubyteArrayOf(0xa1U, 0x58U, 0x01U, 0xc6U),
ubyteArrayOf(0xbcU, 0x9dU, 0x01U, 0xc6U).toTypedArray() ubyteArrayOf(0xbcU, 0x9dU, 0x01U, 0xc6U)
) )
val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput) val aes = Aes(AesKey.Aes128Key(irrelevantKey), irrelevantInput)
@ -183,10 +183,10 @@ class AesTest {
val key = "2b7e151628aed2a6abf7158809cf4f3c" val key = "2b7e151628aed2a6abf7158809cf4f3c"
val expectedResult = "3925841d02dc09fbdc118597196a0b32" 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() val result = aes.encrypt()
assertTrue { 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 input = "3243f6a8885a308d313198a2e0370734"
val key = "2b7e151628aed2a6abf7158809cf4f3c" val key = "2b7e151628aed2a6abf7158809cf4f3c"
val expectedResult = "3925841d02dc09fbdc118597196a0b32" 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 aes = Aes(AesKey.Aes128Key(key), original)
val encrypted = aes.encrypt() val encrypted = aes.encrypt()
assertTrue { 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) val decrypted = Aes.decrypt(AesKey.Aes128Key(key), encrypted)
@ -210,57 +210,57 @@ class AesTest {
val input = "00112233445566778899aabbccddeeff" val input = "00112233445566778899aabbccddeeff"
val key = "000102030405060708090a0b0c0d0e0f" val key = "000102030405060708090a0b0c0d0e0f"
val expectedResult = "69c4e0d86a7b0430d8cdb78070b4c55a" 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 aes = Aes(AesKey.Aes128Key(key), original)
val encrypted = aes.encrypt() val encrypted = aes.encrypt()
assertTrue { 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 aesDec = Aes(AesKey.Aes128Key(key), encrypted)
val decrypted = aesDec.decrypt() val decrypted = aesDec.decrypt()
assertTrue { assertTrue {
aesDec.expandedKey.contentDeepEquals(aes.expandedKey) aesDec.expandedKey.contentDeepEquals(aes.expandedKey)
} }
decrypted.contentDeepEquals(original) decrypted.contentEquals(original)
} }
assertTrue { assertTrue {
val input = "00112233445566778899aabbccddeeff" val input = "00112233445566778899aabbccddeeff"
val key = "000102030405060708090a0b0c0d0e0f" val key = "000102030405060708090a0b0c0d0e0f"
val expectedResult = "69c4e0d86a7b0430d8cdb78070b4c55a" 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) val encrypted = Aes.encrypt(AesKey.Aes128Key(key), original)
assertTrue { 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) val decrypted = Aes.decrypt(AesKey.Aes128Key(key), encrypted)
decrypted.contentDeepEquals(original) decrypted.contentEquals(original)
} }
assertTrue { assertTrue {
val input = "00112233445566778899aabbccddeeff" val input = "00112233445566778899aabbccddeeff"
val key = "000102030405060708090a0b0c0d0e0f1011121314151617" val key = "000102030405060708090a0b0c0d0e0f1011121314151617"
val expectedResult = "dda97ca4864cdfe06eaf70a0ec0d7191" 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) val encrypted = Aes.encrypt(AesKey.Aes192Key(key), original)
assertTrue { 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) val decrypted = Aes.decrypt(AesKey.Aes192Key(key), encrypted)
decrypted.contentDeepEquals(original) decrypted.contentEquals(original)
} }
assertTrue { assertTrue {
val input = "00112233445566778899aabbccddeeff" val input = "00112233445566778899aabbccddeeff"
val key = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" val key = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
val expectedResult = "8ea2b7ca516745bfeafc49904b496089" 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) val encrypted = Aes.encrypt(AesKey.Aes256Key(key), original)
assertTrue { 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) 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 { actual fun getRandomBytes(amount: Int): UByteArray {
val runningOnNode = jsTypeOf(window) == "undefined" val runningOnNode = jsTypeOf(window) == "undefined"
val randomBytes = if (runningOnNode) { val randomBytes = if (runningOnNode) {
println("Running on node")
js("require('crypto')").randomBytes(amount).toJSON().data js("require('crypto')").randomBytes(amount).toJSON().data
} else { } else {
println("Running in browser")
js( js(
""" """
var randomArray = new Uint8Array(amount); var randomArray = new Uint8Array(amount);
@ -41,7 +43,21 @@ actual object SRNG {
var randomArrayResult = js("Array.prototype.slice.call(randomArray);") var randomArrayResult = js("Array.prototype.slice.call(randomArray);")
randomArrayResult 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() { fun testJsSrng() {
val bytes1 = SRNG.getRandomBytes(10) val bytes1 = SRNG.getRandomBytes(10)
val bytes2 = 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 { assertTrue {
!bytes1.contentEquals(bytes2) && !bytes1.contentEquals(bytes2) &&
bytes1.size == 10 && bytes1.size == 10 &&