Working single shot xchacha20poly1305 encryption and decryption in delegated flavour

This commit is contained in:
Ugljesa Jovanovic 2020-06-27 18:20:53 +02:00 committed by Ugljesa Jovanovic
parent 6228263978
commit e6f560ba8e
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
13 changed files with 66 additions and 48 deletions

View File

@ -5,6 +5,8 @@ package com.ionspin.kotlin.crypto.util
* ugljesa.jovanovic@ionspin.com
* on 22-Jun-2020
*/
val _emit = IntArray(0)
fun UByteArray.overwriteWithZeroes() {
for (i in 0 until size) {
this[i] = 0U
@ -15,4 +17,4 @@ fun UIntArray.overwriteWithZeroes() {
for (i in 0 until size) {
this[i] = 0U
}
}
}

View File

@ -15,19 +15,16 @@ import com.ionspin.kotlin.crypto.keyderivation.ArgonResult
*/
object CryptoInitializerDelegated : CryptoInitializer {
private var initialized = false
override suspend fun initialize() {
Initializer.initialize()
initialized = true
}
fun initializeWithCallback(done: () -> Unit) {
initialized = true
Initializer.initializeWithCallback(done)
}
override fun isInitialized(): Boolean {
return initialized
return Initializer.isInitialized()
}
}

View File

@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.crypto.CryptoInitializerDelegated
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.hexColumsPrint
import com.ionspin.kotlin.crypto.util.testBlocking
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@ -18,10 +19,9 @@ class XChaCha20Poly1305Test {
@Test
fun xChaCha20Poly1305() {
testBlocking {
CryptoInitializerDelegated.initialize()
}
fun xChaCha20Poly1305() = testBlocking {
CryptoInitializerDelegated.initialize()
assertTrue {
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()
@ -62,9 +62,12 @@ class XChaCha20Poly1305Test {
0xcfU, 0x49U
)
val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, additionalData)
// val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData)
encrypted.contentEquals(expected) // && decrypted.contentEquals(message)
encrypted.hexColumsPrint()
val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData)
println("Decrypted")
decrypted.hexColumsPrint()
println("----------")
encrypted.contentEquals(expected) && decrypted.contentEquals(message)
}
assertTrue {
@ -91,9 +94,9 @@ class XChaCha20Poly1305Test {
0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU
)
val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, additionalData)
// val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData)
val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData)
encrypted.contentEquals(expected) // && decrypted.contentEquals(message)
encrypted.contentEquals(expected) && decrypted.contentEquals(message)
}

View File

@ -40,7 +40,8 @@ interface JsSodiumInterface {
fun crypto_hash_sha512_final(state: dynamic): Uint8Array
//XChaCha20Poly1305
fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, additionalData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, additionalData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, additionalData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
}

View File

@ -8,10 +8,12 @@ import org.khronos.webgl.set
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 25-Jun-2020
*
* TODO investigate using unsafe cast
*/
fun UByteArray.toUInt8Array() : Uint8Array {
val uint8Result = Uint8Array(toByteArray().toTypedArray())
console.log("Uint8: $uint8Result")
// console.log("Uint8: $uint8Result")
return uint8Result
}
@ -21,7 +23,7 @@ fun Uint8Array.toUByteArray() : UByteArray {
for (i in 0 until length) {
result[i] = get(i).toUByte()
}
console.log("UbyteArray: ${result.joinToString()}")
// console.log("UbyteArray: ${result.joinToString()}")
return result
}

View File

