Adding xchacha20 updateable, and tests

This commit is contained in:
Ugljesa Jovanovic 2020-06-21 19:51:21 +02:00 committed by Ugljesa Jovanovic
parent 1a4fc90922
commit 6fae2fd061
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
9 changed files with 468 additions and 152 deletions

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto package com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.hash.UpdatableHash
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
@ -16,7 +17,7 @@ typealias Blake2bPureStateless = Blake2bPure.Companion
typealias Sha256PureStateless = Sha256Pure.Companion typealias Sha256PureStateless = Sha256Pure.Companion
typealias Sha512PureStateless = Sha512Pure.Companion typealias Sha512PureStateless = Sha512Pure.Companion
object Crypto : CryptoProvider { object Primitives : CryptoProvider {
override suspend fun initialize() { override suspend fun initialize() {
//Nothing to do atm. //Nothing to do atm.
} }
@ -25,7 +26,6 @@ object Crypto : CryptoProvider {
done() done()
} }
object Blake2b { object Blake2b {
fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b { fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b {
checkInitialization() checkInitialization()
@ -62,6 +62,7 @@ object Crypto : CryptoProvider {
} }
} }
private fun checkInitialization() { private fun checkInitialization() {
// Nothing to do atm // Nothing to do atm
} }
@ -85,20 +86,23 @@ interface Encryptable {
fun encryptableData() : UByteArray fun encryptableData() : UByteArray
} }
object PublicApi { data class HashedData(val hash: UByteArray) {
data class HashedData(val hash: UByteArray) {
fun toHexString() : String { fun toHexString() : String {
return hash.toHexString() return hash.toHexString()
} }
} }
data class EncryptedData(val encrypted: UByteArray)
data class EncryptedData(val encrypted: UByteArray)
object PublicApi {
object Hash { object Hash {
fun hash() : HashedData { fun hash(data: UByteArray, key : UByteArray = ubyteArrayOf()) : HashedData {
TODO() return HashedData(Blake2bPureStateless.digest(data, key))
}
fun updateableHash(key: UByteArray? = null) : UpdatableHash {
return Blake2bPure(key)
} }
} }
object Symmetric { object Symmetric {

View File

@ -12,7 +12,7 @@ import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray
* ugljesa.jovanovic@ionspin.com * ugljesa.jovanovic@ionspin.com
* on 17-Jun-2020 * on 17-Jun-2020
*/ */
class ChaCha20Poly1305Pure { internal class ChaCha20Poly1305Pure {
companion object { companion object {
fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray {
@ -38,8 +38,6 @@ class ChaCha20Poly1305Pure {
} }
} }
val oneTimeKey = ChaCha20Pure.hash(state).sliceArray(0 until 32) val oneTimeKey = ChaCha20Pure.hash(state).sliceArray(0 until 32)
println("Poly key:")
oneTimeKey.hexColumsPrint()
val cipherText = ChaCha20Pure.encrypt(key, nonce, message, 1U) val cipherText = ChaCha20Pure.encrypt(key, nonce, message, 1U)
val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U } val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U }
val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U } val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U }
@ -47,11 +45,7 @@ class ChaCha20Poly1305Pure {
cipherText + cipherTextPad + cipherText + cipherTextPad +
additionalData.size.toULong().toLittleEndianUByteArray() + additionalData.size.toULong().toLittleEndianUByteArray() +
cipherText.size.toULong().toLittleEndianUByteArray() cipherText.size.toULong().toLittleEndianUByteArray()
println("Mac data")
macData.hexColumsPrint()
val tag = Poly1305.poly1305Authenticate(oneTimeKey, macData) val tag = Poly1305.poly1305Authenticate(oneTimeKey, macData)
println("Tag:")
tag.hexColumsPrint()
return cipherText + tag return cipherText + tag
} }
} }

View File

@ -1,11 +1,8 @@
package com.ionspin.kotlin.crypto.authenticated package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.bignum.Endianness
import com.ionspin.kotlin.bignum.integer.BigInteger
import com.ionspin.kotlin.crypto.mac.Poly1305 import com.ionspin.kotlin.crypto.mac.Poly1305
import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure
import com.ionspin.kotlin.crypto.symmetric.XChaCha20Pure import com.ionspin.kotlin.crypto.symmetric.XChaCha20Pure
import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUIntWithPosition
import com.ionspin.kotlin.crypto.util.hexColumsPrint import com.ionspin.kotlin.crypto.util.hexColumsPrint
import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray
@ -14,7 +11,7 @@ import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray
* ugljesa.jovanovic@ionspin.com * ugljesa.jovanovic@ionspin.com
* on 17-Jun-2020 * on 17-Jun-2020
*/ */
class XChaCha20Poly1305Pure { internal class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray, val additionalData: UByteArray) {
companion object { companion object {
fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray {
@ -24,7 +21,10 @@ class XChaCha20Poly1305Pure {
oneTimeKey.toLittleEndianUByteArray(), oneTimeKey.toLittleEndianUByteArray(),
ubyteArrayOf(0U, 0U, 0U, 0U) + nonce.sliceArray(16 until 24), ubyteArrayOf(0U, 0U, 0U, 0U) + nonce.sliceArray(16 until 24),
UByteArray(64) { 0U }, UByteArray(64) { 0U },
0U 0U // If this is moved as a default parameter in encrypt, and not here (in 1.4-M2)
// js compiler dies with: e: java.lang.NullPointerException
// at org.jetbrains.kotlin.ir.backend.js.lower.ConstTransformer$visitConst$1$3.invoke(ConstLowering.kt:28)
// at org.jetbrains.kotlin.ir.backend.js.lower.ConstTransformer.lowerConst(ConstLowering.kt:38)
) )
println("Poly sub-key:") println("Poly sub-key:")
oneTimeKey.hexColumsPrint() oneTimeKey.hexColumsPrint()
@ -37,16 +37,25 @@ class XChaCha20Poly1305Pure {
cipherText + cipherTextPad + cipherText + cipherTextPad +
additionalData.size.toULong().toLittleEndianUByteArray() + additionalData.size.toULong().toLittleEndianUByteArray() +
cipherText.size.toULong().toLittleEndianUByteArray() cipherText.size.toULong().toLittleEndianUByteArray()
oneTimeKey.toLittleEndianUByteArray().hexColumsPrint() oneTimeKey.toLittleEndianUByteArray().hexColumsPrint()
println("Ciphertext:")
cipherText.hexColumsPrint()
val tag = Poly1305.poly1305Authenticate(authKey, macData) val tag = Poly1305.poly1305Authenticate(authKey, macData)
println("Tag:")
tag.hexColumsPrint()
return cipherText + tag return cipherText + tag
} }
} }
// val encryption = XChaCha20Pure(key, nonce, initialCounter = 0U) {
//
// }
//
//
// fun encryptPartialData(data: UByteArray) : UByteArray {
//
// }
//
// fun finish() : UByteArray {
//
// }
} }

View File

