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 isStateCreationFunction: Boolean = false,
val outputLengthWhenArray: Int = -1,
val customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null
val customCodeBlockReplacesFunctionBody: List<CodeBlockDefinition>? = null
) {
operator fun ParameterDefinition.unaryPlus() {
parameterList.add(this)
@ -186,7 +186,7 @@ fun funcDef(
dynamicJsReturn: Boolean = false,
isStateCreationFunction: Boolean = false,
outputLengthWhenArray: Int = -1,
customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null,
customCodeBlockReplacesFunctionBody: List<CodeBlockDefinition>? = null,
body: FunctionDefinition.() -> Unit
): FunctionDefinition {
val function = FunctionDefinition(
@ -212,7 +212,7 @@ fun funcDef(
dynamicJsReturn: Boolean = false,
isStateCreationFunction: Boolean = false,
outputLengthWhenArray: Int = -1,
customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null,
customCodeBlockReplacesFunctionBody: List<CodeBlockDefinition>? = null,
body: FunctionDefinition.() -> Unit
): FunctionDefinition {
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(
"crypto_secretstream_xchacha20poly1305_init_push",
returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE,
dynamicJsReturn = true,
isStateCreationFunction = true
isStateCreationFunction = true,
customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit)
) {
+ParameterDefinition(
"key",

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,11 @@ expect class GenericHashState
expect class SecretStreamState
data class SecretStreamStateAndHeader(
val state: SecretStreamState,
val header: UByteArray
)
expect class Crypto internal constructor() {
/**
* Initialize the SHA256 hash
@ -31,9 +36,4 @@ expect class Crypto internal constructor() {
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
)
}

View File

@ -6,6 +6,7 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import kotlin.Any
import kotlin.Int
import kotlin.UByteArray
import org.khronos.webgl.Uint8Array
actual typealias Sha256State = Any
@ -59,6 +60,10 @@ actual class Crypto internal actual constructor() {
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic {
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 {
println("Debug crypto_secretstream_xchacha20poly1305_init_push")
sodium.crypto_secretstream_xchacha20poly1305_init_push(key.asByteArray())
return state
val header = UByteArray(24)
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 {
println("Debug crypto_secretstream_xchacha20poly1305_init_push")
val pinnedKey = key.pin()
libsodium.crypto_secretstream_xchacha20poly1305_init_push(pinnedKey.addressOf(0))
pinnedKey.unpin()
return state
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)
}
}