Use random bytes provided by libsodium on js, add with callback load for sodium, more progress
This commit is contained in:
parent
781c9c1b61
commit
f51374ce15
@ -74,7 +74,7 @@ kotlin {
|
||||
js {
|
||||
browser {
|
||||
testTask {
|
||||
enabled = false //Until I sort out testing on travis
|
||||
enabled = true //Until I sort out testing on travis
|
||||
useKarma {
|
||||
useChrome()
|
||||
}
|
||||
|
@ -23,5 +23,7 @@ object Crypto : CryptoProvider {
|
||||
|
||||
expect object Initializer {
|
||||
suspend fun initialize()
|
||||
|
||||
fun initializeWithCallback(done : () -> (Unit))
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
|
||||
lateinit var sodiumPointer : JsSodiumInterface
|
||||
var sodiumLoaded: Boolean = false
|
||||
|
||||
fun getSodiumPointer() : JsSodiumInterface = sodiumPointer
|
||||
fun getSodium() : JsSodiumInterface = sodiumPointer
|
||||
|
||||
fun setSodiumPointer(jsSodiumInterface: JsSodiumInterface) {
|
||||
js("sodiumPointer = jsSodiumInterface")
|
||||
@ -22,4 +22,10 @@ actual object Initializer {
|
||||
actual suspend fun initialize() {
|
||||
JsSodiumLoader.load()
|
||||
}
|
||||
|
||||
actual fun initializeWithCallback(done: () -> Unit) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,10 +1,17 @@
|
||||
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 crypto_generichash(hashLength: Int, inputMessage: String) : String
|
||||
|
||||
fun crypto_generichash(hashLength: Int, inputMessage: String) : Uint8Array
|
||||
|
||||
fun randombytes_buf(numberOfBytes: Int) : Uint8Array
|
||||
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
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
|
||||
@ -15,19 +14,33 @@ import kotlin.coroutines.suspendCoroutine
|
||||
*/
|
||||
object JsSodiumLoader {
|
||||
|
||||
fun storeSodium(promisedSodium: dynamic, continuation: Continuation<JsSodiumInterface>) {
|
||||
fun storeSodium(promisedSodium: dynamic, continuation: Continuation<Unit>) {
|
||||
setSodiumPointer(promisedSodium)
|
||||
sodiumLoaded = true
|
||||
continuation.resumeWith(Result.success(getSodiumPointer()))
|
||||
continuation.resumeWith(Result.success(Unit))
|
||||
}
|
||||
|
||||
suspend fun load(): JsSodiumInterface = suspendCoroutine { continuation ->
|
||||
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(getSodiumPointer()))
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import kotlin.browser.window
|
||||
import org.khronos.webgl.get
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
@ -27,22 +27,7 @@ actual object SRNG {
|
||||
var counter = 0
|
||||
@ExperimentalUnsignedTypes
|
||||
actual fun getRandomBytes(amount: Int): UByteArray {
|
||||
val runningOnNode = jsTypeOf(window) == "undefined"
|
||||
val randomBytes = if (runningOnNode) {
|
||||
println("Running on node")
|
||||
js("require('crypto')").randomBytes(amount).toJSON().data
|
||||
} else {
|
||||
println("Running in browser")
|
||||
js(
|
||||
"""
|
||||
var randomArray = new Uint8Array(amount);
|
||||
var crypto = (self.crypto || self.msCrypto);
|
||||
crypto.getRandomValues(randomArray);
|
||||
"""
|
||||
)
|
||||
var randomArrayResult = js("Array.prototype.slice.call(randomArray);")
|
||||
randomArrayResult
|
||||
}
|
||||
val randomBytes = getSodium().randombytes_buf(amount)
|
||||
println("Random bytes: $randomBytes")
|
||||
print("Byte at ${randomBytes[0]}")
|
||||
val randomBytesUByteArray = UByteArray(amount) {
|
||||
|
@ -1,9 +1,7 @@
|
||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||
|
||||
import com.ionspin.kotlin.crypto.getSodium
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumInterface
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
|
||||
import ext.libsodium.crypto_generichash
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
@ -39,8 +37,7 @@ actual object Blake2bStateless : Blake2bStatelessInterface {
|
||||
override val MAX_HASH_BYTES: Int = 64
|
||||
|
||||
override suspend fun digest(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||
val sodium = JsSodiumLoader.load()
|
||||
val hashed = sodium.crypto_generichash(64, inputString)
|
||||
val hashed = getSodium().crypto_generichash(64, inputString)
|
||||
val hash = UByteArray(MAX_HASH_BYTES)
|
||||
for (i in 0 until MAX_HASH_BYTES) {
|
||||
js(
|
||||
@ -50,7 +47,21 @@ actual object Blake2bStateless : Blake2bStatelessInterface {
|
||||
)
|
||||
}
|
||||
println("Hash ${hash.toHexString()}")
|
||||
return ubyteArrayOf(0U)
|
||||
return hash
|
||||
}
|
||||
|
||||
fun digestBlocking(inputString: String, key: String?, hashLength: Int): UByteArray {
|
||||
val hashed = getSodium().crypto_generichash(hashLength, inputString)
|
||||
val hash = UByteArray(MAX_HASH_BYTES)
|
||||
for (i in 0 until MAX_HASH_BYTES) {
|
||||
js(
|
||||
"""
|
||||
hash[i] = hashed[i]
|
||||
"""
|
||||
)
|
||||
}
|
||||
println("Hash ${hash.toHexString()}")
|
||||
return hash
|
||||
}
|
||||
|
||||
override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@ -28,14 +30,15 @@ import kotlin.test.assertTrue
|
||||
class SRNGJsTest {
|
||||
|
||||
@Test
|
||||
fun testJsSrng() {
|
||||
fun testJsSrng() = testBlocking {
|
||||
JsSodiumLoader.load()
|
||||
val bytes1 = SRNG.getRandomBytes(10)
|
||||
val bytes2 = SRNG.getRandomBytes(10)
|
||||
println("BYTES1")
|
||||
println("BYTES1\n")
|
||||
bytes1.forEach {
|
||||
print(it.toString(16).padStart(2, '0'))
|
||||
}
|
||||
println("BYTES2")
|
||||
println("BYTES2\n")
|
||||
bytes2.forEach {
|
||||
print(it.toString(16).padStart(2, '0'))
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package com.ionspin.kotlin.crypto.hash.blake2b
|
||||
|
||||
import com.ionspin.kotlin.crypto.Crypto
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
@ -14,13 +16,21 @@ import kotlin.test.Test
|
||||
@ExperimentalStdlibApi
|
||||
class Blake2bJsTest {
|
||||
|
||||
@BeforeTest
|
||||
fun setup() = testBlocking {
|
||||
@Test
|
||||
fun testBlake2BSodiumInterop() = testBlocking {
|
||||
Crypto.initialize()
|
||||
val hash = Blake2bStateless.digest("test")
|
||||
assertEquals(hash.toHexString(), "a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a4" +
|
||||
"83aa9bc33b582f77d30a65e6f29a896c0411f38312e1d66e0bf16386c86a89bea572")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBlake2BSodiumInterop() = testBlocking {
|
||||
Blake2bStateless.digest("test")
|
||||
fun testBlake2BSodiumBlockingInterop() = testBlocking {
|
||||
Crypto.initialize()
|
||||
val hash = Blake2bStateless.digestBlocking("test", null, 64)
|
||||
assertEquals(hash.toHexString(), "a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a4" +
|
||||
"83aa9bc33b582f77d30a65e6f29a896c0411f38312e1d66e0bf16386c86a89bea572")
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user