@ -39,16 +39,9 @@ class Poly1305 {
val r = UByteArray(16) { key[it] } val r = UByteArray(16) { key[it] }
val s= UByteArray(16) { key[it + 16]} val s= UByteArray(16) { key[it + 16]}
clampR(r) clampR(r)
println("P: ${P.toString(16)}")
println("R:")
r.hexColumsPrint()
println("S:")
s.hexColumsPrint()
var accumulator = BigInteger.ZERO var accumulator = BigInteger.ZERO
val rAsBigInt = BigInteger.fromUByteArray(r, Endianness.LITTLE) val rAsBigInt = BigInteger.fromUByteArray(r, Endianness.LITTLE)
println("R: ${rAsBigInt.toString(16)}")
val sAsBigInt = BigInteger.fromUByteArray(s, Endianness.LITTLE) val sAsBigInt = BigInteger.fromUByteArray(s, Endianness.LITTLE)
println("S: ${sAsBigInt.toString(16)}")
val blocks = message.size / 16 val blocks = message.size / 16
val remainder = message.size % 16 val remainder = message.size % 16
@ -56,32 +49,20 @@ class Poly1305 {
val slice = message.sliceArray(i * 16 until i * 16 + 16) val slice = message.sliceArray(i * 16 until i * 16 + 16)
slice.hexColumsPrint() slice.hexColumsPrint()
val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[128] val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[128]
println("blockAsInt: ${blockAsInt.toString(16)}")
accumulator += blockAsInt accumulator += blockAsInt
println("Accumlator: ${accumulator.toString(16)}")
accumulator *= rAsBigInt accumulator *= rAsBigInt
println("Accumlator: ${accumulator.toString(16)}")
accumulator %= P accumulator %= P
println("Accumlator: ${accumulator.toString(16)}")
} }
if (remainder != 0) { if (remainder != 0) {
val slice = message.sliceArray(blocks * 16 until blocks * 16 + remainder) val slice = message.sliceArray(blocks * 16 until blocks * 16 + remainder)
val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[remainder * 8] val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[remainder * 8]
println("blockAsInt: ${blockAsInt.toString(16)}")
accumulator += blockAsInt accumulator += blockAsInt
println("Accumlator: ${accumulator.toString(16)}")
accumulator *= rAsBigInt accumulator *= rAsBigInt
println("Accumlator: ${accumulator.toString(16)}")
accumulator %= P accumulator %= P
println("Accumlator: ${accumulator.toString(16)}")
} }
println("Result mask: ${resultMask.toString(16)}")
accumulator += sAsBigInt accumulator += sAsBigInt
println("Before mask: ${accumulator.toString(16)}")
accumulator = accumulator and resultMask accumulator = accumulator and resultMask
println("Accumlator: ${accumulator.toString(16)}")
val result = accumulator.toUByteArray(Endianness.BIG) val result = accumulator.toUByteArray(Endianness.BIG)
result.reverse() result.reverse()
return result return result

View File

