Adding custom code blocks

This commit is contained in:
Ugljesa Jovanovic 2020-08-14 14:25:26 +02:00
parent a5b20daf5a
commit efe9661c30
No known key found for this signature in database
GPG Key ID: 33A5F353387711A5
11 changed files with 87 additions and 27 deletions

View File

@ -78,7 +78,7 @@ class FunctionDefinition(
val dynamicJsReturn: Boolean = false, val dynamicJsReturn: Boolean = false,
val isStateCreationFunction: Boolean = false, val isStateCreationFunction: Boolean = false,
val outputLengthWhenArray: Int = -1, val outputLengthWhenArray: Int = -1,
val customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null val customCodeBlockReplacesFunctionBody: List<CodeBlockDefinition>? = null
) { ) {
operator fun ParameterDefinition.unaryPlus() { operator fun ParameterDefinition.unaryPlus() {
parameterList.add(this) parameterList.add(this)
@ -186,7 +186,7 @@ fun funcDef(
dynamicJsReturn: Boolean = false, dynamicJsReturn: Boolean = false,
isStateCreationFunction: Boolean = false, isStateCreationFunction: Boolean = false,
outputLengthWhenArray: Int = -1, outputLengthWhenArray: Int = -1,
customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, customCodeBlockReplacesFunctionBody: List<CodeBlockDefinition>? = null,
body: FunctionDefinition.() -> Unit body: FunctionDefinition.() -> Unit
): FunctionDefinition { ): FunctionDefinition {
val function = FunctionDefinition( val function = FunctionDefinition(
@ -212,7 +212,7 @@ fun funcDef(
dynamicJsReturn: Boolean = false, dynamicJsReturn: Boolean = false,
isStateCreationFunction: Boolean = false, isStateCreationFunction: Boolean = false,
outputLengthWhenArray: Int = -1, outputLengthWhenArray: Int = -1,
customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, customCodeBlockReplacesFunctionBody: List<CodeBlockDefinition>? = null,
body: FunctionDefinition.() -> Unit body: FunctionDefinition.() -> Unit
): FunctionDefinition { ): FunctionDefinition {
val function = val function =

View File

@ -30,11 +30,45 @@ fun ClassDefinition.defineSecretStreamFunctions() {
) )
) )
val jsSecretStreamInit = CodeBlockDefinition(
"""
val stateAndHeader = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array())
val state = stateAndHeader.state
val header = (stateAndHeader.header as Uint8Array).toUByteArray()
return SecretStreamStateAndHeader(state, header)
""".trimIndent(),
setOf(TargetPlatform.JS)
)
val jvmSecretStreamInit = CodeBlockDefinition(
"""
val header = UByteArray(24)
val state = SecretStream.State()
sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray())
return SecretStreamStateAndHeader(state, header)
""".trimIndent(),
setOf(TargetPlatform.JVM)
)
val nativeSecretStreamInit = CodeBlockDefinition(
"""
val state = libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!!
.reinterpret<libsodium.crypto_secretstream_xchacha20poly1305_state>()
.pointed
val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U }
val pinnedHeader = header.pin()
libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues())
pinnedHeader.unpin()
return SecretStreamStateAndHeader(state, header)
""".trimIndent(),
setOf(TargetPlatform.NATIVE)
)
+funcDef( +funcDef(
"crypto_secretstream_xchacha20poly1305_init_push", "crypto_secretstream_xchacha20poly1305_init_push",
returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE,
dynamicJsReturn = true, dynamicJsReturn = true,
isStateCreationFunction = true isStateCreationFunction = true,
customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit)
) { ) {
+ParameterDefinition( +ParameterDefinition(
"key", "key",

View File

@ -28,6 +28,7 @@ object CommonLibsodiumGenerator {
} }
val commonClassSpec = val commonClassSpec =
createClass( createClass(
fileBuilder,
commonClassDefinition, commonClassDefinition,
MultiplatformModifier.EXPECT, MultiplatformModifier.EXPECT,
::createCommonMethodSpec ::createCommonMethodSpec

View File

@ -18,6 +18,7 @@ object JsLibsodiumGenerator {
fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUInt8Array") fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUInt8Array")
fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUByteArray") fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUByteArray")
fileBuilder.addImport("com.ionspin.kotlin.crypto", "getSodium") fileBuilder.addImport("com.ionspin.kotlin.crypto", "getSodium")
fileBuilder.addImport("org.khronos.webgl", "Uint8Array")
for (commonClassDefinition in fileDefinition.commonClassList) { for (commonClassDefinition in fileDefinition.commonClassList) {
//Create type-aliases //Create type-aliases
commonClassDefinition.innerClasses.forEach { commonClassDefinition.innerClasses.forEach {
@ -25,6 +26,7 @@ object JsLibsodiumGenerator {
} }
val commonClassSpec = createClass( val commonClassSpec = createClass(
fileBuilder,
commonClassDefinition, commonClassDefinition,
MultiplatformModifier.ACTUAL, MultiplatformModifier.ACTUAL,
::createJsFunctionImplementation ::createJsFunctionImplementation
@ -97,9 +99,10 @@ object JsLibsodiumGenerator {
methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList
methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")")
val constructJsCall = StringBuilder() val constructJsCall = StringBuilder()
if (methodDefinition.customCodeBlockReplacesFunctionBody != null && if (methodDefinition.customCodeBlockReplacesFunctionBody != null) {
methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.JS) }) {
constructJsCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) constructJsCall.append(codeBlock.codeBlock)
}
} else { } else {
when (methodDefinition.returnType) { when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> { TypeDefinition.ARRAY_OF_UBYTES -> {

View File

@ -29,6 +29,7 @@ object JvmLibsodiumGenerator {
} }
val commonClassSpec = createClass( val commonClassSpec = createClass(
fileBuilder,
commonClassDefinition, commonClassDefinition,
MultiplatformModifier.ACTUAL, MultiplatformModifier.ACTUAL,
::createJvmFunctionImplementation ::createJvmFunctionImplementation
@ -98,9 +99,11 @@ object JvmLibsodiumGenerator {
} }
methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")")
val constructJvmCall = StringBuilder() val constructJvmCall = StringBuilder()
if (methodDefinition.customCodeBlockReplacesFunctionBody != null && if (methodDefinition.customCodeBlockReplacesFunctionBody != null) {
methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JVM)) { for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.JVM) }) {
constructJvmCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) constructJvmCall.append(codeBlock.codeBlock)
}
methodBuilder.addStatement(constructJvmCall.toString())
} else { } else {
if (methodDefinition.isStateCreationFunction) { if (methodDefinition.isStateCreationFunction) {
constructJvmCall.append("sodium.${methodDefinition.nativeName}") constructJvmCall.append("sodium.${methodDefinition.nativeName}")

View File

@ -36,6 +36,7 @@ object NativeLibsodiumGenerator {
} }
val commonClassSpec = createClass( val commonClassSpec = createClass(
fileBuilder,
commonClassDefinition, commonClassDefinition,
MultiplatformModifier.ACTUAL, MultiplatformModifier.ACTUAL,
::createNativeFunctionImplementation ::createNativeFunctionImplementation
@ -106,9 +107,11 @@ object NativeLibsodiumGenerator {
methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")")
pinParams(methodDefinition, methodBuilder) pinParams(methodDefinition, methodBuilder)
val constructNativeCall = StringBuilder() val constructNativeCall = StringBuilder()
if (methodDefinition.customCodeBlockReplacesFunctionBody != null && if (methodDefinition.customCodeBlockReplacesFunctionBody != null) {
methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.NATIVE) }) {
constructNativeCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) constructNativeCall.append(codeBlock.codeBlock)
methodBuilder.addStatement(constructNativeCall.toString())
}
} else { } else {
if (methodDefinition.isStateCreationFunction) { if (methodDefinition.isStateCreationFunction) {
constructNativeCall.append("libsodium.${methodDefinition.nativeName}") constructNativeCall.append("libsodium.${methodDefinition.nativeName}")

View File

@ -12,6 +12,7 @@ import com.squareup.kotlinpoet.*
* on 31-Jul-2020 * on 31-Jul-2020
*/ */
fun createClass( fun createClass(
fileBuilder: FileSpec.Builder,
classDefinition: ClassDefinition, classDefinition: ClassDefinition,
multiplatformModifier: MultiplatformModifier, multiplatformModifier: MultiplatformModifier,
methodCreator: (FunctionDefinition) -> FunSpec.Builder methodCreator: (FunctionDefinition) -> FunSpec.Builder
@ -22,7 +23,7 @@ fun createClass(
if (multiplatformModifier == MultiplatformModifier.EXPECT) { if (multiplatformModifier == MultiplatformModifier.EXPECT) {
primaryConstructor.addModifiers(KModifier.INTERNAL) primaryConstructor.addModifiers(KModifier.INTERNAL)
for (dataClassDefinition in classDefinition.dataClasses) { for (dataClassDefinition in classDefinition.dataClasses) {
generateDataClass(commonClassBuilder, dataClassDefinition) generateDataClass(fileBuilder, dataClassDefinition)
} }
} else { } else {
primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL) primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL)
@ -38,7 +39,7 @@ fun createClass(
return commonClassBuilder return commonClassBuilder
} }
fun generateDataClass(classBuilder: TypeSpec.Builder, dataClassDefinition: DataClassDefinition) { fun generateDataClass(fileBuilder: FileSpec.Builder, dataClassDefinition: DataClassDefinition) {
val dataClassBuilder = TypeSpec.classBuilder(dataClassDefinition.name) val dataClassBuilder = TypeSpec.classBuilder(dataClassDefinition.name)
dataClassBuilder.addModifiers(KModifier.DATA) dataClassBuilder.addModifiers(KModifier.DATA)
val dataClassConstructor = FunSpec.constructorBuilder() val dataClassConstructor = FunSpec.constructorBuilder()
@ -54,7 +55,7 @@ fun generateDataClass(classBuilder: TypeSpec.Builder, dataClassDefinition: DataC
.build() .build()
) )
} }
classBuilder.addType(dataClassBuilder.build()) fileBuilder.addType(dataClassBuilder.build())
} }
fun generateDocumentationForMethod(builder: FunSpec.Builder, methodSpec: FunctionDefinition) { fun generateDocumentationForMethod(builder: FunSpec.Builder, methodSpec: FunctionDefinition) {

View File

@ -11,6 +11,11 @@ expect class GenericHashState
expect class SecretStreamState expect class SecretStreamState
data class SecretStreamStateAndHeader(
val state: SecretStreamState,
val header: UByteArray
)
expect class Crypto internal constructor() { expect class Crypto internal constructor() {
/** /**
* Initialize the SHA256 hash * Initialize the SHA256 hash
@ -31,9 +36,4 @@ expect class Crypto internal constructor() {
fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState
fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray
data class SecretStreamStateAndHeader(
val state: SecretStreamState,
val header: UByteArray
)
} }

View File

@ -6,6 +6,7 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import kotlin.Any import kotlin.Any
import kotlin.Int import kotlin.Int
import kotlin.UByteArray import kotlin.UByteArray
import org.khronos.webgl.Uint8Array
actual typealias Sha256State = Any actual typealias Sha256State = Any
@ -59,6 +60,10 @@ actual class Crypto internal actual constructor() {
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic {
println("Debug crypto_secretstream_xchacha20poly1305_init_push") println("Debug crypto_secretstream_xchacha20poly1305_init_push")
val stateAndHeader =
getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array())
val state = stateAndHeader.state
val header = (stateAndHeader.header as Uint8Array).toUByteArray()
return SecretStreamStateAndHeader(state, header)
} }
} }

View File

@ -69,7 +69,10 @@ actual class Crypto internal actual constructor() {
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray {
println("Debug crypto_secretstream_xchacha20poly1305_init_push") println("Debug crypto_secretstream_xchacha20poly1305_init_push")
sodium.crypto_secretstream_xchacha20poly1305_init_push(key.asByteArray()) val header = UByteArray(24)
return state val state = SecretStream.State()
sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(),
key.asByteArray())
return SecretStreamStateAndHeader(state, header)
} }
} }

View File

@ -95,8 +95,15 @@ actual class Crypto internal actual constructor() {
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray {
println("Debug crypto_secretstream_xchacha20poly1305_init_push") println("Debug crypto_secretstream_xchacha20poly1305_init_push")
val pinnedKey = key.pin() val pinnedKey = key.pin()
libsodium.crypto_secretstream_xchacha20poly1305_init_push(pinnedKey.addressOf(0)) val state =
pinnedKey.unpin() libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!!
return state .reinterpret<libsodium.crypto_secretstream_xchacha20poly1305_state>()
.pointed
val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U }
val pinnedHeader = header.pin()
libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr,
pinnedHeader.addressOf(0), key.toCValues())
pinnedHeader.unpin()
return SecretStreamStateAndHeader(state, header)
} }
} }