Our sweet start

This commit is contained in:
Maria Chernova 2024-11-21 14:12:51 +03:00 committed by kildishevps
parent df86967662
commit d26ef0d41e
24 changed files with 2093 additions and 0 deletions

View File

@ -72,6 +72,20 @@ object Deps {
}
object wasmJs {
val stdLib = "stdlib-wasm"
val test = "test-wasm"
// TODO: написано от балды \/
// 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 libsodiumWrappers = Pair("libsodium-wrappers-sumo", "0.7.13")
}
}
object Jvm {
val stdLib = "stdlib-jdk8"
val test = "test"

View File

@ -92,6 +92,15 @@ kotlin {
runningOnLinuxx86_64 {
println("Configuring Linux X86-64 targets")
wasmJs {
browser {
testTask {
useKarma {
useChromeHeadless()
}
}
}
}
js {
browser {
@ -557,6 +566,19 @@ kotlin {
runningOnLinuxx86_64 {
println("Configuring Linux 64 Bit source sets")
val wasmJsMain by getting {
// TODO: разобраться (и с test)
dependencies {
implementation(kotlin(Deps.wasmJs.stdLib))
implementation(npm(Deps.wasmJs.Npm.libsodiumWrappers.first, Deps.wasmJs.Npm.libsodiumWrappers.second))
}
}
val wasmJsTest by getting {
dependencies {
implementation(kotlin(Deps.wasmJs.test))
implementation(npm(Deps.wasmJs.Npm.libsodiumWrappers.first, Deps.wasmJs.Npm.libsodiumWrappers.second))
}
}
val jsMain by getting {
dependencies {
@ -709,6 +731,14 @@ tasks {
// }
// }
// TODO: ваще не жс тест, помогите
val wasmJsBrowserTest by getting(KotlinJsTest::class) {
testLogging {
events("PASSED", "FAILED", "SKIPPED")
showStandardStreams = true
}
}
val jsBrowserTest by getting(KotlinJsTest::class) {
testLogging {
events("PASSED", "FAILED", "SKIPPED")

View File

@ -0,0 +1,367 @@
package ext.libsodium.com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.box.BoxKeyPair
import org.khronos.webgl.Uint8Array
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 27-May-2020
*/
@JsModule("libsodium-wrappers-sumo")
@JsNonModule
external object JsSodiumInterface {
@JsName("crypto_generichash")
fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array): Uint8Array
@JsName("crypto_hash_sha256")
fun crypto_hash_sha256(message: Uint8Array): Uint8Array
@JsName("crypto_hash_sha512")
fun crypto_hash_sha512(message: Uint8Array): Uint8Array
// ---- Generic hash ---- // Updateable
@JsName("crypto_generichash_init")
fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic
@JsName("crypto_generichash_update")
fun crypto_generichash_update(state: dynamic, inputMessage: Uint8Array)
@JsName("crypto_generichash_final")
fun crypto_generichash_final(state: dynamic, hashLength: Int) : Uint8Array
@JsName("crypto_generichash_keygen")
fun crypto_generichash_keygen() : Uint8Array
// ---- Generic hash end ---- // Updateable
// ---- Blake2b ----
@JsName("crypto_generichash_blake2b")
fun crypto_generichash_blake2b(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array): Uint8Array
@JsName("crypto_generichash_blake2b_init")
fun crypto_generichash_blake2b_init(key : Uint8Array, hashLength: Int) : dynamic
@JsName("crypto_generichash_blake2b_update")
fun crypto_generichash_blake2b_update(state: dynamic, inputMessage: Uint8Array)
@JsName("crypto_generichash_blake2b_final")
fun crypto_generichash_blake2b_final(state: dynamic, hashLength: Int) : Uint8Array
@JsName("crypto_generichash_blake2b_keygen")
fun crypto_generichash_blake2b_keygen() : Uint8Array
// ---- Blake2b end ----
// ---- Short hash ----
@JsName("crypto_shorthash")
fun crypto_shorthash(data : Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_shorthash_keygen")
fun crypto_shorthash_keygen() : Uint8Array
// ---- Short hash end ----
@JsName("crypto_hash_sha256_init")
fun crypto_hash_sha256_init() : dynamic
@JsName("crypto_hash_sha256_update")
fun crypto_hash_sha256_update(state: dynamic, message: Uint8Array)
@JsName("crypto_hash_sha256_final")
fun crypto_hash_sha256_final(state: dynamic): Uint8Array
@JsName("crypto_hash_sha512_init")
fun crypto_hash_sha512_init() : dynamic
@JsName("crypto_hash_sha512_update")
fun crypto_hash_sha512_update(state: dynamic, message: Uint8Array)
@JsName("crypto_hash_sha512_final")
fun crypto_hash_sha512_final(state: dynamic): Uint8Array
//XChaCha20Poly1305 - also in bindings
//fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
//fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
//XChaCha20Poly1305
//encrypt
@JsName("crypto_secretstream_xchacha20poly1305_init_push")
fun crypto_secretstream_xchacha20poly1305_init_push(key: Uint8Array) : dynamic
@JsName("crypto_secretstream_xchacha20poly1305_push")
fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, associatedData: Uint8Array, tag: UByte) : Uint8Array
//decrypt
@JsName("crypto_secretstream_xchacha20poly1305_init_pull")
fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic
@JsName("crypto_secretstream_xchacha20poly1305_pull")
fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, associatedData: Uint8Array) : dynamic
//keygen and rekey
@JsName("crypto_secretstream_xchacha20poly1305_keygen")
fun crypto_secretstream_xchacha20poly1305_keygen() : Uint8Array
@JsName("crypto_secretstream_xchacha20poly1305_rekey")
fun crypto_secretstream_xchacha20poly1305_rekey(state: dynamic)
// ---- SecretBox ----
@JsName("crypto_secretbox_detached")
fun crypto_secretbox_detached(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic
@JsName("crypto_secretbox_easy")
fun crypto_secretbox_easy(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_secretbox_keygen")
fun crypto_secretbox_keygen() : Uint8Array
@JsName("crypto_secretbox_open_detached")
fun crypto_secretbox_open_detached(ciphertext : Uint8Array, tag : Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic
@JsName("crypto_secretbox_open_easy")
fun crypto_secretbox_open_easy(ciphertext : Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic
// ---- SecretBox End ----
// ---- AEAD ----
@JsName("crypto_aead_chacha20poly1305_decrypt")
fun crypto_aead_chacha20poly1305_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_aead_chacha20poly1305_decrypt_detached")
fun crypto_aead_chacha20poly1305_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array
@JsName("crypto_aead_chacha20poly1305_encrypt")
fun crypto_aead_chacha20poly1305_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_aead_chacha20poly1305_encrypt_detached")
fun crypto_aead_chacha20poly1305_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic
@JsName("crypto_aead_chacha20poly1305_ietf_decrypt")
fun crypto_aead_chacha20poly1305_ietf_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_aead_chacha20poly1305_ietf_decrypt_detached")
fun crypto_aead_chacha20poly1305_ietf_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array
@JsName("crypto_aead_chacha20poly1305_ietf_encrypt")
fun crypto_aead_chacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_aead_chacha20poly1305_ietf_encrypt_detached")
fun crypto_aead_chacha20poly1305_ietf_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic
@JsName("crypto_aead_chacha20poly1305_ietf_keygen")
fun crypto_aead_chacha20poly1305_ietf_keygen() : Uint8Array
@JsName("crypto_aead_chacha20poly1305_keygen")
fun crypto_aead_chacha20poly1305_keygen() : Uint8Array
@JsName("crypto_aead_xchacha20poly1305_ietf_decrypt")
fun crypto_aead_xchacha20poly1305_ietf_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_aead_xchacha20poly1305_ietf_decrypt_detached")
fun crypto_aead_xchacha20poly1305_ietf_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array
@JsName("crypto_aead_xchacha20poly1305_ietf_encrypt")
fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_aead_xchacha20poly1305_ietf_encrypt_detached")
fun crypto_aead_xchacha20poly1305_ietf_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic
@JsName("crypto_aead_xchacha20poly1305_ietf_keygen")
fun crypto_aead_xchacha20poly1305_ietf_keygen(): Uint8Array
// ---- AEAD end ----
// ---- Auth ----
@JsName("crypto_auth")
fun crypto_auth(message: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_auth_keygen")
fun crypto_auth_keygen() : Uint8Array
@JsName("crypto_auth_verify")
fun crypto_auth_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean
@JsName("crypto_auth_hmacsha256")
fun crypto_auth_hmacsha256(message: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_auth_hmacsha256_keygen")
fun crypto_auth_hmacsha256_keygen() : Uint8Array
@JsName("crypto_auth_hmacsha256_verify")
fun crypto_auth_hmacsha256_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean
@JsName("crypto_auth_hmacsha512")
fun crypto_auth_hmacsha512(message: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_auth_hmacsha512_keygen")
fun crypto_auth_hmacsha512_keygen() : Uint8Array
@JsName("crypto_auth_hmacsha512_verify")
fun crypto_auth_hmacsha512_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean
// ---- Auth end ----
// ---- Box ----
@JsName("crypto_box_keypair")
fun crypto_box_keypair() : dynamic
@JsName("crypto_box_seed_keypair")
fun crypto_box_seed_keypair(seed : Uint8Array) : dynamic
@JsName("crypto_box_easy")
fun crypto_box_easy(message: Uint8Array,
nonce: Uint8Array,
recipientsPublicKey: Uint8Array,
sendersSecretKey: Uint8Array) : Uint8Array
@JsName("crypto_box_open_easy")
fun crypto_box_open_easy(ciphertext: Uint8Array,
nonce: Uint8Array,
sendersPublicKey: Uint8Array,
recipientsSecretKey: Uint8Array) : Uint8Array
@JsName("crypto_box_detached")
fun crypto_box_detached(message: Uint8Array,
nonce: Uint8Array,
recipientsPublicKey: Uint8Array,
sendersSecretKey: Uint8Array) : dynamic
@JsName("crypto_box_open_detached")
fun crypto_box_open_detached(ciphertext: Uint8Array,
tag: Uint8Array,
nonce: Uint8Array,
sendersPublicKey: Uint8Array,
recipientsSecretKey: Uint8Array) : Uint8Array
@JsName("crypto_box_beforenm")
fun crypto_box_beforenm(publicKey: Uint8Array, secretKey: Uint8Array) : Uint8Array
@JsName("crypto_box_easy_afternm")
fun crypto_box_easy_afternm(message: Uint8Array,
nonce: Uint8Array,
precomputedKey: Uint8Array) : Uint8Array
@JsName("crypto_box_open_easy_afternm")
fun crypto_box_open_easy_afternm(ciphertext: Uint8Array,
nonce: Uint8Array,
precomputedKey: Uint8Array) : Uint8Array
@JsName("crypto_box_seal")
fun crypto_box_seal(message: Uint8Array, recipientsPublicKey: Uint8Array) : Uint8Array
@JsName("crypto_box_seal_open")
fun crypto_box_seal_open(ciphertext: Uint8Array, recipientsPublicKey: Uint8Array, recipientsSecretKey: Uint8Array) : Uint8Array
// ---- Box end ----
// ---- Sign start ----
@JsName("crypto_sign")
fun crypto_sign(message: Uint8Array, secretKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_detached")
fun crypto_sign_detached(message: Uint8Array, secretKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_ed25519_pk_to_curve25519")
fun crypto_sign_ed25519_pk_to_curve25519(ed25519PublicKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_ed25519_sk_to_curve25519")
fun crypto_sign_ed25519_sk_to_curve25519(ed25519SecretKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_ed25519_sk_to_pk")
fun crypto_sign_ed25519_sk_to_pk(ed25519SecretKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_ed25519_sk_to_seed")
fun crypto_sign_ed25519_sk_to_seed(ed25519SecretKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_final_create")
fun crypto_sign_final_create(state: dynamic, secretKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_final_verify")
fun crypto_sign_final_verify(state: dynamic, signature: Uint8Array, publicKey: Uint8Array) : Boolean
@JsName("crypto_sign_init")
fun crypto_sign_init() : dynamic
@JsName("crypto_sign_keypair")
fun crypto_sign_keypair() : dynamic
@JsName("crypto_sign_open")
fun crypto_sign_open(signedMessage: Uint8Array, publicKey: Uint8Array) : Uint8Array
@JsName("crypto_sign_seed_keypair")
fun crypto_sign_seed_keypair(seed: Uint8Array) : dynamic
@JsName("crypto_sign_update")
fun crypto_sign_update(state: dynamic, message: Uint8Array)
@JsName("crypto_sign_verify_detached")
fun crypto_sign_verify_detached(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array) : Boolean
// ---- Sign end ----
// ---- KDF ----
@JsName("crypto_kdf_derive_from_key")
fun crypto_kdf_derive_from_key(subkey_len: UInt, subkeyId : UInt, ctx: String, key: Uint8Array) : Uint8Array
@JsName("crypto_kdf_keygen")
fun crypto_kdf_keygen() : Uint8Array
// ---- KDF end -----
// ---- Password hashing ----
@JsName("crypto_pwhash")
fun crypto_pwhash(keyLength : UInt, password : Uint8Array, salt: Uint8Array, opsLimit: UInt, memLimit: UInt, algorithm: UInt) : Uint8Array
@JsName("crypto_pwhash_str")
fun crypto_pwhash_str(password: Uint8Array, opsLimit: UInt, memLimit: UInt) : String
@JsName("crypto_pwhash_str_needs_rehash")
fun crypto_pwhash_str_needs_rehash(hashedPassword: String, opsLimit: UInt, memLimit: UInt) : Boolean
@JsName("crypto_pwhash_str_verify")
fun crypto_pwhash_str_verify(hashedPassword: String, password: Uint8Array) : Boolean
// ---- Password hashing end ----
// ---- Utils ----
@JsName("memcmp")
fun memcmp(first: Uint8Array, second: Uint8Array) : Boolean
@JsName("memzero")
fun memzero(data: Uint8Array)
@JsName("pad")
fun pad(data : Uint8Array, blocksize: Int) : Uint8Array
@JsName("unpad")
fun unpad(data: Uint8Array, blocksize: Int) : Uint8Array
@JsName("to_base64")
fun to_base64(data: Uint8Array, variant: Int) : String
@JsName("to_hex")
fun to_hex(data: Uint8Array) : String
@JsName("to_string")
fun to_string(data: Uint8Array) : String
@JsName("from_base64")
fun from_base64(data: String, variant: Int): Uint8Array
@JsName("from_hex")
fun from_hex(data : String): Uint8Array
@JsName("from_string")
fun from_string(data : String): Uint8Array
// ---- > ---- Random ---- < -----
@JsName("randombytes_buf")
fun randombytes_buf(length: Int) : Uint8Array
@JsName("randombytes_buf_deterministic")
fun randombytes_buf_deterministic(length: UInt, seed : Uint8Array) : Uint8Array
@JsName("randombytes_random")
fun randombytes_random() : UInt
@JsName("randombytes_uniform")
fun randombytes_uniform(upper_bound: UInt) : UInt
// ---- Utils end ----
// ---- Key exchange ----
@JsName("crypto_kx_client_session_keys")
fun crypto_kx_client_session_keys(clientPublicKey: Uint8Array, clientSecretKey: Uint8Array, serverPublicKey: Uint8Array) : dynamic
@JsName("crypto_kx_keypair")
fun crypto_kx_keypair() : dynamic
@JsName("crypto_kx_seed_keypair")
fun crypto_kx_seed_keypair(seed: Uint8Array) : dynamic
@JsName("crypto_kx_server_session_keys")
fun crypto_kx_server_session_keys(serverPublicKey: Uint8Array, serverSecretKey: Uint8Array, clientPublicKey: Uint8Array) : dynamic
// ---- Key exchange end ----
// -- Stream ----
@JsName("crypto_stream_chacha20")
fun crypto_stream_chacha20(outLength: UInt, key: Uint8Array, nonce: Uint8Array) : Uint8Array
@JsName("crypto_stream_chacha20_ietf_xor")
fun crypto_stream_chacha20_ietf_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_stream_chacha20_ietf_xor_ic")
fun crypto_stream_chacha20_ietf_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array
@JsName("crypto_stream_chacha20_keygen")
fun crypto_stream_chacha20_keygen() : Uint8Array
@JsName("crypto_stream_chacha20_xor")
fun crypto_stream_chacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_stream_chacha20_xor_ic")
fun crypto_stream_chacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array
@JsName("crypto_stream_xchacha20_keygen")
fun crypto_stream_xchacha20_keygen() : Uint8Array
@JsName("crypto_stream_xchacha20_xor")
fun crypto_stream_xchacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_stream_xchacha20_xor_ic")
fun crypto_stream_xchacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array
// ---- Stream end ----
// ---- Scalar multiplication ----
@JsName("crypto_scalarmult")
fun crypto_scalarmult(privateKey: Uint8Array, publicKey: Uint8Array) : Uint8Array
@JsName("crypto_scalarmult_base")
fun crypto_scalarmult_base(privateKey: Uint8Array) : Uint8Array
// ---- Scalar multiplication end ----
}

View File

@ -0,0 +1,55 @@
package ext.libsodium.com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.getSodiumLoaded
import com.ionspin.kotlin.crypto.sodiumLoaded
import ext.libsodium._libsodiumPromise
import ext.libsodium.crypto_generichash
import ext.libsodium.crypto_hash_sha256
import ext.libsodium.crypto_hash_sha256_init
import ext.libsodium.crypto_hash_sha512
import ext.libsodium.sodium_init
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)
}
}
suspend fun load() = suspendCoroutine { continuation ->
if (!getSodiumLoaded()) {
_libsodiumPromise.then<dynamic> {
sodium_init()
sodiumLoaded = true
continuation.resumeWith(Result.success(Unit))
}.catch { e ->
continuation.resumeWith(Result.failure(e))
}
} else {
continuation.resumeWith(Result.success(Unit))
}
}
fun loadWithCallback(doneCallback: () -> (Unit)) {
if (!getSodiumLoaded()) {
_libsodiumPromise.then<dynamic> {
sodium_init()
sodiumLoaded = true
doneCallback.invoke()
}
} else {
doneCallback.invoke()
}
}
}

View File

@ -0,0 +1,27 @@
package ext.libsodium.com.ionspin.kotlin.crypto
import org.khronos.webgl.Uint8Array
import org.khronos.webgl.get
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 02-Aug-2020
*/
fun UByteArray.toUInt8Array() : Uint8Array {
val uint8Result = Uint8Array(toByteArray().toTypedArray())
return uint8Result
}
fun Uint8Array.toUByteArray() : UByteArray {
if (length.asDynamic() == undefined) {
println("Error")
}
val result = UByteArray(length)
for (i in 0 until length) {
result[i] = get(i).toUByte()
}
return result
}

View File

@ -0,0 +1,36 @@
package com.ionspin.kotlin.crypto
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumInterface
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
var sodiumLoaded: Boolean = false
fun getSodium() : JsSodiumInterface = JsSodiumInterface
fun getSodiumLoaded() : Boolean = sodiumLoaded
fun setSodiumLoaded(loaded: Boolean) {
sodiumLoaded = loaded
}
actual object LibsodiumInitializer {
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,247 @@
package com.ionspin.kotlin.crypto.aead
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
actual object AuthenticatedEncryptionWithAssociatedData {
// Ietf
// Original chacha20poly1305
actual fun xChaCha20Poly1305IetfEncrypt(
message: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
return getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt(
message.toUInt8Array(),
associatedData.toUInt8Array(),
null,
nonce.toUInt8Array(),
key.toUInt8Array(),
).toUByteArray()
}
actual fun xChaCha20Poly1305IetfDecrypt(
ciphertextAndTag: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
return getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt(
null,
ciphertextAndTag.toUInt8Array(),
associatedData.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
} catch (error: Throwable) {
throw AeadCorrupedOrTamperedDataException()
}
}
actual fun xChaCha20Poly1305IetfEncryptDetached(
message: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): AeadEncryptedDataAndTag {
val result = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
message.toUInt8Array(),
associatedData.toUInt8Array(),
null,
nonce.toUInt8Array(),
key.toUInt8Array(),
)
return AeadEncryptedDataAndTag(
(result.ciphertext as Uint8Array).toUByteArray(),
(result.mac as Uint8Array).toUByteArray()
)
}
actual fun xChaCha20Poly1305IetfDecryptDetached(
ciphertext: UByteArray,
tag: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
return getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
null,
ciphertext.toUInt8Array(),
tag.toUInt8Array(),
associatedData.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
} catch (error: Throwable) {
throw AeadCorrupedOrTamperedDataException()
}
}
actual fun chaCha20Poly1305IetfEncrypt(
message: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
return getSodium().crypto_aead_chacha20poly1305_ietf_encrypt(
message.toUInt8Array(),
associatedData.toUInt8Array(),
null,
nonce.toUInt8Array(),
key.toUInt8Array(),
).toUByteArray()
}
actual fun chaCha20Poly1305IetfDecrypt(
ciphertextAndTag: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
return getSodium().crypto_aead_chacha20poly1305_ietf_decrypt(
null,
ciphertextAndTag.toUInt8Array(),
associatedData.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
} catch (error: Throwable) {
throw AeadCorrupedOrTamperedDataException()
}
}
actual fun chaCha20Poly1305IetfEncryptDetached(
message: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): AeadEncryptedDataAndTag {
val result = getSodium().crypto_aead_chacha20poly1305_ietf_encrypt_detached(
message.toUInt8Array(),
associatedData.toUInt8Array(),
null,
nonce.toUInt8Array(),
key.toUInt8Array(),
)
return AeadEncryptedDataAndTag(
(result.ciphertext as Uint8Array).toUByteArray(),
(result.mac as Uint8Array).toUByteArray()
)
}
actual fun chaCha20Poly1305IetfDecryptDetached(
ciphertext: UByteArray,
tag: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
return getSodium().crypto_aead_chacha20poly1305_ietf_decrypt_detached(
null,
ciphertext.toUInt8Array(),
tag.toUInt8Array(),
associatedData.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
} catch (error: Throwable) {
throw AeadCorrupedOrTamperedDataException()
}
}
actual fun chaCha20Poly1305Encrypt(
message: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
return getSodium().crypto_aead_chacha20poly1305_encrypt(
message.toUInt8Array(),
associatedData.toUInt8Array(),
null,
nonce.toUInt8Array(),
key.toUInt8Array(),
).toUByteArray()
}
actual fun chaCha20Poly1305Decrypt(
ciphertextAndTag: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
return getSodium().crypto_aead_chacha20poly1305_decrypt(
null,
ciphertextAndTag.toUInt8Array(),
associatedData.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
} catch (error: Throwable) {
throw AeadCorrupedOrTamperedDataException()
}
}
actual fun chaCha20Poly1305EncryptDetached(
message: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): AeadEncryptedDataAndTag {
val result = getSodium().crypto_aead_chacha20poly1305_encrypt_detached(
message.toUInt8Array(),
associatedData.toUInt8Array(),
null,
nonce.toUInt8Array(),
key.toUInt8Array(),
)
return AeadEncryptedDataAndTag(
(result.ciphertext as Uint8Array).toUByteArray(),
(result.mac as Uint8Array).toUByteArray()
)
}
actual fun chaCha20Poly1305DecryptDetached(
ciphertext: UByteArray,
tag: UByteArray,
associatedData: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
return getSodium().crypto_aead_chacha20poly1305_decrypt_detached(
null,
ciphertext.toUInt8Array(),
tag.toUInt8Array(),
associatedData.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
} catch (error: Throwable) {
throw AeadCorrupedOrTamperedDataException()
}
}
actual fun xChaCha20Poly1305IetfKeygen(): UByteArray {
return getSodium().crypto_aead_xchacha20poly1305_ietf_keygen().toUByteArray()
}
actual fun chaCha20Poly1305IetfKeygen(): UByteArray {
return getSodium().crypto_aead_chacha20poly1305_ietf_keygen().toUByteArray()
}
actual fun chaCha20Poly1305Keygen(): UByteArray {
return getSodium().crypto_aead_chacha20poly1305_keygen().toUByteArray()
}
}

View File

@ -0,0 +1,74 @@
package com.ionspin.kotlin.crypto.auth
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object Auth {
actual fun authKeygen(): UByteArray {
return getSodium().crypto_auth_keygen().toUByteArray()
}
actual fun auth(message: UByteArray, key: UByteArray): UByteArray {
return getSodium().crypto_auth(
message.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
}
actual fun authVerify(tag: UByteArray, message: UByteArray, key: UByteArray): Boolean {
return getSodium().crypto_auth_verify(
tag.toUInt8Array(),
message.toUInt8Array(),
key.toUInt8Array()
)
}
actual fun authHmacSha256Keygen(): UByteArray {
return getSodium().crypto_auth_hmacsha256_keygen().toUByteArray()
}
actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray {
return getSodium().crypto_auth_hmacsha256(
message.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
}
actual fun authHmacSha256Verify(
tag: UByteArray,
message: UByteArray,
key: UByteArray
): Boolean {
return getSodium().crypto_auth_hmacsha256_verify(
tag.toUInt8Array(),
message.toUInt8Array(),
key.toUInt8Array()
)
}
actual fun authHmacSha512Keygen(): UByteArray {
return getSodium().crypto_auth_hmacsha512_keygen().toUByteArray()
}
actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray {
return getSodium().crypto_auth_hmacsha512(
message.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
}
actual fun authHmacSha512Verify(
tag: UByteArray,
message: UByteArray,
key: UByteArray
): Boolean {
return getSodium().crypto_auth_hmacsha512_verify(
tag.toUInt8Array(),
message.toUInt8Array(),
key.toUInt8Array()
)
}
}

View File

@ -0,0 +1,200 @@
package com.ionspin.kotlin.crypto.box
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
actual object Box {
/**
* The crypto_box_keypair() function randomly generates a secret key and a corresponding public key.
* The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into
* sk (crypto_box_SECRETKEYBYTES bytes).
*/
actual fun keypair(): BoxKeyPair {
val keypair = getSodium().crypto_box_keypair()
return BoxKeyPair(
(keypair.publicKey as Uint8Array).toUByteArray(),
(keypair.privateKey as Uint8Array).toUByteArray()
)
}
/**
* Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes).
*/
actual fun seedKeypair(seed: UByteArray): BoxKeyPair {
val keypair = getSodium().crypto_box_seed_keypair(seed.toUInt8Array())
return BoxKeyPair(
(keypair.publicKey as Uint8Array).toUByteArray(),
(keypair.privateKey as Uint8Array).toUByteArray()
)
}
/**
* The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n.
* n should be crypto_box_NONCEBYTES bytes.
* c should be at least crypto_box_MACBYTES + mlen bytes long.
* This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c,
* immediately followed by the encrypted message, whose length is the same as the plaintext: mlen.
*/
actual fun easy(
message: UByteArray,
nonce: UByteArray,
recipientsPublicKey: UByteArray,
sendersSecretKey: UByteArray
): UByteArray {
return getSodium().crypto_box_easy(
message.toUInt8Array(),
nonce.toUInt8Array(),
recipientsPublicKey.toUInt8Array(),
sendersSecretKey.toUInt8Array(),
).toUByteArray()
}
/**
* The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy().
* c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message.
* The nonce n has to match the nonce used to encrypt and authenticate the message.
* pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it.
* The function throws [BoxCorruptedOrTamperedDataException] if the verification fails.
*/
actual fun openEasy(
ciphertext: UByteArray,
nonce: UByteArray,
sendersPublicKey: UByteArray,
recipientsSecretKey: UByteArray
): UByteArray {
try {
return getSodium().crypto_box_open_easy(
ciphertext.toUInt8Array(),
nonce.toUInt8Array(),
sendersPublicKey.toUInt8Array(),
recipientsSecretKey.toUInt8Array(),
).toUByteArray()
} catch (error: Throwable) {
throw BoxCorruptedOrTamperedDataException()
}
}
/**
* The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk,
* and puts it into k (crypto_box_BEFORENMBYTES bytes).
*/
actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray {
return getSodium().crypto_box_beforenm(
publicKey.toUInt8Array(),
secretKey.toUInt8Array()
).toUByteArray()
}
/**
* The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair.
*/
actual fun easyAfterNM(
message: UByteArray,
nonce: UByteArray,
precomputedKey: UByteArray
): UByteArray {
return getSodium().crypto_box_easy_afternm(
message.toUInt8Array(),
nonce.toUInt8Array(),
precomputedKey.toUInt8Array()
).toUByteArray()
}
/**
* The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair.
*/
actual fun openEasyAfterNM(
ciphertext: UByteArray,
nonce: UByteArray,
precomputedKey: UByteArray
): UByteArray {
try {
return getSodium().crypto_box_open_easy_afternm(
ciphertext.toUInt8Array(),
nonce.toUInt8Array(),
precomputedKey.toUInt8Array(),
).toUByteArray()
} catch (error: Throwable) {
throw BoxCorruptedOrTamperedDataException()
}
}
/**
* This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose
* public key is pk, and puts the encrypted message into c.
* Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag.
* The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac.
*/
actual fun detached(
message: UByteArray,
nonce: UByteArray,
recipientsPublicKey: UByteArray,
sendersSecretKey: UByteArray
): BoxEncryptedDataAndTag {
val detached = getSodium().crypto_box_detached(
message.toUInt8Array(),
nonce.toUInt8Array(),
recipientsPublicKey.toUInt8Array(),
sendersSecretKey.toUInt8Array(),
)
return BoxEncryptedDataAndTag(
(detached.ciphertext as Uint8Array).toUByteArray(),
(detached.mac as Uint8Array).toUByteArray()
)
}
/**
* The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk.
* clen doesn't include the tag, so this length is the same as the plaintext.
* The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k.
* The function throws [BoxCorruptedOrTamperedDataException] if the verification fails.
*/
actual fun openDetached(
ciphertext: UByteArray,
tag: UByteArray,
nonce: UByteArray,
sendersPublicKey: UByteArray,
recipientsSecretKey: UByteArray
): UByteArray {
try {
return getSodium().crypto_box_open_detached(
ciphertext.toUInt8Array(),
tag.toUInt8Array(),
nonce.toUInt8Array(),
sendersPublicKey.toUInt8Array(),
recipientsSecretKey.toUInt8Array(),
).toUByteArray()
} catch (error: Throwable) {
throw BoxCorruptedOrTamperedDataException()
}
}
actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray {
return getSodium().crypto_box_seal(
message.toUInt8Array(),
recipientsPublicKey.toUInt8Array()
).toUByteArray()
}
actual fun sealOpen(
ciphertext: UByteArray,
recipientsPublicKey: UByteArray,
recipientsSecretKey: UByteArray
): UByteArray {
try {
return getSodium().crypto_box_seal_open(
ciphertext.toUInt8Array(),
recipientsPublicKey.toUInt8Array(),
recipientsSecretKey.toUInt8Array(),
).toUByteArray()
} catch (error: Throwable) {
throw BoxCorruptedOrTamperedDataException()
}
}
}

View File

@ -0,0 +1,82 @@
package com.ionspin.kotlin.crypto.generichash
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 21-Aug-2020
*/
actual typealias GenericHashStateInternal = Any
actual object GenericHash {
actual fun genericHash(
message: UByteArray,
requestedHashLength: Int,
key: UByteArray?
): UByteArray {
return getSodium().crypto_generichash(
requestedHashLength,
message.toUInt8Array(),
key?.toUInt8Array() ?: Uint8Array(0)
).toUByteArray()
}
actual fun genericHashInit(
requestedHashLength: Int,
key: UByteArray?
): GenericHashState {
val state = getSodium().crypto_generichash_init(key?.toUInt8Array() ?: Uint8Array(0), requestedHashLength)
return GenericHashState(requestedHashLength, state)
}
actual fun genericHashUpdate(
state: GenericHashState,
messagePart: UByteArray
) {
getSodium().crypto_generichash_update(state.internalState, messagePart.toUInt8Array())
}
actual fun genericHashFinal(state: GenericHashState): UByteArray {
return getSodium().crypto_generichash_final(state.internalState, state.hashLength).toUByteArray()
}
actual fun genericHashKeygen(): UByteArray {
return getSodium().crypto_generichash_keygen().toUByteArray()
}
// -- Not present in LazySodium nor libsodium.js
// actual fun blake2b(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray {
// return getSodium().crypto_generichash_blake2b(
// requestedHashLength,
// message.toUInt8Array(),
// key?.toUInt8Array() ?: Uint8Array(0)
// ).toUByteArray()
// }
//
// actual fun blake2bInit(
// requestedHashLength: Int,
// key: UByteArray?
// ): Blake2bState {
// val state = getSodium().crypto_generichash_blake2b_init(key?.toUInt8Array() ?: Uint8Array(0), requestedHashLength)
// return Blake2bState(requestedHashLength, state)
// }
//
// actual fun blake2bUpdate(
// state: GenericHashState,
// messagePart: UByteArray
// ) {
// getSodium().crypto_generichash_blake2b_update(state.internalState, messagePart.toUInt8Array())
// }
//
// actual fun blake2bFinal(state: GenericHashState): UByteArray {
// return getSodium().crypto_generichash_blake2b_final(state.internalState, state.hashLength).toUByteArray()
// }
//
// actual fun blake2bKeygen(): UByteArray {
// return getSodium().crypto_generichash_blake2b_keygen().toUByteArray()
// }
}

View File

@ -0,0 +1,45 @@
package com.ionspin.kotlin.crypto.hash
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual typealias Sha256State = Any
actual typealias Sha512State = Any
actual object Hash {
actual fun sha256(data: UByteArray): UByteArray {
return getSodium().crypto_hash_sha256(data.toUInt8Array()).toUByteArray()
}
actual fun sha256Init(): Sha256State {
return getSodium().crypto_hash_sha256_init()
}
actual fun sha256Update(state: Sha256State, data: UByteArray) {
getSodium().crypto_hash_sha256_update(state, data.toUInt8Array())
}
actual fun sha256Final(state: Sha256State): UByteArray {
return getSodium().crypto_hash_sha256_final(state).toUByteArray()
}
actual fun sha512(data: UByteArray): UByteArray {
return getSodium().crypto_hash_sha512(data.toUInt8Array()).toUByteArray()
}
actual fun sha512Init(): Sha512State {
return getSodium().crypto_hash_sha512_init()
}
actual fun sha512Update(state: Sha512State, data: UByteArray) {
getSodium().crypto_hash_sha512_update(state, data.toUInt8Array())
}
actual fun sha512Final(state: Sha512State): UByteArray {
return getSodium().crypto_hash_sha512_final(state).toUByteArray()
}
}

View File

@ -0,0 +1,43 @@
package com.ionspin.kotlin.crypto.kdf
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object Kdf {
/**
* The deriveFromKey function derives a subkeyId-th subkey of length subkeyLenght bytes using
* the master key key and the context ctx.
* subkey_id can be any value up to (2^32) because javascript doesn't support long types.
* subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive).
* Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for.
* Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but
* in two distinct contexts is likely to generate two different outputs.
* Contexts don't have to be secret and can have a low entropy.
* Examples of contexts include UserName, __auth__, pictures and userdata.
* They must be crypto_kdf_CONTEXTBYTES bytes long.
* If more convenient, it is also fine to use a single global context for a whole application. This will still
* prevent the same keys from being mistakenly used by another application.
*/
actual fun deriveFromKey(
subkeyId: UInt,
subkeyLength: Int,
context: String,
masterKey: UByteArray
): UByteArray {
return getSodium().crypto_kdf_derive_from_key(
subkeyLength.toUInt(),
subkeyId,
context,
masterKey.toUInt8Array()
).toUByteArray()
}
/**
* The crypto_kdf_keygen() function creates a master key.
*/
actual fun keygen(): UByteArray {
return getSodium().crypto_kdf_keygen().toUByteArray()
}
}

View File

@ -0,0 +1,57 @@
package com.ionspin.kotlin.crypto.keyexchange
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
actual object KeyExchange {
actual fun clientSessionKeys(clientPublicKey: UByteArray, clientSecretKey: UByteArray, serverPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
val result = getSodium().crypto_kx_client_session_keys(
clientPublicKey.toUInt8Array(),
clientSecretKey.toUInt8Array(),
serverPublicKey.toUInt8Array()
)
val receiveKey = (result.sharedRx as Uint8Array).toUByteArray()
val sendKey = (result.sharedTx as Uint8Array).toUByteArray()
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
}
actual fun keypair() : KeyExchangeKeyPair {
val result = getSodium().crypto_kx_keypair()
val publicKey = (result.publicKey as Uint8Array).toUByteArray()
val secretKey = (result.privateKey as Uint8Array).toUByteArray()
return KeyExchangeKeyPair(publicKey, secretKey)
}
actual fun seedKeypair(seed: UByteArray) : KeyExchangeKeyPair {
val result = getSodium().crypto_kx_seed_keypair(seed.toUInt8Array())
val publicKey = (result.publicKey as Uint8Array).toUByteArray()
val secretKey = (result.privateKey as Uint8Array).toUByteArray()
return KeyExchangeKeyPair(publicKey, secretKey)
}
actual fun serverSessionKeys(serverPublicKey: UByteArray, serverSecretKey: UByteArray, clientPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
val result = getSodium().crypto_kx_server_session_keys(
serverPublicKey.toUInt8Array(),
serverSecretKey.toUInt8Array(),
clientPublicKey.toUInt8Array()
)
val receiveKey = (result.sharedRx as Uint8Array).toUByteArray()
val sendKey = (result.sharedTx as Uint8Array).toUByteArray()
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
}
}

View File

@ -0,0 +1,98 @@
package com.ionspin.kotlin.crypto.pwhash
import com.ionspin.kotlin.crypto.getSodium
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object PasswordHash {
/**
* The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen
* and a salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_
* PASSWD_MIN and crypto_pwhash_PASSWD_MAX. outlen should be at least crypto_pwhash_BYTES_MIN = 16 (128 bits) and
* at most crypto_pwhash_BYTES_MAX.
*
* See https://libsodium.gitbook.io/doc/password_hashing/default_phf for more details
*/
actual fun pwhash(
outputLength: Int,
password: String,
salt: UByteArray,
opsLimit: ULong,
memLimit: Int,
algorithm: Int
): UByteArray {
if (opsLimit > UInt.MAX_VALUE) {
throw RuntimeException("Javascript doesnt support more than ${UInt.MAX_VALUE} for opslimit")
}
return getSodium().crypto_pwhash(
outputLength.toUInt(),
password.encodeToUByteArray().toUInt8Array(),
salt.toUInt8Array(),
opsLimit.toUInt(),
memLimit.toUInt(),
algorithm.toUInt()
).toUByteArray()
}
/**
* The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes:
* the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen
* the automatically generated salt used for the previous computation
* the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit.
* out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter.
* The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases
* and other data stores. No extra information has to be stored in order to verify the password.
* The function returns 0 on success and -1 if it didn't complete successfully.
*/
actual fun str(password: String, opslimit: ULong, memlimit: Int): String {
if (opslimit > UInt.MAX_VALUE) {
throw RuntimeException("Javascript doesnt support more than ${UInt.MAX_VALUE} for opslimit")
}
return getSodium().crypto_pwhash_str(
password.encodeToUByteArray().toUInt8Array(),
opslimit.toUInt(),
memlimit.toUInt()
)
}
/**
* Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm.
* The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in.
* The function returns 0 if the parameters already match the given ones.
* It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in.
*/
actual fun strNeedsRehash(
passwordHash: String,
opslimit: ULong,
memlimit: Int
): Int {
if (opslimit > UInt.MAX_VALUE) {
throw RuntimeException("Javascript doesnt support more than ${UInt.MAX_VALUE} for opslimit")
}
return if (
getSodium().crypto_pwhash_str_needs_rehash(
passwordHash,
opslimit.toUInt(),
memlimit.toUInt()
)
) {
1
} else {
0
}
}
/**
* his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen.
* str has to be zero-terminated.
* It returns 0 if the verification succeeds, and -1 on error.
*/
actual fun strVerify(passwordHash: String, password: String): Boolean {
return getSodium().crypto_pwhash_str_verify(
passwordHash,
password.encodeToUByteArray().toUInt8Array()
)
}
}

View File

@ -0,0 +1,40 @@
package com.ionspin.kotlin.crypto.scalarmult
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object ScalarMultiplication {
/**
* This function can be used to compute a shared secret q given a user's secret key and another user's public key.
* n is crypto_scalarmult_SCALARBYTES bytes long, p and the output are crypto_scalarmult_BYTES bytes long.
* q represents the X coordinate of a point on the curve. As a result, the number of possible keys is limited to
* the group size (2^252), which is smaller than the key space.
* For this reason, and to mitigate subtle attacks due to the fact many (p, n) pairs produce the same result,
* using the output of the multiplication q directly as a shared key is not recommended.
* A better way to compute a shared key is h(q pk1 pk2), with pk1 and pk2 being the public keys.
* By doing so, each party can prove what exact public key they intended to perform a key exchange with
* (for a given public key, 11 other public keys producing the same shared secret can be trivially computed).
* This can be achieved with the following code snippet:
*/
actual fun scalarMultiplication(secretKeyN: UByteArray, publicKeyP: UByteArray): UByteArray {
val result = getSodium().crypto_scalarmult(secretKeyN.toUInt8Array(), publicKeyP.toUInt8Array())
return result.toUByteArray()
}
/**
* Given a user's secret key n (crypto_scalarmult_SCALARBYTES bytes), the crypto_scalarmult_base() function
* computes the user's public key and puts it into q (crypto_scalarmult_BYTES bytes).
* crypto_scalarmult_BYTES and crypto_scalarmult_SCALARBYTES are provided for consistency,
* but it is safe to assume that crypto_scalarmult_BYTES == crypto_scalarmult_SCALARBYTES.
*/
actual fun scalarMultiplicationBase(
secretKeyN: UByteArray
): UByteArray {
val result = getSodium().crypto_scalarmult_base( secretKeyN.toUInt8Array())
return result.toUByteArray()
}
}

View File

@ -0,0 +1,74 @@
package com.ionspin.kotlin.crypto.secretbox
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
actual object SecretBox {
actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray {
return getSodium().crypto_secretbox_easy(
message.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
).toUByteArray()
}
actual fun openEasy(
ciphertext: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
val decryptionResult = getSodium().crypto_secretbox_open_easy(
ciphertext.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return (decryptionResult as Uint8Array).toUByteArray()
} catch (error: Throwable) {
throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey()
}
}
actual fun detached(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): SecretBoxEncryptedDataAndTag {
val result = getSodium().crypto_secretbox_detached(
message.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return SecretBoxEncryptedDataAndTag(
(result.cipher as Uint8Array).toUByteArray(),
(result.mac as Uint8Array).toUByteArray()
)
}
actual fun openDetached(
ciphertext: UByteArray,
tag: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
try {
val decryptionResult = getSodium().crypto_secretbox_open_detached(
ciphertext.toUInt8Array(),
tag.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return (decryptionResult as Uint8Array).toUByteArray()
} catch (error: Throwable) {
throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey()
}
}
actual fun keygen(): UByteArray {
return getSodium().crypto_secretbox_keygen().toUByteArray()
}
}

View File

@ -0,0 +1,58 @@
package com.ionspin.kotlin.crypto.secretstream
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
actual typealias SecretStreamState = Any
actual object SecretStream {
actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader {
val state = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array())
return SecretStreamStateAndHeader(state.state, (state.header as Uint8Array).toUByteArray())
}
actual fun xChaCha20Poly1305Push(
state: SecretStreamState,
message: UByteArray,
associatedData: UByteArray,
tag: UByte
): UByteArray {
return getSodium().crypto_secretstream_xchacha20poly1305_push(
state, message.toUInt8Array(), associatedData.toUInt8Array(), tag
).toUByteArray()
}
actual fun xChaCha20Poly1305InitPull(
key: UByteArray,
header: UByteArray
): SecretStreamStateAndHeader {
val state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), key.toUInt8Array())
return SecretStreamStateAndHeader(state, header)
}
actual fun xChaCha20Poly1305Pull(
state: SecretStreamState,
ciphertext: UByteArray,
associatedData: UByteArray
): DecryptedDataAndTag {
val dataAndTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(
state, ciphertext.toUInt8Array(), associatedData.toUInt8Array()
)
if (dataAndTag == false) {
throw SecretStreamCorruptedOrTamperedDataException()
}
return DecryptedDataAndTag((dataAndTag.message as Uint8Array).toUByteArray(), dataAndTag.tag)
}
actual fun xChaCha20Poly1305Keygen(): UByteArray {
return getSodium().crypto_shorthash_keygen().toUByteArray()
}
actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) {
getSodium().crypto_secretstream_xchacha20poly1305_rekey(state)
}
}

View File

@ -0,0 +1,21 @@
package com.ionspin.kotlin.crypto.shortinputhash
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 21-Aug-2020
*/
actual object ShortHash {
actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray {
return getSodium().crypto_shorthash(data.toUInt8Array(), key.toUInt8Array()).toUByteArray()
}
actual fun shortHashKeygen(): UByteArray {
return getSodium().crypto_shorthash_keygen().toUByteArray()
}
}

View File

@ -0,0 +1,161 @@
package com.ionspin.kotlin.crypto.signature
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array
actual typealias SignatureState = Any
actual object Signature {
actual fun init(): SignatureState {
return getSodium().crypto_sign_init()
}
actual fun update(state: SignatureState, data: UByteArray) {
getSodium().crypto_sign_update(state, data.toUInt8Array())
}
actual fun finalCreate(
state: SignatureState,
secretKey: UByteArray
): UByteArray {
return getSodium().crypto_sign_final_create(
state,
secretKey.toUInt8Array()
).toUByteArray()
}
actual fun finalVerify(
state: SignatureState,
signature: UByteArray,
publicKey: UByteArray
) {
val verificationResult = getSodium().crypto_sign_final_verify(
state,
signature.toUInt8Array(),
publicKey.toUInt8Array()
)
if (verificationResult == false) {
throw InvalidSignatureException()
}
}
/**
* The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key.
* The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes).
*/
actual fun keypair(): SignatureKeyPair {
val keypair = getSodium().crypto_sign_keypair()
return SignatureKeyPair(
(keypair.publicKey as Uint8Array).toUByteArray(),
(keypair.privateKey as Uint8Array).toUByteArray()
)
}
/**
* The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key.
* The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes).
* Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes).
*/
actual fun seedKeypair(seed: UByteArray): SignatureKeyPair {
val keypair = getSodium().crypto_sign_seed_keypair(seed.toUInt8Array())
return SignatureKeyPair(
(keypair.publicKey as Uint8Array).toUByteArray(),
(keypair.privateKey as Uint8Array).toUByteArray()
)
}
/**
* The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk.
* The signed message, which includes the signature + a plain copy of the message, is put into sm, and is crypto_sign_BYTES + mlen bytes long.
*/
actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray {
return getSodium().crypto_sign(
message.toUInt8Array(),
secretKey.toUInt8Array()
).toUByteArray()
}
/**
* The crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk.
* If the signature is doesn't appear to be valid, the function throws an exception
*/
actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray {
try {
return getSodium().crypto_sign_open(
signedMessage.toUInt8Array(),
publicKey.toUInt8Array()
).toUByteArray()
} catch (error : Throwable) {
throw InvalidSignatureException()
}
}
/**
* In detached mode, the signature is stored without attaching a copy of the original message to it.
* The crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk,
* and puts the signature into sig, which can be up to crypto_sign_BYTES bytes long.
*/
actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray {
return getSodium().crypto_sign_detached(
message.toUInt8Array(),
secretKey.toUInt8Array()
).toUByteArray()
}
/**
* The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length
* is mlen bytes, using the signer's public key pk.
*/
actual fun verifyDetached(signature: UByteArray, message: UByteArray, publicKey: UByteArray) {
val verificationResult = getSodium().crypto_sign_verify_detached(
signature.toUInt8Array(),
message.toUInt8Array(),
publicKey.toUInt8Array()
)
if (verificationResult == false) {
throw InvalidSignatureException()
}
}
/**
* The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk.
*/
actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray): UByteArray {
return getSodium().crypto_sign_ed25519_pk_to_curve25519(
ed25519PublicKey.toUInt8Array()
).toUByteArray()
}
/**
* The crypto_sign_ed25519_sk_to_curve25519() function converts an Ed25519 secret key ed25519_sk to an X25519 secret key and stores it into x25519_sk.
*/
actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray): UByteArray {
return getSodium().crypto_sign_ed25519_sk_to_curve25519(
ed25519SecretKey.toUInt8Array()
).toUByteArray()
}
/**
* The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key.
* While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.
*/
actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray {
return getSodium().crypto_sign_ed25519_sk_to_seed(
secretKey.toUInt8Array()
).toUByteArray()
}
/**
* The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key.
* While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.
*/
actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray {
return getSodium().crypto_sign_ed25519_sk_to_pk(
secretKey.toUInt8Array()
).toUByteArray()
}
}

View File

@ -0,0 +1,122 @@
package com.ionspin.kotlin.crypto.stream
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object Stream {
actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
//Note, unlike the other ones, here the positions of key and nonce are reversed.
val result = getSodium().crypto_stream_chacha20(clen.toUInt(), key.toUInt8Array(), nonce.toUInt8Array())
return result.toUByteArray()
}
actual fun chacha20IetfXor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_chacha20_ietf_xor(
message.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return result.toUByteArray()
}
actual fun chacha20IetfXorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: UInt,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_chacha20_ietf_xor_ic(
message.toUInt8Array(),
nonce.toUInt8Array(),
initialCounter,
key.toUInt8Array()
)
return result.toUByteArray()
}
actual fun chacha20Keygen(): UByteArray {
val result = getSodium().crypto_stream_chacha20_keygen()
return result.toUByteArray()
}
actual fun chacha20Xor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_chacha20_xor(
message.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return result.toUByteArray()
}
actual fun chacha20XorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
if (initialCounter > UInt.MAX_VALUE) {
throw RuntimeException("Javascript doesnt support more than ${UInt.MAX_VALUE} for initial counter")
}
val result = getSodium().crypto_stream_chacha20_xor_ic(
message.toUInt8Array(),
nonce.toUInt8Array(),
initialCounter.toUInt(),
key.toUInt8Array()
)
return result.toUByteArray()
}
// actual fun xChacha20Keygen(): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_keygen()
//
// return result.toUByteArray()
// }
//
// actual fun xChacha20Xor(
// message: UByteArray,
// nonce: UByteArray,
// key: UByteArray
// ): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_xor(
// message.toUInt8Array(),
// nonce.toUInt8Array(),
// key.toUInt8Array()
// )
//
// return result.toUByteArray()
// }
//
// actual fun xChacha20XorIc(
// message: UByteArray,
// nonce: UByteArray,
// initialCounter: ULong,
// key: UByteArray
// ): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_xor_ic(
// message.toUInt8Array(),
// nonce.toUInt8Array(),
// initialCounter.toUInt(),
// key.toUInt8Array()
// )
//
// return result.toUByteArray()
// }
}

View File

@ -0,0 +1,48 @@
package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 27-Sep-2020
*/
actual object LibsodiumRandom {
/**
* The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes.
*/
actual fun buf(size: Int): UByteArray {
return getSodium().randombytes_buf(size).toUByteArray()
}
/**
* The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed.
* For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays
* and they are limited by Int primitive type
* seed is randombytes_SEEDBYTES bytes long.
* This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher.
*
*/
actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray {
return getSodium().randombytes_buf_deterministic(size.toUInt(), seed.toUInt8Array()).toUByteArray()
}
/**
* The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included).
*/
actual fun random(): UInt {
return getSodium().randombytes_random()
}
/**
* The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r
* andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when
* upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0
*/
actual fun uniform(upperBound: UInt): UInt {
return getSodium().randombytes_uniform(upperBound)
}
}

View File

@ -0,0 +1,50 @@
package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object LibsodiumUtil {
actual fun memcmp(first: UByteArray, second: UByteArray): Boolean {
return getSodium().memcmp(first.toUInt8Array(), second.toUInt8Array())
}
actual fun memzero(target: UByteArray) {
// libsodium.js does this as well, and theres no clear way at the moment of casting ubytearray to uint8array
// although I feel like there should be a way to work around it
(target.indices).forEach {
index -> target[index] = 0U
}
}
actual fun pad(unpaddedData: UByteArray, blocksize: Int): UByteArray {
return getSodium().pad(unpaddedData.toUInt8Array(), blocksize).toUByteArray()
}
actual fun unpad(paddedData: UByteArray, blocksize: Int): UByteArray {
return getSodium().unpad(paddedData.toUInt8Array(), blocksize).toUByteArray()
}
actual fun toBase64(
data: UByteArray,
variant: Base64Variants
): String {
return getSodium().to_base64(data.toUInt8Array(), variant.value)
}
actual fun toHex(data: UByteArray): String {
return getSodium().to_hex(data.toUInt8Array())
}
actual fun fromBase64(
data: String,
variant: Base64Variants
): UByteArray {
return getSodium().from_base64(data, variant.value).toUByteArray()
}
actual fun fromHex(data: String): UByteArray {
return getSodium().from_hex(data).toUByteArray()
}
}

View File

@ -0,0 +1,113 @@
//package debug.test
//
//import com.ionspin.kotlin.crypto.getSodium
//import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
//import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
//import kotlin.Any
//import kotlin.Int
//import kotlin.UByte
//import kotlin.UByteArray
//import org.khronos.webgl.Uint8Array
//
//actual typealias Sha256State = Any
//
//actual typealias Sha512State = Any
//
//actual typealias GenericHashState = Any
//
//actual typealias SecretStreamState = Any
//
//actual class Crypto internal actual constructor() {
// /**
// * Initialize the SHA256 hash
// * returns sha 256 state
// */
// actual fun crypto_hash_sha256_init(): dynamic {
// println("Debug crypto_hash_sha256_init")
// val result = js("getSodium().crypto_hash_sha256_init()")
// return result
// }
//
// actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
// println("Debug crypto_hash_sha256_update")
// getSodium().crypto_hash_sha256_update(state, input.toUInt8Array())
// }
//
// actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray {
// println("Debug crypto_hash_sha256_final")
// return getSodium().crypto_hash_sha256_final(state).toUByteArray()
// }
//
// actual fun crypto_hash_sha512_init(): dynamic {
// println("Debug crypto_hash_sha512_init")
// val result = js("getSodium().crypto_hash_sha512_init()")
// return result
// }
//
// actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
// println("Debug crypto_hash_sha512_update")
// getSodium().crypto_hash_sha512_update(state, input.toUInt8Array())
// }
//
// actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray {
// println("Debug crypto_hash_sha512_final")
// return getSodium().crypto_hash_sha512_final(state).toUByteArray()
// }
//
// actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic {
// println("Debug crypto_generichash_init")
// return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen)
// }
//
// /**
// * Initialize a state and generate a random header. Both are returned inside
// * `SecretStreamStateAndHeader` object.
// */
// actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray):
// SecretStreamStateAndHeader {
// 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)
// }
//
// /**
// * Initialize state from header and key. The state can then be used for decryption.
// */
// actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray):
// dynamic {
// println("Debug crypto_secretstream_xchacha20poly1305_init_pull")
// return getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(),
// key.toUInt8Array())
// }
//
// /**
// * Encrypt next block of data using the previously initialized state. Returns encrypted block.
// */
// actual fun crypto_secretstream_xchacha20poly1305_push(
// state: SecretStreamState,
// m: UByteArray,
// ad: UByteArray,
// tag: UByte
// ): UByteArray {
// println("Debug crypto_secretstream_xchacha20poly1305_push")
// return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(),
// ad.toUInt8Array(), tag).toUByteArray()
// }
//
// /**
// * Decrypt next block of data using the previously initialized state. Returns decrypted block.
// */
// actual fun crypto_secretstream_xchacha20poly1305_pull(
// state: SecretStreamState,
// c: UByteArray,
// ad: UByteArray
// ): DecryptedDataAndTag {
// println("Debug crypto_secretstream_xchacha20poly1305_pull")
//// return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(),
//// ad.toUInt8Array())
// return DecryptedDataAndTag(ubyteArrayOf(), 0U)
// }
//}

View File

@ -0,0 +1,31 @@
@file:JsModule("libsodium-sumo")
@file:JsNonModule
package ext.libsodium
import org.khronos.webgl.Uint8Array
import kotlin.js.Promise
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 25-May-2020
*/
@JsName("ready")
external val _libsodiumPromise : Promise<dynamic>
@JsName("_sodium_init")
external fun sodium_init() : Int
external fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array) : Uint8Array
external fun crypto_hash_sha256(message: Uint8Array) : Uint8Array
external fun crypto_hash_sha512(message: Uint8Array) : Uint8Array
external fun crypto_hash_sha256_init(): dynamic