Working single shot xchacha20poly1305 encryption and decryption in delegated flavour
This commit is contained in:
parent
6228263978
commit
e6f560ba8e
@ -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,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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,6 @@ class XChaCha20Pure(key: UByteArray, nonce: UByteArray, initialCounter: UInt = 0
|
||||
)
|
||||
keystreamRemainingCounter = 64 - remainingBytes
|
||||
processedBytesSoFar += data.size
|
||||
state.overwriteWithZeroes()
|
||||
return ciphertext
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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()}")
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user