@ -57,7 +57,7 @@ internal class ChaCha20Pure {
val sigma2_32 = 2036477234U //ubyteArrayOf(50U, 45U, 98U, 121U) val sigma2_32 = 2036477234U //ubyteArrayOf(50U, 45U, 98U, 121U)
val sigma3_32 = 1797285236U //ubyteArrayOf(116U, 101U, 32U, 107U) val sigma3_32 = 1797285236U //ubyteArrayOf(116U, 101U, 32U, 107U)
fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, initialCounter: UInt = 0U): UByteArray { fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, initialCounter: UInt): UByteArray {
val ciphertext = UByteArray(message.size) val ciphertext = UByteArray(message.size)
val state = UIntArray(16) { val state = UIntArray(16) {
when (it) { when (it) {

View File

@ -1,7 +1,7 @@
package com.ionspin.kotlin.crypto.symmetric package com.ionspin.kotlin.crypto.symmetric
import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUIntWithPosition import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUIntWithPosition
import com.ionspin.kotlin.crypto.util.hexColumsPrint import com.ionspin.kotlin.crypto.util.overwriteWithZeroes
import com.ionspin.kotlin.crypto.util.xorWithPositionsAndInsertIntoArray import com.ionspin.kotlin.crypto.util.xorWithPositionsAndInsertIntoArray
/** /**
@ -9,8 +9,9 @@ import com.ionspin.kotlin.crypto.util.xorWithPositionsAndInsertIntoArray
* ugljesa.jovanovic@ionspin.com * ugljesa.jovanovic@ionspin.com
* on 14-Jun-2020 * on 14-Jun-2020
*/ */
internal class XChaCha20Pure { class XChaCha20Pure(key: UByteArray, nonce: UByteArray, initialCounter: UInt = 0U) {
companion object { companion object {
fun hChacha(key: UByteArray, nonce: UByteArray) : UIntArray { fun hChacha(key: UByteArray, nonce: UByteArray) : UIntArray {
val state = UIntArray(16) { val state = UIntArray(16) {
when (it) { when (it) {
@ -79,6 +80,7 @@ internal class XChaCha20Pure {
else -> 0U else -> 0U
} }
} }
hChaChaKey.overwriteWithZeroes()
val blocks = message.size / 64 val blocks = message.size / 64
val remainder = message.size % 64 val remainder = message.size % 64
for (i in 0 until blocks) { for (i in 0 until blocks) {
@ -98,4 +100,79 @@ internal class XChaCha20Pure {
} }
val state: UIntArray
val keystreamBuffer = UByteArray(64) { 0U}
var keystreamRemainingCounter = 0
var processedBytesSoFar = 0
init {
val hChaChaKey = hChacha(key, nonce)
state = UIntArray(16) {
when (it) {
0 -> ChaCha20Pure.sigma0_32
1 -> ChaCha20Pure.sigma1_32
2 -> ChaCha20Pure.sigma2_32
3 -> ChaCha20Pure.sigma3_32
4 -> hChaChaKey[0]
5 -> hChaChaKey[1]
6 -> hChaChaKey[2]
7 -> hChaChaKey[3]
8 -> hChaChaKey[4]
9 -> hChaChaKey[5]
10 -> hChaChaKey[6]
11 -> hChaChaKey[7]
12 -> initialCounter
13 -> 0U
14 -> nonce.fromLittleEndianArrayToUIntWithPosition(16)
15 -> nonce.fromLittleEndianArrayToUIntWithPosition(20)
else -> 0U
}
}
hChaChaKey.overwriteWithZeroes()
}
fun encryptPartialData(data: UByteArray) : UByteArray {
val ciphertext = UByteArray(data.size) { 0U }
//First use remaining keystream
var processedBytes = 0
if (data.size > keystreamRemainingCounter) {
keystreamBuffer.xorWithPositionsAndInsertIntoArray(
64 - keystreamRemainingCounter, 64,
data, 0,
ciphertext, 0
)
processedBytes += keystreamRemainingCounter
keystreamRemainingCounter = 0
}
//Then do full blocks
var remainingBytes = data.size - processedBytes
for (i in 0 until remainingBytes / 64) {
ChaCha20Pure.hash(state).xorWithPositionsAndInsertIntoArray(
0, 64,
data, processedBytes,
ciphertext, processedBytes
)
state[12] += 1U
if (state[12] == 0U) {
state[13] += 1U
}
processedBytes += 64
}
//Then do the remainder that didn't fit into 64byte blocks
remainingBytes = data.size - processedBytes
ChaCha20Pure.hash(state).copyInto(keystreamBuffer)
state[12] += 1U
if (state[12] == 0U) {
state[13] += 1U
}
keystreamBuffer.xorWithPositionsAndInsertIntoArray(
0, remainingBytes,
data, processedBytes,
ciphertext, processedBytes
)
keystreamRemainingCounter = 64 - remainingBytes
processedBytesSoFar += data.size
return ciphertext
}
} }

View File

@ -18,7 +18,7 @@
package com.ionspin.kotlin.crypto.util package com.ionspin.kotlin.crypto.util
//TODO Reorganize this, currently it's just a pile of useful helper functions
val _emitIntArray: IntArray = intArrayOf(1) val _emitIntArray: IntArray = intArrayOf(1)
/** /**
@ -108,11 +108,16 @@ fun UByteArray.xorWithPositions(start: Int, end: Int, other : UByteArray, otherS
return UByteArray(end - start) { this[start + it] xor other[otherStart + it] } return UByteArray(end - start) { this[start + it] xor other[otherStart + it] }
} }
/**
* Start index is included, end index is excluded
*/
fun UByteArray.xorWithPositionsAndInsertIntoArray( fun UByteArray.xorWithPositionsAndInsertIntoArray(
start: Int, end: Int, start: Int, end: Int,
other : UByteArray, otherStart: Int, other : UByteArray, otherStart: Int,
targetArray: UByteArray, targetStart : Int) { targetArray: UByteArray, targetStart : Int
for (i in start until end) { ) {
val length = end - start
for (i in 0 until length) {
targetArray[targetStart + i] = this[start + i] xor other[otherStart + i] targetArray[targetStart + i] = this[start + i] xor other[otherStart + i]
} }
} }
@ -340,6 +345,12 @@ operator fun UInt.plus(other : UByteArray) : UByteArray {
return this.toLittleEndianUByteArray() + other return this.toLittleEndianUByteArray() + other
} }
fun UIntArray.overwriteWithZeroes() {
for (i in 0 until size) {
this[i] = 0U
}
}
//AES Flatten //AES Flatten
fun Collection<UByteArray>.flattenToUByteArray(): UByteArray { fun Collection<UByteArray>.flattenToUByteArray(): UByteArray {
val result = UByteArray(sumBy { it.size }) val result = UByteArray(sumBy { it.size })

View File

@ -1,56 +1,56 @@
//package com.ionspin.kotlin.crypto.authenticated package com.ionspin.kotlin.crypto.authenticated
//
//import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
//import com.ionspin.kotlin.crypto.util.hexColumsPrint import com.ionspin.kotlin.crypto.util.hexColumsPrint
//import kotlin.test.Test import kotlin.test.Test
//import kotlin.test.assertTrue import kotlin.test.assertTrue
//
///** /**
// * Created by Ugljesa Jovanovic * Created by Ugljesa Jovanovic
// * ugljesa.jovanovic@ionspin.com * ugljesa.jovanovic@ionspin.com
// * on 17-Jun-2020 * on 17-Jun-2020
// */ */
//class ChaCha20Poly1305Test { class ChaCha20Poly1305Test {
//
//
//
// @Test @Test
// fun chaCha20Poly1305() { fun chaCha20Poly1305() {
// val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " +
// "only one tip for the future, sunscreen would be it.").encodeToUByteArray() "only one tip for the future, sunscreen would be it.").encodeToUByteArray()
//
// val additionalData = ubyteArrayOf( val additionalData = ubyteArrayOf(
// 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U
// ) )
// val key = ubyteArrayOf( val key = ubyteArrayOf(
// 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U,
// 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU,
// 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U,
// 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU,
// ) )
//
// val nonce = ubyteArrayOf( val nonce = ubyteArrayOf(
// 0x07U, 0x00U, 0x00U, 0x00U, 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U 0x07U, 0x00U, 0x00U, 0x00U, 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U
// ) )
// //Ciphertext + Poly1305TAG //Ciphertext + Poly1305TAG
// val expected = ubyteArrayOf( val expected = ubyteArrayOf(
// 0xd3U, 0x1aU, 0x8dU, 0x34U, 0x64U, 0x8eU, 0x60U, 0xdbU, 0x7bU, 0x86U, 0xafU, 0xbcU, 0x53U, 0xefU, 0x7eU, 0xc2U, 0xd3U, 0x1aU, 0x8dU, 0x34U, 0x64U, 0x8eU, 0x60U, 0xdbU, 0x7bU, 0x86U, 0xafU, 0xbcU, 0x53U, 0xefU, 0x7eU, 0xc2U,
// 0xa4U, 0xadU, 0xedU, 0x51U, 0x29U, 0x6eU, 0x08U, 0xfeU, 0xa9U, 0xe2U, 0xb5U, 0xa7U, 0x36U, 0xeeU, 0x62U, 0xd6U, 0xa4U, 0xadU, 0xedU, 0x51U, 0x29U, 0x6eU, 0x08U, 0xfeU, 0xa9U, 0xe2U, 0xb5U, 0xa7U, 0x36U, 0xeeU, 0x62U, 0xd6U,
// 0x3dU, 0xbeU, 0xa4U, 0x5eU, 0x8cU, 0xa9U, 0x67U, 0x12U, 0x82U, 0xfaU, 0xfbU, 0x69U, 0xdaU, 0x92U, 0x72U, 0x8bU, 0x3dU, 0xbeU, 0xa4U, 0x5eU, 0x8cU, 0xa9U, 0x67U, 0x12U, 0x82U, 0xfaU, 0xfbU, 0x69U, 0xdaU, 0x92U, 0x72U, 0x8bU,
// 0x1aU, 0x71U, 0xdeU, 0x0aU, 0x9eU, 0x06U, 0x0bU, 0x29U, 0x05U, 0xd6U, 0xa5U, 0xb6U, 0x7eU, 0xcdU, 0x3bU, 0x36U, 0x1aU, 0x71U, 0xdeU, 0x0aU, 0x9eU, 0x06U, 0x0bU, 0x29U, 0x05U, 0xd6U, 0xa5U, 0xb6U, 0x7eU, 0xcdU, 0x3bU, 0x36U,
// 0x92U, 0xddU, 0xbdU, 0x7fU, 0x2dU, 0x77U, 0x8bU, 0x8cU, 0x98U, 0x03U, 0xaeU, 0xe3U, 0x28U, 0x09U, 0x1bU, 0x58U, 0x92U, 0xddU, 0xbdU, 0x7fU, 0x2dU, 0x77U, 0x8bU, 0x8cU, 0x98U, 0x03U, 0xaeU, 0xe3U, 0x28U, 0x09U, 0x1bU, 0x58U,
// 0xfaU, 0xb3U, 0x24U, 0xe4U, 0xfaU, 0xd6U, 0x75U, 0x94U, 0x55U, 0x85U, 0x80U, 0x8bU, 0x48U, 0x31U, 0xd7U, 0xbcU, 0xfaU, 0xb3U, 0x24U, 0xe4U, 0xfaU, 0xd6U, 0x75U, 0x94U, 0x55U, 0x85U, 0x80U, 0x8bU, 0x48U, 0x31U, 0xd7U, 0xbcU,
// 0x3fU, 0xf4U, 0xdeU, 0xf0U, 0x8eU, 0x4bU, 0x7aU, 0x9dU, 0xe5U, 0x76U, 0xd2U, 0x65U, 0x86U, 0xceU, 0xc6U, 0x4bU, 0x3fU, 0xf4U, 0xdeU, 0xf0U, 0x8eU, 0x4bU, 0x7aU, 0x9dU, 0xe5U, 0x76U, 0xd2U, 0x65U, 0x86U, 0xceU, 0xc6U, 0x4bU,
// 0x61U, 0x16U, 0x1aU, 0xe1U, 0x0bU, 0x59U, 0x4fU, 0x09U, 0xe2U, 0x6aU, 0x7eU, 0x90U, 0x2eU, 0xcbU, 0xd0U, 0x60U, 0x61U, 0x16U, 0x1aU, 0xe1U, 0x0bU, 0x59U, 0x4fU, 0x09U, 0xe2U, 0x6aU, 0x7eU, 0x90U, 0x2eU, 0xcbU, 0xd0U, 0x60U,
// 0x06U, 0x91U 0x06U, 0x91U
// ) )
// val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData)
// result.hexColumsPrint() result.hexColumsPrint()
// assertTrue { assertTrue {
// result.contentEquals(expected) result.contentEquals(expected)
// } }
//
// } }
//
//
//} }

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.symmetric package com.ionspin.kotlin.crypto.symmetric
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.hexColumsPrint import com.ionspin.kotlin.crypto.util.hexColumsPrint
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -39,55 +40,96 @@ class XChaCha20Test {
@Test @Test
fun testXChaCha20() { fun testXChaCha20() {
val key = ubyteArrayOf( val key = ubyteArrayOf(
0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U,
0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU,
0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U,
0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU
) )
val nonce = ubyteArrayOf( val nonce = ubyteArrayOf(
0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U,
0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU,
0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x58U 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x58U
) )
val message = ubyteArrayOf( val message = ubyteArrayOf(
0x54U, 0x68U, 0x65U, 0x20U, 0x64U, 0x68U, 0x6fU, 0x6cU, 0x65U, 0x20U, 0x28U, 0x70U, 0x72U, 0x6fU, 0x6eU, 0x6fU, 0x54U, 0x68U, 0x65U, 0x20U, 0x64U, 0x68U, 0x6fU, 0x6cU,
0x75U, 0x6eU, 0x63U, 0x65U, 0x64U, 0x20U, 0x22U, 0x64U, 0x6fU, 0x6cU, 0x65U, 0x22U, 0x29U, 0x20U, 0x69U, 0x73U, 0x65U, 0x20U, 0x28U, 0x70U, 0x72U, 0x6fU, 0x6eU, 0x6fU,
0x20U, 0x61U, 0x6cU, 0x73U, 0x6fU, 0x20U, 0x6bU, 0x6eU, 0x6fU, 0x77U, 0x6eU, 0x20U, 0x61U, 0x73U, 0x20U, 0x74U, 0x75U, 0x6eU, 0x63U, 0x65U, 0x64U, 0x20U, 0x22U, 0x64U,
0x68U, 0x65U, 0x20U, 0x41U, 0x73U, 0x69U, 0x61U, 0x74U, 0x69U, 0x63U, 0x20U, 0x77U, 0x69U, 0x6cU, 0x64U, 0x20U, 0x6fU, 0x6cU, 0x65U, 0x22U, 0x29U, 0x20U, 0x69U, 0x73U,
0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x72U, 0x65U, 0x64U, 0x20U, 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x61U, 0x6eU, 0x20U, 0x61U, 0x6cU, 0x73U, 0x6fU, 0x20U, 0x6bU, 0x6eU,
0x64U, 0x20U, 0x77U, 0x68U, 0x69U, 0x73U, 0x74U, 0x6cU, 0x69U, 0x6eU, 0x67U, 0x20U, 0x64U, 0x6fU, 0x67U, 0x2eU, 0x6fU, 0x77U, 0x6eU, 0x20U, 0x61U, 0x73U, 0x20U, 0x74U,
0x20U, 0x49U, 0x74U, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x62U, 0x6fU, 0x75U, 0x74U, 0x20U, 0x74U, 0x68U, 0x65U, 0x68U, 0x65U, 0x20U, 0x41U, 0x73U, 0x69U, 0x61U, 0x74U,
0x20U, 0x73U, 0x69U, 0x7aU, 0x65U, 0x20U, 0x6fU, 0x66U, 0x20U, 0x61U, 0x20U, 0x47U, 0x65U, 0x72U, 0x6dU, 0x61U, 0x69U, 0x63U, 0x20U, 0x77U, 0x69U, 0x6cU, 0x64U, 0x20U,
0x6eU, 0x20U, 0x73U, 0x68U, 0x65U, 0x70U, 0x68U, 0x65U, 0x72U, 0x64U, 0x20U, 0x62U, 0x75U, 0x74U, 0x20U, 0x6cU, 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x72U, 0x65U, 0x64U,
0x6fU, 0x6fU, 0x6bU, 0x73U, 0x20U, 0x6dU, 0x6fU, 0x72U, 0x65U, 0x20U, 0x6cU, 0x69U, 0x6bU, 0x65U, 0x20U, 0x61U, 0x20U, 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x61U, 0x6eU,
0x20U, 0x6cU, 0x6fU, 0x6eU, 0x67U, 0x2dU, 0x6cU, 0x65U, 0x67U, 0x67U, 0x65U, 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, 0x64U, 0x20U, 0x77U, 0x68U, 0x69U, 0x73U, 0x74U, 0x6cU,
0x2eU, 0x20U, 0x54U, 0x68U, 0x69U, 0x73U, 0x20U, 0x68U, 0x69U, 0x67U, 0x68U, 0x6cU, 0x79U, 0x20U, 0x65U, 0x6cU, 0x69U, 0x6eU, 0x67U, 0x20U, 0x64U, 0x6fU, 0x67U, 0x2eU,
0x75U, 0x73U, 0x69U, 0x76U, 0x65U, 0x20U, 0x61U, 0x6eU, 0x64U, 0x20U, 0x73U, 0x6bU, 0x69U, 0x6cU, 0x6cU, 0x65U, 0x20U, 0x49U, 0x74U, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U,
0x64U, 0x20U, 0x6aU, 0x75U, 0x6dU, 0x70U, 0x65U, 0x72U, 0x20U, 0x69U, 0x73U, 0x20U, 0x63U, 0x6cU, 0x61U, 0x73U, 0x62U, 0x6fU, 0x75U, 0x74U, 0x20U, 0x74U, 0x68U, 0x65U,
0x73U, 0x69U, 0x66U, 0x69U, 0x65U, 0x64U, 0x20U, 0x77U, 0x69U, 0x74U, 0x68U, 0x20U, 0x77U, 0x6fU, 0x6cU, 0x76U, 0x20U, 0x73U, 0x69U, 0x7aU, 0x65U, 0x20U, 0x6fU, 0x66U,
0x65U, 0x73U, 0x2cU, 0x20U, 0x63U, 0x6fU, 0x79U, 0x6fU, 0x74U, 0x65U, 0x73U, 0x2cU, 0x20U, 0x6aU, 0x61U, 0x63U, 0x20U, 0x61U, 0x20U, 0x47U, 0x65U, 0x72U, 0x6dU, 0x61U,
0x6bU, 0x61U, 0x6cU, 0x73U, 0x2cU, 0x20U, 0x61U, 0x6eU, 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, 0x65U, 0x73U, 0x20U, 0x6eU, 0x20U, 0x73U, 0x68U, 0x65U, 0x70U, 0x68U, 0x65U,
0x69U, 0x6eU, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x74U, 0x61U, 0x78U, 0x6fU, 0x6eU, 0x6fU, 0x6dU, 0x69U, 0x63U, 0x72U, 0x64U, 0x20U, 0x62U, 0x75U, 0x74U, 0x20U, 0x6cU,
0x20U, 0x66U, 0x61U, 0x6dU, 0x69U, 0x6cU, 0x79U, 0x20U, 0x43U, 0x61U, 0x6eU, 0x69U, 0x64U, 0x61U, 0x65U, 0x2eU, 0x6fU, 0x6fU, 0x6bU, 0x73U, 0x20U, 0x6dU, 0x6fU, 0x72U,
0x65U, 0x20U, 0x6cU, 0x69U, 0x6bU, 0x65U, 0x20U, 0x61U,
0x20U, 0x6cU, 0x6fU, 0x6eU, 0x67U, 0x2dU, 0x6cU, 0x65U,
0x67U, 0x67U, 0x65U, 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U,
0x2eU, 0x20U, 0x54U, 0x68U, 0x69U, 0x73U, 0x20U, 0x68U,
0x69U, 0x67U, 0x68U, 0x6cU, 0x79U, 0x20U, 0x65U, 0x6cU,
0x75U, 0x73U, 0x69U, 0x76U, 0x65U, 0x20U, 0x61U, 0x6eU,
0x64U, 0x20U, 0x73U, 0x6bU, 0x69U, 0x6cU, 0x6cU, 0x65U,
0x64U, 0x20U, 0x6aU, 0x75U, 0x6dU, 0x70U, 0x65U, 0x72U,
0x20U, 0x69U, 0x73U, 0x20U, 0x63U, 0x6cU, 0x61U, 0x73U,
0x73U, 0x69U, 0x66U, 0x69U, 0x65U, 0x64U, 0x20U, 0x77U,
0x69U, 0x74U, 0x68U, 0x20U, 0x77U, 0x6fU, 0x6cU, 0x76U,
0x65U, 0x73U, 0x2cU, 0x20U, 0x63U, 0x6fU, 0x79U, 0x6fU,
0x74U, 0x65U, 0x73U, 0x2cU, 0x20U, 0x6aU, 0x61U, 0x63U,
0x6bU, 0x61U, 0x6cU, 0x73U, 0x2cU, 0x20U, 0x61U, 0x6eU,
0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, 0x65U, 0x73U, 0x20U,
0x69U, 0x6eU, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x74U,
0x61U, 0x78U, 0x6fU, 0x6eU, 0x6fU, 0x6dU, 0x69U, 0x63U,
0x20U, 0x66U, 0x61U, 0x6dU, 0x69U, 0x6cU, 0x79U, 0x20U,
0x43U, 0x61U, 0x6eU, 0x69U, 0x64U, 0x61U, 0x65U, 0x2eU,
) )
val expected = ubyteArrayOf( val expected = ubyteArrayOf(
0x7dU, 0x0aU, 0x2eU, 0x6bU, 0x7fU, 0x7cU, 0x65U, 0xa2U, 0x36U, 0x54U, 0x26U, 0x30U, 0x29U, 0x4eU, 0x06U, 0x3bU, 0x7dU, 0x0aU, 0x2eU, 0x6bU, 0x7fU, 0x7cU, 0x65U, 0xa2U,
0x7aU, 0xb9U, 0xb5U, 0x55U, 0xa5U, 0xd5U, 0x14U, 0x9aU, 0xa2U, 0x1eU, 0x4aU, 0xe1U, 0xe4U, 0xfbU, 0xceU, 0x87U, 0x36U, 0x54U, 0x26U, 0x30U, 0x29U, 0x4eU, 0x06U, 0x3bU,
0xecU, 0xc8U, 0xe0U, 0x8aU, 0x8bU, 0x5eU, 0x35U, 0x0aU, 0xbeU, 0x62U, 0x2bU, 0x2fU, 0xfaU, 0x61U, 0x7bU, 0x20U, 0x7aU, 0xb9U, 0xb5U, 0x55U, 0xa5U, 0xd5U, 0x14U, 0x9aU,
0x2cU, 0xfaU, 0xd7U, 0x20U, 0x32U, 0xa3U, 0x03U, 0x7eU, 0x76U, 0xffU, 0xdcU, 0xdcU, 0x43U, 0x76U, 0xeeU, 0x05U, 0xa2U, 0x1eU, 0x4aU, 0xe1U, 0xe4U, 0xfbU, 0xceU, 0x87U,
0x3aU, 0x19U, 0x0dU, 0x7eU, 0x46U, 0xcaU, 0x1dU, 0xe0U, 0x41U, 0x44U, 0x85U, 0x03U, 0x81U, 0xb9U, 0xcbU, 0x29U, 0xecU, 0xc8U, 0xe0U, 0x8aU, 0x8bU, 0x5eU, 0x35U, 0x0aU,
0xf0U, 0x51U, 0x91U, 0x53U, 0x86U, 0xb8U, 0xa7U, 0x10U, 0xb8U, 0xacU, 0x4dU, 0x02U, 0x7bU, 0x8bU, 0x05U, 0x0fU, 0xbeU, 0x62U, 0x2bU, 0x2fU, 0xfaU, 0x61U, 0x7bU, 0x20U,
0x7cU, 0xbaU, 0x58U, 0x54U, 0xe0U, 0x28U, 0xd5U, 0x64U, 0xe4U, 0x53U, 0xb8U, 0xa9U, 0x68U, 0x82U, 0x41U, 0x73U, 0x2cU, 0xfaU, 0xd7U, 0x20U, 0x32U, 0xa3U, 0x03U, 0x7eU,
0xfcU, 0x16U, 0x48U, 0x8bU, 0x89U, 0x70U, 0xcaU, 0xc8U, 0x28U, 0xf1U, 0x1aU, 0xe5U, 0x3cU, 0xabU, 0xd2U, 0x01U, 0x76U, 0xffU, 0xdcU, 0xdcU, 0x43U, 0x76U, 0xeeU, 0x05U,
0x12U, 0xf8U, 0x71U, 0x07U, 0xdfU, 0x24U, 0xeeU, 0x61U, 0x83U, 0xd2U, 0x27U, 0x4fU, 0xe4U, 0xc8U, 0xb1U, 0x48U, 0x3aU, 0x19U, 0x0dU, 0x7eU, 0x46U, 0xcaU, 0x1dU, 0xe0U,
0x55U, 0x34U, 0xefU, 0x2cU, 0x5fU, 0xbcU, 0x1eU, 0xc2U, 0x4bU, 0xfcU, 0x36U, 0x63U, 0xefU, 0xaaU, 0x08U, 0xbcU, 0x41U, 0x44U, 0x85U, 0x03U, 0x81U, 0xb9U, 0xcbU, 0x29U,
0x04U, 0x7dU, 0x29U, 0xd2U, 0x50U, 0x43U, 0x53U, 0x2dU, 0xb8U, 0x39U, 0x1aU, 0x8aU, 0x3dU, 0x77U, 0x6bU, 0xf4U, 0xf0U, 0x51U, 0x91U, 0x53U, 0x86U, 0xb8U, 0xa7U, 0x10U,
0x37U, 0x2aU, 0x69U, 0x55U, 0x82U, 0x7cU, 0xcbU, 0x0cU, 0xddU, 0x4aU, 0xf4U, 0x03U, 0xa7U, 0xceU, 0x4cU, 0x63U, 0xb8U, 0xacU, 0x4dU, 0x02U, 0x7bU, 0x8bU, 0x05U, 0x0fU,
0xd5U, 0x95U, 0xc7U, 0x5aU, 0x43U, 0xe0U, 0x45U, 0xf0U, 0xccU, 0xe1U, 0xf2U, 0x9cU, 0x8bU, 0x93U, 0xbdU, 0x65U, 0x7cU, 0xbaU, 0x58U, 0x54U, 0xe0U, 0x28U, 0xd5U, 0x64U,
0xafU, 0xc5U, 0x97U, 0x49U, 0x22U, 0xf2U, 0x14U, 0xa4U, 0x0bU, 0x7cU, 0x40U, 0x2cU, 0xdbU, 0x91U, 0xaeU, 0x73U, 0xe4U, 0x53U, 0xb8U, 0xa9U, 0x68U, 0x82U, 0x41U, 0x73U,
0xc0U, 0xb6U, 0x36U, 0x15U, 0xcdU, 0xadU, 0x04U, 0x80U, 0x68U, 0x0fU, 0x16U, 0x51U, 0x5aU, 0x7aU, 0xceU, 0x9dU, 0xfcU, 0x16U, 0x48U, 0x8bU, 0x89U, 0x70U, 0xcaU, 0xc8U,
0x39U, 0x23U, 0x64U, 0x64U, 0x32U, 0x8aU, 0x37U, 0x74U, 0x3fU, 0xfcU, 0x28U, 0xf4U, 0xddU, 0xb3U, 0x24U, 0xf4U, 0x28U, 0xf1U, 0x1aU, 0xe5U, 0x3cU, 0xabU, 0xd2U, 0x01U,
0xd0U, 0xf5U, 0xbbU, 0xdcU, 0x27U, 0x0cU, 0x65U, 0xb1U, 0x74U, 0x9aU, 0x6eU, 0xffU, 0xf1U, 0xfbU, 0xaaU, 0x09U, 0x12U, 0xf8U, 0x71U, 0x07U, 0xdfU, 0x24U, 0xeeU, 0x61U,
0x53U, 0x61U, 0x75U, 0xccU, 0xd2U, 0x9fU, 0xb9U, 0xe6U, 0x05U, 0x7bU, 0x30U, 0x73U, 0x20U, 0xd3U, 0x16U, 0x83U, 0x83U, 0xd2U, 0x27U, 0x4fU, 0xe4U, 0xc8U, 0xb1U, 0x48U,
0x8aU, 0x9cU, 0x71U, 0xf7U, 0x0bU, 0x5bU, 0x59U, 0x07U, 0xa6U, 0x6fU, 0x7eU, 0xa4U, 0x9aU, 0xadU, 0xc4U, 0x09U, 0x55U, 0x34U, 0xefU, 0x2cU, 0x5fU, 0xbcU, 0x1eU, 0xc2U,
0x4bU, 0xfcU, 0x36U, 0x63U, 0xefU, 0xaaU, 0x08U, 0xbcU,
0x04U, 0x7dU, 0x29U, 0xd2U, 0x50U, 0x43U, 0x53U, 0x2dU,
0xb8U, 0x39U, 0x1aU, 0x8aU, 0x3dU, 0x77U, 0x6bU, 0xf4U,
0x37U, 0x2aU, 0x69U, 0x55U, 0x82U, 0x7cU, 0xcbU, 0x0cU,
0xddU, 0x4aU, 0xf4U, 0x03U, 0xa7U, 0xceU, 0x4cU, 0x63U,
0xd5U, 0x95U, 0xc7U, 0x5aU, 0x43U, 0xe0U, 0x45U, 0xf0U,
0xccU, 0xe1U, 0xf2U, 0x9cU, 0x8bU, 0x93U, 0xbdU, 0x65U,
0xafU, 0xc5U, 0x97U, 0x49U, 0x22U, 0xf2U, 0x14U, 0xa4U,
0x0bU, 0x7cU, 0x40U, 0x2cU, 0xdbU, 0x91U, 0xaeU, 0x73U,
0xc0U, 0xb6U, 0x36U, 0x15U, 0xcdU, 0xadU, 0x04U, 0x80U,
0x68U, 0x0fU, 0x16U, 0x51U, 0x5aU, 0x7aU, 0xceU, 0x9dU,
0x39U, 0x23U, 0x64U, 0x64U, 0x32U, 0x8aU, 0x37U, 0x74U,
0x3fU, 0xfcU, 0x28U, 0xf4U, 0xddU, 0xb3U, 0x24U, 0xf4U,
0xd0U, 0xf5U, 0xbbU, 0xdcU, 0x27U, 0x0cU, 0x65U, 0xb1U,
0x74U, 0x9aU, 0x6eU, 0xffU, 0xf1U, 0xfbU, 0xaaU, 0x09U,
0x53U, 0x61U, 0x75U, 0xccU, 0xd2U, 0x9fU, 0xb9U, 0xe6U,
0x05U, 0x7bU, 0x30U, 0x73U, 0x20U, 0xd3U, 0x16U, 0x83U,
0x8aU, 0x9cU, 0x71U, 0xf7U, 0x0bU, 0x5bU, 0x59U, 0x07U,
0xa6U, 0x6fU, 0x7eU, 0xa4U, 0x9aU, 0xadU, 0xc4U, 0x09U,
) )
@ -98,4 +140,202 @@ class XChaCha20Test {
} }
@Test
fun testXChaCha20Updateable() {
val key = ubyteArrayOf(
0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U,
0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU,
0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U,
0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU
)
val nonce = ubyteArrayOf(
0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U,
0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU,
0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x58U
)
val message = ubyteArrayOf(
0x54U, 0x68U, 0x65U, 0x20U, 0x64U, 0x68U, 0x6fU, 0x6cU,
0x65U, 0x20U, 0x28U, 0x70U, 0x72U, 0x6fU, 0x6eU, 0x6fU,
0x75U, 0x6eU, 0x63U, 0x65U, 0x64U, 0x20U, 0x22U, 0x64U,
0x6fU, 0x6cU, 0x65U, 0x22U, 0x29U, 0x20U, 0x69U, 0x73U,
0x20U, 0x61U, 0x6cU, 0x73U, 0x6fU, 0x20U, 0x6bU, 0x6eU,
0x6fU, 0x77U, 0x6eU, 0x20U, 0x61U, 0x73U, 0x20U, 0x74U,
0x68U, 0x65U, 0x20U, 0x41U, 0x73U, 0x69U, 0x61U, 0x74U,
0x69U, 0x63U, 0x20U, 0x77U, 0x69U, 0x6cU, 0x64U, 0x20U,
0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x72U, 0x65U, 0x64U,
0x20U, 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x61U, 0x6eU,
0x64U, 0x20U, 0x77U, 0x68U, 0x69U, 0x73U, 0x74U, 0x6cU,
0x69U, 0x6eU, 0x67U, 0x20U, 0x64U, 0x6fU, 0x67U, 0x2eU,
0x20U, 0x49U, 0x74U, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U,
0x62U, 0x6fU, 0x75U, 0x74U, 0x20U, 0x74U, 0x68U, 0x65U,
0x20U, 0x73U, 0x69U, 0x7aU, 0x65U, 0x20U, 0x6fU, 0x66U,
0x20U, 0x61U, 0x20U, 0x47U, 0x65U, 0x72U, 0x6dU, 0x61U,
0x6eU, 0x20U, 0x73U, 0x68U, 0x65U, 0x70U, 0x68U, 0x65U,
0x72U, 0x64U, 0x20U, 0x62U, 0x75U, 0x74U, 0x20U, 0x6cU,
0x6fU, 0x6fU, 0x6bU, 0x73U, 0x20U, 0x6dU, 0x6fU, 0x72U,
0x65U, 0x20U, 0x6cU, 0x69U, 0x6bU, 0x65U, 0x20U, 0x61U,
0x20U, 0x6cU, 0x6fU, 0x6eU, 0x67U, 0x2dU, 0x6cU, 0x65U,
0x67U, 0x67U, 0x65U, 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U,
0x2eU, 0x20U, 0x54U, 0x68U, 0x69U, 0x73U, 0x20U, 0x68U,
0x69U, 0x67U, 0x68U, 0x6cU, 0x79U, 0x20U, 0x65U, 0x6cU,
0x75U, 0x73U, 0x69U, 0x76U, 0x65U, 0x20U, 0x61U, 0x6eU,
0x64U, 0x20U, 0x73U, 0x6bU, 0x69U, 0x6cU, 0x6cU, 0x65U,
0x64U, 0x20U, 0x6aU, 0x75U, 0x6dU, 0x70U, 0x65U, 0x72U,
0x20U, 0x69U, 0x73U, 0x20U, 0x63U, 0x6cU, 0x61U, 0x73U,
0x73U, 0x69U, 0x66U, 0x69U, 0x65U, 0x64U, 0x20U, 0x77U,
0x69U, 0x74U, 0x68U, 0x20U, 0x77U, 0x6fU, 0x6cU, 0x76U,
0x65U, 0x73U, 0x2cU, 0x20U, 0x63U, 0x6fU, 0x79U, 0x6fU,
0x74U, 0x65U, 0x73U, 0x2cU, 0x20U, 0x6aU, 0x61U, 0x63U,
0x6bU, 0x61U, 0x6cU, 0x73U, 0x2cU, 0x20U, 0x61U, 0x6eU,
0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, 0x65U, 0x73U, 0x20U,
0x69U, 0x6eU, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x74U,
0x61U, 0x78U, 0x6fU, 0x6eU, 0x6fU, 0x6dU, 0x69U, 0x63U,
0x20U, 0x66U, 0x61U, 0x6dU, 0x69U, 0x6cU, 0x79U, 0x20U,
0x43U, 0x61U, 0x6eU, 0x69U, 0x64U, 0x61U, 0x65U, 0x2eU,
)
val expected = ubyteArrayOf(
0x7dU, 0x0aU, 0x2eU, 0x6bU, 0x7fU, 0x7cU, 0x65U, 0xa2U,
0x36U, 0x54U, 0x26U, 0x30U, 0x29U, 0x4eU, 0x06U, 0x3bU,
0x7aU, 0xb9U, 0xb5U, 0x55U, 0xa5U, 0xd5U, 0x14U, 0x9aU,
0xa2U, 0x1eU, 0x4aU, 0xe1U, 0xe4U, 0xfbU, 0xceU, 0x87U,
0xecU, 0xc8U, 0xe0U, 0x8aU, 0x8bU, 0x5eU, 0x35U, 0x0aU,
0xbeU, 0x62U, 0x2bU, 0x2fU, 0xfaU, 0x61U, 0x7bU, 0x20U,
0x2cU, 0xfaU, 0xd7U, 0x20U, 0x32U, 0xa3U, 0x03U, 0x7eU,
0x76U, 0xffU, 0xdcU, 0xdcU, 0x43U, 0x76U, 0xeeU, 0x05U,
0x3aU, 0x19U, 0x0dU, 0x7eU, 0x46U, 0xcaU, 0x1dU, 0xe0U,
0x41U, 0x44U, 0x85U, 0x03U, 0x81U, 0xb9U, 0xcbU, 0x29U,
0xf0U, 0x51U, 0x91U, 0x53U, 0x86U, 0xb8U, 0xa7U, 0x10U,
0xb8U, 0xacU, 0x4dU, 0x02U, 0x7bU, 0x8bU, 0x05U, 0x0fU,
0x7cU, 0xbaU, 0x58U, 0x54U, 0xe0U, 0x28U, 0xd5U, 0x64U,
0xe4U, 0x53U, 0xb8U, 0xa9U, 0x68U, 0x82U, 0x41U, 0x73U,
0xfcU, 0x16U, 0x48U, 0x8bU, 0x89U, 0x70U, 0xcaU, 0xc8U,
0x28U, 0xf1U, 0x1aU, 0xe5U, 0x3cU, 0xabU, 0xd2U, 0x01U,
0x12U, 0xf8U, 0x71U, 0x07U, 0xdfU, 0x24U, 0xeeU, 0x61U,
0x83U, 0xd2U, 0x27U, 0x4fU, 0xe4U, 0xc8U, 0xb1U, 0x48U,
0x55U, 0x34U, 0xefU, 0x2cU, 0x5fU, 0xbcU, 0x1eU, 0xc2U,
0x4bU, 0xfcU, 0x36U, 0x63U, 0xefU, 0xaaU, 0x08U, 0xbcU,
0x04U, 0x7dU, 0x29U, 0xd2U, 0x50U, 0x43U, 0x53U, 0x2dU,
0xb8U, 0x39U, 0x1aU, 0x8aU, 0x3dU, 0x77U, 0x6bU, 0xf4U,
0x37U, 0x2aU, 0x69U, 0x55U, 0x82U, 0x7cU, 0xcbU, 0x0cU,
0xddU, 0x4aU, 0xf4U, 0x03U, 0xa7U, 0xceU, 0x4cU, 0x63U,
0xd5U, 0x95U, 0xc7U, 0x5aU, 0x43U, 0xe0U, 0x45U, 0xf0U,
0xccU, 0xe1U, 0xf2U, 0x9cU, 0x8bU, 0x93U, 0xbdU, 0x65U,
0xafU, 0xc5U, 0x97U, 0x49U, 0x22U, 0xf2U, 0x14U, 0xa4U,
0x0bU, 0x7cU, 0x40U, 0x2cU, 0xdbU, 0x91U, 0xaeU, 0x73U,
0xc0U, 0xb6U, 0x36U, 0x15U, 0xcdU, 0xadU, 0x04U, 0x80U,
0x68U, 0x0fU, 0x16U, 0x51U, 0x5aU, 0x7aU, 0xceU, 0x9dU,
0x39U, 0x23U, 0x64U, 0x64U, 0x32U, 0x8aU, 0x37U, 0x74U,
0x3fU, 0xfcU, 0x28U, 0xf4U, 0xddU, 0xb3U, 0x24U, 0xf4U,
0xd0U, 0xf5U, 0xbbU, 0xdcU, 0x27U, 0x0cU, 0x65U, 0xb1U,
0x74U, 0x9aU, 0x6eU, 0xffU, 0xf1U, 0xfbU, 0xaaU, 0x09U,
0x53U, 0x61U, 0x75U, 0xccU, 0xd2U, 0x9fU, 0xb9U, 0xe6U,
0x05U, 0x7bU, 0x30U, 0x73U, 0x20U, 0xd3U, 0x16U, 0x83U,
0x8aU, 0x9cU, 0x71U, 0xf7U, 0x0bU, 0x5bU, 0x59U, 0x07U,
0xa6U, 0x6fU, 0x7eU, 0xa4U, 0x9aU, 0xadU, 0xc4U, 0x09U,
)
val xChaCha = XChaCha20Pure(key, nonce, 1U)
val firstChunk = xChaCha.encryptPartialData(message.sliceArray(0 until 5))
val secondChunk = xChaCha.encryptPartialData(message.sliceArray(5 until 90))
val thirdChunk = xChaCha.encryptPartialData(message.sliceArray(90 until message.size))
assertTrue {
(firstChunk + secondChunk + thirdChunk).contentEquals(expected)
}
}
@Test
fun testXChaCha20UpdateableLonger() {
val key = ubyteArrayOf(
0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U,
0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU,
0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U,
0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU
)
val nonce = ubyteArrayOf(
0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U,
0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU,
0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x58U
)
val message = ("This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long." +
"This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long." +
"This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long." +
"This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long.").encodeToUByteArray()
val expected = ubyteArrayOf(
0x7DU, 0x0AU, 0x22U, 0x38U, 0x3BU, 0x7DU, 0x79U, 0xEEU,
0x32U, 0x54U, 0x62U, 0x2FU, 0x35U, 0x46U, 0x0DU, 0x26U,
0x2FU, 0xBAU, 0xB3U, 0x43U, 0xB2U, 0x94U, 0x51U, 0x9BU,
0xEDU, 0x06U, 0x47U, 0xA2U, 0xB9U, 0xFBU, 0xD4U, 0x9CU,
0xA3U, 0xDCU, 0xE0U, 0x9DU, 0xC4U, 0x1DU, 0x31U, 0x12U,
0xB4U, 0x67U, 0x65U, 0x6EU, 0xF7U, 0x7EU, 0x7BU, 0x37U,
0x25U, 0xECU, 0x92U, 0x12U, 0x61U, 0xA3U, 0x0CU, 0x2AU,
0x6BU, 0xF4U, 0x99U, 0x8BU, 0x5FU, 0x6AU, 0xEEU, 0x44U,
0x2AU, 0x13U, 0x0BU, 0x30U, 0x0AU, 0xDDU, 0x58U, 0xE5U,
0x0DU, 0x47U, 0x85U, 0x16U, 0xC4U, 0xEDU, 0xC2U, 0x2AU,
0xBAU, 0x51U, 0xB2U, 0x53U, 0x86U, 0xB8U, 0xF3U, 0x0FU,
0xA5U, 0xB0U, 0x43U, 0x4CU, 0x78U, 0xC4U, 0x0BU, 0x52U,
0x7CU, 0xC2U, 0x1DU, 0x46U, 0xA9U, 0x39U, 0x8CU, 0x71U,
0xE3U, 0x4FU, 0xEDU, 0xB1U, 0x27U, 0x98U, 0x4EU, 0x38U,
0x88U, 0x0DU, 0x48U, 0x82U, 0xCCU, 0x39U, 0xD6U, 0x8EU,
0x69U, 0xB0U, 0x56U, 0xCDU, 0x37U, 0xBEU, 0xDAU, 0x12U,
0x5CU, 0xB5U, 0x67U, 0x1CU, 0xC9U, 0x35U, 0xE1U, 0x61U,
0xD1U, 0xC2U, 0x6FU, 0x4CU, 0xE5U, 0x9CU, 0xE2U, 0x4CU,
0x55U, 0x2EU, 0xE8U, 0x3BU, 0x5FU, 0xB2U, 0x1EU, 0xC6U,
0x4BU, 0xAEU, 0x7AU, 0x6BU, 0xE8U, 0xA3U, 0x08U, 0xBEU,
0x45U, 0x62U, 0x23U, 0xCFU, 0x17U, 0x07U, 0x51U, 0x68U,
0xABU, 0x36U, 0x1AU, 0xCEU, 0x68U, 0x61U, 0x60U, 0xEDU,
0x6DU, 0x6FU, 0x5CU, 0x5FU, 0x87U, 0x6AU, 0xCBU, 0x05U,
0xD8U, 0x4AU, 0xF3U, 0x1DU, 0xB7U, 0x9AU, 0x41U, 0x62U,
0x8EU, 0xC6U, 0xFAU, 0x44U, 0x4FU, 0xB3U, 0x04U, 0xEDU,
0xDCU, 0xB3U, 0xE8U, 0x99U, 0x85U, 0xDFU, 0xB8U, 0x73U,
0xEBU, 0xD4U, 0xCCU, 0x0EU, 0x6FU, 0xE0U, 0x08U, 0xA2U,
0x4EU, 0x66U, 0x13U, 0x60U, 0xD7U, 0x93U, 0xA8U, 0x2EU,
0xE7U, 0xB7U, 0x39U, 0x0FU, 0x88U, 0xA0U, 0x57U, 0xD7U,
0x60U, 0x5BU, 0x12U, 0x1EU, 0x43U, 0x72U, 0xC7U, 0x99U,
0x7CU, 0x3DU, 0x2DU, 0x37U, 0x22U, 0x84U, 0x29U, 0x7EU,
0x6BU, 0xEDU, 0x33U, 0xB9U, 0x89U, 0xF9U, 0x36U, 0xFFU,
0xD4U, 0xE1U, 0xBBU, 0xCBU, 0x2BU, 0x4FU, 0x6BU, 0xA9U,
0x75U, 0xC8U, 0x28U, 0xF1U, 0xE5U, 0xF2U, 0xF9U, 0x4AU,
0x5BU, 0x7CU, 0x30U, 0xCBU, 0x9AU, 0x93U, 0xF7U, 0xB2U,
0x10U, 0x6BU, 0x3AU, 0x3DU, 0x3AU, 0xCEU, 0x1BU, 0x81U,
0xDEU, 0x9FU, 0x71U, 0xF8U, 0x0EU, 0x52U, 0x00U, 0x46U,
0x89U, 0x69U, 0x7FU, 0xBFU, 0x97U, 0xB8U, 0xC9U, 0x4AU,
0x3AU, 0x37U, 0x31U, 0x1EU, 0x88U, 0x68U, 0x35U, 0x98U,
0x76U, 0x93U, 0xCDU, 0x91U, 0xF7U, 0x6AU, 0x59U, 0xE6U,
0x82U, 0xB6U, 0x85U, 0x67U, 0x3FU, 0xF5U, 0x9EU, 0x82U,
0x2DU, 0xFFU, 0x81U, 0x5EU, 0xEAU, 0x3BU, 0xCCU, 0xFBU,
0x1BU, 0x87U, 0x4AU, 0x93U, 0x40U, 0x96U, 0x3CU, 0xB2U,
0x8EU, 0xCCU, 0x38U, 0x00U, 0x3FU, 0xBAU, 0xCCU, 0x84U,
0x88U, 0x2BU, 0xF0U, 0x11U, 0x09U, 0xD5U, 0xAAU, 0x54U,
0x3AU, 0x5BU, 0x98U, 0xE6U, 0xADU, 0xC0U, 0xB9U, 0x95U,
0x53U, 0xDFU, 0x9DU, 0x91U, 0x01U, 0x66U, 0x7CU, 0xB3U,
0xD8U, 0x2BU, 0x2DU, 0xBCU, 0xE0U, 0x77U, 0x71U, 0x59U,
0x36U, 0xACU, 0x6DU, 0x5EU, 0x55U, 0xC9U, 0x29U, 0x40U,
0xD4U, 0xA2U, 0x5BU, 0xBDU, 0xC2U, 0xE2U, 0x98U, 0x3DU,
0x8CU, 0x9FU, 0x07U, 0xE4U, 0x21U, 0x84U, 0x4CU, 0x12U,
0x83U, 0x77U, 0x88U, 0x06U, 0xA4U, 0x6FU, 0xDFU, 0x9EU,
0xF5U, 0xD3U, 0xE1U, 0xFCU, 0x49U, 0x66U, 0x36U, 0x96U,
0x48U, 0xC7U, 0x32U, 0xBAU, 0x73U, 0xFFU, 0xEFU, 0xCCU,
0x00U, 0xC2U, 0x56U, 0x9CU, 0xD0U, 0x70U, 0x2AU, 0x4FU,
0x82U, 0xB4U, 0x0BU, 0x68U, 0xEAU, 0xC1U, 0x87U, 0xB3U,
)
val xChaCha = XChaCha20Pure(key, nonce, 1U)
val firstChunk = xChaCha.encryptPartialData(message.sliceArray(0 until 50))
val secondChunk = xChaCha.encryptPartialData(message.sliceArray(50 until 200))
val thirdChunk = xChaCha.encryptPartialData(message.sliceArray(200 until message.size))
val result = (firstChunk + secondChunk + thirdChunk)
assertTrue {
result.contentEquals(expected)
}
}
} }