@ -3,6 +3,7 @@ package com.ionspin.kotlin.crypto.authenticated
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
/**
* Created by Ugljesa Jovanovic
@ -26,8 +27,9 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
val encrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt(
message.toUInt8Array(),
additionalData.toUInt8Array(),
key.toUInt8Array(),
nonce.toUInt8Array()
Uint8Array(0),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return encrypted.toUByteArray()
}
@ -38,7 +40,14 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
ciphertext: UByteArray,
additionalData: UByteArray
): UByteArray {
TODO("not implemented yet")
val decrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt(
Uint8Array(0),
ciphertext.toUInt8Array(),
additionalData.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return decrypted.toUByteArray()
}
}

View File

@ -38,16 +38,15 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
ciphertext: UByteArray,
additionalData: UByteArray
): UByteArray {
val message = ByteArray(ciphertext.size - sodium.crypto_secretstream_xchacha20poly1305_abytes())
SodiumJava().crypto_aead_xchacha20poly1305_ietf_encrypt(
val message = ByteArray(ciphertext.size - 16)
SodiumJava().crypto_aead_xchacha20poly1305_ietf_decrypt(
message,
longArrayOf(ciphertext.size.toLong()),
null,
ciphertext.toByteArray(),
ciphertext.size.toLong(),
additionalData.toByteArray(),
additionalData.size.toLong(),
null,
nonce.toByteArray(),
key.toByteArray()

View File

@ -1,9 +1,7 @@
@file:Suppress("VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL")
package com.ionspin.kotlin.crypto
import kotlinx.atomicfu.AtomicBoolean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import libsodium.sodium_init
import kotlin.native.concurrent.AtomicInt
@ -29,4 +27,4 @@ actual object Initializer {
actual fun isInitialized(): Boolean {
return isPlatformInitialized.value != 0
}
}
}

View File

@ -5,6 +5,7 @@ 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
/**
@ -25,7 +26,7 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
val ciphertextPinned = ciphertext.pin()
crypto_aead_xchacha20poly1305_ietf_encrypt(
ciphertextPinned.addressOf(0),
ciphertextLength.convert(),
ulongArrayOf(ciphertextLength.convert()).toCValues(),
message.toCValues(),
message.size.convert(),
additionalData.toCValues(),
@ -44,7 +45,22 @@ actual class XChaCha20Poly1305Delegated actual constructor(key: UByteArray, addi
ciphertext: UByteArray,
additionalData: UByteArray
): UByteArray {
TODO("not implemented yet")
val messageLength = ciphertext.size - crypto_aead_xchacha20poly1305_IETF_ABYTES.toInt()
val message = UByteArray(messageLength)
val messagePinned = message.pin()
crypto_aead_xchacha20poly1305_ietf_decrypt(
messagePinned.addressOf(0),
ulongArrayOf(messageLength.convert()).toCValues(),
null,
ciphertext.toCValues(),
ciphertext.size.convert(),
additionalData.toCValues(),
additionalData.size.convert(),
nonce.toCValues(),
key.toCValues()
)
messagePinned.unpin()
return message
}
}

View File

@ -173,7 +173,6 @@ class XChaCha20Pure(key: UByteArray, nonce: UByteArray, initialCounter: UInt = 0
)
keystreamRemainingCounter = 64 - remainingBytes
processedBytesSoFar += data.size
state.overwriteWithZeroes()
return ciphertext
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.symmetric
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.hexColumsPrint
import kotlin.test.Test
import kotlin.test.assertTrue
@ -239,9 +240,9 @@ class XChaCha20Test {
val firstChunk = xChaCha.xorWithKeystream(message.sliceArray(0 until 5))
val secondChunk = xChaCha.xorWithKeystream(message.sliceArray(5 until 90))
val thirdChunk = xChaCha.xorWithKeystream(message.sliceArray(90 until message.size))
val result = firstChunk + secondChunk + thirdChunk
assertTrue {
(firstChunk + secondChunk + thirdChunk).contentEquals(expected)
(result).contentEquals(expected)
}
}

View File

@ -1,13 +1,15 @@
package com.ionspin.kotlin.crypto.sample
import com.ionspin.kotlin.crypto.Crypto
import com.ionspin.kotlin.crypto.CryptoInitializerDelegated
import com.ionspin.kotlin.crypto.CryptoPrimitives
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.toHexString
object Sample {
fun runSample() {
println("Initializing crypto library")
Crypto.initializeWithCallback {
CryptoInitializerDelegated.initializeWithCallback {
blake2b()
}
@ -16,11 +18,11 @@ object Sample {
fun blake2b() {
println("Blake2b updateable")
val blake2bUpdateable = Crypto.Blake2b.updateable()
val blake2bUpdateable = CryptoPrimitives.Blake2b.updateable()
blake2bUpdateable.update("test".encodeToUByteArray())
println(blake2bUpdateable.digest().toHexString())
println("Blake2b stateless")
val statelessResult = Crypto.Blake2b.stateless("test".encodeToByteArray().toUByteArray())
val statelessResult = CryptoPrimitives.Blake2b.stateless("test".encodeToByteArray().toUByteArray())
println("Blake2b stateless: ${statelessResult.toHexString()}")
}
}

View File

@ -1,16 +1,5 @@
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bStateless
import com.ionspin.kotlin.crypto.sample.Sample
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import platform.posix.pthread_self
import platform.posix.sleep
import kotlin.native.concurrent.TransferMode
import kotlin.native.concurrent.Worker
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
@ExperimentalTime