Add delegated xchacha20poly1305 decrypt

This commit is contained in:
Ugljesa Jovanovic 2020-07-07 23:11:12 +02:00 committed by Ugljesa Jovanovic
parent 5d3c14de2f
commit 579c44fcc7
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
5 changed files with 62 additions and 11 deletions

View File

@ -7,6 +7,7 @@ import com.ionspin.kotlin.crypto.util.hexColumsPrint
import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.testBlocking
import kotlin.test.Ignore import kotlin.test.Ignore
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertFails
import kotlin.test.assertTrue import kotlin.test.assertTrue
/** /**
@ -189,7 +190,7 @@ class XChaCha20Poly1305Test {
@Test @Test
fun testStreamingImpl() = testBlocking { fun testStreamingImpl() = testBlocking {
Initializer.initialize() Initializer.initialize()
val key = UByteArray(32) { 0U} val key = UByteArray(32) { 0U }
val state = ubyteArrayOf( val state = ubyteArrayOf(
0x2DU, 0xDBU, 0xC7U, 0xB2U, 0x03U, 0xBCU, 0xC3U, 0x22U, 0xBDU, 0x0CU, 0xBAU, 0x82U, 0xADU, 0x77U, 0x79U, 0x44U, 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, 0xE6U, 0x8FU, 0xA9U, 0x94U, 0x89U, 0xB1U, 0xDFU, 0xBEU, 0x00U, 0x9FU, 0x69U, 0xECU, 0x21U, 0x88U, 0x47U, 0x55U,
@ -210,12 +211,28 @@ class XChaCha20Poly1305Test {
0xDEU, 0xFBU, 0x5CU, 0x7FU, 0x1CU, 0x26U, 0x32U, 0x2CU, 0x51U, 0xF6U, 0xEFU, 0xC6U, 0x34U, 0xC4U, 0xACU, 0x6CU, 0xDEU, 0xFBU, 0x5CU, 0x7FU, 0x1CU, 0x26U, 0x32U, 0x2CU, 0x51U, 0xF6U, 0xEFU, 0xC6U, 0x34U, 0xC4U, 0xACU, 0x6CU,
0xE8U, 0xF9U, 0x4BU, 0xABU, 0xA3U, 0xE8U, 0xF9U, 0x4BU, 0xABU, 0xA3U,
) )
val xcha = XChaCha20Poly1305Delegated(key, state, header) val encryptor = XChaCha20Poly1305Delegated(key, state, header)
val decryptor = XChaCha20Poly1305Delegated(key, state, header)
val data = UByteArray(100) { 0U } val data = UByteArray(100) { 0U }
val result = xcha.encrypt(data) val result = encryptor.encrypt(data)
val decrypted = decryptor.decrypt(result)
println("Encrypted -----------")
result.hexColumsPrint()
println("Encrypted end -----------")
println("Decrypted -----------")
decrypted.hexColumsPrint()
println("Decrypted end -----------")
assertTrue { assertTrue {
expected.contentEquals(result) expected.contentEquals(result) && decrypted.contentEquals(data)
}
val messedUpTag = result.copyOf()
messedUpTag[messedUpTag.size - 2] = 0U
assertFails {
val decryptorForWrongTag = XChaCha20Poly1305Delegated(key, state, header)
val plaintext = decryptorForWrongTag.decrypt(messedUpTag)
println("Decrypted with wrong tag -----------")
plaintext.hexColumsPrint()
println("Decrypted with wrong tag end -----------")
} }
} }
} }

View File

@ -50,6 +50,7 @@ interface JsSodiumInterface {
//decrypt //decrypt
fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic
fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic
} }

View File

@ -1,6 +1,8 @@
package com.ionspin.kotlin.crypto.authenticated package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.crypto.InvalidTagException
import com.ionspin.kotlin.crypto.getSodium import com.ionspin.kotlin.crypto.getSodium
import com.ionspin.kotlin.crypto.util.hexColumsPrint
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array import org.khronos.webgl.Uint8Array
@ -84,7 +86,15 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() {
} }
actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray {
TODO("not implemented yet") val decryptedWithTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(state, data.toUInt8Array(), additionalData.toUInt8Array())
val decrypted = decryptedWithTag.message as Uint8Array
val validTag = decryptedWithTag.tag as UInt
if (validTag != 0U) {
println("Tag validation failed")
throw InvalidTagException()
}
return decrypted.toUByteArray()
} }

View File

@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.authenticated
import com.goterl.lazycode.lazysodium.SodiumJava import com.goterl.lazycode.lazysodium.SodiumJava
import com.goterl.lazycode.lazysodium.interfaces.SecretStream import com.goterl.lazycode.lazysodium.interfaces.SecretStream
import com.ionspin.kotlin.crypto.InvalidTagException
import com.ionspin.kotlin.crypto.util.hexColumsPrint import com.ionspin.kotlin.crypto.util.hexColumsPrint
/** /**
@ -89,14 +90,18 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() {
actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray {
val plaintext = ByteArray(data.size - 17) val plaintext = ByteArray(data.size - 17)
sodium.crypto_secretstream_xchacha20poly1305_pull( val validTag = sodium.crypto_secretstream_xchacha20poly1305_pull(
state, plaintext, null, state, plaintext, null,
data.sliceArray(0 until 1).asByteArray(), null,
data.sliceArray(1 until data.size).asByteArray(), data.asByteArray(),
(data.size - 17).toLong(), (data.size).toLong(),
additionalData.asByteArray(), additionalData.asByteArray(),
additionalData.size.toLong() additionalData.size.toLong()
) )
if (validTag != 0) {
println("Tag validation failed")
throw InvalidTagException()
}
return plaintext.asUByteArray() return plaintext.asUByteArray()
} }

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.authenticated package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint
import com.ionspin.kotlin.crypto.InvalidTagException
import kotlinx.cinterop.* import kotlinx.cinterop.*
import libsodium.* import libsodium.*
import platform.posix.malloc import platform.posix.malloc
@ -127,7 +128,24 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() {
} }
actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray {
TODO("not implemented yet") val plaintext = UByteArray(data.size - crypto_secretstream_xchacha20poly1305_ABYTES.toInt())
val plaintextPinned = plaintext.pin()
val validTag = crypto_secretstream_xchacha20poly1305_pull(
state.ptr,
plaintextPinned.addressOf(0),
null,
null,
data.toCValues(),
data.size.convert(),
additionalData.toCValues(),
additionalData.size.convert()
)
plaintextPinned.unpin()
if (validTag != 0) {
println("Tag validation failed")
throw InvalidTagException()
}
return plaintext
} }