Working js libsodium, need to change apis to suspend
This commit is contained in:
parent
1009b92d33
commit
781c9c1b61
@ -50,8 +50,8 @@ object Deps {
|
|||||||
val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.kotlinSerialization}"
|
val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.kotlinSerialization}"
|
||||||
|
|
||||||
object Npm {
|
object Npm {
|
||||||
val libsodium = Pair("libsodium", "0.7.6")
|
val libsodium = Pair("libsodium-sumo", "0.7.6")
|
||||||
val libsodiumWrappers = Pair("libsodium-wrappers", "0.7.6")
|
val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "0.7.6")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ org.gradle.parallel=true
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
|
|
||||||
kotlin.js.compiler=ir
|
kotlin.js.compiler=ir
|
||||||
|
#kotlin.js.experimental.generateKotlinExternals=true
|
||||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
|
|
||||||
org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=4096m
|
org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=4096m
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.ionspin.kotlin.crypto
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Ugljesa Jovanovic
|
||||||
|
* ugljesa.jovanovic@ionspin.com
|
||||||
|
* on 27-May-2020
|
||||||
|
*/
|
||||||
|
interface CryptoProvider {
|
||||||
|
suspend fun initialize()
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -39,7 +39,7 @@ interface UpdatableHash : Hash {
|
|||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
interface StatelessHash : Hash {
|
interface StatelessHash : Hash {
|
||||||
fun digest(inputString: String, key: String? = null, hashLength: Int = MAX_HASH_BYTES): UByteArray
|
suspend fun digest(inputString: String, key: String? = null, hashLength: Int = MAX_HASH_BYTES): UByteArray
|
||||||
|
|
||||||
fun digest(
|
fun digest(
|
||||||
inputMessage: UByteArray = ubyteArrayOf(),
|
inputMessage: UByteArray = ubyteArrayOf(),
|
||||||
|
@ -13,3 +13,15 @@ import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure
|
|||||||
|
|
||||||
typealias Sha256Stateless = Sha256Pure.Companion
|
typealias Sha256Stateless = Sha256Pure.Companion
|
||||||
typealias Sha512Stateless = Sha512Pure.Companion
|
typealias Sha512Stateless = Sha512Pure.Companion
|
||||||
|
|
||||||
|
object Crypto : CryptoProvider {
|
||||||
|
override suspend fun initialize() {
|
||||||
|
Initializer.initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
expect object Initializer {
|
||||||
|
suspend fun initialize()
|
||||||
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ class Sha256Pure : Sha256 {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
override suspend fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
return digest(
|
return digest(
|
||||||
inputString.encodeToByteArray().toUByteArray(),
|
inputString.encodeToByteArray().toUByteArray(),
|
||||||
key?.run { encodeToByteArray().toUByteArray()} ?: ubyteArrayOf(),
|
key?.run { encodeToByteArray().toUByteArray()} ?: ubyteArrayOf(),
|
||||||
|
@ -134,7 +134,7 @@ class Sha512Pure : Sha512 {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
override suspend fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
return digest(
|
return digest(
|
||||||
inputString.encodeToByteArray().toUByteArray(),
|
inputString.encodeToByteArray().toUByteArray(),
|
||||||
key?.run { encodeToByteArray().toUByteArray() } ?: ubyteArrayOf(),
|
key?.run { encodeToByteArray().toUByteArray() } ?: ubyteArrayOf(),
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
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 getSodiumPointer() : JsSodiumInterface = sodiumPointer
|
||||||
|
|
||||||
|
fun setSodiumPointer(jsSodiumInterface: JsSodiumInterface) {
|
||||||
|
js("sodiumPointer = jsSodiumInterface")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSodiumLoaded() : Boolean = sodiumLoaded
|
||||||
|
|
||||||
|
fun setSodiumLoaded(loaded: Boolean) {
|
||||||
|
js("sodiumLoaded = loaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual object Initializer {
|
||||||
|
actual suspend fun initialize() {
|
||||||
|
JsSodiumLoader.load()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package ext.libsodium.com.ionspin.kotlin.crypto
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Ugljesa Jovanovic
|
||||||
|
* ugljesa.jovanovic@ionspin.com
|
||||||
|
* on 27-May-2020
|
||||||
|
*/
|
||||||
|
interface JsSodiumInterface {
|
||||||
|
fun crypto_generichash(hashLength: Int, inputMessage: String) : String
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package ext.libsodium.com.ionspin.kotlin.crypto
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.getSodiumLoaded
|
||||||
|
import com.ionspin.kotlin.crypto.getSodiumPointer
|
||||||
|
import com.ionspin.kotlin.crypto.setSodiumPointer
|
||||||
|
import com.ionspin.kotlin.crypto.sodiumLoaded
|
||||||
|
import ext.libsodium._libsodiumPromise
|
||||||
|
import kotlin.coroutines.Continuation
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Ugljesa Jovanovic
|
||||||
|
* ugljesa.jovanovic@ionspin.com
|
||||||
|
* on 27-May-2020
|
||||||
|
*/
|
||||||
|
object JsSodiumLoader {
|
||||||
|
|
||||||
|
fun storeSodium(promisedSodium: dynamic, continuation: Continuation<JsSodiumInterface>) {
|
||||||
|
setSodiumPointer(promisedSodium)
|
||||||
|
sodiumLoaded = true
|
||||||
|
continuation.resumeWith(Result.success(getSodiumPointer()))
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun load(): JsSodiumInterface = suspendCoroutine { continuation ->
|
||||||
|
console.log(getSodiumLoaded())
|
||||||
|
if (!getSodiumLoaded()) {
|
||||||
|
val libsodiumModule = js("\$module\$libsodium_wrappers_sumo")
|
||||||
|
_libsodiumPromise.then<dynamic> { storeSodium(libsodiumModule, continuation) }
|
||||||
|
} else {
|
||||||
|
continuation.resumeWith(Result.success(getSodiumPointer()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||||
|
|
||||||
import crypto_generichash
|
import com.ionspin.kotlin.crypto.util.toHexString
|
||||||
import org.khronos.webgl.Uint8Array
|
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumInterface
|
||||||
import org.khronos.webgl.get
|
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
|
||||||
import kotlin.js.Promise
|
import ext.libsodium.crypto_generichash
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Ugljesa Jovanovic
|
* Created by Ugljesa Jovanovic
|
||||||
@ -38,12 +38,18 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I
|
|||||||
actual object Blake2bStateless : Blake2bStatelessInterface {
|
actual object Blake2bStateless : Blake2bStatelessInterface {
|
||||||
override val MAX_HASH_BYTES: Int = 64
|
override val MAX_HASH_BYTES: Int = 64
|
||||||
|
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
override suspend fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
// val hashed = crypto_generichash(64, Uint8Array(inputString.encodeToByteArray().toTypedArray()), null)
|
val sodium = JsSodiumLoader.load()
|
||||||
// return UByteArray(MAX_HASH_BYTES) { hashed[it].toUByte() }
|
val hashed = sodium.crypto_generichash(64, inputString)
|
||||||
|
val hash = UByteArray(MAX_HASH_BYTES)
|
||||||
val hash = crypto_generichash(64, Uint8Array(arrayOf(0U.toByte())));
|
for (i in 0 until MAX_HASH_BYTES) {
|
||||||
println("Hash $hash")
|
js(
|
||||||
|
"""
|
||||||
|
hash[i] = hashed[i]
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
println("Hash ${hash.toHexString()}")
|
||||||
return ubyteArrayOf(0U)
|
return ubyteArrayOf(0U)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,5 +58,4 @@ actual object Blake2bStateless : Blake2bStatelessInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,19 @@
|
|||||||
|
@file:JsModule("libsodium-wrappers-sumo")
|
||||||
|
@file:JsNonModule
|
||||||
|
package ext.libsodium
|
||||||
|
|
||||||
import org.khronos.webgl.Uint8Array
|
import org.khronos.webgl.Uint8Array
|
||||||
|
import kotlin.js.Promise
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Ugljesa Jovanovic
|
* Created by Ugljesa Jovanovic
|
||||||
* ugljesa.jovanovic@ionspin.com
|
* ugljesa.jovanovic@ionspin.com
|
||||||
* on 25-May-2020
|
* on 25-May-2020
|
||||||
*/
|
*/
|
||||||
@JsModule("libsodium")
|
|
||||||
@JsNonModule
|
@JsName("ready")
|
||||||
external fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array) : Uint8Array
|
external val _libsodiumPromise : Promise<dynamic>
|
||||||
|
|
||||||
|
external fun crypto_generichash(hashLength: Int, inputMessage: String) : String
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.Crypto
|
||||||
|
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,8 +14,13 @@ import kotlin.test.Test
|
|||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
class Blake2bJsTest {
|
class Blake2bJsTest {
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setup() = testBlocking {
|
||||||
|
Crypto.initialize()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testBlake2BSodiumInterop() {
|
fun testBlake2BSodiumInterop() = testBlocking {
|
||||||
Blake2bStateless.digest("test")
|
Blake2bStateless.digest("test")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.ionspin.kotlin.crypto
|
||||||
|
|
||||||
|
actual object Initializer {
|
||||||
|
actual suspend fun initialize() {
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I
|
|||||||
}
|
}
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
actual object Blake2bStateless : Blake2bStatelessInterface {
|
actual object Blake2bStateless : Blake2bStatelessInterface {
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
suspend override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
TODO("not implemented yet")
|
TODO("not implemented yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.ionspin.kotlin.crypto
|
||||||
|
|
||||||
|
actual object Initializer {
|
||||||
|
actual suspend fun initialize() {
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I
|
|||||||
|
|
||||||
@Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
@Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||||
actual object Blake2bStateless : Blake2bStatelessInterface {
|
actual object Blake2bStateless : Blake2bStatelessInterface {
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
suspend override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
val hashResult = UByteArray(MAX_HASH_BYTES)
|
val hashResult = UByteArray(MAX_HASH_BYTES)
|
||||||
val hashResultPinned = hashResult.pin()
|
val hashResultPinned = hashResult.pin()
|
||||||
crypto_generichash(
|
crypto_generichash(
|
||||||
|
@ -145,7 +145,7 @@ class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
override suspend fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
val array = inputString.encodeToByteArray().toUByteArray()
|
val array = inputString.encodeToByteArray().toUByteArray()
|
||||||
val keyBytes = key?.run {
|
val keyBytes = key?.run {
|
||||||
encodeToByteArray().toUByteArray()
|
encodeToByteArray().toUByteArray()
|
||||||
|
@ -66,7 +66,7 @@ class Sha256Pure : Sha256 {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
suspend override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
return digest(
|
return digest(
|
||||||
inputString.encodeToByteArray().toUByteArray(),
|
inputString.encodeToByteArray().toUByteArray(),
|
||||||
key?.run { encodeToByteArray().toUByteArray()} ?: ubyteArrayOf(),
|
key?.run { encodeToByteArray().toUByteArray()} ?: ubyteArrayOf(),
|
||||||
|
@ -134,7 +134,7 @@ class Sha512Pure : Sha512 {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
override suspend fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||||
return digest(
|
return digest(
|
||||||
inputString.encodeToByteArray().toUByteArray(),
|
inputString.encodeToByteArray().toUByteArray(),
|
||||||
key?.run { encodeToByteArray().toUByteArray() } ?: ubyteArrayOf(),
|
key?.run { encodeToByteArray().toUByteArray() } ?: ubyteArrayOf(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user