Adopting libsodium secret stream approach for multipart, currently correct state and keystream, but mac is still incorrect on pure implementation

This commit is contained in:
Ugljesa Jovanovic 2020-06-29 21:46:29 +02:00 committed by Ugljesa Jovanovic
parent e6f560ba8e
commit 85e3e2e4ee
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
13 changed files with 220 additions and 37 deletions

View File

@ -55,7 +55,7 @@ object CryptoPrimitives : PrimitivesApi {
}
object Sha512 {
fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha512Multipart {
fun updateable(): Sha512Multipart {
checkInitialization()
return Sha512Delegated()
}

View File

@ -7,6 +7,7 @@ package com.ionspin.kotlin.crypto.authenticated
* on 14-Jun-2020
*/
expect class XChaCha20Poly1305Delegated constructor(key: UByteArray, additionalData: UByteArray) {
internal constructor(key: UByteArray, additionalData: UByteArray, testState : UByteArray, testHeader: UByteArray)
companion object {
fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray
fun decrypt(key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, additionalData: UByteArray) : UByteArray

View File

@ -184,4 +184,32 @@ class XChaCha20Poly1305Test {
}
@Test
fun testStreamingImpl() {
val key = UByteArray(32) { 0U}
val state = ubyteArrayOf(
0x2DU, 0xDBU, 0xC7U, 0xB2U, 0x03U, 0xBCU, 0xC3U, 0x22U, 0xBDU, 0x0CU, 0xBAU, 0x82U, 0xADU, 0x77U, 0x79U, 0x44U,
0xE6U, 0x8FU, 0xA9U, 0x94U, 0x89U, 0xB1U, 0xDFU, 0xBEU, 0x00U, 0x9FU, 0x69U, 0xECU, 0x21U, 0x88U, 0x47U, 0x55U,
0x01U, 0x00U, 0x00U, 0x00U, 0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U,
)
val header = ubyteArrayOf(
0x49U, 0x62U, 0x22U, 0x03U, 0xB7U, 0x46U, 0x11U, 0x97U, 0x8FU, 0x46U, 0x4AU, 0x3BU, 0x2FU, 0x2AU, 0x81U, 0x03U,
0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU,
)
val expected = ubyteArrayOf(
0xAFU, 0xD3U, 0x2DU, 0x59U, 0xB8U, 0xC4U, 0x66U, 0x2EU, 0x47U, 0x29U, 0xC6U, 0xF9U, 0x93U, 0x4BU, 0x09U, 0x27U,
0x24U, 0xDDU, 0xF3U, 0x05U, 0x48U, 0x94U, 0x67U, 0x10U, 0x00U, 0x21U, 0x85U, 0x22U, 0x96U, 0x3CU, 0xCEU, 0x8EU,
0xB7U, 0x53U, 0x9DU, 0x46U, 0xF5U, 0x3CU, 0x5EU, 0x48U, 0x9BU, 0x8CU, 0x13U, 0xB7U, 0x28U, 0x6BU, 0xB3U, 0x6CU,
0x3AU, 0x04U, 0xB7U, 0x25U, 0xB9U, 0x50U, 0x45U, 0x08U, 0x0BU, 0x89U, 0xA2U, 0x0FU, 0x70U, 0xCCU, 0x60U, 0x1BU,
0xC3U, 0x17U, 0x35U, 0x9FU, 0xAEU, 0x82U, 0x51U, 0x43U, 0x1BU, 0x9DU, 0x53U, 0x9EU, 0xE2U, 0xAFU, 0x20U, 0x1FU,
0xFDU, 0x03U, 0x59U, 0x11U, 0x51U, 0x9EU, 0xACU, 0x83U, 0xCDU, 0x78U, 0xD1U, 0xD0U, 0xE5U, 0xD7U, 0x0EU, 0x41U,
0xDEU, 0xFBU, 0x5CU, 0x7FU, 0x1CU, 0x26U, 0x32U, 0x2CU, 0x51U, 0xF6U, 0xEFU, 0xC6U, 0x34U, 0xC4U, 0xACU, 0x6CU,
0xE8U, 0xF9U, 0x4BU, 0xABU, 0xA3U,
)
val xcha = XChaCha20Poly1305Delegated(key, ubyteArrayOf(), state, header)
val data = UByteArray(100) { 0U }
xcha.encryptPartialData(data)
}
}

View File

@ -51,6 +51,10 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
}
}
internal actual constructor(key: UByteArray, additionalData: UByteArray, testState : UByteArray, testHeader: UByteArray) {
}
actual fun encryptPartialData(data: UByteArray): UByteArray {
TODO("not implemented yet")
}

View File

@ -55,6 +55,10 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
}
}
internal actual constructor(key: UByteArray, additionalData: UByteArray, testState : UByteArray, testHeader: UByteArray) {
}
actual fun encryptPartialData(data: UByteArray): UByteArray {
TODO("not implemented yet")
}

