diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt index 7fd0e90..94c730d 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -95,7 +95,8 @@ class FunctionDefinition( class ParameterDefinition( val parameterName: String, val parameterType: GeneralTypeDefinition, - val modifiesReturn: Boolean = false, + val modifiesReturnObjectSize: Boolean = false, + val specificReturnModification : String? = null, val isActuallyAnOutputParam: Boolean = false, val isStateType: Boolean = false, val dropParameterFromDefinition: Boolean = false, diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt index 751faed..9ce1678 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt @@ -33,6 +33,6 @@ fun ClassDefinition.defineGenericHashFunctions() { specificJvmInitializer = "sodium.crypto_generichash_statebytes()" ) +ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES) - +ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true) + +ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturnObjectSize = true) } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index c286144..4801ab0 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -1,7 +1,5 @@ package com.ionspin.kotlin.crypto.generator.libsodium.definitions -import com.squareup.kotlinpoet.ClassName - /** * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Aug/2020 */ @@ -132,7 +130,8 @@ fun ClassDefinition.defineSecretStreamFunctions() { +ParameterDefinition( "m", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, - modifiesReturn = true + modifiesReturnObjectSize = true, + specificReturnModification = "m.size + 17" ) +ParameterDefinition( "ad", @@ -173,7 +172,8 @@ fun ClassDefinition.defineSecretStreamFunctions() { +ParameterDefinition( "c", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, - modifiesReturn = true + modifiesReturnObjectSize = true, + specificReturnModification = "c.size - 17" ) +ParameterDefinition( "ad", @@ -183,4 +183,5 @@ fun ClassDefinition.defineSecretStreamFunctions() { } + } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt index 2aeb944..fea8ca8 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -63,7 +63,7 @@ object JsLibsodiumGenerator { val methodBuilder = FunSpec.builder(methodDefinition.name) var returnModifierFound = false - var returnModifierName = "" + var returnModifierValue = "" var actualReturnType: TypeName = DYNAMIC var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { @@ -74,18 +74,22 @@ object JsLibsodiumGenerator { methodBuilder.addParameter(parameterSpec.build()) } } - if (paramDefinition.modifiesReturn) { + if (paramDefinition.modifiesReturnObjectSize) { if (returnModifierFound == true) { throw RuntimeException("Return modifier already found") } returnModifierFound = true - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierName = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierName = paramDefinition.parameterName + if (paramDefinition.specificReturnModification == null) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierValue = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierValue = paramDefinition.parameterName + } } + } else { + returnModifierValue = paramDefinition.specificReturnModification!! } } if (paramDefinition.isActuallyAnOutputParam) { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index 7e36e8c..0096f83 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -55,7 +55,7 @@ object JvmLibsodiumGenerator { val methodBuilder = FunSpec.builder(methodDefinition.name) methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false - var returnModifierName = "" + var returnModifierValue = "" lateinit var actualReturnParameterDefinition: ParameterDefinition var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { @@ -69,18 +69,23 @@ object JvmLibsodiumGenerator { methodBuilder.addParameter(parameterSpec.build()) } } - if (paramDefinition.modifiesReturn) { + if (paramDefinition.modifiesReturnObjectSize) { if (returnModifierFound == true) { throw RuntimeException("Return modifier already found") } returnModifierFound = true - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierName = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierName = paramDefinition.parameterName + + if (paramDefinition.specificReturnModification == null) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierValue = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierValue = paramDefinition.parameterName + } } + } else { + returnModifierValue = paramDefinition.specificReturnModification!! } } if (paramDefinition.isActuallyAnOutputParam) { @@ -92,7 +97,7 @@ object JvmLibsodiumGenerator { if (returnModifierFound) { createOutputParam( actualReturnParameterDefinition, - returnModifierName, + returnModifierValue, methodBuilder ) } else { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 7f8b552..14b9d0e 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -70,7 +70,7 @@ object NativeLibsodiumGenerator { val methodBuilder = FunSpec.builder(methodDefinition.name) methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false - var returnModifierName = "" + var returnModifierValue = "" lateinit var actualReturnParameterDefinition: ParameterDefinition var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { @@ -84,18 +84,22 @@ object NativeLibsodiumGenerator { methodBuilder.addParameter(parameterSpec.build()) } } - if (paramDefinition.modifiesReturn) { + if (paramDefinition.modifiesReturnObjectSize) { if (returnModifierFound == true) { throw RuntimeException("Return modifier already found") } returnModifierFound = true - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierName = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierName = paramDefinition.parameterName + if (paramDefinition.specificReturnModification == null) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierValue = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierValue = paramDefinition.parameterName + } } + } else { + returnModifierValue = paramDefinition.specificReturnModification!! } } @@ -106,7 +110,7 @@ object NativeLibsodiumGenerator { } if (actualReturnTypeFound) { if (returnModifierFound) { - createOutputParam(actualReturnParameterDefinition, returnModifierName, methodBuilder) + createOutputParam(actualReturnParameterDefinition, returnModifierValue, methodBuilder) } else { if (methodDefinition.outputLengthWhenArray == -1) { throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt index 6b8eb10..b24e406 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt @@ -213,4 +213,4 @@ fun Collection.flattenToUByteArray(): UByteArray { } } return result -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/build.gradle.kts b/multiplatform-crypto-libsodium-bindings/build.gradle.kts index fbd9577..6cbea96 100644 --- a/multiplatform-crypto-libsodium-bindings/build.gradle.kts +++ b/multiplatform-crypto-libsodium-bindings/build.gradle.kts @@ -249,7 +249,6 @@ kotlin { implementation(kotlin(Deps.Common.stdLib)) implementation(kotlin(Deps.Common.test)) implementation(Deps.Common.kotlinBigNum) - api(project(Deps.Common.apiProject)) } } val commonTest by getting { diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt index 905a71c..8eecfd5 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto import com.ionspin.kotlin.bignum.integer.BigInteger -import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.toHexString import debug.test.Crypto diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt new file mode 100644 index 0000000..2b1cbaf --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -0,0 +1,70 @@ +package com.ionspin.kotlin.crypto.secretstream + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import debug.test.Crypto +import kotlin.math.exp +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 15-Aug-2020 + */ +class SecretStreamTest { + @Test + fun testSecretStream() { + 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() + + val additionalData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + 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, 0x57U, + ) + + val expected = ubyteArrayOf( + 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, + 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, + 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, + 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, + 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, + 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, + 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, + 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, + 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, + 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, + 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, + 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, + 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, + 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, + 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, + 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, + 0xcfU, 0x49U + ) + message.hexColumsPrint() + val crypto = Crypto() + val stateAndHeader = crypto.crypto_secretstream_xchacha20poly1305_init_push(key) + val encrypted = crypto.crypto_secretstream_xchacha20poly1305_push(stateAndHeader.state, message, ubyteArrayOf(), 0U) + encrypted.hexColumsPrint() + val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) + val decrypted = crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) + decrypted.hexColumsPrint() + decrypted.contentEquals(message) + + } + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt index 3cb5304..da2e924 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt @@ -34,3 +34,17 @@ fun testBlocking(block : suspend () -> Unit) { } block.startCoroutine(continuation) } + +fun String.encodeToUByteArray() : UByteArray{ + return encodeToByteArray().asUByteArray() +} + +fun UByteArray.toHexString() : String { + return this.joinToString(separator = "") { + if (it <= 0x0FU) { + "0${it.toString(16)}" + } else { + it.toString(16) + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index e058319..b2b3082 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -103,7 +103,7 @@ actual class Crypto internal actual constructor() { ad: UByteArray, tag: UByte ): UByteArray { - val c = UByteArray(m.size) + val c = UByteArray(m.size + 17) println("Debug crypto_secretstream_xchacha20poly1305_push") sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(), m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte()) @@ -118,7 +118,7 @@ actual class Crypto internal actual constructor() { c: UByteArray, ad: UByteArray ): UByteArray { - val m = UByteArray(c.size) + val m = UByteArray(c.size - 17) println("Debug crypto_secretstream_xchacha20poly1305_pull") sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, null, c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 95c3e20..7bb9657 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -142,7 +142,7 @@ actual class Crypto internal actual constructor() { ad: UByteArray, tag: UByte ): UByteArray { - val c = UByteArray(m.size) + val c = UByteArray(m.size + 17) println("Debug crypto_secretstream_xchacha20poly1305_push") val pinnedC = c.pin() val pinnedM = m.pin() @@ -163,7 +163,7 @@ actual class Crypto internal actual constructor() { c: UByteArray, ad: UByteArray ): UByteArray { - val m = UByteArray(c.size) + val m = UByteArray(c.size - 17) println("Debug crypto_secretstream_xchacha20poly1305_pull") val pinnedM = m.pin() val pinnedC = c.pin()