diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index b4ebfdc..fd3f694 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -49,6 +49,11 @@ object Deps { val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Versions.kotlinCoroutines}" val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.kotlinSerialization}" + object Npm { + val libsodium = Pair("libsodium", "0.7.6") + val libsodiumWrappers = Pair("libsodium-wrappers", "0.7.6") + } + } object Jvm { diff --git a/multiplatform-crypto-delegated/build.gradle.kts b/multiplatform-crypto-delegated/build.gradle.kts index 5e258ec..2e2926c 100644 --- a/multiplatform-crypto-delegated/build.gradle.kts +++ b/multiplatform-crypto-delegated/build.gradle.kts @@ -249,12 +249,15 @@ kotlin { dependencies { implementation(kotlin(Deps.Js.stdLib)) implementation(Deps.Js.coroutines) + implementation(npm(Deps.Js.Npm.libsodium.first, Deps.Js.Npm.libsodium.second)) + implementation(npm(Deps.Js.Npm.libsodiumWrappers.first, Deps.Js.Npm.libsodiumWrappers.second)) } } val jsTest by getting { dependencies { implementation(Deps.Js.coroutines) implementation(kotlin(Deps.Js.test)) + implementation(npm(Deps.Js.Npm.libsodium.first, Deps.Js.Npm.libsodium.second)) } } val linuxMain by getting { diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index 94b6559..bde45d0 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -1,5 +1,10 @@ package com.ionspin.kotlin.crypto.hash.blake2b +import crypto_generichash +import org.khronos.webgl.Uint8Array +import org.khronos.webgl.get +import kotlin.js.Promise + /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com @@ -8,7 +13,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b @ExperimentalUnsignedTypes actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: Int) : Blake2b { - override val MAX_HASH_BYTES: Int = 128 + override val MAX_HASH_BYTES: Int = 64 override fun update(data: UByteArray) { @@ -28,17 +33,24 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I } } +@ExperimentalStdlibApi @ExperimentalUnsignedTypes actual object Blake2bStateless : Blake2bStatelessInterface { + override val MAX_HASH_BYTES: Int = 64 + override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray { - TODO("not implemented yet") +// val hashed = crypto_generichash(64, Uint8Array(inputString.encodeToByteArray().toTypedArray()), null) +// return UByteArray(MAX_HASH_BYTES) { hashed[it].toUByte() } + + val hash = crypto_generichash(64, Uint8Array(arrayOf(0U.toByte()))); + println("Hash $hash") + return ubyteArrayOf(0U) } override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { TODO("not implemented yet") } - override val MAX_HASH_BYTES: Int - get() = TODO("not implemented yet") + } \ No newline at end of file diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/libsodium.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/libsodium.kt new file mode 100644 index 0000000..d259753 --- /dev/null +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/libsodium.kt @@ -0,0 +1,10 @@ +import org.khronos.webgl.Uint8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 25-May-2020 + */ +@JsModule("libsodium") +@JsNonModule +external fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array) : Uint8Array \ No newline at end of file diff --git a/multiplatform-crypto-delegated/src/jsTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bJsTest.kt b/multiplatform-crypto-delegated/src/jsTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bJsTest.kt new file mode 100644 index 0000000..710c035 --- /dev/null +++ b/multiplatform-crypto-delegated/src/jsTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bJsTest.kt @@ -0,0 +1,18 @@ +package com.ionspin.kotlin.crypto.hash.blake2b + +import kotlin.test.Test + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 25-May-2020 + */ +@ExperimentalUnsignedTypes +@ExperimentalStdlibApi +class Blake2bJsTest { + + @Test + fun testBlake2BSodiumInterop() { + Blake2bStateless.digest("test") + } +} \ No newline at end of file diff --git a/multiplatform-crypto-delegated/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index c437e85..540153e 100644 --- a/multiplatform-crypto-delegated/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -35,25 +35,36 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I @Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") actual object Blake2bStateless : Blake2bStatelessInterface { override fun digest(inputString: String, key: String?, hashLength: Int): UByteArray { - return memScoped { - val hashResult = UByteArray(MAX_HASH_BYTES) - val hashPointer = hashResult.toCValues().getPointer(this) - crypto_generichash( - hashPointer, - hashLength.toULong(), - inputString.cstr.getPointer(this).reinterpret(), - inputString.length.toULong(), key?.cstr?.getPointer(this)?.reinterpret(), - key?.length?.toULong() ?: 0UL - ) - println("HashPointer: ${hashPointer.readBytes(MAX_HASH_BYTES).toUByteArray().toHexString()}") - println(hashResult.toHexString()) - hashResult - } - + val hashResult = UByteArray(MAX_HASH_BYTES) + val hashResultPinned = hashResult.pin() + crypto_generichash( + hashResultPinned.addressOf(0), + hashLength.toULong(), + inputString.encodeToByteArray().toUByteArray().toCValues(), + inputString.length.toULong(), + key?.run { this.encodeToByteArray().toUByteArray().toCValues() }, + key?.length?.toULong() ?: 0UL + ) + println("HashPointer: ${hashResult.toHexString()}") + println(hashResult.toHexString()) + return hashResult } override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { - TODO("not implemented yet") + val hashResult = UByteArray(MAX_HASH_BYTES) + + crypto_generichash( + StableRef.create(hashResult).asCPointer().reinterpret(), + hashLength.toULong(), + inputMessage.toCValues(), + inputMessage.size.toULong(), + key.toCValues(), + key.size.toULong() ?: 0UL + ) + println("HashPointer: ${hashResult.toHexString()}") + println(hashResult.toHexString()) + return hashResult + } override val MAX_HASH_BYTES: Int = 64