Working on js generator, adding initializers

This commit is contained in:
Ugljesa Jovanovic 2020-08-02 19:05:42 +02:00
parent 93a94724f3
commit 641fbceb3f
No known key found for this signature in database
GPG Key ID: 33A5F353387711A5
9 changed files with 297 additions and 11 deletions

View File

@ -16,11 +16,16 @@ object Coordinator {
val commonFileSpec = CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile)
val jvmFileSpec = JvmLibsodiumGenerator.createJvmFile(packageName, LibSodiumDefinitions.testKotlinFile)
val nativeFileSpec = NativeLibsodiumGenerator.createNativeFile(packageName, LibSodiumDefinitions.testKotlinFile)
val jsFileSpec = JsLibsodiumGenerator.createJsFile(packageName, LibSodiumDefinitions.testKotlinFile)
val commonFile = File("../multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/")
commonFileSpec.writeTo(commonFile)
val jvmFile = File("../multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/")
jvmFileSpec.writeTo(jvmFile)
val nativeFile = File("../multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/")
nativeFileSpec.writeTo(nativeFile)
val jsFile = File("../multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/")
jsFileSpec.writeTo(jsFile)
}
}

View File

@ -13,9 +13,8 @@ object JsLibsodiumGenerator {
fun createJsFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec {
val fileBuilder = FileSpec.builder(packageName, fileDefinition.name)
val sodiumProperty = PropertySpec.builder("sodium", ClassName.bestGuess("com.goterl.lazycode.lazysodium.SodiumJava"))
sodiumProperty.initializer(CodeBlock.of("SodiumJava()"))
fileBuilder.addProperty(sodiumProperty.build())
fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUInt8Array")
fileBuilder.addImport("com.ionspin.kotlin.crypto", "getSodium")
for (commonClassDefinition in fileDefinition.commonClassList) {
//Create type-aliases
commonClassDefinition.innerClasses.forEach {
@ -38,7 +37,7 @@ object JsLibsodiumGenerator {
innerClassDefinition: InnerClassDefinition,
multiplatformModifier: MultiplatformModifier
): TypeAliasSpec {
val innerClassBuilder = TypeAliasSpec.builder(innerClassDefinition.name, ClassName.bestGuess(innerClassDefinition.javaName))
val innerClassBuilder = TypeAliasSpec.builder(innerClassDefinition.name, Any::class.asTypeName())
innerClassBuilder.modifiers += multiplatformModifier.modifierList
return innerClassBuilder.build()
@ -65,7 +64,7 @@ object JsLibsodiumGenerator {
if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append("return getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
@ -74,7 +73,7 @@ object JsLibsodiumGenerator {
if (methodDefinition.returnType == TypeDefinition.INT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append("return getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
@ -83,7 +82,7 @@ object JsLibsodiumGenerator {
if (methodDefinition.returnType == TypeDefinition.UNIT) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("sodium.${methodDefinition.javaName}")
constructJvmCall.append("getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
@ -92,7 +91,7 @@ object JsLibsodiumGenerator {
if (methodDefinition.returnType is CustomTypeDefinition) {
methodBuilder.addStatement("println(\"Debug\")")
val constructJvmCall = StringBuilder()
constructJvmCall.append("return sodium.${methodDefinition.javaName}")
constructJvmCall.append("return getSodium().${methodDefinition.javaName}")
constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString())
@ -117,13 +116,13 @@ object JsLibsodiumGenerator {
if (paramDefinition.parameterType is TypeDefinition) {
when(paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size" + separator)
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array(), " + paramDefinition.parameterName + ".size" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size.toLong()" + separator)
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array(), " + paramDefinition.parameterName + ".size.toLong()" + separator)
}
TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> {
paramsBuilder.append(paramDefinition.parameterName + ".asByteArray()" + separator)
paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator)
}
TypeDefinition.LONG -> {
paramsBuilder.append(paramDefinition.parameterName + separator)

View File

@ -0,0 +1,12 @@
package com.ionspin.kotlin.crypto
/**
* Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020
*/
expect object Initializer {
fun isInitialized() : Boolean
suspend fun initialize()
fun initializeWithCallback(done: () -> (Unit))
}

View File

@ -0,0 +1,43 @@
package com.ionspin.kotlin.crypto
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumInterface
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
/* 1.4-M1 has some weirdness with static/objects, or I'm misusing something, not sure */
lateinit var sodiumPointer : JsSodiumInterface
var sodiumLoaded: Boolean = false
fun getSodium() : JsSodiumInterface = sodiumPointer
//fun getSodiumAdvanced() : JsSodiumAdvancedInterface = js("sodiumPointer.libsodium")
fun setSodiumPointer(jsSodiumInterface: JsSodiumInterface) {
js("sodiumPointer = jsSodiumInterface")
}
fun getSodiumLoaded() : Boolean = sodiumLoaded
fun setSodiumLoaded(loaded: Boolean) {
js("sodiumLoaded = loaded")
}
actual object Initializer {
private var isPlatformInitialized = false
actual suspend fun initialize() {
JsSodiumLoader.load()
isPlatformInitialized = true
}
actual fun initializeWithCallback(done: () -> Unit) {
JsSodiumLoader.loadWithCallback {
isPlatformInitialized = true
done()
}
}
actual fun isInitialized(): Boolean {
return isPlatformInitialized
}
}

View File

@ -0,0 +1,60 @@
package ext.libsodium.com.ionspin.kotlin.crypto
import org.khronos.webgl.Uint8Array
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 27-May-2020
*/
interface JsSodiumInterface {
fun randombytes_buf(numberOfBytes: Int): Uint8Array
fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array,): Uint8Array
fun crypto_hash_sha256(message: Uint8Array): Uint8Array
fun crypto_hash_sha512(message: Uint8Array): Uint8Array
//Updateable
fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic
fun crypto_generichash_update(state: dynamic, inputMessage: Uint8Array)
fun crypto_generichash_final(state: dynamic, hashLength: Int) : Uint8Array
fun crypto_hash_sha256_init() : dynamic
fun crypto_hash_sha256_update(state: dynamic, message: Uint8Array)
fun crypto_hash_sha256_final(state: dynamic): Uint8Array
fun crypto_hash_sha512_init() : dynamic
fun crypto_hash_sha512_update(state: dynamic, message: Uint8Array)
fun crypto_hash_sha512_final(state: dynamic): Uint8Array
//XChaCha20Poly1305
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
//XChaCha20Poly1305
//encrypt
fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic
fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: Uint8Array, tag: UByte) : Uint8Array
//decrypt
fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic
fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic
//util
fun memzero(array: Uint8Array)
}

View File

@ -0,0 +1,56 @@
package ext.libsodium.com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.getSodiumLoaded
import com.ionspin.kotlin.crypto.setSodiumPointer
import com.ionspin.kotlin.crypto.sodiumLoaded
import ext.libsodium.*
import kotlin.coroutines.Continuation
import kotlin.coroutines.suspendCoroutine
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 27-May-2020
*/
object JsSodiumLoader {
class _EmitJsSodiumFunction {
init {
println(::crypto_generichash)
println(::crypto_hash_sha256)
println(::crypto_hash_sha512)
println(::crypto_hash_sha256_init)
}
}
fun storeSodium(promisedSodium: dynamic, continuation: Continuation<Unit>) {
setSodiumPointer(promisedSodium)
sodiumLoaded = true
continuation.resumeWith(Result.success(Unit))
}
suspend fun load() = suspendCoroutine<Unit> { continuation ->
console.log(getSodiumLoaded())
if (!getSodiumLoaded()) {
val libsodiumModule = js("\$module\$libsodium_wrappers_sumo")
_libsodiumPromise.then<dynamic> { storeSodium(libsodiumModule, continuation) }
} else {
continuation.resumeWith(Result.success(Unit))
}
}
fun loadWithCallback(doneCallback: () -> (Unit)) {
console.log(getSodiumLoaded())
if (!getSodiumLoaded()) {
val libsodiumModule = js("\$module\$libsodium_wrappers_sumo")
_libsodiumPromise.then<dynamic> {
setSodiumPointer(libsodiumModule)
sodiumLoaded = true
doneCallback.invoke()
}
} else {
doneCallback.invoke()
}
}
}

View File

@ -0,0 +1,54 @@
package debug.test
import com.ionspin.kotlin.crypto.getSodium
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 {
actual fun crypto_hash_sha256_init(state: Sha256State): Int {
println("Debug")
return getSodium().crypto_hash_sha256_init(state)
}
actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
println("Debug")
getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), input.size.toLong())
}
actual fun crypto_hash_sha256_final(state: Sha256State, out: UByteArray) {
println("Debug")
getSodium().crypto_hash_sha256_final(state, out.toUInt8Array())
}
actual fun crypto_hash_sha512_init(state: Sha512State): Int {
println("Debug")
return getSodium().crypto_hash_sha512_init(state)
}
actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
println("Debug")
getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), input.size.toLong())
}
actual fun crypto_hash_sha512_final(state: Sha512State, out: UByteArray) {
println("Debug")
getSodium().crypto_hash_sha512_final(state, out.toUInt8Array())
}
actual fun crypto_generichash_init(
state: GenericHashState,
key: UByteArray,
outlen: Int
): Int {
println("Debug")
return getSodium().crypto_generichash_init(state, key.toUInt8Array(), key.size, outlen)
}
}

View File

@ -0,0 +1,27 @@
package com.ionspin.kotlin.crypto
import com.goterl.lazycode.lazysodium.SodiumJava
/**
* Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020
*/
actual object Initializer {
private var isPlatformInitialized = false
lateinit var sodium : SodiumJava
actual suspend fun initialize() {
sodium = SodiumJava()
isPlatformInitialized = true
}
actual fun initializeWithCallback(done: () -> Unit) {
sodium = SodiumJava()
isPlatformInitialized = true
done()
}
actual fun isInitialized(): Boolean {
return isPlatformInitialized
}
}

View File

@ -0,0 +1,30 @@
@file:Suppress("VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL")
package com.ionspin.kotlin.crypto
import libsodium.sodium_init
import kotlin.native.concurrent.AtomicInt
actual object Initializer {
private var isPlatformInitialized : AtomicInt = AtomicInt(0)
actual suspend fun initialize() {
if (isPlatformInitialized.compareAndSet(0, 1)) {
sodium_init()
}
}
actual fun initializeWithCallback(done: () -> Unit) {
if (isPlatformInitialized.compareAndSet(0, 1)) {
sodium_init()
}
done()
}
actual fun isInitialized(): Boolean {
return isPlatformInitialized.value != 0
}
}