From a5b20daf5a87f705709e30eb695da0683525797e Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 14 Aug 2020 12:39:27 +0200 Subject: [PATCH] Adding data classes --- .../commonMain/kotlin/debug/test/DebugTest.kt | 30 ------ .../src/jsMain/kotlin/debug/test/DebugTest.kt | 57 ----------- .../jvmMain/kotlin/debug/test/DebugTest.kt | 66 ------------- .../nativeMain/kotlin/debug/test/DebugTest.kt | 92 ------------------ .../libsodium/definitions/DefinitionTypes.kt | 63 +++++++++++-- .../definitions/LibsodiumDefinitions.kt | 1 + .../LibsodiumSecretStreamDefinitions.kt | 26 ++++- .../libsodium/generator/Coordinator.kt | 4 +- .../generator/JsLibsodiumGenerator.kt | 41 ++++---- .../generator/JvmLibsodiumGenerator.kt | 78 +++++++-------- .../generator/NativeLibsodiumGenerator.kt | 94 +++++++++---------- .../libsodium/generator/SharedCreators.kt | 27 +++++- .../kotlin/crypto/generator/DebugTest.kt | 8 +- .../commonMain/kotlin/debug/test/DebugTest.kt | 13 +++ .../src/jsMain/kotlin/debug/test/DebugTest.kt | 11 +++ .../jvmMain/kotlin/debug/test/DebugTest.kt | 13 +++ .../nativeMain/kotlin/debug/test/DebugTest.kt | 14 +++ 17 files changed, 263 insertions(+), 375 deletions(-) delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index c3ee8f9..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -package debug.test - -import kotlin.Int -import kotlin.UByteArray - -expect class Sha256State - -expect class Sha512State - -expect class GenericHashState - -expect class Crypto internal constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - fun crypto_hash_sha256_init(): Sha256State - - fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) - - fun crypto_hash_sha256_final(state: Sha256State): UByteArray - - fun crypto_hash_sha512_init(): Sha512State - - fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) - - fun crypto_hash_sha512_final(state: Sha512State): UByteArray - - fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index f9a210c..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,57 +0,0 @@ -package debug.test - -import com.ionspin.kotlin.crypto.getSodium -import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray -import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array -import kotlin.Any -import kotlin.Int -import kotlin.UByteArray - -actual typealias Sha256State = Any - -actual typealias Sha512State = Any - -actual typealias GenericHashState = Any - -actual class Crypto internal actual constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): dynamic { - println("Debug crypto_hash_sha256_init") - val result = js("getSodium().crypto_hash_sha256_init()") - return result - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - println("Debug crypto_hash_sha256_final") - return getSodium().crypto_hash_sha256_final(state).toUByteArray() - } - - actual fun crypto_hash_sha512_init(): dynamic { - println("Debug crypto_hash_sha512_init") - val result = js("getSodium().crypto_hash_sha512_init()") - return result - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - println("Debug crypto_hash_sha512_final") - return getSodium().crypto_hash_sha512_final(state).toUByteArray() - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { - println("Debug crypto_generichash_init") - return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) - } -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index c6fec61..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -package debug.test - -import com.goterl.lazycode.lazysodium.SodiumJava -import com.goterl.lazycode.lazysodium.interfaces.Hash -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray - -val sodium: SodiumJava = SodiumJava() - -actual typealias Sha256State = Hash.State256 - -actual typealias Sha512State = Hash.State512 - -actual typealias GenericHashState = ByteArray - -actual class Crypto internal actual constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): Sha256State { - val state = debug.test.Sha256State() - println("Debug crypto_hash_sha256_init") - sodium.crypto_hash_sha256_init(state) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - sodium.crypto_hash_sha256_final(state, out.asByteArray()) - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val state = debug.test.Sha512State() - println("Debug crypto_hash_sha512_init") - sodium.crypto_hash_sha512_init(state) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - sodium.crypto_hash_sha512_final(state, out.asByteArray()) - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) - println("Debug crypto_generichash_init") - sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) - return state - } -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index b987ebb..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,92 +0,0 @@ -package debug.test - -import kotlin.Byte -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray -import kotlinx.cinterop.addressOf -import kotlinx.cinterop.convert -import kotlinx.cinterop.pin -import kotlinx.cinterop.pointed -import kotlinx.cinterop.ptr -import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.toCValues -import libsodium.crypto_generichash_blake2b_state -import libsodium.crypto_hash_sha256_state -import libsodium.crypto_hash_sha512_state -import libsodium.sodium_malloc - -actual typealias Sha256State = crypto_hash_sha256_state - -actual typealias Sha512State = crypto_hash_sha512_state - -actual typealias GenericHashState = crypto_generichash_blake2b_state - -actual class Crypto internal actual constructor() { - val _emitByte: Byte = 0 - - val _emitByteArray: ByteArray = ByteArray(0) - - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): Sha256State { - val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha256_init") - libsodium.crypto_hash_sha256_init(state.ptr) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha512_init") - libsodium.crypto_hash_sha512_init(state.ptr) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_generichash_init") - val pinnedKey = key.pin() - libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), - outlen.convert()) - pinnedKey.unpin() - return state - } -} 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 f2f2832..fe7b003 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 @@ -27,7 +27,8 @@ class ClassDefinition( val name: String, val codeDocumentation: String = "", val innerClasses: MutableList = mutableListOf(), - val methods: MutableList = mutableListOf() + val methods: MutableList = mutableListOf(), + val dataClasses: MutableList = mutableListOf() ) { operator fun InnerClassDefinition.unaryPlus() { innerClasses.add(this) @@ -37,6 +38,10 @@ class ClassDefinition( methods.add(this) } + operator fun DataClassDefinition.unaryPlus() { + dataClasses.add(this) + } + operator fun List.unaryPlus() { methods.addAll(this) } @@ -51,6 +56,17 @@ class InnerClassDefinition( val functions: MutableList = mutableListOf() ) +class DataClassDefinition( + val name: String, + val codeDocumentation: String = "", + val parameters : List +) + +/** + * outputLengthWhenArray - if output is an a array and there is no parameter that modifies output length we need + * to tell the function what to expect (think SHA256 32byte output always, and Blake2 dynamic output controlled + * by outputLen parameter) + */ class FunctionDefinition( val name: String, val javaName: String, @@ -61,7 +77,8 @@ class FunctionDefinition( val returnType: GeneralTypeDefinition, val dynamicJsReturn: Boolean = false, val isStateCreationFunction: Boolean = false, - val outputLengthWhenArray: Int = -1 + val outputLengthWhenArray: Int = -1, + val customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null ) { operator fun ParameterDefinition.unaryPlus() { parameterList.add(this) @@ -79,7 +96,13 @@ class ParameterDefinition( ) class CodeBlockDefinition( - codeBlock: String + val codeBlock: String, + val applyOnTargets: Set = setOf( + TargetPlatform.COMMON, + TargetPlatform.JVM, + TargetPlatform.JS, + TargetPlatform.NATIVE + ) ) interface GeneralTypeDefinition { @@ -98,6 +121,10 @@ enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefiniti UNIT(Unit::class.asTypeName()) } +enum class TargetPlatform { + JVM, NATIVE, JS, COMMON +} + fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefinition { val commonKotlinFileInstance = KotlinFileDefinition(name) commonKotlinFileInstance.body() @@ -105,14 +132,26 @@ fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefi } -fun classDef(name: String, codeDocumentation: String = "",body: ClassDefinition.() -> Unit): ClassDefinition { +fun classDef(name: String, codeDocumentation: String = "", body: ClassDefinition.() -> Unit): ClassDefinition { val commonClass = ClassDefinition(name, codeDocumentation) commonClass.body() return commonClass } -fun codeBlock(codeBlock: String) : CodeBlockDefinition { - val codeBlockDefinition = CodeBlockDefinition(codeBlock) +fun dataClassDef(name : String, codeDocumentation: String = "", parameters: List) : DataClassDefinition { + return DataClassDefinition(name, codeDocumentation, parameters) +} + +fun codeBlock( + codeBlock: String, + applyOnTargets: Set = setOf( + TargetPlatform.COMMON, + TargetPlatform.JVM, + TargetPlatform.JS, + TargetPlatform.NATIVE + ) +): CodeBlockDefinition { + val codeBlockDefinition = CodeBlockDefinition(codeBlock, applyOnTargets) return codeBlockDefinition } @@ -123,7 +162,7 @@ fun innerClassDef( jsName: String, nativeName: String, codeDocumentation: String = "", - specificConstructor : String? = null, + specificConstructor: String? = null, body: InnerClassDefinition.() -> Unit = {} ): InnerClassDefinition { val genClass = InnerClassDefinition( @@ -147,6 +186,7 @@ fun funcDef( dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, outputLengthWhenArray: Int = -1, + customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, body: FunctionDefinition.() -> Unit ): FunctionDefinition { val function = FunctionDefinition( @@ -154,11 +194,12 @@ fun funcDef( javaName, jsName, nativeName, - codeDocumentation, + codeDocumentation = codeDocumentation, returnType = returnType, dynamicJsReturn = dynamicJsReturn, isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray + outputLengthWhenArray = outputLengthWhenArray, + customCodeBlockReplacesFunctionBody = customCodeBlockReplacesFunctionBody ) function.body() return function @@ -171,6 +212,7 @@ fun funcDef( dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, outputLengthWhenArray: Int = -1, + customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, body: FunctionDefinition.() -> Unit ): FunctionDefinition { val function = @@ -183,7 +225,8 @@ fun funcDef( returnType = returnType, dynamicJsReturn = dynamicJsReturn, isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray + outputLengthWhenArray = outputLengthWhenArray, + customCodeBlockReplacesFunctionBody = customCodeBlockReplacesFunctionBody ) function.body() return function diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt index 61cacf0..54d4fc0 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt @@ -10,6 +10,7 @@ object LibSodiumDefinitions { +classDef("Crypto") { defineHashFunctions() defineGenericHashFunctions() + defineSecretStreamFunctions() } } } 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 a632968..e4c8935 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 @@ -12,17 +12,33 @@ fun ClassDefinition.defineSecretStreamFunctions() { "SecretStreamState", "crypto_hash_sha256_state" ) + +dataClassDef( + "SecretStreamStateAndHeader", + """ + This data class wraps the state and header objects returned when initializing secret stream encryption + """.trimIndent(), + listOf( + ParameterDefinition( + parameterName = "state", + parameterType = CustomTypeDefinition(withPackageName("SecretStreamState")) + ), + ParameterDefinition( + parameterName = "header", + parameterType = TypeDefinition.ARRAY_OF_UBYTES + ) + + ) + + ) +funcDef( "crypto_secretstream_xchacha20poly1305_init_push", - returnType = TypeDefinition.ARRAY_OF_UBYTES, + returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, dynamicJsReturn = true, isStateCreationFunction = true ) { +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("SecretStreamState"))), - dropParameterFromDefinition = true, - isActuallyAnOutputParam = true + "key", + parameterType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE ) } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt index c347f7c..946b03f 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt @@ -10,8 +10,8 @@ import java.io.File * on 31-Jul-2020 */ object Coordinator { - - fun run() { + @JvmStatic + fun main(args : Array) { val commonFileSpec = CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile) val jvmFileSpec = JvmLibsodiumGenerator.createJvmFile(packageName, LibSodiumDefinitions.testKotlinFile) 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 2255cb8..c2985b7 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 @@ -97,26 +97,31 @@ object JsLibsodiumGenerator { methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") val constructJsCall = StringBuilder() - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()") - } - TypeDefinition.INT -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - TypeDefinition.UNIT -> { - constructJsCall.append("getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - is CustomTypeDefinition -> { - if (methodDefinition.parameterList.filter { it.isStateType.not() }.size > 0) { + if (methodDefinition.customCodeBlockReplacesFunctionBody != null && + methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { + constructJsCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) + } else { + when (methodDefinition.returnType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + constructJsCall.append("return getSodium().${methodDefinition.jsName}") + constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()") + } + TypeDefinition.INT -> { constructJsCall.append("return getSodium().${methodDefinition.jsName}") constructJsCall.append(paramsToString(methodDefinition)) - } else { - constructJsCall.append("val result = js(\"getSodium().${methodDefinition.jsName}()\")") - constructJsCall.append("\nreturn result") + } + TypeDefinition.UNIT -> { + constructJsCall.append("getSodium().${methodDefinition.jsName}") + constructJsCall.append(paramsToString(methodDefinition)) + } + is CustomTypeDefinition -> { + if (methodDefinition.parameterList.filter { it.isStateType.not() }.size > 0) { + constructJsCall.append("return getSodium().${methodDefinition.jsName}") + constructJsCall.append(paramsToString(methodDefinition)) + } else { + constructJsCall.append("val result = js(\"getSodium().${methodDefinition.jsName}()\")") + constructJsCall.append("\nreturn result") + } } } } 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 7283207..bad4c91 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 @@ -1,11 +1,6 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition +import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec @@ -103,40 +98,45 @@ object JvmLibsodiumGenerator { } methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") val constructJvmCall = StringBuilder() - if (methodDefinition.isStateCreationFunction) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return out") + if (methodDefinition.customCodeBlockReplacesFunctionBody != null && + methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JVM)) { + constructJvmCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - } - is CustomTypeDefinition -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") + if (methodDefinition.isStateCreationFunction) { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return state") + } else if (actualReturnTypeFound) { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return out") + } else { + when (methodDefinition.returnType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return result") + } + TypeDefinition.INT -> { + constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return result") + } + TypeDefinition.UNIT -> { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + } + is CustomTypeDefinition -> { + constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return result") + } } } } 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 74a8d88..3f22726 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 @@ -1,11 +1,6 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition +import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec @@ -111,50 +106,55 @@ object NativeLibsodiumGenerator { methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") pinParams(methodDefinition, methodBuilder) val constructNativeCall = StringBuilder() - if (methodDefinition.isStateCreationFunction) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return out") + if (methodDefinition.customCodeBlockReplacesFunctionBody != null && + methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { + constructNativeCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - } - is CustomTypeDefinition -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") + if (methodDefinition.isStateCreationFunction) { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return state") + } else if (actualReturnTypeFound) { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return out") + } else { + when (methodDefinition.returnType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return result") + } + TypeDefinition.INT -> { + constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return result") + } + TypeDefinition.UNIT -> { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + } + is CustomTypeDefinition -> { + constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return result") + } } + + } - - } methodBuilder.returns(methodDefinition.returnType.typeName) diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt index d9b4986..3236be4 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt @@ -1,11 +1,10 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ClassDefinition +import com.ionspin.kotlin.crypto.generator.libsodium.definitions.DataClassDefinition import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.KModifier -import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.* /** * Created by Ugljesa Jovanovic @@ -22,6 +21,9 @@ fun createClass( val primaryConstructor = FunSpec.constructorBuilder() if (multiplatformModifier == MultiplatformModifier.EXPECT) { primaryConstructor.addModifiers(KModifier.INTERNAL) + for (dataClassDefinition in classDefinition.dataClasses) { + generateDataClass(commonClassBuilder, dataClassDefinition) + } } else { primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL) } @@ -36,6 +38,25 @@ fun createClass( return commonClassBuilder } +fun generateDataClass(classBuilder: TypeSpec.Builder, dataClassDefinition: DataClassDefinition) { + val dataClassBuilder = TypeSpec.classBuilder(dataClassDefinition.name) + dataClassBuilder.addModifiers(KModifier.DATA) + val dataClassConstructor = FunSpec.constructorBuilder() + for (parameter in dataClassDefinition.parameters) { + val parameterBuilder = ParameterSpec.builder(parameter.parameterName, parameter.parameterType.typeName) + dataClassConstructor.addParameter(parameterBuilder.build()) + } + dataClassBuilder.primaryConstructor(dataClassConstructor.build()) + for (parameter in dataClassDefinition.parameters) { + dataClassBuilder.addProperty( + PropertySpec.builder(parameter.parameterName, parameter.parameterType.typeName) + .initializer(parameter.parameterName) + .build() + ) + } + classBuilder.addType(dataClassBuilder.build()) +} + fun generateDocumentationForMethod(builder: FunSpec.Builder, methodSpec: FunctionDefinition) { builder.addKdoc(methodSpec.codeDocumentation) } diff --git a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt index 32aa3b2..65fa2d6 100644 --- a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt +++ b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt @@ -1,8 +1,7 @@ package com.ionspin.kotlin.crypto.generator -import com.ionspin.kotlin.crypto.generator.libsodium.generator.CommonLibsodiumGenerator -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefinitions import com.ionspin.kotlin.crypto.generator.libsodium.generator.Coordinator +import com.squareup.kotlinpoet.* import org.junit.Test /** @@ -11,8 +10,5 @@ import org.junit.Test * on 31-Jul-2020 */ class DebugTest { - @Test - fun debugTest() { - Coordinator.run() - } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 6287381..06ba9e5 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -9,7 +9,13 @@ expect class Sha512State expect class GenericHashState +expect class SecretStreamState + expect class Crypto internal constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ fun crypto_hash_sha256_init(): Sha256State fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) @@ -23,4 +29,11 @@ expect class Crypto internal constructor() { fun crypto_hash_sha512_final(state: Sha512State): UByteArray fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState + + fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray + + data class SecretStreamStateAndHeader( + val state: SecretStreamState, + val header: UByteArray + ) } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index 727d9c7..6585ac4 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -13,7 +13,13 @@ actual typealias Sha512State = Any actual typealias GenericHashState = Any +actual typealias SecretStreamState = Any + actual class Crypto internal actual constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): dynamic { println("Debug crypto_hash_sha256_init") val result = js("getSodium().crypto_hash_sha256_init()") @@ -50,4 +56,9 @@ actual class Crypto internal actual constructor() { println("Debug crypto_generichash_init") return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) } + + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { + println("Debug crypto_secretstream_xchacha20poly1305_init_push") + + } } 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 1213842..7d5c0a2 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 @@ -2,6 +2,7 @@ package debug.test import com.goterl.lazycode.lazysodium.SodiumJava import com.goterl.lazycode.lazysodium.interfaces.Hash +import com.goterl.lazycode.lazysodium.interfaces.SecretStream import kotlin.ByteArray import kotlin.Int import kotlin.UByteArray @@ -14,7 +15,13 @@ actual typealias Sha512State = Hash.State512 actual typealias GenericHashState = ByteArray +actual typealias SecretStreamState = SecretStream.State + actual class Crypto internal actual constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): Sha256State { val state = debug.test.Sha256State() println("Debug crypto_hash_sha256_init") @@ -59,4 +66,10 @@ actual class Crypto internal actual constructor() { sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) return state } + + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { + println("Debug crypto_secretstream_xchacha20poly1305_init_push") + sodium.crypto_secretstream_xchacha20poly1305_init_push(key.asByteArray()) + return state + } } 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 5224235..24ee29e 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 @@ -22,11 +22,17 @@ actual typealias Sha512State = crypto_hash_sha512_state actual typealias GenericHashState = crypto_generichash_blake2b_state +actual typealias SecretStreamState = crypto_hash_sha256_state + actual class Crypto internal actual constructor() { val _emitByte: Byte = 0 val _emitByteArray: ByteArray = ByteArray(0) + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): Sha256State { val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! val state = allocated.reinterpret().pointed @@ -85,4 +91,12 @@ actual class Crypto internal actual constructor() { pinnedKey.unpin() return state } + + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { + println("Debug crypto_secretstream_xchacha20poly1305_init_push") + val pinnedKey = key.pin() + libsodium.crypto_secretstream_xchacha20poly1305_init_push(pinnedKey.addressOf(0)) + pinnedKey.unpin() + return state + } }