View File

@ -1,19 +1,16 @@
package com.ionspin.kotlin.crypto.authenticated
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
import kotlinx.cinterop.toCValues
import libsodium.crypto_aead_xchacha20poly1305_IETF_ABYTES
import libsodium.crypto_aead_xchacha20poly1305_ietf_decrypt
import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt
import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint
import kotlinx.cinterop.*
import libsodium.*
import platform.posix.malloc
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 14-Jun-2020
*/
actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, additionalData: UByteArray) {
actual class XChaCha20Poly1305Delegated actual constructor(val key: UByteArray,val additionalData: UByteArray) {
actual companion object {
actual fun encrypt(
key: UByteArray,
@ -64,8 +61,58 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
}
}
actual internal constructor(key: UByteArray, additionalData: UByteArray, testState : UByteArray, testHeader: UByteArray) : this(key, additionalData) {
val pointer = state.ptr.reinterpret<UByteVar>()
for (i in 0 until crypto_secretstream_xchacha20poly1305_state.size.toInt()) {
pointer[i] = testState[i]
}
println("state after setting-----------")
state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).toUByteArray().hexColumsPrint()
println("state after setting-----------")
println("header after setting-----------")
testHeader.copyInto(header)
header.hexColumsPrint()
println("header after setting-----------")
}
var state =
malloc(crypto_secretstream_xchacha20poly1305_state.size.convert())!!
.reinterpret<crypto_secretstream_xchacha20poly1305_state>()
.pointed
val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U }
init {
val pinnedHeader = header.pin()
crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues())
println("state-----------")
state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).toUByteArray().hexColumsPrint()
println("state-----------")
println("--------header-----------")
header.hexColumsPrint()
println("--------header-----------")
}
actual fun encryptPartialData(data: UByteArray): UByteArray {
TODO("not implemented yet")
val ciphertextWithTag = UByteArray(data.size + crypto_secretstream_xchacha20poly1305_ABYTES.toInt())
val ciphertextWithTagPinned = ciphertextWithTag.pin()
crypto_secretstream_xchacha20poly1305_push(
state.ptr,
ciphertextWithTagPinned.addressOf(0),
null,
data.toCValues(),
data.size.convert(),
null,
0U,
0U,
)
println("Encrypt partial")
ciphertextWithTag.hexColumsPrint()
println("Encrypt partial end")
ciphertextWithTagPinned.unpin()
return ciphertextWithTag
}
actual fun verifyPartialData(data: UByteArray) {

View File

@ -2,9 +2,7 @@ package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.crypto.mac.Poly1305
import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure
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.toLittleEndianUByteArray
/**
@ -38,7 +36,7 @@ internal class ChaCha20Poly1305Pure {
}
}
val oneTimeKey = ChaCha20Pure.hash(state).sliceArray(0 until 32)
val cipherText = ChaCha20Pure.encrypt(key, nonce, message, 1U)
val cipherText = ChaCha20Pure.xorWithKeystream(key, nonce, message, 1U)
val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U }
val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U }
val macData = additionalData + additionalDataPad +
@ -49,4 +47,4 @@ internal class ChaCha20Poly1305Pure {
return cipherText + tag
}
}
}
}

View File

@ -2,11 +2,11 @@ package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.crypto.AuthenticatedEncryption
import com.ionspin.kotlin.crypto.InvalidTagException
import com.ionspin.kotlin.crypto.MultipartAuthenticatedDecryption
import com.ionspin.kotlin.crypto.SRNG
import com.ionspin.kotlin.crypto.mac.Poly1305
import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure
import com.ionspin.kotlin.crypto.symmetric.XChaCha20Pure
import com.ionspin.kotlin.crypto.util.hexColumsPrint
import com.ionspin.kotlin.crypto.util.overwriteWithZeroes
import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray
/**
@ -14,13 +14,13 @@ import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray
* ugljesa.jovanovic@ionspin.com
* on 17-Jun-2020
*/
class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray) {
class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
companion object : AuthenticatedEncryption {
override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray {
val subKey = XChaCha20Pure.hChacha(key, nonce)
val authKey =
ChaCha20Pure.encrypt(
ChaCha20Pure.xorWithKeystream(
subKey.toLittleEndianUByteArray(),
ubyteArrayOf(0U, 0U, 0U, 0U) + nonce.sliceArray(16 until 24),
UByteArray(64) { 0U },
@ -43,7 +43,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
override fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray {
val subKey = XChaCha20Pure.hChacha(key, nonce)
val authKey =
ChaCha20Pure.encrypt(
ChaCha20Pure.xorWithKeystream(
subKey.toLittleEndianUByteArray(),
ubyteArrayOf(0U, 0U, 0U, 0U) + nonce.sliceArray(16 until 24),
UByteArray(64) { 0U },
@ -69,8 +69,6 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
}
internal val nonce = SRNG.getRandomBytes(24)
private val updateableEncryptionPrimitive = XChaCha20Pure(key, nonce, initialCounter = 1U)
private val updateableMacPrimitive : Poly1305
@ -82,7 +80,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
init {
val subKey = XChaCha20Pure.hChacha(key, nonce)
val authKey =
ChaCha20Pure.encrypt(
ChaCha20Pure.xorWithKeystream(
subKey.toLittleEndianUByteArray(),
ubyteArrayOf(0U, 0U, 0U, 0U) + nonce.sliceArray(16 until 24),
UByteArray(64) { 0U },
@ -92,17 +90,88 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
// at org.jetbrains.kotlin.ir.backend.js.lower.ConstTransformer.lowerConst(ConstLowering.kt:38)
)
updateableMacPrimitive = Poly1305(authKey)
val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U }
processPolyBytes(additionalData + additionalDataPad)
// val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U }
// processPolyBytes(additionalData + additionalDataPad)
}
// Sketch libsodium stream cipher with chachapoly, because my two pass approach to multipart encryption is
// inneficient, to put it mildly.
// libsodium-like state
// key, 32 Bytes
// nonce, 12 Bytes
// pad, 8 bytes
//libsodium like header
//random header bytes 24 and put that into out
//then hchacha20 of key and random bytes (out) to generate state key
//the reset counter to 1
//then copy to state->NONCE, HCHACHAINPUTBYTES (16B) from out, length of INONCE_BYTES which is 8, which uses up all random from previous step
//Pad state with 8B of zeroes
//header is a 24byte nonce
internal val calcKey : UByteArray = UByteArray(32)
internal val calcNonce : UByteArray = UByteArray(12)
init {
val calc = XChaCha20Pure.hChacha(key, nonce).toLittleEndianUByteArray()
calc.sliceArray(0 until 32).copyInto(calcKey)
nonce.sliceArray(16 until 24).copyInto(calcNonce, 4)
calcNonce[0] = 1U
calcNonce[1] = 0U
calcNonce[2] = 0U
calcNonce[3] = 0U
println("Calckey-------=")
calcKey.hexColumsPrint()
println("Calckey-------=")
println("Calcnonce---------")
calcNonce.hexColumsPrint()
println("Calcnonce---------")
}
fun encryptPartial(data: UByteArray, additionalData: UByteArray = ubyteArrayOf(), tag : UByte = 0U) : UByteArray {
val result = UByteArray(1 + data.size + 16) //Tag marker, ciphertext, mac
//get encryption state
val block = UByteArray(64) { 0U }
ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 0U).copyInto(block) // This is equivalent to the first 64 bytes of keystream
val poly1305 = Poly1305(block)
block.overwriteWithZeroes()
val additionalDataPadded = additionalData + UByteArray(16 - additionalData.size % 16) { 0U }
poly1305.updateMac(additionalDataPadded)
block[0] = tag
ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block) // This just xors block[0] with keystream
poly1305.updateMac(block) // but updates the mac with the full block!
// In libsodium c code, it now sets the first byte to be a tag, we'll just save it for now
val encryptedTag = block[0]
//And then encrypt the rest of the message
val ciphertext = ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, data, 2U) // With appropriate counter
println("ciphertext-----")
ciphertext.hexColumsPrint()
println("ciphertext-----")
poly1305.updateMac(ciphertext + UByteArray(16 - data.size % 16) { 0U } ) //TODO this is inefficient as it creates a new array and copies data
val finalMac = additionalData.size.toULong().toLittleEndianUByteArray() + ciphertext.size.toULong().toLittleEndianUByteArray()
val mac = poly1305.finalizeMac(finalMac)
return ubyteArrayOf(encryptedTag) + ciphertext + mac
}
// Sketch end
fun encryptPartialData(data: UByteArray) : UByteArray {
processedBytes += data.size
val encrypted = updateableEncryptionPrimitive.xorWithKeystream(data)
processPolyBytes(encrypted)
return encrypted
val cipherTextPad = UByteArray(16 - processedBytes % 16) { 0U }
val macData = cipherTextPad +
// additionalData.size.toULong().toLittleEndianUByteArray() +
processedBytes.toULong().toLittleEndianUByteArray()
processPolyBytes(macData)
val tag = updateableMacPrimitive.finalizeMac()
return encrypted + tag
}
fun verifyPartialData(data: UByteArray) {
@ -112,7 +181,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
fun checkTag(expectedTag: UByteArray) {
val cipherTextPad = UByteArray(16 - processedBytes % 16) { 0U }
val macData = cipherTextPad +
additionalData.size.toULong().toLittleEndianUByteArray() +
// additionalData.size.toULong().toLittleEndianUByteArray() +
processedBytes.toULong().toLittleEndianUByteArray()
processPolyBytes(macData)
val tag = updateableMacPrimitive.finalizeMac()
@ -173,7 +242,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
val cipherTextPad = UByteArray(16 - processedBytes % 16) { 0U }
val macData = cipherTextPad +
additionalData.size.toULong().toLittleEndianUByteArray() +
// additionalData.size.toULong().toLittleEndianUByteArray() +
processedBytes.toULong().toLittleEndianUByteArray()
processPolyBytes(macData)
val tag = updateableMacPrimitive.finalizeMac()

View File

@ -80,7 +80,6 @@ class Poly1305(key: UByteArray) {
var accumulator = BigInteger.ZERO
fun updateMac(data : UByteArray) {
data.hexColumsPrint()
val blockAsInt = BigInteger.fromUByteArray(data, Endianness.LITTLE) + powersOfTwo[128]
accumulator += blockAsInt
accumulator *= rAsBigInt
@ -89,7 +88,6 @@ class Poly1305(key: UByteArray) {
fun finalizeMac(data: UByteArray = ubyteArrayOf()) : UByteArray{
if (data.size != 0) {
data.hexColumsPrint()
val blockAsInt = BigInteger.fromUByteArray(data, Endianness.LITTLE) + powersOfTwo[data.size * 8]
accumulator += blockAsInt
accumulator *= rAsBigInt

View File

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

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.hexColumsPrint
import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertTrue
@ -173,4 +174,39 @@ class XChaCha20Poly1305Test {
}
@Test
fun multipartXChaCha20Poly1305() {
val key = UByteArray(32) { 0U}
val state = ubyteArrayOf(
0x2DU, 0xDBU, 0xC7U, 0xB2U, 0x03U, 0xBCU, 0xC3U, 0x22U, 0xBDU, 0x0CU, 0xBAU, 0x82U, 0xADU, 0x77U, 0x79U, 0x44U,
0xE6U, 0x8FU, 0xA9U, 0x94U, 0x89U, 0xB1U, 0xDFU, 0xBEU, 0x00U, 0x9FU, 0x69U, 0xECU, 0x21U, 0x88U, 0x47U, 0x55U,
0x01U, 0x00U, 0x00U, 0x00U, 0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U,
)
val header = ubyteArrayOf(
0x49U, 0x62U, 0x22U, 0x03U, 0xB7U, 0x46U, 0x11U, 0x97U, 0x8FU, 0x46U, 0x4AU, 0x3BU, 0x2FU, 0x2AU, 0x81U, 0x03U,
0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU,
)
val expected = ubyteArrayOf(
0xAFU, 0xD3U, 0x2DU, 0x59U, 0xB8U, 0xC4U, 0x66U, 0x2EU, 0x47U, 0x29U, 0xC6U, 0xF9U, 0x93U, 0x4BU, 0x09U, 0x27U,
0x24U, 0xDDU, 0xF3U, 0x05U, 0x48U, 0x94U, 0x67U, 0x10U, 0x00U, 0x21U, 0x85U, 0x22U, 0x96U, 0x3CU, 0xCEU, 0x8EU,
0xB7U, 0x53U, 0x9DU, 0x46U, 0xF5U, 0x3CU, 0x5EU, 0x48U, 0x9BU, 0x8CU, 0x13U, 0xB7U, 0x28U, 0x6BU, 0xB3U, 0x6CU,
0x3AU, 0x04U, 0xB7U, 0x25U, 0xB9U, 0x50U, 0x45U, 0x08U, 0x0BU, 0x89U, 0xA2U, 0x0FU, 0x70U, 0xCCU, 0x60U, 0x1BU,
0xC3U, 0x17U, 0x35U, 0x9FU, 0xAEU, 0x82U, 0x51U, 0x43U, 0x1BU, 0x9DU, 0x53U, 0x9EU, 0xE2U, 0xAFU, 0x20U, 0x1FU,
0xFDU, 0x03U, 0x59U, 0x11U, 0x51U, 0x9EU, 0xACU, 0x83U, 0xCDU, 0x78U, 0xD1U, 0xD0U, 0xE5U, 0xD7U, 0x0EU, 0x41U,
0xDEU, 0xFBU, 0x5CU, 0x7FU, 0x1CU, 0x26U, 0x32U, 0x2CU, 0x51U, 0xF6U, 0xEFU, 0xC6U, 0x34U, 0xC4U, 0xACU, 0x6CU,
0xE8U, 0xF9U, 0x4BU, 0xABU, 0xA3U,
)
val xcha = XChaCha20Poly1305Pure(key, header)
//Verify the state is correctly created
assertTrue {
xcha.calcKey.contentEquals(state.sliceArray(0 until 32))
xcha.calcNonce.contentEquals(state.sliceArray(32 until 44))
}
val data = UByteArray(100) { 0U }
xcha.encryptPartial(data).hexColumsPrint()
}
}

View File

@ -75,7 +75,7 @@ class Poly1305Test {
0x59U, 0xf0U, 0x88U, 0x71U, 0x29U, 0xccU, 0x2eU, 0xe7U,
)
val message = ubyteArrayOf(
)
val expected = ubyteArrayOf(
0xddU, 0x3fU, 0xabU, 0x22U, 0x51U, 0xf1U, 0x1aU, 0xc7U,
@ -221,4 +221,4 @@ class Poly1305Test {
expected.contentEquals(result)
}
}
}
}

View File

@ -1,8 +1,6 @@
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.toHexString
import kotlin.test.Test
import kotlin.test.assertTrue
@ -80,7 +78,7 @@ class ChaCha20Test {
0x5aU, 0xf9U, 0x0bU, 0xbfU, 0x74U, 0xa3U, 0x5bU, 0xe6U, 0xb4U, 0x0bU, 0x8eU, 0xedU, 0xf2U, 0x78U, 0x5eU, 0x42U,
0x87U, 0x4dU,
)
val result = ChaCha20Pure.encrypt(key, nonce, message, 1U)
val result = ChaCha20Pure.xorWithKeystream(key, nonce, message, 1U)
assertTrue {
expected.contentEquals(result)
}
@ -89,4 +87,4 @@ class ChaCha20Test {
}
}
}